@upstash/workflow 0.1.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.
package/h3.mjs ADDED
@@ -0,0 +1,348 @@
1
+ import {
2
+ serve
3
+ } from "./chunk-JDMP6KKR.mjs";
4
+
5
+ // node_modules/defu/dist/defu.mjs
6
+ function isPlainObject(value) {
7
+ if (value === null || typeof value !== "object") {
8
+ return false;
9
+ }
10
+ const prototype = Object.getPrototypeOf(value);
11
+ if (prototype !== null && prototype !== Object.prototype && Object.getPrototypeOf(prototype) !== null) {
12
+ return false;
13
+ }
14
+ if (Symbol.iterator in value) {
15
+ return false;
16
+ }
17
+ if (Symbol.toStringTag in value) {
18
+ return Object.prototype.toString.call(value) === "[object Module]";
19
+ }
20
+ return true;
21
+ }
22
+ function _defu(baseObject, defaults, namespace = ".", merger) {
23
+ if (!isPlainObject(defaults)) {
24
+ return _defu(baseObject, {}, namespace, merger);
25
+ }
26
+ const object = Object.assign({}, defaults);
27
+ for (const key in baseObject) {
28
+ if (key === "__proto__" || key === "constructor") {
29
+ continue;
30
+ }
31
+ const value = baseObject[key];
32
+ if (value === null || value === void 0) {
33
+ continue;
34
+ }
35
+ if (merger && merger(object, key, value, namespace)) {
36
+ continue;
37
+ }
38
+ if (Array.isArray(value) && Array.isArray(object[key])) {
39
+ object[key] = [...value, ...object[key]];
40
+ } else if (isPlainObject(value) && isPlainObject(object[key])) {
41
+ object[key] = _defu(
42
+ value,
43
+ object[key],
44
+ (namespace ? `${namespace}.` : "") + key.toString(),
45
+ merger
46
+ );
47
+ } else {
48
+ object[key] = value;
49
+ }
50
+ }
51
+ return object;
52
+ }
53
+ function createDefu(merger) {
54
+ return (...arguments_) => (
55
+ // eslint-disable-next-line unicorn/no-array-reduce
56
+ arguments_.reduce((p, c) => _defu(p, c, "", merger), {})
57
+ );
58
+ }
59
+ var defu = createDefu();
60
+ var defuFn = createDefu((object, key, currentValue) => {
61
+ if (object[key] !== void 0 && typeof currentValue === "function") {
62
+ object[key] = currentValue(object[key]);
63
+ return true;
64
+ }
65
+ });
66
+ var defuArrayFn = createDefu((object, key, currentValue) => {
67
+ if (Array.isArray(object[key]) && typeof currentValue === "function") {
68
+ object[key] = currentValue(object[key]);
69
+ return true;
70
+ }
71
+ });
72
+
73
+ // node_modules/h3/dist/index.mjs
74
+ function hasProp(obj, prop) {
75
+ try {
76
+ return prop in obj;
77
+ } catch {
78
+ return false;
79
+ }
80
+ }
81
+ var __defProp$2 = Object.defineProperty;
82
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
83
+ var __publicField$2 = (obj, key, value) => {
84
+ __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
85
+ return value;
86
+ };
87
+ var H3Error = class extends Error {
88
+ constructor(message, opts = {}) {
89
+ super(message, opts);
90
+ __publicField$2(this, "statusCode", 500);
91
+ __publicField$2(this, "fatal", false);
92
+ __publicField$2(this, "unhandled", false);
93
+ __publicField$2(this, "statusMessage");
94
+ __publicField$2(this, "data");
95
+ __publicField$2(this, "cause");
96
+ if (opts.cause && !this.cause) {
97
+ this.cause = opts.cause;
98
+ }
99
+ }
100
+ toJSON() {
101
+ const obj = {
102
+ message: this.message,
103
+ statusCode: sanitizeStatusCode(this.statusCode, 500)
104
+ };
105
+ if (this.statusMessage) {
106
+ obj.statusMessage = sanitizeStatusMessage(this.statusMessage);
107
+ }
108
+ if (this.data !== void 0) {
109
+ obj.data = this.data;
110
+ }
111
+ return obj;
112
+ }
113
+ };
114
+ __publicField$2(H3Error, "__h3_error__", true);
115
+ function createError(input) {
116
+ if (typeof input === "string") {
117
+ return new H3Error(input);
118
+ }
119
+ if (isError(input)) {
120
+ return input;
121
+ }
122
+ const err = new H3Error(input.message ?? input.statusMessage ?? "", {
123
+ cause: input.cause || input
124
+ });
125
+ if (hasProp(input, "stack")) {
126
+ try {
127
+ Object.defineProperty(err, "stack", {
128
+ get() {
129
+ return input.stack;
130
+ }
131
+ });
132
+ } catch {
133
+ try {
134
+ err.stack = input.stack;
135
+ } catch {
136
+ }
137
+ }
138
+ }
139
+ if (input.data) {
140
+ err.data = input.data;
141
+ }
142
+ if (input.statusCode) {
143
+ err.statusCode = sanitizeStatusCode(input.statusCode, err.statusCode);
144
+ } else if (input.status) {
145
+ err.statusCode = sanitizeStatusCode(input.status, err.statusCode);
146
+ }
147
+ if (input.statusMessage) {
148
+ err.statusMessage = input.statusMessage;
149
+ } else if (input.statusText) {
150
+ err.statusMessage = input.statusText;
151
+ }
152
+ if (err.statusMessage) {
153
+ const originalMessage = err.statusMessage;
154
+ const sanitizedMessage = sanitizeStatusMessage(err.statusMessage);
155
+ if (sanitizedMessage !== originalMessage) {
156
+ console.warn(
157
+ "[h3] Please prefer using `message` for longer error messages instead of `statusMessage`. In the future, `statusMessage` will be sanitized by default."
158
+ );
159
+ }
160
+ }
161
+ if (input.fatal !== void 0) {
162
+ err.fatal = input.fatal;
163
+ }
164
+ if (input.unhandled !== void 0) {
165
+ err.unhandled = input.unhandled;
166
+ }
167
+ return err;
168
+ }
169
+ function isError(input) {
170
+ return input?.constructor?.__h3_error__ === true;
171
+ }
172
+ function isMethod(event, expected, allowHead) {
173
+ if (allowHead && event.method === "HEAD") {
174
+ return true;
175
+ }
176
+ if (typeof expected === "string") {
177
+ if (event.method === expected) {
178
+ return true;
179
+ }
180
+ } else if (expected.includes(event.method)) {
181
+ return true;
182
+ }
183
+ return false;
184
+ }
185
+ function assertMethod(event, expected, allowHead) {
186
+ if (!isMethod(event, expected, allowHead)) {
187
+ throw createError({
188
+ statusCode: 405,
189
+ statusMessage: "HTTP method is not allowed."
190
+ });
191
+ }
192
+ }
193
+ var RawBodySymbol = Symbol.for("h3RawBody");
194
+ var ParsedBodySymbol = Symbol.for("h3ParsedBody");
195
+ var PayloadMethods$1 = ["PATCH", "POST", "PUT", "DELETE"];
196
+ function readRawBody(event, encoding = "utf8") {
197
+ assertMethod(event, PayloadMethods$1);
198
+ const _rawBody = event._requestBody || event.web?.request?.body || event.node.req[RawBodySymbol] || event.node.req.rawBody || event.node.req.body;
199
+ if (_rawBody) {
200
+ const promise2 = Promise.resolve(_rawBody).then((_resolved) => {
201
+ if (Buffer.isBuffer(_resolved)) {
202
+ return _resolved;
203
+ }
204
+ if (typeof _resolved.pipeTo === "function") {
205
+ return new Promise((resolve, reject) => {
206
+ const chunks = [];
207
+ _resolved.pipeTo(
208
+ new WritableStream({
209
+ write(chunk) {
210
+ chunks.push(chunk);
211
+ },
212
+ close() {
213
+ resolve(Buffer.concat(chunks));
214
+ },
215
+ abort(reason) {
216
+ reject(reason);
217
+ }
218
+ })
219
+ ).catch(reject);
220
+ });
221
+ } else if (typeof _resolved.pipe === "function") {
222
+ return new Promise((resolve, reject) => {
223
+ const chunks = [];
224
+ _resolved.on("data", (chunk) => {
225
+ chunks.push(chunk);
226
+ }).on("end", () => {
227
+ resolve(Buffer.concat(chunks));
228
+ }).on("error", reject);
229
+ });
230
+ }
231
+ if (_resolved.constructor === Object) {
232
+ return Buffer.from(JSON.stringify(_resolved));
233
+ }
234
+ return Buffer.from(_resolved);
235
+ });
236
+ return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
237
+ }
238
+ if (!Number.parseInt(event.node.req.headers["content-length"] || "") && !String(event.node.req.headers["transfer-encoding"] ?? "").split(",").map((e) => e.trim()).filter(Boolean).includes("chunked")) {
239
+ return Promise.resolve(void 0);
240
+ }
241
+ const promise = event.node.req[RawBodySymbol] = new Promise(
242
+ (resolve, reject) => {
243
+ const bodyData = [];
244
+ event.node.req.on("error", (err) => {
245
+ reject(err);
246
+ }).on("data", (chunk) => {
247
+ bodyData.push(chunk);
248
+ }).on("end", () => {
249
+ resolve(Buffer.concat(bodyData));
250
+ });
251
+ }
252
+ );
253
+ const result = encoding ? promise.then((buff) => buff.toString(encoding)) : promise;
254
+ return result;
255
+ }
256
+ var DISALLOWED_STATUS_CHARS = /[^\u0009\u0020-\u007E]/g;
257
+ function sanitizeStatusMessage(statusMessage = "") {
258
+ return statusMessage.replace(DISALLOWED_STATUS_CHARS, "");
259
+ }
260
+ function sanitizeStatusCode(statusCode, defaultStatusCode = 200) {
261
+ if (!statusCode) {
262
+ return defaultStatusCode;
263
+ }
264
+ if (typeof statusCode === "string") {
265
+ statusCode = Number.parseInt(statusCode, 10);
266
+ }
267
+ if (statusCode < 100 || statusCode > 999) {
268
+ return defaultStatusCode;
269
+ }
270
+ return statusCode;
271
+ }
272
+ var getSessionPromise = Symbol("getSession");
273
+ function defineEventHandler(handler) {
274
+ if (typeof handler === "function") {
275
+ handler.__is_handler__ = true;
276
+ return handler;
277
+ }
278
+ const _hooks = {
279
+ onRequest: _normalizeArray(handler.onRequest),
280
+ onBeforeResponse: _normalizeArray(handler.onBeforeResponse)
281
+ };
282
+ const _handler = (event) => {
283
+ return _callHandler(event, handler.handler, _hooks);
284
+ };
285
+ _handler.__is_handler__ = true;
286
+ _handler.__resolve__ = handler.handler.__resolve__;
287
+ _handler.__websocket__ = handler.websocket;
288
+ return _handler;
289
+ }
290
+ function _normalizeArray(input) {
291
+ return input ? Array.isArray(input) ? input : [input] : void 0;
292
+ }
293
+ async function _callHandler(event, handler, hooks) {
294
+ if (hooks.onRequest) {
295
+ for (const hook of hooks.onRequest) {
296
+ await hook(event);
297
+ if (event.handled) {
298
+ return;
299
+ }
300
+ }
301
+ }
302
+ const body = await handler(event);
303
+ const response = { body };
304
+ if (hooks.onBeforeResponse) {
305
+ for (const hook of hooks.onBeforeResponse) {
306
+ await hook(event, response);
307
+ }
308
+ }
309
+ return response.body;
310
+ }
311
+ var H3Headers = globalThis.Headers;
312
+ var H3Response = globalThis.Response;
313
+
314
+ // platforms/h3.ts
315
+ function transformHeaders(headers) {
316
+ const formattedHeaders = Object.entries(headers).map(([key, value]) => [
317
+ key,
318
+ Array.isArray(value) ? value.join(", ") : value ?? ""
319
+ ]);
320
+ return formattedHeaders;
321
+ }
322
+ var serve2 = (routeFunction, options) => {
323
+ const handler = defineEventHandler(async (event) => {
324
+ const method = event.node.req.method;
325
+ if (method?.toUpperCase() !== "POST") {
326
+ return {
327
+ status: 405,
328
+ body: "Only POST requests are allowed in worklfows"
329
+ };
330
+ }
331
+ const request_ = event.node.req;
332
+ const protocol = request_.headers["x-forwarded-proto"];
333
+ const host = request_.headers.host;
334
+ const url = `${protocol}://${host}${event.path}`;
335
+ const headers = transformHeaders(request_.headers);
336
+ const request = new Request(url, {
337
+ headers,
338
+ body: await readRawBody(event),
339
+ method: "POST"
340
+ });
341
+ const serveHandler = serve(routeFunction, options);
342
+ return await serveHandler(request);
343
+ });
344
+ return handler;
345
+ };
346
+ export {
347
+ serve2 as serve
348
+ };
package/hono.d.mts ADDED
@@ -0,0 +1,25 @@
1
+ import { Context } from 'hono';
2
+ import { R as RouteFunction, W as WorkflowServeOptions } from './types-CfN1Epuj.mjs';
3
+ import '@upstash/qstash';
4
+
5
+ type WorkflowBindings = {
6
+ QSTASH_TOKEN: string;
7
+ QSTASH_URL?: string;
8
+ QSTASH_CURRENT_SIGNING_KEY?: string;
9
+ QSTASH_NEXT_SIGNING_KEY?: string;
10
+ UPSTASH_WORKFLOW_URL?: string;
11
+ };
12
+ /**
13
+ * Serve method to serve a Upstash Workflow in a Nextjs project
14
+ *
15
+ * See for options https://upstash.com/docs/qstash/workflows/basics/serve
16
+ *
17
+ * @param routeFunction workflow function
18
+ * @param options workflow options
19
+ * @returns
20
+ */
21
+ declare const serve: <TInitialPayload = unknown, TBindings extends WorkflowBindings = WorkflowBindings>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => ((context: Context<{
22
+ Bindings: TBindings;
23
+ }>) => Promise<Response>);
24
+
25
+ export { type WorkflowBindings, serve };
package/hono.d.ts ADDED
@@ -0,0 +1,25 @@
1
+ import { Context } from 'hono';
2
+ import { R as RouteFunction, W as WorkflowServeOptions } from './types-CfN1Epuj.js';
3
+ import '@upstash/qstash';
4
+
5
+ type WorkflowBindings = {
6
+ QSTASH_TOKEN: string;
7
+ QSTASH_URL?: string;
8
+ QSTASH_CURRENT_SIGNING_KEY?: string;
9
+ QSTASH_NEXT_SIGNING_KEY?: string;
10
+ UPSTASH_WORKFLOW_URL?: string;
11
+ };
12
+ /**
13
+ * Serve method to serve a Upstash Workflow in a Nextjs project
14
+ *
15
+ * See for options https://upstash.com/docs/qstash/workflows/basics/serve
16
+ *
17
+ * @param routeFunction workflow function
18
+ * @param options workflow options
19
+ * @returns
20
+ */
21
+ declare const serve: <TInitialPayload = unknown, TBindings extends WorkflowBindings = WorkflowBindings>(routeFunction: RouteFunction<TInitialPayload>, options?: Omit<WorkflowServeOptions<Response, TInitialPayload>, "onStepFinish">) => ((context: Context<{
22
+ Bindings: TBindings;
23
+ }>) => Promise<Response>);
24
+
25
+ export { type WorkflowBindings, serve };