Skip to content

Commit

Permalink
feat: hattip adapter (#11)
Browse files Browse the repository at this point in the history
* feat: hattip adapter
  • Loading branch information
magne4000 authored Jul 15, 2024
1 parent 7104140 commit a8f3aa1
Show file tree
Hide file tree
Showing 13 changed files with 2,186 additions and 0 deletions.
1 change: 1 addition & 0 deletions .idea/universal-handler.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions packages/adapter-hattip/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"imports": {
"@universal-middleware/tests": "../tests/dist",
"mri": "npm:mri",
"zx": "npm:zx",
"wait-port": "npm:wait-port"
}
}
1,868 changes: 1,868 additions & 0 deletions packages/adapter-hattip/deno.lock

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions packages/adapter-hattip/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@universal-middleware/hattip",
"version": "0.0.0",
"type": "module",
"description": "Hono adapter for universal middlewares",
"files": [
"dist"
],
"exports": {
".": "./dist/index.js"
},
"author": "Joël Charles <[email protected]>",
"repository": "https://github.com/magne4000/universal-handler",
"license": "MIT",
"scripts": {
"build": "rimraf dist && tsup",
"dev": "tsup --watch",
"prepack": "pnpm build",
"test": "vitest run",
"test:run-hattip:node": "tsx tests/entry-hattip.ts",
"test:run-hattip:bun": "bun tests/entry-hattip.ts",
"test:run-hattip:deno": "deno run --unstable-sloppy-imports -A tests/entry-hattip.ts",
"test:typecheck": "tsc -p tsconfig.json --noEmit",
"release": "LANG=en_US release-me patch",
"release:minor": "LANG=en_US release-me minor",
"release:commit": "LANG=en_US release-me commit"
},
"dependencies": {
"@universal-middleware/core": "^0.1.1"
},
"devDependencies": {
"@brillout/release-me": "^0.3.9",
"@hattip/adapter-bun": "^0.0.46",
"@hattip/adapter-deno": "^0.0.46",
"@hattip/adapter-node": "^0.0.46",
"@hattip/compose": "^0.0.46",
"@hattip/core": "^0.0.46",
"@hattip/cors": "^0.0.46",
"@hattip/router": "^0.0.46",
"@types/node": "^20.14.10",
"@universal-middleware/tests": "workspace:*",
"rimraf": "^6.0.0",
"tsup": "^8.1.0",
"tsx": "^4.16.2",
"typescript": "^5.5.3",
"vitest": "^2.0.2"
}
}
6 changes: 6 additions & 0 deletions packages/adapter-hattip/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# `@universal-middleware/hattip`

[Universal Middleware](https://github.com/magne4000/universal-middleware) adapter for [hattip](https://github.com/hattipjs/hattip).

> [!NOTE]
> Requires `@hattip/core` and `@hattip/compose` to be installed
49 changes: 49 additions & 0 deletions packages/adapter-hattip/src/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { AdapterRequestContext, HattipHandler } from "@hattip/core";
import type { RequestHandler } from "@hattip/compose";
import type {
UniversalHandler,
UniversalMiddleware,
} from "@universal-middleware/core";

export const contextSymbol = Symbol("unContext");

declare module "@hattip/core" {
interface AdapterRequestContext {
[contextSymbol]?: Universal.Context;
}
}

/**
* Creates a request handler to be passed to hattip
*/
export function createHandler(handler: UniversalHandler): HattipHandler {
return (context) => {
context[contextSymbol] ??= {};
return handler(context.request, context[contextSymbol]);
};
}

/**
* Creates a middleware to be passed to @hattip/compose or @hattip/router
*/
export function createMiddleware(
middleware: UniversalMiddleware,
): RequestHandler {
return async (context) => {
context[contextSymbol] ??= {};
const response = await middleware(context.request, context[contextSymbol]);

if (typeof response === "function") {
const res = await context.next();
return response(res);
} else if (typeof response === "object" && "body" in response) {
return response;
}
};
}

export function getContext(
context: AdapterRequestContext,
): Universal.Context | undefined {
return context[contextSymbol];
}
1 change: 1 addition & 0 deletions packages/adapter-hattip/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { createHandler, createMiddleware, getContext } from "./common.js";
52 changes: 52 additions & 0 deletions packages/adapter-hattip/tests/entry-hattip.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { createHandler, createMiddleware } from "../src/index.js";
import { cors } from "@hattip/cors";
import {
args,
bun,
deno,
handler,
middlewares,
} from "@universal-middleware/tests";
import { createRouter } from "@hattip/router";

const app = createRouter();

// standard hattip middleware
app.use(cors());

middlewares.forEach((middleware) => app.use(createMiddleware(middleware)));

// universal handler
app.get("/", createHandler(handler));

const hattipHandler = app.buildHandler();

const port = args.port ? parseInt(args.port) : 3000;

let bunHandler: unknown;
if (deno) {
const { createServeHandler } = await import("@hattip/adapter-deno");
// @ts-ignore
Deno.serve(
{
port,
onListen() {
console.log(`Server listening on http://localhost:${port}`);
},
},
createServeHandler(hattipHandler),
);
} else if (!bun) {
const { createServer } = await import("@hattip/adapter-node");
createServer(hattipHandler).listen(port, () => {
console.log(`Server listening on http://localhost:${port}`);
});
} else {
const bunAdapter = await import("@hattip/adapter-bun");
bunHandler = bunAdapter.default(hattipHandler, {
port,
});
}

// Bun
export default bunHandler;
30 changes: 30 additions & 0 deletions packages/adapter-hattip/tests/hattip.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { type Run, runTests } from "@universal-middleware/tests";
import * as vitest from "vitest";

let port = 3200;

const runs: Run[] = [
{
name: "adapter-hattip: node",
command: "pnpm run test:run-hattip:node",
port: port++,
},
{
name: "adapter-hattip: bun",
command: "pnpm run test:run-hattip:bun",
port: port++,
},
{
name: "adapter-hattip: deno",
command: "pnpm run test:run-hattip:deno",
port: port++,
},
];

runTests(runs, {
vitest,
test(response) {
// added by @hattip/cors
vitest.expect(response.headers.get("vary")).toContain("Origin");
},
});
3 changes: 3 additions & 0 deletions packages/adapter-hattip/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../tsconfig.json"
}
12 changes: 12 additions & 0 deletions packages/adapter-hattip/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from "tsup";

export default defineConfig([
{
entry: ["./src/index.ts"],
format: ["esm"],
platform: "neutral",
target: "es2022",
dts: true,
clean: true,
},
]);
4 changes: 4 additions & 0 deletions packages/adapter-hattip/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/// <reference types="vitest" />
import { defineConfig } from "vite";

export default defineConfig({});
Loading

0 comments on commit a8f3aa1

Please sign in to comment.