@upstash/workflow 0.2.22-rc → 0.2.23-rc
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 +39 -0
- package/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +302 -130
- package/astro.mjs +1 -1
- package/{chunk-CAQSUCHB.mjs → chunk-KAGTWBLF.mjs} +271 -100
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +302 -130
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +304 -131
- package/express.mjs +3 -2
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +302 -130
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +302 -130
- package/hono.mjs +1 -1
- package/index.d.mts +10 -2
- package/index.d.ts +10 -2
- package/index.js +306 -132
- package/index.mjs +5 -3
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +304 -131
- package/nextjs.mjs +3 -2
- package/package.json +1 -1
- package/{serve-many-BNusWYgt.d.mts → serve-many-B5Vbacm6.d.mts} +1 -1
- package/{serve-many-CXqQP3RI.d.ts → serve-many-BCV7INWe.d.ts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +302 -130
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +302 -130
- package/svelte.mjs +1 -1
- package/tanstack.d.mts +2 -2
- package/tanstack.d.ts +2 -2
- package/tanstack.js +302 -130
- package/tanstack.mjs +1 -1
- package/{types-Q3dM0UlR.d.ts → types-BD06btU6.d.mts} +32 -6
- package/{types-Q3dM0UlR.d.mts → types-BD06btU6.d.ts} +32 -6
package/h3.js
CHANGED
|
@@ -339,7 +339,95 @@ var H3Headers = globalThis.Headers;
|
|
|
339
339
|
var H3Response = globalThis.Response;
|
|
340
340
|
|
|
341
341
|
// src/client/utils.ts
|
|
342
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
343
|
+
|
|
344
|
+
// src/error.ts
|
|
342
345
|
var import_qstash = require("@upstash/qstash");
|
|
346
|
+
var WorkflowError = class extends import_qstash.QstashError {
|
|
347
|
+
constructor(message) {
|
|
348
|
+
super(message);
|
|
349
|
+
this.name = "WorkflowError";
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
var WorkflowAbort = class extends Error {
|
|
353
|
+
stepInfo;
|
|
354
|
+
stepName;
|
|
355
|
+
/**
|
|
356
|
+
* whether workflow is to be canceled on abort
|
|
357
|
+
*/
|
|
358
|
+
cancelWorkflow;
|
|
359
|
+
/**
|
|
360
|
+
*
|
|
361
|
+
* @param stepName name of the aborting step
|
|
362
|
+
* @param stepInfo step information
|
|
363
|
+
* @param cancelWorkflow
|
|
364
|
+
*/
|
|
365
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
366
|
+
super(
|
|
367
|
+
`This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
|
|
368
|
+
);
|
|
369
|
+
this.name = "WorkflowAbort";
|
|
370
|
+
this.stepName = stepName;
|
|
371
|
+
this.stepInfo = stepInfo;
|
|
372
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
376
|
+
/**
|
|
377
|
+
* @param message error message to be displayed
|
|
378
|
+
*/
|
|
379
|
+
constructor(message) {
|
|
380
|
+
super("fail", void 0, false);
|
|
381
|
+
this.name = "WorkflowNonRetryableError";
|
|
382
|
+
if (message) this.message = message;
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
var WorkflowRetryAfterError = class extends WorkflowAbort {
|
|
386
|
+
retryAfter;
|
|
387
|
+
/**
|
|
388
|
+
* @param retryAfter time in seconds after which the workflow should be retried
|
|
389
|
+
* @param message error message to be displayed
|
|
390
|
+
*/
|
|
391
|
+
constructor(message, retryAfter) {
|
|
392
|
+
super("retry", void 0, false);
|
|
393
|
+
this.name = "WorkflowRetryAfterError";
|
|
394
|
+
this.retryAfter = retryAfter;
|
|
395
|
+
if (message) this.message = message;
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
var formatWorkflowError = (error) => {
|
|
399
|
+
return error instanceof Error ? {
|
|
400
|
+
error: error.name,
|
|
401
|
+
message: error.message,
|
|
402
|
+
stack: error.stack
|
|
403
|
+
} : {
|
|
404
|
+
error: "Error",
|
|
405
|
+
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
406
|
+
};
|
|
407
|
+
};
|
|
408
|
+
function getConstructorName(obj) {
|
|
409
|
+
if (obj === null || obj === void 0) {
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
const ctor = obj.constructor;
|
|
413
|
+
if (!ctor || ctor.name === "Object") {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
return ctor.name;
|
|
417
|
+
}
|
|
418
|
+
function getConstructorNames(obj) {
|
|
419
|
+
const proto = Object.getPrototypeOf(obj);
|
|
420
|
+
const name = getConstructorName(proto);
|
|
421
|
+
if (name === null) {
|
|
422
|
+
return [];
|
|
423
|
+
}
|
|
424
|
+
return [name, ...getConstructorNames(proto)];
|
|
425
|
+
}
|
|
426
|
+
function isInstanceOf(v, ctor) {
|
|
427
|
+
return getConstructorNames(v).includes(ctor.name);
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// src/client/utils.ts
|
|
343
431
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
344
432
|
const result = await requester.request({
|
|
345
433
|
path: ["v2", "notify", eventId],
|
|
@@ -379,7 +467,7 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
379
467
|
return { steps: filteredSteps, workflowRunEnded: false };
|
|
380
468
|
}
|
|
381
469
|
} catch (error) {
|
|
382
|
-
if (error
|
|
470
|
+
if (isInstanceOf(error, import_qstash2.QstashError) && error.status === 404) {
|
|
383
471
|
await debug?.log("WARN", "ENDPOINT_START", {
|
|
384
472
|
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
385
473
|
error
|
|
@@ -404,65 +492,13 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
404
492
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
405
493
|
var NO_CONCURRENCY = 1;
|
|
406
494
|
var DEFAULT_RETRIES = 3;
|
|
407
|
-
var VERSION = "v0.2.
|
|
495
|
+
var VERSION = "v0.2.22";
|
|
408
496
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
409
497
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
410
498
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
411
499
|
var TELEMETRY_HEADER_RUNTIME = "Upstash-Telemetry-Runtime";
|
|
412
500
|
var TELEMETRY_HEADER_AGENT = "Upstash-Telemetry-Agent";
|
|
413
501
|
|
|
414
|
-
// src/error.ts
|
|
415
|
-
var import_qstash2 = require("@upstash/qstash");
|
|
416
|
-
var WorkflowError = class extends import_qstash2.QstashError {
|
|
417
|
-
constructor(message) {
|
|
418
|
-
super(message);
|
|
419
|
-
this.name = "WorkflowError";
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
var WorkflowAbort = class extends Error {
|
|
423
|
-
stepInfo;
|
|
424
|
-
stepName;
|
|
425
|
-
/**
|
|
426
|
-
* whether workflow is to be canceled on abort
|
|
427
|
-
*/
|
|
428
|
-
cancelWorkflow;
|
|
429
|
-
/**
|
|
430
|
-
*
|
|
431
|
-
* @param stepName name of the aborting step
|
|
432
|
-
* @param stepInfo step information
|
|
433
|
-
* @param cancelWorkflow
|
|
434
|
-
*/
|
|
435
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
436
|
-
super(
|
|
437
|
-
`This is an Upstash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${stepName}'.`
|
|
438
|
-
);
|
|
439
|
-
this.name = "WorkflowAbort";
|
|
440
|
-
this.stepName = stepName;
|
|
441
|
-
this.stepInfo = stepInfo;
|
|
442
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
var WorkflowNonRetryableError = class extends WorkflowAbort {
|
|
446
|
-
/**
|
|
447
|
-
* @param message error message to be displayed
|
|
448
|
-
*/
|
|
449
|
-
constructor(message) {
|
|
450
|
-
super("fail", void 0, false);
|
|
451
|
-
this.name = "WorkflowNonRetryableError";
|
|
452
|
-
if (message) this.message = message;
|
|
453
|
-
}
|
|
454
|
-
};
|
|
455
|
-
var formatWorkflowError = (error) => {
|
|
456
|
-
return error instanceof Error ? {
|
|
457
|
-
error: error.name,
|
|
458
|
-
message: error.message,
|
|
459
|
-
stack: error.stack
|
|
460
|
-
} : {
|
|
461
|
-
error: "Error",
|
|
462
|
-
message: `An error occured while executing workflow: '${typeof error === "string" ? error : JSON.stringify(error)}'`
|
|
463
|
-
};
|
|
464
|
-
};
|
|
465
|
-
|
|
466
502
|
// src/context/auto-executor.ts
|
|
467
503
|
var import_qstash5 = require("@upstash/qstash");
|
|
468
504
|
|
|
@@ -475,8 +511,8 @@ var NANOID_LENGTH = 21;
|
|
|
475
511
|
function getRandomInt() {
|
|
476
512
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
477
513
|
}
|
|
478
|
-
function nanoid() {
|
|
479
|
-
return Array.from({ length
|
|
514
|
+
function nanoid(length = NANOID_LENGTH) {
|
|
515
|
+
return Array.from({ length }).map(() => NANOID_CHARS[getRandomInt()]).join("");
|
|
480
516
|
}
|
|
481
517
|
function getWorkflowRunId(id) {
|
|
482
518
|
return `wfr_${id ?? nanoid()}`;
|
|
@@ -493,6 +529,37 @@ function decodeBase64(base64) {
|
|
|
493
529
|
return binString;
|
|
494
530
|
}
|
|
495
531
|
}
|
|
532
|
+
function getUserIdFromToken(qstashClient) {
|
|
533
|
+
try {
|
|
534
|
+
const token = qstashClient.token;
|
|
535
|
+
const decodedToken = decodeBase64(token);
|
|
536
|
+
const tokenPayload = JSON.parse(decodedToken);
|
|
537
|
+
const userId = tokenPayload.UserID;
|
|
538
|
+
if (!userId) {
|
|
539
|
+
throw new WorkflowError("QStash token payload does not contain userId");
|
|
540
|
+
}
|
|
541
|
+
return userId;
|
|
542
|
+
} catch (error) {
|
|
543
|
+
throw new WorkflowError(
|
|
544
|
+
`Failed to decode QStash token while running create webhook step: ${error.message}`
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
function getQStashUrl(qstashClient) {
|
|
549
|
+
try {
|
|
550
|
+
const requester = qstashClient.http;
|
|
551
|
+
const baseUrl = requester.baseUrl;
|
|
552
|
+
if (!baseUrl) {
|
|
553
|
+
throw new WorkflowError("QStash client does not have a baseUrl");
|
|
554
|
+
}
|
|
555
|
+
return baseUrl;
|
|
556
|
+
} catch (error) {
|
|
557
|
+
throw new WorkflowError(`Failed to get QStash URL from client: ${error.message}`);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
function getEventId() {
|
|
561
|
+
return `evt_${nanoid(15)}`;
|
|
562
|
+
}
|
|
496
563
|
|
|
497
564
|
// node_modules/neverthrow/dist/index.es.js
|
|
498
565
|
var defaultErrorConfig = {
|
|
@@ -918,7 +985,9 @@ var StepTypes = [
|
|
|
918
985
|
"Call",
|
|
919
986
|
"Wait",
|
|
920
987
|
"Notify",
|
|
921
|
-
"Invoke"
|
|
988
|
+
"Invoke",
|
|
989
|
+
"CreateWebhook",
|
|
990
|
+
"WaitForWebhook"
|
|
922
991
|
];
|
|
923
992
|
|
|
924
993
|
// src/workflow-requests.ts
|
|
@@ -1022,17 +1091,17 @@ var triggerRouteFunction = async ({
|
|
|
1022
1091
|
return ok("workflow-finished");
|
|
1023
1092
|
} catch (error) {
|
|
1024
1093
|
const error_ = error;
|
|
1025
|
-
if (error
|
|
1094
|
+
if (isInstanceOf(error, import_qstash3.QstashError) && error.status === 400) {
|
|
1026
1095
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
1027
1096
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
1028
1097
|
name: error.name,
|
|
1029
1098
|
errorMessage: error.message
|
|
1030
1099
|
});
|
|
1031
1100
|
return ok("workflow-was-finished");
|
|
1032
|
-
} else if (
|
|
1033
|
-
return err(error_);
|
|
1034
|
-
} else if (error_ instanceof WorkflowNonRetryableError) {
|
|
1101
|
+
} else if (isInstanceOf(error_, WorkflowNonRetryableError) || isInstanceOf(error_, WorkflowRetryAfterError)) {
|
|
1035
1102
|
return ok(error_);
|
|
1103
|
+
} else if (!isInstanceOf(error_, WorkflowAbort)) {
|
|
1104
|
+
return err(error_);
|
|
1036
1105
|
} else if (error_.cancelWorkflow) {
|
|
1037
1106
|
await onCancel();
|
|
1038
1107
|
return ok("workflow-finished");
|
|
@@ -1230,7 +1299,9 @@ If you want to disable QStash Verification, you should clear env variables QSTAS
|
|
|
1230
1299
|
// src/context/steps.ts
|
|
1231
1300
|
var BaseLazyStep = class _BaseLazyStep {
|
|
1232
1301
|
stepName;
|
|
1233
|
-
|
|
1302
|
+
context;
|
|
1303
|
+
constructor(context, stepName) {
|
|
1304
|
+
this.context = context;
|
|
1234
1305
|
if (!stepName) {
|
|
1235
1306
|
throw new WorkflowError(
|
|
1236
1307
|
"A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
|
|
@@ -1248,13 +1319,14 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
1248
1319
|
*
|
|
1249
1320
|
* will be called when returning the steps to the context from auto executor
|
|
1250
1321
|
*
|
|
1251
|
-
* @param
|
|
1322
|
+
* @param step step
|
|
1252
1323
|
* @returns parsed out field
|
|
1253
1324
|
*/
|
|
1254
|
-
parseOut(
|
|
1325
|
+
parseOut(step) {
|
|
1326
|
+
const out = step.out;
|
|
1255
1327
|
if (out === void 0) {
|
|
1256
1328
|
if (this.allowUndefinedOut) {
|
|
1257
|
-
return
|
|
1329
|
+
return this.handleUndefinedOut(step);
|
|
1258
1330
|
} else {
|
|
1259
1331
|
throw new WorkflowError(
|
|
1260
1332
|
`Error while parsing output of ${this.stepType} step. Expected a string, but got: undefined`
|
|
@@ -1262,27 +1334,26 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
1262
1334
|
}
|
|
1263
1335
|
}
|
|
1264
1336
|
if (typeof out === "object") {
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
return out;
|
|
1270
|
-
}
|
|
1271
|
-
return {
|
|
1272
|
-
...out,
|
|
1273
|
-
eventData: _BaseLazyStep.tryParsing(out.eventData)
|
|
1274
|
-
};
|
|
1337
|
+
console.warn(
|
|
1338
|
+
`Error while parsing ${this.stepType} step output. Expected a string, but got object. Please reach out to Upstash Support.`
|
|
1339
|
+
);
|
|
1340
|
+
return out;
|
|
1275
1341
|
}
|
|
1276
1342
|
if (typeof out !== "string") {
|
|
1277
1343
|
throw new WorkflowError(
|
|
1278
1344
|
`Error while parsing output of ${this.stepType} step. Expected a string or undefined, but got: ${typeof out}`
|
|
1279
1345
|
);
|
|
1280
1346
|
}
|
|
1281
|
-
return this.safeParseOut(out);
|
|
1347
|
+
return this.safeParseOut(out, step);
|
|
1282
1348
|
}
|
|
1283
|
-
|
|
1349
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1350
|
+
safeParseOut(out, step) {
|
|
1284
1351
|
return _BaseLazyStep.tryParsing(out);
|
|
1285
1352
|
}
|
|
1353
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1354
|
+
handleUndefinedOut(step) {
|
|
1355
|
+
return void 0;
|
|
1356
|
+
}
|
|
1286
1357
|
static tryParsing(stepOut) {
|
|
1287
1358
|
try {
|
|
1288
1359
|
return JSON.parse(stepOut);
|
|
@@ -1333,8 +1404,8 @@ var LazyFunctionStep = class extends BaseLazyStep {
|
|
|
1333
1404
|
stepFunction;
|
|
1334
1405
|
stepType = "Run";
|
|
1335
1406
|
allowUndefinedOut = true;
|
|
1336
|
-
constructor(stepName, stepFunction) {
|
|
1337
|
-
super(stepName);
|
|
1407
|
+
constructor(context, stepName, stepFunction) {
|
|
1408
|
+
super(context, stepName);
|
|
1338
1409
|
this.stepFunction = stepFunction;
|
|
1339
1410
|
}
|
|
1340
1411
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1364,8 +1435,8 @@ var LazySleepStep = class extends BaseLazyStep {
|
|
|
1364
1435
|
sleep;
|
|
1365
1436
|
stepType = "SleepFor";
|
|
1366
1437
|
allowUndefinedOut = true;
|
|
1367
|
-
constructor(stepName, sleep) {
|
|
1368
|
-
super(stepName);
|
|
1438
|
+
constructor(context, stepName, sleep) {
|
|
1439
|
+
super(context, stepName);
|
|
1369
1440
|
this.sleep = sleep;
|
|
1370
1441
|
}
|
|
1371
1442
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1406,8 +1477,8 @@ var LazySleepUntilStep = class extends BaseLazyStep {
|
|
|
1406
1477
|
sleepUntil;
|
|
1407
1478
|
stepType = "SleepUntil";
|
|
1408
1479
|
allowUndefinedOut = true;
|
|
1409
|
-
constructor(stepName, sleepUntil) {
|
|
1410
|
-
super(stepName);
|
|
1480
|
+
constructor(context, stepName, sleepUntil) {
|
|
1481
|
+
super(context, stepName);
|
|
1411
1482
|
this.sleepUntil = sleepUntil;
|
|
1412
1483
|
}
|
|
1413
1484
|
getPlanStep(concurrent, targetStep) {
|
|
@@ -1459,8 +1530,8 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1459
1530
|
stringifyBody;
|
|
1460
1531
|
stepType = "Call";
|
|
1461
1532
|
allowUndefinedOut = false;
|
|
1462
|
-
constructor(stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1463
|
-
super(stepName);
|
|
1533
|
+
constructor(context, stepName, url, method, body, headers, retries, retryDelay, timeout, flowControl, stringifyBody) {
|
|
1534
|
+
super(context, stepName);
|
|
1464
1535
|
this.url = url;
|
|
1465
1536
|
this.method = method;
|
|
1466
1537
|
this.body = body;
|
|
@@ -1604,13 +1675,12 @@ var LazyCallStep = class _LazyCallStep extends BaseLazyStep {
|
|
|
1604
1675
|
]);
|
|
1605
1676
|
}
|
|
1606
1677
|
};
|
|
1607
|
-
var
|
|
1678
|
+
var LazyWaitEventStep = class extends BaseLazyStep {
|
|
1608
1679
|
eventId;
|
|
1609
1680
|
timeout;
|
|
1610
|
-
stepType = "Wait";
|
|
1611
1681
|
allowUndefinedOut = false;
|
|
1612
|
-
constructor(stepName, eventId, timeout) {
|
|
1613
|
-
super(stepName);
|
|
1682
|
+
constructor(context, stepName, eventId, timeout) {
|
|
1683
|
+
super(context, stepName);
|
|
1614
1684
|
this.eventId = eventId;
|
|
1615
1685
|
this.timeout = timeout;
|
|
1616
1686
|
}
|
|
@@ -1635,13 +1705,6 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1635
1705
|
concurrent
|
|
1636
1706
|
});
|
|
1637
1707
|
}
|
|
1638
|
-
safeParseOut(out) {
|
|
1639
|
-
const result = JSON.parse(out);
|
|
1640
|
-
return {
|
|
1641
|
-
...result,
|
|
1642
|
-
eventData: BaseLazyStep.tryParsing(result.eventData)
|
|
1643
|
-
};
|
|
1644
|
-
}
|
|
1645
1708
|
getHeaders({ context, telemetry: telemetry2, invokeCount, step }) {
|
|
1646
1709
|
const headers = super.getHeaders({ context, telemetry: telemetry2, invokeCount, step });
|
|
1647
1710
|
headers.headers["Upstash-Workflow-CallType"] = "step";
|
|
@@ -1675,7 +1738,7 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1675
1738
|
timeoutHeaders,
|
|
1676
1739
|
step: {
|
|
1677
1740
|
stepId: step.stepId,
|
|
1678
|
-
stepType:
|
|
1741
|
+
stepType: this.stepType,
|
|
1679
1742
|
stepName: step.stepName,
|
|
1680
1743
|
concurrent: step.concurrent,
|
|
1681
1744
|
targetStep: step.targetStep
|
|
@@ -1696,8 +1759,8 @@ var LazyWaitForEventStep = class extends BaseLazyStep {
|
|
|
1696
1759
|
};
|
|
1697
1760
|
var LazyNotifyStep = class extends LazyFunctionStep {
|
|
1698
1761
|
stepType = "Notify";
|
|
1699
|
-
constructor(stepName, eventId, eventData, requester) {
|
|
1700
|
-
super(stepName, async () => {
|
|
1762
|
+
constructor(context, stepName, eventId, eventData, requester) {
|
|
1763
|
+
super(context, stepName, async () => {
|
|
1701
1764
|
const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
|
|
1702
1765
|
return {
|
|
1703
1766
|
eventId,
|
|
@@ -1722,7 +1785,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1722
1785
|
* workflow id of the invoked workflow
|
|
1723
1786
|
*/
|
|
1724
1787
|
workflowId;
|
|
1725
|
-
constructor(stepName, {
|
|
1788
|
+
constructor(context, stepName, {
|
|
1726
1789
|
workflow,
|
|
1727
1790
|
body,
|
|
1728
1791
|
headers = {},
|
|
@@ -1732,7 +1795,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1732
1795
|
flowControl,
|
|
1733
1796
|
stringifyBody = true
|
|
1734
1797
|
}) {
|
|
1735
|
-
super(stepName);
|
|
1798
|
+
super(context, stepName);
|
|
1736
1799
|
this.params = {
|
|
1737
1800
|
workflow,
|
|
1738
1801
|
body,
|
|
@@ -1793,6 +1856,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1793
1856
|
userHeaders: context.headers,
|
|
1794
1857
|
invokeCount
|
|
1795
1858
|
});
|
|
1859
|
+
context.qstashClient.http.headers?.forEach((value, key) => {
|
|
1860
|
+
invokerHeaders[key] = value;
|
|
1861
|
+
});
|
|
1796
1862
|
invokerHeaders["Upstash-Workflow-Runid"] = context.workflowRunId;
|
|
1797
1863
|
let invokeBody;
|
|
1798
1864
|
if (this.params.stringifyBody) {
|
|
@@ -1864,6 +1930,91 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1864
1930
|
return [result];
|
|
1865
1931
|
}
|
|
1866
1932
|
};
|
|
1933
|
+
var LazyCreateWebhookStep = class extends BaseLazyStep {
|
|
1934
|
+
stepType = "CreateWebhook";
|
|
1935
|
+
allowUndefinedOut = false;
|
|
1936
|
+
getPlanStep(concurrent, targetStep) {
|
|
1937
|
+
return {
|
|
1938
|
+
stepId: 0,
|
|
1939
|
+
stepName: this.stepName,
|
|
1940
|
+
stepType: this.stepType,
|
|
1941
|
+
concurrent,
|
|
1942
|
+
targetStep
|
|
1943
|
+
};
|
|
1944
|
+
}
|
|
1945
|
+
async getResultStep(concurrent, stepId) {
|
|
1946
|
+
return {
|
|
1947
|
+
stepId,
|
|
1948
|
+
stepName: this.stepName,
|
|
1949
|
+
stepType: this.stepType,
|
|
1950
|
+
out: void 0,
|
|
1951
|
+
concurrent
|
|
1952
|
+
};
|
|
1953
|
+
}
|
|
1954
|
+
getBody({ step, context }) {
|
|
1955
|
+
const userId = getUserIdFromToken(context.qstashClient);
|
|
1956
|
+
const out = [userId, context.workflowRunId, getEventId()].join("/");
|
|
1957
|
+
return JSON.stringify({
|
|
1958
|
+
...step,
|
|
1959
|
+
out
|
|
1960
|
+
});
|
|
1961
|
+
}
|
|
1962
|
+
safeParseOut(out) {
|
|
1963
|
+
const [userId, workflowRunId, eventId] = out.split("/");
|
|
1964
|
+
const qstashUrl = getQStashUrl(this.context.qstashClient);
|
|
1965
|
+
return {
|
|
1966
|
+
webhookUrl: `${qstashUrl}/v2/workflows/hooks/${userId}/${workflowRunId}/${eventId}`,
|
|
1967
|
+
eventId
|
|
1968
|
+
};
|
|
1969
|
+
}
|
|
1970
|
+
};
|
|
1971
|
+
var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
|
|
1972
|
+
stepType = "WaitForWebhook";
|
|
1973
|
+
allowUndefinedOut = true;
|
|
1974
|
+
constructor(context, stepName, webhook, timeout) {
|
|
1975
|
+
super(context, stepName, webhook.eventId, timeout);
|
|
1976
|
+
}
|
|
1977
|
+
safeParseOut(out) {
|
|
1978
|
+
const eventData = decodeBase64(out);
|
|
1979
|
+
const parsedEventData = BaseLazyStep.tryParsing(eventData);
|
|
1980
|
+
const body = parsedEventData.body;
|
|
1981
|
+
const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
|
|
1982
|
+
const request = new Request(
|
|
1983
|
+
`${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
|
|
1984
|
+
{
|
|
1985
|
+
method: parsedEventData.method,
|
|
1986
|
+
headers: parsedEventData.header,
|
|
1987
|
+
body: parsedBody
|
|
1988
|
+
}
|
|
1989
|
+
);
|
|
1990
|
+
return {
|
|
1991
|
+
request,
|
|
1992
|
+
timeout: false
|
|
1993
|
+
};
|
|
1994
|
+
}
|
|
1995
|
+
handleUndefinedOut() {
|
|
1996
|
+
return {
|
|
1997
|
+
timeout: true,
|
|
1998
|
+
request: void 0
|
|
1999
|
+
};
|
|
2000
|
+
}
|
|
2001
|
+
};
|
|
2002
|
+
var LazyWaitForEventStep = class extends LazyWaitEventStep {
|
|
2003
|
+
stepType = "Wait";
|
|
2004
|
+
allowUndefinedOut = true;
|
|
2005
|
+
parseWaitForEventOut(out, waitTimeout) {
|
|
2006
|
+
return {
|
|
2007
|
+
eventData: out ? BaseLazyStep.tryParsing(decodeBase64(out)) : void 0,
|
|
2008
|
+
timeout: waitTimeout ?? false
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
2011
|
+
safeParseOut(out, step) {
|
|
2012
|
+
return this.parseWaitForEventOut(out, step.waitTimeout);
|
|
2013
|
+
}
|
|
2014
|
+
handleUndefinedOut(step) {
|
|
2015
|
+
return this.parseWaitForEventOut(void 0, step.waitTimeout);
|
|
2016
|
+
}
|
|
2017
|
+
};
|
|
1867
2018
|
|
|
1868
2019
|
// src/agents/constants.ts
|
|
1869
2020
|
var AGENT_NAME_HEADER = "upstash-agent-name";
|
|
@@ -2268,7 +2419,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2268
2419
|
step,
|
|
2269
2420
|
stepCount: this.stepCount
|
|
2270
2421
|
});
|
|
2271
|
-
return lazyStep.parseOut(step
|
|
2422
|
+
return lazyStep.parseOut(step);
|
|
2272
2423
|
}
|
|
2273
2424
|
const resultStep = await submitSingleStep({
|
|
2274
2425
|
context: this.context,
|
|
@@ -2339,7 +2490,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2339
2490
|
});
|
|
2340
2491
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2341
2492
|
} catch (error) {
|
|
2342
|
-
if (error
|
|
2493
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2343
2494
|
throw error;
|
|
2344
2495
|
}
|
|
2345
2496
|
throw new WorkflowError(
|
|
@@ -2355,7 +2506,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2355
2506
|
const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
|
|
2356
2507
|
validateParallelSteps(parallelSteps, parallelResultSteps);
|
|
2357
2508
|
return parallelResultSteps.map(
|
|
2358
|
-
(step, index) => parallelSteps[index].parseOut(step
|
|
2509
|
+
(step, index) => parallelSteps[index].parseOut(step)
|
|
2359
2510
|
);
|
|
2360
2511
|
}
|
|
2361
2512
|
}
|
|
@@ -2411,7 +2562,6 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2411
2562
|
* @param index index of the current step
|
|
2412
2563
|
* @returns result[index] if lazyStepList > 1, otherwise result
|
|
2413
2564
|
*/
|
|
2414
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
|
|
2415
2565
|
static getResult(lazyStepList, result, index) {
|
|
2416
2566
|
if (lazyStepList.length === 1) {
|
|
2417
2567
|
return result;
|
|
@@ -2446,7 +2596,7 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2446
2596
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2447
2597
|
}
|
|
2448
2598
|
} catch (error) {
|
|
2449
|
-
if (error
|
|
2599
|
+
if (isInstanceOf(error, WorkflowError)) {
|
|
2450
2600
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2451
2601
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2452
2602
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
@@ -2627,7 +2777,7 @@ var fetchWithContextCall = async (context, agentCallParams, ...params) => {
|
|
|
2627
2777
|
headers: responseHeaders
|
|
2628
2778
|
});
|
|
2629
2779
|
} catch (error) {
|
|
2630
|
-
if (error instanceof Error && error
|
|
2780
|
+
if (error instanceof Error && isInstanceOf(error, WorkflowAbort)) {
|
|
2631
2781
|
throw error;
|
|
2632
2782
|
} else {
|
|
2633
2783
|
console.error("Error in fetch implementation:", error);
|
|
@@ -2729,10 +2879,10 @@ var Agent = class {
|
|
|
2729
2879
|
});
|
|
2730
2880
|
return { text: result.text };
|
|
2731
2881
|
} catch (error) {
|
|
2732
|
-
if (error
|
|
2733
|
-
if (error.cause instanceof Error && error.cause
|
|
2882
|
+
if (isInstanceOf(error, import_ai2.ToolExecutionError)) {
|
|
2883
|
+
if (error.cause instanceof Error && isInstanceOf(error.cause, WorkflowAbort)) {
|
|
2734
2884
|
throw error.cause;
|
|
2735
|
-
} else if (error.cause
|
|
2885
|
+
} else if (isInstanceOf(error.cause, import_ai2.ToolExecutionError) && isInstanceOf(error.cause.cause, WorkflowAbort)) {
|
|
2736
2886
|
throw error.cause.cause;
|
|
2737
2887
|
} else {
|
|
2738
2888
|
throw error;
|
|
@@ -3203,7 +3353,7 @@ var WorkflowContext = class {
|
|
|
3203
3353
|
*/
|
|
3204
3354
|
async run(stepName, stepFunction) {
|
|
3205
3355
|
const wrappedStepFunction = () => this.executor.wrapStep(stepName, stepFunction);
|
|
3206
|
-
return await this.addStep(new LazyFunctionStep(stepName, wrappedStepFunction));
|
|
3356
|
+
return await this.addStep(new LazyFunctionStep(this, stepName, wrappedStepFunction));
|
|
3207
3357
|
}
|
|
3208
3358
|
/**
|
|
3209
3359
|
* Stops the execution for the duration provided.
|
|
@@ -3217,7 +3367,7 @@ var WorkflowContext = class {
|
|
|
3217
3367
|
* @returns undefined
|
|
3218
3368
|
*/
|
|
3219
3369
|
async sleep(stepName, duration) {
|
|
3220
|
-
await this.addStep(new LazySleepStep(stepName, duration));
|
|
3370
|
+
await this.addStep(new LazySleepStep(this, stepName, duration));
|
|
3221
3371
|
}
|
|
3222
3372
|
/**
|
|
3223
3373
|
* Stops the execution until the date time provided.
|
|
@@ -3239,13 +3389,14 @@ var WorkflowContext = class {
|
|
|
3239
3389
|
datetime = typeof datetime === "string" ? new Date(datetime) : datetime;
|
|
3240
3390
|
time = Math.round(datetime.getTime() / 1e3);
|
|
3241
3391
|
}
|
|
3242
|
-
await this.addStep(new LazySleepUntilStep(stepName, time));
|
|
3392
|
+
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
3243
3393
|
}
|
|
3244
3394
|
async call(stepName, settings) {
|
|
3245
3395
|
let callStep;
|
|
3246
3396
|
if ("workflow" in settings) {
|
|
3247
3397
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
3248
3398
|
callStep = new LazyCallStep(
|
|
3399
|
+
this,
|
|
3249
3400
|
stepName,
|
|
3250
3401
|
url,
|
|
3251
3402
|
"POST",
|
|
@@ -3270,6 +3421,7 @@ var WorkflowContext = class {
|
|
|
3270
3421
|
stringifyBody = true
|
|
3271
3422
|
} = settings;
|
|
3272
3423
|
callStep = new LazyCallStep(
|
|
3424
|
+
this,
|
|
3273
3425
|
stepName,
|
|
3274
3426
|
url,
|
|
3275
3427
|
method,
|
|
@@ -3321,7 +3473,9 @@ var WorkflowContext = class {
|
|
|
3321
3473
|
async waitForEvent(stepName, eventId, options = {}) {
|
|
3322
3474
|
const { timeout = "7d" } = options;
|
|
3323
3475
|
const timeoutStr = typeof timeout === "string" ? timeout : `${timeout}s`;
|
|
3324
|
-
return await this.addStep(
|
|
3476
|
+
return await this.addStep(
|
|
3477
|
+
new LazyWaitForEventStep(this, stepName, eventId, timeoutStr)
|
|
3478
|
+
);
|
|
3325
3479
|
}
|
|
3326
3480
|
/**
|
|
3327
3481
|
* Notify workflow runs waiting for an event
|
|
@@ -3346,11 +3500,19 @@ var WorkflowContext = class {
|
|
|
3346
3500
|
*/
|
|
3347
3501
|
async notify(stepName, eventId, eventData) {
|
|
3348
3502
|
return await this.addStep(
|
|
3349
|
-
new LazyNotifyStep(stepName, eventId, eventData, this.qstashClient.http)
|
|
3503
|
+
new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
|
|
3350
3504
|
);
|
|
3351
3505
|
}
|
|
3352
3506
|
async invoke(stepName, settings) {
|
|
3353
|
-
return await this.addStep(
|
|
3507
|
+
return await this.addStep(
|
|
3508
|
+
new LazyInvokeStep(this, stepName, settings)
|
|
3509
|
+
);
|
|
3510
|
+
}
|
|
3511
|
+
async createWebhook(stepName) {
|
|
3512
|
+
return await this.addStep(new LazyCreateWebhookStep(this, stepName));
|
|
3513
|
+
}
|
|
3514
|
+
async waitForWebhook(stepName, webhook, timeout) {
|
|
3515
|
+
return await this.addStep(new LazyWaitForWebhookStep(this, stepName, webhook, timeout));
|
|
3354
3516
|
}
|
|
3355
3517
|
/**
|
|
3356
3518
|
* Cancel the current workflow run
|
|
@@ -3481,7 +3643,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3481
3643
|
try {
|
|
3482
3644
|
await routeFunction(disabledContext);
|
|
3483
3645
|
} catch (error) {
|
|
3484
|
-
if (error
|
|
3646
|
+
if (isInstanceOf(error, WorkflowAbort) && error.stepName === this.disabledMessage || isInstanceOf(error, WorkflowNonRetryableError) || isInstanceOf(error, WorkflowRetryAfterError)) {
|
|
3485
3647
|
return ok("step-found");
|
|
3486
3648
|
}
|
|
3487
3649
|
console.warn(
|
|
@@ -3514,13 +3676,6 @@ var processRawSteps = (rawSteps) => {
|
|
|
3514
3676
|
const stepsToDecode = encodedSteps.filter((step) => step.callType === "step");
|
|
3515
3677
|
const otherSteps = stepsToDecode.map((rawStep) => {
|
|
3516
3678
|
const step = JSON.parse(decodeBase64(rawStep.body));
|
|
3517
|
-
if (step.waitEventId) {
|
|
3518
|
-
const newOut = {
|
|
3519
|
-
eventData: step.out ? decodeBase64(step.out) : void 0,
|
|
3520
|
-
timeout: step.waitTimeout ?? false
|
|
3521
|
-
};
|
|
3522
|
-
step.out = newOut;
|
|
3523
|
-
}
|
|
3524
3679
|
return step;
|
|
3525
3680
|
});
|
|
3526
3681
|
const steps = [initialStep, ...otherSteps];
|
|
@@ -3734,13 +3889,24 @@ var processOptions = (options) => {
|
|
|
3734
3889
|
},
|
|
3735
3890
|
status: 489
|
|
3736
3891
|
});
|
|
3737
|
-
} else if (detailedFinishCondition?.condition === "
|
|
3738
|
-
return new Response(detailedFinishCondition.result
|
|
3739
|
-
status: 200,
|
|
3892
|
+
} else if (detailedFinishCondition?.condition === "retry-after-error") {
|
|
3893
|
+
return new Response(JSON.stringify(formatWorkflowError(detailedFinishCondition.result)), {
|
|
3740
3894
|
headers: {
|
|
3895
|
+
"Retry-After": detailedFinishCondition.result.retryAfter.toString(),
|
|
3741
3896
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3742
|
-
}
|
|
3897
|
+
},
|
|
3898
|
+
status: 429
|
|
3743
3899
|
});
|
|
3900
|
+
} else if (detailedFinishCondition?.condition === "failure-callback") {
|
|
3901
|
+
return new Response(
|
|
3902
|
+
JSON.stringify({ result: detailedFinishCondition.result ?? void 0 }),
|
|
3903
|
+
{
|
|
3904
|
+
status: 200,
|
|
3905
|
+
headers: {
|
|
3906
|
+
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|
|
3907
|
+
}
|
|
3908
|
+
}
|
|
3909
|
+
);
|
|
3744
3910
|
}
|
|
3745
3911
|
return new Response(JSON.stringify({ workflowRunId }), {
|
|
3746
3912
|
status: 200,
|
|
@@ -3950,12 +4116,18 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3950
4116
|
},
|
|
3951
4117
|
debug
|
|
3952
4118
|
});
|
|
3953
|
-
if (result.isOk() && result.value
|
|
4119
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowNonRetryableError)) {
|
|
3954
4120
|
return onStepFinish(workflowRunId, result.value, {
|
|
3955
4121
|
condition: "non-retryable-error",
|
|
3956
4122
|
result: result.value
|
|
3957
4123
|
});
|
|
3958
4124
|
}
|
|
4125
|
+
if (result.isOk() && isInstanceOf(result.value, WorkflowRetryAfterError)) {
|
|
4126
|
+
return onStepFinish(workflowRunId, result.value, {
|
|
4127
|
+
condition: "retry-after-error",
|
|
4128
|
+
result: result.value
|
|
4129
|
+
});
|
|
4130
|
+
}
|
|
3959
4131
|
if (result.isErr()) {
|
|
3960
4132
|
await debug?.log("ERROR", "ERROR", { error: result.error.message });
|
|
3961
4133
|
throw result.error;
|
|
@@ -3986,7 +4158,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
|
|
|
3986
4158
|
const errorMessage = `Error while running onError callback: '${formattedOnErrorError.message}'.
|
|
3987
4159
|
Original error: '${formattedError.message}'`;
|
|
3988
4160
|
console.error(errorMessage);
|
|
3989
|
-
return new Response(errorMessage, {
|
|
4161
|
+
return new Response(JSON.stringify({ error: errorMessage }), {
|
|
3990
4162
|
status: 500,
|
|
3991
4163
|
headers: {
|
|
3992
4164
|
[WORKFLOW_PROTOCOL_VERSION_HEADER]: WORKFLOW_PROTOCOL_VERSION
|