@upstash/workflow 1.3.0 → 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/astro.d.mts +2 -2
- package/astro.d.ts +2 -2
- package/astro.js +50 -10
- package/astro.mjs +1 -1
- package/{chunk-G24J5PCC.mjs → chunk-CWCCIOXR.mjs} +53 -10
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +50 -10
- package/cloudflare.mjs +1 -1
- package/express.d.mts +2 -2
- package/express.d.ts +2 -2
- package/express.js +50 -10
- package/express.mjs +1 -1
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +50 -10
- package/h3.mjs +1 -1
- package/hono.d.mts +2 -2
- package/hono.d.ts +2 -2
- package/hono.js +50 -10
- package/hono.mjs +1 -1
- package/index.d.mts +24 -5
- package/index.d.ts +24 -5
- package/index.js +53 -11
- package/index.mjs +8 -3
- package/nextjs.d.mts +2 -2
- package/nextjs.d.ts +2 -2
- package/nextjs.js +50 -10
- 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 +50 -10
- package/react-router.mjs +1 -1
- package/{serve-many-D3D9uE4u.d.mts → serve-many-CG3BFvO3.d.mts} +1 -1
- package/{serve-many-kPOasiyb.d.ts → serve-many-iJF1IUXk.d.ts} +1 -1
- package/solidjs.d.mts +1 -1
- package/solidjs.d.ts +1 -1
- package/solidjs.js +50 -10
- package/solidjs.mjs +1 -1
- package/svelte.d.mts +2 -2
- package/svelte.d.ts +2 -2
- package/svelte.js +50 -10
- package/svelte.mjs +1 -1
- package/tanstack.d.mts +2 -2
- package/tanstack.d.ts +2 -2
- package/tanstack.js +50 -10
- package/tanstack.mjs +1 -1
- package/{types-B_E1VAK6.d.ts → types-CekOpKvz.d.mts} +14 -6
- package/{types-B_E1VAK6.d.mts → types-CekOpKvz.d.ts} +14 -6
package/h3.js
CHANGED
|
@@ -525,6 +525,31 @@ var import_qstash4 = require("@upstash/qstash");
|
|
|
525
525
|
// src/utils.ts
|
|
526
526
|
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
527
527
|
var NANOID_LENGTH = 21;
|
|
528
|
+
var RESOURCE_NAME_PATTERN = /^[a-zA-Z0-9\-_.]+$/;
|
|
529
|
+
function validateLabel(label) {
|
|
530
|
+
if (label === void 0) return;
|
|
531
|
+
const labels = Array.isArray(label) ? label : [label];
|
|
532
|
+
if (labels.length === 0) {
|
|
533
|
+
throw new WorkflowNonRetryableError("Invalid label: label array must not be empty.");
|
|
534
|
+
}
|
|
535
|
+
for (const value of labels) {
|
|
536
|
+
if (!RESOURCE_NAME_PATTERN.test(value)) {
|
|
537
|
+
throw new WorkflowNonRetryableError(
|
|
538
|
+
`Invalid label "${value}": must be alphanumeric, hyphen, underscore, or period.`
|
|
539
|
+
);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
function serializeLabel(label) {
|
|
544
|
+
return Array.isArray(label) ? label.join(",") : label;
|
|
545
|
+
}
|
|
546
|
+
function validateFlowControl(flowControl) {
|
|
547
|
+
if (flowControl?.key !== void 0 && !RESOURCE_NAME_PATTERN.test(flowControl.key)) {
|
|
548
|
+
throw new WorkflowNonRetryableError(
|
|
549
|
+
`Invalid flow control key "${flowControl.key}": must be alphanumeric, hyphen, underscore, or period.`
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
528
553
|
function getRandomInt() {
|
|
529
554
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
530
555
|
}
|
|
@@ -1060,8 +1085,8 @@ var triggerFirstInvocation = async (params) => {
|
|
|
1060
1085
|
if (unknownSdk) {
|
|
1061
1086
|
headers[WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER] = "true";
|
|
1062
1087
|
}
|
|
1063
|
-
if (workflowContext.
|
|
1064
|
-
headers[WORKFLOW_LABEL_HEADER] = workflowContext.
|
|
1088
|
+
if (workflowContext.labels.length > 0) {
|
|
1089
|
+
headers[WORKFLOW_LABEL_HEADER] = serializeLabel(workflowContext.labels);
|
|
1065
1090
|
}
|
|
1066
1091
|
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
1067
1092
|
return {
|
|
@@ -1863,8 +1888,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1863
1888
|
});
|
|
1864
1889
|
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1865
1890
|
if (label) {
|
|
1866
|
-
|
|
1867
|
-
triggerHeaders[
|
|
1891
|
+
const labelHeader = serializeLabel(label);
|
|
1892
|
+
triggerHeaders[WORKFLOW_LABEL_HEADER] = labelHeader;
|
|
1893
|
+
triggerHeaders[`upstash-forward-${WORKFLOW_LABEL_HEADER}`] = labelHeader;
|
|
1868
1894
|
}
|
|
1869
1895
|
return { headers: triggerHeaders, contentType };
|
|
1870
1896
|
}
|
|
@@ -3005,9 +3031,10 @@ var WorkflowContext = class {
|
|
|
3005
3031
|
*/
|
|
3006
3032
|
env;
|
|
3007
3033
|
/**
|
|
3008
|
-
*
|
|
3034
|
+
* Labels attached to the workflow run.
|
|
3009
3035
|
*
|
|
3010
|
-
* Can be used to filter the workflow run logs.
|
|
3036
|
+
* Can be used to filter the workflow run logs. A run can have multiple
|
|
3037
|
+
* labels when triggered with `label: string[]`.
|
|
3011
3038
|
*
|
|
3012
3039
|
* Can be set by passing a `label` parameter when triggering the workflow
|
|
3013
3040
|
* with `client.trigger`:
|
|
@@ -3015,11 +3042,20 @@ var WorkflowContext = class {
|
|
|
3015
3042
|
* ```ts
|
|
3016
3043
|
* await client.trigger({
|
|
3017
3044
|
* url: "https://workflow-endpoint.com",
|
|
3018
|
-
* label: "
|
|
3045
|
+
* label: ["label-1", "label-2"]
|
|
3019
3046
|
* });
|
|
3020
3047
|
* ```
|
|
3021
3048
|
*/
|
|
3022
|
-
|
|
3049
|
+
labels;
|
|
3050
|
+
/**
|
|
3051
|
+
* Label of the workflow run.
|
|
3052
|
+
*
|
|
3053
|
+
* @deprecated Use `labels` instead. When a run has multiple labels, this
|
|
3054
|
+
* only returns the first one.
|
|
3055
|
+
*/
|
|
3056
|
+
get label() {
|
|
3057
|
+
return this.labels[0];
|
|
3058
|
+
}
|
|
3023
3059
|
/**
|
|
3024
3060
|
* Number of times QStash has retried delivering the current request.
|
|
3025
3061
|
*
|
|
@@ -3050,7 +3086,7 @@ var WorkflowContext = class {
|
|
|
3050
3086
|
this.headers = headers;
|
|
3051
3087
|
this.requestPayload = initialPayload;
|
|
3052
3088
|
this.env = env ?? {};
|
|
3053
|
-
this.
|
|
3089
|
+
this.labels = label === void 0 ? [] : Array.isArray(label) ? label : label ? label.split(",") : [];
|
|
3054
3090
|
this.retried = retried ?? 0;
|
|
3055
3091
|
const middlewareManagerInstance = middlewareManager ?? new MiddlewareManager([]);
|
|
3056
3092
|
middlewareManagerInstance.assignContext(this);
|
|
@@ -3131,8 +3167,10 @@ var WorkflowContext = class {
|
|
|
3131
3167
|
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
3132
3168
|
}
|
|
3133
3169
|
async call(stepName, settings) {
|
|
3170
|
+
validateFlowControl(settings.flowControl);
|
|
3134
3171
|
let callStep;
|
|
3135
3172
|
if ("workflow" in settings) {
|
|
3173
|
+
validateLabel(settings.label);
|
|
3136
3174
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
3137
3175
|
const stringBody = typeof settings.body === "string" ? settings.body : settings.body === void 0 ? void 0 : JSON.stringify(settings.body);
|
|
3138
3176
|
callStep = new LazyCallStep({
|
|
@@ -3240,6 +3278,8 @@ var WorkflowContext = class {
|
|
|
3240
3278
|
);
|
|
3241
3279
|
}
|
|
3242
3280
|
async invoke(stepName, settings) {
|
|
3281
|
+
validateLabel(settings.label);
|
|
3282
|
+
validateFlowControl(settings.flowControl);
|
|
3243
3283
|
return await this.addStep(
|
|
3244
3284
|
new LazyInvokeStep(this, stepName, settings)
|
|
3245
3285
|
);
|
|
@@ -3325,7 +3365,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3325
3365
|
url: context.url,
|
|
3326
3366
|
initialPayload: context.requestPayload,
|
|
3327
3367
|
env: context.env,
|
|
3328
|
-
label: context.
|
|
3368
|
+
label: context.labels,
|
|
3329
3369
|
retried: context.retried
|
|
3330
3370
|
});
|
|
3331
3371
|
try {
|
package/h3.mjs
CHANGED
package/hono.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Context } from 'hono';
|
|
2
|
-
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-
|
|
2
|
+
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-CekOpKvz.mjs';
|
|
3
3
|
import { Variables } from 'hono/types';
|
|
4
|
-
import { s as serveManyBase } from './serve-many-
|
|
4
|
+
import { s as serveManyBase } from './serve-many-CG3BFvO3.mjs';
|
|
5
5
|
import '@upstash/qstash';
|
|
6
6
|
import 'zod';
|
|
7
7
|
|
package/hono.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Context } from 'hono';
|
|
2
|
-
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-
|
|
2
|
+
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-CekOpKvz.js';
|
|
3
3
|
import { Variables } from 'hono/types';
|
|
4
|
-
import { s as serveManyBase } from './serve-many-
|
|
4
|
+
import { s as serveManyBase } from './serve-many-iJF1IUXk.js';
|
|
5
5
|
import '@upstash/qstash';
|
|
6
6
|
import 'zod';
|
|
7
7
|
|
package/hono.js
CHANGED
|
@@ -216,6 +216,31 @@ var import_qstash4 = require("@upstash/qstash");
|
|
|
216
216
|
// src/utils.ts
|
|
217
217
|
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
218
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
|
+
}
|
|
219
244
|
function getRandomInt() {
|
|
220
245
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
221
246
|
}
|
|
@@ -751,8 +776,8 @@ var triggerFirstInvocation = async (params) => {
|
|
|
751
776
|
if (unknownSdk) {
|
|
752
777
|
headers[WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER] = "true";
|
|
753
778
|
}
|
|
754
|
-
if (workflowContext.
|
|
755
|
-
headers[WORKFLOW_LABEL_HEADER] = workflowContext.
|
|
779
|
+
if (workflowContext.labels.length > 0) {
|
|
780
|
+
headers[WORKFLOW_LABEL_HEADER] = serializeLabel(workflowContext.labels);
|
|
756
781
|
}
|
|
757
782
|
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
758
783
|
return {
|
|
@@ -1554,8 +1579,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1554
1579
|
});
|
|
1555
1580
|
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1556
1581
|
if (label) {
|
|
1557
|
-
|
|
1558
|
-
triggerHeaders[
|
|
1582
|
+
const labelHeader = serializeLabel(label);
|
|
1583
|
+
triggerHeaders[WORKFLOW_LABEL_HEADER] = labelHeader;
|
|
1584
|
+
triggerHeaders[`upstash-forward-${WORKFLOW_LABEL_HEADER}`] = labelHeader;
|
|
1559
1585
|
}
|
|
1560
1586
|
return { headers: triggerHeaders, contentType };
|
|
1561
1587
|
}
|
|
@@ -2696,9 +2722,10 @@ var WorkflowContext = class {
|
|
|
2696
2722
|
*/
|
|
2697
2723
|
env;
|
|
2698
2724
|
/**
|
|
2699
|
-
*
|
|
2725
|
+
* Labels attached to the workflow run.
|
|
2700
2726
|
*
|
|
2701
|
-
* 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[]`.
|
|
2702
2729
|
*
|
|
2703
2730
|
* Can be set by passing a `label` parameter when triggering the workflow
|
|
2704
2731
|
* with `client.trigger`:
|
|
@@ -2706,11 +2733,20 @@ var WorkflowContext = class {
|
|
|
2706
2733
|
* ```ts
|
|
2707
2734
|
* await client.trigger({
|
|
2708
2735
|
* url: "https://workflow-endpoint.com",
|
|
2709
|
-
* label: "
|
|
2736
|
+
* label: ["label-1", "label-2"]
|
|
2710
2737
|
* });
|
|
2711
2738
|
* ```
|
|
2712
2739
|
*/
|
|
2713
|
-
|
|
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
|
+
}
|
|
2714
2750
|
/**
|
|
2715
2751
|
* Number of times QStash has retried delivering the current request.
|
|
2716
2752
|
*
|
|
@@ -2741,7 +2777,7 @@ var WorkflowContext = class {
|
|
|
2741
2777
|
this.headers = headers;
|
|
2742
2778
|
this.requestPayload = initialPayload;
|
|
2743
2779
|
this.env = env ?? {};
|
|
2744
|
-
this.
|
|
2780
|
+
this.labels = label === void 0 ? [] : Array.isArray(label) ? label : label ? label.split(",") : [];
|
|
2745
2781
|
this.retried = retried ?? 0;
|
|
2746
2782
|
const middlewareManagerInstance = middlewareManager ?? new MiddlewareManager([]);
|
|
2747
2783
|
middlewareManagerInstance.assignContext(this);
|
|
@@ -2822,8 +2858,10 @@ var WorkflowContext = class {
|
|
|
2822
2858
|
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
2823
2859
|
}
|
|
2824
2860
|
async call(stepName, settings) {
|
|
2861
|
+
validateFlowControl(settings.flowControl);
|
|
2825
2862
|
let callStep;
|
|
2826
2863
|
if ("workflow" in settings) {
|
|
2864
|
+
validateLabel(settings.label);
|
|
2827
2865
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2828
2866
|
const stringBody = typeof settings.body === "string" ? settings.body : settings.body === void 0 ? void 0 : JSON.stringify(settings.body);
|
|
2829
2867
|
callStep = new LazyCallStep({
|
|
@@ -2931,6 +2969,8 @@ var WorkflowContext = class {
|
|
|
2931
2969
|
);
|
|
2932
2970
|
}
|
|
2933
2971
|
async invoke(stepName, settings) {
|
|
2972
|
+
validateLabel(settings.label);
|
|
2973
|
+
validateFlowControl(settings.flowControl);
|
|
2934
2974
|
return await this.addStep(
|
|
2935
2975
|
new LazyInvokeStep(this, stepName, settings)
|
|
2936
2976
|
);
|
|
@@ -3016,7 +3056,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3016
3056
|
url: context.url,
|
|
3017
3057
|
initialPayload: context.requestPayload,
|
|
3018
3058
|
env: context.env,
|
|
3019
|
-
label: context.
|
|
3059
|
+
label: context.labels,
|
|
3020
3060
|
retried: context.retried
|
|
3021
3061
|
});
|
|
3022
3062
|
try {
|
package/hono.mjs
CHANGED
package/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as StepType, R as RawStep, W as WorkflowMiddleware, a as WorkflowClient, b as WorkflowReceiver, c as RouteFunction, d as WorkflowServeOptions, T as Telemetry, N as NotifyResponse, e as Waiter } from './types-
|
|
2
|
-
export { A as AsyncStepFunction, C as CallResponse, f as CallSettings, D as DetailedFinishCondition, g as Duration, E as ExclusiveValidationOptions, F as FailureFunctionPayload, h as FinishCondition, H as HeaderParams, I as InvokableWorkflow, i as InvokeStepResponse, j as InvokeWorkflowRequest, L as LazyInvokeStepParams, k as NotifyStepResponse, P as ParallelCallState, Q as QStashClientExtraConfig, l as RequiredExceptFields, m as Step, n as StepFunction, o as StepTypes, p as SyncStepFunction, q as WaitEventOptions, r as WaitRequest, s as WaitStepResponse, t as WorkflowAbort, u as WorkflowContext, v as WorkflowError, w as WorkflowNonRetryableError, x as WorkflowRetryAfterError } from './types-
|
|
1
|
+
import { S as StepType, R as RawStep, W as WorkflowMiddleware, a as WorkflowClient, b as WorkflowReceiver, c as RouteFunction, d as WorkflowServeOptions, T as Telemetry, N as NotifyResponse, e as Waiter } from './types-CekOpKvz.mjs';
|
|
2
|
+
export { A as AsyncStepFunction, C as CallResponse, f as CallSettings, D as DetailedFinishCondition, g as Duration, E as ExclusiveValidationOptions, F as FailureFunctionPayload, h as FinishCondition, H as HeaderParams, I as InvokableWorkflow, i as InvokeStepResponse, j as InvokeWorkflowRequest, L as LazyInvokeStepParams, k as NotifyStepResponse, P as ParallelCallState, Q as QStashClientExtraConfig, l as RequiredExceptFields, m as Step, n as StepFunction, o as StepTypes, p as SyncStepFunction, q as WaitEventOptions, r as WaitRequest, s as WaitStepResponse, t as WorkflowAbort, u as WorkflowContext, v as WorkflowError, w as WorkflowNonRetryableError, x as WorkflowRetryAfterError } from './types-CekOpKvz.mjs';
|
|
3
3
|
import { FlowControl, PublishRequest, HTTPMethods, Client as Client$1 } from '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
@@ -317,9 +317,18 @@ type WorkflowRunLog = {
|
|
|
317
317
|
*/
|
|
318
318
|
dlqId?: string;
|
|
319
319
|
/**
|
|
320
|
-
* Label of the workflow run
|
|
320
|
+
* Label of the workflow run.
|
|
321
|
+
*
|
|
322
|
+
* @deprecated Use `labels` instead. When a run has multiple labels, this
|
|
323
|
+
* field only contains the first one.
|
|
321
324
|
*/
|
|
322
325
|
label?: string;
|
|
326
|
+
/**
|
|
327
|
+
* Labels attached to the workflow run.
|
|
328
|
+
*
|
|
329
|
+
* A run can have multiple labels when triggered with `label: string[]`.
|
|
330
|
+
*/
|
|
331
|
+
labels?: string[];
|
|
323
332
|
};
|
|
324
333
|
type WorkflowRunLogs = {
|
|
325
334
|
cursor: string;
|
|
@@ -403,8 +412,11 @@ type TriggerOptions = {
|
|
|
403
412
|
* Label to apply to the workflow run.
|
|
404
413
|
*
|
|
405
414
|
* Can be used to filter the workflow run logs.
|
|
415
|
+
*
|
|
416
|
+
* Pass an array to attach multiple labels to a single workflow run; they are
|
|
417
|
+
* sent as a comma-separated value in the `Upstash-Label` header.
|
|
406
418
|
*/
|
|
407
|
-
label?: string;
|
|
419
|
+
label?: string | string[];
|
|
408
420
|
/**
|
|
409
421
|
* By default, Workflow SDK sends telemetry about SDK version, framework or runtime.
|
|
410
422
|
*
|
|
@@ -526,7 +538,14 @@ type UniversalFilterFields = {
|
|
|
526
538
|
fromDate?: Date | number;
|
|
527
539
|
toDate?: Date | number;
|
|
528
540
|
callerIp?: string;
|
|
529
|
-
|
|
541
|
+
/**
|
|
542
|
+
* Filter by label.
|
|
543
|
+
*
|
|
544
|
+
* Pass an array to match runs that have any of the given labels (OR semantics).
|
|
545
|
+
* For example, with runs labelled `[label_1, label_2]` and `[label_2, label_3]`,
|
|
546
|
+
* filtering by `[label_1, label_2]` returns both.
|
|
547
|
+
*/
|
|
548
|
+
label?: string | string[];
|
|
530
549
|
flowControlKey?: string;
|
|
531
550
|
};
|
|
532
551
|
/** Workflow-specific filter fields for DLQ and bulk endpoints. */
|
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as StepType, R as RawStep, W as WorkflowMiddleware, a as WorkflowClient, b as WorkflowReceiver, c as RouteFunction, d as WorkflowServeOptions, T as Telemetry, N as NotifyResponse, e as Waiter } from './types-
|
|
2
|
-
export { A as AsyncStepFunction, C as CallResponse, f as CallSettings, D as DetailedFinishCondition, g as Duration, E as ExclusiveValidationOptions, F as FailureFunctionPayload, h as FinishCondition, H as HeaderParams, I as InvokableWorkflow, i as InvokeStepResponse, j as InvokeWorkflowRequest, L as LazyInvokeStepParams, k as NotifyStepResponse, P as ParallelCallState, Q as QStashClientExtraConfig, l as RequiredExceptFields, m as Step, n as StepFunction, o as StepTypes, p as SyncStepFunction, q as WaitEventOptions, r as WaitRequest, s as WaitStepResponse, t as WorkflowAbort, u as WorkflowContext, v as WorkflowError, w as WorkflowNonRetryableError, x as WorkflowRetryAfterError } from './types-
|
|
1
|
+
import { S as StepType, R as RawStep, W as WorkflowMiddleware, a as WorkflowClient, b as WorkflowReceiver, c as RouteFunction, d as WorkflowServeOptions, T as Telemetry, N as NotifyResponse, e as Waiter } from './types-CekOpKvz.js';
|
|
2
|
+
export { A as AsyncStepFunction, C as CallResponse, f as CallSettings, D as DetailedFinishCondition, g as Duration, E as ExclusiveValidationOptions, F as FailureFunctionPayload, h as FinishCondition, H as HeaderParams, I as InvokableWorkflow, i as InvokeStepResponse, j as InvokeWorkflowRequest, L as LazyInvokeStepParams, k as NotifyStepResponse, P as ParallelCallState, Q as QStashClientExtraConfig, l as RequiredExceptFields, m as Step, n as StepFunction, o as StepTypes, p as SyncStepFunction, q as WaitEventOptions, r as WaitRequest, s as WaitStepResponse, t as WorkflowAbort, u as WorkflowContext, v as WorkflowError, w as WorkflowNonRetryableError, x as WorkflowRetryAfterError } from './types-CekOpKvz.js';
|
|
3
3
|
import { FlowControl, PublishRequest, HTTPMethods, Client as Client$1 } from '@upstash/qstash';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
@@ -317,9 +317,18 @@ type WorkflowRunLog = {
|
|
|
317
317
|
*/
|
|
318
318
|
dlqId?: string;
|
|
319
319
|
/**
|
|
320
|
-
* Label of the workflow run
|
|
320
|
+
* Label of the workflow run.
|
|
321
|
+
*
|
|
322
|
+
* @deprecated Use `labels` instead. When a run has multiple labels, this
|
|
323
|
+
* field only contains the first one.
|
|
321
324
|
*/
|
|
322
325
|
label?: string;
|
|
326
|
+
/**
|
|
327
|
+
* Labels attached to the workflow run.
|
|
328
|
+
*
|
|
329
|
+
* A run can have multiple labels when triggered with `label: string[]`.
|
|
330
|
+
*/
|
|
331
|
+
labels?: string[];
|
|
323
332
|
};
|
|
324
333
|
type WorkflowRunLogs = {
|
|
325
334
|
cursor: string;
|
|
@@ -403,8 +412,11 @@ type TriggerOptions = {
|
|
|
403
412
|
* Label to apply to the workflow run.
|
|
404
413
|
*
|
|
405
414
|
* Can be used to filter the workflow run logs.
|
|
415
|
+
*
|
|
416
|
+
* Pass an array to attach multiple labels to a single workflow run; they are
|
|
417
|
+
* sent as a comma-separated value in the `Upstash-Label` header.
|
|
406
418
|
*/
|
|
407
|
-
label?: string;
|
|
419
|
+
label?: string | string[];
|
|
408
420
|
/**
|
|
409
421
|
* By default, Workflow SDK sends telemetry about SDK version, framework or runtime.
|
|
410
422
|
*
|
|
@@ -526,7 +538,14 @@ type UniversalFilterFields = {
|
|
|
526
538
|
fromDate?: Date | number;
|
|
527
539
|
toDate?: Date | number;
|
|
528
540
|
callerIp?: string;
|
|
529
|
-
|
|
541
|
+
/**
|
|
542
|
+
* Filter by label.
|
|
543
|
+
*
|
|
544
|
+
* Pass an array to match runs that have any of the given labels (OR semantics).
|
|
545
|
+
* For example, with runs labelled `[label_1, label_2]` and `[label_2, label_3]`,
|
|
546
|
+
* filtering by `[label_1, label_2]` returns both.
|
|
547
|
+
*/
|
|
548
|
+
label?: string | string[];
|
|
530
549
|
flowControlKey?: string;
|
|
531
550
|
};
|
|
532
551
|
/** Workflow-specific filter fields for DLQ and bulk endpoints. */
|
package/index.js
CHANGED
|
@@ -290,6 +290,31 @@ var import_qstash4 = require("@upstash/qstash");
|
|
|
290
290
|
// src/utils.ts
|
|
291
291
|
var NANOID_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_";
|
|
292
292
|
var NANOID_LENGTH = 21;
|
|
293
|
+
var RESOURCE_NAME_PATTERN = /^[a-zA-Z0-9\-_.]+$/;
|
|
294
|
+
function validateLabel(label) {
|
|
295
|
+
if (label === void 0) return;
|
|
296
|
+
const labels = Array.isArray(label) ? label : [label];
|
|
297
|
+
if (labels.length === 0) {
|
|
298
|
+
throw new WorkflowNonRetryableError("Invalid label: label array must not be empty.");
|
|
299
|
+
}
|
|
300
|
+
for (const value of labels) {
|
|
301
|
+
if (!RESOURCE_NAME_PATTERN.test(value)) {
|
|
302
|
+
throw new WorkflowNonRetryableError(
|
|
303
|
+
`Invalid label "${value}": must be alphanumeric, hyphen, underscore, or period.`
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function serializeLabel(label) {
|
|
309
|
+
return Array.isArray(label) ? label.join(",") : label;
|
|
310
|
+
}
|
|
311
|
+
function validateFlowControl(flowControl) {
|
|
312
|
+
if (flowControl?.key !== void 0 && !RESOURCE_NAME_PATTERN.test(flowControl.key)) {
|
|
313
|
+
throw new WorkflowNonRetryableError(
|
|
314
|
+
`Invalid flow control key "${flowControl.key}": must be alphanumeric, hyphen, underscore, or period.`
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
293
318
|
function getRandomInt() {
|
|
294
319
|
return Math.floor(Math.random() * NANOID_CHARS.length);
|
|
295
320
|
}
|
|
@@ -825,8 +850,8 @@ var triggerFirstInvocation = async (params) => {
|
|
|
825
850
|
if (unknownSdk) {
|
|
826
851
|
headers[WORKFLOW_UNKOWN_SDK_TRIGGER_HEADER] = "true";
|
|
827
852
|
}
|
|
828
|
-
if (workflowContext.
|
|
829
|
-
headers[WORKFLOW_LABEL_HEADER] = workflowContext.
|
|
853
|
+
if (workflowContext.labels.length > 0) {
|
|
854
|
+
headers[WORKFLOW_LABEL_HEADER] = serializeLabel(workflowContext.labels);
|
|
830
855
|
}
|
|
831
856
|
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
832
857
|
return {
|
|
@@ -1628,8 +1653,9 @@ var LazyInvokeStep = class extends BaseLazyStep {
|
|
|
1628
1653
|
});
|
|
1629
1654
|
triggerHeaders["Upstash-Workflow-Invoke"] = "true";
|
|
1630
1655
|
if (label) {
|
|
1631
|
-
|
|
1632
|
-
triggerHeaders[
|
|
1656
|
+
const labelHeader = serializeLabel(label);
|
|
1657
|
+
triggerHeaders[WORKFLOW_LABEL_HEADER] = labelHeader;
|
|
1658
|
+
triggerHeaders[`upstash-forward-${WORKFLOW_LABEL_HEADER}`] = labelHeader;
|
|
1633
1659
|
}
|
|
1634
1660
|
return { headers: triggerHeaders, contentType };
|
|
1635
1661
|
}
|
|
@@ -2703,9 +2729,10 @@ var WorkflowContext = class {
|
|
|
2703
2729
|
*/
|
|
2704
2730
|
env;
|
|
2705
2731
|
/**
|
|
2706
|
-
*
|
|
2732
|
+
* Labels attached to the workflow run.
|
|
2707
2733
|
*
|
|
2708
|
-
* Can be used to filter the workflow run logs.
|
|
2734
|
+
* Can be used to filter the workflow run logs. A run can have multiple
|
|
2735
|
+
* labels when triggered with `label: string[]`.
|
|
2709
2736
|
*
|
|
2710
2737
|
* Can be set by passing a `label` parameter when triggering the workflow
|
|
2711
2738
|
* with `client.trigger`:
|
|
@@ -2713,11 +2740,20 @@ var WorkflowContext = class {
|
|
|
2713
2740
|
* ```ts
|
|
2714
2741
|
* await client.trigger({
|
|
2715
2742
|
* url: "https://workflow-endpoint.com",
|
|
2716
|
-
* label: "
|
|
2743
|
+
* label: ["label-1", "label-2"]
|
|
2717
2744
|
* });
|
|
2718
2745
|
* ```
|
|
2719
2746
|
*/
|
|
2720
|
-
|
|
2747
|
+
labels;
|
|
2748
|
+
/**
|
|
2749
|
+
* Label of the workflow run.
|
|
2750
|
+
*
|
|
2751
|
+
* @deprecated Use `labels` instead. When a run has multiple labels, this
|
|
2752
|
+
* only returns the first one.
|
|
2753
|
+
*/
|
|
2754
|
+
get label() {
|
|
2755
|
+
return this.labels[0];
|
|
2756
|
+
}
|
|
2721
2757
|
/**
|
|
2722
2758
|
* Number of times QStash has retried delivering the current request.
|
|
2723
2759
|
*
|
|
@@ -2748,7 +2784,7 @@ var WorkflowContext = class {
|
|
|
2748
2784
|
this.headers = headers;
|
|
2749
2785
|
this.requestPayload = initialPayload;
|
|
2750
2786
|
this.env = env ?? {};
|
|
2751
|
-
this.
|
|
2787
|
+
this.labels = label === void 0 ? [] : Array.isArray(label) ? label : label ? label.split(",") : [];
|
|
2752
2788
|
this.retried = retried ?? 0;
|
|
2753
2789
|
const middlewareManagerInstance = middlewareManager ?? new MiddlewareManager([]);
|
|
2754
2790
|
middlewareManagerInstance.assignContext(this);
|
|
@@ -2829,8 +2865,10 @@ var WorkflowContext = class {
|
|
|
2829
2865
|
await this.addStep(new LazySleepUntilStep(this, stepName, time));
|
|
2830
2866
|
}
|
|
2831
2867
|
async call(stepName, settings) {
|
|
2868
|
+
validateFlowControl(settings.flowControl);
|
|
2832
2869
|
let callStep;
|
|
2833
2870
|
if ("workflow" in settings) {
|
|
2871
|
+
validateLabel(settings.label);
|
|
2834
2872
|
const url = getNewUrlFromWorkflowId(this.url, settings.workflow.workflowId);
|
|
2835
2873
|
const stringBody = typeof settings.body === "string" ? settings.body : settings.body === void 0 ? void 0 : JSON.stringify(settings.body);
|
|
2836
2874
|
callStep = new LazyCallStep({
|
|
@@ -2938,6 +2976,8 @@ var WorkflowContext = class {
|
|
|
2938
2976
|
);
|
|
2939
2977
|
}
|
|
2940
2978
|
async invoke(stepName, settings) {
|
|
2979
|
+
validateLabel(settings.label);
|
|
2980
|
+
validateFlowControl(settings.flowControl);
|
|
2941
2981
|
return await this.addStep(
|
|
2942
2982
|
new LazyInvokeStep(this, stepName, settings)
|
|
2943
2983
|
);
|
|
@@ -3023,7 +3063,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
3023
3063
|
url: context.url,
|
|
3024
3064
|
initialPayload: context.requestPayload,
|
|
3025
3065
|
env: context.env,
|
|
3026
|
-
label: context.
|
|
3066
|
+
label: context.labels,
|
|
3027
3067
|
retried: context.retried
|
|
3028
3068
|
});
|
|
3029
3069
|
try {
|
|
@@ -4111,13 +4151,15 @@ var Client4 = class {
|
|
|
4111
4151
|
const isBatchInput = Array.isArray(params);
|
|
4112
4152
|
const options = isBatchInput ? params : [params];
|
|
4113
4153
|
const invocations = options.map((option) => {
|
|
4154
|
+
validateLabel(option.label);
|
|
4155
|
+
validateFlowControl(option.flowControl);
|
|
4114
4156
|
const failureUrl = option.failureUrl ?? option.url;
|
|
4115
4157
|
const finalWorkflowRunId = getWorkflowRunId(option.workflowRunId);
|
|
4116
4158
|
const context = new WorkflowContext({
|
|
4117
4159
|
qstashClient: this.client,
|
|
4118
4160
|
headers: new Headers({
|
|
4119
4161
|
...option.headers ?? {},
|
|
4120
|
-
...option.label ? { [WORKFLOW_LABEL_HEADER]: option.label } : {}
|
|
4162
|
+
...option.label ? { [WORKFLOW_LABEL_HEADER]: serializeLabel(option.label) } : {}
|
|
4121
4163
|
}),
|
|
4122
4164
|
initialPayload: option.body,
|
|
4123
4165
|
steps: [],
|
package/index.mjs
CHANGED
|
@@ -15,9 +15,12 @@ import {
|
|
|
15
15
|
makeNotifyRequest,
|
|
16
16
|
normalizeCursor,
|
|
17
17
|
prepareFlowControl,
|
|
18
|
+
serializeLabel,
|
|
18
19
|
serve,
|
|
19
|
-
triggerFirstInvocation
|
|
20
|
-
|
|
20
|
+
triggerFirstInvocation,
|
|
21
|
+
validateFlowControl,
|
|
22
|
+
validateLabel
|
|
23
|
+
} from "./chunk-CWCCIOXR.mjs";
|
|
21
24
|
|
|
22
25
|
// src/client/index.ts
|
|
23
26
|
import { Client as QStashClient } from "@upstash/qstash";
|
|
@@ -248,13 +251,15 @@ var Client = class {
|
|
|
248
251
|
const isBatchInput = Array.isArray(params);
|
|
249
252
|
const options = isBatchInput ? params : [params];
|
|
250
253
|
const invocations = options.map((option) => {
|
|
254
|
+
validateLabel(option.label);
|
|
255
|
+
validateFlowControl(option.flowControl);
|
|
251
256
|
const failureUrl = option.failureUrl ?? option.url;
|
|
252
257
|
const finalWorkflowRunId = getWorkflowRunId(option.workflowRunId);
|
|
253
258
|
const context = new WorkflowContext({
|
|
254
259
|
qstashClient: this.client,
|
|
255
260
|
headers: new Headers({
|
|
256
261
|
...option.headers ?? {},
|
|
257
|
-
...option.label ? { [WORKFLOW_LABEL_HEADER]: option.label } : {}
|
|
262
|
+
...option.label ? { [WORKFLOW_LABEL_HEADER]: serializeLabel(option.label) } : {}
|
|
258
263
|
}),
|
|
259
264
|
initialPayload: option.body,
|
|
260
265
|
steps: [],
|
package/nextjs.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
-
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-CekOpKvz.mjs';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-CG3BFvO3.mjs';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
package/nextjs.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
-
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-
|
|
3
|
-
import { s as serveManyBase } from './serve-many-
|
|
2
|
+
import { c as RouteFunction, d as WorkflowServeOptions, I as InvokableWorkflow } from './types-CekOpKvz.js';
|
|
3
|
+
import { s as serveManyBase } from './serve-many-iJF1IUXk.js';
|
|
4
4
|
import '@upstash/qstash';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|