@upstash/qstash 2.7.0-workflow-alpha.1 → 2.7.0-workflow-alpha.3
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/{chunk-IH67DXYC.mjs → chunk-M4XG6QUQ.mjs} +41 -41
- package/{chunk-Y7J2MMPD.js → chunk-NYJWM6N6.js} +40 -40
- package/{client-CNTh3Kdn.d.mts → client-CMBMVtW3.d.mts} +29 -11
- package/{client-CNTh3Kdn.d.ts → client-CMBMVtW3.d.ts} +29 -11
- package/index.d.mts +5 -5
- package/index.d.ts +5 -5
- package/index.js +2 -2
- package/index.mjs +5 -5
- package/nextjs.d.mts +1 -1
- package/nextjs.d.ts +1 -1
- package/nextjs.js +6 -6
- package/nextjs.mjs +1 -1
- package/nuxt.d.mts +1 -1
- package/nuxt.d.ts +1 -1
- package/nuxt.js +4 -4
- package/nuxt.mjs +1 -1
- package/package.json +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +4 -4
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +1 -1
- package/svelte.d.ts +1 -1
- package/svelte.js +4 -4
- package/svelte.mjs +1 -1
- package/workflow.d.mts +1 -1
- package/workflow.d.ts +1 -1
- package/workflow.js +2 -2
- package/workflow.mjs +1 -1
|
@@ -158,20 +158,20 @@ var QstashDailyRatelimitError = class extends QstashError {
|
|
|
158
158
|
this.name = "QstashChatRatelimitError";
|
|
159
159
|
}
|
|
160
160
|
};
|
|
161
|
-
var
|
|
161
|
+
var QStashWorkflowError = class extends QstashError {
|
|
162
162
|
constructor(message) {
|
|
163
163
|
super(message);
|
|
164
|
-
this.name = "
|
|
164
|
+
this.name = "QStashWorkflowError";
|
|
165
165
|
}
|
|
166
166
|
};
|
|
167
|
-
var
|
|
167
|
+
var QStashWorkflowAbort = class extends Error {
|
|
168
168
|
stepInfo;
|
|
169
169
|
stepName;
|
|
170
170
|
constructor(stepName, stepInfo) {
|
|
171
171
|
super(
|
|
172
|
-
`This is an QStash Workflow error thrown after a step executes. It is expected to be raised.
|
|
172
|
+
`This is an QStash 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}'.`
|
|
173
173
|
);
|
|
174
|
-
this.name = "
|
|
174
|
+
this.name = "QStashWorkflowAbort";
|
|
175
175
|
this.stepName = stepName;
|
|
176
176
|
this.stepInfo = stepInfo;
|
|
177
177
|
}
|
|
@@ -1561,7 +1561,7 @@ var triggerRouteFunction = async ({
|
|
|
1561
1561
|
return ok("workflow-finished");
|
|
1562
1562
|
} catch (error) {
|
|
1563
1563
|
const error_ = error;
|
|
1564
|
-
return error_ instanceof
|
|
1564
|
+
return error_ instanceof QStashWorkflowAbort ? ok("step-finished") : err(error_);
|
|
1565
1565
|
}
|
|
1566
1566
|
};
|
|
1567
1567
|
var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
|
|
@@ -1649,7 +1649,7 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
|
|
|
1649
1649
|
} catch (error) {
|
|
1650
1650
|
const isCallReturn = request.headers.get("Upstash-Workflow-Callback");
|
|
1651
1651
|
return err(
|
|
1652
|
-
new
|
|
1652
|
+
new QStashWorkflowError(
|
|
1653
1653
|
`Error when handling call return (isCallReturn=${isCallReturn}): ${error}`
|
|
1654
1654
|
)
|
|
1655
1655
|
);
|
|
@@ -1717,7 +1717,7 @@ var verifyRequest = async (body, signature, verifier) => {
|
|
|
1717
1717
|
throw new Error("Signature in `Upstash-Signature` header is not valid");
|
|
1718
1718
|
}
|
|
1719
1719
|
} catch (error) {
|
|
1720
|
-
throw new
|
|
1720
|
+
throw new QStashWorkflowError(
|
|
1721
1721
|
`Failed to verify that the Workflow request comes from QStash: ${error}
|
|
1722
1722
|
|
|
1723
1723
|
If signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.
|
|
@@ -1757,14 +1757,14 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1757
1757
|
*
|
|
1758
1758
|
* If a function is already executing (this.executingStep), this
|
|
1759
1759
|
* means that there is a nested step which is not allowed. In this
|
|
1760
|
-
* case, addStep throws
|
|
1760
|
+
* case, addStep throws QStashWorkflowError.
|
|
1761
1761
|
*
|
|
1762
1762
|
* @param stepInfo step plan to add
|
|
1763
1763
|
* @returns result of the step function
|
|
1764
1764
|
*/
|
|
1765
1765
|
async addStep(stepInfo) {
|
|
1766
1766
|
if (this.executingStep) {
|
|
1767
|
-
throw new
|
|
1767
|
+
throw new QStashWorkflowError(
|
|
1768
1768
|
`A step can not be run inside another step. Tried to run '${stepInfo.stepName}' inside '${this.executingStep}'`
|
|
1769
1769
|
);
|
|
1770
1770
|
}
|
|
@@ -1833,7 +1833,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1833
1833
|
step: resultStep,
|
|
1834
1834
|
stepCount: this.stepCount
|
|
1835
1835
|
});
|
|
1836
|
-
await this.
|
|
1836
|
+
await this.submitStepsToQStash([resultStep]);
|
|
1837
1837
|
return resultStep.out;
|
|
1838
1838
|
}
|
|
1839
1839
|
/**
|
|
@@ -1849,7 +1849,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1849
1849
|
const sortedSteps = sortSteps(this.steps);
|
|
1850
1850
|
const plannedParallelStepCount = sortedSteps[initialStepCount + this.planStepCount]?.concurrent;
|
|
1851
1851
|
if (parallelCallState !== "first" && plannedParallelStepCount !== parallelSteps.length) {
|
|
1852
|
-
throw new
|
|
1852
|
+
throw new QStashWorkflowError(
|
|
1853
1853
|
`Incompatible number of parallel steps when call state was '${parallelCallState}'. Expected ${parallelSteps.length}, got ${plannedParallelStepCount} from the request.`
|
|
1854
1854
|
);
|
|
1855
1855
|
}
|
|
@@ -1865,13 +1865,13 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1865
1865
|
const planSteps = parallelSteps.map(
|
|
1866
1866
|
(parallelStep, index) => parallelStep.getPlanStep(parallelSteps.length, initialStepCount + index)
|
|
1867
1867
|
);
|
|
1868
|
-
await this.
|
|
1868
|
+
await this.submitStepsToQStash(planSteps);
|
|
1869
1869
|
break;
|
|
1870
1870
|
}
|
|
1871
1871
|
case "partial": {
|
|
1872
1872
|
const planStep = this.steps.at(-1);
|
|
1873
1873
|
if (!planStep || planStep.targetStep === void 0) {
|
|
1874
|
-
throw new
|
|
1874
|
+
throw new QStashWorkflowError(
|
|
1875
1875
|
`There must be a last step and it should have targetStep larger than 0.Received: ${JSON.stringify(planStep)}`
|
|
1876
1876
|
);
|
|
1877
1877
|
}
|
|
@@ -1882,19 +1882,19 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1882
1882
|
parallelSteps.length,
|
|
1883
1883
|
planStep.targetStep
|
|
1884
1884
|
);
|
|
1885
|
-
await this.
|
|
1885
|
+
await this.submitStepsToQStash([resultStep]);
|
|
1886
1886
|
} catch (error) {
|
|
1887
|
-
if (error instanceof
|
|
1887
|
+
if (error instanceof QStashWorkflowAbort) {
|
|
1888
1888
|
throw error;
|
|
1889
1889
|
}
|
|
1890
|
-
throw new
|
|
1891
|
-
`Error submitting steps to
|
|
1890
|
+
throw new QStashWorkflowError(
|
|
1891
|
+
`Error submitting steps to QStash in partial parallel step execution: ${error}`
|
|
1892
1892
|
);
|
|
1893
1893
|
}
|
|
1894
1894
|
break;
|
|
1895
1895
|
}
|
|
1896
1896
|
case "discard": {
|
|
1897
|
-
throw new
|
|
1897
|
+
throw new QStashWorkflowAbort("discarded parallel");
|
|
1898
1898
|
}
|
|
1899
1899
|
case "last": {
|
|
1900
1900
|
const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
|
|
@@ -1943,10 +1943,10 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1943
1943
|
*
|
|
1944
1944
|
* @param steps steps to send
|
|
1945
1945
|
*/
|
|
1946
|
-
async
|
|
1946
|
+
async submitStepsToQStash(steps) {
|
|
1947
1947
|
if (steps.length === 0) {
|
|
1948
|
-
throw new
|
|
1949
|
-
`Unable to submit steps to
|
|
1948
|
+
throw new QStashWorkflowError(
|
|
1949
|
+
`Unable to submit steps to QStash. Provided list is empty. Current step: ${this.stepCount}`
|
|
1950
1950
|
);
|
|
1951
1951
|
}
|
|
1952
1952
|
await this.debug?.log("SUBMIT", "SUBMIT_STEP", { length: steps.length, steps });
|
|
@@ -1956,7 +1956,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1956
1956
|
"false",
|
|
1957
1957
|
this.context.workflowRunId,
|
|
1958
1958
|
this.context.url,
|
|
1959
|
-
this.context.headers,
|
|
1959
|
+
singleStep.callUrl ? void 0 : this.context.headers,
|
|
1960
1960
|
singleStep,
|
|
1961
1961
|
this.context.failureUrl
|
|
1962
1962
|
);
|
|
@@ -1996,7 +1996,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
1996
1996
|
};
|
|
1997
1997
|
})
|
|
1998
1998
|
});
|
|
1999
|
-
throw new
|
|
1999
|
+
throw new QStashWorkflowAbort(steps[0].stepName, steps[0]);
|
|
2000
2000
|
}
|
|
2001
2001
|
/**
|
|
2002
2002
|
* Get the promise by executing the lazt steps list. If there is a single
|
|
@@ -2020,7 +2020,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2020
2020
|
} else if (Array.isArray(result) && lazyStepList.length === result.length && index < lazyStepList.length) {
|
|
2021
2021
|
return result[index];
|
|
2022
2022
|
} else {
|
|
2023
|
-
throw new
|
|
2023
|
+
throw new QStashWorkflowError(
|
|
2024
2024
|
`Unexpected parallel call result while executing step ${index}: '${result}'. Expected ${lazyStepList.length} many items`
|
|
2025
2025
|
);
|
|
2026
2026
|
}
|
|
@@ -2032,12 +2032,12 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2032
2032
|
};
|
|
2033
2033
|
var validateStep = (lazyStep, stepFromRequest) => {
|
|
2034
2034
|
if (lazyStep.stepName !== stepFromRequest.stepName) {
|
|
2035
|
-
throw new
|
|
2035
|
+
throw new QStashWorkflowError(
|
|
2036
2036
|
`Incompatible step name. Expected '${lazyStep.stepName}', got '${stepFromRequest.stepName}' from the request`
|
|
2037
2037
|
);
|
|
2038
2038
|
}
|
|
2039
2039
|
if (lazyStep.stepType !== stepFromRequest.stepType) {
|
|
2040
|
-
throw new
|
|
2040
|
+
throw new QStashWorkflowError(
|
|
2041
2041
|
`Incompatible step type. Expected '${lazyStep.stepType}', got '${stepFromRequest.stepType}' from the request`
|
|
2042
2042
|
);
|
|
2043
2043
|
}
|
|
@@ -2048,12 +2048,12 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2048
2048
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2049
2049
|
}
|
|
2050
2050
|
} catch (error) {
|
|
2051
|
-
if (error instanceof
|
|
2051
|
+
if (error instanceof QStashWorkflowError) {
|
|
2052
2052
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2053
2053
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2054
2054
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
2055
2055
|
const requestStepTypes = stepsFromRequest.map((step) => step.stepType);
|
|
2056
|
-
throw new
|
|
2056
|
+
throw new QStashWorkflowError(
|
|
2057
2057
|
`Incompatible steps detected in parallel execution: ${error.message}
|
|
2058
2058
|
> Step Names from the request: ${JSON.stringify(requestStepNames)}
|
|
2059
2059
|
Step Types from the request: ${JSON.stringify(requestStepTypes)}
|
|
@@ -2419,14 +2419,14 @@ var WorkflowContext = class {
|
|
|
2419
2419
|
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
2420
2420
|
static disabledMessage = "disabled-qstash-worklfow-run";
|
|
2421
2421
|
/**
|
|
2422
|
-
* overwrite the WorkflowContext.addStep method to always raise
|
|
2422
|
+
* overwrite the WorkflowContext.addStep method to always raise QStashWorkflowAbort
|
|
2423
2423
|
* error in order to stop the execution whenever we encounter a step.
|
|
2424
2424
|
*
|
|
2425
2425
|
* @param _step
|
|
2426
2426
|
*/
|
|
2427
2427
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
2428
2428
|
async addStep(_step) {
|
|
2429
|
-
throw new
|
|
2429
|
+
throw new QStashWorkflowAbort(_DisabledWorkflowContext.disabledMessage);
|
|
2430
2430
|
}
|
|
2431
2431
|
/**
|
|
2432
2432
|
* copies the passed context to create a DisabledWorkflowContext. Then, runs the
|
|
@@ -2453,7 +2453,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2453
2453
|
try {
|
|
2454
2454
|
await routeFunction(disabledContext);
|
|
2455
2455
|
} catch (error) {
|
|
2456
|
-
if (error instanceof
|
|
2456
|
+
if (error instanceof QStashWorkflowAbort && error.stepName === this.disabledMessage) {
|
|
2457
2457
|
return ok("step-found");
|
|
2458
2458
|
}
|
|
2459
2459
|
return err(error);
|
|
@@ -2600,7 +2600,7 @@ var checkIfLastOneIsDuplicate = async (steps, debug) => {
|
|
|
2600
2600
|
for (let index = 0; index < steps.length - 1; index++) {
|
|
2601
2601
|
const step = steps[index];
|
|
2602
2602
|
if (step.stepId === lastStepId && step.targetStep === lastTargetStepId) {
|
|
2603
|
-
const message = `
|
|
2603
|
+
const message = `QStash Workflow: The step '${step.stepName}' with id '${step.stepId}' has run twice during workflow execution. Rest of the workflow will continue running as usual.`;
|
|
2604
2604
|
await debug?.log("WARN", "RESPONSE_DEFAULT", message);
|
|
2605
2605
|
console.warn(message);
|
|
2606
2606
|
return true;
|
|
@@ -2612,13 +2612,13 @@ var validateRequest = (request) => {
|
|
|
2612
2612
|
const versionHeader = request.headers.get(WORKFLOW_PROTOCOL_VERSION_HEADER);
|
|
2613
2613
|
const isFirstInvocation = !versionHeader;
|
|
2614
2614
|
if (!isFirstInvocation && versionHeader !== WORKFLOW_PROTOCOL_VERSION) {
|
|
2615
|
-
throw new
|
|
2615
|
+
throw new QStashWorkflowError(
|
|
2616
2616
|
`Incompatible workflow sdk protocol version. Expected ${WORKFLOW_PROTOCOL_VERSION}, got ${versionHeader} from the request.`
|
|
2617
2617
|
);
|
|
2618
2618
|
}
|
|
2619
2619
|
const workflowRunId = isFirstInvocation ? `wfr_${nanoid()}` : request.headers.get(WORKFLOW_ID_HEADER) ?? "";
|
|
2620
2620
|
if (workflowRunId.length === 0) {
|
|
2621
|
-
throw new
|
|
2621
|
+
throw new QStashWorkflowError("Couldn't get workflow id from header");
|
|
2622
2622
|
}
|
|
2623
2623
|
return {
|
|
2624
2624
|
isFirstInvocation,
|
|
@@ -2634,7 +2634,7 @@ var parseRequest = async (requestPayload, isFirstInvocation, debug) => {
|
|
|
2634
2634
|
};
|
|
2635
2635
|
} else {
|
|
2636
2636
|
if (!requestPayload) {
|
|
2637
|
-
throw new
|
|
2637
|
+
throw new QStashWorkflowError("Only first call can have an empty body");
|
|
2638
2638
|
}
|
|
2639
2639
|
const { rawInitialPayload, steps } = parsePayload(requestPayload);
|
|
2640
2640
|
const isLastDuplicate = await checkIfLastOneIsDuplicate(steps, debug);
|
|
@@ -2652,13 +2652,13 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2652
2652
|
}
|
|
2653
2653
|
if (!failureFunction) {
|
|
2654
2654
|
return err(
|
|
2655
|
-
new
|
|
2655
|
+
new QStashWorkflowError(
|
|
2656
2656
|
"Workflow endpoint is called to handle a failure, but a failureFunction is not provided in serve options. Either provide a failureUrl or a failureFunction."
|
|
2657
2657
|
)
|
|
2658
2658
|
);
|
|
2659
2659
|
}
|
|
2660
2660
|
try {
|
|
2661
|
-
const { status,
|
|
2661
|
+
const { status, header, body, url, sourceHeader, sourceBody, workflowRunId } = JSON.parse(
|
|
2662
2662
|
requestPayload
|
|
2663
2663
|
);
|
|
2664
2664
|
const decodedBody = body ? atob(body) : "{}";
|
|
@@ -2679,7 +2679,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2679
2679
|
failureUrl: url,
|
|
2680
2680
|
debug
|
|
2681
2681
|
});
|
|
2682
|
-
await failureFunction(workflowContext, status, errorPayload.message);
|
|
2682
|
+
await failureFunction(workflowContext, status, errorPayload.message, header);
|
|
2683
2683
|
} catch (error) {
|
|
2684
2684
|
return err(error);
|
|
2685
2685
|
}
|
|
@@ -2854,8 +2854,8 @@ export {
|
|
|
2854
2854
|
QstashRatelimitError,
|
|
2855
2855
|
QstashChatRatelimitError,
|
|
2856
2856
|
QstashDailyRatelimitError,
|
|
2857
|
-
|
|
2858
|
-
|
|
2857
|
+
QStashWorkflowError,
|
|
2858
|
+
QStashWorkflowAbort,
|
|
2859
2859
|
formatWorkflowError,
|
|
2860
2860
|
setupAnalytics,
|
|
2861
2861
|
upstash,
|
|
@@ -158,20 +158,20 @@ var QstashDailyRatelimitError = class extends QstashError {
|
|
|
158
158
|
this.name = "QstashChatRatelimitError";
|
|
159
159
|
}
|
|
160
160
|
};
|
|
161
|
-
var
|
|
161
|
+
var QStashWorkflowError = class extends QstashError {
|
|
162
162
|
constructor(message) {
|
|
163
163
|
super(message);
|
|
164
|
-
this.name = "
|
|
164
|
+
this.name = "QStashWorkflowError";
|
|
165
165
|
}
|
|
166
166
|
};
|
|
167
|
-
var
|
|
167
|
+
var QStashWorkflowAbort = class extends Error {
|
|
168
168
|
|
|
169
169
|
|
|
170
170
|
constructor(stepName, stepInfo) {
|
|
171
171
|
super(
|
|
172
|
-
`This is an QStash Workflow error thrown after a step executes. It is expected to be raised.
|
|
172
|
+
`This is an QStash 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}'.`
|
|
173
173
|
);
|
|
174
|
-
this.name = "
|
|
174
|
+
this.name = "QStashWorkflowAbort";
|
|
175
175
|
this.stepName = stepName;
|
|
176
176
|
this.stepInfo = stepInfo;
|
|
177
177
|
}
|
|
@@ -1561,7 +1561,7 @@ var triggerRouteFunction = async ({
|
|
|
1561
1561
|
return ok("workflow-finished");
|
|
1562
1562
|
} catch (error) {
|
|
1563
1563
|
const error_ = error;
|
|
1564
|
-
return error_ instanceof
|
|
1564
|
+
return error_ instanceof QStashWorkflowAbort ? ok("step-finished") : err(error_);
|
|
1565
1565
|
}
|
|
1566
1566
|
};
|
|
1567
1567
|
var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
|
|
@@ -1649,7 +1649,7 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
|
|
|
1649
1649
|
} catch (error) {
|
|
1650
1650
|
const isCallReturn = request.headers.get("Upstash-Workflow-Callback");
|
|
1651
1651
|
return err(
|
|
1652
|
-
new
|
|
1652
|
+
new QStashWorkflowError(
|
|
1653
1653
|
`Error when handling call return (isCallReturn=${isCallReturn}): ${error}`
|
|
1654
1654
|
)
|
|
1655
1655
|
);
|
|
@@ -1717,7 +1717,7 @@ var verifyRequest = async (body, signature, verifier) => {
|
|
|
1717
1717
|
throw new Error("Signature in `Upstash-Signature` header is not valid");
|
|
1718
1718
|
}
|
|
1719
1719
|
} catch (error) {
|
|
1720
|
-
throw new
|
|
1720
|
+
throw new QStashWorkflowError(
|
|
1721
1721
|
`Failed to verify that the Workflow request comes from QStash: ${error}
|
|
1722
1722
|
|
|
1723
1723
|
If signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.
|
|
@@ -1757,14 +1757,14 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1757
1757
|
*
|
|
1758
1758
|
* If a function is already executing (this.executingStep), this
|
|
1759
1759
|
* means that there is a nested step which is not allowed. In this
|
|
1760
|
-
* case, addStep throws
|
|
1760
|
+
* case, addStep throws QStashWorkflowError.
|
|
1761
1761
|
*
|
|
1762
1762
|
* @param stepInfo step plan to add
|
|
1763
1763
|
* @returns result of the step function
|
|
1764
1764
|
*/
|
|
1765
1765
|
async addStep(stepInfo) {
|
|
1766
1766
|
if (this.executingStep) {
|
|
1767
|
-
throw new
|
|
1767
|
+
throw new QStashWorkflowError(
|
|
1768
1768
|
`A step can not be run inside another step. Tried to run '${stepInfo.stepName}' inside '${this.executingStep}'`
|
|
1769
1769
|
);
|
|
1770
1770
|
}
|
|
@@ -1833,7 +1833,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1833
1833
|
step: resultStep,
|
|
1834
1834
|
stepCount: this.stepCount
|
|
1835
1835
|
})]);
|
|
1836
|
-
await this.
|
|
1836
|
+
await this.submitStepsToQStash([resultStep]);
|
|
1837
1837
|
return resultStep.out;
|
|
1838
1838
|
}
|
|
1839
1839
|
/**
|
|
@@ -1849,7 +1849,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1849
1849
|
const sortedSteps = sortSteps(this.steps);
|
|
1850
1850
|
const plannedParallelStepCount = _optionalChain([sortedSteps, 'access', _53 => _53[initialStepCount + this.planStepCount], 'optionalAccess', _54 => _54.concurrent]);
|
|
1851
1851
|
if (parallelCallState !== "first" && plannedParallelStepCount !== parallelSteps.length) {
|
|
1852
|
-
throw new
|
|
1852
|
+
throw new QStashWorkflowError(
|
|
1853
1853
|
`Incompatible number of parallel steps when call state was '${parallelCallState}'. Expected ${parallelSteps.length}, got ${plannedParallelStepCount} from the request.`
|
|
1854
1854
|
);
|
|
1855
1855
|
}
|
|
@@ -1865,13 +1865,13 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1865
1865
|
const planSteps = parallelSteps.map(
|
|
1866
1866
|
(parallelStep, index) => parallelStep.getPlanStep(parallelSteps.length, initialStepCount + index)
|
|
1867
1867
|
);
|
|
1868
|
-
await this.
|
|
1868
|
+
await this.submitStepsToQStash(planSteps);
|
|
1869
1869
|
break;
|
|
1870
1870
|
}
|
|
1871
1871
|
case "partial": {
|
|
1872
1872
|
const planStep = this.steps.at(-1);
|
|
1873
1873
|
if (!planStep || planStep.targetStep === void 0) {
|
|
1874
|
-
throw new
|
|
1874
|
+
throw new QStashWorkflowError(
|
|
1875
1875
|
`There must be a last step and it should have targetStep larger than 0.Received: ${JSON.stringify(planStep)}`
|
|
1876
1876
|
);
|
|
1877
1877
|
}
|
|
@@ -1882,19 +1882,19 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1882
1882
|
parallelSteps.length,
|
|
1883
1883
|
planStep.targetStep
|
|
1884
1884
|
);
|
|
1885
|
-
await this.
|
|
1885
|
+
await this.submitStepsToQStash([resultStep]);
|
|
1886
1886
|
} catch (error) {
|
|
1887
|
-
if (error instanceof
|
|
1887
|
+
if (error instanceof QStashWorkflowAbort) {
|
|
1888
1888
|
throw error;
|
|
1889
1889
|
}
|
|
1890
|
-
throw new
|
|
1891
|
-
`Error submitting steps to
|
|
1890
|
+
throw new QStashWorkflowError(
|
|
1891
|
+
`Error submitting steps to QStash in partial parallel step execution: ${error}`
|
|
1892
1892
|
);
|
|
1893
1893
|
}
|
|
1894
1894
|
break;
|
|
1895
1895
|
}
|
|
1896
1896
|
case "discard": {
|
|
1897
|
-
throw new
|
|
1897
|
+
throw new QStashWorkflowAbort("discarded parallel");
|
|
1898
1898
|
}
|
|
1899
1899
|
case "last": {
|
|
1900
1900
|
const parallelResultSteps = sortedSteps.filter((step) => step.stepId >= initialStepCount).slice(0, parallelSteps.length);
|
|
@@ -1943,10 +1943,10 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1943
1943
|
*
|
|
1944
1944
|
* @param steps steps to send
|
|
1945
1945
|
*/
|
|
1946
|
-
async
|
|
1946
|
+
async submitStepsToQStash(steps) {
|
|
1947
1947
|
if (steps.length === 0) {
|
|
1948
|
-
throw new
|
|
1949
|
-
`Unable to submit steps to
|
|
1948
|
+
throw new QStashWorkflowError(
|
|
1949
|
+
`Unable to submit steps to QStash. Provided list is empty. Current step: ${this.stepCount}`
|
|
1950
1950
|
);
|
|
1951
1951
|
}
|
|
1952
1952
|
await _optionalChain([this, 'access', _61 => _61.debug, 'optionalAccess', _62 => _62.log, 'call', _63 => _63("SUBMIT", "SUBMIT_STEP", { length: steps.length, steps })]);
|
|
@@ -1956,7 +1956,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1956
1956
|
"false",
|
|
1957
1957
|
this.context.workflowRunId,
|
|
1958
1958
|
this.context.url,
|
|
1959
|
-
this.context.headers,
|
|
1959
|
+
singleStep.callUrl ? void 0 : this.context.headers,
|
|
1960
1960
|
singleStep,
|
|
1961
1961
|
this.context.failureUrl
|
|
1962
1962
|
);
|
|
@@ -1996,7 +1996,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
1996
1996
|
};
|
|
1997
1997
|
})
|
|
1998
1998
|
})]);
|
|
1999
|
-
throw new
|
|
1999
|
+
throw new QStashWorkflowAbort(steps[0].stepName, steps[0]);
|
|
2000
2000
|
}
|
|
2001
2001
|
/**
|
|
2002
2002
|
* Get the promise by executing the lazt steps list. If there is a single
|
|
@@ -2020,7 +2020,7 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
2020
2020
|
} else if (Array.isArray(result) && lazyStepList.length === result.length && index < lazyStepList.length) {
|
|
2021
2021
|
return result[index];
|
|
2022
2022
|
} else {
|
|
2023
|
-
throw new
|
|
2023
|
+
throw new QStashWorkflowError(
|
|
2024
2024
|
`Unexpected parallel call result while executing step ${index}: '${result}'. Expected ${lazyStepList.length} many items`
|
|
2025
2025
|
);
|
|
2026
2026
|
}
|
|
@@ -2032,12 +2032,12 @@ var AutoExecutor = (_class3 = class _AutoExecutor {
|
|
|
2032
2032
|
}, _class3);
|
|
2033
2033
|
var validateStep = (lazyStep, stepFromRequest) => {
|
|
2034
2034
|
if (lazyStep.stepName !== stepFromRequest.stepName) {
|
|
2035
|
-
throw new
|
|
2035
|
+
throw new QStashWorkflowError(
|
|
2036
2036
|
`Incompatible step name. Expected '${lazyStep.stepName}', got '${stepFromRequest.stepName}' from the request`
|
|
2037
2037
|
);
|
|
2038
2038
|
}
|
|
2039
2039
|
if (lazyStep.stepType !== stepFromRequest.stepType) {
|
|
2040
|
-
throw new
|
|
2040
|
+
throw new QStashWorkflowError(
|
|
2041
2041
|
`Incompatible step type. Expected '${lazyStep.stepType}', got '${stepFromRequest.stepType}' from the request`
|
|
2042
2042
|
);
|
|
2043
2043
|
}
|
|
@@ -2048,12 +2048,12 @@ var validateParallelSteps = (lazySteps, stepsFromRequest) => {
|
|
|
2048
2048
|
validateStep(lazySteps[index], stepFromRequest);
|
|
2049
2049
|
}
|
|
2050
2050
|
} catch (error) {
|
|
2051
|
-
if (error instanceof
|
|
2051
|
+
if (error instanceof QStashWorkflowError) {
|
|
2052
2052
|
const lazyStepNames = lazySteps.map((lazyStep) => lazyStep.stepName);
|
|
2053
2053
|
const lazyStepTypes = lazySteps.map((lazyStep) => lazyStep.stepType);
|
|
2054
2054
|
const requestStepNames = stepsFromRequest.map((step) => step.stepName);
|
|
2055
2055
|
const requestStepTypes = stepsFromRequest.map((step) => step.stepType);
|
|
2056
|
-
throw new
|
|
2056
|
+
throw new QStashWorkflowError(
|
|
2057
2057
|
`Incompatible steps detected in parallel execution: ${error.message}
|
|
2058
2058
|
> Step Names from the request: ${JSON.stringify(requestStepNames)}
|
|
2059
2059
|
Step Types from the request: ${JSON.stringify(requestStepTypes)}
|
|
@@ -2419,14 +2419,14 @@ var WorkflowContext = class {
|
|
|
2419
2419
|
var DisabledWorkflowContext = (_class8 = class _DisabledWorkflowContext extends WorkflowContext {
|
|
2420
2420
|
static __initStatic() {this.disabledMessage = "disabled-qstash-worklfow-run"}
|
|
2421
2421
|
/**
|
|
2422
|
-
* overwrite the WorkflowContext.addStep method to always raise
|
|
2422
|
+
* overwrite the WorkflowContext.addStep method to always raise QStashWorkflowAbort
|
|
2423
2423
|
* error in order to stop the execution whenever we encounter a step.
|
|
2424
2424
|
*
|
|
2425
2425
|
* @param _step
|
|
2426
2426
|
*/
|
|
2427
2427
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
2428
2428
|
async addStep(_step) {
|
|
2429
|
-
throw new
|
|
2429
|
+
throw new QStashWorkflowAbort(_DisabledWorkflowContext.disabledMessage);
|
|
2430
2430
|
}
|
|
2431
2431
|
/**
|
|
2432
2432
|
* copies the passed context to create a DisabledWorkflowContext. Then, runs the
|
|
@@ -2453,7 +2453,7 @@ var DisabledWorkflowContext = (_class8 = class _DisabledWorkflowContext extends
|
|
|
2453
2453
|
try {
|
|
2454
2454
|
await routeFunction(disabledContext);
|
|
2455
2455
|
} catch (error) {
|
|
2456
|
-
if (error instanceof
|
|
2456
|
+
if (error instanceof QStashWorkflowAbort && error.stepName === this.disabledMessage) {
|
|
2457
2457
|
return ok("step-found");
|
|
2458
2458
|
}
|
|
2459
2459
|
return err(error);
|
|
@@ -2600,7 +2600,7 @@ var checkIfLastOneIsDuplicate = async (steps, debug) => {
|
|
|
2600
2600
|
for (let index = 0; index < steps.length - 1; index++) {
|
|
2601
2601
|
const step = steps[index];
|
|
2602
2602
|
if (step.stepId === lastStepId && step.targetStep === lastTargetStepId) {
|
|
2603
|
-
const message = `
|
|
2603
|
+
const message = `QStash Workflow: The step '${step.stepName}' with id '${step.stepId}' has run twice during workflow execution. Rest of the workflow will continue running as usual.`;
|
|
2604
2604
|
await _optionalChain([debug, 'optionalAccess', _67 => _67.log, 'call', _68 => _68("WARN", "RESPONSE_DEFAULT", message)]);
|
|
2605
2605
|
console.warn(message);
|
|
2606
2606
|
return true;
|
|
@@ -2612,13 +2612,13 @@ var validateRequest = (request) => {
|
|
|
2612
2612
|
const versionHeader = request.headers.get(WORKFLOW_PROTOCOL_VERSION_HEADER);
|
|
2613
2613
|
const isFirstInvocation = !versionHeader;
|
|
2614
2614
|
if (!isFirstInvocation && versionHeader !== WORKFLOW_PROTOCOL_VERSION) {
|
|
2615
|
-
throw new
|
|
2615
|
+
throw new QStashWorkflowError(
|
|
2616
2616
|
`Incompatible workflow sdk protocol version. Expected ${WORKFLOW_PROTOCOL_VERSION}, got ${versionHeader} from the request.`
|
|
2617
2617
|
);
|
|
2618
2618
|
}
|
|
2619
2619
|
const workflowRunId = isFirstInvocation ? `wfr_${nanoid()}` : _nullishCoalesce(request.headers.get(WORKFLOW_ID_HEADER), () => ( ""));
|
|
2620
2620
|
if (workflowRunId.length === 0) {
|
|
2621
|
-
throw new
|
|
2621
|
+
throw new QStashWorkflowError("Couldn't get workflow id from header");
|
|
2622
2622
|
}
|
|
2623
2623
|
return {
|
|
2624
2624
|
isFirstInvocation,
|
|
@@ -2634,7 +2634,7 @@ var parseRequest = async (requestPayload, isFirstInvocation, debug) => {
|
|
|
2634
2634
|
};
|
|
2635
2635
|
} else {
|
|
2636
2636
|
if (!requestPayload) {
|
|
2637
|
-
throw new
|
|
2637
|
+
throw new QStashWorkflowError("Only first call can have an empty body");
|
|
2638
2638
|
}
|
|
2639
2639
|
const { rawInitialPayload, steps } = parsePayload(requestPayload);
|
|
2640
2640
|
const isLastDuplicate = await checkIfLastOneIsDuplicate(steps, debug);
|
|
@@ -2652,13 +2652,13 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2652
2652
|
}
|
|
2653
2653
|
if (!failureFunction) {
|
|
2654
2654
|
return err(
|
|
2655
|
-
new
|
|
2655
|
+
new QStashWorkflowError(
|
|
2656
2656
|
"Workflow endpoint is called to handle a failure, but a failureFunction is not provided in serve options. Either provide a failureUrl or a failureFunction."
|
|
2657
2657
|
)
|
|
2658
2658
|
);
|
|
2659
2659
|
}
|
|
2660
2660
|
try {
|
|
2661
|
-
const { status,
|
|
2661
|
+
const { status, header, body, url, sourceHeader, sourceBody, workflowRunId } = JSON.parse(
|
|
2662
2662
|
requestPayload
|
|
2663
2663
|
);
|
|
2664
2664
|
const decodedBody = body ? atob(body) : "{}";
|
|
@@ -2679,7 +2679,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2679
2679
|
failureUrl: url,
|
|
2680
2680
|
debug
|
|
2681
2681
|
});
|
|
2682
|
-
await failureFunction(workflowContext, status, errorPayload.message);
|
|
2682
|
+
await failureFunction(workflowContext, status, errorPayload.message, header);
|
|
2683
2683
|
} catch (error) {
|
|
2684
2684
|
return err(error);
|
|
2685
2685
|
}
|
|
@@ -2873,4 +2873,4 @@ var Workflow = class {
|
|
|
2873
2873
|
|
|
2874
2874
|
|
|
2875
2875
|
|
|
2876
|
-
exports.SignatureError = SignatureError; exports.Receiver = Receiver; exports.QstashError = QstashError; exports.QstashRatelimitError = QstashRatelimitError; exports.QstashChatRatelimitError = QstashChatRatelimitError; exports.QstashDailyRatelimitError = QstashDailyRatelimitError; exports.
|
|
2876
|
+
exports.SignatureError = SignatureError; exports.Receiver = Receiver; exports.QstashError = QstashError; exports.QstashRatelimitError = QstashRatelimitError; exports.QstashChatRatelimitError = QstashChatRatelimitError; exports.QstashDailyRatelimitError = QstashDailyRatelimitError; exports.QStashWorkflowError = QStashWorkflowError; exports.QStashWorkflowAbort = QStashWorkflowAbort; exports.formatWorkflowError = formatWorkflowError; exports.setupAnalytics = setupAnalytics; exports.upstash = upstash; exports.openai = openai; exports.custom = custom; exports.Chat = Chat; exports.Messages = Messages; exports.Schedules = Schedules; exports.UrlGroups = UrlGroups; exports.StepTypes = StepTypes; exports.WorkflowContext = WorkflowContext; exports.DisabledWorkflowContext = DisabledWorkflowContext; exports.WorkflowLogger = WorkflowLogger; exports.processOptions = processOptions; exports.serve = serve; exports.Workflow = Workflow; exports.Client = Client;
|