Skip to content

Commit

Permalink
Migrate to TypeScript (#21)
Browse files Browse the repository at this point in the history
* Migrate to TypeScript

* ready for publish
  • Loading branch information
yusukebe authored Jan 5, 2022
1 parent ce6bd99 commit e6039f6
Show file tree
Hide file tree
Showing 36 changed files with 834 additions and 1,034 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
dist

# Cloudflare Workers
worker

Expand Down Expand Up @@ -92,7 +94,6 @@ out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
Expand Down
4 changes: 3 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
example
benchmark
.github
.github
tsconfig.json
src
77 changes: 40 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,21 @@ app.fire()
## Feature

- Fast - the router is implemented with Trie-Tree structure.
- Tiny - use only standard API.
- Portable - zero dependencies.
- Flexible - you can make your own middlewares.
- Optimized - for Cloudflare Workers and Fastly Compute@Edge.
- Easy - simple API, builtin middleware, and TypeScript support.
- Optimized - for Cloudflare Workers or Fastly Compute@Edge.

## Benchmark

Hono is fastest!!

```
hono x 813,001 ops/sec ±2.96% (75 runs sampled)
itty-router x 160,415 ops/sec ±3.31% (85 runs sampled)
sunder x 307,438 ops/sec ±4.77% (73 runs sampled)
hono x 758,264 ops/sec ±5.41% (75 runs sampled)
itty-router x 158,359 ops/sec ±3.21% (89 runs sampled)
sunder x 297,581 ops/sec ±4.74% (83 runs sampled)
Fastest is hono
✨ Done in 37.03s.
✨ Done in 42.84s.
```

## Install
Expand All @@ -45,8 +47,8 @@ $ npm install hono

## Methods

- app.**HTTP_METHOD**(path, callback)
- app.**all**(path, callback)
- app.**HTTP_METHOD**(path, handler)
- app.**all**(path, handler)
- app.**route**(path)
- app.**use**(path, middleware)

Expand Down Expand Up @@ -120,46 +122,44 @@ const { Hono, Middleware } = require('hono')

...

app.use('*', Middleware.poweredBy)
app.use('*', Middleware.poweredBy())
app.use('*', Middleware.logger())

```
### Custom Middleware
```js
const logger = async (c, next) => {
// Custom logger
app.use('*', async (c, next) => {
console.log(`[${c.req.method}] ${c.req.url}`)
await next()
}
})

const addHeader = async (c, next) => {
// Add custom header
app.use('/message/*', async (c, next) => {
await next()
await c.res.headers.add('x-message', 'This is middleware!')
}

app.use('*', logger)
app.use('/message/*', addHeader)
})

app.get('/message/hello', () => 'Hello Middleware!')
```
### Custom 404 Response
```js
const customNotFound = async (c, next) => {
app.use('*', async (c, next) => {
await next()
if (c.res.status === 404) {
c.res = new Response('Custom 404 Not Found', { status: 404 })
}
}

app.use('*', customNotFound)
})
```
### Complex Pattern
```js
// Log response time
// Output response time
app.use('*', async (c, next) => {
await next()
const responseTime = await c.res.headers.get('X-Response-Time')
Expand All @@ -180,46 +180,49 @@ app.use('*', async (c, next) => {
### req
```js

// Get Request object
app.get('/hello', (c) => {
const userAgent = c.req.headers.get('User-Agent')
...
})

// Query params
app.get('/search', (c) => {
const query = c.req.query('q')
...
})

// Captured params
app.get('/entry/:id', (c) => {
const id = c.req.params('id')
...
})
```
### res
```js
// Response object
app.use('/', (c, next) => {
next()
c.res.headers.append('X-Debug', 'Debug message')
})
```
## Request
### query
### text
```js
app.get('/search', (c) => {
const query = c.req.query('q')
...
})
```
### params
```js
app.get('/entry/:id', (c) => {
const id = c.req.params('id')
...
app.get('/say', (c) => {
return c.text('Hello!')
})
```
## Hono in 1 minute
Create your first Cloudflare Workers with Hono from scratch.
### Demo
### How to setup
![Demo](https://user-images.githubusercontent.com/10682/147877447-ff5907cd-49be-4976-b3b4-5df2ac6dfda4.gif)
Expand Down
2 changes: 1 addition & 1 deletion benchmark/handleEvent/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Benchmark from 'benchmark'
import { makeEdgeEnv } from 'edge-mock'
import { Hono } from '../../src/hono.js'
import { Hono } from '../../dist/index'
import itty from 'itty-router'
const { Router: IttyRouter } = itty
import { Router as SunderRouter, Sunder } from 'sunder'
Expand Down
2 changes: 1 addition & 1 deletion benchmark/webapp/hono/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { Hono } = require('../../../src/hono')
const { Hono } = require('../../../dist/index')

const hono = new Hono()
hono.get('/user', () => new Response('User'))
Expand Down
14 changes: 8 additions & 6 deletions example/basic/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
const { Hono, Middleware } = require('../../src/hono')
const { Hono, Middleware } = require('../../dist/index')
// or install from npm:
// const { Hono, Middleware } = require('hono')
const app = new Hono()

// Mount Builtin Middleware
app.use('*', Middleware.poweredBy)
app.use('*', Middleware.poweredBy())
app.use('*', Middleware.logger())

// Custom Middleware
// Add Custom Header
const addHeader = async (c, next) => {
app.use('/hello/*', async (c, next) => {
await next()
await c.res.headers.append('X-message', 'This is addHeader middleware!')
}
app.use('/hello/*', addHeader)
})

// Log response time
app.use('*', async (c, next) => {
Expand All @@ -29,7 +30,7 @@ app.use('*', async (c, next) => {
})

// Routing
app.get('/', () => 'Hono!!')
app.get('/', () => new Response('Hono!!'))
app.get('/hello', () => new Response('This is /hello'))
app.get('/entry/:id', (c) => {
const id = c.req.params('id')
Expand All @@ -42,6 +43,7 @@ app.get('/fetch-url', async () => {
return new Response(`https://example.com/ is ${response.status}`)
})

// Request headers
app.get('/user-agent', (c) => {
const userAgent = c.req.headers.get('User-Agent')
return new Response(`Your UserAgent is ${userAgent}`)
Expand Down
2 changes: 1 addition & 1 deletion example/compute-at-edge/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { Hono } = require('hono')
const app = new Hono()

app.use('*', (c, next) => {
app.use('*', async (c, next) => {
console.log(`[${c.req.method}] ${c.req.url}`)
next()
})
Expand Down
6 changes: 6 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
testMatch: ['**/test/**/*.+(ts|tsx|js)', '**/src/**/(*.)+(spec|test).+(ts|tsx|js)'],
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
},
}
27 changes: 20 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
{
"name": "hono",
"version": "0.0.10",
"description": "Minimal web framework for Cloudflare Workers and Fastly Compute@Edge",
"main": "src/hono.js",
"version": "0.0.11",
"description": "Tiny web framework for Cloudflare Workers and others.",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"test": "jest"
"test": "jest",
"build": "rimraf dist && tsc",
"watch": "tsc -w",
"prepublishOnly": "yarn build"
},
"author": "Yusuke Wada <[email protected]> (https://github.com/yusukebe)",
"license": "MIT",
Expand All @@ -26,7 +33,13 @@
"compute@edge"
],
"devDependencies": {
"edge-mock": "^0.0.15",
"jest": "^27.4.5"
"@cloudflare/workers-types": "^3.3.0",
"@types/jest": "^27.4.0",
"@types/service-worker-mock": "^2.0.1",
"jest": "^27.4.5",
"rimraf": "^3.0.2",
"service-worker-mock": "^2.0.5",
"ts-jest": "^27.1.2",
"typescript": "^4.5.4"
}
}
}
8 changes: 3 additions & 5 deletions src/compose.js → src/compose.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Based on the code in the MIT licensed `koa-compose` package.
const compose = (middleware) => {
return function (context, next) {
export const compose = (middleware: any) => {
return function (context: any, next?: Function) {
let index = -1
return dispatch(0)
function dispatch(i) {
function dispatch(i: number): any {
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i
let fn = middleware[i]
Expand All @@ -17,5 +17,3 @@ const compose = (middleware) => {
}
}
}

module.exports = compose
67 changes: 0 additions & 67 deletions src/hono.d.ts

This file was deleted.

Loading

0 comments on commit e6039f6

Please sign in to comment.