[e2e] Remove /api/hook and /api/test-health-check endpoints, call APIs directly

- Remove debug logging from bench.bench.ts
- Remove awaitReturnValue() wrapper, use run.returnValue directly in benchmarks
- Add changeset for Nitro builder manifest fix
- Refactor hookWorkflow tests to call getHookByToken()/resumeHook() directly
  (pass hook object to resumeHook to avoid duplicate lookups)
- Refactor queue-based health check test to call healthCheck() directly
- Assert specific error message for invalid hook token test
- Remove /api/hook and /api/test-health-check endpoints from all workbench apps
  (nextjs-turbopack, nextjs-webpack, vite, hono, express, fastify, sveltekit,
  astro, nuxt, nitro-v2, nitro-v3, nest, example)
This commit is contained in:
Nathan Rajlich
2026-02-07 09:00:19 -08:00
committed by GitHub
parent 82c209c669
commit 5b5b36a03b
25 changed files with 61 additions and 846 deletions
+5
View File
@@ -0,0 +1,5 @@
---
"@workflow/nitro": patch
---
Fix Nitro prod builds: use a physical handler file with inlined manifest content instead of a virtual module with `readFileSync` that referenced an absolute build-machine path
+6 -56
View File
@@ -14,15 +14,6 @@ if (!deploymentUrl) {
throw new Error('`DEPLOYMENT_URL` environment variable is not set');
}
console.log('[bench] deploymentUrl:', deploymentUrl);
console.log('[bench] isLocalDeployment:', isLocalDeployment());
console.log('[bench] WORKFLOW_VERCEL_ENV:', process.env.WORKFLOW_VERCEL_ENV);
console.log('[bench] VERCEL_DEPLOYMENT_ID:', process.env.VERCEL_DEPLOYMENT_ID);
console.log(
'[bench] WORKFLOW_TARGET_WORLD:',
process.env.WORKFLOW_TARGET_WORLD
);
// Configure the World for the bench runner process (same as e2e tests)
if (isLocalDeployment()) {
process.env.WORKFLOW_LOCAL_BASE_URL = deploymentUrl;
@@ -31,19 +22,12 @@ if (isLocalDeployment()) {
const isNextJs = appName.includes('nextjs') || appName.includes('next-');
const dataDirName = isNextJs ? '.next/workflow-data' : '.workflow-data';
process.env.WORKFLOW_LOCAL_DATA_DIR = path.join(appPath, dataDirName);
console.log(
'[bench] configured local world, dataDir:',
process.env.WORKFLOW_LOCAL_DATA_DIR
);
} else if (process.env.WORKFLOW_VERCEL_ENV) {
if (!process.env.VERCEL_DEPLOYMENT_ID) {
throw new Error(
'VERCEL_DEPLOYMENT_ID is required for Vercel benchmarks but is not set'
);
}
console.log('[bench] configured for Vercel world');
} else {
console.log('[bench] no special world configuration');
}
// Manifest type and helpers (same as e2e tests)
@@ -61,22 +45,15 @@ let cachedManifest: WorkflowManifest | null = null;
async function fetchManifest(): Promise<WorkflowManifest> {
if (cachedManifest) return cachedManifest;
const url = new URL('/.well-known/workflow/v1/manifest.json', deploymentUrl);
console.log('[bench] fetching manifest from:', url.toString());
const res = await fetch(url, {
headers: getProtectionBypassHeaders(),
signal: AbortSignal.timeout(30_000),
redirect: 'follow',
});
console.log('[bench] manifest response status:', res.status, 'url:', res.url);
if (!res.ok) {
const text = await res.text();
throw new Error(`Failed to fetch manifest: ${res.status} ${text}`);
}
cachedManifest = (await res.json()) as WorkflowManifest;
console.log(
'[bench] manifest loaded, workflows:',
Object.keys(cachedManifest.workflows).join(', ')
);
return cachedManifest;
}
@@ -133,27 +110,6 @@ const bufferedTimings: Map<
{ run: any; extra?: { firstByteTimeMs?: number; slurpTimeMs?: number } }[]
> = new Map();
/**
* Await run.returnValue with a timeout to prevent benchmarks from hanging.
*/
async function awaitReturnValue<T>(
run: Run<T>,
timeoutMs = 120_000
): Promise<T> {
const timeout = new Promise<never>((_, reject) =>
setTimeout(
() =>
reject(
new Error(
`run.returnValue timed out after ${timeoutMs}ms for run ${run.runId}`
)
),
timeoutMs
)
);
return Promise.race([run.returnValue, timeout]);
}
/**
* Collect run timing metadata from a completed run.
*/
@@ -328,14 +284,8 @@ describe('Workflow Performance Benchmarks', () => {
bench(
'workflow with no steps',
async () => {
console.log('[bench] resolving workflow metadata...');
const wf = await benchWf('noStepsWorkflow');
console.log('[bench] calling start() with workflowId:', wf.workflowId);
const run = await start(wf, [42]);
console.log('[bench] start() returned, runId:', run.runId);
console.log('[bench] awaiting returnValue...');
await awaitReturnValue(run);
console.log('[bench] returnValue resolved');
const run = await start(await benchWf('noStepsWorkflow'), [42]);
await run.returnValue;
const timings = await getRunTimings(run);
stageTiming('workflow with no steps', timings);
},
@@ -346,7 +296,7 @@ describe('Workflow Performance Benchmarks', () => {
'workflow with 1 step',
async () => {
const run = await start(await benchWf('oneStepWorkflow'), [100]);
await awaitReturnValue(run);
await run.returnValue;
const timings = await getRunTimings(run);
stageTiming('workflow with 1 step', timings);
},
@@ -374,7 +324,7 @@ describe('Workflow Performance Benchmarks', () => {
const run = await start(await benchWf('sequentialStepsWorkflow'), [
count,
]);
await awaitReturnValue(run);
await run.returnValue;
const timings = await getRunTimings(run);
stageTiming(name, timings);
},
@@ -386,7 +336,7 @@ describe('Workflow Performance Benchmarks', () => {
'workflow with stream',
async () => {
const run = await start(await benchWf('streamWorkflow'), []);
const value = await awaitReturnValue(run);
const value = await run.returnValue;
const timings = await getRunTimings(run);
// Consume the entire stream and track:
// - firstByteTimeMs: time from workflow start to first byte
@@ -446,7 +396,7 @@ describe('Workflow Performance Benchmarks', () => {
name,
async () => {
const run = await start(await benchWf(workflow), [count]);
await awaitReturnValue(run);
await run.returnValue;
const timings = await getRunTimings(run);
stageTiming(name, timings);
},
+49 -90
View File
@@ -3,7 +3,14 @@ import fs from 'fs';
import path from 'path';
import { afterAll, assert, beforeAll, describe, expect, test } from 'vitest';
import type { Run } from '../src/runtime';
import { getRun, start } from '../src/runtime';
import {
getHookByToken,
getRun,
getWorld,
healthCheck,
resumeHook,
start,
} from '../src/runtime';
import {
cliHealthJson,
cliInspectJson,
@@ -323,51 +330,37 @@ describe('e2e', () => {
const run = await start(await e2e('hookWorkflow'), [token, customData]);
// Wait a few seconds so that the webhook is registered.
// Wait a few seconds so that the hook is registered.
// TODO: make this more efficient when we add subscription support.
await new Promise((resolve) => setTimeout(resolve, 5_000));
const hookUrl = new URL('/api/hook', deploymentUrl);
let res = await fetch(hookUrl, {
method: 'POST',
headers: getProtectionBypassHeaders(),
body: JSON.stringify({ token, data: { message: 'one' } }),
// Look up the hook and resume it with the first payload
let hook = await getHookByToken(token);
expect(hook.runId).toBe(run.runId);
await resumeHook(hook, {
message: 'one',
customData: (hook.metadata as any)?.customData,
});
expect(res.status).toBe(200);
let body = await res.json();
expect(body.runId).toBe(run.runId);
// Invalid token test
res = await fetch(hookUrl, {
method: 'POST',
headers: getProtectionBypassHeaders(),
body: JSON.stringify({ token: 'invalid' }),
});
// NOTE: For Nitro apps (Vite, Hono, etc.) in dev mode, status 404 does some
// unexpected stuff and could return a Vite SPA fallback or can cause a Hono route to hang.
// This is because Nitro passes the 404 requests to the dev server to handle.
expect(res.status).toBeOneOf([404, 422]);
body = await res.json();
expect(body).toBeNull();
await expect(getHookByToken('invalid')).rejects.toThrow(/not found/i);
res = await fetch(hookUrl, {
method: 'POST',
headers: getProtectionBypassHeaders(),
body: JSON.stringify({ token, data: { message: 'two' } }),
// Resume with second payload
hook = await getHookByToken(token);
expect(hook.runId).toBe(run.runId);
await resumeHook(hook, {
message: 'two',
customData: (hook.metadata as any)?.customData,
});
expect(res.status).toBe(200);
body = await res.json();
expect(body.runId).toBe(run.runId);
res = await fetch(hookUrl, {
method: 'POST',
headers: getProtectionBypassHeaders(),
body: JSON.stringify({ token, data: { message: 'three', done: true } }),
// Resume with third (final) payload
hook = await getHookByToken(token);
expect(hook.runId).toBe(run.runId);
await resumeHook(hook, {
message: 'three',
done: true,
customData: (hook.metadata as any)?.customData,
});
expect(res.status).toBe(200);
body = await res.json();
expect(body.runId).toBe(run.runId);
const returnValue = await run.returnValue;
expect(returnValue).toBeInstanceOf(Array);
@@ -961,20 +954,13 @@ describe('e2e', () => {
await new Promise((resolve) => setTimeout(resolve, 5_000));
// Send payload to first workflow
const hookUrl = new URL('/api/hook', deploymentUrl);
let res = await fetch(hookUrl, {
method: 'POST',
headers: getProtectionBypassHeaders(),
body: JSON.stringify({
token,
data: { message: 'test-message-1', customData },
}),
let hook = await getHookByToken(token);
expect(hook.runId).toBe(run1.runId);
await resumeHook(hook, {
message: 'test-message-1',
customData: (hook.metadata as any)?.customData,
});
expect(res.status).toBe(200);
let body = await res.json();
expect(body.runId).toBe(run1.runId);
// Get first workflow result
const run1Result = await run1.returnValue;
expect(run1Result).toMatchObject({
@@ -993,19 +979,13 @@ describe('e2e', () => {
await new Promise((resolve) => setTimeout(resolve, 5_000));
// Send payload to second workflow using same token
res = await fetch(hookUrl, {
method: 'POST',
headers: getProtectionBypassHeaders(),
body: JSON.stringify({
token,
data: { message: 'test-message-2', customData },
}),
hook = await getHookByToken(token);
expect(hook.runId).toBe(run2.runId);
await resumeHook(hook, {
message: 'test-message-2',
customData: (hook.metadata as any)?.customData,
});
expect(res.status).toBe(200);
body = await res.json();
expect(body.runId).toBe(run2.runId);
// Get second workflow result
const run2Result = await run2.returnValue;
expect(run2Result).toMatchObject({
@@ -1059,16 +1039,11 @@ describe('e2e', () => {
expect(run2Data.status).toBe('failed');
// Now send a payload to complete workflow 1
const hookUrl = new URL('/api/hook', deploymentUrl);
const res = await fetch(hookUrl, {
method: 'POST',
headers: getProtectionBypassHeaders(),
body: JSON.stringify({
token,
data: { message: 'test-concurrent', customData },
}),
const hook = await getHookByToken(token);
await resumeHook(hook, {
message: 'test-concurrent',
customData: (hook.metadata as any)?.customData,
});
expect(res.status).toBe(200);
// Verify workflow 1 completed successfully
const run1Result = await run1.returnValue;
@@ -1250,35 +1225,19 @@ describe('e2e', () => {
'health check (queue-based) - workflow and step endpoints respond to health check messages',
{ timeout: 60_000 },
async () => {
// NOTE: This tests the queue-based health check using healthCheck() function.
// This approach bypasses Vercel Deployment Protection by sending messages
// Tests the queue-based health check using healthCheck() directly.
// This bypasses Vercel Deployment Protection by sending messages
// through the Queue infrastructure rather than direct HTTP.
const url = new URL('/api/test-health-check', deploymentUrl);
const world = getWorld();
// Test workflow endpoint health check
const workflowRes = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...getProtectionBypassHeaders(),
},
body: JSON.stringify({ endpoint: 'workflow', timeout: 30000 }),
const workflowResult = await healthCheck(world, 'workflow', {
timeout: 30000,
});
expect(workflowRes.status).toBe(200);
const workflowResult = await workflowRes.json();
expect(workflowResult.healthy).toBe(true);
// Test step endpoint health check
const stepRes = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
...getProtectionBypassHeaders(),
},
body: JSON.stringify({ endpoint: 'step', timeout: 30000 }),
});
expect(stepRes.status).toBe(200);
const stepResult = await stepRes.json();
const stepResult = await healthCheck(world, 'step', { timeout: 30000 });
expect(stepResult.healthy).toBe(true);
}
);
-27
View File
@@ -1,27 +0,0 @@
import type { APIRoute } from 'astro';
import { getHookByToken, resumeHook } from 'workflow/api';
export const POST: APIRoute = async ({ request }: { request: Request }) => {
const { token, data } = await request.json();
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 404 assuming it's the "invalid" token test case
return Response.json(null, { status: 404 });
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return Response.json(hook);
};
export const prerender = false;
@@ -1,32 +0,0 @@
// This route tests the queue-based health check functionality
import { getWorld, healthCheck } from 'workflow/runtime';
export async function POST({ request }: { request: Request }) {
try {
const body = await request.json();
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return Response.json(result);
} catch (error) {
console.error('Health check test failed:', error);
return Response.json(
{
healthy: false,
error: error instanceof Error ? error.message : String(error),
},
{ status: 500 }
);
}
}
export const prerender = false;
-24
View File
@@ -1,24 +0,0 @@
import { getHookByToken, resumeHook } from 'workflow/api';
export const POST = async (request: Request) => {
const { token, data } = await request.json();
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 404 assuming it's the "invalid" token test case
return Response.json(null, { status: 404 });
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return Response.json(hook);
};
@@ -1,30 +0,0 @@
// This route tests the queue-based health check functionality
import { getWorld, healthCheck } from 'workflow/runtime';
export async function POST(req: Request) {
try {
const body = await req.json();
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return Response.json(result);
} catch (error) {
console.error('Health check test failed:', error);
return Response.json(
{
healthy: false,
error: error instanceof Error ? error.message : String(error),
},
{ status: 500 }
);
}
}
-50
View File
@@ -1,6 +1,4 @@
import express from 'express';
import { getHookByToken, resumeHook } from 'workflow/api';
import { getWorld, healthCheck } from 'workflow/runtime';
// Side-effect import to keep _workflows in Nitro's dependency graph for HMR
import '../_workflows.js';
@@ -10,54 +8,6 @@ app.use(express.json());
app.use(express.text({ type: 'text/*' }));
app.use(express.raw({ type: 'application/octet-stream' }));
app.post('/api/hook', async (req, res) => {
const { token, data } = JSON.parse(req.body);
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 422 assuming it's the "invalid" token test case
// NOTE: Need to return 422 because Nitro passes 404 requests to the dev server to handle.
return res.status(422).json(null);
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return res.json(hook);
});
app.post('/api/test-health-check', async (req, res) => {
// This route tests the queue-based health check functionality
try {
const { endpoint = 'workflow', timeout = 30000 } = req.body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return res.json(result);
} catch (error) {
console.error('Health check test failed:', error);
return res.status(500).json({
healthy: false,
error: error instanceof Error ? error.message : String(error),
});
}
});
app.post('/api/test-direct-step-call', async (req, res) => {
// This route tests calling step functions directly outside of any workflow context
// After the SWC compiler changes, step functions in client mode have their directive removed
-48
View File
@@ -1,8 +1,6 @@
import { readFile } from 'node:fs/promises';
import { resolve } from 'node:path';
import Fastify from 'fastify';
import { getHookByToken, resumeHook } from 'workflow/api';
import { getWorld, healthCheck } from 'workflow/runtime';
// Side-effect import to keep _workflows in Nitro's dependency graph for HMR
import '../_workflows.js';
@@ -50,52 +48,6 @@ server.get('/', async (req, reply) => {
return reply.type('text/html').send(html);
});
server.post('/api/hook', async (req: any, reply) => {
const body = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
const { token, data } = body;
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
return reply.code(422).send(null);
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return hook;
});
server.post('/api/test-health-check', async (req: any, reply) => {
// This route tests the queue-based health check functionality
try {
const { endpoint = 'workflow', timeout = 30000 } = req.body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return reply.send(result);
} catch (error) {
console.error('Health check test failed:', error);
return reply.code(500).send({
healthy: false,
error: error instanceof Error ? error.message : String(error),
});
}
});
server.post('/api/test-direct-step-call', async (req: any, reply) => {
// This route tests calling step functions directly outside of any workflow context
// After the SWC compiler changes, step functions in client mode have their directive removed
-54
View File
@@ -1,63 +1,9 @@
import { Hono } from 'hono';
import { getHookByToken, resumeHook } from 'workflow/api';
import { getWorld, healthCheck } from 'workflow/runtime';
// Side-effect import to keep _workflows in Nitro's dependency graph for HMR
import '../_workflows.js';
const app = new Hono();
app.post('/api/hook', async ({ req }) => {
const { token, data } = await req.json();
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 422 assuming it's the "invalid" token test case
// NOTE: Need to return 422 because Nitro passes 404 requests to the dev server to handle.
return Response.json(null, { status: 422 });
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return Response.json(hook);
});
app.post('/api/test-health-check', async ({ req }) => {
// This route tests the queue-based health check functionality
try {
const body = await req.json();
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return Response.json(result);
} catch (error) {
console.error('Health check test failed:', error);
return Response.json(
{
healthy: false,
error: error instanceof Error ? error.message : String(error),
},
{ status: 500 }
);
}
});
app.post('/api/test-direct-step-call', async ({ req }) => {
// This route tests calling step functions directly outside of any workflow context
// After the SWC compiler changes, step functions in client mode have their directive removed
+1 -71
View File
@@ -1,77 +1,7 @@
import {
Body,
Controller,
HttpCode,
HttpException,
HttpStatus,
Post,
Res,
} from '@nestjs/common';
import type { Response } from 'express';
import { getHookByToken, resumeHook } from 'workflow/api';
import { getWorld, healthCheck } from 'workflow/runtime';
import { Body, Controller, Post } from '@nestjs/common';
@Controller('api')
export class AppController {
@Post('hook')
async resumeWorkflowHook(
@Body() body: { token: string; data: any } | string,
@Res() res: Response
) {
// Handle body as string (when Content-Type is not application/json) or object
const parsedBody = typeof body === 'string' ? JSON.parse(body) : body;
const { token, data } = parsedBody;
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// Return 422 for invalid token with null body (matching other workbench apps)
return res.status(HttpStatus.UNPROCESSABLE_ENTITY).json(null);
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return res.status(HttpStatus.OK).json(hook);
}
@Post('test-health-check')
@HttpCode(HttpStatus.OK)
async testHealthCheck(@Body() body: { endpoint?: string; timeout?: number }) {
// This route tests the queue-based health check functionality
try {
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint as 'workflow' | 'step', {
timeout,
});
console.log(`Health check result:`, result);
return result;
} catch (error) {
console.error('Health check test failed:', error);
throw new HttpException(
{
healthy: false,
error: error instanceof Error ? error.message : String(error),
},
HttpStatus.INTERNAL_SERVER_ERROR
);
}
}
@Post('test-direct-step-call')
async invokeStepDirectly(@Body() body: { x: number; y: number }) {
// This route tests calling step functions directly outside of any workflow context
@@ -1 +0,0 @@
../../../../example/api/hook.ts
@@ -1,30 +0,0 @@
// This route tests the queue-based health check functionality
import { getWorld, healthCheck } from 'workflow/runtime';
export async function POST(req: Request) {
try {
const body = await req.json();
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return Response.json(result);
} catch (error) {
console.error('Health check test failed:', error);
return Response.json(
{
healthy: false,
error: error instanceof Error ? error.message : String(error),
},
{ status: 500 }
);
}
}
@@ -1,24 +0,0 @@
import { getHookByToken, resumeHook } from 'workflow/api';
export const POST = async (request: Request) => {
const { token, data } = await request.json();
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 404 assuming it's the "invalid" token test case
return Response.json(null, { status: 404 });
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return Response.json(hook);
};
@@ -1,30 +0,0 @@
// This route tests the queue-based health check functionality
import { getWorld, healthCheck } from 'workflow/runtime';
export async function POST(req: Request) {
try {
const body = await req.json();
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return Response.json(result);
} catch (error) {
console.error('Health check test failed:', error);
return Response.json(
{
healthy: false,
error: error instanceof Error ? error.message : String(error),
},
{ status: 500 }
);
}
}
@@ -1,26 +0,0 @@
import { defineEventHandler, readRawBody } from 'h3';
import { getHookByToken, resumeHook } from 'workflow/api';
export default defineEventHandler(async (event) => {
const body = await readRawBody(event);
const { token, data } = JSON.parse(body as string);
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 404 assuming it's the "invalid" token test case
return Response.json(null, { status: 404 });
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return Response.json(hook);
});
@@ -1,29 +0,0 @@
// This route tests the queue-based health check functionality
import { defineEventHandler, readRawBody } from 'h3';
import { getWorld, healthCheck } from 'workflow/runtime';
export default defineEventHandler(async (event) => {
try {
const rawBody = await readRawBody(event);
const body = rawBody ? JSON.parse(rawBody) : {};
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return result;
} catch (error) {
console.error('Health check test failed:', error);
return {
healthy: false,
error: error instanceof Error ? error.message : String(error),
};
}
});
@@ -1,24 +0,0 @@
import { getHookByToken, resumeHook } from 'workflow/api';
export default async ({ req }: { req: Request }) => {
const { token, data } = await req.json();
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 404 assuming it's the "invalid" token test case
return Response.json(null, { status: 404 });
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return Response.json(hook);
};
@@ -1,30 +0,0 @@
// This route tests the queue-based health check functionality
import { getWorld, healthCheck } from 'workflow/runtime';
export default async ({ req }: { req: Request }) => {
try {
const body = await req.json();
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return Response.json(result);
} catch (error) {
console.error('Health check test failed:', error);
return Response.json(
{
healthy: false,
error: error instanceof Error ? error.message : String(error),
},
{ status: 500 }
);
}
};
-26
View File
@@ -1,26 +0,0 @@
import { defineEventHandler, readRawBody } from 'h3';
import { getHookByToken, resumeHook } from 'workflow/api';
export default defineEventHandler(async (event) => {
const body = await readRawBody(event);
const { token, data } = JSON.parse(body as string);
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 404 assuming it's the "invalid" token test case
return Response.json(null, { status: 404 });
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return Response.json(hook);
});
@@ -1,29 +0,0 @@
// This route tests the queue-based health check functionality
import { defineEventHandler, readRawBody } from 'h3';
import { getWorld, healthCheck } from 'workflow/runtime';
export default defineEventHandler(async (event) => {
try {
const rawBody = await readRawBody(event);
const body = rawBody ? JSON.parse(rawBody) : {};
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return result;
} catch (error) {
console.error('Health check test failed:', error);
return {
healthy: false,
error: error instanceof Error ? error.message : String(error),
};
}
});
@@ -1,29 +0,0 @@
import { json, type RequestHandler } from '@sveltejs/kit';
import { getHookByToken, resumeHook } from 'workflow/api';
export const POST: RequestHandler = async ({
request,
}: {
request: Request;
}) => {
const { token, data } = await request.json();
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 404 assuming it's the "invalid" token test case
return json(null, { status: 404 });
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return json(hook);
};
@@ -1,31 +0,0 @@
// This route tests the queue-based health check functionality
import type { RequestHandler } from '@sveltejs/kit';
import { getWorld, healthCheck } from 'workflow/runtime';
export const POST: RequestHandler = async ({ request }) => {
try {
const body = await request.json();
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return Response.json(result);
} catch (error) {
console.error('Health check test failed:', error);
return Response.json(
{
healthy: false,
error: error instanceof Error ? error.message : String(error),
},
{ status: 500 }
);
}
};
-25
View File
@@ -1,25 +0,0 @@
import { getHookByToken, resumeHook } from 'workflow/api';
export default async ({ req }: { req: Request }) => {
const { token, data } = await req.json();
let hook: Awaited<ReturnType<typeof getHookByToken>>;
try {
hook = await getHookByToken(token);
console.log('hook', hook);
} catch (error) {
console.log('error during getHookByToken', error);
// TODO: `WorkflowAPIError` is not exported, so for now
// we'll return 422 assuming it's the "invalid" token test case
// NOTE: Need to return 422 because Nitro passes 404 requests to the dev server to handle.
return Response.json(null, { status: 422 });
}
await resumeHook(hook.token, {
...data,
// @ts-expect-error metadata is not typed
customData: hook.metadata?.customData,
});
return Response.json(hook);
};
@@ -1,30 +0,0 @@
// This route tests the queue-based health check functionality
import { getWorld, healthCheck } from 'workflow/runtime';
export default async ({ req }: { req: Request }) => {
try {
const body = await req.json();
const { endpoint = 'workflow', timeout = 30000 } = body;
console.log(
`Testing queue-based health check for endpoint: ${endpoint}, timeout: ${timeout}ms`
);
const world = getWorld();
const result = await healthCheck(world, endpoint, { timeout });
console.log(`Health check result:`, result);
return Response.json(result);
} catch (error) {
console.error('Health check test failed:', error);
return Response.json(
{
healthy: false,
error: error instanceof Error ? error.message : String(error),
},
{ status: 500 }
);
}
};