@upstash/qstash 2.7.0-workflow-alpha.6 → 2.7.0

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.
@@ -1,10 +0,0 @@
1
- "use strict";var Ze=Object.create;var j=Object.defineProperty;var et=Object.getOwnPropertyDescriptor;var tt=Object.getOwnPropertyNames;var rt=Object.getPrototypeOf,st=Object.prototype.hasOwnProperty;var nt=(r,e)=>{for(var t in e)j(r,t,{get:e[t],enumerable:!0})},Ee=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of tt(e))!st.call(r,n)&&n!==t&&j(r,n,{get:()=>e[n],enumerable:!(s=et(e,n))||s.enumerable});return r};var Ce=(r,e,t)=>(t=r!=null?Ze(rt(r)):{},Ee(e||!r||!r.__esModule?j(t,"default",{value:r,enumerable:!0}):t,r)),ot=r=>Ee(j({},"__esModule",{value:!0}),r);var St={};nt(St,{DisabledWorkflowContext:()=>G,StepTypes:()=>Te,Workflow:()=>H,WorkflowContext:()=>v,WorkflowLogger:()=>$,processOptions:()=>ze,serve:()=>Tt});module.exports=ot(St);var Ie=Ce(require("jose")),we=Ce(require("crypto-js")),q=class extends Error{constructor(e){super(e),this.name="SignatureError"}},z=class{currentSigningKey;nextSigningKey;constructor(e){this.currentSigningKey=e.currentSigningKey,this.nextSigningKey=e.nextSigningKey}async verify(e){return await this.verifyWithKey(this.currentSigningKey,e)?!0:this.verifyWithKey(this.nextSigningKey,e)}async verifyWithKey(e,t){let n=(await Ie.jwtVerify(t.signature,new TextEncoder().encode(e),{issuer:"Upstash",clockTolerance:t.clockTolerance}).catch(a=>{throw new q(a.message)})).payload;if(t.url!==void 0&&n.sub!==t.url)throw new q(`invalid subject: ${n.sub}, want: ${t.url}`);let o=we.default.SHA256(t.body).toString(we.default.enc.Base64url),i=new RegExp(/=+$/);if(n.body.replace(i,"")!==o.replace(i,""))throw new q(`body hash does not match, want: ${n.body}, got: ${o}`);return!0}};var V=class{http;constructor(e){this.http=e}async listMessages(e){let t={...e?.filter,topicName:e?.filter?.urlGroup},s=await this.http.request({method:"GET",path:["v2","dlq"],query:{cursor:e?.cursor,count:e?.count,...t}});return{messages:s.messages.map(n=>({...n,urlGroup:n.topicName})),cursor:s.cursor}}async delete(e){return await this.http.request({method:"DELETE",path:["v2","dlq",e],parseResponseAsJson:!1})}async deleteMany(e){return await this.http.request({method:"DELETE",path:["v2","dlq"],headers:{"Content-Type":"application/json"},body:JSON.stringify({dlqIds:e.dlqIds})})}};var P=class extends Error{constructor(e){super(e),this.name="QstashError"}},Y=class extends P{limit;remaining;reset;constructor(e){super(`Exceeded burst rate limit. ${JSON.stringify(e)} `),this.name="QstashRatelimitError",this.limit=e.limit,this.remaining=e.remaining,this.reset=e.reset}},X=class extends P{limitRequests;limitTokens;remainingRequests;remainingTokens;resetRequests;resetTokens;constructor(e){super(`Exceeded chat rate limit. ${JSON.stringify(e)} `),this.limitRequests=e["limit-requests"],this.limitTokens=e["limit-tokens"],this.remainingRequests=e["remaining-requests"],this.remainingTokens=e["remaining-tokens"],this.resetRequests=e["reset-requests"],this.resetTokens=e["reset-tokens"]}},Z=class extends P{limit;remaining;reset;constructor(e){super(`Exceeded daily rate limit. ${JSON.stringify(e)} `),this.limit=e.limit,this.remaining=e.remaining,this.reset=e.reset,this.name="QstashChatRatelimitError"}},d=class extends P{constructor(e){super(e),this.name="QStashWorkflowError"}},R=class extends Error{stepInfo;stepName;constructor(e,t){super(`This is an QStash Workflow error thrown after a step executes. It is expected to be raised. Make sure that you await for each step. Also, if you are using try/catch blocks, you should not wrap context.run/sleep/sleepUntil/call methods with try/catch. Aborting workflow after executing step '${e}'.`),this.name="QStashWorkflowAbort",this.stepName=e,this.stepInfo=t}},xe=r=>r instanceof Error?{error:r.name,message:r.message}:{error:"Error",message:"An error occured while executing workflow."};var ee=class{baseUrl;authorization;options;retry;constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.authorization=e.authorization,this.retry=typeof e.retry=="boolean"&&!e.retry?{attempts:1,backoff:()=>0}:{attempts:e.retry?.retries?e.retry.retries+1:5,backoff:e.retry?.backoff??(t=>Math.exp(t)*50)}}async request(e){let{response:t}=await this.requestWithBackoff(e);if(e.parseResponseAsJson!==!1)return await t.json()}async*requestStream(e){let{response:t}=await this.requestWithBackoff(e);if(!t.body)throw new Error("No response body");let n=t.body.getReader(),o=new TextDecoder;try{for(;;){let{done:i,value:a}=await n.read();if(i)break;let p=o.decode(a,{stream:!0}).split(`
2
- `).filter(Boolean);for(let c of p)if(c.startsWith("data: ")){let m=c.slice(6);if(m==="[DONE]")break;yield JSON.parse(m)}}}finally{await n.cancel()}}requestWithBackoff=async e=>{let[t,s]=this.processRequest(e),n,o;for(let i=0;i<this.retry.attempts;i++)try{n=await fetch(t.toString(),s);break}catch(a){o=a,await new Promise(l=>setTimeout(l,this.retry.backoff(i)))}if(!n)throw o??new Error("Exhausted all retries");return await this.checkResponse(n),{response:n,error:o}};processRequest=e=>{let t=new Headers(e.headers);t.has("Authorization")||t.set("Authorization",this.authorization);let s={method:e.method,headers:t,body:e.body,keepalive:e.keepalive},n=new URL([e.baseUrl??this.baseUrl,...e.path].join("/"));if(e.query)for(let[o,i]of Object.entries(e.query))i!==void 0&&n.searchParams.set(o,i.toString());return[n.toString(),s]};async checkResponse(e){if(e.status===429)throw e.headers.get("x-ratelimit-limit-requests")?new X({"limit-requests":e.headers.get("x-ratelimit-limit-requests"),"limit-tokens":e.headers.get("x-ratelimit-limit-tokens"),"remaining-requests":e.headers.get("x-ratelimit-remaining-requests"),"remaining-tokens":e.headers.get("x-ratelimit-remaining-tokens"),"reset-requests":e.headers.get("x-ratelimit-reset-requests"),"reset-tokens":e.headers.get("x-ratelimit-reset-tokens")}):e.headers.get("RateLimit-Limit")?new Z({limit:e.headers.get("RateLimit-Limit"),remaining:e.headers.get("RateLimit-Remaining"),reset:e.headers.get("RateLimit-Reset")}):new Y({limit:e.headers.get("Burst-RateLimit-Limit"),remaining:e.headers.get("Burst-RateLimit-Remaining"),reset:e.headers.get("Burst-RateLimit-Reset")});if(e.status<200||e.status>=300){let t=await e.text();throw new P(t.length>0?t:`Error: status=${e.status}`)}}};var I=(r,e,t,s)=>{if(!r)return{};switch(r.name){case"helicone":switch(s){case"upstash":return{baseURL:"https://qstash.helicone.ai/llm/v1/chat/completions",defaultHeaders:{"Helicone-Auth":`Bearer ${r.token}`,Authorization:`Bearer ${e}`}};default:return{baseURL:"https://gateway.helicone.ai/v1/chat/completions",defaultHeaders:{"Helicone-Auth":`Bearer ${r.token}`,"Helicone-Target-Url":t,Authorization:`Bearer ${e}`}}}default:throw new Error("Unknown analytics provider")}};var te=class r{http;token;constructor(e,t){this.http=e,this.token=t}static toChatRequest(e){let t=[];return t.push({role:"system",content:e.system},{role:"user",content:e.user}),{...e,messages:t}}create=async e=>{if(e.provider.owner!="upstash")return this.createThirdParty(e);let t=JSON.stringify(e),s,n={"Content-Type":"application/json",Authorization:`Bearer ${this.token}`,..."stream"in e&&e.stream?{Connection:"keep-alive",Accept:"text/event-stream","Cache-Control":"no-cache"}:{}};if(e.analytics){let{baseURL:i,defaultHeaders:a}=I({name:"helicone",token:e.analytics.token},this.getAuthorizationToken(),e.provider.baseUrl,"upstash");n={...n,...a},s=i}let o=e.analytics?[]:["llm","v1","chat","completions"];return"stream"in e&&e.stream?this.http.requestStream({path:o,method:"POST",headers:n,baseUrl:s,body:t}):this.http.request({path:o,method:"POST",headers:n,baseUrl:s,body:t})};createThirdParty=async e=>{let{baseUrl:t,token:s,owner:n}=e.provider;if(n==="upstash")throw new Error("Upstash is not 3rd party provider!");delete e.provider,delete e.system;let o=e.analytics;delete e.analytics;let i=JSON.stringify(e),a=o?.name&&o.token,l=o?.name&&o.token?I({name:o.name,token:o.token},s,t,n):{defaultHeaders:void 0,baseURL:t},p="stream"in e&&e.stream,c={"Content-Type":"application/json",Authorization:`Bearer ${s}`,...p?{Connection:"keep-alive",Accept:"text/event-stream","Cache-Control":"no-cache"}:{},...l.defaultHeaders};return await this.http[p?"requestStream":"request"]({path:a?[]:["v1","chat","completions"],method:"POST",headers:c,body:i,baseUrl:l.baseURL})};getAuthorizationToken(){let t=String(this.http.authorization).match(/Bearer (.+)/);if(!t)throw new Error("Invalid authorization header format");return t[1]}prompt=async e=>{let t=r.toChatRequest(e);return this.create(t)}};function W(r,e,t){if(!r.api)return;let s=r.api.provider,n=r.api.analytics;if(s?.owner==="upstash"){it(r,e,t,n);return}if(!("provider"in r.api))return;let{baseUrl:o,token:i}=at(s),a=n?I({name:n.name,token:n.token},i,o,"custom"):void 0;a?(Ue(e,a),r.url=a.baseURL):(r.url=`${o}/v1/chat/completions`,e.set("Authorization",`Bearer ${i}`))}function it(r,e,t,s){if(s){let n=I({name:s.name,token:s.token},String(t.authorization).split("Bearer ")[1],r.api?.provider?.baseUrl,"upstash");Ue(e,n),r.url=n.baseURL}else r.api={name:"llm"}}function at(r){if(!r?.baseUrl)throw new Error("baseUrl cannot be empty or undefined!");if(!r.token)throw new Error("token cannot be empty or undefined!");return{baseUrl:r.baseUrl,token:r.token}}function Ue(r,e){r.set("Helicone-Auth",e.defaultHeaders?.["Helicone-Auth"]??""),r.set("Authorization",e.defaultHeaders?.Authorization??""),e.defaultHeaders?.["Helicone-Target-Url"]&&r.set("Helicone-Target-Url",e.defaultHeaders["Helicone-Target-Url"])}function A(r){if(r.api?.name==="llm"&&!r.callback)throw new TypeError("Callback cannot be undefined when using LLM")}var re=class{http;constructor(e){this.http=e}async get(e){let t=await this.http.request({method:"GET",path:["v2","messages",e]});return{...t,urlGroup:t.topicName}}async delete(e){return await this.http.request({method:"DELETE",path:["v2","messages",e],parseResponseAsJson:!1})}async deleteMany(e){return(await this.http.request({method:"DELETE",path:["v2","messages"],headers:{"Content-Type":"application/json"},body:JSON.stringify({messageIds:e})})).cancelled}async deleteAll(){return(await this.http.request({method:"DELETE",path:["v2","messages"]})).cancelled}};var lt=r=>{let e=r.toLowerCase();return e.startsWith("content-type")||e.startsWith("upstash-")};function E(r){let e=[...r.keys()].filter(t=>!lt(t));for(let t of e){let s=r.get(t);s!==null&&r.set(`Upstash-Forward-${t}`,s),r.delete(t)}return r}function _(r){let e=E(new Headers(r.headers));return e.set("Upstash-Method",r.method??"POST"),r.delay!==void 0&&e.set("Upstash-Delay",`${r.delay.toFixed(0)}s`),r.notBefore!==void 0&&e.set("Upstash-Not-Before",r.notBefore.toFixed(0)),r.deduplicationId!==void 0&&e.set("Upstash-Deduplication-Id",r.deduplicationId),r.contentBasedDeduplication!==void 0&&e.set("Upstash-Content-Based-Deduplication","true"),r.retries!==void 0&&e.set("Upstash-Retries",r.retries.toFixed(0)),r.callback!==void 0&&e.set("Upstash-Callback",r.callback),r.failureCallback!==void 0&&e.set("Upstash-Failure-Callback",r.failureCallback),r.timeout!==void 0&&e.set("Upstash-Timeout",`${r.timeout}s`),e}function F(r){return r.url??r.urlGroup??r.topic??`api/${r.api?.name}`}var Oe="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_",ut=21;function Ne(){return[...crypto.getRandomValues(new Uint8Array(ut))].map(r=>Oe[r%Oe.length]).join("")}var se=class{http;queueName;constructor(e,t){this.http=e,this.queueName=t}async upsert(e){if(!this.queueName)throw new Error("Please provide a queue name to the Queue constructor");let t={queueName:this.queueName,parallelism:e.parallelism??1,paused:e.paused??!1};await this.http.request({method:"POST",path:["v2","queues"],headers:{"Content-Type":"application/json"},body:JSON.stringify(t),parseResponseAsJson:!1})}async get(){if(!this.queueName)throw new Error("Please provide a queue name to the Queue constructor");return await this.http.request({method:"GET",path:["v2","queues",this.queueName]})}async list(){return await this.http.request({method:"GET",path:["v2","queues"]})}async delete(){if(!this.queueName)throw new Error("Please provide a queue name to the Queue constructor");await this.http.request({method:"DELETE",path:["v2","queues",this.queueName],parseResponseAsJson:!1})}async enqueue(e){if(!this.queueName)throw new Error("Please provide a queue name to the Queue constructor");let t=_(e),s=F(e);return await this.http.request({path:["v2","enqueue",this.queueName,s],body:e.body,headers:t,method:"POST"})}async enqueueJSON(e){let t=E(new Headers(e.headers));return t.set("Content-Type","application/json"),A(e),W(e,t,this.http),await this.enqueue({...e,body:JSON.stringify(e.body),headers:t})}async pause(){if(!this.queueName)throw new Error("Please provide a queue name to the Queue constructor");await this.http.request({method:"POST",path:["v2","queues",this.queueName,"pause"],parseResponseAsJson:!1})}async resume(){if(!this.queueName)throw new Error("Please provide a queue name to the Queue constructor");await this.http.request({method:"POST",path:["v2","queues",this.queueName,"resume"],parseResponseAsJson:!1})}};var ne=class{http;constructor(e){this.http=e}async create(e){let t=E(new Headers(e.headers));return t.has("Content-Type")||t.set("Content-Type","application/json"),t.set("Upstash-Cron",e.cron),e.method!==void 0&&t.set("Upstash-Method",e.method),e.delay!==void 0&&t.set("Upstash-Delay",`${e.delay.toFixed(0)}s`),e.retries!==void 0&&t.set("Upstash-Retries",e.retries.toFixed(0)),e.callback!==void 0&&t.set("Upstash-Callback",e.callback),e.failureCallback!==void 0&&t.set("Upstash-Failure-Callback",e.failureCallback),e.timeout!==void 0&&t.set("Upstash-Timeout",`${e.timeout}s`),e.scheduleId!==void 0&&t.set("Upstash-Schedule-Id",e.scheduleId),await this.http.request({method:"POST",headers:t,path:["v2","schedules",e.destination],body:e.body})}async get(e){return await this.http.request({method:"GET",path:["v2","schedules",e]})}async list(){return await this.http.request({method:"GET",path:["v2","schedules"]})}async delete(e){return await this.http.request({method:"DELETE",path:["v2","schedules",e],parseResponseAsJson:!1})}async pause({schedule:e}){await this.http.request({method:"PATCH",path:["v2","schedules",e,"pause"],parseResponseAsJson:!1})}async resume({schedule:e}){await this.http.request({method:"PATCH",path:["v2","schedules",e,"resume"],parseResponseAsJson:!1})}};var oe=class{http;constructor(e){this.http=e}async addEndpoints(e){await this.http.request({method:"POST",path:["v2","topics",e.name,"endpoints"],headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoints:e.endpoints}),parseResponseAsJson:!1})}async removeEndpoints(e){await this.http.request({method:"DELETE",path:["v2","topics",e.name,"endpoints"],headers:{"Content-Type":"application/json"},body:JSON.stringify({endpoints:e.endpoints}),parseResponseAsJson:!1})}async list(){return await this.http.request({method:"GET",path:["v2","topics"]})}async get(e){return await this.http.request({method:"GET",path:["v2","topics",e]})}async delete(e){return await this.http.request({method:"DELETE",path:["v2","topics",e],parseResponseAsJson:!1})}};var x=class{http;token;constructor(e){this.http=new ee({retry:e.retry,baseUrl:e.baseUrl?e.baseUrl.replace(/\/$/,""):"https://qstash.upstash.io",authorization:`Bearer ${e.token}`}),this.token=e.token}get urlGroups(){return new oe(this.http)}get topics(){return this.urlGroups}get dlq(){return new V(this.http)}get messages(){return new re(this.http)}get schedules(){return new ne(this.http)}get workflow(){return new H(this.http)}queue(e){return new se(this.http,e?.queueName)}chat(){return new te(this.http,this.token)}async publish(e){let t=_(e);return await this.http.request({path:["v2","publish",F(e)],body:e.body,headers:t,method:"POST"})}async publishJSON(e){let t=E(new Headers(e.headers));return t.set("Content-Type","application/json"),A(e),W(e,t,this.http),await this.publish({...e,headers:t,body:JSON.stringify(e.body)})}async batch(e){let t=[];for(let o of e){let i=_(o),a=Object.fromEntries(i.entries());t.push({destination:F(o),headers:a,body:o.body,...o.queueName&&{queue:o.queueName}})}let s=await this.http.request({path:["v2","batch"],body:JSON.stringify(t),headers:{"Content-Type":"application/json"},method:"POST"});return Array.isArray(s)?s:[s]}async batchJSON(e){for(let s of e)"body"in s&&(s.body=JSON.stringify(s.body)),s.headers=new Headers(s.headers),A(s),W(s,s.headers,this.http),s.headers.set("Content-Type","application/json");return await this.batch(e)}async events(e){let t={};e?.cursor&&e.cursor>0&&(t.cursor=e.cursor.toString());for(let[n,o]of Object.entries(e?.filter??{}))typeof o=="number"&&o<0||(n==="urlGroup"?t.topicName=o.toString():typeof o<"u"&&(t[n]=o.toString()));let s=await this.http.request({path:["v2","events"],method:"GET",query:t});return{cursor:s.cursor,events:s.events.map(n=>({...n,urlGroup:n.topicName}))}}};var pt={withStackTrace:!1},qe=(r,e,t=pt)=>{let s=e.isOk()?{type:"Ok",value:e.value}:{type:"Err",value:e.error},n=t.withStackTrace?new Error().stack:void 0;return{data:s,message:r,stack:n}};function U(r,e,t,s){function n(o){return o instanceof t?o:new t(function(i){i(o)})}return new(t||(t=Promise))(function(o,i){function a(c){try{p(s.next(c))}catch(m){i(m)}}function l(c){try{p(s.throw(c))}catch(m){i(m)}}function p(c){c.done?o(c.value):n(c.value).then(a,l)}p((s=s.apply(r,[])).next())})}function Le(r){var e=typeof Symbol=="function"&&Symbol.iterator,t=e&&r[e],s=0;if(t)return t.call(r);if(r&&typeof r.length=="number")return{next:function(){return r&&s>=r.length&&(r=void 0),{value:r&&r[s++],done:!r}}};throw new TypeError(e?"Object is not iterable.":"Symbol.iterator is not defined.")}function C(r){return this instanceof C?(this.v=r,this):new C(r)}function ct(r,e,t){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var s=t.apply(r,e||[]),n,o=[];return n={},i("next"),i("throw"),i("return"),n[Symbol.asyncIterator]=function(){return this},n;function i(u){s[u]&&(n[u]=function(w){return new Promise(function(f,g){o.push([u,w,f,g])>1||a(u,w)})})}function a(u,w){try{l(s[u](w))}catch(f){m(o[0][3],f)}}function l(u){u.value instanceof C?Promise.resolve(u.value.v).then(p,c):m(o[0][2],u)}function p(u){a("next",u)}function c(u){a("throw",u)}function m(u,w){u(w),o.shift(),o.length&&a(o[0][0],o[0][1])}}function dt(r){var e,t;return e={},s("next"),s("throw",function(n){throw n}),s("return"),e[Symbol.iterator]=function(){return this},e;function s(n,o){e[n]=r[n]?function(i){return(t=!t)?{value:C(r[n](i)),done:n==="return"}:o?o(i):i}:o}}function ht(r){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var e=r[Symbol.asyncIterator],t;return e?e.call(r):(r=typeof Le=="function"?Le(r):r[Symbol.iterator](),t={},s("next"),s("throw"),s("return"),t[Symbol.asyncIterator]=function(){return this},t);function s(o){t[o]=r[o]&&function(i){return new Promise(function(a,l){i=r[o](i),n(a,l,i.done,i.value)})}}function n(o,i,a,l){Promise.resolve(l).then(function(p){o({value:p,done:a})},i)}}var k=class r{constructor(e){this._promise=e}static fromSafePromise(e){let t=e.then(s=>new T(s));return new r(t)}static fromPromise(e,t){let s=e.then(n=>new T(n)).catch(n=>new b(t(n)));return new r(s)}static fromThrowable(e,t){return(...s)=>new r(U(this,void 0,void 0,function*(){try{return new T(yield e(...s))}catch(n){return new b(t?t(n):n)}}))}static combine(e){return mt(e)}static combineWithAllErrors(e){return ft(e)}map(e){return new r(this._promise.then(t=>U(this,void 0,void 0,function*(){return t.isErr()?new b(t.error):new T(yield e(t.value))})))}andThrough(e){return new r(this._promise.then(t=>U(this,void 0,void 0,function*(){if(t.isErr())return new b(t.error);let s=yield e(t.value);return s.isErr()?new b(s.error):new T(t.value)})))}andTee(e){return new r(this._promise.then(t=>U(this,void 0,void 0,function*(){if(t.isErr())return new b(t.error);try{yield e(t.value)}catch{}return new T(t.value)})))}mapErr(e){return new r(this._promise.then(t=>U(this,void 0,void 0,function*(){return t.isOk()?new T(t.value):new b(yield e(t.error))})))}andThen(e){return new r(this._promise.then(t=>{if(t.isErr())return new b(t.error);let s=e(t.value);return s instanceof r?s._promise:s}))}orElse(e){return new r(this._promise.then(t=>U(this,void 0,void 0,function*(){return t.isErr()?e(t.error):new T(t.value)})))}match(e,t){return this._promise.then(s=>s.match(e,t))}unwrapOr(e){return this._promise.then(t=>t.unwrapOr(e))}safeUnwrap(){return ct(this,arguments,function*(){return yield C(yield C(yield*dt(ht(yield C(this._promise.then(t=>t.safeUnwrap()))))))})}then(e,t){return this._promise.then(e,t)}};var be=r=>new k(Promise.resolve(new b(r))),er=k.fromPromise,tr=k.fromSafePromise,rr=k.fromThrowable,We=r=>{let e=h([]);for(let t of r)if(t.isErr()){e=y(t.error);break}else e.map(s=>s.push(t.value));return e},mt=r=>k.fromSafePromise(Promise.all(r)).andThen(We),Ae=r=>{let e=h([]);for(let t of r)t.isErr()&&e.isErr()?e.error.push(t.error):t.isErr()&&e.isOk()?e=y([t.error]):t.isOk()&&e.isOk()&&e.value.push(t.value);return e},ft=r=>k.fromSafePromise(Promise.all(r)).andThen(Ae),Re;(function(r){function e(n,o){return(...i)=>{try{let a=n(...i);return h(a)}catch(a){return y(o?o(a):a)}}}r.fromThrowable=e;function t(n){return We(n)}r.combine=t;function s(n){return Ae(n)}r.combineWithAllErrors=s})(Re||(Re={}));var h=r=>new T(r);function y(r){return new b(r)}var T=class{constructor(e){this.value=e}isOk(){return!0}isErr(){return!this.isOk()}map(e){return h(e(this.value))}mapErr(e){return h(this.value)}andThen(e){return e(this.value)}andThrough(e){return e(this.value).map(t=>this.value)}andTee(e){try{e(this.value)}catch{}return h(this.value)}orElse(e){return h(this.value)}asyncAndThen(e){return e(this.value)}asyncAndThrough(e){return e(this.value).map(()=>this.value)}asyncMap(e){return k.fromSafePromise(e(this.value))}unwrapOr(e){return this.value}match(e,t){return e(this.value)}safeUnwrap(){let e=this.value;return function*(){return e}()}_unsafeUnwrap(e){return this.value}_unsafeUnwrapErr(e){throw qe("Called `_unsafeUnwrapErr` on an Ok",this,e)}},b=class{constructor(e){this.error=e}isOk(){return!1}isErr(){return!this.isOk()}map(e){return y(this.error)}mapErr(e){return y(e(this.error))}andThrough(e){return y(this.error)}andTee(e){return y(this.error)}andThen(e){return y(this.error)}orElse(e){return e(this.error)}asyncAndThen(e){return be(this.error)}asyncAndThrough(e){return be(this.error)}asyncMap(e){return be(this.error)}unwrapOr(e){return e}match(e,t){return t(this.error)}safeUnwrap(){let e=this.error;return function*(){throw yield y(e),new Error("Do not use this generator out of `safeTry`")}()}_unsafeUnwrap(e){throw qe("Called `_unsafeUnwrap` on an Err",this,e)}_unsafeUnwrapErr(e){return this.error}},sr=Re.fromThrowable;var B="Upstash-Workflow-RunId",_e="Upstash-Workflow-Init",Fe="Upstash-Workflow-Url",ie="Upstash-Workflow-Is-Failure",D="1",ae="Upstash-Workflow-Sdk-Version",He="application/json";var Te=["Initial","Run","SleepFor","SleepUntil","Call"];var Be=async(r,e)=>{let t=le("true",r.workflowRunId,r.url,r.headers,void 0,r.failureUrl);await e?.log("SUBMIT","SUBMIT_FIRST_INVOCATION",{headers:t,requestPayload:r.requestPayload,url:r.url});try{return await r.qstashClient.publishJSON({headers:t,method:"POST",body:r.requestPayload,url:r.url}),h("success")}catch(s){return y(s)}},De=async({onCleanup:r,onStep:e})=>{try{return await e(),await r(),h("workflow-finished")}catch(t){let s=t;return s instanceof R?h("step-finished"):y(s)}},Me=async(r,e,t=!1)=>{await e?.log("SUBMIT","SUBMIT_CLEANUP",{deletedWorkflowRunId:r.workflowRunId});let s=await r.qstashClient.http.request({path:["v2","workflows","runs",`${r.workflowRunId}?cancel=${t}`],method:"DELETE",parseResponseAsJson:!1});await e?.log("SUBMIT","SUBMIT_CLEANUP",s)},M=r=>{let e=new Headers,t=r.entries();for(let[s,n]of t){let o=s.toLowerCase();!o.startsWith("upstash-workflow-")&&!o.startsWith("x-vercel-")&&!o.startsWith("x-forwarded-")&&e.append(s,n)}return e},Ge=async(r,e,t,s,n,o)=>{try{if(r.headers.get("Upstash-Workflow-Callback")){let i=JSON.parse(e);if(!(i.status>=200&&i.status<300))return await o?.log("WARN","SUBMIT_THIRD_PARTY_RESULT",i),h("call-will-retry");let a=r.headers.get(B),l=r.headers.get("Upstash-Workflow-StepId"),p=r.headers.get("Upstash-Workflow-StepName"),c=r.headers.get("Upstash-Workflow-StepType"),m=r.headers.get("Upstash-Workflow-Concurrent"),u=r.headers.get("Upstash-Workflow-ContentType");if(!(a&&l&&p&&Te.includes(c)&&m&&u))throw new Error(`Missing info in callback message source header: ${JSON.stringify({workflowRunId:a,stepIdString:l,stepName:p,stepType:c,concurrentString:m,contentType:u})}`);let w=M(r.headers),f=le("false",a,s,w,void 0,n),g={stepId:Number(l),stepName:p,stepType:c,out:Buffer.from(i.body,"base64").toString(),concurrent:Number(m)};await o?.log("SUBMIT","SUBMIT_THIRD_PARTY_RESULT",{step:g,headers:f,url:s});let S=await t.publishJSON({headers:f,method:"POST",body:g,url:s});return await o?.log("SUBMIT","SUBMIT_THIRD_PARTY_RESULT",{messageId:S.messageId}),h("is-call-return")}else return h("continue-workflow")}catch(i){let a=r.headers.get("Upstash-Workflow-Callback");return y(new d(`Error when handling call return (isCallReturn=${a}): ${i}`))}},le=(r,e,t,s,n,o)=>{let i={[_e]:r,[B]:e,[Fe]:t,[`Upstash-Forward-${ae}`]:D,...o?{[`Upstash-Failure-Callback-Forward-${ie}`]:"true","Upstash-Failure-Callback":o}:{}};if(s)for(let a of s.keys())n?.callHeaders?i[`Upstash-Callback-Forward-${a}`]=s.get(a):i[`Upstash-Forward-${a}`]=s.get(a);if(n?.callHeaders){let a=Object.fromEntries(Object.entries(n.callHeaders).map(([p,c])=>[`Upstash-Forward-${p}`,c])),l=n.callHeaders["Content-Type"];return{...i,...a,"Upstash-Callback":t,"Upstash-Callback-Workflow-RunId":e,"Upstash-Callback-Workflow-CallType":"fromCallback","Upstash-Callback-Workflow-Init":"false","Upstash-Callback-Workflow-Url":t,"Upstash-Callback-Forward-Upstash-Workflow-Callback":"true","Upstash-Callback-Forward-Upstash-Workflow-StepId":n.stepId.toString(),"Upstash-Callback-Forward-Upstash-Workflow-StepName":n.stepName,"Upstash-Callback-Forward-Upstash-Workflow-StepType":n.stepType,"Upstash-Callback-Forward-Upstash-Workflow-Concurrent":n.concurrent.toString(),"Upstash-Callback-Forward-Upstash-Workflow-ContentType":l??He,"Upstash-Workflow-CallType":"toCallback"}}return i},$e=async(r,e,t)=>{if(t)try{if(!e)throw new Error("`Upstash-Signature` header is not passed.");if(!await t.verify({body:r,signature:e}))throw new Error("Signature in `Upstash-Signature` header is not valid")}catch(s){throw new d(`Failed to verify that the Workflow request comes from QStash: ${s}
3
-
4
- If signature is missing, trigger the workflow endpoint by publishing your request to QStash instead of calling it directly.
5
-
6
- If you want to disable QStash Verification, you should clear env variables QSTASH_CURRENT_SIGNING_KEY and QSTASH_NEXT_SIGNING_KEY`)}};var pe=class r{context;promises=new WeakMap;activeLazyStepList;debug;nonPlanStepCount;steps;indexInCurrentList=0;stepCount=0;planStepCount=0;executingStep=!1;constructor(e,t,s){this.context=e,this.debug=s,this.steps=t,this.nonPlanStepCount=this.steps.filter(n=>!n.targetStep).length}async addStep(e){if(this.executingStep)throw new d(`A step can not be run inside another step. Tried to run '${e.stepName}' inside '${this.executingStep}'`);this.stepCount+=1;let t=this.activeLazyStepList??[];this.activeLazyStepList||(this.activeLazyStepList=t,this.indexInCurrentList=0),t.push(e);let s=this.indexInCurrentList++,o=await this.deferExecution().then(async()=>{if(!this.promises.has(t)){let a=this.getExecutionPromise(t);this.promises.set(t,a),this.activeLazyStepList=void 0,this.planStepCount+=t.length>1?t.length:0}return this.promises.get(t)});return r.getResult(t,o,s)}wrapStep(e,t){this.executingStep=e;let s=t();return this.executingStep=!1,s}async runSingle(e){if(this.stepCount<this.nonPlanStepCount){let s=this.steps[this.stepCount+this.planStepCount];return Se(e,s),await this.debug?.log("INFO","RUN_SINGLE",{fromRequest:!0,step:s,stepCount:this.stepCount}),s.out}let t=await e.getResultStep(1,this.stepCount);return await this.debug?.log("INFO","RUN_SINGLE",{fromRequest:!1,step:t,stepCount:this.stepCount}),await this.submitStepsToQStash([t]),t.out}async runParallel(e){let t=this.stepCount-(e.length-1),s=this.getParallelCallState(e.length,t),n=gt(this.steps),o=n[t+this.planStepCount]?.concurrent;if(s!=="first"&&o!==e.length)throw new d(`Incompatible number of parallel steps when call state was '${s}'. Expected ${e.length}, got ${o} from the request.`);switch(await this.debug?.log("INFO","RUN_PARALLEL",{parallelCallState:s,initialStepCount:t,plannedParallelStepCount:o,stepCount:this.stepCount,planStepCount:this.planStepCount}),s){case"first":{let a=e.map((l,p)=>l.getPlanStep(e.length,t+p));await this.submitStepsToQStash(a);break}case"partial":{let a=this.steps.at(-1);if(!a||a.targetStep===void 0)throw new d(`There must be a last step and it should have targetStep larger than 0.Received: ${JSON.stringify(a)}`);let l=a.targetStep-t;Se(e[l],a);try{let p=await e[l].getResultStep(e.length,a.targetStep);await this.submitStepsToQStash([p])}catch(p){throw p instanceof R?p:new d(`Error submitting steps to QStash in partial parallel step execution: ${p}`)}break}case"discard":throw new R("discarded parallel");case"last":{let a=n.filter(l=>l.stepId>=t).slice(0,e.length);return yt(e,a),a.map(l=>l.out)}}return Array.from({length:e.length}).fill(void 0)}getParallelCallState(e,t){let s=this.steps.filter(n=>(n.targetStep??n.stepId)>=t);return s.length===0?"first":s.length>=2*e?"last":s.at(-1)?.targetStep?"partial":"discard"}async submitStepsToQStash(e){if(e.length===0)throw new d(`Unable to submit steps to QStash. Provided list is empty. Current step: ${this.stepCount}`);await this.debug?.log("SUBMIT","SUBMIT_STEP",{length:e.length,steps:e});let t=await this.context.qstashClient.batchJSON(e.map(s=>{let n=le("false",this.context.workflowRunId,this.context.url,this.context.headers,s,this.context.failureUrl),o=s.concurrent===1||s.stepId===0;return s.callUrl?{headers:n,method:s.callMethod,body:s.callBody,url:s.callUrl}:{headers:n,method:"POST",body:s,url:this.context.url,notBefore:o?s.sleepUntil:void 0,delay:o?s.sleepFor:void 0}}));throw await this.debug?.log("INFO","SUBMIT_STEP",{messageIds:t.map(s=>({message:s.messageId}))}),new R(e[0].stepName,e[0])}getExecutionPromise(e){return e.length===1?this.runSingle(e[0]):this.runParallel(e)}static getResult(e,t,s){if(e.length===1)return t;if(Array.isArray(t)&&e.length===t.length&&s<e.length)return t[s];throw new d(`Unexpected parallel call result while executing step ${s}: '${t}'. Expected ${e.length} many items`)}async deferExecution(){await Promise.resolve(),await Promise.resolve()}},Se=(r,e)=>{if(r.stepName!==e.stepName)throw new d(`Incompatible step name. Expected '${r.stepName}', got '${e.stepName}' from the request`);if(r.stepType!==e.stepType)throw new d(`Incompatible step type. Expected '${r.stepType}', got '${e.stepType}' from the request`)},yt=(r,e)=>{try{for(let[t,s]of e.entries())Se(r[t],s)}catch(t){if(t instanceof d){let s=r.map(a=>a.stepName),n=r.map(a=>a.stepType),o=e.map(a=>a.stepName),i=e.map(a=>a.stepType);throw new d(`Incompatible steps detected in parallel execution: ${t.message}
7
- > Step Names from the request: ${JSON.stringify(o)}
8
- Step Types from the request: ${JSON.stringify(i)}
9
- > Step Names expected: ${JSON.stringify(s)}
10
- Step Types expected: ${JSON.stringify(n)}`)}throw t}},gt=r=>{let e=t=>t.targetStep??t.stepId;return r.toSorted((t,s)=>e(t)-e(s))};var O=class{stepName;constructor(e){this.stepName=e}},ce=class extends O{stepFunction;stepType="Run";constructor(e,t){super(e),this.stepFunction=t}getPlanStep(e,t){return{stepId:0,stepName:this.stepName,stepType:this.stepType,concurrent:e,targetStep:t}}async getResultStep(e,t){let s=this.stepFunction();return s instanceof Promise&&(s=await s),{stepId:t,stepName:this.stepName,stepType:this.stepType,out:s,concurrent:e}}},de=class extends O{sleep;stepType="SleepFor";constructor(e,t){super(e),this.sleep=t}getPlanStep(e,t){return{stepId:0,stepName:this.stepName,stepType:this.stepType,sleepFor:this.sleep,concurrent:e,targetStep:t}}async getResultStep(e,t){return await Promise.resolve({stepId:t,stepName:this.stepName,stepType:this.stepType,sleepFor:this.sleep,concurrent:e})}},he=class extends O{sleepUntil;stepType="SleepUntil";constructor(e,t){super(e),this.sleepUntil=t}getPlanStep(e,t){return{stepId:0,stepName:this.stepName,stepType:this.stepType,sleepUntil:this.sleepUntil,concurrent:e,targetStep:t}}async getResultStep(e,t){return await Promise.resolve({stepId:t,stepName:this.stepName,stepType:this.stepType,sleepUntil:this.sleepUntil,concurrent:e})}},me=class extends O{url;method;body;headers;stepType="Call";constructor(e,t,s,n,o){super(e),this.url=t,this.method=s,this.body=n,this.headers=o}getPlanStep(e,t){return{stepId:0,stepName:this.stepName,stepType:this.stepType,concurrent:e,targetStep:t}}async getResultStep(e,t){return await Promise.resolve({stepId:t,stepName:this.stepName,stepType:this.stepType,concurrent:e,callUrl:this.url,callMethod:this.method,callBody:this.body,callHeaders:this.headers})}};var v=class{executor;steps;qstashClient;workflowRunId;url;failureUrl;requestPayload;headers;rawInitialPayload;env;constructor({qstashClient:e,workflowRunId:t,headers:s,steps:n,url:o,failureUrl:i,debug:a,initialPayload:l,rawInitialPayload:p,env:c}){this.qstashClient=e,this.workflowRunId=t,this.steps=n,this.url=o,this.failureUrl=i,this.headers=s,this.requestPayload=l,this.rawInitialPayload=p??JSON.stringify(this.requestPayload),this.env=c??{},this.executor=new pe(this,this.steps,a)}async run(e,t){let s=()=>this.executor.wrapStep(e,t);return this.addStep(new ce(e,s))}async sleep(e,t){await this.addStep(new de(e,t))}async sleepUntil(e,t){let s;typeof t=="number"?s=t:(t=typeof t=="string"?new Date(t):t,s=Math.round(t.getTime()/1e3)),await this.addStep(new he(e,s))}async call(e,t,s,n,o){return await this.addStep(new me(e,t,s,n,o??{}))}async addStep(e){return await this.executor.addStep(e)}},G=class r extends v{static disabledMessage="disabled-qstash-worklfow-run";async addStep(e){throw new R(r.disabledMessage)}static async tryAuthentication(e,t){let s=new r({qstashClient:new x({baseUrl:"disabled-client",token:"disabled-client"}),workflowRunId:t.workflowRunId,headers:t.headers,steps:[],url:t.url,failureUrl:t.failureUrl,initialPayload:t.requestPayload,rawInitialPayload:t.rawInitialPayload,env:t.env});try{await e(s)}catch(n){return n instanceof R&&n.stepName===this.disabledMessage?h("step-found"):y(n)}return h("run-ended")}};var Je=["DEBUG","INFO","SUBMIT","WARN","ERROR"],$=class r{logs=[];options;workflowRunId=void 0;constructor(e){this.options=e}async log(e,t,s){if(this.shouldLog(e)){let o={timestamp:Date.now(),workflowRunId:this.workflowRunId??"",logLevel:e,eventType:t,details:s};this.logs.push(o),this.options.logOutput==="console"&&this.writeToConsole(o),await new Promise(i=>setTimeout(i,100))}}setWorkflowRunId(e){this.workflowRunId=e}writeToConsole(e){console.log(JSON.stringify(e,void 0,2))}shouldLog(e){return Je.indexOf(e)>=Je.indexOf(this.options.logLevel)}static getLogger(e){return typeof e=="object"?e:e?new r({logLevel:"INFO",logOutput:"console"}):void 0}};var Qe=async r=>{try{return await r.text()}catch{return}},wt=r=>{let[e,...t]=JSON.parse(r),s=atob(e.body),n={stepId:0,stepName:"init",stepType:"Initial",out:s,concurrent:1},i=t.filter(l=>l.callType==="step").map(l=>JSON.parse(atob(l.body))),a=[n,...i];return{rawInitialPayload:s,steps:a}},bt=r=>{let e=[],t=[],s=[];for(let n of r)n.stepId===0?e.includes(n.targetStep??0)||(s.push(n),e.push(n.targetStep??0)):t.includes(n.stepId)||(s.push(n),t.push(n.stepId));return s},Rt=async(r,e)=>{if(r.length<2)return!1;let t=r.at(-1),s=t.stepId,n=t.targetStep;for(let o=0;o<r.length-1;o++){let i=r[o];if(i.stepId===s&&i.targetStep===n){let a=`QStash Workflow: The step '${i.stepName}' with id '${i.stepId}' has run twice during workflow execution. Rest of the workflow will continue running as usual.`;return await e?.log("WARN","RESPONSE_DEFAULT",a),console.warn(a),!0}}return!1},Ke=r=>{let e=r.headers.get(ae),t=!e;if(!t&&e!==D)throw new d(`Incompatible workflow sdk protocol version. Expected ${D}, got ${e} from the request.`);let s=t?`wfr_${Ne()}`:r.headers.get(B)??"";if(s.length===0)throw new d("Couldn't get workflow id from header");return{isFirstInvocation:t,workflowRunId:s}},ke=async(r,e,t)=>{if(e)return{rawInitialPayload:r??"",steps:[],isLastDuplicate:!1};{if(!r)throw new d("Only first call can have an empty body");let{rawInitialPayload:s,steps:n}=wt(r),o=await Rt(n,t),i=bt(n);return{rawInitialPayload:s,steps:i,isLastDuplicate:o}}},je=async(r,e,t,s,n,o)=>{if(r.headers.get(ie)!=="true")return h("not-failure-callback");if(!n)return y(new d("Workflow endpoint is called to handle a failure, but a failureFunction is not provided in serve options. Either provide a failureUrl or a failureFunction."));try{let{status:i,header:a,body:l,url:p,sourceHeader:c,sourceBody:m,workflowRunId:u}=JSON.parse(e),w=l?atob(l):"{}",f=JSON.parse(w),{rawInitialPayload:g,steps:S,isLastDuplicate:fe}=await ke(atob(m),!1,o),N=new v({qstashClient:t,workflowRunId:u,initialPayload:s(g),rawInitialPayload:g,headers:M(new Headers(c)),steps:S,url:p,failureUrl:p,debug:o});await n(N,i,f.message,a)}catch(i){return y(i)}return h("is-failure-callback")};var ze=r=>{let e=r?.env??(typeof process>"u"?{}:process.env),t=!!(e.QSTASH_CURRENT_SIGNING_KEY&&e.QSTASH_NEXT_SIGNING_KEY);return{qstashClient:new x({baseUrl:e.QSTASH_URL,token:e.QSTASH_TOKEN}),onStepFinish:(s,n)=>new Response(JSON.stringify({workflowRunId:s}),{status:200}),initialPayloadParser:s=>{if(s)try{return JSON.parse(s)}catch(n){if(n instanceof SyntaxError)return s;throw n}},receiver:t?new z({currentSigningKey:e.QSTASH_CURRENT_SIGNING_KEY,nextSigningKey:e.QSTASH_NEXT_SIGNING_KEY}):void 0,baseUrl:e.UPSTASH_WORKFLOW_URL,env:e,...r}},Tt=(r,e)=>{let{qstashClient:t,onStepFinish:s,initialPayloadParser:n,url:o,verbose:i,receiver:a,failureUrl:l,failureFunction:p,baseUrl:c,env:m}=ze(e),u=$.getLogger(i),w=async f=>{let g=o??f.url,S=c?g.replace(/^(https?:\/\/[^/]+)(\/.*)?$/,(K,kt,Xe)=>c+(Xe||"")):g;S!==g&&await u?.log("WARN","ENDPOINT_START",{warning:`QStash Workflow: replacing the base of the url with "${c}" and using it as workflow endpoint.`,originalURL:g,updatedURL:S});let fe=p?S:l,N=await Qe(f)??"";await $e(N,f.headers.get("upstash-signature"),a),await u?.log("INFO","ENDPOINT_START");let ye=await je(f,N,t,n,p);if(ye.isErr())throw ye.error;if(ye.value==="is-failure-callback")return await u?.log("WARN","RESPONSE_DEFAULT","failureFunction executed"),s("no-workflow-id","failure-callback");let{isFirstInvocation:Pe,workflowRunId:ve}=Ke(f);u?.setWorkflowRunId(ve);let{rawInitialPayload:ge,steps:Ve,isLastDuplicate:Ye}=await ke(N,Pe,u);if(Ye)return s("no-workflow-id","duplicate-step");let L=new v({qstashClient:t,workflowRunId:ve,initialPayload:n(ge),rawInitialPayload:ge,headers:M(f.headers),steps:Ve,url:S,failureUrl:fe,debug:u,env:m}),J=await G.tryAuthentication(r,L);if(J.isErr())throw await u?.log("ERROR","ERROR",{error:J.error.message}),J.error;if(J.value==="run-ended")return s("no-workflow-id","auth-fail");let Q=await Ge(f,ge,t,S,fe,u);if(Q.isErr())throw await u?.log("ERROR","SUBMIT_THIRD_PARTY_RESULT",{error:Q.error.message}),Q.error;if(Q.value==="continue-workflow"){let K=Pe?await Be(L,u):await De({onStep:async()=>r(L),onCleanup:async()=>{await Me(L,u)}});if(K.isErr())throw await u?.log("ERROR","ERROR",{error:K.error.message}),K.error;return await u?.log("INFO","RESPONSE_WORKFLOW"),s(L.workflowRunId,"success")}return await u?.log("INFO","RESPONSE_DEFAULT"),s("no-workflow-id","fromCallback")};return async f=>{try{return await w(f)}catch(g){return console.error(g),new Response(JSON.stringify(xe(g)),{status:500})}}};var H=class{http;constructor(e){this.http=e}async cancel(e){return await this.http.request({path:["v2","workflows","runs",`${e}?cancel=true`],method:"DELETE",parseResponseAsJson:!1})??!0}};0&&(module.exports={DisabledWorkflowContext,StepTypes,Workflow,WorkflowContext,WorkflowLogger,processOptions,serve});
File without changes
File without changes