@upstash/workflow 0.2.1 → 0.2.3
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 +248 -76
- package/astro.mjs +5 -5
- package/{chunk-ADOBNR4O.mjs → chunk-QBJ3LQIO.mjs} +222 -221
- package/cloudflare.d.mts +2 -2
- package/cloudflare.d.ts +2 -2
- package/cloudflare.js +248 -76
- package/cloudflare.mjs +5 -5
- package/express.d.mts +1 -1
- package/express.d.ts +1 -1
- package/express.js +1620 -1305
- package/express.mjs +1395 -1252
- package/h3.d.mts +2 -2
- package/h3.d.ts +2 -2
- package/h3.js +248 -76
- package/h3.mjs +5 -5
- package/hono.d.mts +4 -2
- package/hono.d.ts +4 -2
- package/hono.js +248 -76
- package/hono.mjs +5 -5
- package/index.d.mts +3 -3
- package/index.d.ts +3 -3
- package/index.js +252 -74
- package/index.mjs +189 -3
- package/nextjs.d.mts +3 -3
- package/nextjs.d.ts +3 -3
- package/nextjs.js +249 -77
- package/nextjs.mjs +6 -6
- package/package.json +1 -1
- package/solidjs.d.mts +2 -2
- package/solidjs.d.ts +2 -2
- package/solidjs.js +248 -76
- package/solidjs.mjs +5 -5
- package/svelte.d.mts +3 -3
- package/svelte.d.ts +3 -3
- package/svelte.js +251 -76
- package/svelte.mjs +8 -5
- package/{types-Be4hC1mu.d.mts → types-R9q4MUwl.d.mts} +246 -12
- package/{types-Be4hC1mu.d.ts → types-R9q4MUwl.d.ts} +246 -12
package/h3.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as h3 from 'h3';
|
|
2
|
-
import { R as RouteFunction,
|
|
2
|
+
import { R as RouteFunction, j as PublicServeOptions } from './types-R9q4MUwl.mjs';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
|
|
5
|
-
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?:
|
|
5
|
+
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
|
|
6
6
|
handler: h3.EventHandler<h3.EventHandlerRequest, Promise<Response | {
|
|
7
7
|
status: number;
|
|
8
8
|
body: string;
|
package/h3.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as h3 from 'h3';
|
|
2
|
-
import { R as RouteFunction,
|
|
2
|
+
import { R as RouteFunction, j as PublicServeOptions } from './types-R9q4MUwl.js';
|
|
3
3
|
import '@upstash/qstash';
|
|
4
4
|
|
|
5
|
-
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?:
|
|
5
|
+
declare const serve: <TInitialPayload = unknown>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => {
|
|
6
6
|
handler: h3.EventHandler<h3.EventHandlerRequest, Promise<Response | {
|
|
7
7
|
status: number;
|
|
8
8
|
body: string;
|
package/h3.js
CHANGED
|
@@ -20,7 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// platforms/h3.ts
|
|
21
21
|
var h3_exports = {};
|
|
22
22
|
__export(h3_exports, {
|
|
23
|
-
serve: () =>
|
|
23
|
+
serve: () => serve
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(h3_exports);
|
|
26
26
|
|
|
@@ -336,48 +336,8 @@ async function _callHandler(event, handler, hooks) {
|
|
|
336
336
|
var H3Headers = globalThis.Headers;
|
|
337
337
|
var H3Response = globalThis.Response;
|
|
338
338
|
|
|
339
|
-
// src/error.ts
|
|
340
|
-
var import_qstash = require("@upstash/qstash");
|
|
341
|
-
var WorkflowError = class extends import_qstash.QstashError {
|
|
342
|
-
constructor(message) {
|
|
343
|
-
super(message);
|
|
344
|
-
this.name = "WorkflowError";
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
var WorkflowAbort = class extends Error {
|
|
348
|
-
stepInfo;
|
|
349
|
-
stepName;
|
|
350
|
-
/**
|
|
351
|
-
* whether workflow is to be canceled on abort
|
|
352
|
-
*/
|
|
353
|
-
cancelWorkflow;
|
|
354
|
-
/**
|
|
355
|
-
*
|
|
356
|
-
* @param stepName name of the aborting step
|
|
357
|
-
* @param stepInfo step information
|
|
358
|
-
* @param cancelWorkflow
|
|
359
|
-
*/
|
|
360
|
-
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
361
|
-
super(
|
|
362
|
-
`This is an Upstash 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 '${stepName}'.`
|
|
363
|
-
);
|
|
364
|
-
this.name = "WorkflowAbort";
|
|
365
|
-
this.stepName = stepName;
|
|
366
|
-
this.stepInfo = stepInfo;
|
|
367
|
-
this.cancelWorkflow = cancelWorkflow;
|
|
368
|
-
}
|
|
369
|
-
};
|
|
370
|
-
var formatWorkflowError = (error) => {
|
|
371
|
-
return error instanceof Error ? {
|
|
372
|
-
error: error.name,
|
|
373
|
-
message: error.message
|
|
374
|
-
} : {
|
|
375
|
-
error: "Error",
|
|
376
|
-
message: "An error occured while executing workflow."
|
|
377
|
-
};
|
|
378
|
-
};
|
|
379
|
-
|
|
380
339
|
// src/client/utils.ts
|
|
340
|
+
var import_qstash = require("@upstash/qstash");
|
|
381
341
|
var makeNotifyRequest = async (requester, eventId, eventData) => {
|
|
382
342
|
const result = await requester.request({
|
|
383
343
|
path: ["v2", "notify", eventId],
|
|
@@ -404,26 +364,71 @@ var getSteps = async (requester, workflowRunId, messageId, debug) => {
|
|
|
404
364
|
await debug?.log("INFO", "ENDPOINT_START", {
|
|
405
365
|
message: `Pulled ${steps.length} steps from QStashand returned them without filtering with messageId.`
|
|
406
366
|
});
|
|
407
|
-
return steps;
|
|
367
|
+
return { steps, workflowRunEnded: false };
|
|
408
368
|
} else {
|
|
409
369
|
const index = steps.findIndex((item) => item.messageId === messageId);
|
|
410
370
|
if (index === -1) {
|
|
411
|
-
return [];
|
|
371
|
+
return { steps: [], workflowRunEnded: false };
|
|
412
372
|
}
|
|
413
373
|
const filteredSteps = steps.slice(0, index + 1);
|
|
414
374
|
await debug?.log("INFO", "ENDPOINT_START", {
|
|
415
375
|
message: `Pulled ${steps.length} steps from QStash and filtered them to ${filteredSteps.length} using messageId.`
|
|
416
376
|
});
|
|
417
|
-
return filteredSteps;
|
|
377
|
+
return { steps: filteredSteps, workflowRunEnded: false };
|
|
418
378
|
}
|
|
419
379
|
} catch (error) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
380
|
+
if (error instanceof import_qstash.QstashError && error.status === 404) {
|
|
381
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
382
|
+
message: "Couldn't fetch workflow run steps. This can happen if the workflow run succesfully ends before some callback is executed.",
|
|
383
|
+
error
|
|
384
|
+
});
|
|
385
|
+
return { steps: void 0, workflowRunEnded: true };
|
|
386
|
+
} else {
|
|
387
|
+
throw error;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
// src/error.ts
|
|
393
|
+
var import_qstash2 = require("@upstash/qstash");
|
|
394
|
+
var WorkflowError = class extends import_qstash2.QstashError {
|
|
395
|
+
constructor(message) {
|
|
396
|
+
super(message);
|
|
397
|
+
this.name = "WorkflowError";
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
var WorkflowAbort = class extends Error {
|
|
401
|
+
stepInfo;
|
|
402
|
+
stepName;
|
|
403
|
+
/**
|
|
404
|
+
* whether workflow is to be canceled on abort
|
|
405
|
+
*/
|
|
406
|
+
cancelWorkflow;
|
|
407
|
+
/**
|
|
408
|
+
*
|
|
409
|
+
* @param stepName name of the aborting step
|
|
410
|
+
* @param stepInfo step information
|
|
411
|
+
* @param cancelWorkflow
|
|
412
|
+
*/
|
|
413
|
+
constructor(stepName, stepInfo, cancelWorkflow = false) {
|
|
414
|
+
super(
|
|
415
|
+
`This is an Upstash 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 '${stepName}'.`
|
|
416
|
+
);
|
|
417
|
+
this.name = "WorkflowAbort";
|
|
418
|
+
this.stepName = stepName;
|
|
419
|
+
this.stepInfo = stepInfo;
|
|
420
|
+
this.cancelWorkflow = cancelWorkflow;
|
|
425
421
|
}
|
|
426
422
|
};
|
|
423
|
+
var formatWorkflowError = (error) => {
|
|
424
|
+
return error instanceof Error ? {
|
|
425
|
+
error: error.name,
|
|
426
|
+
message: error.message
|
|
427
|
+
} : {
|
|
428
|
+
error: "Error",
|
|
429
|
+
message: "An error occured while executing workflow."
|
|
430
|
+
};
|
|
431
|
+
};
|
|
427
432
|
|
|
428
433
|
// src/context/steps.ts
|
|
429
434
|
var BaseLazyStep = class {
|
|
@@ -1045,8 +1050,8 @@ var StepTypes = [
|
|
|
1045
1050
|
];
|
|
1046
1051
|
|
|
1047
1052
|
// src/workflow-requests.ts
|
|
1048
|
-
var
|
|
1049
|
-
var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
1053
|
+
var import_qstash3 = require("@upstash/qstash");
|
|
1054
|
+
var triggerFirstInvocation = async (workflowContext, retries, useJSONContent, debug) => {
|
|
1050
1055
|
const { headers } = getHeaders(
|
|
1051
1056
|
"true",
|
|
1052
1057
|
workflowContext.workflowRunId,
|
|
@@ -1056,6 +1061,9 @@ var triggerFirstInvocation = async (workflowContext, retries, debug) => {
|
|
|
1056
1061
|
workflowContext.failureUrl,
|
|
1057
1062
|
retries
|
|
1058
1063
|
);
|
|
1064
|
+
if (useJSONContent) {
|
|
1065
|
+
headers["content-type"] = "application/json";
|
|
1066
|
+
}
|
|
1059
1067
|
try {
|
|
1060
1068
|
const body = typeof workflowContext.requestPayload === "string" ? workflowContext.requestPayload : JSON.stringify(workflowContext.requestPayload);
|
|
1061
1069
|
const result = await workflowContext.qstashClient.publish({
|
|
@@ -1099,7 +1107,7 @@ var triggerRouteFunction = async ({
|
|
|
1099
1107
|
return ok("workflow-finished");
|
|
1100
1108
|
} catch (error) {
|
|
1101
1109
|
const error_ = error;
|
|
1102
|
-
if (error instanceof
|
|
1110
|
+
if (error instanceof import_qstash3.QstashError && error.status === 400) {
|
|
1103
1111
|
await debug?.log("WARN", "RESPONSE_WORKFLOW", {
|
|
1104
1112
|
message: `tried to append to a cancelled workflow. exiting without publishing.`,
|
|
1105
1113
|
name: error.name,
|
|
@@ -1133,7 +1141,7 @@ var triggerWorkflowDelete = async (workflowContext, debug, cancel = false) => {
|
|
|
1133
1141
|
);
|
|
1134
1142
|
return { deleted: true };
|
|
1135
1143
|
} catch (error) {
|
|
1136
|
-
if (error instanceof
|
|
1144
|
+
if (error instanceof import_qstash3.QstashError && error.status === 404) {
|
|
1137
1145
|
await debug?.log("WARN", "SUBMIT_CLEANUP", {
|
|
1138
1146
|
message: `Failed to remove workflow run ${workflowContext.workflowRunId} as it doesn't exist.`,
|
|
1139
1147
|
name: error.name,
|
|
@@ -1170,11 +1178,19 @@ var handleThirdPartyCallResult = async (request, requestPayload, client, workflo
|
|
|
1170
1178
|
if (!workflowRunId2)
|
|
1171
1179
|
throw new WorkflowError("workflow run id missing in context.call lazy fetch.");
|
|
1172
1180
|
if (!messageId) throw new WorkflowError("message id missing in context.call lazy fetch.");
|
|
1173
|
-
const steps = await getSteps(
|
|
1181
|
+
const { steps, workflowRunEnded } = await getSteps(
|
|
1182
|
+
client.http,
|
|
1183
|
+
workflowRunId2,
|
|
1184
|
+
messageId,
|
|
1185
|
+
debug
|
|
1186
|
+
);
|
|
1187
|
+
if (workflowRunEnded) {
|
|
1188
|
+
return ok("workflow-ended");
|
|
1189
|
+
}
|
|
1174
1190
|
const failingStep = steps.find((step) => step.messageId === messageId);
|
|
1175
1191
|
if (!failingStep)
|
|
1176
1192
|
throw new WorkflowError(
|
|
1177
|
-
"Failed to submit the context.call." + (steps.length === 0 ? "No steps found." : `No step was found with matching messageId ${messageId} out of ${steps.length} steps.`)
|
|
1193
|
+
"Failed to submit the context.call. " + (steps.length === 0 ? "No steps found." : `No step was found with matching messageId ${messageId} out of ${steps.length} steps.`)
|
|
1178
1194
|
);
|
|
1179
1195
|
callbackPayload = atob(failingStep.body);
|
|
1180
1196
|
}
|
|
@@ -1757,6 +1773,127 @@ var sortSteps = (steps) => {
|
|
|
1757
1773
|
return [...steps].sort((step, stepOther) => getStepId(step) - getStepId(stepOther));
|
|
1758
1774
|
};
|
|
1759
1775
|
|
|
1776
|
+
// src/context/api/anthropic.ts
|
|
1777
|
+
var import_qstash4 = require("@upstash/qstash");
|
|
1778
|
+
|
|
1779
|
+
// src/context/provider.ts
|
|
1780
|
+
var getProviderInfo = (api) => {
|
|
1781
|
+
if (!api.provider) {
|
|
1782
|
+
throw new WorkflowError("A Provider must be provided.");
|
|
1783
|
+
}
|
|
1784
|
+
if (api.provider.owner === "upstash") {
|
|
1785
|
+
throw new WorkflowError("Upstash provider isn't supported.");
|
|
1786
|
+
}
|
|
1787
|
+
const { name, provider, ...parameters } = api;
|
|
1788
|
+
if (!provider.baseUrl) throw new TypeError("baseUrl cannot be empty or undefined!");
|
|
1789
|
+
if (!provider.token) throw new TypeError("token cannot be empty or undefined!");
|
|
1790
|
+
if (provider.apiKind !== name) {
|
|
1791
|
+
throw new TypeError(`Unexpected api name. Expected '${provider.apiKind}', received ${name}`);
|
|
1792
|
+
}
|
|
1793
|
+
const providerInfo = {
|
|
1794
|
+
url: provider.getUrl(),
|
|
1795
|
+
baseUrl: provider.baseUrl,
|
|
1796
|
+
route: provider.getRoute(),
|
|
1797
|
+
appendHeaders: provider.getHeaders(parameters),
|
|
1798
|
+
owner: provider.owner,
|
|
1799
|
+
method: provider.method
|
|
1800
|
+
};
|
|
1801
|
+
return provider.onFinish(providerInfo, parameters);
|
|
1802
|
+
};
|
|
1803
|
+
|
|
1804
|
+
// src/context/api/base.ts
|
|
1805
|
+
var BaseWorkflowApi = class {
|
|
1806
|
+
context;
|
|
1807
|
+
constructor({ context }) {
|
|
1808
|
+
this.context = context;
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* context.call which uses a QStash API
|
|
1812
|
+
*
|
|
1813
|
+
* @param stepName
|
|
1814
|
+
* @param settings
|
|
1815
|
+
* @returns
|
|
1816
|
+
*/
|
|
1817
|
+
async callApi(stepName, settings) {
|
|
1818
|
+
const { url, appendHeaders, method } = getProviderInfo(settings.api);
|
|
1819
|
+
const { method: userMethod, body, headers = {}, retries = 0, timeout } = settings;
|
|
1820
|
+
return await this.context.call(stepName, {
|
|
1821
|
+
url,
|
|
1822
|
+
method: userMethod ?? method,
|
|
1823
|
+
body,
|
|
1824
|
+
headers: {
|
|
1825
|
+
...appendHeaders,
|
|
1826
|
+
...headers
|
|
1827
|
+
},
|
|
1828
|
+
retries,
|
|
1829
|
+
timeout
|
|
1830
|
+
});
|
|
1831
|
+
}
|
|
1832
|
+
};
|
|
1833
|
+
|
|
1834
|
+
// src/context/api/anthropic.ts
|
|
1835
|
+
var AnthropicAPI = class extends BaseWorkflowApi {
|
|
1836
|
+
async call(stepName, settings) {
|
|
1837
|
+
const { token, operation, ...parameters } = settings;
|
|
1838
|
+
return await this.callApi(stepName, {
|
|
1839
|
+
api: {
|
|
1840
|
+
name: "llm",
|
|
1841
|
+
provider: (0, import_qstash4.anthropic)({ token })
|
|
1842
|
+
},
|
|
1843
|
+
...parameters
|
|
1844
|
+
});
|
|
1845
|
+
}
|
|
1846
|
+
};
|
|
1847
|
+
|
|
1848
|
+
// src/context/api/openai.ts
|
|
1849
|
+
var import_qstash5 = require("@upstash/qstash");
|
|
1850
|
+
var OpenAIAPI = class extends BaseWorkflowApi {
|
|
1851
|
+
async call(stepName, settings) {
|
|
1852
|
+
const { token, organization, operation, ...parameters } = settings;
|
|
1853
|
+
return await this.callApi(stepName, {
|
|
1854
|
+
api: {
|
|
1855
|
+
name: "llm",
|
|
1856
|
+
provider: (0, import_qstash5.openai)({ token, organization })
|
|
1857
|
+
},
|
|
1858
|
+
...parameters
|
|
1859
|
+
});
|
|
1860
|
+
}
|
|
1861
|
+
};
|
|
1862
|
+
|
|
1863
|
+
// src/context/api/resend.ts
|
|
1864
|
+
var import_qstash6 = require("@upstash/qstash");
|
|
1865
|
+
var ResendAPI = class extends BaseWorkflowApi {
|
|
1866
|
+
async call(stepName, settings) {
|
|
1867
|
+
const { token, batch = false, ...parameters } = settings;
|
|
1868
|
+
return await this.callApi(stepName, {
|
|
1869
|
+
api: {
|
|
1870
|
+
name: "email",
|
|
1871
|
+
provider: (0, import_qstash6.resend)({ token, batch })
|
|
1872
|
+
},
|
|
1873
|
+
...parameters
|
|
1874
|
+
});
|
|
1875
|
+
}
|
|
1876
|
+
};
|
|
1877
|
+
|
|
1878
|
+
// src/context/api/index.ts
|
|
1879
|
+
var WorkflowApi = class extends BaseWorkflowApi {
|
|
1880
|
+
get openai() {
|
|
1881
|
+
return new OpenAIAPI({
|
|
1882
|
+
context: this.context
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
get resend() {
|
|
1886
|
+
return new ResendAPI({
|
|
1887
|
+
context: this.context
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
get anthropic() {
|
|
1891
|
+
return new AnthropicAPI({
|
|
1892
|
+
context: this.context
|
|
1893
|
+
});
|
|
1894
|
+
}
|
|
1895
|
+
};
|
|
1896
|
+
|
|
1760
1897
|
// src/context/context.ts
|
|
1761
1898
|
var WorkflowContext = class {
|
|
1762
1899
|
executor;
|
|
@@ -2136,6 +2273,11 @@ var WorkflowContext = class {
|
|
|
2136
2273
|
async addStep(step) {
|
|
2137
2274
|
return await this.executor.addStep(step);
|
|
2138
2275
|
}
|
|
2276
|
+
get api() {
|
|
2277
|
+
return new WorkflowApi({
|
|
2278
|
+
context: this
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2139
2281
|
};
|
|
2140
2282
|
|
|
2141
2283
|
// src/logger.ts
|
|
@@ -2213,7 +2355,7 @@ function decodeBase64(base64) {
|
|
|
2213
2355
|
}
|
|
2214
2356
|
|
|
2215
2357
|
// src/serve/authorization.ts
|
|
2216
|
-
var
|
|
2358
|
+
var import_qstash7 = require("@upstash/qstash");
|
|
2217
2359
|
var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowContext {
|
|
2218
2360
|
static disabledMessage = "disabled-qstash-worklfow-run";
|
|
2219
2361
|
/**
|
|
@@ -2244,7 +2386,7 @@ var DisabledWorkflowContext = class _DisabledWorkflowContext extends WorkflowCon
|
|
|
2244
2386
|
*/
|
|
2245
2387
|
static async tryAuthentication(routeFunction, context) {
|
|
2246
2388
|
const disabledContext = new _DisabledWorkflowContext({
|
|
2247
|
-
qstashClient: new
|
|
2389
|
+
qstashClient: new import_qstash7.Client({
|
|
2248
2390
|
baseUrl: "disabled-client",
|
|
2249
2391
|
token: "disabled-client"
|
|
2250
2392
|
}),
|
|
@@ -2368,7 +2510,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2368
2510
|
return {
|
|
2369
2511
|
rawInitialPayload: requestPayload ?? "",
|
|
2370
2512
|
steps: [],
|
|
2371
|
-
isLastDuplicate: false
|
|
2513
|
+
isLastDuplicate: false,
|
|
2514
|
+
workflowRunEnded: false
|
|
2372
2515
|
};
|
|
2373
2516
|
} else {
|
|
2374
2517
|
let rawSteps;
|
|
@@ -2378,7 +2521,21 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2378
2521
|
"ENDPOINT_START",
|
|
2379
2522
|
"request payload is empty, steps will be fetched from QStash."
|
|
2380
2523
|
);
|
|
2381
|
-
|
|
2524
|
+
const { steps: fetchedSteps, workflowRunEnded } = await getSteps(
|
|
2525
|
+
requester,
|
|
2526
|
+
workflowRunId,
|
|
2527
|
+
messageId,
|
|
2528
|
+
debug
|
|
2529
|
+
);
|
|
2530
|
+
if (workflowRunEnded) {
|
|
2531
|
+
return {
|
|
2532
|
+
rawInitialPayload: void 0,
|
|
2533
|
+
steps: void 0,
|
|
2534
|
+
isLastDuplicate: void 0,
|
|
2535
|
+
workflowRunEnded: true
|
|
2536
|
+
};
|
|
2537
|
+
}
|
|
2538
|
+
rawSteps = fetchedSteps;
|
|
2382
2539
|
} else {
|
|
2383
2540
|
rawSteps = JSON.parse(requestPayload);
|
|
2384
2541
|
}
|
|
@@ -2388,7 +2545,8 @@ var parseRequest = async (requestPayload, isFirstInvocation, workflowRunId, requ
|
|
|
2388
2545
|
return {
|
|
2389
2546
|
rawInitialPayload,
|
|
2390
2547
|
steps: deduplicatedSteps,
|
|
2391
|
-
isLastDuplicate
|
|
2548
|
+
isLastDuplicate,
|
|
2549
|
+
workflowRunEnded: false
|
|
2392
2550
|
};
|
|
2393
2551
|
}
|
|
2394
2552
|
};
|
|
@@ -2442,15 +2600,15 @@ var handleFailure = async (request, requestPayload, qstashClient, initialPayload
|
|
|
2442
2600
|
};
|
|
2443
2601
|
|
|
2444
2602
|
// src/serve/options.ts
|
|
2445
|
-
var
|
|
2446
|
-
var
|
|
2603
|
+
var import_qstash8 = require("@upstash/qstash");
|
|
2604
|
+
var import_qstash9 = require("@upstash/qstash");
|
|
2447
2605
|
var processOptions = (options) => {
|
|
2448
2606
|
const environment = options?.env ?? (typeof process === "undefined" ? {} : process.env);
|
|
2449
2607
|
const receiverEnvironmentVariablesSet = Boolean(
|
|
2450
2608
|
environment.QSTASH_CURRENT_SIGNING_KEY && environment.QSTASH_NEXT_SIGNING_KEY
|
|
2451
2609
|
);
|
|
2452
2610
|
return {
|
|
2453
|
-
qstashClient: new
|
|
2611
|
+
qstashClient: new import_qstash9.Client({
|
|
2454
2612
|
baseUrl: environment.QSTASH_URL,
|
|
2455
2613
|
token: environment.QSTASH_TOKEN
|
|
2456
2614
|
}),
|
|
@@ -2484,13 +2642,14 @@ var processOptions = (options) => {
|
|
|
2484
2642
|
throw error;
|
|
2485
2643
|
}
|
|
2486
2644
|
},
|
|
2487
|
-
receiver: receiverEnvironmentVariablesSet ? new
|
|
2645
|
+
receiver: receiverEnvironmentVariablesSet ? new import_qstash8.Receiver({
|
|
2488
2646
|
currentSigningKey: environment.QSTASH_CURRENT_SIGNING_KEY,
|
|
2489
2647
|
nextSigningKey: environment.QSTASH_NEXT_SIGNING_KEY
|
|
2490
2648
|
}) : void 0,
|
|
2491
2649
|
baseUrl: environment.UPSTASH_WORKFLOW_URL,
|
|
2492
2650
|
env: environment,
|
|
2493
2651
|
retries: DEFAULT_RETRIES,
|
|
2652
|
+
useJSONContent: false,
|
|
2494
2653
|
...options
|
|
2495
2654
|
};
|
|
2496
2655
|
};
|
|
@@ -2507,6 +2666,16 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
|
|
|
2507
2666
|
});
|
|
2508
2667
|
}
|
|
2509
2668
|
const workflowFailureUrl = failureFunction ? workflowUrl : failureUrl;
|
|
2669
|
+
if (workflowUrl.includes("localhost")) {
|
|
2670
|
+
await debug?.log("WARN", "ENDPOINT_START", {
|
|
2671
|
+
message: `Workflow URL contains localhost. This can happen in local development, but shouldn't happen in production unless you have a route which contains localhost. Received: ${workflowUrl}`
|
|
2672
|
+
});
|
|
2673
|
+
}
|
|
2674
|
+
if (!(workflowUrl.startsWith("http://") || workflowUrl.startsWith("https://"))) {
|
|
2675
|
+
throw new WorkflowError(
|
|
2676
|
+
`Workflow URL should start with 'http://' or 'https://'. Recevied is '${workflowUrl}'`
|
|
2677
|
+
);
|
|
2678
|
+
}
|
|
2510
2679
|
return {
|
|
2511
2680
|
workflowUrl,
|
|
2512
2681
|
workflowFailureUrl
|
|
@@ -2515,7 +2684,7 @@ var determineUrls = async (request, url, baseUrl, failureFunction, failureUrl, d
|
|
|
2515
2684
|
var AUTH_FAIL_MESSAGE = `Failed to authenticate Workflow request. If this is unexpected, see the caveat https://upstash.com/docs/workflow/basics/caveats#avoid-non-deterministic-code-outside-context-run`;
|
|
2516
2685
|
|
|
2517
2686
|
// src/serve/index.ts
|
|
2518
|
-
var
|
|
2687
|
+
var serveBase = (routeFunction, options) => {
|
|
2519
2688
|
const {
|
|
2520
2689
|
qstashClient,
|
|
2521
2690
|
onStepFinish,
|
|
@@ -2527,7 +2696,8 @@ var serve = (routeFunction, options) => {
|
|
|
2527
2696
|
failureFunction,
|
|
2528
2697
|
baseUrl,
|
|
2529
2698
|
env,
|
|
2530
|
-
retries
|
|
2699
|
+
retries,
|
|
2700
|
+
useJSONContent
|
|
2531
2701
|
} = processOptions(options);
|
|
2532
2702
|
const debug = WorkflowLogger.getLogger(verbose);
|
|
2533
2703
|
const handler = async (request) => {
|
|
@@ -2544,7 +2714,7 @@ var serve = (routeFunction, options) => {
|
|
|
2544
2714
|
await verifyRequest(requestPayload, request.headers.get("upstash-signature"), receiver);
|
|
2545
2715
|
const { isFirstInvocation, workflowRunId } = validateRequest(request);
|
|
2546
2716
|
debug?.setWorkflowRunId(workflowRunId);
|
|
2547
|
-
const { rawInitialPayload, steps, isLastDuplicate } = await parseRequest(
|
|
2717
|
+
const { rawInitialPayload, steps, isLastDuplicate, workflowRunEnded } = await parseRequest(
|
|
2548
2718
|
requestPayload,
|
|
2549
2719
|
isFirstInvocation,
|
|
2550
2720
|
workflowRunId,
|
|
@@ -2552,8 +2722,11 @@ var serve = (routeFunction, options) => {
|
|
|
2552
2722
|
request.headers.get("upstash-message-id"),
|
|
2553
2723
|
debug
|
|
2554
2724
|
);
|
|
2725
|
+
if (workflowRunEnded) {
|
|
2726
|
+
return onStepFinish(workflowRunId, "workflow-already-ended");
|
|
2727
|
+
}
|
|
2555
2728
|
if (isLastDuplicate) {
|
|
2556
|
-
return onStepFinish(
|
|
2729
|
+
return onStepFinish(workflowRunId, "duplicate-step");
|
|
2557
2730
|
}
|
|
2558
2731
|
const failureCheck = await handleFailure(
|
|
2559
2732
|
request,
|
|
@@ -2567,7 +2740,7 @@ var serve = (routeFunction, options) => {
|
|
|
2567
2740
|
throw failureCheck.error;
|
|
2568
2741
|
} else if (failureCheck.value === "is-failure-callback") {
|
|
2569
2742
|
await debug?.log("WARN", "RESPONSE_DEFAULT", "failureFunction executed");
|
|
2570
|
-
return onStepFinish(
|
|
2743
|
+
return onStepFinish(workflowRunId, "failure-callback");
|
|
2571
2744
|
}
|
|
2572
2745
|
const workflowContext = new WorkflowContext({
|
|
2573
2746
|
qstashClient,
|
|
@@ -2610,7 +2783,7 @@ var serve = (routeFunction, options) => {
|
|
|
2610
2783
|
});
|
|
2611
2784
|
throw callReturnCheck.error;
|
|
2612
2785
|
} else if (callReturnCheck.value === "continue-workflow") {
|
|
2613
|
-
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, debug) : await triggerRouteFunction({
|
|
2786
|
+
const result = isFirstInvocation ? await triggerFirstInvocation(workflowContext, retries, useJSONContent, debug) : await triggerRouteFunction({
|
|
2614
2787
|
onStep: async () => routeFunction(workflowContext),
|
|
2615
2788
|
onCleanup: async () => {
|
|
2616
2789
|
await triggerWorkflowDelete(workflowContext, debug);
|
|
@@ -2626,6 +2799,8 @@ var serve = (routeFunction, options) => {
|
|
|
2626
2799
|
}
|
|
2627
2800
|
await debug?.log("INFO", "RESPONSE_WORKFLOW");
|
|
2628
2801
|
return onStepFinish(workflowContext.workflowRunId, "success");
|
|
2802
|
+
} else if (callReturnCheck.value === "workflow-ended") {
|
|
2803
|
+
return onStepFinish(workflowContext.workflowRunId, "workflow-already-ended");
|
|
2629
2804
|
}
|
|
2630
2805
|
await debug?.log("INFO", "RESPONSE_DEFAULT");
|
|
2631
2806
|
return onStepFinish("no-workflow-id", "fromCallback");
|
|
@@ -2643,9 +2818,6 @@ var serve = (routeFunction, options) => {
|
|
|
2643
2818
|
return { handler: safeHandler };
|
|
2644
2819
|
};
|
|
2645
2820
|
|
|
2646
|
-
// src/client/index.ts
|
|
2647
|
-
var import_qstash6 = require("@upstash/qstash");
|
|
2648
|
-
|
|
2649
2821
|
// platforms/h3.ts
|
|
2650
2822
|
function transformHeaders(headers) {
|
|
2651
2823
|
const formattedHeaders = Object.entries(headers).map(([key, value]) => [
|
|
@@ -2654,7 +2826,7 @@ function transformHeaders(headers) {
|
|
|
2654
2826
|
]);
|
|
2655
2827
|
return formattedHeaders;
|
|
2656
2828
|
}
|
|
2657
|
-
var
|
|
2829
|
+
var serve = (routeFunction, options) => {
|
|
2658
2830
|
const handler = defineEventHandler(async (event) => {
|
|
2659
2831
|
const method = event.node.req.method;
|
|
2660
2832
|
if (method?.toUpperCase() !== "POST") {
|
|
@@ -2673,7 +2845,7 @@ var serve2 = (routeFunction, options) => {
|
|
|
2673
2845
|
body: await readRawBody(event),
|
|
2674
2846
|
method: "POST"
|
|
2675
2847
|
});
|
|
2676
|
-
const { handler: serveHandler } =
|
|
2848
|
+
const { handler: serveHandler } = serveBase(routeFunction, options);
|
|
2677
2849
|
return await serveHandler(request);
|
|
2678
2850
|
});
|
|
2679
2851
|
return { handler };
|
package/h3.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
serveBase
|
|
3
|
+
} from "./chunk-QBJ3LQIO.mjs";
|
|
4
4
|
|
|
5
5
|
// node_modules/defu/dist/defu.mjs
|
|
6
6
|
function isPlainObject(value) {
|
|
@@ -322,7 +322,7 @@ function transformHeaders(headers) {
|
|
|
322
322
|
]);
|
|
323
323
|
return formattedHeaders;
|
|
324
324
|
}
|
|
325
|
-
var
|
|
325
|
+
var serve = (routeFunction, options) => {
|
|
326
326
|
const handler = defineEventHandler(async (event) => {
|
|
327
327
|
const method = event.node.req.method;
|
|
328
328
|
if (method?.toUpperCase() !== "POST") {
|
|
@@ -341,11 +341,11 @@ var serve2 = (routeFunction, options) => {
|
|
|
341
341
|
body: await readRawBody(event),
|
|
342
342
|
method: "POST"
|
|
343
343
|
});
|
|
344
|
-
const { handler: serveHandler } =
|
|
344
|
+
const { handler: serveHandler } = serveBase(routeFunction, options);
|
|
345
345
|
return await serveHandler(request);
|
|
346
346
|
});
|
|
347
347
|
return { handler };
|
|
348
348
|
};
|
|
349
349
|
export {
|
|
350
|
-
|
|
350
|
+
serve
|
|
351
351
|
};
|
package/hono.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context } from 'hono';
|
|
2
|
-
import { R as RouteFunction,
|
|
2
|
+
import { R as RouteFunction, j as PublicServeOptions } from './types-R9q4MUwl.mjs';
|
|
3
|
+
import { Variables } from 'hono/types';
|
|
3
4
|
import '@upstash/qstash';
|
|
4
5
|
|
|
5
6
|
type WorkflowBindings = {
|
|
@@ -18,8 +19,9 @@ type WorkflowBindings = {
|
|
|
18
19
|
* @param options workflow options
|
|
19
20
|
* @returns
|
|
20
21
|
*/
|
|
21
|
-
declare const serve: <TInitialPayload = unknown, TBindings extends WorkflowBindings = WorkflowBindings>(routeFunction: RouteFunction<TInitialPayload>, options?:
|
|
22
|
+
declare const serve: <TInitialPayload = unknown, TBindings extends WorkflowBindings = WorkflowBindings, TVariables extends Variables = object>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => ((context: Context<{
|
|
22
23
|
Bindings: TBindings;
|
|
24
|
+
Variables: TVariables;
|
|
23
25
|
}>) => Promise<Response>);
|
|
24
26
|
|
|
25
27
|
export { type WorkflowBindings, serve };
|
package/hono.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context } from 'hono';
|
|
2
|
-
import { R as RouteFunction,
|
|
2
|
+
import { R as RouteFunction, j as PublicServeOptions } from './types-R9q4MUwl.js';
|
|
3
|
+
import { Variables } from 'hono/types';
|
|
3
4
|
import '@upstash/qstash';
|
|
4
5
|
|
|
5
6
|
type WorkflowBindings = {
|
|
@@ -18,8 +19,9 @@ type WorkflowBindings = {
|
|
|
18
19
|
* @param options workflow options
|
|
19
20
|
* @returns
|
|
20
21
|
*/
|
|
21
|
-
declare const serve: <TInitialPayload = unknown, TBindings extends WorkflowBindings = WorkflowBindings>(routeFunction: RouteFunction<TInitialPayload>, options?:
|
|
22
|
+
declare const serve: <TInitialPayload = unknown, TBindings extends WorkflowBindings = WorkflowBindings, TVariables extends Variables = object>(routeFunction: RouteFunction<TInitialPayload>, options?: PublicServeOptions<TInitialPayload>) => ((context: Context<{
|
|
22
23
|
Bindings: TBindings;
|
|
24
|
+
Variables: TVariables;
|
|
23
25
|
}>) => Promise<Response>);
|
|
24
26
|
|
|
25
27
|
export { type WorkflowBindings, serve };
|