@upstash/workflow 1.2.1 → 1.3.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 +10 -0
- package/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +80 -14
- package/astro.mjs +1 -1
- package/{chunk-THS5AX2D.mjs → chunk-CWCCIOXR.mjs} +83 -14
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +80 -14
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +80 -14
- package/express.mjs +1 -1
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +80 -14
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +80 -14
- package/hono.mjs +1 -1
- package/index.d.mts +24 -5
- package/index.d.ts +24 -5
- package/index.js +83 -15
- package/index.mjs +8 -3
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +80 -14
- package/nextjs.mjs +1 -1
- package/package.json +1 -1
- package/react-router.d.mts +2 -2
- package/react-router.d.ts +2 -2
- package/react-router.js +80 -14
- package/react-router.mjs +1 -1
- package/{serve-many-C6sa_DxN.d.mts → serve-many-CG3BFvO3.d.mts} +1 -1
- package/{serve-many-B-fe7bh7.d.ts → serve-many-iJF1IUXk.d.ts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +80 -14
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +80 -14
- package/svelte.mjs +1 -1
- package/tanstack.d.mts +2 -2
- package/tanstack.d.ts +2 -2
- package/tanstack.js +80 -14
- package/tanstack.mjs +1 -1
- package/{types-B2S08hRU.d.ts → types-CekOpKvz.d.mts} +23 -7
- package/{types-B2S08hRU.d.mts → types-CekOpKvz.d.ts} +23 -7
package/react-router.js
CHANGED
|
@@ -35,6 +35,7 @@ var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
|
|
|
35
35
|
var WORKFLOW_FAILURE_CALLBACK_HEADER = "Upstash-Workflow-Failure-Callback";
|
|
36
36
|
var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
|
|
37
37
|
var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
|
|
38
|
+
var WORKFLOW_RETRIED_HEADER = "Upstash-Retried";
|
|
38
39
|
var WORKFLOW_LABEL_HEADER = "Upstash-Label";
|
|
39
40
|
var WORKFLOW_UNKOWN_SDK_VERSION_HEADER = "Upstash-Workflow-Unknown-Sdk";
|
|
40
41
|
var WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER = "upstash-workflow-trigger-by-sdk";
|
|
@@ -43,7 +44,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
43
44
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
44
45
|
var NO_CONCURRENCY = 1;
|
|
45
46
|
var DEFAULT_RETRIES = 3;
|
|
46
|
-
var VERSION = "v1.
|
|
47
|
+
var VERSION = "v1.2.1";
|
|
47
48
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
48
49
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
49
50
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
@@ -215,6 +216,31 @@ var import_qstash4 = require("@upstash/qstash");
|
|
|
215
216
|
// src/utils.ts
|
|
216
217
|
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
217
218
|
var NANOID_LENGTH = 21;
|
|
219
|
+
var RESOURCE_NAME_PATTERN = /^[a-zA-Z0-9\-_.]+$/;
|
|
220
|
+
function validateLabel(label) {
|
|
221
|
+
if (label === void 0) return;
|
|
222
|
+
const labels = Array.isArray(label) ? label : [label];
|
|
223
|
+
if (labels.length === 0) {
|
|
224
|
+
throw new WorkflowNonRetryableError("Invalid label: label array must not be empty.");
|
|
225
|
+
}
|
|
226
|
+
for (const value of labels) {
|
|
227
|
+
if (!RESOURCE_NAME_PATTERN.test(value)) {
|
|
228
|
+
throw new WorkflowNonRetryableError(
|
|
229
|
+
`Invalid label "${value}": must be alphanumeric, hyphen, underscore, or period.`
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function serializeLabel(label) {
|
|
235
|
+
return Array.isArray(label) ? label.join(",") : label;
|
|
236
|
+
}
|
|
237
|
+
function validateFlowControl(flowControl) {
|
|
238
|
+
if (flowControl?.key !== void 0 && !RESOURCE_NAME_PATTERN.test(flowControl.key)) {
|
|
239
|
+
throw new WorkflowNonRetryableError(
|
|
240
|
+
`Invalid flow control key "${flowControl.key}": must be alphanumeric, hyphen, underscore, or period.`
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
218
244
|
function getRandomInt() {
|
|
219
245
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
220
246
|
}
|
|
@@ -750,8 +776,8 @@ var triggerFirstInvocation = async (params) => {
|
|
|
750
776
|
if (unknownSdk) {
|
|
751
777
|
headers[WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER] = "true";
|
|
752
778
|
}
|
|
753
|
-
if (workflowContext.
|
|
754
|
-
headers[WORKFLOW_LABEL_HEADER] = workflowContext.
|
|
779
|
+
if (workflowContext.labels.length > 0) {
|
|
780
|
+
headers[WORKFLOW_LABEL_HEADER] = serializeLabel(workflowContext.labels);
|
|
755
781
|
}
|
|
756
782
|
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
757
783
|
return {
|
|
@@ -855,6 +881,9 @@ var recreateUserHeaders = (headers) => {
|
|
|
855
881
|
}
|
|
856
882
|
return filteredHeaders;
|
|
857
883
|
};
|
|
884
|
+
var isThirdPartyCallResult = (request) => {
|
|
885
|
+
return request.headers.get("Upstash-Workflow-Callback") !== null;
|
|
886
|
+
};
|
|
858
887
|
var handleThirdPartyCallResult = async ({
|
|
859
888
|
request,
|
|
860
889
|
requestPayload,
|
|
@@ -864,7 +893,7 @@ var handleThirdPartyCallResult = async ({
|
|
|
864
893
|
middlewareManager
|
|
865
894
|
}) => {
|
|
866
895
|
try {
|
|
867
|
-
if (request
|
|
896
|
+
if (isThirdPartyCallResult(request)) {
|
|
868
897
|
let callbackPayload;
|
|
869
898
|
if (requestPayload) {
|
|
870
899
|
callbackPayload = requestPayload;
|
|
@@ -1550,8 +1579,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1550
1579
|
});
|
|
1551
1580
|
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1552
1581
|
if (label) {
|
|
1553
|
-
|
|
1554
|
-
triggerHeaders[
|
|
1582
|
+
const labelHeader = serializeLabel(label);
|
|
1583
|
+
triggerHeaders[WORKFLOW_LABEL_HEADER] = labelHeader;
|
|
1584
|
+
triggerHeaders[`upstash-forward-${WORKFLOW_LABEL_HEADER}`] = labelHeader;
|
|
1555
1585
|
}
|
|
1556
1586
|
return { headers: triggerHeaders, contentType };
|
|
1557
1587
|
}
|
|
@@ -2692,9 +2722,10 @@ var WorkflowContext = class {
|
|
|
2692
2722
|
*/
|
|
2693
2723
|
env;
|
|
2694
2724
|
/**
|
|
2695
|
-
*
|
|
2725
|
+
* Labels attached to the workflow run.
|
|
2696
2726
|
*
|
|
2697
|
-
* Can be used to filter the workflow run logs.
|
|
2727
|
+
* Can be used to filter the workflow run logs. A run can have multiple
|
|
2728
|
+
* labels when triggered with `label: string[]`.
|
|
2698
2729
|
*
|
|
2699
2730
|
* Can be set by passing a `label` parameter when triggering the workflow
|
|
2700
2731
|
* with `client.trigger`:
|
|
@@ -2702,11 +2733,27 @@ var WorkflowContext = class {
|
|
|
2702
2733
|
* ```ts
|
|
2703
2734
|
* await client.trigger({
|
|
2704
2735
|
* url: "https://workflow-endpoint.com",
|
|
2705
|
-
* label: "
|
|
2736
|
+
* label: ["label-1", "label-2"]
|
|
2706
2737
|
* });
|
|
2707
2738
|
* ```
|
|
2708
2739
|
*/
|
|
2709
|
-
|
|
2740
|
+
labels;
|
|
2741
|
+
/**
|
|
2742
|
+
* Label of the workflow run.
|
|
2743
|
+
*
|
|
2744
|
+
* @deprecated Use `labels` instead. When a run has multiple labels, this
|
|
2745
|
+
* only returns the first one.
|
|
2746
|
+
*/
|
|
2747
|
+
get label() {
|
|
2748
|
+
return this.labels[0];
|
|
2749
|
+
}
|
|
2750
|
+
/**
|
|
2751
|
+
* Number of times QStash has retried delivering the current request.
|
|
2752
|
+
*
|
|
2753
|
+
* Sourced from the `Upstash-Retried` header. `0` on the first delivery,
|
|
2754
|
+
* `1` on the first retry, `2` on the second, and so on.
|
|
2755
|
+
*/
|
|
2756
|
+
retried;
|
|
2710
2757
|
constructor({
|
|
2711
2758
|
qstashClient,
|
|
2712
2759
|
workflowRunId,
|
|
@@ -2719,6 +2766,7 @@ var WorkflowContext = class {
|
|
|
2719
2766
|
telemetry: telemetry2,
|
|
2720
2767
|
invokeCount,
|
|
2721
2768
|
label,
|
|
2769
|
+
retried,
|
|
2722
2770
|
middlewareManager
|
|
2723
2771
|
}) {
|
|
2724
2772
|
this.qstashClient = qstashClient;
|
|
@@ -2729,7 +2777,8 @@ var WorkflowContext = class {
|
|
|
2729
2777
|
this.headers = headers;
|
|
2730
2778
|
this.requestPayload = initialPayload;
|
|
2731
2779
|
this.env = env ?? {};
|
|
2732
|
-
this.
|
|
2780
|
+
this.labels = label === void 0 ? [] : Array.isArray(label) ? label : label ? label.split(",") : [];
|
|
2781
|
+
this.retried = retried ?? 0;
|
|
2733
2782
|
const middlewareManagerInstance = middlewareManager ?? new MiddlewareManager([]);
|
|
2734
2783
|
middlewareManagerInstance.assignContext(this);
|
|
2735
2784
|
this.executor = new AutoExecutor(
|
|
@@ -2809,8 +2858,10 @@ var WorkflowContext = class {
|
|
|
2809
2858
|
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
2810
2859
|
}
|
|
2811
2860
|
async call(stepName, settings) {
|
|
2861
|
+
validateFlowControl(settings.flowControl);
|
|
2812
2862
|
let callStep;
|
|
2813
2863
|
if ("workflow" in settings) {
|
|
2864
|
+
validateLabel(settings.label);
|
|
2814
2865
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2815
2866
|
const stringBody = typeof settings.body === "string" ? settings.body : settings.body === void 0 ? void 0 : JSON.stringify(settings.body);
|
|
2816
2867
|
callStep = new LazyCallStep({
|
|
@@ -2918,6 +2969,8 @@ var WorkflowContext = class {
|
|
|
2918
2969
|
);
|
|
2919
2970
|
}
|
|
2920
2971
|
async invoke(stepName, settings) {
|
|
2972
|
+
validateLabel(settings.label);
|
|
2973
|
+
validateFlowControl(settings.flowControl);
|
|
2921
2974
|
return await this.addStep(
|
|
2922
2975
|
new LazyInvokeStep(this, stepName, settings)
|
|
2923
2976
|
);
|
|
@@ -2993,7 +3046,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2993
3046
|
const disabledContext = new _DisabledWorkflowContext({
|
|
2994
3047
|
qstashClient: new import_qstash10.Client({
|
|
2995
3048
|
baseUrl: "disabled-client",
|
|
2996
|
-
token: "disabled-client"
|
|
3049
|
+
token: "disabled-client",
|
|
3050
|
+
devMode: false
|
|
2997
3051
|
}),
|
|
2998
3052
|
workflowRunId: context.workflowRunId,
|
|
2999
3053
|
workflowRunCreatedAt: context.workflowRunCreatedAt,
|
|
@@ -3002,7 +3056,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3002
3056
|
url: context.url,
|
|
3003
3057
|
initialPayload: context.requestPayload,
|
|
3004
3058
|
env: context.env,
|
|
3005
|
-
label: context.
|
|
3059
|
+
label: context.labels,
|
|
3060
|
+
retried: context.retried
|
|
3006
3061
|
});
|
|
3007
3062
|
try {
|
|
3008
3063
|
await routeFunction(disabledContext);
|
|
@@ -3218,6 +3273,7 @@ var handleFailure = async ({
|
|
|
3218
3273
|
errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
|
|
3219
3274
|
}
|
|
3220
3275
|
const userHeaders = recreateUserHeaders(request.headers);
|
|
3276
|
+
const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
|
|
3221
3277
|
const workflowContext = new WorkflowContext({
|
|
3222
3278
|
qstashClient,
|
|
3223
3279
|
workflowRunId,
|
|
@@ -3229,6 +3285,7 @@ var handleFailure = async ({
|
|
|
3229
3285
|
telemetry: void 0,
|
|
3230
3286
|
// not going to make requests in authentication check
|
|
3231
3287
|
label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0,
|
|
3288
|
+
retried,
|
|
3232
3289
|
workflowRunCreatedAt: workflowCreatedAt,
|
|
3233
3290
|
middlewareManager: void 0
|
|
3234
3291
|
});
|
|
@@ -3388,6 +3445,9 @@ var getReceiver = (environment, receiverConfig, region) => {
|
|
|
3388
3445
|
if (receiverConfig === "set-to-undefined") {
|
|
3389
3446
|
return void 0;
|
|
3390
3447
|
}
|
|
3448
|
+
if (isQStashDevModeEnabled(environment)) {
|
|
3449
|
+
return new import_qstash11.Receiver({ devMode: true });
|
|
3450
|
+
}
|
|
3391
3451
|
const receiverEnv = readReceiverEnvironmentVariables(environment, region);
|
|
3392
3452
|
return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash11.Receiver({
|
|
3393
3453
|
currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
|
|
@@ -3397,6 +3457,10 @@ var getReceiver = (environment, receiverConfig, region) => {
|
|
|
3397
3457
|
return receiverConfig;
|
|
3398
3458
|
}
|
|
3399
3459
|
};
|
|
3460
|
+
var isQStashDevModeEnabled = (env) => {
|
|
3461
|
+
const value = env.QSTASH_DEV;
|
|
3462
|
+
return value === "true" || value === "1";
|
|
3463
|
+
};
|
|
3400
3464
|
var getQStashHandlerOptions = (...params) => {
|
|
3401
3465
|
const handlers = getQStashHandlers(...params);
|
|
3402
3466
|
return {
|
|
@@ -3706,12 +3770,13 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
|
|
|
3706
3770
|
);
|
|
3707
3771
|
}
|
|
3708
3772
|
const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
|
|
3773
|
+
const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
|
|
3709
3774
|
const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
|
|
3710
3775
|
const workflowRunCreatedAt = request.headers.get(WORKFLOW_CREATED_AT_HEADER);
|
|
3711
3776
|
const workflowContext = new WorkflowContext({
|
|
3712
3777
|
qstashClient: regionalClient,
|
|
3713
3778
|
workflowRunId,
|
|
3714
|
-
initialPayload: initialPayloadParser(rawInitialPayload),
|
|
3779
|
+
initialPayload: isThirdPartyCallResult(request) ? JSON.parse(rawInitialPayload) : initialPayloadParser(rawInitialPayload),
|
|
3715
3780
|
headers: recreateUserHeaders(request.headers),
|
|
3716
3781
|
steps,
|
|
3717
3782
|
url: workflowUrl,
|
|
@@ -3719,6 +3784,7 @@ var serveBase = (routeFunction, telemetry2, options, internalOptions) => {
|
|
|
3719
3784
|
telemetry: telemetry2,
|
|
3720
3785
|
invokeCount,
|
|
3721
3786
|
label,
|
|
3787
|
+
retried,
|
|
3722
3788
|
workflowRunCreatedAt: Number(workflowRunCreatedAt),
|
|
3723
3789
|
middlewareManager
|
|
3724
3790
|
});
|
package/react-router.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as WorkflowServeOptions, c as RouteFunction, I as InvokableWorkflow } from './types-
|
|
1
|
+
import { d as WorkflowServeOptions, c as RouteFunction, I as InvokableWorkflow } from './types-CekOpKvz.mjs';
|
|
2
2
|
|
|
3
3
|
type OmitOptionsInServeMany<TOptions> = Omit<TOptions, "env" | "url" | "schema" | "initialPayloadParser">;
|
|
4
4
|
declare const serveManyBase: <THandler extends (...params: any[]) => any, TOptions extends OmitOptionsInServeMany<WorkflowServeOptions> = OmitOptionsInServeMany<WorkflowServeOptions>, TServeParams extends [routeFunction: RouteFunction<any, any>, options: TOptions] = [routeFunction: RouteFunction<any, any>, options: TOptions]>({ workflows, getUrl, serveMethod, options, }: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as WorkflowServeOptions, c as RouteFunction, I as InvokableWorkflow } from './types-
|
|
1
|
+
import { d as WorkflowServeOptions, c as RouteFunction, I as InvokableWorkflow } from './types-CekOpKvz.js';
|
|
2
2
|
|
|
3
3
|
type OmitOptionsInServeMany<TOptions> = Omit<TOptions, "env" | "url" | "schema" | "initialPayloadParser">;
|
|
4
4
|
declare const serveManyBase: <THandler extends (...params: any[]) => any, TOptions extends OmitOptionsInServeMany<WorkflowServeOptions> = OmitOptionsInServeMany<WorkflowServeOptions>, TServeParams extends [routeFunction: RouteFunction<any, any>, options: TOptions] = [routeFunction: RouteFunction<any, any>, options: TOptions]>({ workflows, getUrl, serveMethod, options, }: {
|
package/solidjs.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { APIEvent } from '@solidjs/start/server';
|
|
2
|
-
import { c as RouteFunction, d as WorkflowServeOptions } from './types-
|
|
2
|
+
import { c as RouteFunction, d as WorkflowServeOptions } from './types-CekOpKvz.mjs';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
package/solidjs.d.ts
CHANGED
package/solidjs.js
CHANGED
|
@@ -190,6 +190,7 @@ var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
|
|
|
190
190
|
var WORKFLOW_FAILURE_CALLBACK_HEADER = "Upstash-Workflow-Failure-Callback";
|
|
191
191
|
var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
|
|
192
192
|
var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
|
|
193
|
+
var WORKFLOW_RETRIED_HEADER = "Upstash-Retried";
|
|
193
194
|
var WORKFLOW_LABEL_HEADER = "Upstash-Label";
|
|
194
195
|
var WORKFLOW_UNKOWN_SDK_VERSION_HEADER = "Upstash-Workflow-Unknown-Sdk";
|
|
195
196
|
var WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER = "upstash-workflow-trigger-by-sdk";
|
|
@@ -198,7 +199,7 @@ var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
|
|
|
198
199
|
var DEFAULT_CONTENT_TYPE = "application/json";
|
|
199
200
|
var NO_CONCURRENCY = 1;
|
|
200
201
|
var DEFAULT_RETRIES = 3;
|
|
201
|
-
var VERSION = "v1.
|
|
202
|
+
var VERSION = "v1.2.1";
|
|
202
203
|
var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
|
|
203
204
|
var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
|
|
204
205
|
var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
|
|
@@ -213,6 +214,31 @@ var import_qstash4 = require("@upstash/qstash");
|
|
|
213
214
|
// src/utils.ts
|
|
214
215
|
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
215
216
|
var NANOID_LENGTH = 21;
|
|
217
|
+
var RESOURCE_NAME_PATTERN = /^[a-zA-Z0-9\-_.]+$/;
|
|
218
|
+
function validateLabel(label) {
|
|
219
|
+
if (label === void 0) return;
|
|
220
|
+
const labels = Array.isArray(label) ? label : [label];
|
|
221
|
+
if (labels.length === 0) {
|
|
222
|
+
throw new WorkflowNonRetryableError("Invalid label: label array must not be empty.");
|
|
223
|
+
}
|
|
224
|
+
for (const value of labels) {
|
|
225
|
+
if (!RESOURCE_NAME_PATTERN.test(value)) {
|
|
226
|
+
throw new WorkflowNonRetryableError(
|
|
227
|
+
`Invalid label "${value}": must be alphanumeric, hyphen, underscore, or period.`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
function serializeLabel(label) {
|
|
233
|
+
return Array.isArray(label) ? label.join(",") : label;
|
|
234
|
+
}
|
|
235
|
+
function validateFlowControl(flowControl) {
|
|
236
|
+
if (flowControl?.key !== void 0 && !RESOURCE_NAME_PATTERN.test(flowControl.key)) {
|
|
237
|
+
throw new WorkflowNonRetryableError(
|
|
238
|
+
`Invalid flow control key "${flowControl.key}": must be alphanumeric, hyphen, underscore, or period.`
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
216
242
|
function getRandomInt() {
|
|
217
243
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
218
244
|
}
|
|
@@ -748,8 +774,8 @@ var triggerFirstInvocation = async (params) => {
|
|
|
748
774
|
if (unknownSdk) {
|
|
749
775
|
headers[WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER] = "true";
|
|
750
776
|
}
|
|
751
|
-
if (workflowContext.
|
|
752
|
-
headers[WORKFLOW_LABEL_HEADER] = workflowContext.
|
|
777
|
+
if (workflowContext.labels.length > 0) {
|
|
778
|
+
headers[WORKFLOW_LABEL_HEADER] = serializeLabel(workflowContext.labels);
|
|
753
779
|
}
|
|
754
780
|
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
755
781
|
return {
|
|
@@ -853,6 +879,9 @@ var recreateUserHeaders = (headers) => {
|
|
|
853
879
|
}
|
|
854
880
|
return filteredHeaders;
|
|
855
881
|
};
|
|
882
|
+
var isThirdPartyCallResult = (request) => {
|
|
883
|
+
return request.headers.get("Upstash-Workflow-Callback") !== null;
|
|
884
|
+
};
|
|
856
885
|
var handleThirdPartyCallResult = async ({
|
|
857
886
|
request,
|
|
858
887
|
requestPayload,
|
|
@@ -862,7 +891,7 @@ var handleThirdPartyCallResult = async ({
|
|
|
862
891
|
middlewareManager
|
|
863
892
|
}) => {
|
|
864
893
|
try {
|
|
865
|
-
if (request
|
|
894
|
+
if (isThirdPartyCallResult(request)) {
|
|
866
895
|
let callbackPayload;
|
|
867
896
|
if (requestPayload) {
|
|
868
897
|
callbackPayload = requestPayload;
|
|
@@ -1548,8 +1577,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1548
1577
|
});
|
|
1549
1578
|
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1550
1579
|
if (label) {
|
|
1551
|
-
|
|
1552
|
-
triggerHeaders[
|
|
1580
|
+
const labelHeader = serializeLabel(label);
|
|
1581
|
+
triggerHeaders[WORKFLOW_LABEL_HEADER] = labelHeader;
|
|
1582
|
+
triggerHeaders[`upstash-forward-${WORKFLOW_LABEL_HEADER}`] = labelHeader;
|
|
1553
1583
|
}
|
|
1554
1584
|
return { headers: triggerHeaders, contentType };
|
|
1555
1585
|
}
|
|
@@ -2623,9 +2653,10 @@ var WorkflowContext = class {
|
|
|
2623
2653
|
*/
|
|
2624
2654
|
env;
|
|
2625
2655
|
/**
|
|
2626
|
-
*
|
|
2656
|
+
* Labels attached to the workflow run.
|
|
2627
2657
|
*
|
|
2628
|
-
* Can be used to filter the workflow run logs.
|
|
2658
|
+
* Can be used to filter the workflow run logs. A run can have multiple
|
|
2659
|
+
* labels when triggered with `label: string[]`.
|
|
2629
2660
|
*
|
|
2630
2661
|
* Can be set by passing a `label` parameter when triggering the workflow
|
|
2631
2662
|
* with `client.trigger`:
|
|
@@ -2633,11 +2664,27 @@ var WorkflowContext = class {
|
|
|
2633
2664
|
* ```ts
|
|
2634
2665
|
* await client.trigger({
|
|
2635
2666
|
* url: "https://workflow-endpoint.com",
|
|
2636
|
-
* label: "
|
|
2667
|
+
* label: ["label-1", "label-2"]
|
|
2637
2668
|
* });
|
|
2638
2669
|
* ```
|
|
2639
2670
|
*/
|
|
2640
|
-
|
|
2671
|
+
labels;
|
|
2672
|
+
/**
|
|
2673
|
+
* Label of the workflow run.
|
|
2674
|
+
*
|
|
2675
|
+
* @deprecated Use `labels` instead. When a run has multiple labels, this
|
|
2676
|
+
* only returns the first one.
|
|
2677
|
+
*/
|
|
2678
|
+
get label() {
|
|
2679
|
+
return this.labels[0];
|
|
2680
|
+
}
|
|
2681
|
+
/**
|
|
2682
|
+
* Number of times QStash has retried delivering the current request.
|
|
2683
|
+
*
|
|
2684
|
+
* Sourced from the `Upstash-Retried` header. `0` on the first delivery,
|
|
2685
|
+
* `1` on the first retry, `2` on the second, and so on.
|
|
2686
|
+
*/
|
|
2687
|
+
retried;
|
|
2641
2688
|
constructor({
|
|
2642
2689
|
qstashClient,
|
|
2643
2690
|
workflowRunId,
|
|
@@ -2650,6 +2697,7 @@ var WorkflowContext = class {
|
|
|
2650
2697
|
telemetry,
|
|
2651
2698
|
invokeCount,
|
|
2652
2699
|
label,
|
|
2700
|
+
retried,
|
|
2653
2701
|
middlewareManager
|
|
2654
2702
|
}) {
|
|
2655
2703
|
this.qstashClient = qstashClient;
|
|
@@ -2660,7 +2708,8 @@ var WorkflowContext = class {
|
|
|
2660
2708
|
this.headers = headers;
|
|
2661
2709
|
this.requestPayload = initialPayload;
|
|
2662
2710
|
this.env = env ?? {};
|
|
2663
|
-
this.
|
|
2711
|
+
this.labels = label === void 0 ? [] : Array.isArray(label) ? label : label ? label.split(",") : [];
|
|
2712
|
+
this.retried = retried ?? 0;
|
|
2664
2713
|
const middlewareManagerInstance = middlewareManager ?? new MiddlewareManager([]);
|
|
2665
2714
|
middlewareManagerInstance.assignContext(this);
|
|
2666
2715
|
this.executor = new AutoExecutor(
|
|
@@ -2740,8 +2789,10 @@ var WorkflowContext = class {
|
|
|
2740
2789
|
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
2741
2790
|
}
|
|
2742
2791
|
async call(stepName, settings) {
|
|
2792
|
+
validateFlowControl(settings.flowControl);
|
|
2743
2793
|
let callStep;
|
|
2744
2794
|
if ("workflow" in settings) {
|
|
2795
|
+
validateLabel(settings.label);
|
|
2745
2796
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2746
2797
|
const stringBody = typeof settings.body === "string" ? settings.body : settings.body === void 0 ? void 0 : JSON.stringify(settings.body);
|
|
2747
2798
|
callStep = new LazyCallStep({
|
|
@@ -2849,6 +2900,8 @@ var WorkflowContext = class {
|
|
|
2849
2900
|
);
|
|
2850
2901
|
}
|
|
2851
2902
|
async invoke(stepName, settings) {
|
|
2903
|
+
validateLabel(settings.label);
|
|
2904
|
+
validateFlowControl(settings.flowControl);
|
|
2852
2905
|
return await this.addStep(
|
|
2853
2906
|
new LazyInvokeStep(this, stepName, settings)
|
|
2854
2907
|
);
|
|
@@ -2924,7 +2977,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2924
2977
|
const disabledContext = new _DisabledWorkflowContext({
|
|
2925
2978
|
qstashClient: new import_qstash10.Client({
|
|
2926
2979
|
baseUrl: "disabled-client",
|
|
2927
|
-
token: "disabled-client"
|
|
2980
|
+
token: "disabled-client",
|
|
2981
|
+
devMode: false
|
|
2928
2982
|
}),
|
|
2929
2983
|
workflowRunId: context.workflowRunId,
|
|
2930
2984
|
workflowRunCreatedAt: context.workflowRunCreatedAt,
|
|
@@ -2933,7 +2987,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2933
2987
|
url: context.url,
|
|
2934
2988
|
initialPayload: context.requestPayload,
|
|
2935
2989
|
env: context.env,
|
|
2936
|
-
label: context.
|
|
2990
|
+
label: context.labels,
|
|
2991
|
+
retried: context.retried
|
|
2937
2992
|
});
|
|
2938
2993
|
try {
|
|
2939
2994
|
await routeFunction(disabledContext);
|
|
@@ -3149,6 +3204,7 @@ var handleFailure = async ({
|
|
|
3149
3204
|
errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
|
|
3150
3205
|
}
|
|
3151
3206
|
const userHeaders = recreateUserHeaders(request.headers);
|
|
3207
|
+
const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
|
|
3152
3208
|
const workflowContext = new WorkflowContext({
|
|
3153
3209
|
qstashClient,
|
|
3154
3210
|
workflowRunId,
|
|
@@ -3160,6 +3216,7 @@ var handleFailure = async ({
|
|
|
3160
3216
|
telemetry: void 0,
|
|
3161
3217
|
// not going to make requests in authentication check
|
|
3162
3218
|
label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0,
|
|
3219
|
+
retried,
|
|
3163
3220
|
workflowRunCreatedAt: workflowCreatedAt,
|
|
3164
3221
|
middlewareManager: void 0
|
|
3165
3222
|
});
|
|
@@ -3319,6 +3376,9 @@ var getReceiver = (environment, receiverConfig, region) => {
|
|
|
3319
3376
|
if (receiverConfig === "set-to-undefined") {
|
|
3320
3377
|
return void 0;
|
|
3321
3378
|
}
|
|
3379
|
+
if (isQStashDevModeEnabled(environment)) {
|
|
3380
|
+
return new import_qstash11.Receiver({ devMode: true });
|
|
3381
|
+
}
|
|
3322
3382
|
const receiverEnv = readReceiverEnvironmentVariables(environment, region);
|
|
3323
3383
|
return receiverEnv.QSTASH_CURRENT_SIGNING_KEY && receiverEnv.QSTASH_NEXT_SIGNING_KEY ? new import_qstash11.Receiver({
|
|
3324
3384
|
currentSigningKey: receiverEnv.QSTASH_CURRENT_SIGNING_KEY,
|
|
@@ -3328,6 +3388,10 @@ var getReceiver = (environment, receiverConfig, region) => {
|
|
|
3328
3388
|
return receiverConfig;
|
|
3329
3389
|
}
|
|
3330
3390
|
};
|
|
3391
|
+
var isQStashDevModeEnabled = (env) => {
|
|
3392
|
+
const value = env.QSTASH_DEV;
|
|
3393
|
+
return value === "true" || value === "1";
|
|
3394
|
+
};
|
|
3331
3395
|
var getQStashHandlerOptions = (...params) => {
|
|
3332
3396
|
const handlers = getQStashHandlers(...params);
|
|
3333
3397
|
return {
|
|
@@ -3637,12 +3701,13 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3637
3701
|
);
|
|
3638
3702
|
}
|
|
3639
3703
|
const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
|
|
3704
|
+
const retried = Number(request.headers.get(WORKFLOW_RETRIED_HEADER) ?? "0");
|
|
3640
3705
|
const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
|
|
3641
3706
|
const workflowRunCreatedAt = request.headers.get(WORKFLOW_CREATED_AT_HEADER);
|
|
3642
3707
|
const workflowContext = new WorkflowContext({
|
|
3643
3708
|
qstashClient: regionalClient,
|
|
3644
3709
|
workflowRunId,
|
|
3645
|
-
initialPayload: initialPayloadParser(rawInitialPayload),
|
|
3710
|
+
initialPayload: isThirdPartyCallResult(request) ? JSON.parse(rawInitialPayload) : initialPayloadParser(rawInitialPayload),
|
|
3646
3711
|
headers: recreateUserHeaders(request.headers),
|
|
3647
3712
|
steps,
|
|
3648
3713
|
url: workflowUrl,
|
|
@@ -3650,6 +3715,7 @@ var serveBase = (routeFunction, telemetry, options, internalOptions) => {
|
|
|
3650
3715
|
telemetry,
|
|
3651
3716
|
invokeCount,
|
|
3652
3717
|
label,
|
|
3718
|
+
retried,
|
|
3653
3719
|
workflowRunCreatedAt: Number(workflowRunCreatedAt),
|
|
3654
3720
|
middlewareManager
|
|
3655
3721
|
});
|
package/solidjs.mjs
CHANGED
package/svelte.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _sveltejs_kit from '@sveltejs/kit';
|
|
2
2
|
import { RequestHandler } from '@sveltejs/kit';
|
|
3
|
-
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-
|
|
4
|
-
import { s as serveManyBase } from './serve-many-
|
|
3
|
+
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-CekOpKvz.mjs';
|
|
4
|
+
import { s as serveManyBase } from './serve-many-CG3BFvO3.mjs';
|
|
5
5
|
import '@upstash/qstash';
|
|
6
6
|
import 'zod';
|
|
7
7
|
|
package/svelte.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _sveltejs_kit from '@sveltejs/kit';
|
|
2
2
|
import { RequestHandler } from '@sveltejs/kit';
|
|
3
|
-
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-
|
|
4
|
-
import { s as serveManyBase } from './serve-many-
|
|
3
|
+
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-CekOpKvz.js';
|
|
4
|
+
import { s as serveManyBase } from './serve-many-iJF1IUXk.js';
|
|
5
5
|
import '@upstash/qstash';
|
|
6
6
|
import 'zod';
|
|
7
7
|
|