@feelai/cf-worker
v1.1.0
Published
A lightweight, type-safe wrapper for Cloudflare Workers that integrates seamlessly with `@feelai/contract`.
Downloads
443
Readme
@feelai/cf-worker
A lightweight, type-safe wrapper for Cloudflare Workers that integrates seamlessly with @feelai/contract.
Features
- Type Safety: Full TypeScript support with type inference from your contracts.
- Contract-First: automatically validates inputs against your TypeBox schemas.
- Middleware: Support for
beforeRequest,beforeResponse, andbeforeStreamhooks. - Protocols: Easy handling of HTTP APIs, Server-Sent Events (Streams), and WebSockets.
Installation
bun add @feelai/cf-workerUsage
1. Define your Contract
First, ensure you have a contract defined using @feelai/contract.
// contract.ts
import { Contract, defineApiMap } from "@feelai/contract";
import { Type } from "typebox";
const api = defineApiMap({
"/api/hello": {
input: Type.Object({ name: Type.String() }),
output: Type.Object({ message: Type.String() }),
},
});
export const myContract = new Contract().api(api);2. Initialize the Worker
Create a worker instance passing your contract.
// worker.ts
import { CfWorker } from "@feelai/cf-worker";
import { myContract } from "./contract";
export interface Env {
// Your Cloudflare bindings
kv: KVNamespace;
}
export const worker = new CfWorker<typeof myContract, Env>(myContract);3. Register Handlers
Implement the logic for your defined routes. The input and output types are automatically inferred.
// handlers.ts
import { worker } from "./worker";
worker.fetch("/api/hello", async ({ input, env }) => {
return {
message: `Hello, ${input.name}!`,
};
});4. Export the Worker
Finally, export the fetch handler in your main entry file.
// index.ts
import { worker } from "./worker";
import "./handlers"; // Import to register handlers
export default {
fetch: (req, env, ctx) => {
return worker.handleRequest(req, env, ctx);
},
};Middleware
You can add middleware to intercept requests and responses, for example, to handle CORS or Authentication.
worker
.beforeRequest((req, env, ctx) => {
// Check auth, CORS preflight, etc.
if (req.method === "OPTIONS") {
return new Response(null, { status: 204 });
}
})
.beforeResponse((res, req, env, ctx) => {
// Add CORS headers
res.headers.set("Access-Control-Allow-Origin", "*");
return res;
});Stream & Socket
The worker also supports Stream and Socket handlers if your contract defines them.
// Stream
worker.stream("streamRoute", async ({ stream, input }) => {
stream.emit("event", { data: "foo" });
});
// Socket
worker.socket("socketRoute", async ({ req, env, ctx }) => {
// Handle WebSocket upgrade
// ...
});