From 45f24838e060968767e88814668a128ee8f61aac Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Wed, 20 Dec 2023 17:34:05 -0600 Subject: [PATCH 01/12] fixed: createResponse(undefined) should return undefined --- CHANGELOG.md | 2 ++ src/createResponse.spec.ts | 8 ++++++++ src/createResponse.ts | 20 +++++++------------- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c4ddf11..572c33d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## Changelog +- **v4.0.24** + - fixed: createResponse(undefined) should return undefined (not a Response) - **v4.1.0** - added: `HasContent` type to `withContent` (credit [@alexrosenfeld10](https://github.com/alexrosenfeld10)) - added: Adds basic text/formData support to supplement the native JSON support of `withContent` diff --git a/src/createResponse.spec.ts b/src/createResponse.spec.ts index 4346a598..9462cdae 100644 --- a/src/createResponse.spec.ts +++ b/src/createResponse.spec.ts @@ -51,6 +51,14 @@ describe('createResponse(mimeType: string, transform?: Function)', () => { expect(r2).toBe(r1) }) + it('will ignore an undefined body', async () => { + const r1 = json() + const r2 = json(undefined) + + expect(r1).toBeUndefined() + expect(r2).toBeUndefined() + }) + describe('format helpers', () => { const formats = [ { name: 'json', fn: json, mime: 'application/json; charset=utf-8' }, diff --git a/src/createResponse.ts b/src/createResponse.ts index 59558a68..4faac51d 100644 --- a/src/createResponse.ts +++ b/src/createResponse.ts @@ -11,16 +11,10 @@ export const createResponse = format = 'text/plain; charset=utf-8', transform?: BodyTransformer ): ResponseFormatter => - (body, options?: ResponseInit) => { - const { headers = {}, ...rest } = options || {} - - if (body?.constructor.name === 'Response') return body - - return new Response(transform ? transform(body) : body, { - headers: { - 'content-type': format, - ...headers, - }, - ...rest, - }) - } + (body, { headers = {}, ...rest } = {}) => + body === undefined || body?.constructor.name === 'Response' + ? body + : new Response(transform ? transform(body) : body, { + headers: { 'content-type': format, ...headers }, + ...rest + }) From 564591a6413c3be0180b7ec6d7a9f358185c1f8b Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Wed, 20 Dec 2023 17:34:34 -0600 Subject: [PATCH 02/12] released v4.0.24 - released 4.0.24 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb69d765..8be32aa0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "itty-router", - "version": "4.0.23", + "version": "4.0.24", "description": "A tiny, zero-dependency router, designed to make beautiful APIs in any environment.", "main": "./index.js", "module": "./index.mjs", From 8f68b7d0185a38de287eda5baff470b00c69f8fa Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Wed, 20 Dec 2023 17:46:49 -0600 Subject: [PATCH 03/12] densified withParams, losing ~10 bytes --- src/withParams.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/withParams.ts b/src/withParams.ts index 3bfad31f..a225cec8 100644 --- a/src/withParams.ts +++ b/src/withParams.ts @@ -2,11 +2,6 @@ import { IRequest } from './Router' export const withParams = (request: IRequest): void => { request.proxy = new Proxy(request.proxy || request, { - get: (obj, prop) => { - let p - if ((p = obj[prop]) !== undefined) return p.bind?.(request) || p - - return obj?.params?.[prop] - }, + get: (obj, prop) => obj[prop] !== undefined ? obj[prop].bind?.(request) || obj[prop] : obj?.params?.[prop] }) } From dbd73e214675227a223f819d97e7f975c6a94d39 Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Wed, 20 Dec 2023 21:01:07 -0600 Subject: [PATCH 04/12] error minification --- src/error.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/error.ts b/src/error.ts index 0459e8e7..d58e335a 100644 --- a/src/error.ts +++ b/src/error.ts @@ -12,17 +12,13 @@ export interface ErrorFormatter { (error: ErrorLike): Response } -const getMessage = (code: number): string => { - return ( - { - 400: 'Bad Request', - 401: 'Unauthorized', - 403: 'Forbidden', - 404: 'Not Found', - 500: 'Internal Server Error', - }[code] || 'Unknown Error' - ) -} +const getMessage = (code: number): string => ({ + 400: 'Bad Request', + 401: 'Unauthorized', + 403: 'Forbidden', + 404: 'Not Found', + 500: 'Internal Server Error', +})[code] || 'Unknown Error' export const error: ErrorFormatter = (a = 500, b?: ErrorBody) => { // handle passing an Error | StatusError directly in From 1f737b3762e0d512ef3849b8ece91ddde46ffc28 Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Wed, 20 Dec 2023 21:01:42 -0600 Subject: [PATCH 05/12] withParams readability --- src/withParams.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/withParams.ts b/src/withParams.ts index a225cec8..de1d7ad8 100644 --- a/src/withParams.ts +++ b/src/withParams.ts @@ -2,6 +2,8 @@ import { IRequest } from './Router' export const withParams = (request: IRequest): void => { request.proxy = new Proxy(request.proxy || request, { - get: (obj, prop) => obj[prop] !== undefined ? obj[prop].bind?.(request) || obj[prop] : obj?.params?.[prop] + get: (obj, prop) => obj[prop] !== undefined + ? obj[prop].bind?.(request) || obj[prop] + : obj?.params?.[prop] }) } From c848914219bff66305a89be223ee276951c48a99 Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Thu, 21 Dec 2023 21:35:51 -0600 Subject: [PATCH 06/12] minification passes --- src/Router.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Router.ts b/src/Router.ts index 3daa6d39..516a9428 100644 --- a/src/Router.ts +++ b/src/Router.ts @@ -95,17 +95,17 @@ export const Router = < routes, async handle (request: RequestLike, ...args) { let response, match, url = new URL(request.url), query: any = request.query = { __proto__: null } - for (let [k, v] of url.searchParams) { - query[k] = query[k] === undefined ? v : [query[k], v].flat() - } - for (let [method, regex, handlers, path] of routes) { + + for (let [k, v] of url.searchParams) + // @ts-expect-error - overloads + query[k] = query[k] ? [].concat(query[k], v) : v + + for (let [method, regex, handlers, path] of routes) if ((method === request.method || method === 'ALL') && (match = url.pathname.match(regex))) { request.params = match.groups || {} // embed params in request request.route = path // embed route path in request - for (let handler of handlers) { - if ((response = await handler(request.proxy || request, ...args)) !== undefined) return response - } + for (let handler of handlers) + if ((response = await handler(request.proxy ?? request, ...args)) != null) return response } - } } }) From fcccc50f48f888f2d15ea88a14fcb4a71dfdadd2 Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Thu, 21 Dec 2023 21:40:50 -0600 Subject: [PATCH 07/12] removed ts-expect-error --- src/Router.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Router.ts b/src/Router.ts index 516a9428..36ebc93b 100644 --- a/src/Router.ts +++ b/src/Router.ts @@ -96,10 +96,11 @@ export const Router = < async handle (request: RequestLike, ...args) { let response, match, url = new URL(request.url), query: any = request.query = { __proto__: null } + // 1. parse query params for (let [k, v] of url.searchParams) - // @ts-expect-error - overloads - query[k] = query[k] ? [].concat(query[k], v) : v + query[k] = query[k] ? ([] as string[]).concat(query[k], v) : v + // 2. then test routes for (let [method, regex, handlers, path] of routes) if ((method === request.method || method === 'ALL') && (match = url.pathname.match(regex))) { request.params = match.groups || {} // embed params in request From d570f40f1e0eaefd97f8fb97bfab60a5fa52d55b Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Thu, 21 Dec 2023 21:42:12 -0600 Subject: [PATCH 08/12] fixed type on query --- src/Router.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Router.ts b/src/Router.ts index 36ebc93b..5c456d29 100644 --- a/src/Router.ts +++ b/src/Router.ts @@ -94,7 +94,7 @@ export const Router = < }), routes, async handle (request: RequestLike, ...args) { - let response, match, url = new URL(request.url), query: any = request.query = { __proto__: null } + let response, match, url = new URL(request.url), query: Record = request.query = { __proto__: null } // 1. parse query params for (let [k, v] of url.searchParams) From 093960fb75e5c035e803f08cc38eb5d5a284483b Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Thu, 21 Dec 2023 21:47:27 -0600 Subject: [PATCH 09/12] released v4.0.25 - minification pass --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8be32aa0..9bfb4fa0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "itty-router", - "version": "4.0.24", + "version": "4.0.25", "description": "A tiny, zero-dependency router, designed to make beautiful APIs in any environment.", "main": "./index.js", "module": "./index.mjs", From 8c9f21bc323deb9c887feafa2dd56121886e9568 Mon Sep 17 00:00:00 2001 From: Kevin Whitley Date: Wed, 3 Jan 2024 12:46:34 -0600 Subject: [PATCH 10/12] released v4.0.26 - attempt to fix badges --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9bfb4fa0..cc32da77 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "itty-router", - "version": "4.0.25", + "version": "4.0.26", "description": "A tiny, zero-dependency router, designed to make beautiful APIs in any environment.", "main": "./index.js", "module": "./index.mjs", From ef226b578674f06fe0a114ff541155384bb0b422 Mon Sep 17 00:00:00 2001 From: "Kevin R. Whitley" Date: Sun, 7 Jan 2024 17:16:27 -0600 Subject: [PATCH 11/12] cleaning up testing syntax (#209) --- src/Router.spec.ts | 138 ++++++++++++++++++++++++--------------------- test/index.ts | 23 +++++--- 2 files changed, 91 insertions(+), 70 deletions(-) diff --git a/src/Router.spec.ts b/src/Router.spec.ts index 1e504680..55e05cae 100644 --- a/src/Router.spec.ts +++ b/src/Router.spec.ts @@ -1,6 +1,6 @@ import 'isomorphic-fetch' import { describe, expect, it, vi } from 'vitest' -import { buildRequest, createTestRunner, extract } from '../test' +import { createTestRunner, extract, toReq } from '../test' import { Router } from './Router' const ERROR_MESSAGE = 'Error Message' @@ -17,7 +17,7 @@ describe('Router', () => { { path: '/foo', callback: vi.fn(extract), method: 'post' }, { path: '/passthrough', - callback: vi.fn(({ path, name }) => ({ path, name })), + callback: vi.fn(({ method, name }) => ({ method, name })), method: 'get', }, ] @@ -57,18 +57,18 @@ describe('Router', () => { const router = Router({ routes: [ - ['GET', /^\/test\.(?[^/]+)\/*$/, [basicHandler]], - ['GET', /^\/custom-(?\d{2,4})$/, [customHandler]], + ['GET', /^\/test\.(?[^/]+)\/*$/, [basicHandler], '/test'], + ['GET', /^\/custom-(?\d{2,4})$/, [customHandler], '/custom'], ], }) - await router.handle(buildRequest({ path: '/test.a.b' })) + await router.handle(toReq('/test.a.b')) expect(basicHandler).toHaveReturnedWith({ x: 'a.b' }) - await router.handle(buildRequest({ path: '/custom-12345' })) + await router.handle(toReq('/custom-12345')) expect(customHandler).not.toHaveBeenCalled() // custom route mismatch - await router.handle(buildRequest({ path: '/custom-123' })) + await router.handle(toReq('/custom-123')) expect(customHandler).toHaveReturnedWith({ custom: '123' }) // custom route hit }) @@ -78,9 +78,9 @@ describe('Router', () => { const router = Router() // allows manual loading (after config) - router.routes.push(['GET', /^\/custom2-(?\w\d{3})$/, [handler]]) + router.routes.push(['GET', /^\/custom2-(?\w\d{3})$/, [handler], '/custom']) - await router.handle(buildRequest({ path: '/custom2-a456' })) + await router.handle(toReq('/custom2-a456')) expect(handler).toHaveReturnedWith({ custom: 'a456' }) // custom route hit }) @@ -98,7 +98,7 @@ describe('Router', () => { const handler3 = vi.fn((req) => ({ c: 3, ...req })) r.get('/multi/:id', handler1, handler2, handler3) - await r.handle(buildRequest({ path: '/multi/foo' })) + await r.handle(toReq('/multi/foo')) expect(handler2).toHaveBeenCalled() expect(handler3).not.toHaveBeenCalled() @@ -110,7 +110,7 @@ describe('Router', () => { const syncRouter = Router() syncRouter.get('/foo', () => 3) - const response = syncRouter.handle(buildRequest({ path: '/foo' })) + const response = syncRouter.handle(toReq('/foo')) expect(typeof response?.then).toBe('function') expect(typeof response?.catch).toBe('function') @@ -118,7 +118,7 @@ describe('Router', () => { it('returns { path, query } from match', async () => { const route = routes.find((r) => r.path === '/foo/:id') - await router.handle(buildRequest({ path: '/foo/13?foo=bar&cat=dog' })) + await router.handle(toReq('/foo/13?foo=bar&cat=dog')) expect(route?.callback).toHaveReturnedWith({ params: { id: '13' }, @@ -128,7 +128,7 @@ describe('Router', () => { it('BUG: avoids toString prototype bug', async () => { const route = routes.find((r) => r.path === '/foo/:id') - await router.handle(buildRequest({ path: '/foo/13?toString=value' })) + await router.handle(toReq('/foo/13?toString=value')) expect(route?.callback).toHaveReturnedWith({ params: { id: '13' }, @@ -139,9 +139,9 @@ describe('Router', () => { it('requires exact route match', async () => { const route = routes.find((r) => r.path === '/') - await router.handle(buildRequest({ path: '/foo' })) + await router.handle(toReq('/foo')) - expect(route.callback).not.toHaveBeenCalled() + expect(route?.callback).not.toHaveBeenCalled() }) it('returns { method, route } from matched route', async () => { @@ -152,10 +152,10 @@ describe('Router', () => { const router = Router() router.get(route1, handler).post(route2, handler) - await router.handle(buildRequest({ path: route1, method: 'GET' })) + await router.handle(toReq(route1)) expect(handler).toHaveReturnedWith({ method: 'GET', route: route1 }) - await router.handle(buildRequest({ path: route2, method: 'POST' })) + await router.handle(toReq(`POST ${route2}`)) expect(handler).toHaveReturnedWith({ method: 'POST', route: route2 }) }) @@ -166,30 +166,28 @@ describe('Router', () => { router.get('/foo/static', handler1) router.get('/foo/:id', handler2) - await router.handle(buildRequest({ path: '/foo/static' })) + await router.handle(toReq('/foo/static')) expect(handler1).toHaveBeenCalled() expect(handler2).not.toHaveBeenCalled() - await router.handle(buildRequest({ path: '/foo/3' })) + await router.handle(toReq('/foo/3')) expect(handler1).toHaveBeenCalledTimes(1) expect(handler2).toHaveBeenCalled() }) it('honors correct method (e.g. GET, POST, etc)', async () => { const route = routes.find((r) => r.path === '/foo' && r.method === 'post') - await router.handle(buildRequest({ method: 'POST', path: '/foo' })) + await router.handle(toReq('POST /foo')) - expect(route.callback).toHaveBeenCalled() + expect(route!.callback).toHaveBeenCalled() }) it('passes the entire original request through to the handler', async () => { const route = routes.find((r) => r.path === '/passthrough') - await router.handle( - buildRequest({ path: '/passthrough', name: 'miffles' }) - ) + await router.handle({ ...toReq('/passthrough'), name: 'miffles' }) - expect(route.callback).toHaveReturnedWith({ - path: '/passthrough', + expect(route!.callback).toHaveReturnedWith({ + method: 'GET', name: 'miffles', }) }) @@ -204,10 +202,10 @@ describe('Router', () => { router2.get('/foo', matchHandler) router1.all('/nested/*', router2.handle).all('*', missingHandler) - await router1.handle(buildRequest({ path: '/foo' })) + await router1.handle(toReq('/foo')) expect(missingHandler).toHaveBeenCalled() - await router1.handle(buildRequest({ path: '/nested/foo' })) + await router1.handle(toReq('/nested/foo')) expect(matchHandler).toHaveBeenCalled() }) @@ -229,7 +227,7 @@ describe('Router', () => { r.get('/middleware/*', middleware) r.get('/middleware/:id', handler) - await r.handle(buildRequest({ path: '/middleware/foo' })) + await r.handle(toReq('/middleware/foo')) expect(handler).toHaveBeenCalled() expect(handler).toHaveReturnedWith(13) @@ -240,10 +238,10 @@ describe('Router', () => { const handler = vi.fn() router.get('/foo/:id?', handler) - await router.handle(buildRequest({ path: '/api/foo' })) + await router.handle(toReq('/api/foo')) expect(handler).toHaveBeenCalled() - await router.handle(buildRequest({ path: '/api/foo/13' })) + await router.handle(toReq('/api/foo/13')) expect(handler).toHaveBeenCalledTimes(2) }) @@ -252,7 +250,7 @@ describe('Router', () => { const handler = vi.fn() router.get('/foo/:id?', handler) - await router.handle(buildRequest({ path: '/foo' })) + await router.handle(toReq('/foo')) expect(handler).toHaveBeenCalled() }) @@ -261,41 +259,20 @@ describe('Router', () => { const handler = vi.fn((req) => req.params) router.get('/:id', handler) - await router.handle(buildRequest({ path: '/todos/13' })) + await router.handle(toReq('/todos/13')) expect(handler).toHaveBeenCalled() expect(handler).toHaveReturnedWith({ collection: 'todos', id: '13' }) }) - it('can handle nested routers', async () => { - const router1 = Router() - const router2 = Router({ base: '/nested' }) - const handler1 = vi.fn() - const handler2 = vi.fn() - const handler3 = vi.fn() - router1.get('/pet', handler1) - router1.get('/nested/*', router2.handle) - router2.get('/', handler3) - router2.get('/bar/:id?', handler2) - - await router1.handle(buildRequest({ path: '/pet' })) - expect(handler1).toHaveBeenCalled() - - await router1.handle(buildRequest({ path: '/nested/bar' })) - expect(handler2).toHaveBeenCalled() - - await router1.handle(buildRequest({ path: '/nested' })) - expect(handler3).toHaveBeenCalled() - }) - it('allows any method to match an "all" route', async () => { const router = Router() const handler = vi.fn() router.all('/crud/*', handler) - await router.handle(buildRequest({ path: '/crud/foo' })) + await router.handle(toReq('/crud/foo')) expect(handler).toHaveBeenCalled() - await router.handle(buildRequest({ method: 'POST', path: '/crud/bar' })) + await router.handle(toReq('POST /crud/bar')) expect(handler).toHaveBeenCalledTimes(2) }) @@ -310,7 +287,7 @@ describe('Router', () => { const escape = (err) => err - await router.handle(buildRequest({ path: '/foo' })).catch(escape) + await router.handle(toReq('/foo')).catch(escape) expect(handler1).toHaveBeenCalled() expect(handler2).toHaveBeenCalled() @@ -326,7 +303,7 @@ describe('Router', () => { router.get('/foo', handlerWithError) - await router.handle(buildRequest({ path: '/foo' })).catch(errorHandler) + await router.handle(toReq('/foo')).catch(errorHandler) expect(handlerWithError).toHaveBeenCalled() expect(errorHandler).toHaveBeenCalled() @@ -376,7 +353,7 @@ describe('Router', () => { it('can easily create a ThrowableRouter', async () => { const error = (status, message) => new Response(message, { status }) - const ThrowableRouter = (options) => + const ThrowableRouter = (options = {}) => new Proxy(Router(options), { get: (obj, prop) => @@ -395,7 +372,7 @@ describe('Router', () => { router.get('/foo', handlerWithError) - const response = await router.handle(buildRequest({ path: '/foo' })) + const response = await router.handle(toReq('/foo')) expect(response instanceof Response).toBe(true) expect(response.status).toBe(500) @@ -421,7 +398,7 @@ describe('Router', () => { const originalA = 'A' const originalB = {} r.get('*', h) - const req = buildRequest({ path: '/foo' }) + const req: any = toReq('/foo') await r.handle(req, originalA, originalB) @@ -440,7 +417,7 @@ describe('Router', () => { router.get('/foo', withProxy, handler) - await router.handle(buildRequest({ path: '/foo' })) + await router.handle(toReq('/foo')) expect(handler).toHaveReturnedWith(proxy) }) @@ -507,6 +484,41 @@ describe('Router', () => { }) }) +describe('NESTING', () => { + it('can handle legacy nested routers (with explicit base path)', async () => { + const router1 = Router() + const router2 = Router({ base: '/nested' }) + const handler1 = vi.fn() + const handler2 = vi.fn() + const handler3 = vi.fn() + router1.get('/pet', handler1) + router1.get('/nested/*', router2.handle) + router2.get('/', handler3) + router2.get('/bar/:id?', handler2) + + await router1.handle(toReq('/pet')) + expect(handler1).toHaveBeenCalled() + + await router1.handle(toReq('/nested/bar')) + expect(handler2).toHaveBeenCalled() + + await router1.handle(toReq('/nested')) + expect(handler3).toHaveBeenCalled() + }) + + it('can nest with route params on the nested route if given router.handle and base path', async () => { + const child = Router({ base: '/child/:bar' }).get('/', () => 'child') + const parent = Router() + .get('/', () => 'parent') + .all('/child/:bar/*', child.handle) + + console.log({ child: child.routes, parent: parent.routes }) + + expect(await parent.handle(toReq('/'))).toBe('parent') + expect(await parent.handle(toReq('/child/kitten'))).toBe('child') + }) +}) + describe('MIDDLEWARE', () => { it('calls any handler until a return', async () => { const router = Router() @@ -516,7 +528,7 @@ describe('MIDDLEWARE', () => { router.get('*', h1, h2, h3) - const results = await router.handle(buildRequest({ path: '/' })) + const results = await router.handle(toReq('/')) expect(h1).toHaveBeenCalled() expect(h2).toHaveBeenCalled() expect(h3).toHaveBeenCalled() diff --git a/test/index.ts b/test/index.ts index c1dc3eeb..d378aa86 100644 --- a/test/index.ts +++ b/test/index.ts @@ -1,12 +1,21 @@ /* istanbul ignore file */ import { expect, it, vi } from 'vitest' -export const buildRequest = ({ - method = 'GET', - path, - url = `https://example.com${path}`, - ...other -}) => ({ method, path, url, ...other }) +// generates a request from a string like: +// GET /whatever +// /foo +export const toReq = (methodAndPath: string) => { + let [method, path] = methodAndPath.split(' ') + if (!path) { + path = method + method = 'GET' + } + + return { + method, + url: `https://example.com${path}` + } +} export const extract = ({ params, query }) => ({ params, query }) @@ -27,7 +36,7 @@ const testRoute = async ( path, }) - await router.handle(buildRequest({ method: method.toUpperCase(), path })) + await router.handle(toReq(`${method.toUpperCase()} ${path}`)) if (!returns) { expect(handler).not.toHaveBeenCalled() From f01628c0ec1e919acd4f3c1520510f1c147722b3 Mon Sep 17 00:00:00 2001 From: Chris Lalos Date: Sun, 7 Jan 2024 18:17:17 -0500 Subject: [PATCH 12/12] Slight changes (#211) In Section #2 and elsewhere, 'we' refers to developers who are using itty, or the application code written by said developers. In Sections #3 and #4, 'we' switches to refer to itty itself. This might not be noticed by anyone but me ... but I did notice it so here's a PR :) My suggested changes might not be the best, so modification and improvement is welcome! --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7530cfd8..5fb4079d 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ router ``` ### 3. It's all Promises. -We `await` every handler, looking for a return value. If we get one, we break the flow and return your value. If we don't, we continue processing handlers/routes until we do. This means that every handler can either be synchronous or async - it's all the same. +itty `await`s every handler, looking for a return value. If it gets one, it breaks the flow and returns the value. If it doesn't, it continues processing handlers/routes until it does. This means that every handler can either be synchronous or async - it's all the same. When paired with the fact that we can simply return raw data and transform it later, this is AWESOME for working with async APIs, database layers, etc. We don't need to transform anything at the route, we can simply return the Promise (to data) itself! @@ -186,7 +186,7 @@ router ``` ### 4. Only one required argument. The rest is up to you. -We only require one argument in itty - a Request-like object with the following shape: `{ url, method }` (usually a native [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request)). Because itty is not opinionated about [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) creation, there is not "response" argument built in. Every other argument you pass to `route.handle` is given to each handler, in the same order. +itty only requires one argument - a Request-like object with the following shape: `{ url, method }` (usually a native [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request)). Because itty is not opinionated about [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) creation, there is not "response" argument built in. Every other argument you pass to `route.handle` is given to each handler, in the same order. > ### This makes itty one of the most platform-agnostic routers, *period*, as it's able to match up to any platform's signature.