@upstash/workflow 0.2.0 → 0.2.2
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 +175 -88
- package/astro.mjs +5 -5
- package/{chunk-5R2BFC3N.mjs → chunk-Z7WS5XIR.mjs} +150 -234
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +175 -88
- package/cloudflare.mjs +5 -5
- package/express.d.mts +1 -1
- package/express.d.ts +1 -1
- package/express.js +187 -93
- package/express.mjs +17 -10
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +175 -88
- package/h3.mjs +5 -5
- package/hono.d.mts +4 -2
- package/hono.d.ts +4 -2
- package/hono.js +175 -88
- package/hono.mjs +5 -5
- package/index.d.mts +3 -3
- package/index.d.ts +3 -3
- package/index.js +179 -86
- package/index.mjs +189 -3
- package/nextjs.d.mts +3 -3
- package/nextjs.d.ts +3 -3
- package/nextjs.js +179 -92
- package/nextjs.mjs +9 -9
- package/package.json +1 -1
- package/solidjs.d.mts +2 -2
- package/solidjs.d.ts +2 -2
- package/solidjs.js +175 -88
- package/solidjs.mjs +5 -5
- package/svelte.d.mts +3 -3
- package/svelte.d.ts +3 -3
- package/svelte.js +178 -88
- package/svelte.mjs +8 -5
- package/{types-Cki_MHrh.d.mts → types-APRap-aV.d.mts} +12 -2
- package/{types-Cki_MHrh.d.ts → types-APRap-aV.d.ts} +12 -2
package/express.js
CHANGED
|
@@ -23556,52 +23556,12 @@ var require_express2 = __commonJS({
|
|
|
23556
23556
|
// platforms/express.ts
|
|
23557
23557
|
var express_exports = {};
|
|
23558
23558
|
__export(express_exports, {
|
|
23559
|
-
serve: () =>
|
|
23559
|
+
serve: () => serve
|
|
23560
23560
|
});
|
|
23561
23561
|
module.exports = __toCommonJS(express_exports);
|
|
23562
23562
|
|
|
23563
|
-
// src/error.ts
|
|
23564
|
-
var import_qstash = require("@upstash/qstash");
|
|
23565
|
-
var WorkflowError = class extends import_qstash.QstashError {
|
|
23566
|
-
constructor(message) {
|
|
23567
|
-
super(message);
|
|
23568
|
-
this.name = "WorkflowError";
|
|
23569
|
-
}
|
|
23570
|
-
};
|
|
23571
|
-
var WorkflowAbort = class extends Error {
|
|
23572
|
-
stepInfo;
|
|
23573
|
-
stepName;
|
|
23574
|
-
/**
|
|
23575
|
-
* whether workflow is to be canceled on abort
|
|
23576
|
-
*/
|
|
23577
|
-
cancelWorkflow;
|
|
23578
|
-
/**
|
|
23579
|
-
*
|
|
23580
|
-
* @param stepName name of the aborting step
|
|
23581
|
-
* @param stepInfo step information
|
|
23582
|
-
* @param cancelWorkflow
|
|
23583
|
-
*/
|
|
23584
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
23585
|
-
super(
|
|
23586
|
-
`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}'.`
|
|
23587
|
-
);
|
|
23588
|
-
this.name = "WorkflowAbort";
|
|
23589
|
-
this.stepName = stepName;
|
|
23590
|
-
this.stepInfo = stepInfo;
|
|
23591
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
23592
|
-
}
|
|
23593
|
-
};
|
|
23594
|
-
var formatWorkflowError = (error) => {
|
|
23595
|
-
return error instanceof Error ? {
|
|
23596
|
-
error: error.name,
|
|
23597
|
-
message: error.message
|
|
23598
|
-
} : {
|
|
23599
|
-
error: "Error",
|
|
23600
|
-
message: "An error occured while executing workflow."
|
|
23601
|
-
};
|
|
23602
|
-
};
|
|
23603
|
-
|
|
23604
23563
|
// src/client/utils.ts
|
|
23564
|
+
var import_qstash = require("@upstash/qstash");
|
|
23605
23565
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
23606
23566
|
const result = await requester.request({
|
|
23607
23567
|
path: ["v2", "notify", eventId],
|
|
@@ -23628,32 +23588,82 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
23628
23588
|
await debug?.log("INFO", "ENDPOINT_START", {
|
|
23629
23589
|
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
23630
23590
|
});
|
|
23631
|
-
return steps;
|
|
23591
|
+
return { steps, workflowRunEnded: false };
|
|
23632
23592
|
} else {
|
|
23633
23593
|
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
23634
23594
|
if (index === -1) {
|
|
23635
|
-
return [];
|
|
23595
|
+
return { steps: [], workflowRunEnded: false };
|
|
23636
23596
|
}
|
|
23637
23597
|
const filteredSteps = steps.slice(0, index + 1);
|
|
23638
23598
|
await debug?.log("INFO", "ENDPOINT_START", {
|
|
23639
23599
|
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
23640
23600
|
});
|
|
23641
|
-
return filteredSteps;
|
|
23601
|
+
return { steps: filteredSteps, workflowRunEnded: false };
|
|
23642
23602
|
}
|
|
23643
23603
|
} catch (error) {
|
|
23644
|
-
|
|
23645
|
-
|
|
23646
|
-
|
|
23647
|
-
|
|
23648
|
-
|
|
23604
|
+
if (error instanceof import_qstash.QstashError && error.status === 404) {
|
|
23605
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
23606
|
+
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
23607
|
+
error
|
|
23608
|
+
});
|
|
23609
|
+
return { steps: void 0, workflowRunEnded: true };
|
|
23610
|
+
} else {
|
|
23611
|
+
throw error;
|
|
23612
|
+
}
|
|
23649
23613
|
}
|
|
23650
23614
|
};
|
|
23651
23615
|
|
|
23616
|
+
// src/error.ts
|
|
23617
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
23618
|
+
var WorkflowError = class extends import_qstash2.QstashError {
|
|
23619
|
+
constructor(message) {
|
|
23620
|
+
super(message);
|
|
23621
|
+
this.name = "WorkflowError";
|
|
23622
|
+
}
|
|
23623
|
+
};
|
|
23624
|
+
var WorkflowAbort = class extends Error {
|
|
23625
|
+
stepInfo;
|
|
23626
|
+
stepName;
|
|
23627
|
+
/**
|
|
23628
|
+
* whether workflow is to be canceled on abort
|
|
23629
|
+
*/
|
|
23630
|
+
cancelWorkflow;
|
|
23631
|
+
/**
|
|
23632
|
+
*
|
|
23633
|
+
* @param stepName name of the aborting step
|
|
23634
|
+
* @param stepInfo step information
|
|
23635
|
+
* @param cancelWorkflow
|
|
23636
|
+
*/
|
|
23637
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
23638
|
+
super(
|
|
23639
|
+
`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}'.`
|
|
23640
|
+
);
|
|
23641
|
+
this.name = "WorkflowAbort";
|
|
23642
|
+
this.stepName = stepName;
|
|
23643
|
+
this.stepInfo = stepInfo;
|
|
23644
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
23645
|
+
}
|
|
23646
|
+
};
|
|
23647
|
+
var formatWorkflowError = (error) => {
|
|
23648
|
+
return error instanceof Error ? {
|
|
23649
|
+
error: error.name,
|
|
23650
|
+
message: error.message
|
|
23651
|
+
} : {
|
|
23652
|
+
error: "Error",
|
|
23653
|
+
message: "An error occured while executing workflow."
|
|
23654
|
+
};
|
|
23655
|
+
};
|
|
23656
|
+
|
|
23652
23657
|
// src/context/steps.ts
|
|
23653
23658
|
var BaseLazyStep = class {
|
|
23654
23659
|
stepName;
|
|
23655
23660
|
// will be set in the subclasses
|
|
23656
23661
|
constructor(stepName) {
|
|
23662
|
+
if (!stepName) {
|
|
23663
|
+
throw new WorkflowError(
|
|
23664
|
+
"A workflow step name cannot be undefined or an empty string. Please provide a name for your workflow step."
|
|
23665
|
+
);
|
|
23666
|
+
}
|
|
23657
23667
|
this.stepName = stepName;
|
|
23658
23668
|
}
|
|
23659
23669
|
};
|
|
@@ -23746,15 +23756,17 @@ var LazyCallStep = class extends BaseLazyStep {
|
|
|
23746
23756
|
method;
|
|
23747
23757
|
body;
|
|
23748
23758
|
headers;
|
|
23749
|
-
stepType = "Call";
|
|
23750
23759
|
retries;
|
|
23751
|
-
|
|
23760
|
+
timeout;
|
|
23761
|
+
stepType = "Call";
|
|
23762
|
+
constructor(stepName, url, method, body, headers, retries, timeout) {
|
|
23752
23763
|
super(stepName);
|
|
23753
23764
|
this.url = url;
|
|
23754
23765
|
this.method = method;
|
|
23755
23766
|
this.body = body;
|
|
23756
23767
|
this.headers = headers;
|
|
23757
23768
|
this.retries = retries;
|
|
23769
|
+
this.timeout = timeout;
|
|
23758
23770
|
}
|
|
23759
23771
|
getPlanStep(concurrent, targetStep) {
|
|
23760
23772
|
return {
|
|
@@ -24262,8 +24274,8 @@ var StepTypes = [
|
|
|
24262
24274
|
];
|
|
24263
24275
|
|
|
24264
24276
|
// src/workflow-requests.ts
|
|
24265
|
-
var
|
|
24266
|
-
var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
24277
|
+
var import_qstash3 = require("@upstash/qstash");
|
|
24278
|
+
var triggerFirstInvocation = async (workflowContext, retries, useJSONContent, debug) => {
|
|
24267
24279
|
const { headers } = getHeaders(
|
|
24268
24280
|
"true",
|
|
24269
24281
|
workflowContext.workflowRunId,
|
|
@@ -24273,6 +24285,9 @@ var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
|
24273
24285
|
workflowContext.failureUrl,
|
|
24274
24286
|
retries
|
|
24275
24287
|
);
|
|
24288
|
+
if (useJSONContent) {
|
|
24289
|
+
headers["content-type"] = "application/json";
|
|
24290
|
+
}
|
|
24276
24291
|
try {
|
|
24277
24292
|
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
24278
24293
|
const result = await workflowContext.qstashClient.publish({
|
|
@@ -24316,7 +24331,7 @@ var triggerRouteFunction = async ({
|
|
|
24316
24331
|
return ok("workflow-finished");
|
|
24317
24332
|
} catch (error) {
|
|
24318
24333
|
const error_ = error;
|
|
24319
|
-
if (error instanceof
|
|
24334
|
+
if (error instanceof import_qstash3.QstashError && error.status === 400) {
|
|
24320
24335
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
24321
24336
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
24322
24337
|
name: error.name,
|
|
@@ -24350,7 +24365,7 @@ var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
|
|
|
24350
24365
|
);
|
|
24351
24366
|
return { deleted: true };
|
|
24352
24367
|
} catch (error) {
|
|
24353
|
-
if (error instanceof
|
|
24368
|
+
if (error instanceof import_qstash3.QstashError && error.status === 404) {
|
|
24354
24369
|
await debug?.log("WARN", "SUBMIT_CLEANUP", {
|
|
24355
24370
|
message: `Failed to remove workflow run ${workflowContext.workflowRunId} as it doesn't exist.`,
|
|
24356
24371
|
name: error.name,
|
|
@@ -24366,7 +24381,10 @@ var recreateUserHeaders = (headers) => {
|
|
|
24366
24381
|
const pairs = headers.entries();
|
|
24367
24382
|
for (const [header, value] of pairs) {
|
|
24368
24383
|
const headerLowerCase = header.toLowerCase();
|
|
24369
|
-
if (!headerLowerCase.startsWith("upstash-workflow-") &&
|
|
24384
|
+
if (!headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
|
|
24385
|
+
!headerLowerCase.startsWith("x-vercel-") && !headerLowerCase.startsWith("x-forwarded-") && // https://blog.cloudflare.com/preventing-request-loops-using-cdn-loop/
|
|
24386
|
+
headerLowerCase !== "cf-connecting-ip" && headerLowerCase !== "cdn-loop" && headerLowerCase !== "cf-ew-via" && headerLowerCase !== "cf-ray" && // For Render https://render.com
|
|
24387
|
+
headerLowerCase !== "render-proxy-ttl") {
|
|
24370
24388
|
filteredHeaders.append(header, value);
|
|
24371
24389
|
}
|
|
24372
24390
|
}
|
|
@@ -24384,11 +24402,19 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
|
|
|
24384
24402
|
if (!workflowRunId2)
|
|
24385
24403
|
throw new WorkflowError("workflow run id missing in context.call lazy fetch.");
|
|
24386
24404
|
if (!messageId) throw new WorkflowError("message id missing in context.call lazy fetch.");
|
|
24387
|
-
const steps = await getSteps(
|
|
24405
|
+
const { steps, workflowRunEnded } = await getSteps(
|
|
24406
|
+
client.http,
|
|
24407
|
+
workflowRunId2,
|
|
24408
|
+
messageId,
|
|
24409
|
+
debug
|
|
24410
|
+
);
|
|
24411
|
+
if (workflowRunEnded) {
|
|
24412
|
+
return ok("workflow-ended");
|
|
24413
|
+
}
|
|
24388
24414
|
const failingStep = steps.find((step) => step.messageId === messageId);
|
|
24389
24415
|
if (!failingStep)
|
|
24390
24416
|
throw new WorkflowError(
|
|
24391
|
-
"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.`)
|
|
24417
|
+
"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.`)
|
|
24392
24418
|
);
|
|
24393
24419
|
callbackPayload = atob(failingStep.body);
|
|
24394
24420
|
}
|
|
@@ -24469,7 +24495,7 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
24469
24495
|
);
|
|
24470
24496
|
}
|
|
24471
24497
|
};
|
|
24472
|
-
var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step, failureUrl, retries, callRetries) => {
|
|
24498
|
+
var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step, failureUrl, retries, callRetries, callTimeout) => {
|
|
24473
24499
|
const baseHeaders = {
|
|
24474
24500
|
[WORKFLOW_INIT_HEADER]: initHeaderValue,
|
|
24475
24501
|
[WORKFLOW_ID_HEADER]: workflowRunId,
|
|
@@ -24479,6 +24505,9 @@ var getHeaders = (initHeaderValue, workflowRunId, workflowUrl, userHeaders, step
|
|
|
24479
24505
|
if (!step?.callUrl) {
|
|
24480
24506
|
baseHeaders[`Upstash-Forward-${WORKFLOW_PROTOCOL_VERSION_HEADER}`] = WORKFLOW_PROTOCOL_VERSION;
|
|
24481
24507
|
}
|
|
24508
|
+
if (callTimeout) {
|
|
24509
|
+
baseHeaders[`Upstash-Timeout`] = callTimeout.toString();
|
|
24510
|
+
}
|
|
24482
24511
|
if (failureUrl) {
|
|
24483
24512
|
baseHeaders[`Upstash-Failure-Callback-Forward-${WORKFLOW_FAILURE_HEADER}`] = "true";
|
|
24484
24513
|
if (!step?.callUrl) {
|
|
@@ -24854,7 +24883,8 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
24854
24883
|
singleStep,
|
|
24855
24884
|
this.context.failureUrl,
|
|
24856
24885
|
this.context.retries,
|
|
24857
|
-
lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0
|
|
24886
|
+
lazyStep instanceof LazyCallStep ? lazyStep.retries : void 0,
|
|
24887
|
+
lazyStep instanceof LazyCallStep ? lazyStep.timeout : void 0
|
|
24858
24888
|
);
|
|
24859
24889
|
const willWait = singleStep.concurrent === NO_CONCURRENCY || singleStep.stepId === 0;
|
|
24860
24890
|
singleStep.out = JSON.stringify(singleStep.out);
|
|
@@ -25204,6 +25234,7 @@ var WorkflowContext = class {
|
|
|
25204
25234
|
* @param body call body
|
|
25205
25235
|
* @param headers call headers
|
|
25206
25236
|
* @param retries number of call retries. 0 by default
|
|
25237
|
+
* @param timeout max duration to wait for the endpoint to respond. in seconds.
|
|
25207
25238
|
* @returns call result as {
|
|
25208
25239
|
* status: number;
|
|
25209
25240
|
* body: unknown;
|
|
@@ -25211,9 +25242,17 @@ var WorkflowContext = class {
|
|
|
25211
25242
|
* }
|
|
25212
25243
|
*/
|
|
25213
25244
|
async call(stepName, settings) {
|
|
25214
|
-
const { url, method = "GET", body, headers = {}, retries = 0 } = settings;
|
|
25245
|
+
const { url, method = "GET", body, headers = {}, retries = 0, timeout } = settings;
|
|
25215
25246
|
const result = await this.addStep(
|
|
25216
|
-
new LazyCallStep(
|
|
25247
|
+
new LazyCallStep(
|
|
25248
|
+
stepName,
|
|
25249
|
+
url,
|
|
25250
|
+
method,
|
|
25251
|
+
body,
|
|
25252
|
+
headers,
|
|
25253
|
+
retries,
|
|
25254
|
+
timeout
|
|
25255
|
+
)
|
|
25217
25256
|
);
|
|
25218
25257
|
if (typeof result === "string") {
|
|
25219
25258
|
try {
|
|
@@ -25414,7 +25453,7 @@ function decodeBase64(base64) {
|
|
|
25414
25453
|
}
|
|
25415
25454
|
|
|
25416
25455
|
// src/serve/authorization.ts
|
|
25417
|
-
var
|
|
25456
|
+
var import_qstash4 = require("@upstash/qstash");
|
|
25418
25457
|
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
25419
25458
|
static disabledMessage = "disabled-qstash-worklfow-run";
|
|
25420
25459
|
/**
|
|
@@ -25445,7 +25484,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
25445
25484
|
*/
|
|
25446
25485
|
static async tryAuthentication(routeFunction, context) {
|
|
25447
25486
|
const disabledContext = new _DisabledWorkflowContext({
|
|
25448
|
-
qstashClient: new
|
|
25487
|
+
qstashClient: new import_qstash4.Client({
|
|
25449
25488
|
baseUrl: "disabled-client",
|
|
25450
25489
|
token: "disabled-client"
|
|
25451
25490
|
}),
|
|
@@ -25569,7 +25608,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
25569
25608
|
return {
|
|
25570
25609
|
rawInitialPayload: requestPayload ?? "",
|
|
25571
25610
|
steps: [],
|
|
25572
|
-
isLastDuplicate: false
|
|
25611
|
+
isLastDuplicate: false,
|
|
25612
|
+
workflowRunEnded: false
|
|
25573
25613
|
};
|
|
25574
25614
|
} else {
|
|
25575
25615
|
let rawSteps;
|
|
@@ -25579,7 +25619,21 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
25579
25619
|
"ENDPOINT_START",
|
|
25580
25620
|
"request payload is empty, steps will be fetched from QStash."
|
|
25581
25621
|
);
|
|
25582
|
-
|
|
25622
|
+
const { steps: fetchedSteps, workflowRunEnded } = await getSteps(
|
|
25623
|
+
requester,
|
|
25624
|
+
workflowRunId,
|
|
25625
|
+
messageId,
|
|
25626
|
+
debug
|
|
25627
|
+
);
|
|
25628
|
+
if (workflowRunEnded) {
|
|
25629
|
+
return {
|
|
25630
|
+
rawInitialPayload: void 0,
|
|
25631
|
+
steps: void 0,
|
|
25632
|
+
isLastDuplicate: void 0,
|
|
25633
|
+
workflowRunEnded: true
|
|
25634
|
+
};
|
|
25635
|
+
}
|
|
25636
|
+
rawSteps = fetchedSteps;
|
|
25583
25637
|
} else {
|
|
25584
25638
|
rawSteps = JSON.parse(requestPayload);
|
|
25585
25639
|
}
|
|
@@ -25589,7 +25643,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
25589
25643
|
return {
|
|
25590
25644
|
rawInitialPayload,
|
|
25591
25645
|
steps: deduplicatedSteps,
|
|
25592
|
-
isLastDuplicate
|
|
25646
|
+
isLastDuplicate,
|
|
25647
|
+
workflowRunEnded: false
|
|
25593
25648
|
};
|
|
25594
25649
|
}
|
|
25595
25650
|
};
|
|
@@ -25613,7 +25668,7 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
25613
25668
|
const workflowContext = new WorkflowContext({
|
|
25614
25669
|
qstashClient,
|
|
25615
25670
|
workflowRunId,
|
|
25616
|
-
initialPayload: initialPayloadParser(decodeBase64(sourceBody)),
|
|
25671
|
+
initialPayload: sourceBody ? initialPayloadParser(decodeBase64(sourceBody)) : void 0,
|
|
25617
25672
|
headers: recreateUserHeaders(new Headers(sourceHeader)),
|
|
25618
25673
|
steps: [],
|
|
25619
25674
|
url,
|
|
@@ -25643,22 +25698,35 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
25643
25698
|
};
|
|
25644
25699
|
|
|
25645
25700
|
// src/serve/options.ts
|
|
25646
|
-
var import_qstash4 = require("@upstash/qstash");
|
|
25647
25701
|
var import_qstash5 = require("@upstash/qstash");
|
|
25702
|
+
var import_qstash6 = require("@upstash/qstash");
|
|
25648
25703
|
var processOptions = (options) => {
|
|
25649
25704
|
const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
|
|
25650
25705
|
const receiverEnvironmentVariablesSet = Boolean(
|
|
25651
25706
|
environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
|
|
25652
25707
|
);
|
|
25653
25708
|
return {
|
|
25654
|
-
qstashClient: new
|
|
25709
|
+
qstashClient: new import_qstash6.Client({
|
|
25655
25710
|
baseUrl: environment.QSTASH_URL,
|
|
25656
25711
|
token: environment.QSTASH_TOKEN
|
|
25657
25712
|
}),
|
|
25658
|
-
|
|
25659
|
-
|
|
25660
|
-
|
|
25661
|
-
|
|
25713
|
+
onStepFinish: (workflowRunId, finishCondition) => {
|
|
25714
|
+
if (finishCondition === "auth-fail") {
|
|
25715
|
+
console.error(AUTH_FAIL_MESSAGE);
|
|
25716
|
+
return new Response(
|
|
25717
|
+
JSON.stringify({
|
|
25718
|
+
message: AUTH_FAIL_MESSAGE,
|
|
25719
|
+
workflowRunId
|
|
25720
|
+
}),
|
|
25721
|
+
{
|
|
25722
|
+
status: 400
|
|
25723
|
+
}
|
|
25724
|
+
);
|
|
25725
|
+
}
|
|
25726
|
+
return new Response(JSON.stringify({ workflowRunId }), {
|
|
25727
|
+
status: 200
|
|
25728
|
+
});
|
|
25729
|
+
},
|
|
25662
25730
|
initialPayloadParser: (initialRequest) => {
|
|
25663
25731
|
if (!initialRequest) {
|
|
25664
25732
|
return void 0;
|
|
@@ -25672,13 +25740,14 @@ var processOptions = (options) => {
|
|
|
25672
25740
|
throw error;
|
|
25673
25741
|
}
|
|
25674
25742
|
},
|
|
25675
|
-
receiver: receiverEnvironmentVariablesSet ? new
|
|
25743
|
+
receiver: receiverEnvironmentVariablesSet ? new import_qstash5.Receiver({
|
|
25676
25744
|
currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
|
|
25677
25745
|
nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
|
|
25678
25746
|
}) : void 0,
|
|
25679
25747
|
baseUrl: environment.UPSTASH_WORKFLOW_URL,
|
|
25680
25748
|
env: environment,
|
|
25681
25749
|
retries: DEFAULT_RETRIES,
|
|
25750
|
+
useJSONContent: false,
|
|
25682
25751
|
...options
|
|
25683
25752
|
};
|
|
25684
25753
|
};
|
|
@@ -25695,14 +25764,25 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
|
|
|
25695
25764
|
});
|
|
25696
25765
|
}
|
|
25697
25766
|
const workflowFailureUrl = failureFunction ? workflowUrl : failureUrl;
|
|
25767
|
+
if (workflowUrl.includes("localhost")) {
|
|
25768
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
25769
|
+
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}`
|
|
25770
|
+
});
|
|
25771
|
+
}
|
|
25772
|
+
if (!(workflowUrl.startsWith("http://") || workflowUrl.startsWith("https://"))) {
|
|
25773
|
+
throw new WorkflowError(
|
|
25774
|
+
`Workflow URL should start with 'http://' or 'https://'. Recevied is '${workflowUrl}'`
|
|
25775
|
+
);
|
|
25776
|
+
}
|
|
25698
25777
|
return {
|
|
25699
25778
|
workflowUrl,
|
|
25700
25779
|
workflowFailureUrl
|
|
25701
25780
|
};
|
|
25702
25781
|
};
|
|
25782
|
+
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`;
|
|
25703
25783
|
|
|
25704
25784
|
// src/serve/index.ts
|
|
25705
|
-
var
|
|
25785
|
+
var serveBase = (routeFunction, options) => {
|
|
25706
25786
|
const {
|
|
25707
25787
|
qstashClient,
|
|
25708
25788
|
onStepFinish,
|
|
@@ -25714,7 +25794,8 @@ var serve = (routeFunction, options) => {
|
|
|
25714
25794
|
failureFunction,
|
|
25715
25795
|
baseUrl,
|
|
25716
25796
|
env,
|
|
25717
|
-
retries
|
|
25797
|
+
retries,
|
|
25798
|
+
useJSONContent
|
|
25718
25799
|
} = processOptions(options);
|
|
25719
25800
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
25720
25801
|
const handler = async (request) => {
|
|
@@ -25731,7 +25812,7 @@ var serve = (routeFunction, options) => {
|
|
|
25731
25812
|
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
|
|
25732
25813
|
const { isFirstInvocation, workflowRunId } = validateRequest(request);
|
|
25733
25814
|
debug?.setWorkflowRunId(workflowRunId);
|
|
25734
|
-
const { rawInitialPayload, steps, isLastDuplicate } = await parseRequest(
|
|
25815
|
+
const { rawInitialPayload, steps, isLastDuplicate, workflowRunEnded } = await parseRequest(
|
|
25735
25816
|
requestPayload,
|
|
25736
25817
|
isFirstInvocation,
|
|
25737
25818
|
workflowRunId,
|
|
@@ -25739,8 +25820,11 @@ var serve = (routeFunction, options) => {
|
|
|
25739
25820
|
request.headers.get("upstash-message-id"),
|
|
25740
25821
|
debug
|
|
25741
25822
|
);
|
|
25823
|
+
if (workflowRunEnded) {
|
|
25824
|
+
return onStepFinish(workflowRunId, "workflow-already-ended");
|
|
25825
|
+
}
|
|
25742
25826
|
if (isLastDuplicate) {
|
|
25743
|
-
return onStepFinish(
|
|
25827
|
+
return onStepFinish(workflowRunId, "duplicate-step");
|
|
25744
25828
|
}
|
|
25745
25829
|
const failureCheck = await handleFailure(
|
|
25746
25830
|
request,
|
|
@@ -25754,7 +25838,7 @@ var serve = (routeFunction, options) => {
|
|
|
25754
25838
|
throw failureCheck.error;
|
|
25755
25839
|
} else if (failureCheck.value === "is-failure-callback") {
|
|
25756
25840
|
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
25757
|
-
return onStepFinish(
|
|
25841
|
+
return onStepFinish(workflowRunId, "failure-callback");
|
|
25758
25842
|
}
|
|
25759
25843
|
const workflowContext = new WorkflowContext({
|
|
25760
25844
|
qstashClient,
|
|
@@ -25776,7 +25860,11 @@ var serve = (routeFunction, options) => {
|
|
|
25776
25860
|
await debug?.log("ERROR", "ERROR", { error: authCheck.error.message });
|
|
25777
25861
|
throw authCheck.error;
|
|
25778
25862
|
} else if (authCheck.value === "run-ended") {
|
|
25779
|
-
|
|
25863
|
+
await debug?.log("ERROR", "ERROR", { error: AUTH_FAIL_MESSAGE });
|
|
25864
|
+
return onStepFinish(
|
|
25865
|
+
isFirstInvocation ? "no-workflow-id" : workflowContext.workflowRunId,
|
|
25866
|
+
"auth-fail"
|
|
25867
|
+
);
|
|
25780
25868
|
}
|
|
25781
25869
|
const callReturnCheck = await handleThirdPartyCallResult(
|
|
25782
25870
|
request,
|
|
@@ -25793,7 +25881,7 @@ var serve = (routeFunction, options) => {
|
|
|
25793
25881
|
});
|
|
25794
25882
|
throw callReturnCheck.error;
|
|
25795
25883
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
25796
|
-
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, debug) : await triggerRouteFunction({
|
|
25884
|
+
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, useJSONContent, debug) : await triggerRouteFunction({
|
|
25797
25885
|
onStep: async () => routeFunction(workflowContext),
|
|
25798
25886
|
onCleanup: async () => {
|
|
25799
25887
|
await triggerWorkflowDelete(workflowContext, debug);
|
|
@@ -25809,6 +25897,8 @@ var serve = (routeFunction, options) => {
|
|
|
25809
25897
|
}
|
|
25810
25898
|
await debug?.log("INFO", "RESPONSE_WORKFLOW");
|
|
25811
25899
|
return onStepFinish(workflowContext.workflowRunId, "success");
|
|
25900
|
+
} else if (callReturnCheck.value === "workflow-ended") {
|
|
25901
|
+
return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended");
|
|
25812
25902
|
}
|
|
25813
25903
|
await debug?.log("INFO", "RESPONSE_DEFAULT");
|
|
25814
25904
|
return onStepFinish("no-workflow-id", "fromCallback");
|
|
@@ -25826,21 +25916,22 @@ var serve = (routeFunction, options) => {
|
|
|
25826
25916
|
return { handler: safeHandler };
|
|
25827
25917
|
};
|
|
25828
25918
|
|
|
25829
|
-
// src/client/index.ts
|
|
25830
|
-
var import_qstash6 = require("@upstash/qstash");
|
|
25831
|
-
|
|
25832
25919
|
// platforms/express.ts
|
|
25833
25920
|
var import_express = __toESM(require_express2());
|
|
25834
|
-
function
|
|
25921
|
+
function serve(routeFunction, options) {
|
|
25835
25922
|
const router = (0, import_express.Router)();
|
|
25836
25923
|
const handler = async (request_, res) => {
|
|
25837
25924
|
if (request_.method.toUpperCase() !== "POST") {
|
|
25838
25925
|
res.status(405).json("Only POST requests are allowed in workflows");
|
|
25839
25926
|
return;
|
|
25840
25927
|
}
|
|
25841
|
-
|
|
25842
|
-
|
|
25843
|
-
|
|
25928
|
+
let requestBody;
|
|
25929
|
+
if (request_.headers["content-type"]?.includes("text/plain")) {
|
|
25930
|
+
requestBody = request_.body;
|
|
25931
|
+
} else if (request_.headers["content-type"]?.includes("application/json")) {
|
|
25932
|
+
requestBody = JSON.stringify(request_.body);
|
|
25933
|
+
} else {
|
|
25934
|
+
requestBody = typeof request_.body === "string" ? request_.body : JSON.stringify(request_.body);
|
|
25844
25935
|
}
|
|
25845
25936
|
const protocol = request_.protocol;
|
|
25846
25937
|
const host = request_.get("host") || "localhost";
|
|
@@ -25848,11 +25939,14 @@ function serve2(routeFunction, options) {
|
|
|
25848
25939
|
const webRequest = new Request(url, {
|
|
25849
25940
|
method: request_.method,
|
|
25850
25941
|
headers: new Headers(request_.headers),
|
|
25851
|
-
body:
|
|
25942
|
+
body: requestBody
|
|
25852
25943
|
});
|
|
25853
|
-
const { handler: serveHandler } =
|
|
25944
|
+
const { handler: serveHandler } = serveBase(
|
|
25854
25945
|
(workflowContext) => routeFunction(workflowContext),
|
|
25855
|
-
|
|
25946
|
+
{
|
|
25947
|
+
...options,
|
|
25948
|
+
useJSONContent: true
|
|
25949
|
+
}
|
|
25856
25950
|
);
|
|
25857
25951
|
const response = await serveHandler(webRequest);
|
|
25858
25952
|
res.status(response.status).json(await response.json());
|
package/express.mjs
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
__commonJS,
|
|
3
3
|
__require,
|
|
4
4
|
__toESM,
|
|
5
|
-
|
|
6
|
-
} from "./chunk-
|
|
5
|
+
serveBase
|
|
6
|
+
} from "./chunk-Z7WS5XIR.mjs";
|
|
7
7
|
|
|
8
8
|
// node_modules/depd/index.js
|
|
9
9
|
var require_depd = __commonJS({
|
|
@@ -23530,16 +23530,20 @@ var require_express2 = __commonJS({
|
|
|
23530
23530
|
|
|
23531
23531
|
// platforms/express.ts
|
|
23532
23532
|
var import_express = __toESM(require_express2());
|
|
23533
|
-
function
|
|
23533
|
+
function serve(routeFunction, options) {
|
|
23534
23534
|
const router = (0, import_express.Router)();
|
|
23535
23535
|
const handler = async (request_, res) => {
|
|
23536
23536
|
if (request_.method.toUpperCase() !== "POST") {
|
|
23537
23537
|
res.status(405).json("Only POST requests are allowed in workflows");
|
|
23538
23538
|
return;
|
|
23539
23539
|
}
|
|
23540
|
-
|
|
23541
|
-
|
|
23542
|
-
|
|
23540
|
+
let requestBody;
|
|
23541
|
+
if (request_.headers["content-type"]?.includes("text/plain")) {
|
|
23542
|
+
requestBody = request_.body;
|
|
23543
|
+
} else if (request_.headers["content-type"]?.includes("application/json")) {
|
|
23544
|
+
requestBody = JSON.stringify(request_.body);
|
|
23545
|
+
} else {
|
|
23546
|
+
requestBody = typeof request_.body === "string" ? request_.body : JSON.stringify(request_.body);
|
|
23543
23547
|
}
|
|
23544
23548
|
const protocol = request_.protocol;
|
|
23545
23549
|
const host = request_.get("host") || "localhost";
|
|
@@ -23547,11 +23551,14 @@ function serve2(routeFunction, options) {
|
|
|
23547
23551
|
const webRequest = new Request(url, {
|
|
23548
23552
|
method: request_.method,
|
|
23549
23553
|
headers: new Headers(request_.headers),
|
|
23550
|
-
body:
|
|
23554
|
+
body: requestBody
|
|
23551
23555
|
});
|
|
23552
|
-
const { handler: serveHandler } =
|
|
23556
|
+
const { handler: serveHandler } = serveBase(
|
|
23553
23557
|
(workflowContext) => routeFunction(workflowContext),
|
|
23554
|
-
|
|
23558
|
+
{
|
|
23559
|
+
...options,
|
|
23560
|
+
useJSONContent: true
|
|
23561
|
+
}
|
|
23555
23562
|
);
|
|
23556
23563
|
const response = await serveHandler(webRequest);
|
|
23557
23564
|
res.status(response.status).json(await response.json());
|
|
@@ -23560,7 +23567,7 @@ function serve2(routeFunction, options) {
|
|
|
23560
23567
|
return router;
|
|
23561
23568
|
}
|
|
23562
23569
|
export {
|
|
23563
|
-
|
|
23570
|
+
serve
|
|
23564
23571
|
};
|
|
23565
23572
|
/*! Bundled license information:
|
|
23566
23573
|
|
package/h3.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as h3 from 'h3';
|
|
2
|
-
import { R as RouteFunction,
|
|
2
|
+
import { R as RouteFunction, j as PublicServeOptions } from './types-APRap-aV.mjs';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
|
|
5
|
-
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?:
|
|
5
|
+
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
|
|
6
6
|
handler: h3.EventHandler<h3.EventHandlerRequest, Promise<Response | {
|
|
7
7
|
status: number;
|
|
8
8
|
body: string;
|
package/h3.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as h3 from 'h3';
|
|
2
|
-
import { R as RouteFunction,
|
|
2
|
+
import { R as RouteFunction, j as PublicServeOptions } from './types-APRap-aV.js';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
|
|
5
|
-
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?:
|
|
5
|
+
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
|
|
6
6
|
handler: h3.EventHandler<h3.EventHandlerRequest, Promise<Response | {
|
|
7
7
|
status: number;
|
|
8
8
|
body: string;
|