@stepflowjs/adapter-hono 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +58 -0
- package/dist/index.js +409 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Stepflow } from '@stepflowjs/core';
|
|
2
|
+
import { AuthContext, AuthConfig, EndpointOption, BaseAdapterOptions } from '@stepflowjs/adapter-shared';
|
|
3
|
+
export { AuthConfig, AuthContext, AuthHandler, AuthResult, EndpointConfig, EndpointOption, EndpointPreset, RouteName, allOf, anyOf, createApiKeyAuth, createBearerAuth, isRouteEnabled, resolveEndpoints } from '@stepflowjs/adapter-shared';
|
|
4
|
+
import { Context, Hono, MiddlewareHandler } from 'hono';
|
|
5
|
+
|
|
6
|
+
/** Hono-specific request type for auth handlers */
|
|
7
|
+
type HonoRequest = {
|
|
8
|
+
header(name: string): string | undefined;
|
|
9
|
+
headers: Headers;
|
|
10
|
+
url: string;
|
|
11
|
+
method: string;
|
|
12
|
+
query(name: string): string | undefined;
|
|
13
|
+
};
|
|
14
|
+
/** Hono-specific auth context */
|
|
15
|
+
type HonoAuthContext = AuthContext<HonoRequest, Context>;
|
|
16
|
+
/** Hono-specific auth config */
|
|
17
|
+
type HonoAuthConfig = AuthConfig<HonoRequest, Context>;
|
|
18
|
+
interface MiddlewareOptions {
|
|
19
|
+
/** Base path for Stepflow routes. When set, middleware only handles paths under this base. */
|
|
20
|
+
basePath?: string;
|
|
21
|
+
/** Endpoint configuration - preset or fine-grained */
|
|
22
|
+
endpoints?: EndpointOption;
|
|
23
|
+
/** Authorization configuration */
|
|
24
|
+
auth?: HonoAuthConfig;
|
|
25
|
+
/** Callback when authorization fails */
|
|
26
|
+
onAuthFailure?: BaseAdapterOptions<HonoRequest, Context>["onAuthFailure"];
|
|
27
|
+
}
|
|
28
|
+
interface RouteOptions {
|
|
29
|
+
/** Prefix all routes under this base path (e.g. "/api/stepflow"). */
|
|
30
|
+
basePath?: string;
|
|
31
|
+
/** Custom health check function. Defaults to stepflow.healthCheck(). */
|
|
32
|
+
healthCheck?: () => Promise<boolean>;
|
|
33
|
+
/** Endpoint configuration - preset or fine-grained */
|
|
34
|
+
endpoints?: EndpointOption;
|
|
35
|
+
/** Authorization configuration */
|
|
36
|
+
auth?: HonoAuthConfig;
|
|
37
|
+
/** Callback when authorization fails */
|
|
38
|
+
onAuthFailure?: BaseAdapterOptions<HonoRequest, Context>["onAuthFailure"];
|
|
39
|
+
}
|
|
40
|
+
interface TriggerRequestBody<TPayload = unknown> {
|
|
41
|
+
payload: TPayload;
|
|
42
|
+
metadata?: Record<string, unknown>;
|
|
43
|
+
runId?: string;
|
|
44
|
+
delay?: number;
|
|
45
|
+
idempotencyKey?: string;
|
|
46
|
+
}
|
|
47
|
+
interface NotifyRequestBody {
|
|
48
|
+
data: unknown;
|
|
49
|
+
}
|
|
50
|
+
interface ErrorResponseBody {
|
|
51
|
+
error: string;
|
|
52
|
+
message?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
declare function createStepflowRoutes(stepflow: Stepflow, options?: RouteOptions): Hono;
|
|
56
|
+
declare function createStepflowMiddleware(stepflow: Stepflow, options?: MiddlewareOptions): MiddlewareHandler;
|
|
57
|
+
|
|
58
|
+
export { type ErrorResponseBody, type HonoAuthConfig, type HonoAuthContext, type HonoRequest, type MiddlewareOptions, type NotifyRequestBody, type RouteOptions, type TriggerRequestBody, createStepflowMiddleware, createStepflowRoutes };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
isRouteEnabled,
|
|
4
|
+
runAuth,
|
|
5
|
+
getAuthFailureResponse,
|
|
6
|
+
createErrorBody
|
|
7
|
+
} from "@stepflowjs/adapter-shared";
|
|
8
|
+
import { Hono } from "hono";
|
|
9
|
+
import { streamSSE } from "hono/streaming";
|
|
10
|
+
import {
|
|
11
|
+
createApiKeyAuth,
|
|
12
|
+
createBearerAuth,
|
|
13
|
+
anyOf,
|
|
14
|
+
allOf,
|
|
15
|
+
isRouteEnabled as isRouteEnabled2,
|
|
16
|
+
resolveEndpoints
|
|
17
|
+
} from "@stepflowjs/adapter-shared";
|
|
18
|
+
function normalizeBasePath(basePath) {
|
|
19
|
+
if (!basePath) return "";
|
|
20
|
+
if (basePath === "/") return "";
|
|
21
|
+
return basePath.startsWith("/") ? basePath.replace(/\/$/, "") : `/${basePath}`;
|
|
22
|
+
}
|
|
23
|
+
function getAccessToken(c) {
|
|
24
|
+
const queryToken = c.req.query("token");
|
|
25
|
+
if (queryToken) return queryToken;
|
|
26
|
+
const authHeader = c.req.header("authorization") ?? c.req.header("Authorization");
|
|
27
|
+
if (!authHeader) return void 0;
|
|
28
|
+
const match = authHeader.match(/^Bearer\s+(.+)$/i);
|
|
29
|
+
return match?.[1];
|
|
30
|
+
}
|
|
31
|
+
function jsonError(_c, status, error, message) {
|
|
32
|
+
const body = message ? { error, message } : { error };
|
|
33
|
+
return new Response(JSON.stringify(body), {
|
|
34
|
+
status,
|
|
35
|
+
headers: { "Content-Type": "application/json" }
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function jsonAuthError(_c, status, code, message) {
|
|
39
|
+
const body = createErrorBody(code, message);
|
|
40
|
+
return new Response(JSON.stringify(body), {
|
|
41
|
+
status,
|
|
42
|
+
headers: { "Content-Type": "application/json" }
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
async function parseJsonBody(c) {
|
|
46
|
+
try {
|
|
47
|
+
return await c.req.json();
|
|
48
|
+
} catch {
|
|
49
|
+
throw new Error("Invalid JSON body");
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function createHonoRequest(c) {
|
|
53
|
+
return {
|
|
54
|
+
header: (name) => c.req.header(name),
|
|
55
|
+
headers: c.req.raw.headers,
|
|
56
|
+
url: c.req.url,
|
|
57
|
+
method: c.req.method,
|
|
58
|
+
query: (name) => c.req.query(name)
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async function checkAuth(c, route, options, params = {}) {
|
|
62
|
+
const ctx = {
|
|
63
|
+
route,
|
|
64
|
+
request: createHonoRequest(c),
|
|
65
|
+
extra: c,
|
|
66
|
+
...params
|
|
67
|
+
};
|
|
68
|
+
const result = await runAuth(ctx, options.auth);
|
|
69
|
+
if (!result.ok) {
|
|
70
|
+
const { status, code, message } = getAuthFailureResponse(result);
|
|
71
|
+
await options.onAuthFailure?.(ctx, result);
|
|
72
|
+
return jsonAuthError(c, status, code, message);
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
function createStepflowRoutes(stepflow, options = {}) {
|
|
77
|
+
const basePath = normalizeBasePath(options.basePath);
|
|
78
|
+
const app = new Hono();
|
|
79
|
+
if (isRouteEnabled("health", options.endpoints)) {
|
|
80
|
+
app.get(`${basePath}/health`, async (c) => {
|
|
81
|
+
const authError = await checkAuth(c, "health", options);
|
|
82
|
+
if (authError) return authError;
|
|
83
|
+
try {
|
|
84
|
+
const ok = await (options.healthCheck?.() ?? stepflow.healthCheck());
|
|
85
|
+
return c.json({ ok }, 200);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return jsonError(
|
|
88
|
+
c,
|
|
89
|
+
500,
|
|
90
|
+
"Internal server error",
|
|
91
|
+
error.message
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
if (isRouteEnabled("trigger", options.endpoints)) {
|
|
97
|
+
app.post(`${basePath}/trigger/:workflowId`, async (c) => {
|
|
98
|
+
const workflowId = c.req.param("workflowId");
|
|
99
|
+
const authError = await checkAuth(c, "trigger", options, { workflowId });
|
|
100
|
+
if (authError) return authError;
|
|
101
|
+
try {
|
|
102
|
+
const body = await parseJsonBody(c);
|
|
103
|
+
const result = await stepflow.trigger(workflowId, body.payload, {
|
|
104
|
+
runId: body.runId,
|
|
105
|
+
metadata: body.metadata,
|
|
106
|
+
delay: body.delay,
|
|
107
|
+
idempotencyKey: body.idempotencyKey
|
|
108
|
+
});
|
|
109
|
+
const response = result;
|
|
110
|
+
return c.json(response, 200);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
const message = error.message;
|
|
113
|
+
if (message.includes("Workflow") && message.includes("not found")) {
|
|
114
|
+
return jsonError(c, 404, "Not found", message);
|
|
115
|
+
}
|
|
116
|
+
if (message === "Invalid JSON body") {
|
|
117
|
+
return jsonError(c, 400, "Bad request", message);
|
|
118
|
+
}
|
|
119
|
+
return jsonError(c, 500, "Internal server error", message);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (isRouteEnabled("runs", options.endpoints)) {
|
|
124
|
+
app.get(`${basePath}/runs/:runId`, async (c) => {
|
|
125
|
+
const runId = c.req.param("runId");
|
|
126
|
+
const authError = await checkAuth(c, "runs", options, { runId });
|
|
127
|
+
if (authError) return authError;
|
|
128
|
+
try {
|
|
129
|
+
const accessToken = getAccessToken(c);
|
|
130
|
+
const run = await stepflow.getRun(runId, { accessToken });
|
|
131
|
+
if (!run) {
|
|
132
|
+
return jsonError(c, 404, "Not found", `Run "${runId}" not found`);
|
|
133
|
+
}
|
|
134
|
+
const response = run;
|
|
135
|
+
return c.json(response, 200);
|
|
136
|
+
} catch (error) {
|
|
137
|
+
const message = error.message;
|
|
138
|
+
if (message === "Invalid access token") {
|
|
139
|
+
return jsonError(c, 401, "Unauthorized", message);
|
|
140
|
+
}
|
|
141
|
+
return jsonError(c, 500, "Internal server error", message);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (isRouteEnabled("runsStream", options.endpoints)) {
|
|
146
|
+
app.get(`${basePath}/runs/:runId/stream`, async (c) => {
|
|
147
|
+
const runId = c.req.param("runId");
|
|
148
|
+
const authError = await checkAuth(c, "runsStream", options, { runId });
|
|
149
|
+
if (authError) return authError;
|
|
150
|
+
const accessToken = getAccessToken(c);
|
|
151
|
+
if (accessToken) {
|
|
152
|
+
try {
|
|
153
|
+
await stepflow.getRun(runId, { accessToken });
|
|
154
|
+
} catch (error) {
|
|
155
|
+
const message = error.message;
|
|
156
|
+
if (message === "Invalid access token") {
|
|
157
|
+
return jsonError(c, 401, "Unauthorized", message);
|
|
158
|
+
}
|
|
159
|
+
return jsonError(c, 500, "Internal server error", message);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const throttleMsParam = c.req.query("throttle");
|
|
163
|
+
const throttleMs = throttleMsParam ? Number(throttleMsParam) : void 0;
|
|
164
|
+
const effectiveThrottleMs = throttleMs !== void 0 && Number.isFinite(throttleMs) && throttleMs >= 0 ? throttleMs : void 0;
|
|
165
|
+
return streamSSE(c, async (stream) => {
|
|
166
|
+
let lastSentAt = 0;
|
|
167
|
+
let executionId;
|
|
168
|
+
let unsubscribeExecution;
|
|
169
|
+
const send = async (type, data) => {
|
|
170
|
+
if (effectiveThrottleMs !== void 0) {
|
|
171
|
+
const now = Date.now();
|
|
172
|
+
if (now - lastSentAt < effectiveThrottleMs) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
lastSentAt = now;
|
|
176
|
+
}
|
|
177
|
+
await stream.writeSSE({
|
|
178
|
+
event: type,
|
|
179
|
+
data: JSON.stringify(data)
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
const publishCurrentExecution = async () => {
|
|
183
|
+
const current = await stepflow.getRun(runId);
|
|
184
|
+
if (!current) return;
|
|
185
|
+
executionId = current.id;
|
|
186
|
+
await send("update", current);
|
|
187
|
+
if (current.status === "completed") {
|
|
188
|
+
await send("execution:complete", { result: current.result });
|
|
189
|
+
}
|
|
190
|
+
if (current.status === "failed") {
|
|
191
|
+
await send("execution:failed", { error: current.error });
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const handleExecutionEvent = (event) => {
|
|
195
|
+
void (async () => {
|
|
196
|
+
if (!executionId) return;
|
|
197
|
+
const execution = await stepflow.getExecution(executionId);
|
|
198
|
+
if (execution) {
|
|
199
|
+
await send("update", execution);
|
|
200
|
+
if (execution.status === "completed") {
|
|
201
|
+
await send("execution:complete", { result: execution.result });
|
|
202
|
+
}
|
|
203
|
+
if (execution.status === "failed") {
|
|
204
|
+
await send("execution:failed", { error: execution.error });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (typeof event === "object" && event !== null && "type" in event && "stepName" in event && typeof event.type === "string" && typeof event.stepName === "string") {
|
|
208
|
+
const type = event.type;
|
|
209
|
+
const stepName = event.stepName;
|
|
210
|
+
if (type === "step:complete" && execution) {
|
|
211
|
+
const step = execution.steps.find(
|
|
212
|
+
(s) => s.name === stepName
|
|
213
|
+
);
|
|
214
|
+
if (step) {
|
|
215
|
+
await send("step:complete", step);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (type === "step:failed" && execution) {
|
|
219
|
+
const step = execution.steps.find(
|
|
220
|
+
(s) => s.name === stepName
|
|
221
|
+
);
|
|
222
|
+
if (step) {
|
|
223
|
+
await send("step:failed", step);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
})();
|
|
228
|
+
};
|
|
229
|
+
try {
|
|
230
|
+
await publishCurrentExecution();
|
|
231
|
+
while (!executionId) {
|
|
232
|
+
await stream.sleep(250);
|
|
233
|
+
await publishCurrentExecution();
|
|
234
|
+
}
|
|
235
|
+
unsubscribeExecution = stepflow.subscribeToExecution(
|
|
236
|
+
executionId,
|
|
237
|
+
handleExecutionEvent
|
|
238
|
+
);
|
|
239
|
+
await stream.sleep(60 * 60 * 1e3);
|
|
240
|
+
} finally {
|
|
241
|
+
unsubscribeExecution?.();
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
if (isRouteEnabled("notify", options.endpoints)) {
|
|
247
|
+
app.post(`${basePath}/notify/:eventId`, async (c) => {
|
|
248
|
+
const eventId = c.req.param("eventId");
|
|
249
|
+
const authError = await checkAuth(c, "notify", options, { eventId });
|
|
250
|
+
if (authError) return authError;
|
|
251
|
+
try {
|
|
252
|
+
const body = await parseJsonBody(c);
|
|
253
|
+
const result = await stepflow.notify(eventId, body.data);
|
|
254
|
+
const response = result;
|
|
255
|
+
return c.json(response, 200);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
const message = error.message;
|
|
258
|
+
if (message === "Invalid JSON body") {
|
|
259
|
+
return jsonError(c, 400, "Bad request", message);
|
|
260
|
+
}
|
|
261
|
+
return jsonError(c, 500, "Internal server error", message);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
if (isRouteEnabled("workflowsTrigger", options.endpoints)) {
|
|
266
|
+
app.post(
|
|
267
|
+
`${basePath}/workflows/:workflowId/trigger`,
|
|
268
|
+
async (c) => {
|
|
269
|
+
const workflowId = c.req.param("workflowId");
|
|
270
|
+
const authError = await checkAuth(c, "workflowsTrigger", options, {
|
|
271
|
+
workflowId
|
|
272
|
+
});
|
|
273
|
+
if (authError) return authError;
|
|
274
|
+
try {
|
|
275
|
+
const body = await parseJsonBody(c);
|
|
276
|
+
const result = await stepflow.trigger(workflowId, body.payload, {
|
|
277
|
+
runId: body.runId,
|
|
278
|
+
metadata: body.metadata,
|
|
279
|
+
delay: body.delay,
|
|
280
|
+
idempotencyKey: body.idempotencyKey
|
|
281
|
+
});
|
|
282
|
+
const response = result;
|
|
283
|
+
return c.json(response, 200);
|
|
284
|
+
} catch (error) {
|
|
285
|
+
const message = error.message;
|
|
286
|
+
if (message.includes("Workflow") && message.includes("not found")) {
|
|
287
|
+
return jsonError(c, 404, "Not found", message);
|
|
288
|
+
}
|
|
289
|
+
if (message === "Invalid JSON body") {
|
|
290
|
+
return jsonError(c, 400, "Bad request", message);
|
|
291
|
+
}
|
|
292
|
+
return jsonError(c, 500, "Internal server error", message);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
if (isRouteEnabled("eventsNotify", options.endpoints)) {
|
|
298
|
+
app.post(`${basePath}/events/:eventId/notify`, async (c) => {
|
|
299
|
+
const eventId = c.req.param("eventId");
|
|
300
|
+
const authError = await checkAuth(c, "eventsNotify", options, {
|
|
301
|
+
eventId
|
|
302
|
+
});
|
|
303
|
+
if (authError) return authError;
|
|
304
|
+
try {
|
|
305
|
+
const body = await parseJsonBody(c);
|
|
306
|
+
const result = await stepflow.notify(eventId, body.data);
|
|
307
|
+
const response = result;
|
|
308
|
+
return c.json(response, 200);
|
|
309
|
+
} catch (error) {
|
|
310
|
+
const message = error.message;
|
|
311
|
+
if (message === "Invalid JSON body") {
|
|
312
|
+
return jsonError(c, 400, "Bad request", message);
|
|
313
|
+
}
|
|
314
|
+
return jsonError(c, 500, "Internal server error", message);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
if (isRouteEnabled("workflowsStream", options.endpoints)) {
|
|
319
|
+
app.post(`${basePath}/workflows/:workflowId/stream`, async (c) => {
|
|
320
|
+
const workflowId = c.req.param("workflowId");
|
|
321
|
+
const authError = await checkAuth(c, "workflowsStream", options, {
|
|
322
|
+
workflowId
|
|
323
|
+
});
|
|
324
|
+
if (authError) return authError;
|
|
325
|
+
try {
|
|
326
|
+
const body = await parseJsonBody(c);
|
|
327
|
+
const { runId, publicAccessToken } = await stepflow.trigger(
|
|
328
|
+
workflowId,
|
|
329
|
+
body.payload
|
|
330
|
+
);
|
|
331
|
+
return streamSSE(c, async (stream) => {
|
|
332
|
+
await stream.writeSSE({
|
|
333
|
+
event: "trigger",
|
|
334
|
+
data: JSON.stringify({ runId, accessToken: publicAccessToken })
|
|
335
|
+
});
|
|
336
|
+
let executionId;
|
|
337
|
+
while (!executionId) {
|
|
338
|
+
const run = await stepflow.getRun(runId);
|
|
339
|
+
executionId = run?.id;
|
|
340
|
+
if (!executionId) {
|
|
341
|
+
await stream.sleep(100);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
const unsubscribe = stepflow.subscribeToExecution(executionId, () => {
|
|
345
|
+
void (async () => {
|
|
346
|
+
const execution = await stepflow.getExecution(executionId);
|
|
347
|
+
if (execution) {
|
|
348
|
+
await stream.writeSSE({
|
|
349
|
+
event: "update",
|
|
350
|
+
data: JSON.stringify(execution)
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
})();
|
|
354
|
+
});
|
|
355
|
+
try {
|
|
356
|
+
await stream.sleep(60 * 60 * 1e3);
|
|
357
|
+
} finally {
|
|
358
|
+
unsubscribe();
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
} catch (error) {
|
|
362
|
+
const message = error.message;
|
|
363
|
+
if (message.includes("Workflow") && message.includes("not found")) {
|
|
364
|
+
return jsonError(c, 404, "Not found", message);
|
|
365
|
+
}
|
|
366
|
+
if (message === "Invalid JSON body") {
|
|
367
|
+
return jsonError(c, 400, "Bad request", message);
|
|
368
|
+
}
|
|
369
|
+
return jsonError(c, 500, "Internal server error", message);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
return app;
|
|
374
|
+
}
|
|
375
|
+
function createStepflowMiddleware(stepflow, options = {}) {
|
|
376
|
+
const basePath = normalizeBasePath(options.basePath);
|
|
377
|
+
const app = createStepflowRoutes(stepflow, {
|
|
378
|
+
basePath,
|
|
379
|
+
endpoints: options.endpoints,
|
|
380
|
+
auth: options.auth,
|
|
381
|
+
onAuthFailure: options.onAuthFailure
|
|
382
|
+
});
|
|
383
|
+
return async (c, next) => {
|
|
384
|
+
const pathname = new URL(c.req.url).pathname;
|
|
385
|
+
if (basePath && !pathname.startsWith(basePath)) {
|
|
386
|
+
await next();
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const executionCtx = (() => {
|
|
390
|
+
try {
|
|
391
|
+
return c.executionCtx;
|
|
392
|
+
} catch {
|
|
393
|
+
return void 0;
|
|
394
|
+
}
|
|
395
|
+
})();
|
|
396
|
+
return app.fetch(c.req.raw, c.env, executionCtx);
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
export {
|
|
400
|
+
allOf,
|
|
401
|
+
anyOf,
|
|
402
|
+
createApiKeyAuth,
|
|
403
|
+
createBearerAuth,
|
|
404
|
+
createStepflowMiddleware,
|
|
405
|
+
createStepflowRoutes,
|
|
406
|
+
isRouteEnabled2 as isRouteEnabled,
|
|
407
|
+
resolveEndpoints
|
|
408
|
+
};
|
|
409
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Execution, TriggerResult, NotifyResult } from \"@stepflowjs/core\";\nimport type { Stepflow } from \"@stepflowjs/core\";\nimport {\n type AuthConfig,\n type AuthContext,\n type BaseAdapterOptions,\n type EndpointOption,\n type RouteName,\n isRouteEnabled,\n runAuth,\n getAuthFailureResponse,\n createErrorBody,\n} from \"@stepflowjs/adapter-shared\";\nimport { Hono } from \"hono\";\nimport type { Context, MiddlewareHandler, Next } from \"hono\";\nimport type { SSEStreamingApi } from \"hono/streaming\";\nimport { streamSSE } from \"hono/streaming\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Hono-specific request type for auth handlers */\nexport type HonoRequest = {\n header(name: string): string | undefined;\n headers: Headers;\n url: string;\n method: string;\n query(name: string): string | undefined;\n};\n\n/** Hono-specific auth context */\nexport type HonoAuthContext = AuthContext<HonoRequest, Context>;\n\n/** Hono-specific auth config */\nexport type HonoAuthConfig = AuthConfig<HonoRequest, Context>;\n\nexport interface MiddlewareOptions {\n /** Base path for Stepflow routes. When set, middleware only handles paths under this base. */\n basePath?: string;\n /** Endpoint configuration - preset or fine-grained */\n endpoints?: EndpointOption;\n /** Authorization configuration */\n auth?: HonoAuthConfig;\n /** Callback when authorization fails */\n onAuthFailure?: BaseAdapterOptions<HonoRequest, Context>[\"onAuthFailure\"];\n}\n\nexport interface RouteOptions {\n /** Prefix all routes under this base path (e.g. \"/api/stepflow\"). */\n basePath?: string;\n /** Custom health check function. Defaults to stepflow.healthCheck(). */\n healthCheck?: () => Promise<boolean>;\n /** Endpoint configuration - preset or fine-grained */\n endpoints?: EndpointOption;\n /** Authorization configuration */\n auth?: HonoAuthConfig;\n /** Callback when authorization fails */\n onAuthFailure?: BaseAdapterOptions<HonoRequest, Context>[\"onAuthFailure\"];\n}\n\nexport interface TriggerRequestBody<TPayload = unknown> {\n payload: TPayload;\n metadata?: Record<string, unknown>;\n runId?: string;\n delay?: number;\n idempotencyKey?: string;\n}\n\nexport interface NotifyRequestBody {\n data: unknown;\n}\n\nexport interface ErrorResponseBody {\n error: string;\n message?: string;\n}\n\n// ============================================================================\n// Re-exports from shared\n// ============================================================================\n\nexport {\n type AuthContext,\n type AuthResult,\n type AuthHandler,\n type AuthConfig,\n type EndpointConfig,\n type EndpointOption,\n type EndpointPreset,\n type RouteName,\n createApiKeyAuth,\n createBearerAuth,\n anyOf,\n allOf,\n isRouteEnabled,\n resolveEndpoints,\n} from \"@stepflowjs/adapter-shared\";\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction normalizeBasePath(basePath: string | undefined): string {\n if (!basePath) return \"\";\n if (basePath === \"/\") return \"\";\n return basePath.startsWith(\"/\")\n ? basePath.replace(/\\/$/, \"\")\n : `/${basePath}`;\n}\n\nfunction getAccessToken(c: Context): string | undefined {\n const queryToken = c.req.query(\"token\");\n if (queryToken) return queryToken;\n\n const authHeader =\n c.req.header(\"authorization\") ?? c.req.header(\"Authorization\");\n if (!authHeader) return undefined;\n\n const match = authHeader.match(/^Bearer\\s+(.+)$/i);\n return match?.[1];\n}\n\nfunction jsonError(\n _c: Context,\n status: number,\n error: string,\n message?: string,\n): Response {\n const body: ErrorResponseBody = message ? { error, message } : { error };\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\nfunction jsonAuthError(\n _c: Context,\n status: number,\n code: string,\n message: string,\n): Response {\n const body = createErrorBody(code, message);\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\nasync function parseJsonBody<T>(c: Context): Promise<T> {\n try {\n return (await c.req.json()) as T;\n } catch {\n throw new Error(\"Invalid JSON body\");\n }\n}\n\n/**\n * Creates a HonoRequest object from Hono Context for auth handlers\n */\nfunction createHonoRequest(c: Context): HonoRequest {\n return {\n header: (name: string) => c.req.header(name),\n headers: c.req.raw.headers,\n url: c.req.url,\n method: c.req.method,\n query: (name: string) => c.req.query(name),\n };\n}\n\n/**\n * Runs authorization check and returns error response if denied\n */\nasync function checkAuth(\n c: Context,\n route: RouteName,\n options: RouteOptions,\n params: { workflowId?: string; eventId?: string; runId?: string } = {},\n): Promise<Response | null> {\n const ctx: HonoAuthContext = {\n route,\n request: createHonoRequest(c),\n extra: c,\n ...params,\n };\n\n const result = await runAuth(ctx, options.auth);\n\n if (!result.ok) {\n const { status, code, message } = getAuthFailureResponse(result);\n await options.onAuthFailure?.(ctx, result);\n return jsonAuthError(c, status, code, message);\n }\n\n return null;\n}\n\n// ============================================================================\n// Routes\n// ============================================================================\n\nexport function createStepflowRoutes(\n stepflow: Stepflow,\n options: RouteOptions = {},\n): Hono {\n const basePath = normalizeBasePath(options.basePath);\n const app = new Hono();\n\n // Health check\n if (isRouteEnabled(\"health\", options.endpoints)) {\n app.get(`${basePath}/health`, async (c: Context) => {\n const authError = await checkAuth(c, \"health\", options);\n if (authError) return authError;\n\n try {\n const ok = await (options.healthCheck?.() ?? stepflow.healthCheck());\n return c.json({ ok }, 200);\n } catch (error) {\n return jsonError(\n c,\n 500,\n \"Internal server error\",\n (error as Error).message,\n );\n }\n });\n }\n\n // Trigger a workflow\n if (isRouteEnabled(\"trigger\", options.endpoints)) {\n app.post(`${basePath}/trigger/:workflowId`, async (c: Context) => {\n const workflowId = c.req.param(\"workflowId\");\n\n const authError = await checkAuth(c, \"trigger\", options, { workflowId });\n if (authError) return authError;\n\n try {\n const body = await parseJsonBody<TriggerRequestBody>(c);\n const result = await stepflow.trigger(workflowId, body.payload, {\n runId: body.runId,\n metadata: body.metadata,\n delay: body.delay,\n idempotencyKey: body.idempotencyKey,\n });\n\n const response: TriggerResult = result;\n return c.json(response, 200);\n } catch (error) {\n const message = (error as Error).message;\n if (message.includes(\"Workflow\") && message.includes(\"not found\")) {\n return jsonError(c, 404, \"Not found\", message);\n }\n if (message === \"Invalid JSON body\") {\n return jsonError(c, 400, \"Bad request\", message);\n }\n return jsonError(c, 500, \"Internal server error\", message);\n }\n });\n }\n\n // Get run status\n if (isRouteEnabled(\"runs\", options.endpoints)) {\n app.get(`${basePath}/runs/:runId`, async (c: Context) => {\n const runId = c.req.param(\"runId\");\n\n const authError = await checkAuth(c, \"runs\", options, { runId });\n if (authError) return authError;\n\n try {\n const accessToken = getAccessToken(c);\n const run = await stepflow.getRun(runId, { accessToken });\n\n if (!run) {\n return jsonError(c, 404, \"Not found\", `Run \"${runId}\" not found`);\n }\n\n const response: Execution = run;\n return c.json(response, 200);\n } catch (error) {\n const message = (error as Error).message;\n if (message === \"Invalid access token\") {\n return jsonError(c, 401, \"Unauthorized\", message);\n }\n return jsonError(c, 500, \"Internal server error\", message);\n }\n });\n }\n\n // SSE stream for run updates\n if (isRouteEnabled(\"runsStream\", options.endpoints)) {\n app.get(`${basePath}/runs/:runId/stream`, async (c: Context) => {\n const runId = c.req.param(\"runId\");\n\n const authError = await checkAuth(c, \"runsStream\", options, { runId });\n if (authError) return authError;\n\n const accessToken = getAccessToken(c);\n if (accessToken) {\n try {\n await stepflow.getRun(runId, { accessToken });\n } catch (error) {\n const message = (error as Error).message;\n if (message === \"Invalid access token\") {\n return jsonError(c, 401, \"Unauthorized\", message);\n }\n return jsonError(c, 500, \"Internal server error\", message);\n }\n }\n\n const throttleMsParam = c.req.query(\"throttle\");\n const throttleMs = throttleMsParam ? Number(throttleMsParam) : undefined;\n const effectiveThrottleMs =\n throttleMs !== undefined &&\n Number.isFinite(throttleMs) &&\n throttleMs >= 0\n ? throttleMs\n : undefined;\n\n return streamSSE(c, async (stream: SSEStreamingApi) => {\n let lastSentAt = 0;\n let executionId: string | undefined;\n let unsubscribeExecution: (() => void) | undefined;\n\n const send = async (type: string, data: unknown) => {\n if (effectiveThrottleMs !== undefined) {\n const now = Date.now();\n if (now - lastSentAt < effectiveThrottleMs) {\n return;\n }\n lastSentAt = now;\n }\n\n await stream.writeSSE({\n event: type,\n data: JSON.stringify(data),\n });\n };\n\n const publishCurrentExecution = async () => {\n const current = await stepflow.getRun(runId);\n if (!current) return;\n\n executionId = current.id;\n await send(\"update\", current);\n\n if (current.status === \"completed\") {\n await send(\"execution:complete\", { result: current.result });\n }\n if (current.status === \"failed\") {\n await send(\"execution:failed\", { error: current.error });\n }\n };\n\n const handleExecutionEvent = (event: unknown) => {\n // We cannot await inside the realtime callback.\n void (async () => {\n if (!executionId) return;\n\n const execution = await stepflow.getExecution(executionId);\n if (execution) {\n await send(\"update\", execution);\n\n if (execution.status === \"completed\") {\n await send(\"execution:complete\", { result: execution.result });\n }\n if (execution.status === \"failed\") {\n await send(\"execution:failed\", { error: execution.error });\n }\n }\n\n if (\n typeof event === \"object\" &&\n event !== null &&\n \"type\" in event &&\n \"stepName\" in event &&\n typeof (event as { type: unknown }).type === \"string\" &&\n typeof (event as { stepName: unknown }).stepName === \"string\"\n ) {\n const type = (event as { type: string }).type;\n const stepName = (event as { stepName: string }).stepName;\n\n if (type === \"step:complete\" && execution) {\n const step = execution.steps.find(\n (s: { name: string }) => s.name === stepName,\n );\n if (step) {\n await send(\"step:complete\", step);\n }\n }\n if (type === \"step:failed\" && execution) {\n const step = execution.steps.find(\n (s: { name: string }) => s.name === stepName,\n );\n if (step) {\n await send(\"step:failed\", step);\n }\n }\n }\n })();\n };\n\n try {\n await publishCurrentExecution();\n\n // If the run doesn't exist yet, poll until it does.\n while (!executionId) {\n await stream.sleep(250);\n await publishCurrentExecution();\n }\n\n unsubscribeExecution = stepflow.subscribeToExecution(\n executionId,\n handleExecutionEvent,\n );\n\n // Keep connection open\n await stream.sleep(60 * 60 * 1000);\n } finally {\n unsubscribeExecution?.();\n }\n });\n });\n }\n\n // Notify an event\n if (isRouteEnabled(\"notify\", options.endpoints)) {\n app.post(`${basePath}/notify/:eventId`, async (c: Context) => {\n const eventId = c.req.param(\"eventId\");\n\n const authError = await checkAuth(c, \"notify\", options, { eventId });\n if (authError) return authError;\n\n try {\n const body = await parseJsonBody<NotifyRequestBody>(c);\n const result = await stepflow.notify(eventId, body.data);\n const response: NotifyResult = result;\n return c.json(response, 200);\n } catch (error) {\n const message = (error as Error).message;\n if (message === \"Invalid JSON body\") {\n return jsonError(c, 400, \"Bad request\", message);\n }\n return jsonError(c, 500, \"Internal server error\", message);\n }\n });\n }\n\n // Alias routes for StepflowClient (client-ts) conventions\n\n if (isRouteEnabled(\"workflowsTrigger\", options.endpoints)) {\n app.post(\n `${basePath}/workflows/:workflowId/trigger`,\n async (c: Context) => {\n const workflowId = c.req.param(\"workflowId\");\n\n const authError = await checkAuth(c, \"workflowsTrigger\", options, {\n workflowId,\n });\n if (authError) return authError;\n\n try {\n const body = await parseJsonBody<{\n payload: unknown;\n metadata?: Record<string, unknown>;\n runId?: string;\n delay?: number;\n idempotencyKey?: string;\n }>(c);\n\n const result = await stepflow.trigger(workflowId, body.payload, {\n runId: body.runId,\n metadata: body.metadata,\n delay: body.delay,\n idempotencyKey: body.idempotencyKey,\n });\n\n const response: TriggerResult = result;\n return c.json(response, 200);\n } catch (error) {\n const message = (error as Error).message;\n if (message.includes(\"Workflow\") && message.includes(\"not found\")) {\n return jsonError(c, 404, \"Not found\", message);\n }\n if (message === \"Invalid JSON body\") {\n return jsonError(c, 400, \"Bad request\", message);\n }\n return jsonError(c, 500, \"Internal server error\", message);\n }\n },\n );\n }\n\n if (isRouteEnabled(\"eventsNotify\", options.endpoints)) {\n app.post(`${basePath}/events/:eventId/notify`, async (c: Context) => {\n const eventId = c.req.param(\"eventId\");\n\n const authError = await checkAuth(c, \"eventsNotify\", options, {\n eventId,\n });\n if (authError) return authError;\n\n try {\n const body = await parseJsonBody<NotifyRequestBody>(c);\n const result = await stepflow.notify(eventId, body.data);\n const response: NotifyResult = result;\n return c.json(response, 200);\n } catch (error) {\n const message = (error as Error).message;\n if (message === \"Invalid JSON body\") {\n return jsonError(c, 400, \"Bad request\", message);\n }\n return jsonError(c, 500, \"Internal server error\", message);\n }\n });\n }\n\n // Minimal stream endpoint: trigger + return SSE stream\n if (isRouteEnabled(\"workflowsStream\", options.endpoints)) {\n app.post(`${basePath}/workflows/:workflowId/stream`, async (c: Context) => {\n const workflowId = c.req.param(\"workflowId\");\n\n const authError = await checkAuth(c, \"workflowsStream\", options, {\n workflowId,\n });\n if (authError) return authError;\n\n try {\n const body = await parseJsonBody<{ payload: unknown }>(c);\n const { runId, publicAccessToken } = await stepflow.trigger(\n workflowId,\n body.payload,\n );\n\n return streamSSE(c, async (stream: SSEStreamingApi) => {\n await stream.writeSSE({\n event: \"trigger\",\n data: JSON.stringify({ runId, accessToken: publicAccessToken }),\n });\n\n // Delegate to the run stream logic by subscribing to the execution.\n // We need executionId; poll until the run exists.\n let executionId: string | undefined;\n while (!executionId) {\n const run = await stepflow.getRun(runId);\n executionId = run?.id;\n if (!executionId) {\n await stream.sleep(100);\n }\n }\n\n const unsubscribe = stepflow.subscribeToExecution(executionId, () => {\n void (async () => {\n const execution = await stepflow.getExecution(executionId);\n if (execution) {\n await stream.writeSSE({\n event: \"update\",\n data: JSON.stringify(execution),\n });\n }\n })();\n });\n\n try {\n await stream.sleep(60 * 60 * 1000);\n } finally {\n unsubscribe();\n }\n });\n } catch (error) {\n const message = (error as Error).message;\n if (message.includes(\"Workflow\") && message.includes(\"not found\")) {\n return jsonError(c, 404, \"Not found\", message);\n }\n if (message === \"Invalid JSON body\") {\n return jsonError(c, 400, \"Bad request\", message);\n }\n return jsonError(c, 500, \"Internal server error\", message);\n }\n });\n }\n\n return app;\n}\n\n// ============================================================================\n// Middleware\n// ============================================================================\n\nexport function createStepflowMiddleware(\n stepflow: Stepflow,\n options: MiddlewareOptions = {},\n): MiddlewareHandler {\n const basePath = normalizeBasePath(options.basePath);\n const app = createStepflowRoutes(stepflow, {\n basePath,\n endpoints: options.endpoints,\n auth: options.auth,\n onAuthFailure: options.onAuthFailure,\n });\n\n return async (c: Context, next: Next) => {\n const pathname = new URL(c.req.url).pathname;\n\n if (basePath && !pathname.startsWith(basePath)) {\n await next();\n return;\n }\n\n // Hono's executionCtx only exists in certain runtimes (e.g. Cloudflare).\n // In Node test environment it may throw when accessed.\n const executionCtx = (() => {\n try {\n return c.executionCtx;\n } catch {\n return undefined;\n }\n })();\n\n return app.fetch(c.req.raw, c.env, executionCtx);\n };\n}\n"],"mappings":"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","names":["isRouteEnabled"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stepflowjs/adapter-hono",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Hono framework adapter for Stepflow workflows",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@stepflowjs/adapter-shared": "0.0.1",
|
|
20
|
+
"@stepflowjs/core": "0.0.1"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"hono": "^4.7.11",
|
|
24
|
+
"tsup": "^8.5.1",
|
|
25
|
+
"vitest": "^4.0.17"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"hono": "^4.0.0",
|
|
29
|
+
"typescript": "^5.0.0"
|
|
30
|
+
},
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"author": "Stepflow Contributors",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://stepflow-production.up.railway.app",
|
|
36
|
+
"directory": "packages/adapters/hono"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://stepflow-production.up.railway.app",
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://stepflow-production.up.railway.app"
|
|
41
|
+
},
|
|
42
|
+
"keywords": [
|
|
43
|
+
"stepflow",
|
|
44
|
+
"adapter",
|
|
45
|
+
"hono",
|
|
46
|
+
"framework",
|
|
47
|
+
"workflow",
|
|
48
|
+
"orchestration"
|
|
49
|
+
],
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsup",
|
|
55
|
+
"dev": "tsup --watch",
|
|
56
|
+
"typecheck": "tsc --noEmit",
|
|
57
|
+
"test": "vitest",
|
|
58
|
+
"clean": "rm -rf dist"
|
|
59
|
+
}
|
|
60
|
+
}
|