adapter-edge 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vincent Adiasor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # adapter-edge
2
+
3
+ A lightweight adapter for running a single, framework-agnostic request handler
4
+ on any edge runtime that speaks the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) —
5
+ Cloudflare Workers, Vercel Edge, Deno Deploy, Netlify Edge, Bun, and more.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm install adapter-edge
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```ts
16
+ import { createEdgeAdapter, toFetchHandler } from "adapter-edge";
17
+
18
+ const handler = createEdgeAdapter(
19
+ async (request, ctx) => {
20
+ return Response.json({ url: request.url, hasEnv: !!ctx.env });
21
+ },
22
+ {
23
+ middleware: [
24
+ (next) => async (req, ctx) => {
25
+ const res = await next(req, ctx);
26
+ res.headers.set("x-powered-by", "adapter-edge");
27
+ return res;
28
+ },
29
+ ],
30
+ },
31
+ );
32
+
33
+ // Cloudflare Workers / Vercel Edge style export:
34
+ export default { fetch: toFetchHandler(handler) };
35
+ ```
36
+
37
+ ## API
38
+
39
+ ### `createEdgeAdapter(handler, options?)`
40
+
41
+ Composes a handler with middleware and error handling into a single `EdgeHandler`.
42
+
43
+ - `middleware` — array of `EdgeMiddleware`, applied outermost-first.
44
+ - `onError(error, request)` — called when the handler throws; defaults to a JSON 500.
45
+
46
+ ### `toFetchHandler(handler)`
47
+
48
+ Adapts an `EdgeHandler` to the `(request, env, ctx)` signature used by
49
+ Cloudflare Workers and Vercel Edge functions.
50
+
51
+ ### `notFound`
52
+
53
+ A ready-made `EdgeHandler` that returns `404 Not Found`.
54
+
55
+ ## License
56
+
57
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ createEdgeAdapter: () => createEdgeAdapter,
24
+ notFound: () => notFound,
25
+ toFetchHandler: () => toFetchHandler
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var defaultOnError = (error) => {
29
+ const message = error instanceof Error ? error.message : "Internal Server Error";
30
+ return new Response(JSON.stringify({ error: message }), {
31
+ status: 500,
32
+ headers: { "content-type": "application/json" }
33
+ });
34
+ };
35
+ function createEdgeAdapter(handler, options = {}) {
36
+ const { middleware = [], onError = defaultOnError } = options;
37
+ const composed = middleware.reduceRight(
38
+ (next, mw) => mw(next),
39
+ handler
40
+ );
41
+ return async (request, context) => {
42
+ try {
43
+ return await composed(request, context);
44
+ } catch (error) {
45
+ return onError(error, request);
46
+ }
47
+ };
48
+ }
49
+ function toFetchHandler(handler) {
50
+ return (request, env, ctx) => handler(request, { env, waitUntil: ctx?.waitUntil });
51
+ }
52
+ var notFound = () => new Response("Not Found", { status: 404 });
53
+ // Annotate the CommonJS export names for ESM import in node:
54
+ 0 && (module.exports = {
55
+ createEdgeAdapter,
56
+ notFound,
57
+ toFetchHandler
58
+ });
@@ -0,0 +1,48 @@
1
+ /**
2
+ * adapter-edge
3
+ *
4
+ * A tiny adapter that lets you write a single, framework-agnostic request
5
+ * handler and run it on any edge runtime that speaks the Fetch API
6
+ * (Cloudflare Workers, Vercel Edge, Deno Deploy, Netlify Edge, Bun, etc.).
7
+ */
8
+ /**
9
+ * Extra context passed alongside the request. Edge runtimes expose different
10
+ * shapes here (env bindings, waitUntil, etc.), so it is intentionally open.
11
+ */
12
+ interface EdgeContext {
13
+ /** Runtime-provided environment / bindings (e.g. Cloudflare `env`). */
14
+ env?: Record<string, unknown>;
15
+ /** Schedule background work that outlives the response, when supported. */
16
+ waitUntil?: (promise: Promise<unknown>) => void;
17
+ /** Anything else the host runtime wants to surface. */
18
+ [key: string]: unknown;
19
+ }
20
+ /**
21
+ * A framework-agnostic handler. Receives a standard `Request` plus an
22
+ * `EdgeContext` and returns a `Response` (or a promise of one).
23
+ */
24
+ type EdgeHandler = (request: Request, context: EdgeContext) => Response | Promise<Response>;
25
+ /** Middleware wraps a handler, optionally short-circuiting it. */
26
+ type EdgeMiddleware = (handler: EdgeHandler) => EdgeHandler;
27
+ interface CreateEdgeAdapterOptions {
28
+ /** Middleware applied outermost-first (left to right). */
29
+ middleware?: EdgeMiddleware[];
30
+ /** Called when the handler throws. Defaults to a 500 response. */
31
+ onError?: (error: unknown, request: Request) => Response | Promise<Response>;
32
+ }
33
+ /**
34
+ * Compose a handler with middleware and error handling into a single
35
+ * `EdgeHandler` you can mount on any edge runtime.
36
+ */
37
+ declare function createEdgeAdapter(handler: EdgeHandler, options?: CreateEdgeAdapterOptions): EdgeHandler;
38
+ /**
39
+ * Convenience wrapper for Cloudflare Workers / Vercel Edge style exports,
40
+ * mapping their `(request, env, ctx)` signature onto an `EdgeHandler`.
41
+ */
42
+ declare function toFetchHandler(handler: EdgeHandler): (request: Request, env?: Record<string, unknown>, ctx?: {
43
+ waitUntil?: (p: Promise<unknown>) => void;
44
+ }) => Response | Promise<Response>;
45
+ /** A no-op handler returning 404 — handy as a fallback. */
46
+ declare const notFound: EdgeHandler;
47
+
48
+ export { type CreateEdgeAdapterOptions, type EdgeContext, type EdgeHandler, type EdgeMiddleware, createEdgeAdapter, notFound, toFetchHandler };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * adapter-edge
3
+ *
4
+ * A tiny adapter that lets you write a single, framework-agnostic request
5
+ * handler and run it on any edge runtime that speaks the Fetch API
6
+ * (Cloudflare Workers, Vercel Edge, Deno Deploy, Netlify Edge, Bun, etc.).
7
+ */
8
+ /**
9
+ * Extra context passed alongside the request. Edge runtimes expose different
10
+ * shapes here (env bindings, waitUntil, etc.), so it is intentionally open.
11
+ */
12
+ interface EdgeContext {
13
+ /** Runtime-provided environment / bindings (e.g. Cloudflare `env`). */
14
+ env?: Record<string, unknown>;
15
+ /** Schedule background work that outlives the response, when supported. */
16
+ waitUntil?: (promise: Promise<unknown>) => void;
17
+ /** Anything else the host runtime wants to surface. */
18
+ [key: string]: unknown;
19
+ }
20
+ /**
21
+ * A framework-agnostic handler. Receives a standard `Request` plus an
22
+ * `EdgeContext` and returns a `Response` (or a promise of one).
23
+ */
24
+ type EdgeHandler = (request: Request, context: EdgeContext) => Response | Promise<Response>;
25
+ /** Middleware wraps a handler, optionally short-circuiting it. */
26
+ type EdgeMiddleware = (handler: EdgeHandler) => EdgeHandler;
27
+ interface CreateEdgeAdapterOptions {
28
+ /** Middleware applied outermost-first (left to right). */
29
+ middleware?: EdgeMiddleware[];
30
+ /** Called when the handler throws. Defaults to a 500 response. */
31
+ onError?: (error: unknown, request: Request) => Response | Promise<Response>;
32
+ }
33
+ /**
34
+ * Compose a handler with middleware and error handling into a single
35
+ * `EdgeHandler` you can mount on any edge runtime.
36
+ */
37
+ declare function createEdgeAdapter(handler: EdgeHandler, options?: CreateEdgeAdapterOptions): EdgeHandler;
38
+ /**
39
+ * Convenience wrapper for Cloudflare Workers / Vercel Edge style exports,
40
+ * mapping their `(request, env, ctx)` signature onto an `EdgeHandler`.
41
+ */
42
+ declare function toFetchHandler(handler: EdgeHandler): (request: Request, env?: Record<string, unknown>, ctx?: {
43
+ waitUntil?: (p: Promise<unknown>) => void;
44
+ }) => Response | Promise<Response>;
45
+ /** A no-op handler returning 404 — handy as a fallback. */
46
+ declare const notFound: EdgeHandler;
47
+
48
+ export { type CreateEdgeAdapterOptions, type EdgeContext, type EdgeHandler, type EdgeMiddleware, createEdgeAdapter, notFound, toFetchHandler };
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ // src/index.ts
2
+ var defaultOnError = (error) => {
3
+ const message = error instanceof Error ? error.message : "Internal Server Error";
4
+ return new Response(JSON.stringify({ error: message }), {
5
+ status: 500,
6
+ headers: { "content-type": "application/json" }
7
+ });
8
+ };
9
+ function createEdgeAdapter(handler, options = {}) {
10
+ const { middleware = [], onError = defaultOnError } = options;
11
+ const composed = middleware.reduceRight(
12
+ (next, mw) => mw(next),
13
+ handler
14
+ );
15
+ return async (request, context) => {
16
+ try {
17
+ return await composed(request, context);
18
+ } catch (error) {
19
+ return onError(error, request);
20
+ }
21
+ };
22
+ }
23
+ function toFetchHandler(handler) {
24
+ return (request, env, ctx) => handler(request, { env, waitUntil: ctx?.waitUntil });
25
+ }
26
+ var notFound = () => new Response("Not Found", { status: 404 });
27
+ export {
28
+ createEdgeAdapter,
29
+ notFound,
30
+ toFetchHandler
31
+ };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "adapter-edge",
3
+ "version": "0.1.0",
4
+ "description": "A lightweight adapter for running framework-agnostic handlers on edge runtimes (Cloudflare Workers, Vercel Edge, Deno, etc.).",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format esm,cjs --dts --clean",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "typecheck": "tsc --noEmit",
24
+ "prepublishOnly": "npm run build"
25
+ },
26
+ "keywords": [
27
+ "edge",
28
+ "adapter",
29
+ "cloudflare-workers",
30
+ "vercel-edge",
31
+ "deno",
32
+ "fetch",
33
+ "handler",
34
+ "serverless"
35
+ ],
36
+ "author": "@ydaymad",
37
+ "license": "MIT",
38
+ "engines": {
39
+ "node": ">=18"
40
+ },
41
+ "devDependencies": {
42
+ "tsup": "^8.0.0",
43
+ "typescript": "^5.4.0",
44
+ "vitest": "^1.5.0"
45
+ }
46
+ }