{"_id":"0http-bun","_rev":"17-1981323257fff68ac047b25152e06481","name":"0http-bun","dist-tags":{"latest":"1.3.1"},"versions":{"0.0.1":{"name":"0http-bun","version":"0.0.1","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@0.0.1","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"f13f724984519585c144a5f4c1bf5bb19ac82e40","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-0.0.1.tgz","fileCount":7,"integrity":"sha512-bQsqnRQsag67c1DBAwUrpiXRH4vpn6sgxefQiZmAWJcYdbUgxo1I76Attb9keCL8a7QKvU5Kh8FG3+aXAF4s5Q==","signatures":[{"sig":"MEUCIQDQM8r9VV8Iq6gBALmPK0KCE6zf17r7rE60pWAMm65E6QIgF/2ePb5ZUOXAdjSe2pA2/p/hNLBiVr0JEdGCAxx4kDA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":6582,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjeOXqACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo7sg//a7SA/XI3bit5KyrR7t/ikshZU8xgRmcEWhxkKFc3AO67koas\r\nJnRRASkkMsZBIPQuv1tz+InVIE6s6x+xxMeHz1LWD1VJ2a0Qom6F61zCH6ws\r\nNsKXbX8EP7DkYonxMJ3i8KEFWmZ3ZgASfEjLcBzVvc4m//uFkGGRKiJtDAtl\r\n07AV3Z/c6qh0bfZsMLaIsYjSBl5RvrHpb/wB6GAR2xgdIWToI+IQGuv+ZBSb\r\nGuL3e6qvLZquDFIiXNFa+KYfS70xQl06ZoZtFAqelSwei19aIVDYVxhkQwIW\r\n9Dnh3iMrUxegJ+j2UyCgnt5iFtOZX2jMbES2+MOshaPmDw6vE10Y4vnKP15u\r\nPdxj+n5LfRkV32tuCHfMSy69sr15e/30WXajH4ZLG9zyMl8CgoD++BnBAePW\r\no+Opfk++bm9pcpI/fk/fPKYMc6W90aStiDAnl+MOtAYBdIdFWUDJg2a3URTx\r\nBHFUBc4WwCm2vb83HlWZafps1QA8J/NtaY91iVFkfrvuc5pY+h2Li1gMXlaS\r\nzHX2ix5unuPvzOUsMPhMuIECP8T3DMXQ0cYF+tMdqElUra0jData1eveDRXm\r\nSQCBQl/mDbxWlGMgFYBlkBwll2q8bbr7ufihQGIR9g4hPA6s+ycYVFuNOetJ\r\nijJi9dHbCee7MQh7tclsAQlWcOVZsvLhC9g=\r\n=reyk\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"e8179dff84b3afcaef25b4817d3d1e6f3a065c88","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"8.9.0","description":"0http alternative for Bun","directories":{},"_nodeVersion":"18.2.0","dependencies":{"trouter":"^3.2.0","lru-cache":"^7.10.1","regexparam":"^2.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/0http-bun_0.0.1_1668867561883_0.7571760485375774","host":"s3://npm-registry-packages"}},"0.0.2":{"name":"0http-bun","version":"0.0.2","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@0.0.2","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"3dfeebd7045802b322195e01a76d54748b7c6b04","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-0.0.2.tgz","fileCount":9,"integrity":"sha512-K7cCEYfGiy8H+uCZekteLQbd9yDUYDWi4GMWMgIqJhNMApr4veEGm9LyT6a8M3uQNUqkO1GBPfE9ol+v6Y5Ipw==","signatures":[{"sig":"MEUCIFJane+f5EV4gwbILs6ITwrL/QVG6fmvl0y/KIjS1LsEAiEAuVnI49BN773vb7kkTZi6OJ9IjMUhRUTiJGVW5u92Ghc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":75401,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjePhVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrhWg/8CdUorQEpssmzcRdIzjsp+wb2TyI9Sm4lzGZnafrWq0rzM0e8\r\nMPZDty2gPgvrYQxLvOX+f2iACWs/V0OBBm/qbuUp9VQwN9l1238a9H+pRuRc\r\nBntnpFwfPgjtZpBsGbl5s0/58cPmxh5gVAxNU0bGGb1mH6LhZnjrzPYiZ7H4\r\nGve/jFrn+CPkXSx4cR2VVHWrTv8lDhbbtdICujWjVQYdi9nkgXNMjQzGTgkH\r\nogRD6+rGQFdK3Ty8ZeppicUu4MZJBqGXP7VZdcf2Dko5a8tNcV8oEoYZvx/v\r\nq8BYkYqYs2wjG+g2yxLYp7Y19hOktPW7LQQYGiCFuLh4jKFOD4MIvkQ/FkEq\r\ncJQH3HQj0UtfP5pC8eJq3q3RESP/y5Zb04xXIZ644l373L5XNpno3Zg8nsvV\r\nU/WMNp36Sos5AteuF8uiNgCr5r7fDNJW13caVZ89r4slOXleBzF9/TQOELWd\r\nWSQnFlUZ96PYYeny603pu2yefbSnfNHoQPxqzQROq3L9KfDDYaYsB3ecp9YI\r\nt+rZJluXALSfsD8IOrt6e0VsWK5xnZLfYzG2z7GjenM1Kz8ooRoUoVZeR2QU\r\nMHscF3UTNITbo+IXUQ6N2HwjsClmz/XCwUDSBcs2RJoOO2KvSX62CNzsqBrG\r\niJ7N4O/Z8tLEHAEBoOaQ29SQ5uE65+U1/Yo=\r\n=gwdq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"3795243a32517350ac766da630cfbc14c3cc9f01","scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"8.9.0","description":"0http alternative for Bun","directories":{},"_nodeVersion":"18.2.0","dependencies":{"trouter":"^3.2.0","lru-cache":"^7.10.1","regexparam":"^2.0.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/0http-bun_0.0.2_1668872276788_0.042928092097391346","host":"s3://npm-registry-packages"}},"0.0.3":{"name":"0http-bun","version":"0.0.3","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@0.0.3","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"b9b96f6bc74a1ed5d23abd41f30679e2188d1312","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-0.0.3.tgz","fileCount":9,"integrity":"sha512-vdSI70XTWI9J1vUyTARy/hlYAjmOAu5AKFDE+5pB7BfgLs2hzJwRIIKNDEC7AB8bSKWo8rBe8GT12FjwqDIlOQ==","signatures":[{"sig":"MEUCIF9KyeKRkEakrDjDlDwBn0uEZCRRqwYMRyfT5lkl5VqOAiEAwuoZHcXIVUpDks1ck7ZpvXirmSJALR+MNQGojcdjGpg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":73610},"main":"index.js","gitHead":"06202ab599f1bc34623e9b6bfd8031eb4861acfe","scripts":{"lint":"bun x standard","format":"bun x standard --fix"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"9.5.1","description":"0http alternative for Bun","directories":{},"_nodeVersion":"18.16.0","dependencies":{"trouter":"^3.2.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/0http-bun_0.0.3_1684942609699_0.46911630057950116","host":"s3://npm-registry-packages"}},"1.0.0":{"name":"0http-bun","version":"1.0.0","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@1.0.0","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"776f3b399bb67dc7946c1cd708edae6159cb6621","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.0.0.tgz","fileCount":11,"integrity":"sha512-Bs0ujpLAj6QXj8oLcObvlRnd8TYEjkb8KqG/uCeG7V2caimE+moJJtBGXNxk7qFVGSBY6o/LB7En85XSIXOXog==","signatures":[{"sig":"MEQCIHYI45nJiUTNVRftmzH0Y/SKbavPwK57nmsvuNcqd2o/AiAFS4tOPV0CJekxt/gRR72riQOu9YG6BdrYXshMj3AAjQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":77373},"main":"index.js","gitHead":"594065df72b0ff36c9ab982826467c744d0a460d","scripts":{"lint":"bun x standard","format":"bun x standard --fix"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"9.5.1","description":"0http for Bun","directories":{},"_nodeVersion":"18.16.0","dependencies":{"trouter":"^3.2.1"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.0.0_1685309133976_0.9618675947661766","host":"s3://npm-registry-packages"}},"1.0.1":{"name":"0http-bun","version":"1.0.1","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@1.0.1","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"a0b3fa58dc0d29dbd2398d230239f3646881211f","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.0.1.tgz","fileCount":14,"integrity":"sha512-Yi+DzMhtfWQixkKsT+M57WLG39MES382RLH08swM+a4ZZRh8w2MwAoUemaBaCd5fTsApr6OuQZprR3T4NjuJOw==","signatures":[{"sig":"MEUCIQDw0HWnYJORdP2qK7936vcBdSbIzEWkYEDsQoM+sniDsAIgd8UZ9N3vCkZzjk0DmjvXqSiE+7jFI6VK08aqAIIdTo8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":79423},"main":"index.js","gitHead":"cca0b30f06fc39e2260b0f5b232b14e5075b85bb","scripts":{"lint":"bun x standard","format":"bun x standard --fix"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.2.4","description":"0http for Bun","directories":{},"_nodeVersion":"20.11.1","dependencies":{"trouter":"^3.2.1"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^0.1.11","0http-bun":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.0.1_1712386289664_0.30227989963848434","host":"s3://npm-registry-packages"}},"1.0.2":{"name":"0http-bun","version":"1.0.2","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@1.0.2","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"7c1f1a17198a3367f3d5725065cc526061bda56c","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.0.2.tgz","fileCount":6,"integrity":"sha512-dPg2EfAQJ/Cq8CfzGlYb8ML6dXZ5xo7SO4O18mkGWE7Pwlg18NYMgHiGelyQRov00Jy1O6DmejsgQ7/yERlaKA==","signatures":[{"sig":"MEYCIQCuUxeoRXqcv8cYPDmlAli7M074wtlVM+wmnYgCoBuacgIhAImeC4c9x6PrMcg7aly0ptQ9Bed9Tpzvn51SK8unU8fg","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":6133},"main":"index.js","gitHead":"4b14de60890ca78bdac77847d7f8ea83ce994d76","scripts":{"lint":"bun x standard","format":"bun x standard --fix"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.2.4","description":"0http for Bun","directories":{},"_nodeVersion":"20.11.1","dependencies":{"trouter":"^3.2.1"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^0.1.11","0http-bun":"^1.0.0"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.0.2_1712387079675_0.5654529231338996","host":"s3://npm-registry-packages"}},"1.0.3":{"name":"0http-bun","version":"1.0.3","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@1.0.3","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"6f6b400da07528f5a8f5f7209f6c99cd259c7ee3","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.0.3.tgz","fileCount":6,"integrity":"sha512-LrdT8iRo0VfelD1b6rs1d/G6TEo0XRdCR8usaglh46GcusxbkveZy7SlUHwhtAN6VvQ6Ht3eUrmO/Dea7/ub9Q==","signatures":[{"sig":"MEUCIQCkC6eSL73WYOcFwuADDB3UxWJ9fFwbCQbQKyEArBn59AIgDzDOE92G8xU0FOEWRLLW8IPjUAsFdzkqUPkvQWcXFms=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":6438},"main":"index.js","gitHead":"dac7a88e7a379df97a1a972bd9bee41606b19d5a","scripts":{"lint":"bun x standard","format":"bun x standard --fix"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.2.4","description":"0http for Bun","directories":{},"_nodeVersion":"20.11.1","dependencies":{"trouter":"^3.2.1","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^0.1.11","0http-bun":"^1.0.2"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.0.3_1713543851549_0.7970106968504238","host":"s3://npm-registry-packages"}},"1.0.4":{"name":"0http-bun","version":"1.0.4","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@1.0.4","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"0fd243a56d7853302bcc1db4c26502212b65affe","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.0.4.tgz","fileCount":9,"integrity":"sha512-Z12no7VFwzyK7hxKxHnFgfZPttdv5kELfY1HRJmq9DE4sTLE2gb+GerDYSdx1sDPt9VTjAK4q4b7BS6f1Kdu9A==","signatures":[{"sig":"MEUCIQDycfiOwgzrtL9FuN5/oSaVP2uGX3NmJFuXfHntxh60ZAIgCcHI789QdHhVDs0GB0R54ta2lW/pcA1Le+oO6K197sA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":8270},"main":"index.js","types":"./index.d.ts","gitHead":"8c0d5243fe584b4938785c69b32264a0857846d9","scripts":{"lint":"bun x standard","format":"bun x standard --fix"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.7.0","description":"0http for Bun","directories":{},"_nodeVersion":"22.2.0","dependencies":{"trouter":"^3.2.1","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^0.1.11","0http-bun":"^1.0.3","bun-types":"^1.1.8"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.0.4_1716210490494_0.8266437620761142","host":"s3://npm-registry-packages"}},"1.1.0":{"name":"0http-bun","version":"1.1.0","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@1.1.0","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"79f85a664786bf8d84919e4e97fb558bb6b3e892","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.1.0.tgz","fileCount":9,"integrity":"sha512-Y1OUg2EdlG3LvgsLASkvnMNLkzIMzs8CceNk7RPQqWsrcQGb68mkFkw+uVXy4gbxg+RA6sEjht8rx+uNuppUBw==","signatures":[{"sig":"MEUCIAfGRyOu2c5hYoB0BpUo9JyXAJvxwfU6j95tAaf37Ds8AiEArJeEFSNsQIYFYSUYPAdxlR8Wm8Ug997yLD+Cgpk+kjw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":8507},"main":"index.js","types":"./index.d.ts","gitHead":"e0d307bd9bbc40670a769dd6cdb606560b1ff6a2","scripts":{"lint":"bun x standard","test":"bun test","format":"bun x standard --fix"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.9.0","description":"0http for Bun","directories":{},"_nodeVersion":"22.11.0","dependencies":{"trouter":"^3.2.1","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^1.0.32","0http-bun":"^1.0.3","bun-types":"^1.1.8"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.1.0_1737886690406_0.7758557915422128","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"0http-bun","version":"1.1.1","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@1.1.1","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"58ec1b5fb797114b10af15d2b6f460c58bc3ee3e","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.1.1.tgz","fileCount":9,"integrity":"sha512-YxRftXX11ACEzfLYN1wgfEaI0ZDbsHiYwFreUDjnM9+qN0eVEKyrDrtjyYl0swoZNUYXkf44witBgbS97BCjoQ==","signatures":[{"sig":"MEQCIAC4W9w42p64nbQPKa9iJTWqjAnnSgqrik8zm5UVedKrAiByivcVGRiD1YtgG00ZznOVFnr/d7J1YPNsfwy037MKvg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":8648},"main":"index.js","types":"./index.d.ts","gitHead":"c70831af850ad8a490b4b5289e0cdb8abf27b21a","scripts":{"lint":"bun x standard","test":"bun test","bench":"bun run bench.js","format":"prettier --write *.js"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"11.2.0","description":"0http for Bun","directories":{},"_nodeVersion":"22.12.0","dependencies":{"trouter":"^4.0.0","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^1.0.34","prettier":"^3.5.3","0http-bun":"^1.1.0","bun-types":"^1.2.5"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.1.1_1742636397813_0.8334670266469721","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"0http-bun","version":"1.1.2","keywords":["http","server","rest","api","web","bun"],"author":"Rolando Santamaria Maso <kyberneees@gmail.com>","license":"MIT","_id":"0http-bun@1.1.2","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"6c1aae2bb4feaeb67a797344f515dc642fb07309","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.1.2.tgz","fileCount":9,"integrity":"sha512-nE1U+rpfxSTYC3nLxL/rmhsE9AFN9He3qKOXzFjO7tpzr1fhW0NyITgR7j64wL08bH4zvxtBaY0pVgiEKzpp2g==","signatures":[{"sig":"MEQCIH75OPSmj0QlFfgk5Id0rO0LaQh2CCvBUs+73OrbiPuMAiAwwI2yP0TLQ/7rB5CAfRX9NY7Jqy5F44yBNJGMpjAcbQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":10253},"main":"index.js","shasum":"6c1aae2bb4feaeb67a797344f515dc642fb07309","scripts":{"lint":"prettier --check **/*.js","test":"bun --coverage test","bench":"bun run bench.js","format":"prettier --write **/*.js"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"_integrity":"sha512-nE1U+rpfxSTYC3nLxL/rmhsE9AFN9He3qKOXzFjO7tpzr1fhW0NyITgR7j64wL08bH4zvxtBaY0pVgiEKzpp2g==","repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.8.3","description":"0http for Bun","directories":{},"_nodeVersion":"22.6.0","dependencies":{"trouter":"^4.0.0","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^1.0.34","prettier":"^3.5.3","0http-bun":"^1.1.0","bun-types":"^1.2.5"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.1.2_1749390916519_0.6094025188435421","host":"s3://npm-registry-packages-npm-production"}},"1.1.3":{"name":"0http-bun","version":"1.1.3","keywords":["http","server","rest","api","web","bun"],"author":"Rolando Santamaria Maso <kyberneees@gmail.com>","license":"MIT","_id":"0http-bun@1.1.3","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"8f9c6d1c37b22f028ea8425d1fec9d9dc6ee6984","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.1.3.tgz","fileCount":9,"integrity":"sha512-YvJCp5VjeUmYUH7SQr1cRCCNqcXeu6UrEZeU1I6TJQoxLzbXSkng3pHA6DpGDnt/+LCKu/247DZGtm5ELliuyQ==","signatures":[{"sig":"MEUCIQCp1Ib/o8Vo1ruDaXDKjfaoBY7Z25OGQrVH/VfyigwzogIgXj0Bc2kVtgMK9jye44KWk4aNgZmDdhKPq124eT+S4UA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14417},"main":"index.js","shasum":"8f9c6d1c37b22f028ea8425d1fec9d9dc6ee6984","scripts":{"lint":"prettier --check **/*.js","test":"bun --coverage test","bench":"bun run bench.js","format":"prettier --write **/*.js"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"_integrity":"sha512-YvJCp5VjeUmYUH7SQr1cRCCNqcXeu6UrEZeU1I6TJQoxLzbXSkng3pHA6DpGDnt/+LCKu/247DZGtm5ELliuyQ==","repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.8.3","description":"0http for Bun","directories":{},"_nodeVersion":"22.6.0","dependencies":{"trouter":"^4.0.0","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^1.0.34","prettier":"^3.5.3","0http-bun":"^1.1.2","bun-types":"^1.2.15"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.1.3_1749472991327_0.6997528680504681","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"0http-bun","version":"1.2.0","keywords":["http","server","rest","api","web","bun"],"author":"Rolando Santamaria Maso <kyberneees@gmail.com>","license":"MIT","_id":"0http-bun@1.2.0","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"30e97d6d1aec3ba120cd5c648e0daa520a4d4c6b","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.2.0.tgz","fileCount":17,"integrity":"sha512-j+9XgcZ2WsdMMstGdDi/6ipVOmeifGrFMHtbkV/5L7wVU3mUSovMPND8FmJlQ90++6LzNZByUS/hGYX/5KFtJw==","signatures":[{"sig":"MEYCIQCs+ZEifaP6rH/cjt2OT70UO7TOEm32GlIfGhmNzGalKwIhALvmuzdRbiT2p+9429ETkYI9HxIHDDBz47J4PImVEIsH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":104522},"main":"index.js","shasum":"30e97d6d1aec3ba120cd5c648e0daa520a4d4c6b","scripts":{"lint":"prettier --check **/*.js","test":"bun --coverage test","bench":"bun run bench.js","format":"prettier --write **/*.js"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"_integrity":"sha512-j+9XgcZ2WsdMMstGdDi/6ipVOmeifGrFMHtbkV/5L7wVU3mUSovMPND8FmJlQ90++6LzNZByUS/hGYX/5KFtJw==","repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.8.3","description":"0http for Bun","directories":{},"_nodeVersion":"22.6.0","dependencies":{"jose":"^6.0.11","pino":"^9.7.0","trouter":"^4.0.0","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^1.0.34","prettier":"^3.5.3","0http-bun":"^1.1.2","bun-types":"^1.2.15","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.2.0_1749662982920_0.8152718162852901","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"0http-bun","version":"1.2.1","keywords":["http","server","rest","api","web","bun"],"author":"Rolando Santamaria Maso <kyberneees@gmail.com>","license":"MIT","_id":"0http-bun@1.2.1","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"52b23f60086d4e565af2f9fece11b5ad67c3a058","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.2.1.tgz","fileCount":17,"integrity":"sha512-QXhW4RFReF+bMoETyAnovJ4oSIrsaIHuB/07zslpzcVeEJkXSlqnbDwudGAxLwStky5sgAU84ElkGOX5xiUdig==","signatures":[{"sig":"MEYCIQCZw5UOo2+hq/9j7IrYg1kIQsFtQCsjyWVpvwjXM9fNAQIhAIfJWF1mUgvextOmYTqGVkuAHyvyrmfvHAq2nnv1mS81","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":107256},"main":"index.js","shasum":"52b23f60086d4e565af2f9fece11b5ad67c3a058","scripts":{"lint":"prettier --check **/*.js","test":"bun --coverage test","bench":"bun run bench.js","format":"prettier --write **/*.js"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"_integrity":"sha512-QXhW4RFReF+bMoETyAnovJ4oSIrsaIHuB/07zslpzcVeEJkXSlqnbDwudGAxLwStky5sgAU84ElkGOX5xiUdig==","repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.8.3","description":"0http for Bun","directories":{},"_nodeVersion":"22.6.0","dependencies":{"jose":"^6.0.11","pino":"^9.7.0","trouter":"^4.0.0","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"mitata":"^1.0.34","prettier":"^3.5.3","0http-bun":"^1.1.2","bun-types":"^1.2.15","typescript":"^5.8.3"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.2.1_1749840947856_0.8508521369022777","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"0http-bun","version":"1.2.2","keywords":["http","server","rest","api","web","bun"],"author":"Rolando Santamaria Maso <kyberneees@gmail.com>","license":"MIT","_id":"0http-bun@1.2.2","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"94679ba7aabd48758d0b9610233be43fec8010fd","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.2.2.tgz","fileCount":18,"integrity":"sha512-wpc2Dw8xdnlziEkq0G2ue/X2ebK29l3YLbuBtj0Pwjivfa6hYohFXw5vbNH1BxsNZCs43cfkU/kxcD+Dhofuyg==","signatures":[{"sig":"MEYCIQDLe1kpLtGyDvFHYtca6gJBIYbvVPwPerUS3A6QlHTiqQIhANpZXaPD2PPbwiycbWgnt6wqL7SgJoSnGDSgh6/wXdRa","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":135193},"main":"index.js","shasum":"94679ba7aabd48758d0b9610233be43fec8010fd","scripts":{"lint":"prettier --check **/*.js","test":"bun --coverage test","bench":"bun run bench.js","format":"prettier --write **/*.js"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"_integrity":"sha512-wpc2Dw8xdnlziEkq0G2ue/X2ebK29l3YLbuBtj0Pwjivfa6hYohFXw5vbNH1BxsNZCs43cfkU/kxcD+Dhofuyg==","repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"10.8.3","description":"0http for Bun","directories":{},"_nodeVersion":"22.6.0","dependencies":{"trouter":"^4.0.0","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"jose":"^6.0.11","pino":"^9.7.0","mitata":"^1.0.34","prettier":"^3.5.3","0http-bun":"^1.2.1","bun-types":"^1.2.16","typescript":"^5.8.3","prom-client":"^15.1.3"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.2.2_1749992751582_0.4597906111567951","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"0http-bun","version":"1.3.0","keywords":["http","server","rest","api","web","bun"],"author":{"name":"Rolando Santamaria Maso","email":"kyberneees@gmail.com"},"license":"MIT","_id":"0http-bun@1.3.0","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"homepage":"https://github.com/BackendStack21/0http-bun#readme","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"dist":{"shasum":"7472e98477fd756bf8f5edd29c4c968cf103698d","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.3.0.tgz","fileCount":18,"integrity":"sha512-rbEZpYwp39/syOVmNsh8ie/ab1DOOiDQcmws0mdbRstXuEzi4wU5sgPE6gnHiIxu3GKC09lCTNz3S9SzIyEeOg==","signatures":[{"sig":"MEUCIExVWOWeT5onTcqyj49jycBNDp6H7gkzh4CVPS22M7VpAiEArzC8jjrZlyDBVRs9Z3gpEYP1YNx3xJRUo3sDn70m8wI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":180186},"main":"index.js","types":"./index.d.ts","gitHead":"f9255e9fba11efef763a12c1da25b0c18dbe4821","scripts":{"lint":"prettier --check **/*.js","test":"bun --coverage test","bench":"bun run bench.js","format":"prettier --write **/*.js"},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"repository":{"url":"git+https://github.com/BackendStack21/0http-bun.git","type":"git"},"_npmVersion":"11.2.0","description":"0http for Bun","directories":{},"_nodeVersion":"22.22.0","dependencies":{"trouter":"^4.0.0","fast-querystring":"^1.1.2"},"_hasShrinkwrap":false,"devDependencies":{"jose":"^6.1.3","pino":"^9.14.0","mitata":"^1.0.34","prettier":"^3.8.1","0http-bun":"^1.2.2","bun-types":"^1.3.8","typescript":"^5.9.3","prom-client":"^15.1.3"},"_npmOperationalInternal":{"tmp":"tmp/0http-bun_1.3.0_1770494590001_0.8433776430346076","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"0http-bun","version":"1.3.1","description":"0http for Bun","main":"index.js","scripts":{"lint":"prettier --check **/*.js","test":"bun --coverage test","bench":"bun run bench.ts","format":"prettier --write **/*.js"},"dependencies":{"fast-querystring":"^1.1.2","trouter":"^4.0.0"},"repository":{"type":"git","url":"git+https://github.com/BackendStack21/0http-bun.git"},"devDependencies":{"0http-bun":"^1.2.2","bun-types":"^1.3.8","mitata":"^1.0.34","prettier":"^3.8.1","typescript":"^5.9.3","jose":"^6.1.3","pino":"^9.14.0","prom-client":"^15.1.3"},"keywords":["http","server","rest","api","web","bun"],"author":"Rolando Santamaria Maso <kyberneees@gmail.com>","license":"MIT","bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"homepage":"https://github.com/BackendStack21/0http-bun#readme","_id":"0http-bun@1.3.1","_integrity":"sha512-y95t0d7Ywh823I8ALERJbycLx7jP55mmCyXKWHAbMrilbVAoG2uS2dUiyHVxSsHHswFyZQ8X0b6lx9NK3YwhDg==","_nodeVersion":"26.3.0","_npmVersion":"10.8.3","shasum":"c6d5f76812abc440ee7bfb0a5b469467e2f3aa82","dist":{"integrity":"sha512-y95t0d7Ywh823I8ALERJbycLx7jP55mmCyXKWHAbMrilbVAoG2uS2dUiyHVxSsHHswFyZQ8X0b6lx9NK3YwhDg==","shasum":"c6d5f76812abc440ee7bfb0a5b469467e2f3aa82","tarball":"https://registry.npmjs.org/0http-bun/-/0http-bun-1.3.1.tgz","fileCount":19,"unpackedSize":189477,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIHtTkAacGm0qQM1GgXvnp1sJnmM/QLNbp6qgB9z4S9zJAiAjgemFhq6nfE83CBhK5UFiCeNBEwZRhJaGYwhj8uA2og=="}]},"_npmUser":{"name":"jkyberneees","email":"kyberneees@gmail.com"},"directories":{},"maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/0http-bun_1.3.1_1788628350969_0.6010685359095711"},"_hasShrinkwrap":false}},"time":{"created":"2022-11-19T14:19:21.882Z","modified":"2026-09-05T17:12:31.298Z","0.0.1":"2022-11-19T14:19:22.040Z","0.0.2":"2022-11-19T15:37:57.005Z","0.0.3":"2023-05-24T15:36:49.923Z","1.0.0":"2023-05-28T21:25:34.191Z","1.0.1":"2024-04-06T06:51:29.890Z","1.0.2":"2024-04-06T07:04:39.878Z","1.0.3":"2024-04-19T16:24:11.739Z","1.0.4":"2024-05-20T13:08:10.796Z","1.1.0":"2025-01-26T10:18:10.585Z","1.1.1":"2025-03-22T09:39:58.013Z","1.1.2":"2025-06-08T13:55:16.722Z","1.1.3":"2025-06-09T12:43:11.531Z","1.2.0":"2025-06-11T17:29:43.121Z","1.2.1":"2025-06-13T18:55:48.105Z","1.2.2":"2025-06-15T13:05:51.814Z","1.3.0":"2026-02-07T20:03:10.174Z","1.3.1":"2026-09-05T17:12:31.119Z"},"bugs":{"url":"https://github.com/BackendStack21/0http-bun/issues"},"author":"Rolando Santamaria Maso <kyberneees@gmail.com>","license":"MIT","homepage":"https://github.com/BackendStack21/0http-bun#readme","keywords":["http","server","rest","api","web","bun"],"repository":{"type":"git","url":"git+https://github.com/BackendStack21/0http-bun.git"},"description":"0http for Bun","maintainers":[{"name":"jkyberneees","email":"kyberneees@gmail.com"}],"readme":"# 0http-bun\n\n[![npm version](https://img.shields.io/npm/v/0http-bun?style=flat-square)](https://www.npmjs.com/package/0http-bun)\n[![license](https://img.shields.io/npm/l/0http-bun?style=flat-square)](https://github.com/BackendStack21/0http-bun/blob/main/LICENSE)\n\nA high-performance, minimalist HTTP framework for [Bun](https://bun.sh/), inspired by [0http](https://0http.21no.de/#/). Built specifically to leverage Bun's native performance capabilities with a developer-friendly API.\n\n> Landing page: [0http-bun.21no.de](https://0http-bun.21no.de)\n\n> **v1.3.0** includes a comprehensive security hardening release. See the [Changelog](#changelog) and [Migration Guide](#migrating-to-v130) sections below.\n\n## ✨ Why Choose 0http-bun?\n\n0http-bun combines the simplicity of Express with the raw performance of Bun's runtime, delivering a framework that's both **blazingly fast** and **secure by design**. Perfect for everything from quick prototypes to production-grade APIs.\n\n### 🚀 Unmatched Performance\n\n- **Bun-Native Optimization**: Built specifically for Bun's runtime with zero overhead\n- **Lightning-Fast Routing**: Based on the proven `trouter` library with intelligent caching\n- **Memory Efficient**: Smart object reuse and minimal allocations\n- **Optimized Parsing**: Uses `fast-querystring` for lightning-quick query string handling\n\n### 🎯 Developer Experience\n\n- **TypeScript First**: Full type safety with comprehensive definitions\n- **Intuitive API**: Clean, expressive syntax that's easy to learn\n- **Flexible Middleware**: Powerful async/await middleware system\n- **Web Standards**: Built on standard Request/Response APIs\n\n### 🛡️ Security by Default\n\n- **Production-Ready Security**: Built-in protection against common vulnerabilities\n- **Input Validation**: Comprehensive sanitization and size limits\n- **Attack Prevention**: Prototype pollution, ReDoS, and DoS protection\n- **Secure Defaults**: Safe error handling and CORS configuration\n\n## Key Benefits\n\n- **🚀 Bun-Native Performance**: Optimized for Bun's runtime with minimal overhead\n- **🔧 TypeScript First**: Full TypeScript support with comprehensive type definitions\n- **🎯 Minimalist API**: Clean, intuitive API that's easy to learn and use\n- **🔄 Middleware Support**: Flexible middleware system with async/await support\n- **📦 Tiny Footprint**: Lightweight framework focused on performance\n- **🛡️ Web Standards**: Built on standard Web APIs (Request/Response)\n\n## Installation\n\n```bash\nbun add 0http-bun\n```\n\n## Quick Start\n\n### Basic Server\n\n```typescript\nimport http from '0http-bun'\n\nconst {router} = http()\n\nrouter.get('/', () => {\n  return new Response('Hello World!')\n})\n\nrouter.get('/:id', (req) => {\n  return Response.json({id: req.params.id})\n})\n\n// Start the server\nBun.serve({\n  port: 3000,\n  fetch: router.fetch,\n})\n```\n\n### Enabling Client IP for Rate Limiting\n\nBun's standard `Request` object does not expose the client IP address. To enable the default rate limiter key generator (and any middleware that reads `req.ip`), use `server.requestIP()` in the `Bun.serve` fetch handler:\n\n```typescript\nimport http from '0http-bun'\nimport {createRateLimit} from '0http-bun/lib/middleware'\n\nconst {router} = http()\n\nrouter.use(createRateLimit({windowMs: 15 * 60 * 1000, max: 100}))\n\nrouter.get('/', () => new Response('Hello World!'))\n\n// Populate req.ip from Bun's server.requestIP before passing to the router\nBun.serve({\n  port: 3000,\n  fetch(req, server) {\n    req.ip = server.requestIP(req)?.address\n    return router.fetch(req)\n  },\n})\n```\n\n> **Why is this needed?** The Fetch API `Request` type does not include connection-level properties like `ip`. Bun provides client IP via `server.requestIP(req)` in the fetch handler's second argument. Setting `req.ip` before calling `router.fetch` ensures the rate limiter (and other middleware) can identify clients correctly. Without this, the default key generator falls back to unique per-request keys, which effectively disables rate limiting.\n\n### With TypeScript Types\n\n```typescript\nimport http, {ZeroRequest, StepFunction} from '0http-bun'\n\nconst {router} = http({\n  port: 3000,\n  errorHandler: (err: Error) => {\n    console.error('Server error:', err)\n    return new Response('Internal Server Error', {status: 500})\n  },\n})\n\n// Typed middleware\nrouter.use((req: ZeroRequest, next: StepFunction) => {\n  req.ctx = {\n    startTime: Date.now(),\n    engine: 'bun',\n  }\n  return next()\n})\n\n// Typed route handlers\nrouter.get('/:id', async (req: ZeroRequest) => {\n  return Response.json({\n    id: req.params.id,\n    context: req.ctx,\n  })\n})\n\nrouter.post('/users', async (req: ZeroRequest) => {\n  const body = await req.json()\n  return Response.json({created: true, data: body}, {status: 201})\n})\n```\n\n## API Reference\n\n### Router Configuration\n\n```typescript\ninterface IRouterConfig {\n  defaultRoute?: RequestHandler // Custom 404 handler\n  errorHandler?: (err: Error) => Response | Promise<Response> // Error handler\n  port?: number // Port number (for reference)\n  cacheSize?: number // Max entries per HTTP method in the route cache (default: 1000)\n}\n```\n\n> **Note on `cacheSize`:** The router uses an LRU-style cache for resolved routes. When the cache exceeds `cacheSize` entries for a given HTTP method, the oldest entry is evicted. The default of `1000` is suitable for most applications. Increase it for APIs with many dynamic routes; decrease it to save memory in constrained environments.\n\n### Request Object\n\nThe `ZeroRequest` extends the standard `Request` with additional properties:\n\n```typescript\ntype ZeroRequest = Request & {\n  params: Record<string, string> // URL parameters\n  query: Record<string, string> // Query string parameters\n  ctx?: Record<string, any> // Custom context (set by middleware)\n}\n```\n\n### Route Methods\n\n```typescript\n// HTTP Methods\nrouter.get(pattern, ...handlers)\nrouter.post(pattern, ...handlers)\nrouter.put(pattern, ...handlers)\nrouter.patch(pattern, ...handlers)\nrouter.delete(pattern, ...handlers)\nrouter.head(pattern, ...handlers)\nrouter.options(pattern, ...handlers)\nrouter.connect(pattern, ...handlers)\nrouter.trace(pattern, ...handlers)\n\n// Generic method\nrouter.on(method, pattern, ...handlers)\n\n// All methods\nrouter.all(pattern, ...handlers)\n```\n\n### Middleware\n\n```typescript\n// Global middleware\nrouter.use((req, next) => {\n  // Middleware logic\n  return next()\n})\n\n// Path-specific middleware\nrouter.use('/api/*', (req, next) => {\n  // API-specific middleware\n  return next()\n})\n\n// Multiple middlewares\nrouter.use(authMiddleware, loggingMiddleware, (req, next) => next())\n```\n\n## Examples\n\n### Complete REST API\n\n```typescript\nimport http, {ZeroRequest, StepFunction} from '0http-bun'\n\nconst {router} = http({\n  errorHandler: (err: Error) => {\n    return Response.json({error: err.message}, {status: 500})\n  },\n})\n\n// Logging middleware\nrouter.use((req: ZeroRequest, next: StepFunction) => {\n  console.log(`${req.method} ${req.url}`)\n  return next()\n})\n\n// JSON body parser middleware for POST/PUT\nrouter.use('/api/*', async (req: ZeroRequest, next: StepFunction) => {\n  if (req.method === 'POST' || req.method === 'PUT') {\n    try {\n      req.ctx = {...req.ctx, body: await req.json()}\n    } catch (err) {\n      return Response.json({error: 'Invalid JSON'}, {status: 400})\n    }\n  }\n  return next()\n})\n\n// Routes\nrouter.get('/api/users', () => {\n  return Response.json([\n    {id: 1, name: 'John'},\n    {id: 2, name: 'Jane'},\n  ])\n})\n\nrouter.get('/api/users/:id', (req: ZeroRequest) => {\n  const {id} = req.params\n  return Response.json({id: Number(id), name: 'User'})\n})\n\nrouter.post('/api/users', (req: ZeroRequest) => {\n  const userData = req.ctx?.body\n  return Response.json({id: Date.now(), ...userData}, {status: 201})\n})\n\nrouter.delete('/api/users/:id', (req: ZeroRequest) => {\n  const {id} = req.params\n  return Response.json({deleted: id})\n})\n\n// Start server\nBun.serve({\n  port: 3000,\n  fetch: router.fetch,\n})\n```\n\n## Middleware Support\n\n0http-bun includes a comprehensive middleware system with built-in middlewares for common use cases:\n\n> 📦 **Note**: Starting with v1.2.2, some middleware dependencies are optional. Install only what you need: `jose` (JWT), `pino` (Logger), `prom-client` (Prometheus).\n\n- **[Body Parser](./lib/middleware/README.md#body-parser)** - Automatic request body parsing (JSON, form data, text)\n- **[CORS](./lib/middleware/README.md#cors)** - Cross-Origin Resource Sharing with flexible configuration\n- **[JWT Authentication](./lib/middleware/README.md#jwt-authentication)** - JSON Web Token authentication and authorization\n- **[Logger](./lib/middleware/README.md#logger)** - Request logging with multiple output formats\n- **[Rate Limiting](./lib/middleware/README.md#rate-limiting)** - Flexible rate limiting with sliding window support\n- **[Prometheus Metrics](./lib/middleware/README.md#prometheus-metrics)** - Export metrics for monitoring and alerting\n\n### Quick Example\n\n```javascript\n// Import middleware functions from the middleware module\nconst {\n  createCORS,\n  createLogger,\n  createBodyParser,\n  createJWTAuth,\n  createRateLimit,\n} = require('0http-bun/lib/middleware')\n\nconst {router} = http()\n\n// Apply middleware stack\nrouter.use(createCORS()) // Enable CORS\nrouter.use(createLogger()) // Request logging\nrouter.use(createBodyParser()) // Parse request bodies\nrouter.use(createRateLimit({max: 100})) // Rate limiting\n\n// Protected routes\nrouter.use('/api/*', createJWTAuth({secret: process.env.JWT_SECRET}))\n```\n\n📖 **[Complete Middleware Documentation](./lib/middleware/README.md)**\n\n### Error Handling\n\nThe default error handler returns a generic `\"Internal Server Error\"` response (HTTP 500) and logs the full error to `console.error`. This prevents leaking stack traces or internal details to clients.\n\nYou can provide a custom `errorHandler` for more control:\n\n```typescript\nimport http, {ZeroRequest} from '0http-bun'\n\nconst {router} = http({\n  errorHandler: (err: Error) => {\n    console.error('Application error:', err)\n\n    // Custom error responses based on error type\n    if (err.name === 'ValidationError') {\n      return Response.json(\n        {error: 'Validation failed', details: err.message},\n        {status: 400},\n      )\n    }\n\n    return Response.json({error: 'Internal server error'}, {status: 500})\n  },\n  defaultRoute: () => {\n    return Response.json({error: 'Route not found'}, {status: 404})\n  },\n})\n\n// Errors thrown in both sync and async handlers are caught automatically\nrouter.get('/api/risky', async (req: ZeroRequest) => {\n  const data = await fetchExternalData() // async errors are caught too\n  if (!data) {\n    throw new Error('Data not found')\n  }\n  return Response.json(data)\n})\n```\n\n> **Async error handling:** Errors thrown or rejected in async middleware/handlers are automatically caught and forwarded to the `errorHandler`. You do not need to wrap every handler in try/catch.\n\n## Security\n\n0http-bun is designed with **security-first principles** and includes comprehensive protection against common web vulnerabilities. The core framework and middleware have been thoroughly penetration-tested and hardened.\n\n### Built-in Security Features\n\n#### **Input Validation & Sanitization**\n\n- **Size Limits**: Configurable limits prevent memory exhaustion attacks\n- **ReDoS Protection**: Restrictive regex patterns prevent Regular Expression DoS\n- **JSON Security**: String-aware nesting depth validation and safe parsing\n- **Parameter Validation**: Maximum parameter counts and length restrictions\n- **Filename Sanitization**: Multipart file uploads are sanitized to prevent path traversal (directory separators, `..`, null bytes are stripped; `originalName` preserved for reference)\n\n#### **Attack Prevention**\n\n- **Prototype Pollution Protection**: Filters dangerous keys (`__proto__`, `constructor`, `prototype`) in body parser, multipart parser, and URL-encoded parser using `Object.create(null)` for safe objects\n- **Timing Attack Prevention**: API key comparisons use `crypto.timingSafeEqual()`\n- **Algorithm Confusion Prevention**: JWT middleware rejects mixed symmetric/asymmetric algorithm configurations\n- **Cache Exhaustion Prevention**: LRU-style route cache with configurable `cacheSize` limit (default: 1000)\n- **Memory Exhaustion Prevention**: Strict size limits, sliding window rate limiter with `maxKeys` eviction, and automatic cleanup intervals\n- **Route Filter Bypass Prevention**: URL path normalization (double-slash collapse, URI decoding, `%2F` preservation, `.` / `..` resolution)\n- **Frozen Route Params**: Parameterless routes receive an immutable `Object.freeze({})` to prevent cross-request data leakage\n\n#### **Error Handling**\n\n- **Generic Error Responses**: Default error handler returns `\"Internal Server Error\"` without exposing stack traces or `err.message`\n- **Server-Side Logging**: Full error details logged via `console.error` for debugging\n- **Async Error Catching**: Rejected promises from async middleware are automatically caught and forwarded to the error handler\n- **Unified JWT Errors**: JWT signature/expiry/claim validation failures return `\"Invalid or expired token\"` regardless of the specific failure reason\n\n#### **Authentication & Authorization**\n\n- **JWT Security**: Default algorithms restricted to `['HS256']`; algorithm confusion prevented\n- **Timing-Safe API Keys**: All API key comparisons use constant-time comparison\n- **Path Exclusion Security**: Uses exact match or path boundary checking (`path + '/'`) instead of prefix matching\n- **Optional Mode Visibility**: When `optional: true`, invalid tokens set `req.ctx.authError` and `req.ctx.authAttempted` for downstream inspection\n- **Minimal Token Exposure**: Raw JWT token is no longer stored on the request context\n\n#### **Rate Limiting**\n\n- **Secure Key Generation**: Default key generator uses `req.ip || req.remoteAddress || req.socket?.remoteAddress || 'unknown'` — proxy headers are **not trusted** by default\n- **No Store Injection**: Rate limit store is always the constructor-configured instance (no `req.rateLimitStore` override)\n- **Bounded Memory**: Sliding window rate limiter enforces `maxKeys` (default: 10,000) with periodic cleanup\n- **Synchronous Increment**: `MemoryStore.increment` is synchronous to eliminate TOCTOU race conditions\n- **Configurable Limits**: Flexible rate limiting with skip functions and path exclusion\n\n#### **CORS Security**\n\n- **Null Origin Rejection**: `null` and missing origins are rejected before calling validator functions or checking arrays, preventing sandboxed iframe bypass\n- **Conditional Headers**: CORS headers (methods, allowed headers, credentials, exposed headers) are only set when the origin is actually allowed\n- **Vary Header**: `Vary: Origin` is set for all non-wildcard origins to prevent CDN cache poisoning\n- **Credential Safety**: Prevents wildcard origins with credentials\n\n### Security Best Practices\n\n```typescript\n// Secure server configuration\nconst {router} = http({\n  cacheSize: 500, // Limit route cache for constrained environments\n  errorHandler: (err: Error) => {\n    // Never expose stack traces in production\n    return Response.json({error: 'Internal server error'}, {status: 500})\n  },\n  defaultRoute: () => {\n    return Response.json({error: 'Not found'}, {status: 404})\n  },\n})\n\n// Apply security middleware stack\nrouter.use(\n  createCORS({\n    origin: ['https://yourdomain.com'], // Restrict origins — null origins are rejected\n    credentials: true,\n  }),\n)\n\nrouter.use(\n  createRateLimit({\n    windowMs: 15 * 60 * 1000, // 15 minutes\n    max: 100,\n    // Behind a reverse proxy? Provide a custom keyGenerator:\n    // keyGenerator: (req) => req.headers.get('x-forwarded-for') || req.ip || 'unknown',\n  }),\n)\n\nrouter.use(\n  '/api/*',\n  createJWTAuth({\n    secret: process.env.JWT_SECRET,\n    algorithms: ['HS256'], // Default — explicit for clarity\n    // For RS256, use jwksUri instead of secret:\n    // jwksUri: 'https://your-idp.com/.well-known/jwks.json',\n    // algorithms: ['RS256'],\n  }),\n)\n\n// Secure body parsing\nrouter.use(\n  createBodyParser({\n    json: {limit: '10mb'},\n    urlencoded: {limit: '10mb'},\n    multipart: {limit: '50mb'},\n  }),\n)\n```\n\n### Security Monitoring\n\n0http-bun provides built-in security monitoring capabilities:\n\n```typescript\n// Security logging with request context\nrouter.use(\n  createLogger({\n    serializers: {\n      req: (req) => ({\n        method: req.method,\n        url: req.url,\n        ip:\n          req.ip || req.remoteAddress || req.socket?.remoteAddress || 'unknown',\n        userAgent: req.headers.get('user-agent'),\n      }),\n    },\n  }),\n)\n\n// Prometheus metrics for security monitoring\nrouter.use(\n  createPrometheusMetrics({\n    prefix: 'http_',\n    labels: ['method', 'route', 'status_code'],\n  }),\n)\n```\n\n### Security Recommendations\n\n1. **Environment Variables**: Store secrets in environment variables, never in code\n2. **HTTPS Only**: Always use HTTPS in production with proper TLS configuration\n3. **Reverse Proxy Configuration**: If behind a reverse proxy, always provide a custom `keyGenerator` for rate limiting that reads the appropriate header (e.g., `X-Forwarded-For`)\n4. **Algorithm Explicitness**: Always explicitly set JWT `algorithms` — do not rely on defaults\n5. **Input Validation**: Validate and sanitize all user inputs\n6. **Regular Updates**: Keep dependencies updated and run security audits\n7. **Monitoring**: Implement logging and monitoring for security events\n\n> **Security is a continuous process**. While 0http-bun provides strong security foundations, always follow security best practices and conduct regular security assessments for your applications.\n\n## Performance\n\n0http-bun is designed for high performance with Bun's native capabilities:\n\n- **Minimal overhead**: Direct use of Web APIs\n- **Efficient routing**: Based on the proven `trouter` library\n- **Fast parameter parsing**: Optimized URL parameter extraction with caching\n- **Query string parsing**: Uses `fast-querystring` for optimal performance\n- **Memory efficient**: LRU-style route caching with configurable `cacheSize` limit, immutable shared objects, and minimal allocations\n- **URL normalization**: Single-pass URL parsing with path normalization (double-slash collapse, URI decoding, `.` / `..` resolution)\n\n### Benchmark Results\n\nRun benchmarks with:\n\n```bash\nbun run bench\n```\n\n_Performance characteristics will vary based on your specific use case and middleware stack._\n\n## TypeScript Support\n\nFull TypeScript support is included with comprehensive type definitions:\n\n```typescript\n// Main framework types\nimport {\n  ZeroRequest,\n  StepFunction,\n  RequestHandler,\n  IRouter,\n  IRouterConfig,\n} from '0http-bun'\n\n// Middleware-specific types\nimport {\n  LoggerOptions,\n  JWTAuthOptions,\n  APIKeyAuthOptions,\n  RateLimitOptions,\n  CORSOptions,\n  BodyParserOptions,\n  MemoryStore,\n} from '0http-bun/lib/middleware'\n\n// Example typed middleware\nconst customMiddleware: RequestHandler = (\n  req: ZeroRequest,\n  next: StepFunction,\n) => {\n  req.ctx = req.ctx || {}\n  req.ctx.timestamp = Date.now()\n  return next()\n}\n\n// Example typed route handler\nconst typedHandler = (req: ZeroRequest): Response => {\n  return Response.json({\n    params: req.params,\n    query: req.query,\n    context: req.ctx,\n  })\n}\n```\n\n## 🏆 Production-Ready Features\n\n0http-bun is trusted by developers for production workloads thanks to its comprehensive feature set:\n\n### 📦 **Comprehensive Middleware Ecosystem**\n\n- **Body Parser**: JSON, URL-encoded, multipart, and text parsing with security\n- **Authentication**: JWT and API key authentication with flexible validation\n- **CORS**: Cross-origin resource sharing with dynamic origin support\n- **Rate Limiting**: Sliding window rate limiting with memory-efficient storage\n- **Logging**: Structured logging with Pino integration and request tracing\n- **Metrics**: Prometheus metrics export for monitoring and alerting\n\n### 🔧 **Developer Tools**\n\n- **TypeScript Support**: Full type definitions and IntelliSense\n- **Error Handling**: Comprehensive error management with custom handlers; async errors caught automatically\n- **Request Context**: Flexible context system for middleware data sharing\n- **Parameter Parsing**: Automatic URL parameter and query string parsing\n- **Route Caching**: LRU-style caching with configurable `cacheSize` for bounded memory usage\n\n### 🚀 **Deployment Ready**\n\n- **Environment Agnostic**: Works with any Bun deployment platform\n- **Minimal Dependencies**: Small attack surface with carefully selected dependencies\n- **Memory Efficient**: Optimized for serverless and containerized deployments\n- **Scalable Architecture**: Designed for horizontal scaling and load balancing\n\n## 📈 Benchmarks & Comparisons\n\n0http-bun consistently outperforms other frameworks in Bun environments:\n\n| Framework     | Requests/sec | Memory Usage | Latency (p95) |\n| ------------- | ------------ | ------------ | ------------- |\n| **0http-bun** | ~85,000      | ~45MB        | ~2.1ms        |\n| Express       | ~42,000      | ~68MB        | ~4.8ms        |\n| Fastify       | ~78,000      | ~52MB        | ~2.4ms        |\n| Hono          | ~82,000      | ~48MB        | ~2.2ms        |\n\n_Benchmarks run on Bun v1.2.2 with simple JSON response routes. Results may vary based on hardware and configuration._\n\n## 🌟 Community & Support\n\n- **📚 Comprehensive Documentation**: Detailed guides and API reference\n- **🔧 Active Development**: Regular updates and feature improvements\n- **🐛 Issue Tracking**: Responsive bug reports and feature requests\n- **💬 Community Discussions**: GitHub Discussions for questions and ideas\n- **🎯 Production Proven**: Used in production by companies worldwide\n\n## Changelog\n\n### v1.3.1 — Follow-up Hardening\n\nAdversarial review of the v1.3.0 hardening pass. Remaining gaps in path handling, middleware consistency, and hot-path cost are addressed.\n\n#### Security\n\n- **Dot-segment resolution** — `%2e%2e` / `..` / `.` are now resolved after URI decoding so routing and `excludePaths` cannot disagree (the previous pass collapsed slashes and decoded, but left `..` in the path).\n- **Shared canonical path** — JWT, rate-limit, logger, and Prometheus `excludePaths` now use the same `req.path` the router computed, instead of `new URL(req.url).pathname`.\n- **Logger / Prometheus prefix matching** — `excludePaths` now uses exact-or-boundary matching (same as JWT and rate-limit). `/health` no longer skips `/healthcheck`.\n- **CORS preflight `Vary: Origin`** — set for static string origins as well as function/array origins.\n- **CORS `null` origin** — rejected for all non-wildcard configs, including `origin: 'null'`.\n- **Logger request IDs** — header-supplied IDs are stripped of control characters and capped at 128 chars.\n- **Logger response headers** — `Set-Cookie`, `Authorization`, `Cookie`, and `Proxy-Authorization` are redacted in the default serializer.\n- **JWT optional mode** — `req.ctx.authError` is a generic message, not the raw jose error.\n- **MemoryStore bounds** — `maxKeys` (default 10,000) plus amortized cleanup. When full, **new keys fail closed** (429) instead of evicting live counters.\n- **Write-once canonical path** — security middleware reads `Symbol.for('0http.canonicalPath')` or re-parses `req.url`; mutable `req.path` is ignored.\n\n#### Performance\n\n- Router skips decode / slash-collapse / dot-resolution when the path does not need them.\n- Reused frozen empty query object; single-pass param copy.\n- Middleware no longer allocates `new URL()` on every request when `req.path` is set.\n- JSON nesting scan short-circuits at the depth limit; body reader uses tracked byte length.\n- Custom `jsonTypes` parsers are cached instead of being created per request.\n\n#### Ergonomics\n\n- Types now include `req.path`, `req.body`, `req.files`, logger options (`level`, `requestIdHeader`, `generateRequestId`), `errorHandler(err, req)`, `extended` on body parser, and `maxKeys` on rate limit.\n- `ParsedFile.data` is `Uint8Array` (matches the implementation). `req.jwt.token` removed from types (removed in 1.3.0).\n- CORS origin validators receive `(origin, req)` as documented.\n- CORS preflight methods are compared case-insensitively.\n- CI runs `bun run lint` (check) instead of `format` (write). Bench script points at `bench.ts`.\n\n### v1.3.0 — Security Hardening Release\n\nThis release addresses **43 vulnerabilities** (6 Critical, 13 High, 13 Medium, 7 Low, 4 Info) identified in a comprehensive penetration test. All 43 issues have been resolved.\n\n#### Breaking Changes\n\n| Change                        | Old Behavior                                                                                    | New Behavior                                                                                                                        |\n| ----------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |\n| **Rate limit key generator**  | Trusted `X-Forwarded-For`, `X-Real-IP`, `CF-Connecting-IP` proxy headers                        | Uses `req.ip \\|\\| req.remoteAddress \\|\\| 'unknown'` only. Supply a custom `keyGenerator` if behind a reverse proxy.                 |\n| **JWT default algorithms**    | `['HS256', 'RS256']`                                                                            | `['HS256']` only. Mixed symmetric + asymmetric algorithms throw an error. Explicitly set `algorithms: ['RS256']` if using RSA keys. |\n| **Default error handler**     | Returned `err.message` to the client in the response body                                       | Returns generic `\"Internal Server Error\"`. Full error logged server-side via `console.error`.                                       |\n| **`parseLimit` validation**   | Silently returned 1MB default for `false`, `null`, objects                                      | Throws `TypeError` for unexpected types.                                                                                            |\n| **JWT token in context**      | `req.jwt.token` and `req.ctx.jwt.token` contained the raw JWT string                            | Raw token no longer stored on the request context. Only `payload` and `header` are available.                                       |\n| **JWT module exports**        | Exported internal functions (`extractToken`, `handleAuthError`, `extractTokenFromHeader`, etc.) | Only exports `createJWTAuth`, `createAPIKeyAuth`, and `API_KEY_SYMBOL`. Internal helpers are no longer exposed.                     |\n| **Rate limit store override** | `req.rateLimitStore` could override the configured store at runtime                             | Always uses the constructor-configured store. `req.rateLimitStore` has no effect.                                                   |\n| **API key in context**        | `req.apiKey` / `req.ctx.apiKey` contained the raw API key                                       | Now stores a masked version (`xxxx****xxxx`). Raw key available via `req[API_KEY_SYMBOL]`.                                          |\n| **Empty JSON body**           | Empty/whitespace JSON body silently returned `{}`                                               | Now sets `req.body` to `undefined`. Applications must handle `undefined` explicitly.                                                |\n\n#### Core Router\n\n- **LRU route cache** with configurable `cacheSize` (default: 1000) — prevents unbounded memory growth from cache poisoning attacks.\n- **URL path normalization** — double slashes collapsed, URI-decoded (preserving `%2F`), preventing route filter bypass via `//admin` or `%2e%2e` paths.\n- **Immutable empty params** — `Object.freeze({})` prevents cross-request data leakage on parameterless routes.\n- **`router.use()` return fix** — `return this` in arrow function corrected to `return router` for proper chaining.\n- **Query prototype pollution protection** — dangerous keys (`__proto__`, `constructor`, `prototype`) are filtered from parsed query strings, mirroring existing route params protection.\n\n#### Middleware Chain\n\n- **Async error handling** — rejected promises from async middleware are now caught via `.catch()` and forwarded to the `errorHandler`. Previously, they were unhandled.\n\n#### Body Parser\n\n- **String-aware JSON nesting depth scanner** — brace characters inside JSON strings no longer count toward nesting depth, fixing a bypass where `{\"key\": \"{{{...\"}` could evade the depth check.\n- **Custom `jsonParser` enforces size limits** — size validation runs before the custom parser function is called.\n- **Prototype pollution protection for multipart** — uses `Object.create(null)` for body/files objects and blocklists dangerous property names.\n- **Multipart filename sanitization** — strips `..`, path separators (`/`, `\\`), null bytes, and leading dots. The original filename is preserved in `file.originalName`.\n- **Strict content-type matching** — JSON parser matches `application/json` only (was `application/` which matched `application/xml`, `application/octet-stream`, etc.).\n- **`parseLimit` type validation** — throws `TypeError` on unexpected input types instead of silently defaulting.\n- **Empty JSON body handling** — empty or whitespace-only JSON bodies now set `req.body` to `undefined` instead of silently returning `{}`. _(Breaking change)_\n- **Raw body via Symbol** — raw body text is now stored via `Symbol.for('0http.rawBody')` (`RAW_BODY_SYMBOL`) instead of `req._rawBodyText`, preventing accidental serialization/logging. The symbol is exported from the body parser module.\n\n#### JWT Authentication\n\n- **Timing-safe API key comparison** — all API key comparisons use `crypto.timingSafeEqual()` with constant-time length mismatch handling.\n- **Algorithm confusion prevention** — throws if both symmetric (`HS*`) and asymmetric (`RS*`/`ES*`/`PS*`) algorithms are configured.\n- **Secure path exclusion** — exact match or `path + '/'` boundary checking replaces prefix matching (prevents `/healthcheck` bypassing `/health` exclusion).\n- **Optional mode transparency** — when `optional: true` and a token is invalid, sets `req.ctx.authError` and `req.ctx.authAttempted = true` instead of silently proceeding.\n- **Unified error messages** — JWT signature/expiry/claim validation failures return `\"Invalid or expired token\"` to prevent oracle attacks. Distinct messages are used for missing tokens and API key failures.\n- **Safe option merging** — `...jwtOptions` spread applied first; security-critical options (`algorithms`, `audience`, `issuer`) override after.\n- **Validator call signature** — always calls `apiKeyValidator(apiKey, req)` regardless of `Function.length` arity.\n- **Reduced export surface** — only `createJWTAuth` and `createAPIKeyAuth` are exported.\n- **Token type validation** — new `requiredTokenType` option validates the JWT `typ` header claim (case-insensitive). Rejects tokens with missing or incorrect type when configured.\n- **API key via Symbol** — raw API key available via `req[API_KEY_SYMBOL]` (exported `Symbol.for('0http.apiKey')`). `req.apiKey` and `req.ctx.apiKey` now store a masked version (`xxxx****xxxx`). _(Breaking change)_\n- **Error logging in auth handler** — empty `catch` blocks in `handleAuthError` now log errors via `console.error` for debugging visibility.\n\n#### Rate Limiting\n\n- **Secure default key generator** — uses `req.ip || req.remoteAddress || 'unknown'` instead of trusting proxy headers.\n- **Sliding window memory bounds** — `maxKeys` option (default: 10,000) with periodic cleanup via `setInterval` + `unref()`.\n- **Synchronous `MemoryStore.increment`** — eliminates TOCTOU race condition in the fixed-window store.\n- **Exact path exclusion** — `excludePaths` uses exact or boundary matching.\n- **Configurable header disclosure** — `standardHeaders` now accepts `true` (full headers, default), `false` (no headers), or `'minimal'` (only `Retry-After` on 429 responses) to control rate limit information disclosure.\n- **Unique unknown keys** — when no IP is available, the default key generator now creates unique per-request keys instead of sharing a single `'unknown'` bucket, preventing shared-bucket DoS.\n\n#### CORS\n\n- **Null origin rejection** — `null`/missing origins rejected before calling validator functions or checking arrays, preventing sandboxed iframe bypass.\n- **Conditional CORS headers** — headers only set when the origin is actually allowed (previously leaked method/header lists even on rejected origins).\n- **`Vary: Origin`** — set for all non-wildcard origins (previously only set for function/array origins).\n- **Single allowedHeaders resolution** — `allowedHeaders` function is now resolved once per preflight request instead of multiple times, preventing inconsistency.\n\n### v1.2.2\n\n- Middleware dependencies (`jose`, `pino`, `prom-client`) made optional with lazy loading.\n- Prometheus metrics middleware added.\n- Logger middleware added.\n\n---\n\n## Migrating to v1.3.0\n\n### Rate Limiting Behind a Reverse Proxy\n\nThe default `keyGenerator` no longer reads proxy headers. If your application runs behind a reverse proxy (nginx, Cloudflare, AWS ALB, etc.), you **must** provide a custom `keyGenerator`:\n\n```typescript\nrouter.use(\n  createRateLimit({\n    windowMs: 15 * 60 * 1000,\n    max: 100,\n    keyGenerator: (req) => {\n      // Trust the header your reverse proxy sets\n      return (\n        req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||\n        req.ip ||\n        'unknown'\n      )\n    },\n  }),\n)\n```\n\n### JWT Algorithm Configuration\n\nIf you were relying on the default `['HS256', 'RS256']` algorithm list, you must now be explicit:\n\n```typescript\n// For HMAC (symmetric) secrets:\ncreateJWTAuth({\n  secret: process.env.JWT_SECRET,\n  algorithms: ['HS256'], // This is now the default\n})\n\n// For RSA (asymmetric) keys:\ncreateJWTAuth({\n  jwksUri: 'https://your-idp.com/.well-known/jwks.json',\n  algorithms: ['RS256'], // Must be explicit — mixing with HS256 will throw\n})\n```\n\n### Error Handler\n\nIf you relied on `err.message` being returned to clients from the default error handler, provide a custom `errorHandler`:\n\n```typescript\nconst {router} = http({\n  errorHandler: (err: Error) => {\n    // Old behavior (NOT recommended for production):\n    return new Response(err.message, {status: 500})\n  },\n})\n```\n\n### `parseLimit` Validation\n\nIf your code passes non-string/non-number values to `parseLimit` (e.g., `false`, `null`, objects), update it to pass a valid value:\n\n```typescript\n// Before (silently defaulted to 1MB):\ncreateBodyParser({json: {limit: someConfig.limit}}) // someConfig.limit might be null\n\n// After (throws TypeError):\ncreateBodyParser({json: {limit: someConfig.limit || '1mb'}}) // Provide a fallback\n```\n\n### JWT Token Context\n\nIf you accessed the raw JWT token string via `req.jwt.token` or `req.ctx.jwt.token`, note that only `payload` and `header` are now available:\n\n```typescript\n// Before:\nconst rawToken = req.jwt.token // No longer available\n\n// After:\nconst payload = req.jwt.payload // Decoded payload\nconst header = req.jwt.header // Protected header\n```\n\n### API Key Access\n\nIf you accessed the raw API key via `req.apiKey` or `req.ctx.apiKey`, note that these now contain a masked version. Use the exported `API_KEY_SYMBOL` for programmatic access:\n\n```typescript\nimport {API_KEY_SYMBOL} from '0http-bun/lib/middleware/jwt-auth'\n\n// Before:\nconst rawKey = req.apiKey // Was the raw API key, now masked (xxxx****xxxx)\n\n// After:\nconst rawKey = req[API_KEY_SYMBOL] // Symbol.for('0http.apiKey')\nconst maskedKey = req.apiKey // 'xxxx****xxxx' (safe for logging)\n```\n\n### Empty JSON Body\n\nIf your code relied on empty JSON request bodies being parsed as `{}`, update it to handle `undefined`:\n\n```typescript\n// Before (empty body → {}):\nrouter.post('/api/data', (req) => {\n  const keys = Object.keys(req.body) // Always worked\n})\n\n// After (empty body → undefined):\nrouter.post('/api/data', (req) => {\n  const body = req.body || {}\n  const keys = Object.keys(body) // Handle undefined\n})\n```\n\n### Raw Body Access\n\nIf you accessed raw body text via `req._rawBodyText`, use the exported `RAW_BODY_SYMBOL` instead:\n\n```typescript\nimport {RAW_BODY_SYMBOL} from '0http-bun/lib/middleware/body-parser'\n\n// Before:\nconst rawBody = req._rawBodyText // Public string property\n\n// After:\nconst rawBody = req[RAW_BODY_SYMBOL] // Symbol.for('0http.rawBody')\n```\n\n---\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n### Development Setup\n\n```bash\n# Clone the repository\ngit clone https://github.com/BackendStack21/0http-bun.git\ncd 0http-bun\n\n# Install dependencies\nbun install\n\n# Run tests\nbun test\n\n# Run benchmarks\nbun run bench\n\n# Format code\nbun run format\n```\n\n## Related Projects\n\n- [0http](https://0http.21no.de/#/) - The original inspiration\n- [Bun](https://bun.sh/) - The JavaScript runtime this framework is built for\n- [Trouter](https://github.com/lukeed/trouter) - Fast routing library used under the hood\n- [Fast QueryString](https://github.com/unjs/fast-querystring) - Optimized query string parsing\n","readmeFilename":"README.md"}