@upstash/workflow 0.2.1 → 0.2.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/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +248 -76
- package/astro.mjs +5 -5
- package/{chunk-ADOBNR4O.mjs → chunk-QBJ3LQIO.mjs} +222 -221
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +248 -76
- package/cloudflare.mjs +5 -5
- package/express.d.mts +1 -1
- package/express.d.ts +1 -1
- package/express.js +1620 -1305
- package/express.mjs +1395 -1252
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +248 -76
- package/h3.mjs +5 -5
- package/hono.d.mts +4 -2
- package/hono.d.ts +4 -2
- package/hono.js +248 -76
- package/hono.mjs +5 -5
- package/index.d.mts +3 -3
- package/index.d.ts +3 -3
- package/index.js +252 -74
- package/index.mjs +189 -3
- package/nextjs.d.mts +3 -3
- package/nextjs.d.ts +3 -3
- package/nextjs.js +249 -77
- package/nextjs.mjs +6 -6
- package/package.json +1 -1
- package/solidjs.d.mts +2 -2
- package/solidjs.d.ts +2 -2
- package/solidjs.js +248 -76
- package/solidjs.mjs +5 -5
- package/svelte.d.mts +3 -3
- package/svelte.d.ts +3 -3
- package/svelte.js +251 -76
- package/svelte.mjs +8 -5
- package/{types-Be4hC1mu.d.mts → types-R9q4MUwl.d.mts} +246 -12
- package/{types-Be4hC1mu.d.ts → types-R9q4MUwl.d.ts} +246 -12
package/index.js
CHANGED
|
@@ -20,7 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
-
Client: () =>
|
|
23
|
+
Client: () => Client4,
|
|
24
24
|
StepTypes: () => StepTypes,
|
|
25
25
|
WorkflowAbort: () => WorkflowAbort,
|
|
26
26
|
WorkflowContext: () => WorkflowContext,
|
|
@@ -30,48 +30,8 @@ __export(src_exports, {
|
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(src_exports);
|
|
32
32
|
|
|
33
|
-
// src/error.ts
|
|
34
|
-
var import_qstash = require("@upstash/qstash");
|
|
35
|
-
var WorkflowError = class extends import_qstash.QstashError {
|
|
36
|
-
constructor(message) {
|
|
37
|
-
super(message);
|
|
38
|
-
this.name = "WorkflowError";
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
var WorkflowAbort = class extends Error {
|
|
42
|
-
stepInfo;
|
|
43
|
-
stepName;
|
|
44
|
-
/**
|
|
45
|
-
* whether workflow is to be canceled on abort
|
|
46
|
-
*/
|
|
47
|
-
cancelWorkflow;
|
|
48
|
-
/**
|
|
49
|
-
*
|
|
50
|
-
* @param stepName name of the aborting step
|
|
51
|
-
* @param stepInfo step information
|
|
52
|
-
* @param cancelWorkflow
|
|
53
|
-
*/
|
|
54
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
55
|
-
super(
|
|
56
|
-
`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}'.`
|
|
57
|
-
);
|
|
58
|
-
this.name = "WorkflowAbort";
|
|
59
|
-
this.stepName = stepName;
|
|
60
|
-
this.stepInfo = stepInfo;
|
|
61
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
62
|
-
}
|
|
63
|
-
};
|
|
64
|
-
var formatWorkflowError = (error) => {
|
|
65
|
-
return error instanceof Error ? {
|
|
66
|
-
error: error.name,
|
|
67
|
-
message: error.message
|
|
68
|
-
} : {
|
|
69
|
-
error: "Error",
|
|
70
|
-
message: "An error occured while executing workflow."
|
|
71
|
-
};
|
|
72
|
-
};
|
|
73
|
-
|
|
74
33
|
// src/client/utils.ts
|
|
34
|
+
var import_qstash = require("@upstash/qstash");
|
|
75
35
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
76
36
|
const result = await requester.request({
|
|
77
37
|
path: ["v2", "notify", eventId],
|
|
@@ -105,26 +65,71 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
105
65
|
await debug?.log("INFO", "ENDPOINT_START", {
|
|
106
66
|
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
107
67
|
});
|
|
108
|
-
return steps;
|
|
68
|
+
return { steps, workflowRunEnded: false };
|
|
109
69
|
} else {
|
|
110
70
|
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
111
71
|
if (index === -1) {
|
|
112
|
-
return [];
|
|
72
|
+
return { steps: [], workflowRunEnded: false };
|
|
113
73
|
}
|
|
114
74
|
const filteredSteps = steps.slice(0, index + 1);
|
|
115
75
|
await debug?.log("INFO", "ENDPOINT_START", {
|
|
116
76
|
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
117
77
|
});
|
|
118
|
-
return filteredSteps;
|
|
78
|
+
return { steps: filteredSteps, workflowRunEnded: false };
|
|
119
79
|
}
|
|
120
80
|
} catch (error) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
81
|
+
if (error instanceof import_qstash.QstashError && error.status === 404) {
|
|
82
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
83
|
+
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
84
|
+
error
|
|
85
|
+
});
|
|
86
|
+
return { steps: void 0, workflowRunEnded: true };
|
|
87
|
+
} else {
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// src/error.ts
|
|
94
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
95
|
+
var WorkflowError = class extends import_qstash2.QstashError {
|
|
96
|
+
constructor(message) {
|
|
97
|
+
super(message);
|
|
98
|
+
this.name = "WorkflowError";
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
var WorkflowAbort = class extends Error {
|
|
102
|
+
stepInfo;
|
|
103
|
+
stepName;
|
|
104
|
+
/**
|
|
105
|
+
* whether workflow is to be canceled on abort
|
|
106
|
+
*/
|
|
107
|
+
cancelWorkflow;
|
|
108
|
+
/**
|
|
109
|
+
*
|
|
110
|
+
* @param stepName name of the aborting step
|
|
111
|
+
* @param stepInfo step information
|
|
112
|
+
* @param cancelWorkflow
|
|
113
|
+
*/
|
|
114
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
115
|
+
super(
|
|
116
|
+
`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}'.`
|
|
117
|
+
);
|
|
118
|
+
this.name = "WorkflowAbort";
|
|
119
|
+
this.stepName = stepName;
|
|
120
|
+
this.stepInfo = stepInfo;
|
|
121
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
126
122
|
}
|
|
127
123
|
};
|
|
124
|
+
var formatWorkflowError = (error) => {
|
|
125
|
+
return error instanceof Error ? {
|
|
126
|
+
error: error.name,
|
|
127
|
+
message: error.message
|
|
128
|
+
} : {
|
|
129
|
+
error: "Error",
|
|
130
|
+
message: "An error occured while executing workflow."
|
|
131
|
+
};
|
|
132
|
+
};
|
|
128
133
|
|
|
129
134
|
// src/context/steps.ts
|
|
130
135
|
var BaseLazyStep = class {
|
|
@@ -746,8 +751,8 @@ var StepTypes = [
|
|
|
746
751
|
];
|
|
747
752
|
|
|
748
753
|
// src/workflow-requests.ts
|
|
749
|
-
var
|
|
750
|
-
var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
754
|
+
var import_qstash3 = require("@upstash/qstash");
|
|
755
|
+
var triggerFirstInvocation = async (workflowContext, retries, useJSONContent, debug) => {
|
|
751
756
|
const { headers } = getHeaders(
|
|
752
757
|
"true",
|
|
753
758
|
workflowContext.workflowRunId,
|
|
@@ -757,6 +762,9 @@ var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
|
757
762
|
workflowContext.failureUrl,
|
|
758
763
|
retries
|
|
759
764
|
);
|
|
765
|
+
if (useJSONContent) {
|
|
766
|
+
headers["content-type"] = "application/json";
|
|
767
|
+
}
|
|
760
768
|
try {
|
|
761
769
|
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
762
770
|
const result = await workflowContext.qstashClient.publish({
|
|
@@ -800,7 +808,7 @@ var triggerRouteFunction = async ({
|
|
|
800
808
|
return ok("workflow-finished");
|
|
801
809
|
} catch (error) {
|
|
802
810
|
const error_ = error;
|
|
803
|
-
if (error instanceof
|
|
811
|
+
if (error instanceof import_qstash3.QstashError && error.status === 400) {
|
|
804
812
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
805
813
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
806
814
|
name: error.name,
|
|
@@ -834,7 +842,7 @@ var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
|
|
|
834
842
|
);
|
|
835
843
|
return { deleted: true };
|
|
836
844
|
} catch (error) {
|
|
837
|
-
if (error instanceof
|
|
845
|
+
if (error instanceof import_qstash3.QstashError && error.status === 404) {
|
|
838
846
|
await debug?.log("WARN", "SUBMIT_CLEANUP", {
|
|
839
847
|
message: `Failed to remove workflow run ${workflowContext.workflowRunId} as it doesn't exist.`,
|
|
840
848
|
name: error.name,
|
|
@@ -871,11 +879,19 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
|
|
|
871
879
|
if (!workflowRunId2)
|
|
872
880
|
throw new WorkflowError("workflow run id missing in context.call lazy fetch.");
|
|
873
881
|
if (!messageId) throw new WorkflowError("message id missing in context.call lazy fetch.");
|
|
874
|
-
const steps = await getSteps(
|
|
882
|
+
const { steps, workflowRunEnded } = await getSteps(
|
|
883
|
+
client.http,
|
|
884
|
+
workflowRunId2,
|
|
885
|
+
messageId,
|
|
886
|
+
debug
|
|
887
|
+
);
|
|
888
|
+
if (workflowRunEnded) {
|
|
889
|
+
return ok("workflow-ended");
|
|
890
|
+
}
|
|
875
891
|
const failingStep = steps.find((step) => step.messageId === messageId);
|
|
876
892
|
if (!failingStep)
|
|
877
893
|
throw new WorkflowError(
|
|
878
|
-
"Failed to submit the context.call." + (steps.length === 0 ? "No steps found." : `No step was found with matching messageId ${messageId} out of ${steps.length} steps.`)
|
|
894
|
+
"Failed to submit the context.call. " + (steps.length === 0 ? "No steps found." : `No step was found with matching messageId ${messageId} out of ${steps.length} steps.`)
|
|
879
895
|
);
|
|
880
896
|
callbackPayload = atob(failingStep.body);
|
|
881
897
|
}
|
|
@@ -1458,6 +1474,127 @@ var sortSteps = (steps) => {
|
|
|
1458
1474
|
return [...steps].sort((step, stepOther) => getStepId(step) - getStepId(stepOther));
|
|
1459
1475
|
};
|
|
1460
1476
|
|
|
1477
|
+
// src/context/api/anthropic.ts
|
|
1478
|
+
var import_qstash4 = require("@upstash/qstash");
|
|
1479
|
+
|
|
1480
|
+
// src/context/provider.ts
|
|
1481
|
+
var getProviderInfo = (api) => {
|
|
1482
|
+
if (!api.provider) {
|
|
1483
|
+
throw new WorkflowError("A Provider must be provided.");
|
|
1484
|
+
}
|
|
1485
|
+
if (api.provider.owner === "upstash") {
|
|
1486
|
+
throw new WorkflowError("Upstash provider isn't supported.");
|
|
1487
|
+
}
|
|
1488
|
+
const { name, provider, ...parameters } = api;
|
|
1489
|
+
if (!provider.baseUrl) throw new TypeError("baseUrl cannot be empty or undefined!");
|
|
1490
|
+
if (!provider.token) throw new TypeError("token cannot be empty or undefined!");
|
|
1491
|
+
if (provider.apiKind !== name) {
|
|
1492
|
+
throw new TypeError(`Unexpected api name. Expected '${provider.apiKind}', received ${name}`);
|
|
1493
|
+
}
|
|
1494
|
+
const providerInfo = {
|
|
1495
|
+
url: provider.getUrl(),
|
|
1496
|
+
baseUrl: provider.baseUrl,
|
|
1497
|
+
route: provider.getRoute(),
|
|
1498
|
+
appendHeaders: provider.getHeaders(parameters),
|
|
1499
|
+
owner: provider.owner,
|
|
1500
|
+
method: provider.method
|
|
1501
|
+
};
|
|
1502
|
+
return provider.onFinish(providerInfo, parameters);
|
|
1503
|
+
};
|
|
1504
|
+
|
|
1505
|
+
// src/context/api/base.ts
|
|
1506
|
+
var BaseWorkflowApi = class {
|
|
1507
|
+
context;
|
|
1508
|
+
constructor({ context }) {
|
|
1509
|
+
this.context = context;
|
|
1510
|
+
}
|
|
1511
|
+
/**
|
|
1512
|
+
* context.call which uses a QStash API
|
|
1513
|
+
*
|
|
1514
|
+
* @param stepName
|
|
1515
|
+
* @param settings
|
|
1516
|
+
* @returns
|
|
1517
|
+
*/
|
|
1518
|
+
async callApi(stepName, settings) {
|
|
1519
|
+
const { url, appendHeaders, method } = getProviderInfo(settings.api);
|
|
1520
|
+
const { method: userMethod, body, headers = {}, retries = 0, timeout } = settings;
|
|
1521
|
+
return await this.context.call(stepName, {
|
|
1522
|
+
url,
|
|
1523
|
+
method: userMethod ?? method,
|
|
1524
|
+
body,
|
|
1525
|
+
headers: {
|
|
1526
|
+
...appendHeaders,
|
|
1527
|
+
...headers
|
|
1528
|
+
},
|
|
1529
|
+
retries,
|
|
1530
|
+
timeout
|
|
1531
|
+
});
|
|
1532
|
+
}
|
|
1533
|
+
};
|
|
1534
|
+
|
|
1535
|
+
// src/context/api/anthropic.ts
|
|
1536
|
+
var AnthropicAPI = class extends BaseWorkflowApi {
|
|
1537
|
+
async call(stepName, settings) {
|
|
1538
|
+
const { token, operation, ...parameters } = settings;
|
|
1539
|
+
return await this.callApi(stepName, {
|
|
1540
|
+
api: {
|
|
1541
|
+
name: "llm",
|
|
1542
|
+
provider: (0, import_qstash4.anthropic)({ token })
|
|
1543
|
+
},
|
|
1544
|
+
...parameters
|
|
1545
|
+
});
|
|
1546
|
+
}
|
|
1547
|
+
};
|
|
1548
|
+
|
|
1549
|
+
// src/context/api/openai.ts
|
|
1550
|
+
var import_qstash5 = require("@upstash/qstash");
|
|
1551
|
+
var OpenAIAPI = class extends BaseWorkflowApi {
|
|
1552
|
+
async call(stepName, settings) {
|
|
1553
|
+
const { token, organization, operation, ...parameters } = settings;
|
|
1554
|
+
return await this.callApi(stepName, {
|
|
1555
|
+
api: {
|
|
1556
|
+
name: "llm",
|
|
1557
|
+
provider: (0, import_qstash5.openai)({ token, organization })
|
|
1558
|
+
},
|
|
1559
|
+
...parameters
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1563
|
+
|
|
1564
|
+
// src/context/api/resend.ts
|
|
1565
|
+
var import_qstash6 = require("@upstash/qstash");
|
|
1566
|
+
var ResendAPI = class extends BaseWorkflowApi {
|
|
1567
|
+
async call(stepName, settings) {
|
|
1568
|
+
const { token, batch = false, ...parameters } = settings;
|
|
1569
|
+
return await this.callApi(stepName, {
|
|
1570
|
+
api: {
|
|
1571
|
+
name: "email",
|
|
1572
|
+
provider: (0, import_qstash6.resend)({ token, batch })
|
|
1573
|
+
},
|
|
1574
|
+
...parameters
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
};
|
|
1578
|
+
|
|
1579
|
+
// src/context/api/index.ts
|
|
1580
|
+
var WorkflowApi = class extends BaseWorkflowApi {
|
|
1581
|
+
get openai() {
|
|
1582
|
+
return new OpenAIAPI({
|
|
1583
|
+
context: this.context
|
|
1584
|
+
});
|
|
1585
|
+
}
|
|
1586
|
+
get resend() {
|
|
1587
|
+
return new ResendAPI({
|
|
1588
|
+
context: this.context
|
|
1589
|
+
});
|
|
1590
|
+
}
|
|
1591
|
+
get anthropic() {
|
|
1592
|
+
return new AnthropicAPI({
|
|
1593
|
+
context: this.context
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
};
|
|
1597
|
+
|
|
1461
1598
|
// src/context/context.ts
|
|
1462
1599
|
var WorkflowContext = class {
|
|
1463
1600
|
executor;
|
|
@@ -1837,6 +1974,11 @@ var WorkflowContext = class {
|
|
|
1837
1974
|
async addStep(step) {
|
|
1838
1975
|
return await this.executor.addStep(step);
|
|
1839
1976
|
}
|
|
1977
|
+
get api() {
|
|
1978
|
+
return new WorkflowApi({
|
|
1979
|
+
context: this
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1840
1982
|
};
|
|
1841
1983
|
|
|
1842
1984
|
// src/logger.ts
|
|
@@ -1914,7 +2056,7 @@ function decodeBase64(base64) {
|
|
|
1914
2056
|
}
|
|
1915
2057
|
|
|
1916
2058
|
// src/serve/authorization.ts
|
|
1917
|
-
var
|
|
2059
|
+
var import_qstash7 = require("@upstash/qstash");
|
|
1918
2060
|
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
1919
2061
|
static disabledMessage = "disabled-qstash-worklfow-run";
|
|
1920
2062
|
/**
|
|
@@ -1945,7 +2087,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
1945
2087
|
*/
|
|
1946
2088
|
static async tryAuthentication(routeFunction, context) {
|
|
1947
2089
|
const disabledContext = new _DisabledWorkflowContext({
|
|
1948
|
-
qstashClient: new
|
|
2090
|
+
qstashClient: new import_qstash7.Client({
|
|
1949
2091
|
baseUrl: "disabled-client",
|
|
1950
2092
|
token: "disabled-client"
|
|
1951
2093
|
}),
|
|
@@ -2069,7 +2211,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2069
2211
|
return {
|
|
2070
2212
|
rawInitialPayload: requestPayload ?? "",
|
|
2071
2213
|
steps: [],
|
|
2072
|
-
isLastDuplicate: false
|
|
2214
|
+
isLastDuplicate: false,
|
|
2215
|
+
workflowRunEnded: false
|
|
2073
2216
|
};
|
|
2074
2217
|
} else {
|
|
2075
2218
|
let rawSteps;
|
|
@@ -2079,7 +2222,21 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2079
2222
|
"ENDPOINT_START",
|
|
2080
2223
|
"request payload is empty, steps will be fetched from QStash."
|
|
2081
2224
|
);
|
|
2082
|
-
|
|
2225
|
+
const { steps: fetchedSteps, workflowRunEnded } = await getSteps(
|
|
2226
|
+
requester,
|
|
2227
|
+
workflowRunId,
|
|
2228
|
+
messageId,
|
|
2229
|
+
debug
|
|
2230
|
+
);
|
|
2231
|
+
if (workflowRunEnded) {
|
|
2232
|
+
return {
|
|
2233
|
+
rawInitialPayload: void 0,
|
|
2234
|
+
steps: void 0,
|
|
2235
|
+
isLastDuplicate: void 0,
|
|
2236
|
+
workflowRunEnded: true
|
|
2237
|
+
};
|
|
2238
|
+
}
|
|
2239
|
+
rawSteps = fetchedSteps;
|
|
2083
2240
|
} else {
|
|
2084
2241
|
rawSteps = JSON.parse(requestPayload);
|
|
2085
2242
|
}
|
|
@@ -2089,7 +2246,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2089
2246
|
return {
|
|
2090
2247
|
rawInitialPayload,
|
|
2091
2248
|
steps: deduplicatedSteps,
|
|
2092
|
-
isLastDuplicate
|
|
2249
|
+
isLastDuplicate,
|
|
2250
|
+
workflowRunEnded: false
|
|
2093
2251
|
};
|
|
2094
2252
|
}
|
|
2095
2253
|
};
|
|
@@ -2143,15 +2301,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2143
2301
|
};
|
|
2144
2302
|
|
|
2145
2303
|
// src/serve/options.ts
|
|
2146
|
-
var
|
|
2147
|
-
var
|
|
2304
|
+
var import_qstash8 = require("@upstash/qstash");
|
|
2305
|
+
var import_qstash9 = require("@upstash/qstash");
|
|
2148
2306
|
var processOptions = (options) => {
|
|
2149
2307
|
const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
|
|
2150
2308
|
const receiverEnvironmentVariablesSet = Boolean(
|
|
2151
2309
|
environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
|
|
2152
2310
|
);
|
|
2153
2311
|
return {
|
|
2154
|
-
qstashClient: new
|
|
2312
|
+
qstashClient: new import_qstash9.Client({
|
|
2155
2313
|
baseUrl: environment.QSTASH_URL,
|
|
2156
2314
|
token: environment.QSTASH_TOKEN
|
|
2157
2315
|
}),
|
|
@@ -2185,13 +2343,14 @@ var processOptions = (options) => {
|
|
|
2185
2343
|
throw error;
|
|
2186
2344
|
}
|
|
2187
2345
|
},
|
|
2188
|
-
receiver: receiverEnvironmentVariablesSet ? new
|
|
2346
|
+
receiver: receiverEnvironmentVariablesSet ? new import_qstash8.Receiver({
|
|
2189
2347
|
currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
|
|
2190
2348
|
nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
|
|
2191
2349
|
}) : void 0,
|
|
2192
2350
|
baseUrl: environment.UPSTASH_WORKFLOW_URL,
|
|
2193
2351
|
env: environment,
|
|
2194
2352
|
retries: DEFAULT_RETRIES,
|
|
2353
|
+
useJSONContent: false,
|
|
2195
2354
|
...options
|
|
2196
2355
|
};
|
|
2197
2356
|
};
|
|
@@ -2208,6 +2367,16 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
|
|
|
2208
2367
|
});
|
|
2209
2368
|
}
|
|
2210
2369
|
const workflowFailureUrl = failureFunction ? workflowUrl : failureUrl;
|
|
2370
|
+
if (workflowUrl.includes("localhost")) {
|
|
2371
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
2372
|
+
message: `Workflow URL contains localhost. This can happen in local development, but shouldn't happen in production unless you have a route which contains localhost. Received: ${workflowUrl}`
|
|
2373
|
+
});
|
|
2374
|
+
}
|
|
2375
|
+
if (!(workflowUrl.startsWith("http://") || workflowUrl.startsWith("https://"))) {
|
|
2376
|
+
throw new WorkflowError(
|
|
2377
|
+
`Workflow URL should start with 'http://' or 'https://'. Recevied is '${workflowUrl}'`
|
|
2378
|
+
);
|
|
2379
|
+
}
|
|
2211
2380
|
return {
|
|
2212
2381
|
workflowUrl,
|
|
2213
2382
|
workflowFailureUrl
|
|
@@ -2216,7 +2385,7 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
|
|
|
2216
2385
|
var AUTH_FAIL_MESSAGE = `Failed to authenticate Workflow request. If this is unexpected, see the caveat https://upstash.com/docs/workflow/basics/caveats#avoid-non-deterministic-code-outside-context-run`;
|
|
2217
2386
|
|
|
2218
2387
|
// src/serve/index.ts
|
|
2219
|
-
var
|
|
2388
|
+
var serveBase = (routeFunction, options) => {
|
|
2220
2389
|
const {
|
|
2221
2390
|
qstashClient,
|
|
2222
2391
|
onStepFinish,
|
|
@@ -2228,7 +2397,8 @@ var serve = (routeFunction, options) => {
|
|
|
2228
2397
|
failureFunction,
|
|
2229
2398
|
baseUrl,
|
|
2230
2399
|
env,
|
|
2231
|
-
retries
|
|
2400
|
+
retries,
|
|
2401
|
+
useJSONContent
|
|
2232
2402
|
} = processOptions(options);
|
|
2233
2403
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
2234
2404
|
const handler = async (request) => {
|
|
@@ -2245,7 +2415,7 @@ var serve = (routeFunction, options) => {
|
|
|
2245
2415
|
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
|
|
2246
2416
|
const { isFirstInvocation, workflowRunId } = validateRequest(request);
|
|
2247
2417
|
debug?.setWorkflowRunId(workflowRunId);
|
|
2248
|
-
const { rawInitialPayload, steps, isLastDuplicate } = await parseRequest(
|
|
2418
|
+
const { rawInitialPayload, steps, isLastDuplicate, workflowRunEnded } = await parseRequest(
|
|
2249
2419
|
requestPayload,
|
|
2250
2420
|
isFirstInvocation,
|
|
2251
2421
|
workflowRunId,
|
|
@@ -2253,8 +2423,11 @@ var serve = (routeFunction, options) => {
|
|
|
2253
2423
|
request.headers.get("upstash-message-id"),
|
|
2254
2424
|
debug
|
|
2255
2425
|
);
|
|
2426
|
+
if (workflowRunEnded) {
|
|
2427
|
+
return onStepFinish(workflowRunId, "workflow-already-ended");
|
|
2428
|
+
}
|
|
2256
2429
|
if (isLastDuplicate) {
|
|
2257
|
-
return onStepFinish(
|
|
2430
|
+
return onStepFinish(workflowRunId, "duplicate-step");
|
|
2258
2431
|
}
|
|
2259
2432
|
const failureCheck = await handleFailure(
|
|
2260
2433
|
request,
|
|
@@ -2268,7 +2441,7 @@ var serve = (routeFunction, options) => {
|
|
|
2268
2441
|
throw failureCheck.error;
|
|
2269
2442
|
} else if (failureCheck.value === "is-failure-callback") {
|
|
2270
2443
|
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
2271
|
-
return onStepFinish(
|
|
2444
|
+
return onStepFinish(workflowRunId, "failure-callback");
|
|
2272
2445
|
}
|
|
2273
2446
|
const workflowContext = new WorkflowContext({
|
|
2274
2447
|
qstashClient,
|
|
@@ -2311,7 +2484,7 @@ var serve = (routeFunction, options) => {
|
|
|
2311
2484
|
});
|
|
2312
2485
|
throw callReturnCheck.error;
|
|
2313
2486
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
2314
|
-
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, debug) : await triggerRouteFunction({
|
|
2487
|
+
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, useJSONContent, debug) : await triggerRouteFunction({
|
|
2315
2488
|
onStep: async () => routeFunction(workflowContext),
|
|
2316
2489
|
onCleanup: async () => {
|
|
2317
2490
|
await triggerWorkflowDelete(workflowContext, debug);
|
|
@@ -2327,6 +2500,8 @@ var serve = (routeFunction, options) => {
|
|
|
2327
2500
|
}
|
|
2328
2501
|
await debug?.log("INFO", "RESPONSE_WORKFLOW");
|
|
2329
2502
|
return onStepFinish(workflowContext.workflowRunId, "success");
|
|
2503
|
+
} else if (callReturnCheck.value === "workflow-ended") {
|
|
2504
|
+
return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended");
|
|
2330
2505
|
}
|
|
2331
2506
|
await debug?.log("INFO", "RESPONSE_DEFAULT");
|
|
2332
2507
|
return onStepFinish("no-workflow-id", "fromCallback");
|
|
@@ -2343,10 +2518,13 @@ var serve = (routeFunction, options) => {
|
|
|
2343
2518
|
};
|
|
2344
2519
|
return { handler: safeHandler };
|
|
2345
2520
|
};
|
|
2521
|
+
var serve = (routeFunction, options) => {
|
|
2522
|
+
return serveBase(routeFunction, options);
|
|
2523
|
+
};
|
|
2346
2524
|
|
|
2347
2525
|
// src/client/index.ts
|
|
2348
|
-
var
|
|
2349
|
-
var
|
|
2526
|
+
var import_qstash10 = require("@upstash/qstash");
|
|
2527
|
+
var Client4 = class {
|
|
2350
2528
|
client;
|
|
2351
2529
|
constructor(clientConfig) {
|
|
2352
2530
|
if (!clientConfig.token) {
|
|
@@ -2354,7 +2532,7 @@ var Client3 = class {
|
|
|
2354
2532
|
"QStash token is required for Upstash Workflow!\n\nTo fix this:\n1. Get your token from the Upstash Console (https://console.upstash.com/qstash)\n2. Initialize the workflow client with:\n\n const client = new Client({\n token: '<YOUR_QSTASH_TOKEN>'\n });"
|
|
2355
2533
|
);
|
|
2356
2534
|
}
|
|
2357
|
-
this.client = new
|
|
2535
|
+
this.client = new import_qstash10.Client(clientConfig);
|
|
2358
2536
|
}
|
|
2359
2537
|
/**
|
|
2360
2538
|
* Cancel an ongoing workflow
|