@upstash/workflow 0.2.17 → 0.2.18

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/h3.js CHANGED
@@ -398,12 +398,13 @@ var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
398
398
  var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
399
399
  var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
400
400
  var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
401
+ var WORKFLOW_LABEL_HEADER = "Upstash-Label";
401
402
  var WORKFLOW_PROTOCOL_VERSION = "1";
402
403
  var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
403
404
  var DEFAULT_CONTENT_TYPE = "application/json";
404
405
  var NO_CONCURRENCY = 1;
405
406
  var DEFAULT_RETRIES = 3;
406
- var VERSION = "v0.2.17";
407
+ var VERSION = "v0.2.18";
407
408
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
408
409
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
409
410
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -947,6 +948,9 @@ var triggerFirstInvocation = async (params) => {
947
948
  if (useJSONContent) {
948
949
  headers["content-type"] = "application/json";
949
950
  }
951
+ if (workflowContext.label) {
952
+ headers[WORKFLOW_LABEL_HEADER] = workflowContext.label;
953
+ }
950
954
  const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
951
955
  return {
952
956
  headers,
@@ -1047,10 +1051,11 @@ var recreateUserHeaders = (headers) => {
1047
1051
  const pairs = headers.entries();
1048
1052
  for (const [header, value] of pairs) {
1049
1053
  const headerLowerCase = header.toLowerCase();
1050
- if (!headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
1054
+ const isUserHeader = !headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
1051
1055
  !headerLowerCase.startsWith("x-vercel-") && !headerLowerCase.startsWith("x-forwarded-") && // https://blog.cloudflare.com/preventing-request-loops-using-cdn-loop/
1052
1056
  headerLowerCase !== "cf-connecting-ip" && headerLowerCase !== "cdn-loop" && headerLowerCase !== "cf-ew-via" && headerLowerCase !== "cf-ray" && // For Render https://render.com
1053
- headerLowerCase !== "render-proxy-ttl") {
1057
+ headerLowerCase !== "render-proxy-ttl" || headerLowerCase === WORKFLOW_LABEL_HEADER.toLocaleLowerCase();
1058
+ if (isUserHeader) {
1054
1059
  filteredHeaders.append(header, value);
1055
1060
  }
1056
1061
  }
@@ -3080,6 +3085,22 @@ var WorkflowContext = class {
3080
3085
  * and number of requests per second with the same key.
3081
3086
  */
3082
3087
  flowControl;
3088
+ /**
3089
+ * Label to apply to the workflow run.
3090
+ *
3091
+ * Can be used to filter the workflow run logs.
3092
+ *
3093
+ * Can be set by passing a `label` parameter when triggering the workflow
3094
+ * with `client.trigger`:
3095
+ *
3096
+ * ```ts
3097
+ * await client.trigger({
3098
+ * url: "https://workflow-endpoint.com",
3099
+ * label: "my-label"
3100
+ * });
3101
+ * ```
3102
+ */
3103
+ label;
3083
3104
  constructor({
3084
3105
  qstashClient,
3085
3106
  workflowRunId,
@@ -3094,7 +3115,8 @@ var WorkflowContext = class {
3094
3115
  retryDelay,
3095
3116
  telemetry: telemetry2,
3096
3117
  invokeCount,
3097
- flowControl
3118
+ flowControl,
3119
+ label
3098
3120
  }) {
3099
3121
  this.qstashClient = qstashClient;
3100
3122
  this.workflowRunId = workflowRunId;
@@ -3107,6 +3129,7 @@ var WorkflowContext = class {
3107
3129
  this.retries = retries ?? DEFAULT_RETRIES;
3108
3130
  this.retryDelay = retryDelay;
3109
3131
  this.flowControl = flowControl;
3132
+ this.label = label;
3110
3133
  this.executor = new AutoExecutor(this, this.steps, telemetry2, invokeCount, debug);
3111
3134
  }
3112
3135
  /**
@@ -3407,7 +3430,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3407
3430
  env: context.env,
3408
3431
  retries: context.retries,
3409
3432
  retryDelay: context.retryDelay,
3410
- flowControl: context.flowControl
3433
+ flowControl: context.flowControl,
3434
+ label: context.label
3411
3435
  });
3412
3436
  try {
3413
3437
  await routeFunction(disabledContext);
@@ -3584,11 +3608,12 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3584
3608
  if (!errorMessage) {
3585
3609
  errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
3586
3610
  }
3611
+ const userHeaders = recreateUserHeaders(request.headers);
3587
3612
  const workflowContext = new WorkflowContext({
3588
3613
  qstashClient,
3589
3614
  workflowRunId,
3590
3615
  initialPayload: sourceBody ? initialPayloadParser(decodeBase64(sourceBody)) : void 0,
3591
- headers: recreateUserHeaders(request.headers),
3616
+ headers: userHeaders,
3592
3617
  steps: [],
3593
3618
  url,
3594
3619
  failureUrl: url,
@@ -3597,8 +3622,9 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3597
3622
  retries,
3598
3623
  retryDelay,
3599
3624
  flowControl,
3600
- telemetry: void 0
3625
+ telemetry: void 0,
3601
3626
  // not going to make requests in authentication check
3627
+ label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0
3602
3628
  });
3603
3629
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
3604
3630
  routeFunction,
@@ -3807,6 +3833,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3807
3833
  });
3808
3834
  }
3809
3835
  const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
3836
+ const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
3810
3837
  const workflowContext = new WorkflowContext({
3811
3838
  qstashClient,
3812
3839
  workflowRunId,
@@ -3821,7 +3848,8 @@ var serveBase = (routeFunction, telemetry2, options) => {
3821
3848
  retryDelay,
3822
3849
  telemetry: telemetry2,
3823
3850
  invokeCount,
3824
- flowControl
3851
+ flowControl,
3852
+ label
3825
3853
  });
3826
3854
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
3827
3855
  routeFunction,
package/h3.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-RP7G4UD5.mjs";
5
+ } from "./chunk-EHL7SSJF.mjs";
6
6
 
7
7
  // node_modules/defu/dist/defu.mjs
8
8
  function isPlainObject(value) {
package/hono.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Context } from 'hono';
2
- import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.mjs';
2
+ import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types-B7_5AkKQ.mjs';
3
3
  import { Variables } from 'hono/types';
4
- import { s as serveManyBase } from './serve-many-DgDSOvQs.mjs';
4
+ import { s as serveManyBase } from './serve-many-CEUYWQvV.mjs';
5
5
  import '@upstash/qstash';
6
6
  import 'zod';
7
7
  import 'ai';
package/hono.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Context } from 'hono';
2
- import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.js';
2
+ import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types-B7_5AkKQ.js';
3
3
  import { Variables } from 'hono/types';
4
- import { s as serveManyBase } from './serve-many-B3DfoTFt.js';
4
+ import { s as serveManyBase } from './serve-many-BObe3pdI.js';
5
5
  import '@upstash/qstash';
6
6
  import 'zod';
7
7
  import 'ai';
package/hono.js CHANGED
@@ -86,12 +86,13 @@ var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
86
86
  var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
87
87
  var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
88
88
  var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
89
+ var WORKFLOW_LABEL_HEADER = "Upstash-Label";
89
90
  var WORKFLOW_PROTOCOL_VERSION = "1";
90
91
  var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
91
92
  var DEFAULT_CONTENT_TYPE = "application/json";
92
93
  var NO_CONCURRENCY = 1;
93
94
  var DEFAULT_RETRIES = 3;
94
- var VERSION = "v0.2.17";
95
+ var VERSION = "v0.2.18";
95
96
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
96
97
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
97
98
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -635,6 +636,9 @@ var triggerFirstInvocation = async (params) => {
635
636
  if (useJSONContent) {
636
637
  headers["content-type"] = "application/json";
637
638
  }
639
+ if (workflowContext.label) {
640
+ headers[WORKFLOW_LABEL_HEADER] = workflowContext.label;
641
+ }
638
642
  const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
639
643
  return {
640
644
  headers,
@@ -735,10 +739,11 @@ var recreateUserHeaders = (headers) => {
735
739
  const pairs = headers.entries();
736
740
  for (const [header, value] of pairs) {
737
741
  const headerLowerCase = header.toLowerCase();
738
- if (!headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
742
+ const isUserHeader = !headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
739
743
  !headerLowerCase.startsWith("x-vercel-") && !headerLowerCase.startsWith("x-forwarded-") && // https://blog.cloudflare.com/preventing-request-loops-using-cdn-loop/
740
744
  headerLowerCase !== "cf-connecting-ip" && headerLowerCase !== "cdn-loop" && headerLowerCase !== "cf-ew-via" && headerLowerCase !== "cf-ray" && // For Render https://render.com
741
- headerLowerCase !== "render-proxy-ttl") {
745
+ headerLowerCase !== "render-proxy-ttl" || headerLowerCase === WORKFLOW_LABEL_HEADER.toLocaleLowerCase();
746
+ if (isUserHeader) {
742
747
  filteredHeaders.append(header, value);
743
748
  }
744
749
  }
@@ -2768,6 +2773,22 @@ var WorkflowContext = class {
2768
2773
  * and number of requests per second with the same key.
2769
2774
  */
2770
2775
  flowControl;
2776
+ /**
2777
+ * Label to apply to the workflow run.
2778
+ *
2779
+ * Can be used to filter the workflow run logs.
2780
+ *
2781
+ * Can be set by passing a `label` parameter when triggering the workflow
2782
+ * with `client.trigger`:
2783
+ *
2784
+ * ```ts
2785
+ * await client.trigger({
2786
+ * url: "https://workflow-endpoint.com",
2787
+ * label: "my-label"
2788
+ * });
2789
+ * ```
2790
+ */
2791
+ label;
2771
2792
  constructor({
2772
2793
  qstashClient,
2773
2794
  workflowRunId,
@@ -2782,7 +2803,8 @@ var WorkflowContext = class {
2782
2803
  retryDelay,
2783
2804
  telemetry: telemetry2,
2784
2805
  invokeCount,
2785
- flowControl
2806
+ flowControl,
2807
+ label
2786
2808
  }) {
2787
2809
  this.qstashClient = qstashClient;
2788
2810
  this.workflowRunId = workflowRunId;
@@ -2795,6 +2817,7 @@ var WorkflowContext = class {
2795
2817
  this.retries = retries ?? DEFAULT_RETRIES;
2796
2818
  this.retryDelay = retryDelay;
2797
2819
  this.flowControl = flowControl;
2820
+ this.label = label;
2798
2821
  this.executor = new AutoExecutor(this, this.steps, telemetry2, invokeCount, debug);
2799
2822
  }
2800
2823
  /**
@@ -3095,7 +3118,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3095
3118
  env: context.env,
3096
3119
  retries: context.retries,
3097
3120
  retryDelay: context.retryDelay,
3098
- flowControl: context.flowControl
3121
+ flowControl: context.flowControl,
3122
+ label: context.label
3099
3123
  });
3100
3124
  try {
3101
3125
  await routeFunction(disabledContext);
@@ -3272,11 +3296,12 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3272
3296
  if (!errorMessage) {
3273
3297
  errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
3274
3298
  }
3299
+ const userHeaders = recreateUserHeaders(request.headers);
3275
3300
  const workflowContext = new WorkflowContext({
3276
3301
  qstashClient,
3277
3302
  workflowRunId,
3278
3303
  initialPayload: sourceBody ? initialPayloadParser(decodeBase64(sourceBody)) : void 0,
3279
- headers: recreateUserHeaders(request.headers),
3304
+ headers: userHeaders,
3280
3305
  steps: [],
3281
3306
  url,
3282
3307
  failureUrl: url,
@@ -3285,8 +3310,9 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3285
3310
  retries,
3286
3311
  retryDelay,
3287
3312
  flowControl,
3288
- telemetry: void 0
3313
+ telemetry: void 0,
3289
3314
  // not going to make requests in authentication check
3315
+ label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0
3290
3316
  });
3291
3317
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
3292
3318
  routeFunction,
@@ -3495,6 +3521,7 @@ var serveBase = (routeFunction, telemetry2, options) => {
3495
3521
  });
3496
3522
  }
3497
3523
  const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
3524
+ const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
3498
3525
  const workflowContext = new WorkflowContext({
3499
3526
  qstashClient,
3500
3527
  workflowRunId,
@@ -3509,7 +3536,8 @@ var serveBase = (routeFunction, telemetry2, options) => {
3509
3536
  retryDelay,
3510
3537
  telemetry: telemetry2,
3511
3538
  invokeCount,
3512
- flowControl
3539
+ flowControl,
3540
+ label
3513
3541
  });
3514
3542
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
3515
3543
  routeFunction,
package/hono.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  SDK_TELEMETRY,
3
3
  serveBase,
4
4
  serveManyBase
5
- } from "./chunk-RP7G4UD5.mjs";
5
+ } from "./chunk-EHL7SSJF.mjs";
6
6
 
7
7
  // platforms/hono.ts
8
8
  var telemetry = {
package/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouteFunction, W as WorkflowServeOptions, E as ExclusiveValidationOptions, T as Telemetry, S as StepType, a as RawStep, N as NotifyResponse, b as Waiter } from './types--R_3XZXz.mjs';
2
- export { A as AsyncStepFunction, C as CallResponse, v as CallSettings, D as DetailedFinishCondition, t as Duration, o as FailureFunctionPayload, F as FinishCondition, H as HeaderParams, x as InvokableWorkflow, w as InvokeStepResponse, I as InvokeWorkflowRequest, L as LazyInvokeStepParams, y as LogLevel, s as NotifyStepResponse, P as ParallelCallState, n as PublicServeOptions, p as RequiredExceptFields, k as Step, m as StepFunction, j as StepTypes, l as SyncStepFunction, u as WaitEventOptions, q as WaitRequest, r as WaitStepResponse, d as WorkflowAbort, h as WorkflowClient, g as WorkflowContext, c as WorkflowError, B as WorkflowLogger, z as WorkflowLoggerOptions, e as WorkflowNonRetryableError, i as WorkflowReceiver, f as WorkflowTool } from './types--R_3XZXz.mjs';
1
+ import { R as RouteFunction, W as WorkflowServeOptions, E as ExclusiveValidationOptions, T as Telemetry, S as StepType, a as RawStep, N as NotifyResponse, b as Waiter } from './types-B7_5AkKQ.mjs';
2
+ export { A as AsyncStepFunction, C as CallResponse, v as CallSettings, D as DetailedFinishCondition, t as Duration, o as FailureFunctionPayload, F as FinishCondition, H as HeaderParams, x as InvokableWorkflow, w as InvokeStepResponse, I as InvokeWorkflowRequest, L as LazyInvokeStepParams, y as LogLevel, s as NotifyStepResponse, P as ParallelCallState, n as PublicServeOptions, p as RequiredExceptFields, k as Step, m as StepFunction, j as StepTypes, l as SyncStepFunction, u as WaitEventOptions, q as WaitRequest, r as WaitStepResponse, d as WorkflowAbort, h as WorkflowClient, g as WorkflowContext, c as WorkflowError, B as WorkflowLogger, z as WorkflowLoggerOptions, e as WorkflowNonRetryableError, i as WorkflowReceiver, f as WorkflowTool } from './types-B7_5AkKQ.mjs';
3
3
  import { FlowControl, PublishRequest, HTTPMethods, State, Client as Client$1 } from '@upstash/qstash';
4
4
  import 'zod';
5
5
  import 'ai';
@@ -343,6 +343,10 @@ type WorkflowRunLog = {
343
343
  * If the workflow run has failed, id of the run in DLQ
344
344
  */
345
345
  dlqId?: string;
346
+ /**
347
+ * Label of the workflow run
348
+ */
349
+ label?: string;
346
350
  };
347
351
  type WorkflowRunLogs = {
348
352
  cursor: string;
@@ -412,6 +416,12 @@ type TriggerOptions = {
412
416
  * Delay to apply before triggering the workflow.
413
417
  */
414
418
  delay?: PublishRequest["delay"];
419
+ /**
420
+ * Label to apply to the workflow run.
421
+ *
422
+ * Can be used to filter the workflow run logs.
423
+ */
424
+ label?: string;
415
425
  } & ({
416
426
  /**
417
427
  * URL to call if the first request to the workflow endpoint fails
@@ -456,6 +466,7 @@ type DLQFilterOptions = Pick<QStashDLQFilterOptions, "fromDate" | "toDate" | "ur
456
466
  workflowRunId?: string;
457
467
  workflowCreatedAt?: string;
458
468
  failureFunctionState?: FailureCallbackInfo["state"];
469
+ label?: string;
459
470
  };
460
471
  type FailureCallbackInfo = {
461
472
  state?: "CALLBACK_FAIL" | "CALLBACK_SUCCESS" | "CALLBACK_INPROGRESS";
@@ -491,8 +502,12 @@ type DLQMessage = {
491
502
  * status of the failure callback
492
503
  */
493
504
  failureCallbackInfo?: FailureCallbackInfo;
505
+ /**
506
+ * label passed when triggering workflow
507
+ */
508
+ label?: string;
494
509
  };
495
- type PublicDLQMessage = Pick<DLQMessage, "header" | "body" | "maxRetries" | "notBefore" | "createdAt" | "callerIP" | "workflowRunId" | "workflowCreatedAt" | "workflowUrl" | "responseStatus" | "responseHeader" | "responseBody" | "dlqId" | "failureCallback" | "failureCallbackInfo">;
510
+ type PublicDLQMessage = Pick<DLQMessage, "header" | "body" | "maxRetries" | "notBefore" | "createdAt" | "callerIP" | "workflowRunId" | "workflowCreatedAt" | "workflowUrl" | "responseStatus" | "responseHeader" | "responseBody" | "dlqId" | "failureCallback" | "failureCallbackInfo" | "label">;
496
511
  declare class DLQ {
497
512
  private client;
498
513
  constructor(client: Client$1);
@@ -832,6 +847,7 @@ declare class Client {
832
847
  state?: WorkflowRunLog["workflowState"];
833
848
  workflowUrl?: WorkflowRunLog["workflowUrl"];
834
849
  workflowCreatedAt?: WorkflowRunLog["workflowRunCreatedAt"];
850
+ label?: WorkflowRunLog["label"];
835
851
  }): Promise<WorkflowRunLogs>;
836
852
  get dlq(): DLQ;
837
853
  }
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RouteFunction, W as WorkflowServeOptions, E as ExclusiveValidationOptions, T as Telemetry, S as StepType, a as RawStep, N as NotifyResponse, b as Waiter } from './types--R_3XZXz.js';
2
- export { A as AsyncStepFunction, C as CallResponse, v as CallSettings, D as DetailedFinishCondition, t as Duration, o as FailureFunctionPayload, F as FinishCondition, H as HeaderParams, x as InvokableWorkflow, w as InvokeStepResponse, I as InvokeWorkflowRequest, L as LazyInvokeStepParams, y as LogLevel, s as NotifyStepResponse, P as ParallelCallState, n as PublicServeOptions, p as RequiredExceptFields, k as Step, m as StepFunction, j as StepTypes, l as SyncStepFunction, u as WaitEventOptions, q as WaitRequest, r as WaitStepResponse, d as WorkflowAbort, h as WorkflowClient, g as WorkflowContext, c as WorkflowError, B as WorkflowLogger, z as WorkflowLoggerOptions, e as WorkflowNonRetryableError, i as WorkflowReceiver, f as WorkflowTool } from './types--R_3XZXz.js';
1
+ import { R as RouteFunction, W as WorkflowServeOptions, E as ExclusiveValidationOptions, T as Telemetry, S as StepType, a as RawStep, N as NotifyResponse, b as Waiter } from './types-B7_5AkKQ.js';
2
+ export { A as AsyncStepFunction, C as CallResponse, v as CallSettings, D as DetailedFinishCondition, t as Duration, o as FailureFunctionPayload, F as FinishCondition, H as HeaderParams, x as InvokableWorkflow, w as InvokeStepResponse, I as InvokeWorkflowRequest, L as LazyInvokeStepParams, y as LogLevel, s as NotifyStepResponse, P as ParallelCallState, n as PublicServeOptions, p as RequiredExceptFields, k as Step, m as StepFunction, j as StepTypes, l as SyncStepFunction, u as WaitEventOptions, q as WaitRequest, r as WaitStepResponse, d as WorkflowAbort, h as WorkflowClient, g as WorkflowContext, c as WorkflowError, B as WorkflowLogger, z as WorkflowLoggerOptions, e as WorkflowNonRetryableError, i as WorkflowReceiver, f as WorkflowTool } from './types-B7_5AkKQ.js';
3
3
  import { FlowControl, PublishRequest, HTTPMethods, State, Client as Client$1 } from '@upstash/qstash';
4
4
  import 'zod';
5
5
  import 'ai';
@@ -343,6 +343,10 @@ type WorkflowRunLog = {
343
343
  * If the workflow run has failed, id of the run in DLQ
344
344
  */
345
345
  dlqId?: string;
346
+ /**
347
+ * Label of the workflow run
348
+ */
349
+ label?: string;
346
350
  };
347
351
  type WorkflowRunLogs = {
348
352
  cursor: string;
@@ -412,6 +416,12 @@ type TriggerOptions = {
412
416
  * Delay to apply before triggering the workflow.
413
417
  */
414
418
  delay?: PublishRequest["delay"];
419
+ /**
420
+ * Label to apply to the workflow run.
421
+ *
422
+ * Can be used to filter the workflow run logs.
423
+ */
424
+ label?: string;
415
425
  } & ({
416
426
  /**
417
427
  * URL to call if the first request to the workflow endpoint fails
@@ -456,6 +466,7 @@ type DLQFilterOptions = Pick<QStashDLQFilterOptions, "fromDate" | "toDate" | "ur
456
466
  workflowRunId?: string;
457
467
  workflowCreatedAt?: string;
458
468
  failureFunctionState?: FailureCallbackInfo["state"];
469
+ label?: string;
459
470
  };
460
471
  type FailureCallbackInfo = {
461
472
  state?: "CALLBACK_FAIL" | "CALLBACK_SUCCESS" | "CALLBACK_INPROGRESS";
@@ -491,8 +502,12 @@ type DLQMessage = {
491
502
  * status of the failure callback
492
503
  */
493
504
  failureCallbackInfo?: FailureCallbackInfo;
505
+ /**
506
+ * label passed when triggering workflow
507
+ */
508
+ label?: string;
494
509
  };
495
- type PublicDLQMessage = Pick<DLQMessage, "header" | "body" | "maxRetries" | "notBefore" | "createdAt" | "callerIP" | "workflowRunId" | "workflowCreatedAt" | "workflowUrl" | "responseStatus" | "responseHeader" | "responseBody" | "dlqId" | "failureCallback" | "failureCallbackInfo">;
510
+ type PublicDLQMessage = Pick<DLQMessage, "header" | "body" | "maxRetries" | "notBefore" | "createdAt" | "callerIP" | "workflowRunId" | "workflowCreatedAt" | "workflowUrl" | "responseStatus" | "responseHeader" | "responseBody" | "dlqId" | "failureCallback" | "failureCallbackInfo" | "label">;
496
511
  declare class DLQ {
497
512
  private client;
498
513
  constructor(client: Client$1);
@@ -832,6 +847,7 @@ declare class Client {
832
847
  state?: WorkflowRunLog["workflowState"];
833
848
  workflowUrl?: WorkflowRunLog["workflowUrl"];
834
849
  workflowCreatedAt?: WorkflowRunLog["workflowRunCreatedAt"];
850
+ label?: WorkflowRunLog["label"];
835
851
  }): Promise<WorkflowRunLogs>;
836
852
  get dlq(): DLQ;
837
853
  }
package/index.js CHANGED
@@ -99,12 +99,13 @@ var WORKFLOW_URL_HEADER = "Upstash-Workflow-Url";
99
99
  var WORKFLOW_FAILURE_HEADER = "Upstash-Workflow-Is-Failure";
100
100
  var WORKFLOW_FEATURE_HEADER = "Upstash-Feature-Set";
101
101
  var WORKFLOW_INVOKE_COUNT_HEADER = "Upstash-Workflow-Invoke-Count";
102
+ var WORKFLOW_LABEL_HEADER = "Upstash-Label";
102
103
  var WORKFLOW_PROTOCOL_VERSION = "1";
103
104
  var WORKFLOW_PROTOCOL_VERSION_HEADER = "Upstash-Workflow-Sdk-Version";
104
105
  var DEFAULT_CONTENT_TYPE = "application/json";
105
106
  var NO_CONCURRENCY = 1;
106
107
  var DEFAULT_RETRIES = 3;
107
- var VERSION = "v0.2.17";
108
+ var VERSION = "v0.2.18";
108
109
  var SDK_TELEMETRY = `@upstash/workflow@${VERSION}`;
109
110
  var TELEMETRY_HEADER_SDK = "Upstash-Telemetry-Sdk";
110
111
  var TELEMETRY_HEADER_FRAMEWORK = "Upstash-Telemetry-Framework";
@@ -648,6 +649,9 @@ var triggerFirstInvocation = async (params) => {
648
649
  if (useJSONContent) {
649
650
  headers["content-type"] = "application/json";
650
651
  }
652
+ if (workflowContext.label) {
653
+ headers[WORKFLOW_LABEL_HEADER] = workflowContext.label;
654
+ }
651
655
  const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
652
656
  return {
653
657
  headers,
@@ -748,10 +752,11 @@ var recreateUserHeaders = (headers) => {
748
752
  const pairs = headers.entries();
749
753
  for (const [header, value] of pairs) {
750
754
  const headerLowerCase = header.toLowerCase();
751
- if (!headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
755
+ const isUserHeader = !headerLowerCase.startsWith("upstash-workflow-") && // https://vercel.com/docs/edge-network/headers/request-headers#x-vercel-id
752
756
  !headerLowerCase.startsWith("x-vercel-") && !headerLowerCase.startsWith("x-forwarded-") && // https://blog.cloudflare.com/preventing-request-loops-using-cdn-loop/
753
757
  headerLowerCase !== "cf-connecting-ip" && headerLowerCase !== "cdn-loop" && headerLowerCase !== "cf-ew-via" && headerLowerCase !== "cf-ray" && // For Render https://render.com
754
- headerLowerCase !== "render-proxy-ttl") {
758
+ headerLowerCase !== "render-proxy-ttl" || headerLowerCase === WORKFLOW_LABEL_HEADER.toLocaleLowerCase();
759
+ if (isUserHeader) {
755
760
  filteredHeaders.append(header, value);
756
761
  }
757
762
  }
@@ -2745,6 +2750,22 @@ var WorkflowContext = class {
2745
2750
  * and number of requests per second with the same key.
2746
2751
  */
2747
2752
  flowControl;
2753
+ /**
2754
+ * Label to apply to the workflow run.
2755
+ *
2756
+ * Can be used to filter the workflow run logs.
2757
+ *
2758
+ * Can be set by passing a `label` parameter when triggering the workflow
2759
+ * with `client.trigger`:
2760
+ *
2761
+ * ```ts
2762
+ * await client.trigger({
2763
+ * url: "https://workflow-endpoint.com",
2764
+ * label: "my-label"
2765
+ * });
2766
+ * ```
2767
+ */
2768
+ label;
2748
2769
  constructor({
2749
2770
  qstashClient,
2750
2771
  workflowRunId,
@@ -2759,7 +2780,8 @@ var WorkflowContext = class {
2759
2780
  retryDelay,
2760
2781
  telemetry,
2761
2782
  invokeCount,
2762
- flowControl
2783
+ flowControl,
2784
+ label
2763
2785
  }) {
2764
2786
  this.qstashClient = qstashClient;
2765
2787
  this.workflowRunId = workflowRunId;
@@ -2772,6 +2794,7 @@ var WorkflowContext = class {
2772
2794
  this.retries = retries ?? DEFAULT_RETRIES;
2773
2795
  this.retryDelay = retryDelay;
2774
2796
  this.flowControl = flowControl;
2797
+ this.label = label;
2775
2798
  this.executor = new AutoExecutor(this, this.steps, telemetry, invokeCount, debug);
2776
2799
  }
2777
2800
  /**
@@ -3072,7 +3095,8 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
3072
3095
  env: context.env,
3073
3096
  retries: context.retries,
3074
3097
  retryDelay: context.retryDelay,
3075
- flowControl: context.flowControl
3098
+ flowControl: context.flowControl,
3099
+ label: context.label
3076
3100
  });
3077
3101
  try {
3078
3102
  await routeFunction(disabledContext);
@@ -3249,11 +3273,12 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3249
3273
  if (!errorMessage) {
3250
3274
  errorMessage = `Couldn't parse 'failResponse' in 'failureFunction', received: '${decodedBody}'`;
3251
3275
  }
3276
+ const userHeaders = recreateUserHeaders(request.headers);
3252
3277
  const workflowContext = new WorkflowContext({
3253
3278
  qstashClient,
3254
3279
  workflowRunId,
3255
3280
  initialPayload: sourceBody ? initialPayloadParser(decodeBase64(sourceBody)) : void 0,
3256
- headers: recreateUserHeaders(request.headers),
3281
+ headers: userHeaders,
3257
3282
  steps: [],
3258
3283
  url,
3259
3284
  failureUrl: url,
@@ -3262,8 +3287,9 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
3262
3287
  retries,
3263
3288
  retryDelay,
3264
3289
  flowControl,
3265
- telemetry: void 0
3290
+ telemetry: void 0,
3266
3291
  // not going to make requests in authentication check
3292
+ label: userHeaders.get(WORKFLOW_LABEL_HEADER) ?? void 0
3267
3293
  });
3268
3294
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
3269
3295
  routeFunction,
@@ -3472,6 +3498,7 @@ var serveBase = (routeFunction, telemetry, options) => {
3472
3498
  });
3473
3499
  }
3474
3500
  const invokeCount = Number(request.headers.get(WORKFLOW_INVOKE_COUNT_HEADER) ?? "0");
3501
+ const label = request.headers.get(WORKFLOW_LABEL_HEADER) ?? void 0;
3475
3502
  const workflowContext = new WorkflowContext({
3476
3503
  qstashClient,
3477
3504
  workflowRunId,
@@ -3486,7 +3513,8 @@ var serveBase = (routeFunction, telemetry, options) => {
3486
3513
  retryDelay,
3487
3514
  telemetry,
3488
3515
  invokeCount,
3489
- flowControl
3516
+ flowControl,
3517
+ label
3490
3518
  });
3491
3519
  const authCheck = await DisabledWorkflowContext.tryAuthentication(
3492
3520
  routeFunction,
@@ -3832,7 +3860,10 @@ var Client4 = class {
3832
3860
  const context = new WorkflowContext({
3833
3861
  qstashClient: this.client,
3834
3862
  // @ts-expect-error header type mismatch because of bun
3835
- headers: new Headers(option.headers ?? {}),
3863
+ headers: new Headers({
3864
+ ...option.headers ?? {},
3865
+ ...option.label ? { [WORKFLOW_LABEL_HEADER]: option.label } : {}
3866
+ }),
3836
3867
  initialPayload: option.body,
3837
3868
  steps: [],
3838
3869
  url: option.url,
@@ -3841,7 +3872,8 @@ var Client4 = class {
3841
3872
  retryDelay: option.retryDelay,
3842
3873
  telemetry: { sdk: SDK_TELEMETRY },
3843
3874
  flowControl: option.flowControl,
3844
- failureUrl
3875
+ failureUrl,
3876
+ label: option.label
3845
3877
  });
3846
3878
  return {
3847
3879
  workflowContext: context,
@@ -3907,6 +3939,9 @@ var Client4 = class {
3907
3939
  if (workflowCreatedAt) {
3908
3940
  urlParams.append("workflowCreatedAt", workflowCreatedAt.toString());
3909
3941
  }
3942
+ if (params?.label) {
3943
+ urlParams.append("label", params.label);
3944
+ }
3910
3945
  const result = await this.client.http.request({
3911
3946
  path: ["v2", "workflows", `events?${urlParams.toString()}`]
3912
3947
  });
package/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  SDK_TELEMETRY,
3
3
  StepTypes,
4
+ WORKFLOW_LABEL_HEADER,
4
5
  WorkflowAbort,
5
6
  WorkflowContext,
6
7
  WorkflowError,
@@ -13,7 +14,7 @@ import {
13
14
  prepareFlowControl,
14
15
  serve,
15
16
  triggerFirstInvocation
16
- } from "./chunk-RP7G4UD5.mjs";
17
+ } from "./chunk-EHL7SSJF.mjs";
17
18
 
18
19
  // src/client/index.ts
19
20
  import { Client as QStashClient } from "@upstash/qstash";
@@ -246,7 +247,10 @@ var Client = class {
246
247
  const context = new WorkflowContext({
247
248
  qstashClient: this.client,
248
249
  // @ts-expect-error header type mismatch because of bun
249
- headers: new Headers(option.headers ?? {}),
250
+ headers: new Headers({
251
+ ...option.headers ?? {},
252
+ ...option.label ? { [WORKFLOW_LABEL_HEADER]: option.label } : {}
253
+ }),
250
254
  initialPayload: option.body,
251
255
  steps: [],
252
256
  url: option.url,
@@ -255,7 +259,8 @@ var Client = class {
255
259
  retryDelay: option.retryDelay,
256
260
  telemetry: { sdk: SDK_TELEMETRY },
257
261
  flowControl: option.flowControl,
258
- failureUrl
262
+ failureUrl,
263
+ label: option.label
259
264
  });
260
265
  return {
261
266
  workflowContext: context,
@@ -321,6 +326,9 @@ var Client = class {
321
326
  if (workflowCreatedAt) {
322
327
  urlParams.append("workflowCreatedAt", workflowCreatedAt.toString());
323
328
  }
329
+ if (params?.label) {
330
+ urlParams.append("label", params.label);
331
+ }
324
332
  const result = await this.client.http.request({
325
333
  path: ["v2", "workflows", `events?${urlParams.toString()}`]
326
334
  });
package/nextjs.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.mjs';
3
- import { s as serveManyBase } from './serve-many-DgDSOvQs.mjs';
2
+ import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types-B7_5AkKQ.mjs';
3
+ import { s as serveManyBase } from './serve-many-CEUYWQvV.mjs';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';
package/nextjs.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { NextApiHandler, NextApiRequest, NextApiResponse } from 'next';
2
- import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types--R_3XZXz.js';
3
- import { s as serveManyBase } from './serve-many-B3DfoTFt.js';
2
+ import { R as RouteFunction, n as PublicServeOptions, x as InvokableWorkflow } from './types-B7_5AkKQ.js';
3
+ import { s as serveManyBase } from './serve-many-BObe3pdI.js';
4
4
  import '@upstash/qstash';
5
5
  import 'zod';
6
6
  import 'ai';