@upstash/workflow 1.2.0-demo-rc.1 → 1.2.1
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 +1 -0
- package/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +72 -69
- package/astro.mjs +1 -1
- package/{chunk-NZCQPOPR.mjs → chunk-THS5AX2D.mjs} +128 -257
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +72 -69
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +72 -69
- package/express.mjs +1 -1
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +76 -73
- package/h3.mjs +5 -5
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +73 -265
- package/hono.mjs +2 -7
- package/index.d.mts +229 -138
- package/index.d.ts +229 -138
- package/index.js +275 -454
- package/index.mjs +144 -196
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +72 -263
- package/nextjs.mjs +1 -5
- package/package.json +1 -1
- package/react-router.d.mts +38 -0
- package/react-router.d.ts +38 -0
- package/react-router.js +3881 -0
- package/react-router.mjs +45 -0
- package/{serve-many-Bi8XaOyq.d.ts → serve-many-B-fe7bh7.d.ts} +1 -1
- package/{serve-many-CppVPJrh.d.mts → serve-many-C6sa_DxN.d.mts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +72 -69
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +72 -69
- package/svelte.mjs +1 -1
- package/tanstack.d.mts +2 -2
- package/tanstack.d.ts +2 -2
- package/tanstack.js +72 -69
- package/tanstack.mjs +1 -1
- package/{types-CUwgrpCM.d.ts → types-B2S08hRU.d.mts} +18 -3
- package/{types-CUwgrpCM.d.mts → types-B2S08hRU.d.ts} +18 -3
package/nextjs.js
CHANGED
|
@@ -129,9 +129,10 @@ function isInstanceOf(v, ctor) {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
// src/client/utils.ts
|
|
132
|
-
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
132
|
+
var makeNotifyRequest = async (requester, eventId, eventData, workflowRunId) => {
|
|
133
|
+
const path = workflowRunId ? ["v2", "notify", workflowRunId, eventId] : ["v2", "notify", eventId];
|
|
133
134
|
const result = await requester.request({
|
|
134
|
-
path
|
|
135
|
+
path,
|
|
135
136
|
method: "POST",
|
|
136
137
|
body: typeof eventData === "string" ? eventData : JSON.stringify(eventData)
|
|
137
138
|
});
|
|
@@ -189,6 +190,7 @@ var getSteps = async (requester, workflowRunId, messageId, dispatchDebug) => {
|
|
|
189
190
|
var WORKFLOW_ID_HEADER = "Upstash-Workflow-RunId";
|
|
190
191
|
var WORKFLOW_INIT_HEADER = "Upstash-Workflow-Init";
|
|
191
192
|
var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
|
|
193
|
+
var WORKFLOW_CREATED_AT_HEADER = "Upstash-Workflow-CreatedAt";
|
|
192
194
|
var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
|
|
193
195
|
var WORKFLOW_FAILURE_CALLBACK_HEADER = "Upstash-Workflow-Failure-Callback";
|
|
194
196
|
var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
|
|
@@ -724,6 +726,7 @@ var triggerFirstInvocation = async (params) => {
|
|
|
724
726
|
retries,
|
|
725
727
|
retryDelay,
|
|
726
728
|
flowControl,
|
|
729
|
+
redact,
|
|
727
730
|
unknownSdk
|
|
728
731
|
}) => {
|
|
729
732
|
const { headers } = getHeaders({
|
|
@@ -760,7 +763,8 @@ var triggerFirstInvocation = async (params) => {
|
|
|
760
763
|
body,
|
|
761
764
|
url: workflowContext.url,
|
|
762
765
|
delay,
|
|
763
|
-
notBefore
|
|
766
|
+
notBefore,
|
|
767
|
+
redact
|
|
764
768
|
};
|
|
765
769
|
}
|
|
766
770
|
);
|
|
@@ -919,7 +923,6 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
919
923
|
})}`
|
|
920
924
|
);
|
|
921
925
|
}
|
|
922
|
-
const userHeaders = recreateUserHeaders(request.headers);
|
|
923
926
|
const { headers: requestHeaders } = getHeaders({
|
|
924
927
|
initHeaderValue: "false",
|
|
925
928
|
workflowConfig: {
|
|
@@ -927,7 +930,6 @@ ${atob(callbackMessage.body ?? "")}`
|
|
|
927
930
|
workflowUrl,
|
|
928
931
|
telemetry
|
|
929
932
|
},
|
|
930
|
-
userHeaders,
|
|
931
933
|
invokeCount: Number(invokeCount)
|
|
932
934
|
});
|
|
933
935
|
const callResponse = {
|
|
@@ -1076,7 +1078,6 @@ var BaseLazyStep = class _BaseLazyStep {
|
|
|
1076
1078
|
useJSONContent: false,
|
|
1077
1079
|
telemetry
|
|
1078
1080
|
},
|
|
1079
|
-
userHeaders: context.headers,
|
|
1080
1081
|
invokeCount,
|
|
1081
1082
|
stepInfo: {
|
|
1082
1083
|
step,
|
|
@@ -1434,9 +1435,9 @@ var LazyWaitEventStep = class extends BaseLazyStep {
|
|
|
1434
1435
|
};
|
|
1435
1436
|
var LazyNotifyStep = class extends LazyFunctionStep {
|
|
1436
1437
|
stepType = "Notify";
|
|
1437
|
-
constructor(context, stepName, eventId, eventData, requester) {
|
|
1438
|
+
constructor(context, stepName, eventId, eventData, requester, workflowRunId) {
|
|
1438
1439
|
super(context, stepName, async () => {
|
|
1439
|
-
const notifyResponse = await makeNotifyRequest(requester, eventId, eventData);
|
|
1440
|
+
const notifyResponse = await makeNotifyRequest(requester, eventId, eventData, workflowRunId);
|
|
1440
1441
|
return {
|
|
1441
1442
|
eventId,
|
|
1442
1443
|
eventData,
|
|
@@ -1506,7 +1507,6 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1506
1507
|
telemetry,
|
|
1507
1508
|
useJSONContent: false
|
|
1508
1509
|
},
|
|
1509
|
-
userHeaders: context.headers,
|
|
1510
1510
|
invokeCount
|
|
1511
1511
|
});
|
|
1512
1512
|
context.qstashClient.http.headers?.forEach((value, key) => {
|
|
@@ -1519,6 +1519,7 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1519
1519
|
Object.entries(invokerHeaders).map((pairs) => [pairs[0], [pairs[1]]])
|
|
1520
1520
|
),
|
|
1521
1521
|
workflowRunId: context.workflowRunId,
|
|
1522
|
+
workflowRunCreatedAt: context.workflowRunCreatedAt,
|
|
1522
1523
|
workflowUrl: context.url,
|
|
1523
1524
|
step
|
|
1524
1525
|
};
|
|
@@ -1614,12 +1615,14 @@ var LazyWaitForWebhookStep = class extends LazyWaitEventStep {
|
|
|
1614
1615
|
const parsedEventData = BaseLazyStep.tryParsing(eventData);
|
|
1615
1616
|
const body = parsedEventData.body;
|
|
1616
1617
|
const parsedBody = typeof body === "string" ? decodeBase64(body) : void 0;
|
|
1618
|
+
const methodUpper = parsedEventData.method.toUpperCase();
|
|
1619
|
+
const canHaveBody = methodUpper !== "GET" && methodUpper !== "HEAD";
|
|
1617
1620
|
const request = new Request(
|
|
1618
1621
|
`${parsedEventData.proto}://${parsedEventData.host}${parsedEventData.url}`,
|
|
1619
1622
|
{
|
|
1620
1623
|
method: parsedEventData.method,
|
|
1621
1624
|
headers: parsedEventData.header,
|
|
1622
|
-
body: parsedBody
|
|
1625
|
+
body: canHaveBody ? parsedBody : void 0
|
|
1623
1626
|
}
|
|
1624
1627
|
);
|
|
1625
1628
|
return {
|
|
@@ -1753,6 +1756,9 @@ var WorkflowHeaders = class {
|
|
|
1753
1756
|
}
|
|
1754
1757
|
}
|
|
1755
1758
|
addUserHeaders() {
|
|
1759
|
+
if (!this.userHeaders) {
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1756
1762
|
for (const [key, value] of this.userHeaders.entries()) {
|
|
1757
1763
|
const forwardKey = `Forward-${key}`;
|
|
1758
1764
|
this.headers.workflowHeaders[forwardKey] = value;
|
|
@@ -1859,7 +1865,6 @@ var submitParallelSteps = async ({
|
|
|
1859
1865
|
workflowUrl: context.url,
|
|
1860
1866
|
telemetry
|
|
1861
1867
|
},
|
|
1862
|
-
userHeaders: context.headers,
|
|
1863
1868
|
invokeCount
|
|
1864
1869
|
});
|
|
1865
1870
|
return {
|
|
@@ -2112,7 +2117,7 @@ var AutoExecutor = class _AutoExecutor {
|
|
|
2112
2117
|
});
|
|
2113
2118
|
throw new WorkflowAbort(parallelStep.stepName, resultStep);
|
|
2114
2119
|
} catch (error) {
|
|
2115
|
-
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400) {
|
|
2120
|
+
if (isInstanceOf(error, WorkflowAbort) || isInstanceOf(error, import_qstash5.QstashError) && error.status === 400 || isInstanceOf(error, import_qstash5.QstashError) && error.status === 412) {
|
|
2116
2121
|
throw error;
|
|
2117
2122
|
}
|
|
2118
2123
|
throw new WorkflowError(
|
|
@@ -2586,6 +2591,7 @@ var MiddlewareManager = class {
|
|
|
2586
2591
|
};
|
|
2587
2592
|
|
|
2588
2593
|
// src/context/context.ts
|
|
2594
|
+
var import_qstash9 = require("@upstash/qstash");
|
|
2589
2595
|
var WorkflowContext = class {
|
|
2590
2596
|
executor;
|
|
2591
2597
|
steps;
|
|
@@ -2612,6 +2618,10 @@ var WorkflowContext = class {
|
|
|
2612
2618
|
* Run id of the workflow
|
|
2613
2619
|
*/
|
|
2614
2620
|
workflowRunId;
|
|
2621
|
+
/**
|
|
2622
|
+
* Creation time of the workflow run
|
|
2623
|
+
*/
|
|
2624
|
+
workflowRunCreatedAt;
|
|
2615
2625
|
/**
|
|
2616
2626
|
* URL of the workflow
|
|
2617
2627
|
*
|
|
@@ -2703,6 +2713,7 @@ var WorkflowContext = class {
|
|
|
2703
2713
|
constructor({
|
|
2704
2714
|
qstashClient,
|
|
2705
2715
|
workflowRunId,
|
|
2716
|
+
workflowRunCreatedAt,
|
|
2706
2717
|
headers,
|
|
2707
2718
|
steps,
|
|
2708
2719
|
url,
|
|
@@ -2715,6 +2726,7 @@ var WorkflowContext = class {
|
|
|
2715
2726
|
}) {
|
|
2716
2727
|
this.qstashClient = qstashClient;
|
|
2717
2728
|
this.workflowRunId = workflowRunId;
|
|
2729
|
+
this.workflowRunCreatedAt = workflowRunCreatedAt;
|
|
2718
2730
|
this.steps = steps;
|
|
2719
2731
|
this.url = url;
|
|
2720
2732
|
this.headers = headers;
|
|
@@ -2889,14 +2901,23 @@ var WorkflowContext = class {
|
|
|
2889
2901
|
* a notifyResponse field which contains a list of `Waiter` objects, each corresponding
|
|
2890
2902
|
* to a notified workflow run.
|
|
2891
2903
|
*
|
|
2904
|
+
* Optionally, you can pass a workflowRunId to enable lookback functionality:
|
|
2905
|
+
*
|
|
2906
|
+
* ```ts
|
|
2907
|
+
* const { eventId, eventData, notifyResponse } = await context.notify(
|
|
2908
|
+
* "notify step", "event-id", "event-data", "wfr_123"
|
|
2909
|
+
* );
|
|
2910
|
+
* ```
|
|
2911
|
+
*
|
|
2892
2912
|
* @param stepName
|
|
2893
2913
|
* @param eventId event id to notify
|
|
2894
2914
|
* @param eventData event data to notify with
|
|
2915
|
+
* @param workflowRunId optional workflow run id for lookback support
|
|
2895
2916
|
* @returns notify response which has event id, event data and list of waiters which were notified
|
|
2896
2917
|
*/
|
|
2897
|
-
async notify(stepName, eventId, eventData) {
|
|
2918
|
+
async notify(stepName, eventId, eventData, workflowRunId) {
|
|
2898
2919
|
return await this.addStep(
|
|
2899
|
-
new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http)
|
|
2920
|
+
new LazyNotifyStep(this, stepName, eventId, eventData, this.qstashClient.http, workflowRunId)
|
|
2900
2921
|
);
|
|
2901
2922
|
}
|
|
2902
2923
|
async invoke(stepName, settings) {
|
|
@@ -2924,7 +2945,14 @@ var WorkflowContext = class {
|
|
|
2924
2945
|
* DisabledWorkflowContext.
|
|
2925
2946
|
*/
|
|
2926
2947
|
async addStep(step) {
|
|
2927
|
-
|
|
2948
|
+
try {
|
|
2949
|
+
return await this.executor.addStep(step);
|
|
2950
|
+
} catch (error) {
|
|
2951
|
+
if (isInstanceOf(error, import_qstash9.QstashError) && error.status === 412) {
|
|
2952
|
+
throw new WorkflowNonRetryableError(error.message);
|
|
2953
|
+
}
|
|
2954
|
+
throw error;
|
|
2955
|
+
}
|
|
2928
2956
|
}
|
|
2929
2957
|
get api() {
|
|
2930
2958
|
return new WorkflowApi({
|
|
@@ -2933,214 +2961,8 @@ var WorkflowContext = class {
|
|
|
2933
2961
|
}
|
|
2934
2962
|
};
|
|
2935
2963
|
|
|
2936
|
-
// src/dev-server.ts
|
|
2937
|
-
var import_child_process = require("child_process");
|
|
2938
|
-
var import_fs = require("fs");
|
|
2939
|
-
var import_https = require("https");
|
|
2940
|
-
var import_http = require("http");
|
|
2941
|
-
var import_path = require("path");
|
|
2942
|
-
var import_os = require("os");
|
|
2943
|
-
var DEV_QSTASH_TOKEN = "eyJVc2VySUQiOiJkZWZhdWx0VXNlciIsIlBhc3N3b3JkIjoiZGVmYXVsdFBhc3N3b3JkIn0=";
|
|
2944
|
-
var DEV_QSTASH_CURRENT_SIGNING_KEY = "sig_7kYjw48mhY7kAjqNGcy6cr29RJ6r";
|
|
2945
|
-
var DEV_QSTASH_NEXT_SIGNING_KEY = "sig_5ZB6DVzB1wjE8S6rZ7eenA8Pdnhs";
|
|
2946
|
-
function getDevCredentials(port) {
|
|
2947
|
-
return {
|
|
2948
|
-
QSTASH_URL: `http://localhost:${port}`,
|
|
2949
|
-
QSTASH_TOKEN: DEV_QSTASH_TOKEN,
|
|
2950
|
-
QSTASH_CURRENT_SIGNING_KEY: DEV_QSTASH_CURRENT_SIGNING_KEY,
|
|
2951
|
-
QSTASH_NEXT_SIGNING_KEY: DEV_QSTASH_NEXT_SIGNING_KEY
|
|
2952
|
-
};
|
|
2953
|
-
}
|
|
2954
|
-
var CACHE_DIR = (0, import_path.join)("node_modules", ".cache", "upstash");
|
|
2955
|
-
function getPlatformArch() {
|
|
2956
|
-
const platform = process.platform === "darwin" ? "darwin" : "linux";
|
|
2957
|
-
const arch = process.arch === "arm64" ? "arm64" : "amd64";
|
|
2958
|
-
return { platform, arch };
|
|
2959
|
-
}
|
|
2960
|
-
function httpsGet(url) {
|
|
2961
|
-
return new Promise((resolve, reject) => {
|
|
2962
|
-
const request = (currentUrl) => {
|
|
2963
|
-
(0, import_https.get)(currentUrl, { headers: { "User-Agent": "upstash-workflow" } }, (res) => {
|
|
2964
|
-
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
2965
|
-
request(res.headers.location);
|
|
2966
|
-
return;
|
|
2967
|
-
}
|
|
2968
|
-
if (res.statusCode && res.statusCode >= 400) {
|
|
2969
|
-
reject(new Error(`HTTP ${res.statusCode} fetching ${currentUrl}`));
|
|
2970
|
-
return;
|
|
2971
|
-
}
|
|
2972
|
-
const chunks = [];
|
|
2973
|
-
res.on("data", (chunk) => chunks.push(chunk));
|
|
2974
|
-
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
2975
|
-
res.on("error", reject);
|
|
2976
|
-
}).on("error", reject);
|
|
2977
|
-
};
|
|
2978
|
-
request(url);
|
|
2979
|
-
});
|
|
2980
|
-
}
|
|
2981
|
-
function downloadToFile(url, dest) {
|
|
2982
|
-
return new Promise((resolve, reject) => {
|
|
2983
|
-
const request = (currentUrl) => {
|
|
2984
|
-
(0, import_https.get)(currentUrl, { headers: { "User-Agent": "upstash-workflow" } }, (res) => {
|
|
2985
|
-
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
2986
|
-
request(res.headers.location);
|
|
2987
|
-
return;
|
|
2988
|
-
}
|
|
2989
|
-
if (res.statusCode && res.statusCode >= 400) {
|
|
2990
|
-
reject(new Error(`HTTP ${res.statusCode} downloading ${currentUrl}`));
|
|
2991
|
-
return;
|
|
2992
|
-
}
|
|
2993
|
-
const file = (0, import_fs.createWriteStream)(dest);
|
|
2994
|
-
res.pipe(file);
|
|
2995
|
-
file.on("finish", () => {
|
|
2996
|
-
file.close(() => resolve());
|
|
2997
|
-
});
|
|
2998
|
-
file.on("error", reject);
|
|
2999
|
-
}).on("error", reject);
|
|
3000
|
-
};
|
|
3001
|
-
request(url);
|
|
3002
|
-
});
|
|
3003
|
-
}
|
|
3004
|
-
async function resolveLatestVersion() {
|
|
3005
|
-
const data = await httpsGet("https://api.github.com/repos/upstash/qstash-cli/releases/latest");
|
|
3006
|
-
const json = JSON.parse(data.toString());
|
|
3007
|
-
return json.tag_name;
|
|
3008
|
-
}
|
|
3009
|
-
async function ensureBinary() {
|
|
3010
|
-
const version = await resolveLatestVersion();
|
|
3011
|
-
const cacheDir = (0, import_path.join)(CACHE_DIR, `qstash-server-${version}`);
|
|
3012
|
-
const binaryPath = (0, import_path.join)(cacheDir, "qstash");
|
|
3013
|
-
if ((0, import_fs.existsSync)(binaryPath)) {
|
|
3014
|
-
return binaryPath;
|
|
3015
|
-
}
|
|
3016
|
-
const { platform, arch } = getPlatformArch();
|
|
3017
|
-
const downloadUrl = `https://artifacts.upstash.com/qstash/versions/${version}/qstash-server_${version}_${platform}_${arch}.tar.gz`;
|
|
3018
|
-
console.log(`[workflow-dev] Downloading QStash server...`);
|
|
3019
|
-
(0, import_fs.mkdirSync)(cacheDir, { recursive: true });
|
|
3020
|
-
const tempFile = (0, import_path.join)((0, import_os.tmpdir)(), `qstash-server-${version}-${Date.now()}.tar.gz`);
|
|
3021
|
-
await downloadToFile(downloadUrl, tempFile);
|
|
3022
|
-
(0, import_child_process.execSync)(`tar -xzf "${tempFile}" -C "${cacheDir}"`);
|
|
3023
|
-
(0, import_fs.chmodSync)(binaryPath, 493);
|
|
3024
|
-
return binaryPath;
|
|
3025
|
-
}
|
|
3026
|
-
function startServer(binaryPath, port) {
|
|
3027
|
-
return new Promise((resolve, reject) => {
|
|
3028
|
-
const child = (0, import_child_process.spawn)(binaryPath, ["dev", "-port", String(port)], {
|
|
3029
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
3030
|
-
});
|
|
3031
|
-
let resolved = false;
|
|
3032
|
-
const cleanup = () => {
|
|
3033
|
-
if (!child.killed) {
|
|
3034
|
-
child.kill("SIGTERM");
|
|
3035
|
-
}
|
|
3036
|
-
};
|
|
3037
|
-
process.on("exit", cleanup);
|
|
3038
|
-
process.on("SIGINT", () => {
|
|
3039
|
-
cleanup();
|
|
3040
|
-
process.exit(0);
|
|
3041
|
-
});
|
|
3042
|
-
process.on("SIGTERM", () => {
|
|
3043
|
-
cleanup();
|
|
3044
|
-
process.exit(0);
|
|
3045
|
-
});
|
|
3046
|
-
let stdoutBuffer = "";
|
|
3047
|
-
child.stdout.on("data", (data) => {
|
|
3048
|
-
const text = data.toString();
|
|
3049
|
-
stdoutBuffer += text;
|
|
3050
|
-
const lines = stdoutBuffer.split("\n");
|
|
3051
|
-
stdoutBuffer = lines.pop() ?? "";
|
|
3052
|
-
for (const line of lines) {
|
|
3053
|
-
if (line.match(/runn+ing at/) && !resolved) {
|
|
3054
|
-
resolved = true;
|
|
3055
|
-
const creds = getDevCredentials(port);
|
|
3056
|
-
console.log(`[workflow-dev] QStash server running at ${creds.QSTASH_URL}`);
|
|
3057
|
-
console.log(
|
|
3058
|
-
`[workflow-dev] View logs at \x1B[1;32mhttps://console.upstash.com/workflow/local-mode-user/logs\x1B[0m`
|
|
3059
|
-
);
|
|
3060
|
-
resolve(cleanup);
|
|
3061
|
-
}
|
|
3062
|
-
}
|
|
3063
|
-
});
|
|
3064
|
-
child.stderr.on("data", (data) => {
|
|
3065
|
-
const text = data.toString();
|
|
3066
|
-
if (!resolved) {
|
|
3067
|
-
process.stderr.write(`[workflow-dev] ${text}`);
|
|
3068
|
-
}
|
|
3069
|
-
});
|
|
3070
|
-
child.on("error", (err2) => {
|
|
3071
|
-
if (!resolved) {
|
|
3072
|
-
reject(new Error(`[workflow-dev] Failed to start QStash server: ${err2.message}`));
|
|
3073
|
-
}
|
|
3074
|
-
});
|
|
3075
|
-
child.on("exit", (code) => {
|
|
3076
|
-
if (!resolved) {
|
|
3077
|
-
reject(
|
|
3078
|
-
new Error(`[workflow-dev] QStash server exited with code ${code} before becoming ready`)
|
|
3079
|
-
);
|
|
3080
|
-
}
|
|
3081
|
-
});
|
|
3082
|
-
setTimeout(() => {
|
|
3083
|
-
if (!resolved) {
|
|
3084
|
-
cleanup();
|
|
3085
|
-
reject(new Error("[workflow-dev] QStash server did not become ready within 30 seconds"));
|
|
3086
|
-
}
|
|
3087
|
-
}, 3e4);
|
|
3088
|
-
});
|
|
3089
|
-
}
|
|
3090
|
-
function isDevServerRunning(port) {
|
|
3091
|
-
return new Promise((resolve) => {
|
|
3092
|
-
const req = (0, import_http.get)(
|
|
3093
|
-
`http://127.0.0.1:${port}/v2/keys`,
|
|
3094
|
-
{
|
|
3095
|
-
headers: { Authorization: `Bearer ${DEV_QSTASH_TOKEN}` },
|
|
3096
|
-
timeout: 2e3
|
|
3097
|
-
},
|
|
3098
|
-
(res) => {
|
|
3099
|
-
if (res.statusCode !== 200) {
|
|
3100
|
-
resolve(false);
|
|
3101
|
-
return;
|
|
3102
|
-
}
|
|
3103
|
-
const chunks = [];
|
|
3104
|
-
res.on("data", (chunk) => chunks.push(chunk));
|
|
3105
|
-
res.on("end", () => {
|
|
3106
|
-
try {
|
|
3107
|
-
const body = JSON.parse(Buffer.concat(chunks).toString());
|
|
3108
|
-
resolve(
|
|
3109
|
-
body.current === DEV_QSTASH_CURRENT_SIGNING_KEY && body.next === DEV_QSTASH_NEXT_SIGNING_KEY
|
|
3110
|
-
);
|
|
3111
|
-
} catch {
|
|
3112
|
-
resolve(false);
|
|
3113
|
-
}
|
|
3114
|
-
});
|
|
3115
|
-
res.on("error", () => resolve(false));
|
|
3116
|
-
}
|
|
3117
|
-
);
|
|
3118
|
-
req.on("error", () => resolve(false));
|
|
3119
|
-
req.on("timeout", () => {
|
|
3120
|
-
req.destroy();
|
|
3121
|
-
resolve(false);
|
|
3122
|
-
});
|
|
3123
|
-
});
|
|
3124
|
-
}
|
|
3125
|
-
var serverPromise = null;
|
|
3126
|
-
var serverCleanup = null;
|
|
3127
|
-
function ensureDevServer(environment) {
|
|
3128
|
-
if (!serverPromise) {
|
|
3129
|
-
const port = Number(environment.WORKFLOW_DEV_PORT) || 8080;
|
|
3130
|
-
serverPromise = isDevServerRunning(port).then((alreadyRunning) => {
|
|
3131
|
-
if (alreadyRunning) {
|
|
3132
|
-
return;
|
|
3133
|
-
}
|
|
3134
|
-
return ensureBinary().then((binaryPath) => startServer(binaryPath, port)).then((cleanup) => {
|
|
3135
|
-
serverCleanup = cleanup;
|
|
3136
|
-
});
|
|
3137
|
-
});
|
|
3138
|
-
}
|
|
3139
|
-
return serverPromise;
|
|
3140
|
-
}
|
|
3141
|
-
|
|
3142
2964
|
// src/serve/authorization.ts
|
|
3143
|
-
var
|
|
2965
|
+
var import_qstash10 = require("@upstash/qstash");
|
|
3144
2966
|
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
3145
2967
|
static disabledMessage = "disabled-qstash-worklfow-run";
|
|
3146
2968
|
disabled = true;
|
|
@@ -3172,11 +2994,12 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3172
2994
|
*/
|
|
3173
2995
|
static async tryAuthentication(routeFunction, context) {
|
|
3174
2996
|
const disabledContext = new _DisabledWorkflowContext({
|
|
3175
|
-
qstashClient: new
|
|
2997
|
+
qstashClient: new import_qstash10.Client({
|
|
3176
2998
|
baseUrl: "disabled-client",
|
|
3177
2999
|
token: "disabled-client"
|
|
3178
3000
|
}),
|
|
3179
3001
|
workflowRunId: context.workflowRunId,
|
|
3002
|
+
workflowRunCreatedAt: context.workflowRunCreatedAt,
|
|
3180
3003
|
headers: context.headers,
|
|
3181
3004
|
steps: [],
|
|
3182
3005
|
url: context.url,
|
|
@@ -3378,7 +3201,9 @@ var handleFailure = async ({
|
|
|
3378
3201
|
return ok({ result: "failure-function-undefined" });
|
|
3379
3202
|
}
|
|
3380
3203
|
try {
|
|
3381
|
-
const { status, header, body, url, sourceBody, workflowRunId } = JSON.parse(
|
|
3204
|
+
const { status, header, body, url, sourceBody, workflowRunId, workflowCreatedAt } = JSON.parse(
|
|
3205
|
+
requestPayload
|
|
3206
|
+
);
|
|
3382
3207
|
const decodedBody = body ? decodeBase64(body) : "{}";
|
|
3383
3208
|
let errorMessage = "";
|
|
3384
3209
|
let failStack = "";
|
|
@@ -3407,6 +3232,7 @@ var handleFailure = async ({
|
|
|
3407
3232
|
telemetry: void 0,
|
|
3408
3233
|
// not going to make requests in authentication check
|
|
3409
3234
|
label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0,
|
|
3235
|
+
workflowRunCreatedAt: workflowCreatedAt,
|
|
3410
3236
|
middlewareManager: void 0
|
|
3411
3237
|
});
|
|
3412
3238
|
const authCheck = await DisabledWorkflowContext.tryAuthentication(
|
|
@@ -3435,7 +3261,7 @@ var handleFailure = async ({
|
|
|
3435
3261
|
};
|
|
3436
3262
|
|
|
3437
3263
|
// src/serve/multi-region/handlers.ts
|
|
3438
|
-
var
|
|
3264
|
+
var import_qstash11 = require("@upstash/qstash");
|
|
3439
3265
|
|
|
3440
3266
|
// src/serve/multi-region/utils.ts
|
|
3441
3267
|
var VALID_REGIONS = ["EU_CENTRAL_1", "US_EAST_1"];
|
|
@@ -3500,7 +3326,7 @@ var getHandlersForRequest = (qstashHandlers, regionHeader, isFirstInvocation) =>
|
|
|
3500
3326
|
};
|
|
3501
3327
|
var createRegionalHandler = (environment, receiverConfig, region, clientOptions) => {
|
|
3502
3328
|
const clientEnv = readClientEnvironmentVariables(environment, region);
|
|
3503
|
-
const client = new
|
|
3329
|
+
const client = new import_qstash11.Client({
|
|
3504
3330
|
...clientOptions,
|
|
3505
3331
|
baseUrl: clientEnv.QSTASH_URL,
|
|
3506
3332
|
token: clientEnv.QSTASH_TOKEN
|
|
@@ -3550,7 +3376,7 @@ var getQStashHandlers = ({
|
|
|
3550
3376
|
return {
|
|
3551
3377
|
mode: "single-region",
|
|
3552
3378
|
handlers: {
|
|
3553
|
-
client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new
|
|
3379
|
+
client: qstashClientOption && "http" in qstashClientOption ? qstashClientOption : new import_qstash11.Client({
|
|
3554
3380
|
...qstashClientOption,
|
|
3555
3381
|
baseUrl: environment.QSTASH_URL,
|
|
3556
3382
|
token: environment.QSTASH_TOKEN
|
|
@@ -3566,7 +3392,7 @@ var getReceiver = (environment, receiverConfig, region) => {
|
|
|
3566
3392
|
return void 0;
|
|
3567
3393
|
}
|
|
3568
3394
|
const receiverEnv = readReceiverEnvironmentVariables(environment, region);
|
|
3569
|
-
return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new
|
|
3395
|
+
return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash11.Receiver({
|
|
3570
3396
|
currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
|
|
3571
3397
|
nextSigningKey: receiverEnv.QSTASH_NEXT_SIGNING_KEY
|
|
3572
3398
|
}) : void 0;
|
|
@@ -3792,33 +3618,19 @@ var AUTH_FAIL_MESSAGE = `Failed to authenticate Workflow request. If this is une
|
|
|
3792
3618
|
|
|
3793
3619
|
// src/serve/index.ts
|
|
3794
3620
|
var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
3795
|
-
const
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
const
|
|
3807
|
-
options,
|
|
3808
|
-
internalOptions
|
|
3809
|
-
);
|
|
3621
|
+
const {
|
|
3622
|
+
initialPayloadParser,
|
|
3623
|
+
url,
|
|
3624
|
+
failureFunction,
|
|
3625
|
+
baseUrl,
|
|
3626
|
+
env,
|
|
3627
|
+
disableTelemetry,
|
|
3628
|
+
middlewares,
|
|
3629
|
+
internal
|
|
3630
|
+
} = processOptions(options, internalOptions);
|
|
3631
|
+
telemetry = disableTelemetry ? void 0 : telemetry;
|
|
3632
|
+
const { generateResponse: responseGenerator, useJSONContent } = internal;
|
|
3810
3633
|
const handler = async (request, middlewareManager) => {
|
|
3811
|
-
const {
|
|
3812
|
-
initialPayloadParser,
|
|
3813
|
-
url,
|
|
3814
|
-
failureFunction,
|
|
3815
|
-
baseUrl,
|
|
3816
|
-
env,
|
|
3817
|
-
disableTelemetry: optDisableTelemetry,
|
|
3818
|
-
internal
|
|
3819
|
-
} = resolvedOptions;
|
|
3820
|
-
const currentTelemetry = optDisableTelemetry ? void 0 : telemetry;
|
|
3821
|
-
const { generateResponse: responseGenerator, useJSONContent } = internal;
|
|
3822
3634
|
await middlewareManager.dispatchDebug("onInfo", {
|
|
3823
3635
|
info: `Received request for workflow execution.`
|
|
3824
3636
|
});
|
|
@@ -3898,6 +3710,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3898
3710
|
}
|
|
3899
3711
|
const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
|
|
3900
3712
|
const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
|
|
3713
|
+
const workflowRunCreatedAt = request.headers.get(WORKFLOW_CREATED_AT_HEADER);
|
|
3901
3714
|
const workflowContext = new WorkflowContext({
|
|
3902
3715
|
qstashClient: regionalClient,
|
|
3903
3716
|
workflowRunId,
|
|
@@ -3906,9 +3719,10 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3906
3719
|
steps,
|
|
3907
3720
|
url: workflowUrl,
|
|
3908
3721
|
env,
|
|
3909
|
-
telemetry
|
|
3722
|
+
telemetry,
|
|
3910
3723
|
invokeCount,
|
|
3911
3724
|
label,
|
|
3725
|
+
workflowRunCreatedAt: Number(workflowRunCreatedAt),
|
|
3912
3726
|
middlewareManager
|
|
3913
3727
|
});
|
|
3914
3728
|
const authCheck = await DisabledWorkflowContext.tryAuthentication(
|
|
@@ -3932,7 +3746,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3932
3746
|
requestPayload: rawInitialPayload,
|
|
3933
3747
|
client: regionalClient,
|
|
3934
3748
|
workflowUrl,
|
|
3935
|
-
telemetry
|
|
3749
|
+
telemetry,
|
|
3936
3750
|
middlewareManager
|
|
3937
3751
|
});
|
|
3938
3752
|
if (callReturnCheck.isErr()) {
|
|
@@ -3941,7 +3755,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3941
3755
|
const result = isFirstInvocation ? await triggerFirstInvocation({
|
|
3942
3756
|
workflowContext,
|
|
3943
3757
|
useJSONContent,
|
|
3944
|
-
telemetry
|
|
3758
|
+
telemetry,
|
|
3945
3759
|
invokeCount,
|
|
3946
3760
|
middlewareManager,
|
|
3947
3761
|
unknownSdk
|
|
@@ -4009,9 +3823,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
4009
3823
|
);
|
|
4010
3824
|
};
|
|
4011
3825
|
const safeHandler = async (request) => {
|
|
4012
|
-
const middlewareManager = new MiddlewareManager(
|
|
4013
|
-
resolvedOptions.middlewares
|
|
4014
|
-
);
|
|
3826
|
+
const middlewareManager = new MiddlewareManager(middlewares);
|
|
4015
3827
|
try {
|
|
4016
3828
|
return await handler(request, middlewareManager);
|
|
4017
3829
|
} catch (error) {
|
|
@@ -4031,9 +3843,6 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
4031
3843
|
};
|
|
4032
3844
|
|
|
4033
3845
|
// platforms/nextjs.ts
|
|
4034
|
-
if (typeof process !== "undefined" && process.env.WORKFLOW_DEV === "true") {
|
|
4035
|
-
ensureDevServer(process.env);
|
|
4036
|
-
}
|
|
4037
3846
|
var appTelemetry = {
|
|
4038
3847
|
sdk: SDK_TELEMETRY,
|
|
4039
3848
|
framework: "nextjs",
|
package/nextjs.mjs
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SDK_TELEMETRY,
|
|
3
|
-
ensureDevServer,
|
|
4
3
|
serveBase,
|
|
5
4
|
serveManyBase
|
|
6
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-THS5AX2D.mjs";
|
|
7
6
|
|
|
8
7
|
// platforms/nextjs.ts
|
|
9
|
-
if (typeof process !== "undefined" && process.env.WORKFLOW_DEV === "true") {
|
|
10
|
-
ensureDevServer(process.env);
|
|
11
|
-
}
|
|
12
8
|
var appTelemetry = {
|
|
13
9
|
sdk: SDK_TELEMETRY,
|
|
14
10
|
framework: "nextjs",
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"@upstash/workflow","version":"
|
|
1
|
+
{"name":"@upstash/workflow","version":"1.2.1","description":"Durable, Reliable and Performant Serverless Functions","main":"./index.js","module":"./index.mjs","types":"./index.d.ts","files":["./*"],"exports":{".":{"import":"./index.mjs","require":"./index.js"},"./dist/nextjs":{"import":"./nextjs.mjs","require":"./nextjs.js"},"./nextjs":{"import":"./nextjs.mjs","require":"./nextjs.js"},"./h3":{"import":"./h3.mjs","require":"./h3.js"},"./svelte":{"import":"./svelte.mjs","require":"./svelte.js"},"./solidjs":{"import":"./solidjs.mjs","require":"./solidjs.js"},"./workflow":{"import":"./workflow.mjs","require":"./workflow.js"},"./hono":{"import":"./hono.mjs","require":"./hono.js"},"./cloudflare":{"import":"./cloudflare.mjs","require":"./cloudflare.js"},"./astro":{"import":"./astro.mjs","require":"./astro.js"},"./express":{"import":"./express.mjs","require":"./express.js"},"./tanstack":{"import":"./tanstack.mjs","require":"./tanstack.js"},"./react-router":{"import":"./react-router.mjs","require":"./react-router.js"}},"scripts":{"build":"tsup && cp README.md ./dist/ && cp package.json ./dist/ && cp LICENSE ./dist/","test":"bun test src","fmt":"prettier --write .","lint":"tsc && eslint \"{src,platforms}/**/*.{js,ts,tsx}\" --quiet --fix","check-exports":"bun run build && cd dist && attw -P"},"repository":{"type":"git","url":"git@github.com:upstash/workflow-js.git"},"keywords":["upstash","qstash","workflow","serverless"],"author":"Cahid Arda Oz","license":"MIT","bugs":{"url":"https://github.com/upstash/workflow-ts/issues"},"homepage":"https://github.com/upstash/workflow-ts#readme","devDependencies":{"@commitlint/cli":"^19.5.0","@commitlint/config-conventional":"^19.5.0","@eslint/js":"^9.11.1","@solidjs/start":"^1.0.8","@sveltejs/kit":"^2.6.1","@types/bun":"^1.1.10","@types/express":"^5.0.6","astro":"^4.16.7","eslint":"^9.11.1","eslint-plugin-unicorn":"^55.0.0","express":"^5.1.0","globals":"^15.10.0","h3":"^1.12.0","hono":"^4.6.20","husky":"^9.1.6","next":"^14.2.14","prettier":"3.3.3","tsup":"^8.3.0","typescript":"^5.7.2","typescript-eslint":"^8.18.0"},"dependencies":{"@upstash/qstash":"^2.10.1"},"directories":{"example":"examples"},"peerDependencies":{"zod":"^3.25.0 || ^4.0.0"}}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-B2S08hRU.mjs';
|
|
2
|
+
import { s as serveManyBase } from './serve-many-C6sa_DxN.mjs';
|
|
3
|
+
import '@upstash/qstash';
|
|
4
|
+
import 'zod';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Serve method to serve an Upstash Workflow in a React Router v7 project
|
|
8
|
+
*
|
|
9
|
+
* Use this in your route's action function to handle workflow requests.
|
|
10
|
+
*
|
|
11
|
+
* See for options https://upstash.com/docs/qstash/workflows/basics/serve
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```tsx
|
|
15
|
+
* import { serve } from "@upstash/workflow/react-router";
|
|
16
|
+
*
|
|
17
|
+
* export const action = serve<{ message: string }>(
|
|
18
|
+
* async (context) => {
|
|
19
|
+
* const input = context.requestPayload;
|
|
20
|
+
* await context.sleep("sleep", 10);
|
|
21
|
+
* console.log("Workflow completed:", input.message);
|
|
22
|
+
* }
|
|
23
|
+
* );
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @param routeFunction workflow function
|
|
27
|
+
* @param options workflow options
|
|
28
|
+
* @returns action function compatible with React Router v7
|
|
29
|
+
*/
|
|
30
|
+
declare const serve: <TInitialPayload = unknown, TResult = unknown>(routeFunction: RouteFunction<TInitialPayload, TResult>, options?: WorkflowServeOptions<TInitialPayload, TResult>) => ({ request }: {
|
|
31
|
+
request: Request;
|
|
32
|
+
}) => Promise<Response>;
|
|
33
|
+
declare const createWorkflow: <TInitialPayload, TResult>(...params: Parameters<typeof serve<TInitialPayload, TResult>>) => InvokableWorkflow<TInitialPayload, TResult>;
|
|
34
|
+
declare const serveMany: (workflows: Parameters<typeof serveManyBase>[0]["workflows"], options?: Parameters<typeof serveManyBase>[0]["options"]) => (params_0: {
|
|
35
|
+
request: Request;
|
|
36
|
+
}) => Promise<any>;
|
|
37
|
+
|
|
38
|
+
export { createWorkflow, serve, serveMany };
|