Compare commits
15 Commits
a4fd646d6b
...
v3.2.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
e04bcfb395
|
|||
|
f2ba5f5bc5
|
|||
|
306c046adb
|
|||
|
2dab64be19
|
|||
|
175deddc9c
|
|||
|
ff638ad04f
|
|||
|
b118c28dc7
|
|||
|
9451f466fc
|
|||
|
71fcd6c3c0
|
|||
|
e55392d890
|
|||
|
3aaecd8877
|
|||
|
d8d13c4339
|
|||
|
09d5586cc6
|
|||
|
110bfdd95c
|
|||
|
c68a979614
|
6
.github/workflows/publish-main.yml
vendored
6
.github/workflows/publish-main.yml
vendored
@@ -1,8 +1,8 @@
|
||||
name: Publish (main)
|
||||
name: Publish
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
types: [ published ]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
@@ -28,4 +28,4 @@ jobs:
|
||||
- name: Publish to GPR
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
run: npm publish --tag latest --access public
|
||||
run: npm publish --tag latest --access public
|
||||
21
.github/workflows/test.yml
vendored
Normal file
21
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: latest
|
||||
registry-url: https://registry.npmjs.org/
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Run tests
|
||||
run: npm test
|
||||
@@ -1,6 +1,6 @@
|
||||
.github/
|
||||
src/
|
||||
test/
|
||||
tests/
|
||||
.nvmrc
|
||||
MIGRATION.md
|
||||
tsconfig.json
|
||||
|
||||
@@ -240,7 +240,6 @@ Key | Type | Default Value
|
||||
### Supported Methods
|
||||
|
||||
- `router.any(url, [...handlers])`
|
||||
- `router.connect(url, [...handlers])`
|
||||
- `router.delete(url, [...handlers])`
|
||||
- `router.get(url, [...handlers])`
|
||||
- `router.head(url, [...handlers])`
|
||||
@@ -248,7 +247,6 @@ Key | Type | Default Value
|
||||
- `router.patch(url, [...handlers])`
|
||||
- `router.post(url, [...handlers])`
|
||||
- `router.put(url, [...handlers])`
|
||||
- `router.trace(url, [...handlers])`
|
||||
|
||||
|
||||
#### `url` (string)
|
||||
@@ -410,4 +408,4 @@ export default {
|
||||
return router.handle(request, env, ctx)
|
||||
}
|
||||
}
|
||||
```
|
||||
```
|
||||
9
jest.config.ts
Normal file
9
jest.config.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { Config } from 'jest'
|
||||
|
||||
const config: Config = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
verbose: true
|
||||
}
|
||||
|
||||
export default config
|
||||
3869
package-lock.json
generated
3869
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
10
package.json
10
package.json
@@ -1,11 +1,12 @@
|
||||
{
|
||||
"name": "@tsndr/cloudflare-worker-router",
|
||||
"version": "3.1.3",
|
||||
"version": "3.2.3",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
"build": "tsc",
|
||||
"test": "jest"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -32,6 +33,11 @@
|
||||
"homepage": "https://github.com/tsndr/cloudflare-worker-router#readme",
|
||||
"devDependencies": {
|
||||
"@cloudflare/workers-types": "^4.20231025.0",
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@types/jest": "^29.5.11",
|
||||
"jest": "^29.7.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,4 +442,4 @@ export class Router<Env = any, CtxExt = {}, ReqExt = {}> {
|
||||
|
||||
return response
|
||||
}
|
||||
}
|
||||
}
|
||||
366
tests/index.spec.ts
Normal file
366
tests/index.spec.ts
Normal file
@@ -0,0 +1,366 @@
|
||||
import { describe, expect, test } from '@jest/globals'
|
||||
import { Router } from '../src/index'
|
||||
|
||||
describe('Router', () => {
|
||||
test('use', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/')
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.use(() => testResponse)).toBeInstanceOf(Router)
|
||||
|
||||
router.get('/', () => new Response('failed'))
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('delete', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/', { method: 'DELETE' })
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.delete('/', () => testResponse)).toBeInstanceOf(Router)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('get', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/', { method: 'GET' })
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.get('/', () => testResponse)).toBeInstanceOf(Router)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('head', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/', { method: 'HEAD' })
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.head('/', () => testResponse)).toBeInstanceOf(Router)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('options', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/', { method: 'OPTIONS' })
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.options('/', () => testResponse)).toBeInstanceOf(Router)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('patch', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/', { method: 'PATCH' })
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.patch('/', () => testResponse)).toBeInstanceOf(Router)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('post', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/', { method: 'POST' })
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.post('/test', () => testResponse)).toBeInstanceOf(Router)
|
||||
expect(router.post('/', () => testResponse)).toBeInstanceOf(Router)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('put', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/', { method: 'PUT' })
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.put('/test', () => testResponse)).toBeInstanceOf(Router)
|
||||
expect(router.put('/', () => testResponse)).toBeInstanceOf(Router)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('any', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/', { method: 'POST' })
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.any('/test', () => testResponse)).toBeInstanceOf(Router)
|
||||
expect(router.any('/', () => testResponse)).toBeInstanceOf(Router)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('cors', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/', { method: 'GET' })
|
||||
const testOptionsRequest = new Request('https://example.com/', { method: 'OPTIONS' })
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
expect(router.cors()).toBeInstanceOf(Router)
|
||||
|
||||
router.get('/', () => testResponse)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toBe(200)
|
||||
|
||||
expect(response.headers.get('Access-Control-Allow-Origin')).toBe('*')
|
||||
expect(response.headers.get('Access-Control-Allow-Methods')).toBe('*')
|
||||
expect(response.headers.get('Access-Control-Allow-Headers')).toBe('*')
|
||||
expect(response.headers.get('Access-Control-Allow-Credentials')).toBe(null)
|
||||
expect(response.headers.get('vary')).toBe(null)
|
||||
expect(response.headers.get('Access-Control-Max-Age')).toBe('86400')
|
||||
|
||||
const optionsRes = await router.handle(testOptionsRequest, {})
|
||||
|
||||
expect(optionsRes.status).toBe(204)
|
||||
expect(optionsRes.headers.get('Access-Control-Allow-Origin')).toBe('*')
|
||||
expect(optionsRes.headers.get('Access-Control-Allow-Methods')).toBe('*')
|
||||
expect(optionsRes.headers.get('Access-Control-Allow-Headers')).toBe('*')
|
||||
expect(optionsRes.headers.get('Access-Control-Allow-Credentials')).toBe(null)
|
||||
expect(optionsRes.headers.get('vary')).toBe(null)
|
||||
expect(optionsRes.headers.get('Access-Control-Max-Age')).toBe('86400')
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('params', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/bar/foo')
|
||||
|
||||
router.get('/:foo/:bar', ({ req }) => {
|
||||
return Response.json(req.params)
|
||||
})
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
|
||||
expect(await response.json()).toMatchObject({ foo: 'bar', bar: 'foo' })
|
||||
})
|
||||
|
||||
test('query', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/?foo=bar&bar=foo')
|
||||
|
||||
router.get('/', ({ req }) => {
|
||||
return Response.json(req.query)
|
||||
})
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
|
||||
expect(await response.json()).toMatchObject({ foo: 'bar', bar: 'foo' })
|
||||
})
|
||||
|
||||
test('404', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/')
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toEqual(404)
|
||||
})
|
||||
|
||||
test('debug mode', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/')
|
||||
|
||||
router.debug()
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toEqual(404)
|
||||
|
||||
expect(await response.text()).toBe('Route not found!')
|
||||
})
|
||||
|
||||
test('handler no response', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/')
|
||||
|
||||
router.debug()
|
||||
|
||||
router.get('/', () => {})
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toEqual(404)
|
||||
|
||||
expect(await response.text()).toBe('Handler did not return a Response!')
|
||||
})
|
||||
|
||||
test('wildcard', async () => {
|
||||
const router = new Router()
|
||||
const testRequest = new Request('https://example.com/foo/bar')
|
||||
const testResponse = new Response('success', { status: 200 })
|
||||
|
||||
router.get('*', () => testResponse)
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('bearer', async () => {
|
||||
const router = new Router()
|
||||
const testToken = 'super-secret-token'
|
||||
const testRequest = new Request('https://example.com/', { headers: { 'Authorization': `Bearer ${testToken}` }})
|
||||
|
||||
router.get('/', ({ req }) => new Response(req.bearer()))
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
|
||||
expect(await response.text()).toBe(testToken)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Middleware', () => {
|
||||
const router = new Router()
|
||||
const testHandlerSuccess = () => new Response('success', { status: 200 })
|
||||
const testHandlerContinue = () => {}
|
||||
const testHandlerFailed = () => new Response('failed', { status: 403 })
|
||||
|
||||
router.get('/success', testHandlerContinue, testHandlerSuccess)
|
||||
router.get('/failed', testHandlerFailed, testHandlerSuccess)
|
||||
|
||||
test('continue', async () => {
|
||||
const testRequest = new Request('https://example.com/success')
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toEqual(200)
|
||||
|
||||
expect(await response.text()).toBe('success')
|
||||
})
|
||||
|
||||
test('block', async () => {
|
||||
const testRequest = new Request('https://example.com/failed')
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(response.status).toEqual(403)
|
||||
|
||||
expect(await response.text()).toBe('failed')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Body', () => {
|
||||
|
||||
test('text then text', async () => {
|
||||
const router = new Router()
|
||||
const testText = "lorem ipsum dolor sit amet"
|
||||
const testRequest = new Request('https://example.com/', { method: 'POST', body: testText })
|
||||
|
||||
router.post('/', async ({ req }) => {
|
||||
return Response.json({
|
||||
text: await req.text(),
|
||||
text2: await req.text()
|
||||
})
|
||||
})
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(await response.json()).toMatchObject({ text: testText, text2: testText })
|
||||
})
|
||||
|
||||
test('json then json', async () => {
|
||||
const router = new Router()
|
||||
const testObject = { text: 'cloudflare-worker-router', binary: true, amount: 17 }
|
||||
const testJson = JSON.stringify(testObject)
|
||||
const testRequest = new Request('https://example.com/', { method: 'POST', body: testJson })
|
||||
|
||||
router.post('/', async ({ req }) => {
|
||||
return Response.json({
|
||||
json: await req.json(),
|
||||
json2: await req.json()
|
||||
})
|
||||
})
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(await response.json()).toMatchObject({ json: testObject, json2: testObject })
|
||||
})
|
||||
|
||||
test('text then json', async () => {
|
||||
const router = new Router()
|
||||
const testObject = { text: 'cloudflare-worker-router', binary: true, amount: 17 }
|
||||
const testJson = JSON.stringify(testObject)
|
||||
const testRequest = new Request('https://example.com/', { method: 'POST', body: testJson })
|
||||
|
||||
router.post('/', async ({ req }) => {
|
||||
return Response.json({
|
||||
text: await req.text(),
|
||||
json: await req.json()
|
||||
})
|
||||
})
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(await response.json()).toMatchObject({ text: testJson, json: testObject })
|
||||
})
|
||||
|
||||
test('json then text', async () => {
|
||||
const router = new Router()
|
||||
const testObject = { text: 'cloudflare-worker-router', binary: true, amount: 17 }
|
||||
const testJson = JSON.stringify(testObject)
|
||||
const testRequest = new Request('https://example.com/', { method: 'POST', body: testJson })
|
||||
|
||||
router.post('/', async ({ req }) => {
|
||||
return Response.json({
|
||||
json: await req.json(),
|
||||
text: await req.text()
|
||||
})
|
||||
})
|
||||
|
||||
const response = await router.handle(testRequest, {})
|
||||
|
||||
expect(await response.json()).toMatchObject({ text: testJson, json: testObject })
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user