{"_id":"s3proxy","_rev":"34-60dcdd3379c0b58ef905f1786276a163","name":"s3proxy","dist-tags":{"latest":"4.2.1"},"versions":{"1.0.0":{"name":"s3proxy","version":"1.0.0","keywords":["aws","s3","http","express","node","nodejs"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.0.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3front#readme","bugs":{"url":"https://github.com/gmoon/s3front/issues"},"dist":{"shasum":"982b040a86bc358754c291985d4004cb76c43e33","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.0.0.tgz","integrity":"sha512-Se4ApILrOq+2XdFOsCzW0GevUW9CaOcfKyOBhrC/MoG3BZMoOKGoJbfQKGSrjweI1eV8eX/l5ICSC7Tb56H/AQ==","signatures":[{"sig":"MEYCIQDjVHTJPks9H3mRQsBWCKs7jsHLVTB52ujSubRGQMDuvQIhAN+95iY9ewFCQZdJt0qXeIyRtQ2XCHhU+hJVro3IiKY2","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"s3proxy.js","_from":".","_shasum":"982b040a86bc358754c291985d4004cb76c43e33","gitHead":"41ea01d5f5ab9d5701a7a07a3e659006cf6684aa","scripts":{"test":"mocha"},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3front.git","type":"git"},"_npmVersion":"4.1.2","description":"Front AWS S3 with a web server that you control","directories":{},"_nodeVersion":"7.5.0","dependencies":{},"devDependencies":{"chai":"^4.1.2","mocha":"^3.5.3","sinon":"^3.2.1"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy-1.0.0.tgz_1505503723727_0.8128206194378436","host":"s3://npm-registry-packages"}},"1.1.0":{"name":"s3proxy","version":"1.1.0","keywords":["aws","s3","http","express","node","nodejs"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.1.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"2ccb7565057638c3ad3cbd87e38acc18023229aa","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.1.0.tgz","integrity":"sha512-eO9M9kAAwkWUl2DcExPmDE8kKJsLdrfra4KbjfM4YQpOSpg3AeDwQ1rmVPFi2reIusa2arO8wt+4/sQfdXKJlA==","signatures":[{"sig":"MEYCIQDFREfSWPCqDcaGMnvoNrUjURewqHjrw0pYyKaqEAgwJQIhAKkae8AzNqcM+Ij0U39kaeSeulbMTcQkTqoKWVNBDU5q","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"s3proxy.js","_from":".","_shasum":"2ccb7565057638c3ad3cbd87e38acc18023229aa","scripts":{"test":"make -j test"},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"4.1.2","description":"Front AWS S3 with a web server that you control","directories":{},"_nodeVersion":"7.5.0","dependencies":{"aws-sdk":"^2.118.0"},"devDependencies":{"chai":"^4.1.2","mocha":"^3.5.3","sinon":"^3.2.1","eslint":"^4.7.0","eslint-plugin-import":"^2.7.0","eslint-config-airbnb-base":"^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy-1.1.0.tgz_1505959541745_0.6692042821086943","host":"s3://npm-registry-packages"}},"1.2.0":{"name":"s3proxy","version":"1.2.0","keywords":["aws","s3","http","express","node","nodejs"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.2.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"9a8c063737611beffeb813631ded9deceff54164","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.2.0.tgz","integrity":"sha512-0I0acnBokEH3YIH5ZYuQvPfcM8SakA33GO7PlHbTgF6lrfcj9vJ+NulgYq6rSL5+LLrvAo9tR2KJkvDTAz6dVQ==","signatures":[{"sig":"MEQCIDhIalF6g3fm6+ZnVaHmWBplRLv9Ll+SNxy/Am7sXaDfAiArjhj1M62QHjhLN6w2zVPf506RkEq5tg3cPX+zz0UbZg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"s3proxy.js","_from":".","_shasum":"9a8c063737611beffeb813631ded9deceff54164","scripts":{"test":"make -j test"},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"4.1.2","description":"Front AWS S3 with a web server that you control","directories":{},"_nodeVersion":"7.5.0","dependencies":{"aws-sdk":"^2.118.0"},"devDependencies":{"chai":"^4.1.2","mocha":"^3.5.3","sinon":"^3.2.1","eslint":"^4.7.0","eslint-plugin-import":"^2.7.0","eslint-config-airbnb-base":"^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy-1.2.0.tgz_1506138422565_0.33093337900936604","host":"s3://npm-registry-packages"}},"1.2.1":{"name":"s3proxy","version":"1.2.1","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.2.1","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"97d3276142051ae1c5dae418ababc31368a7f821","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.2.1.tgz","integrity":"sha512-NXCFdzZFHwHVUoKN+Z/KLjZF/jhJHzixpNC0kZL4ee7xmYTLfL7VmXvdFvAXyvA4MQbtIl8T0AbnkLZyfvBBNw==","signatures":[{"sig":"MEUCIF3w1jWyK5lDEezzjzTRv4BV+vihuGDIJSyv1TSdiYyoAiEA/lwyUnQPa5LQMbBtS0+cVOYkVnVJLl+vVPYgP1FIDCU=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["README.md","LICENSE","index.js"],"_shasum":"97d3276142051ae1c5dae418ababc31368a7f821","gitHead":"a08a22689474774d5a5fde5408ba5fa20d8be490","scripts":{"test":"make -j test"},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"4.1.2","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"7.5.0","dependencies":{"aws-sdk":"^2.118.0"},"devDependencies":{"chai":"^4.1.2","mocha":"^3.5.3","eslint":"^4.7.0","express":"^4.15.4","istanbul":"^0.4.5","chai-http":"^3.0.0","eslint-plugin-import":"^2.7.0","eslint-config-airbnb-base":"^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy-1.2.1.tgz_1508257420967_0.6488229234237224","host":"s3://npm-registry-packages"}},"1.3.0":{"name":"s3proxy","version":"1.3.0","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.3.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"4c39967b1424ce2636007b53d498567b66f40632","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.3.0.tgz","integrity":"sha512-RZXb/EvoHCeKndmWVAcCQ+UWcgkQCz/Pvg2EDDb/1Mdlmj0lZTUP14Tru8+GK2mW8UsxhGBXB7dWhMjsejC4FQ==","signatures":[{"sig":"MEUCIQD4JAgKAMSF0oDQ0KcNVIgd1DxFIYaYe+sbk2I0rXxkMwIge7VqHOnAaG8PqOVz+cVmpV8pQRf1HZDje5BMroMR90w=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"index.js","_from":".","files":["README.md","LICENSE","index.js"],"_shasum":"4c39967b1424ce2636007b53d498567b66f40632","gitHead":"4f76938d3842a84d1eb1691e3ed3ba6dafa9a7b1","scripts":{"test":"make -j test","mocha":"mocha","istanbul":"istanbul"},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"4.1.2","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"7.5.0","dependencies":{"aws-sdk":"^2.118.0"},"devDependencies":{"chai":"^4.1.2","mocha":"^3.5.3","eslint":"^4.7.0","morgan":"^1.9.0","express":"^4.15.4","istanbul":"^0.4.5","chai-http":"^3.0.0","express-request-id":"^1.4.0","eslint-plugin-import":"^2.7.0","eslint-config-airbnb-base":"^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy-1.3.0.tgz_1517933817323_0.690532477106899","host":"s3://npm-registry-packages"}},"1.3.1":{"name":"s3proxy","version":"1.3.1","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.3.1","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"d829a39b2fe67984cafdeca3a5680a85a2e0a7d8","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.3.1.tgz","fileCount":4,"integrity":"sha512-OiT8O+mIkECVHJP8KNPSOFvIZqtKvqa19DlyTyEWQiiNqMbMxEGPfIBxaKPLXf1TA/K7WNvBbpjQM+43/oqwOg==","signatures":[{"sig":"MEUCIHUcCg8rw0eHjkWu26CD/zLLvGIoydK9WPkG221x6/gbAiEAkSjb1qSEVvQf/f2RINhWLI4xiOX4xrMJs3lwa3lBZ60=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":20039,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdFlSwCRA9TVsSAnZWagAAfvoP/31PdajO21pJj/06cMiD\nAcNSo/UJX++Uky1/tEwzwnrkxKxdqs37fHajjjaG9KjKVlvhlA3q+eXoT2LF\necVtG2mp0Z9SJ5J8NA2BSe8K+gaXr8pMJRBbRZSIE6s9MH+Y98gbIiY6Ugsv\nPGwP8y789bSLwEMO4C3reV+0IOTIpuBiV3Oa6TenHK4WepXrTIqGuREtJFZu\nP7m9QotWy7tfFmTGTFOpDnl8KW3humzzwAFGxvQB+pzxjr9d7xca5NVW4iTc\nSVcoYfwvOKCFC6Qc3IgzUepdA1pgDFkhxoOTgNZxZmVuOZWPBlaL/oohZMGA\nEJaqrU0KFX27s6MqsRdRflez+9RYjm5yHxaeQ9w12nGojTCfNodfnOP2qDNb\noQyNaCKGx6BOVy6hrqwwR1hF5WyKgrxnTzVGIfyWswKuboIhlNfNtYKvhzfX\nz6cL/gJ5DZvrvlFQt1N1rbBw+SZgiQp+QwFE5hn40uDsec3da1wAxkSPFEVY\nPkotKSfJUmycfxDuKA4xC/z8NNlFgXZKHdcR9va2OGf4BDV77q6PRRvfl5L0\n7fNaD5kMf12BedQDn9DN6RJDabMJ84HMCDZy30G4o17tXPHb1aadDajdufo6\nGPqyVQiyYMPy9VCrF2drPQxTpdk6V7NCJKyqzzInBSZEziBWOPf15SWOTOpN\ne/Ik\r\n=4Gx7\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"f98d27c93b6f674f75df414b9ff63cb9fa171259","scripts":{"test":"make -j test","mocha":"mocha","nyc-coverage":"nyc --reporter=html --reporter=text"},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"6.4.1","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"8.12.0","dependencies":{"aws-sdk":"^2.484.0","istanbul":"^0.4.5"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^14.1.1","chai":"^4.2.0","mocha":"^6.1.4","eslint":"^6.0.1","morgan":"^1.9.1","express":"^4.17.1","chai-http":"^4.3.0","express-request-id":"^1.4.1","eslint-plugin-import":"^2.18.0","eslint-config-airbnb-base":"^13.1.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.3.1_1561744560278_0.9933098889217853","host":"s3://npm-registry-packages"}},"1.4.1":{"name":"s3proxy","version":"1.4.1","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.4.1","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"c5c8481ce4990f6fdff0ff183296b605949d16af","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.4.1.tgz","fileCount":6,"integrity":"sha512-LTzFvloQzfeaGpC9rZdhFz/ke5Y3yPnNcQ9grljOlxVHyV4YjdyBiwXKYbzGMEm7EUjuAfP0CevhDuNXsk9Jzw==","signatures":[{"sig":"MEYCIQDUThCaMsDknqrscHNZV6fc+0fTVFw5COFe3i4SkLkDYgIhALKUcCcVq41uu5yrNYSTBZuY1qcxDg0+DWE1NcwS0LLP","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":28677,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfOKzlCRA9TVsSAnZWagAApuEQAIXYnljvxA8j8aVtcCsh\nIoGrHwT8GlXdB0BRotwBknAQzQD4SBlZVtc/W9Dbcmk6Nl5RoGOCPWYJmLW6\n0Vr2FXchC+LNrv4gdlkKb6sum6SljMijffv9QTKVUcpCncu2Hh78fyA/5h0q\nyq14yLLEwzmCcarfZjq2Teq2BuXEnLvNpoXng6GWpv1CkG+jvGrzmgUmbTC4\n0OPrIMQtTDefRoiO0KRWDwmO5nC3sPJio2c30Ych/IPTtKodzROcayPLaXIL\n6pMz7VM3Ht3zSzjK1R7l75073C0II042lazmitnRyxeQFAMrWx+r0iPqNTlk\nz9CF6ytTAuoQsvt84wxkCOkEuR1Jg77Mmxiql43QWSpy35xHOj6yTZvsu29n\nRlXSHShkf2XEkBi9DoiqXKPO2kweeZVfR4Ep6hUSYdFwxg8KZ1AqzcRbSGfD\nPZRzuusBJrlzSE3MgTwugflcefhD58uFBKzK2ymUxI26+SYK15EpPx8uCUxt\n3gQGmyP2DO5mI7VB9tBepaYKhNR+PgKURJqJ+C44x1FtVtedcw4Wvzx1VFSm\n12yQdEcvKyFhqZgiaNM7ze6+2hKGOmiPxsdGORpYdViVA5sz1e2MlUEiyKsS\nIGoQ6t9OAXHK/+XQ8NLfkb4YfwJMMCTkXmUH+KYRn471IsH/j88R+7LS34m+\nv0HS\r\n=nUiO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"ecf37152579de8aea38fa552655ed1605e0a9dec","scripts":{"test":"make test","mocha":"mocha","start":"PORT=3000 node examples/express-basic.js","artillery":"artillery run test/artillery.yml","artillery-ci":"start-server-and-test start :3000 artillery","nyc-coverage":"nyc --reporter=html --reporter=text"},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"6.14.5","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"10.16.3","dependencies":{"url":"^0.11.0","aws-sdk":"^2.734.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.2.0","nock":"^13.0.4","mocha":"^8.1.1","sinon":"^9.0.3","eslint":"^7.7.0","morgan":"^1.10.0","express":"^4.17.1","artillery":"^1.6.1","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.0.0","express-request-id":"^1.4.1","eslint-plugin-import":"^2.22.0","start-server-and-test":"^1.11.3","artillery-plugin-expect":"^1.3.0","eslint-config-airbnb-base":"^14.2.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.4.1_1597549796846_0.03359606860034625","host":"s3://npm-registry-packages"}},"1.5.0":{"name":"s3proxy","version":"1.5.0","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.5.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"7c565e16edace4a02970d2388748eeb9905a4ae4","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.5.0.tgz","fileCount":6,"integrity":"sha512-6CSuRjWoLWSRVwjN/3Ine1KDiP0QUk1o8gUb+jnP9U4Fi1i4TZOVBV8Grgyf3sl/kH3cHDzUduQ8RHp5puNAwg==","signatures":[{"sig":"MEYCIQDUvhiwiOQk3lmb3NgRkd4mqUyK2dnrxdKNzuJqTae/4QIhANSnf0NbfkU6QNOeqr+njOC5FHxnu0dynn8BuzMWMR+B","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":31000,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgnZmnCRA9TVsSAnZWagAAlT4QAJiCQ8XHXjkZyUS72Koq\nDM9L+CAIz1NzrG0loYSaXcYpcOVkDmc/5Ilj0cxglMYW9ArIKHhMe4bk8jnr\nn9eO9qRVR8KIaKVuR/rGacotS3PTjYjvP/0W4rHEboMMX/Iyf3HNrLustIPA\nwVpWSD+SsbuOUNpjMp+RMdv7R7aC6zxWmhc4qXWfq0wEdEF7a7yZ7wimWRIr\npgReAphn5tB+i1Hq+v1m6DuMPuDr6oc41RN/Ph/WRPgi5137W1XK1hNOOmCX\n8g30ZAZ+NzCxoiUl1BZOVPpEUcYUhpmv6mL4NLf44GcZ4hx73MTzKJlqsF8w\n2lFzeszvWavwKclKvH1IcZvm22NKBA78rmrZF44uxlyl6pmrBI8EdFmwyreV\nruzSyZH8GYIVWNHyvNl9ukI7GHcEIBb2he1VEWLtBmWpU+hTTvNhH46L8JkL\npS2eNAo+JQkpGMHz4oBYqc807c1SJLZZ52kV6MfSKHeBoH6yu4Jz+6B6AoPb\n8WAi7BjnNduiXxbTfJTXCuDYlr6Fg40OTJdA0EsQ0tPKcAO4b/IZNu24mQI1\n1GanlySjhwjUtKgxNg/4huudoHTDuy7pOdRUjkPEEEL6Md9+vMBikkn+pWni\nXY8qejrR3IxYFtaMLFkmiMgCJuFXs2QfuliBSzmb0y7poD3UVyO2epahAkYb\nP2GK\r\n=CuxV\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"e1934eb2530d08cbd7af9f6b1a99ef7545fc941f","scripts":{"test":"make test","mocha":"mocha","start":"PORT=3000 node examples/express-basic.js","artillery":"artillery run test/artillery.yml","artillery-ci":"start-server-and-test start :3000 artillery","nyc-coverage":"nyc --reporter=html --reporter=text"},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"7.11.2","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.1.0","dependencies":{"url":"^0.11.0","aws-sdk":"^2.906.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.4","nock":"^13.0.11","mocha":"^8.4.0","sinon":"^10.0.0","eslint":"^7.26.0","morgan":"^1.10.0","express":"^4.17.1","artillery":"^1.7.2","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.0.0","express-request-id":"^1.4.1","eslint-plugin-import":"^2.22.1","start-server-and-test":"^1.12.1","artillery-plugin-expect":"^1.3.0","eslint-config-airbnb-base":"^14.2.1"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.5.0_1620941223227_0.4023647388788467","host":"s3://npm-registry-packages"}},"1.5.1":{"name":"s3proxy","version":"1.5.1","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.5.1","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"74e17103081651ec05917e92922f2586342682bb","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.5.1.tgz","fileCount":6,"integrity":"sha512-ObX9/NuAXr/dE5wScTXH589/YI0pfv1d/GS6HlGmuVhl1W2wqbnA49s1i1G31YUQRezPALSacJiIxABHyNylsA==","signatures":[{"sig":"MEUCIBg+7yoSD8fKbtzuorDEq0Cj2SUTJ1dJVsfz5Dt1g9g8AiEA5UgQyFt3PV6m/HRCUghhd4iP/gSDM/F2FEULIFO3+2I=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":31154,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgoxjjCRA9TVsSAnZWagAAxv0P/2LvX+juQYv9hHRsRxRw\np/bz/Jebb/o8TFlsNJJN8R5ewoyKT7OxgzirQHmFiihtI3JdYmtMOypj2l1S\nfLi18VnkiN0jDyyL6WYdBRdFXS27Z0wah5UoOWQb+jVbJu5R/hUxGMn26Gci\nuQE3Ma1vkszfTTNntfddDJ4VEHr1U8ThZwqHNTaIEM4frfsm7QpwZa+0CtyU\nN8OdONQ8RzrtuPjQClkvNDVCcZV6LUIaRCpslGxhk7bQ9XmOX3c3/XDJiTco\nbjdDQn+GjTp2myW4mZ50NlyPk2MHzLu/6DAERccocHS6ztfF2gEKrmwtRbuL\nIgyjqm81erEHXVryr2sv93RLbC5pl94PWFu1Vn6K51uRZvCz6N6+dzf2YQOs\nAjCKYbg1/ELbQod0ftoCecX7PnnLQvIy0rOvGJcZ/Sk3omWbPUNKQh8HsgPe\nw1zbEJWpJE6jghf1iCwIOCESa7W5p/gGOcW+qrnzi2TRwOCJnysB4J8iWL88\nrTS3L1rqMsQxkqd0IdLtg+PxE911WwS5ToFf9CHUEuoQpltUnENOPwjn4eBQ\nL7CqcdSVPfXnPdgQ3wgzO8itxEVrtVz74MdJTOUWYfU7cuqoCCPXqW96zaNc\nXrtYJ6Ztj8uY3rcJGFmO3kEyO0hOWaEg1A9F43g+wJtqLvlydlqtLTm3yxWF\nhQGS\r\n=0Gmu\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"42f4c8eefd1df1c3fce7edb8702dfc95b7d1b954","scripts":{"test":"make test","mocha":"mocha","start":"PORT=3000 node examples/express-basic.js","artillery":"artillery run test/artillery.yml","artillery-ci":"start-server-and-test start :3000 artillery","nyc-coverage":"nyc --reporter=html --reporter=text"},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"7.11.2","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.1.0","dependencies":{"url":"^0.11.0","aws-sdk":"^2.906.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.4","nock":"^13.0.11","mocha":"^8.4.0","sinon":"^10.0.0","eslint":"^7.26.0","morgan":"^1.10.0","express":"^4.17.1","artillery":"^1.7.2","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.0.0","express-request-id":"^1.4.1","eslint-plugin-import":"^2.22.1","start-server-and-test":"^1.12.1","artillery-plugin-expect":"^1.3.0","eslint-config-airbnb-base":"^14.2.1"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.5.1_1621301474414_0.5451223474266875","host":"s3://npm-registry-packages"}},"1.5.2":{"name":"s3proxy","version":"1.5.2","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.5.2","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"e9f74409fa99019d3f762f368b7f0655f141458f","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.5.2.tgz","fileCount":6,"integrity":"sha512-IYe+5MdW8FOh7iOb0PcttVE0cMKMpTKfqH/nxEK4hSY4RkSdTfw3Ko640Lh10o0TpPFSjALC3eQPNMB3UXJD5g==","signatures":[{"sig":"MEUCIHouns3HPZl8w4gZ5Qb6Gg5EkouG//5UA1bIbHkc8WZ/AiEA0MGntzfK8mOwZIY7wy0KQ5p4/YZfukjLswoT4WO+Tg4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":35050,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhKn50CRA9TVsSAnZWagAARLQQAIGegq0g0Zm9yDDQ+B27\nL6Rmo29q9X3V5UeZSSSVHd/QjzwxN4VrRl92FZc6jGFPRrXJnU+lGFEpykaz\nZnUvhEePAg538uLW0B944lgjyjqXKXfnyBSW689v9MwfWa5g93AP617uBJ69\noJaJhkoO4u3054RM/gY69qtBpm3lKw/obn6Pz0p2tBRNaH/vD/prbFPGTOrX\nffpnEgtOgMJB19Cb/sP9yijEGXRTQCE+K3uur9XSDIQh4gtRGRPZddS2cKqU\n0VyAcKLLQrQkPrZ194Tsb55NMmrPPnrnCXNFFrPm7nuVvhqIeRGmsjUGNSDD\nu/ZRqKfLJMvHLkfX0UCtK20/ZTYo28de0srAb0IXwEI5Z/LzTOhInZeeGg1r\nSyMoo4UsaVhlBmmcQp3hZwXobrn+pkRu6oLXJEp2DtIT2IZrqpL/XnLUQgCJ\nNP7EK7yViKkbxv84uoBDBRariGWNBxI3cSbMZQccC9Kg6UDb1E8grLJT0p7g\nXhT95Pa9mQ7u1JHnYgroAfFePEM6e7XXzlzuZbbD+XWp77nZ3OakE4+qyFvX\nqfO+O8n9ttZmFA2OlQcWVr/Uysw8En3XiP4KPB1ErJmoNVQCyINtJdh1bGZt\nf7DOGqfW/nFC/uM2k07lycQlLFqrGzdZ10XzSTkKzuuJvPyYYYnm/YztG1GM\nTZIg\r\n=EsBg\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"c4793f37be667ecc285218c76b8ad3c3a4872b07","scripts":{"test":"npm run eslint && npm run nyc-coverage mocha && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha","start":"PORT=8080 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","artillery":"artillery run --config test/artillery-config-quick.yml test/artillery.yml","credentials":"aws sts get-session-token --duration 900 > credentials.json","artillery-ci":"start-server-and-test start :8080 artillery","nyc-coverage":"nyc --reporter=html --reporter=text","artillery-docker":"npm run dockerize-for-test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","dockerize-for-test":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --target test --load -t s3proxy:test .","artillery-performance":"artillery run --quiet --output artillery.json --config test/artillery-config-performance.yml test/artillery.yml && artillery report --output artillery.html artillery.json","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"7.21.1","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.1.0","dependencies":{"url":"^0.11.0","aws-sdk":"^2.978.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.4","nock":"^13.1.3","mocha":"^9.1.1","sinon":"^11.1.2","eslint":"^7.32.0","helmet":"^4.6.0","morgan":"^1.10.0","express":"^4.17.1","wait-on":"^6.0.0","artillery":"^1.7.7","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.0.0","express-request-id":"^1.4.1","eslint-plugin-import":"^2.24.2","start-server-and-test":"^1.13.1","artillery-plugin-expect":"^1.5.0","eslint-config-airbnb-base":"^14.2.1"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.5.2_1630174836384_0.42253673371544065","host":"s3://npm-registry-packages"}},"1.6.0":{"name":"s3proxy","version":"1.6.0","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.6.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"927e05ac11884525a724da49c76a279a829ef202","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.6.0.tgz","fileCount":6,"integrity":"sha512-XP+QtTFPhomUOim52UYF2yIlD/81p8K9SoBawmPjReRYIcdEHUD63PByeed8xTGwgcOaTHUp086EAcHXB3cbqA==","signatures":[{"sig":"MEUCIFxKtsfUqcn4DVzLTdP7rbAUr9WGpR32LgVdUTUitY+PAiEA8gQjTB9Oki7JjeanguQcR/4vCxSuHoUCnqniDXEMr+E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":36532,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhMshfCRA9TVsSAnZWagAAH8MP+gN3fwiW7/6YnvC5GD7H\n0SfD6noECvExpxsrOAzZnjREp3eI2DVpB3ba78TnNR5Kkre+8NKyfU//+jJU\n+EDGqAlptk5BJDhADPSm72rUgIXCUqItcBVBO1Hkwx6tIS0yLT5/9byiaW+P\n0LvAiazk7XkLUYrE1X9k5nFlEQsqxFtdaxrl5mnJqnXKt7TOrgo5rxRE0eQA\nALQediVRrNH3om1wwtRXJEhrhYB/jVSBAi+Zc4OWVOOCW22+0sWoCxE8dFJa\nk1c61ehugMKIqEvhs7QZJdXEGg9Wq4yIr5T03dtTJXt5RrakotBUyF7GWXm5\nUkFpOkJVaRt0bCQiW/SutXHWovhypWveGeNbjQir4v0h8YxPdtkfGV6giZlp\njM7JJYMXxXkzjle5X3/y3RBTPYz9Q6SvmKawN8CXgcRN6t8/wibch1Wmhy06\n9IEEAhcnvz7H55L8D8cupvI02OY5/nz2zkFfpejOuBrg12nhvwGCf2xniC91\n7p5Bxx3dXnO7Du9B5JxNC8ovzkfK1VDxvfZzQI2FbNk+pKMB1WBS0+gswKBY\nFH9nY8eEx7dqy2CQO8Fsx8EK8iX+YF4YuXMnXVFjwdGBGx+s/cIxjY3MCbmS\nuEtBsUWJVg9dCp5Z2WiVbzmWrxddsI5N8g9hzZEsuSwoDlhawrZGHJV61i02\nsVui\r\n=Yq5u\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"fa148dd66a94966dd9d34d8b55f88578aad1feba","scripts":{"test":"npm run eslint && npm run nyc-coverage mocha && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha","start":"PORT=8080 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","artillery":"artillery run --config test/artillery-config-quick.yml test/artillery.yml","credentials":"aws sts get-session-token --duration 900 > credentials.json","artillery-ci":"start-server-and-test start :8080 artillery","nyc-coverage":"nyc --reporter=html --reporter=text","artillery-docker":"npm run dockerize-for-test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","dockerize-for-test":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --target test --load -t s3proxy:test .","artillery-performance":"artillery run --quiet --output artillery.json --config test/artillery-config-performance.yml test/artillery.yml && artillery report --output artillery.html artillery.json","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"7.21.1","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.1.0","dependencies":{"url":"^0.11.0","aws-sdk":"^2.983.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.4","nock":"^13.1.3","mocha":"^9.1.1","sinon":"^11.1.2","eslint":"^7.32.0","helmet":"^4.6.0","morgan":"^1.10.0","express":"^4.17.1","wait-on":"^6.0.0","artillery":"^1.7.8","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.0.0","express-request-id":"^1.4.1","eslint-plugin-import":"^2.24.2","start-server-and-test":"^1.14.0","artillery-plugin-expect":"^1.5.0","eslint-config-airbnb-base":"^14.2.1"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.6.0_1630718047672_0.18577357084692037","host":"s3://npm-registry-packages"}},"1.6.1":{"name":"s3proxy","version":"1.6.1","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.6.1","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"8e42f4e11ea35115592b7a0237f61a5d9b020c30","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.6.1.tgz","fileCount":6,"integrity":"sha512-p28r1Amsp9n0sxd7A426AUUi8j8erjbnbwb1GTRldnL3SwaGL03bdCi5UYJYRBUO4XXx7g19svY5Na73Z/g9Yg==","signatures":[{"sig":"MEUCIQCl8WDPTLOaPWIAfVUASn8+4BHTrnmY1gUXeEdDzx88CwIgRj16YeSgoSl2l4efWRO4fLbzBfOSd/lKMqNbTdHf5A8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37063,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhN9Z3CRA9TVsSAnZWagAA/UUP/3WIyipxRTfDbkb5jsnr\n7TX5snCk2BRrfzm7y1wYABbx3gvYpPJBHUDvfWWRcsuCBRcBY5fCU4x+y9cF\nPuKKlfC+phbRzA3aHI8fWs/gU6+Yl5/KWxEIQav98Lq5jjvR8BMzLG4Y1dPr\nY9dhQZK6An6CyTAvYLrrWciT61FEk/akw849GuutCZYG61ndvefe1N9GE039\n+u8D9nvEig4yi+pCiquyZOScSixB0g2omdDjqgjtWkQZ2zCCYMv7z4WASAL2\n8aHuDNuOpzWRiycaTdeCP/d6Lus5FYFUODpGnhhNDqjuhz/qflu8dGPFl9l4\nSwYwYHTdtNQZxfVxjXQPFbZADD2BrDnPGEsmtfUixTBKlQx9JkhzYtpGgNbA\ne6HUesw9KvrR786FWCcVUleL8xCDElFQ7qodW6ZAkU+VRNdsUg2WhfPrPi1f\nXb6KHR0Jq8Jay2eGqNF3mNmq1bLBOREykCMBfd8BtUENt62/UoT2oQV63s1F\nLIDlEsJFv1fYQPB54MrzvVRMR4+CUThKAdsJtjgoj4a0p65jstcG6HtDJF42\nnL4kWD03pybbWeBIpZns39cueCYJtb8NpTdjkt/e6VFlWErXSOaoFO1CqZv5\nXGqIo/IFk84ABPkO1kJFf9k1+IW1ZhtqbqCsUzn3aNRBXrxA4VA0+l5vZ/DW\nx48Y\r\n=D4gI\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"3cbb171356c3d1da9f831dcb3b9eacc0789560da","scripts":{"test":"npm run eslint && npm run nyc-coverage mocha && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha","start":"PORT=8080 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","artillery":"artillery run --config test/artillery-config-quick.yml test/artillery.yml","credentials":"aws sts get-session-token --duration 900 > credentials.json","artillery-ci":"start-server-and-test start :8080 artillery","nyc-coverage":"nyc --reporter=html --reporter=text","artillery-docker":"npm run dockerize-for-test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","dockerize-for-test":"npm run package && cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --target test --load -t s3proxy:test .","artillery-performance":"artillery run --quiet --output artillery.json --config test/artillery-config-performance.yml test/artillery.yml && artillery report --output artillery.html artillery.json","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"7.21.1","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.1.0","dependencies":{"url":"^0.11.0","aws-sdk":"^2.983.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.4","nock":"^13.1.3","mocha":"^9.1.1","sinon":"^11.1.2","eslint":"^7.32.0","helmet":"^4.6.0","morgan":"^1.10.0","express":"^4.17.1","wait-on":"^6.0.0","artillery":"^1.7.8","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.0.0","express-request-id":"^1.4.1","eslint-plugin-import":"^2.24.2","start-server-and-test":"^1.14.0","artillery-plugin-expect":"^1.5.0","eslint-config-airbnb-base":"^14.2.1"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.6.1_1631049335700_0.35931193574726294","host":"s3://npm-registry-packages"}},"1.6.2":{"name":"s3proxy","version":"1.6.2","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.6.2","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"8a9cf50b0883faede3297e3a9800f354ef7ec609","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.6.2.tgz","fileCount":6,"integrity":"sha512-i4zD6Pp7fMGXBoJobLRQ/I2WKk4RnXeAQeIybKRPnpKLJySjNXmLd0k9SCbOHXKm6O5jHnxZ3bR3S3fmBC+FIA==","signatures":[{"sig":"MEUCIFQRIECK2oGv3zg9CpVMMHw70gxS7nHe0gH9fO+qatMPAiEAm9rAFy9eM2JPgDLQpN+ZyC+J9eMdkVroCn5pnZK7AHk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37556},"main":"index.js","gitHead":"5161a9f05112479917a68410b7ce87d31cb342c6","scripts":{"test":"npm run eslint && npm run nyc-coverage mocha && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha","start":"PORT=8080 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","credentials":"aws sts get-session-token --duration 900 > credentials.json","artillery-ci":"start-server-and-test start :8080 artillery-local","nyc-coverage":"nyc --reporter=html --reporter=text","artillery-ecs":"artillery run --config test/artillery-config-quick-ecs.yml test/artillery.yml","artillery-apigw":"artillery run --config test/artillery-config-quick-apigw.yml test/artillery.yml","artillery-local":"artillery run --config test/artillery-config-quick-local.yml test/artillery.yml","artillery-docker":"npm run dockerize-for-test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery-local; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","artillery-perf-ecs":"artillery run --config test/artillery-config-perf-ecs.yml test/artillery.yml","dockerize-for-test":"npm run package && cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --target test --load -t s3proxy:test .","artillery-perf-apigw":"artillery run --config test/artillery-config-perf-apigw.yml test/artillery.yml","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","software-bill-of-materials":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --load --target production -t forkzero/s3proxy:$npm_package_version . && syft forkzero/s3proxy:$npm_package_version","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"8.1.0","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.1.0","dependencies":{"url":"^0.11.0","aws-sdk":"^2.1008.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.4","nock":"^13.1.3","mocha":"^9.1.2","sinon":"^11.1.2","eslint":"^8.0.1","helmet":"^4.6.0","morgan":"^1.10.0","express":"^4.17.1","wait-on":"^6.0.0","artillery":"^1.7.9","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.0.0","express-request-id":"^1.4.1","eslint-plugin-import":"^2.25.2","start-server-and-test":"^1.14.0","artillery-plugin-expect":"^1.5.0","eslint-config-airbnb-base":"^14.2.1"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.6.2_1634261951150_0.36232225479777336","host":"s3://npm-registry-packages"}},"1.6.3":{"name":"s3proxy","version":"1.6.3","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.6.3","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"2830d6ab8622050e33bff6d370926e9a9c1390e9","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.6.3.tgz","fileCount":6,"integrity":"sha512-OnJLpw3OcOZkn323/ilrv3qQ5NDOVj7ZimG2vquAYbUSh2bqIGutPXXNTGo1li07XSe5WqVx0JhTXHj64fSHVQ==","signatures":[{"sig":"MEUCIBPLjQKcc7YLWb1WwvYdQcjgi5WSN95taBCMHH/rKtyzAiEAmDhb2kAUE/1AEh72DL/YPAykbYbHyw8H+eNmuvNOIuw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37883,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh04XoCRA9TVsSAnZWagAAmT0QAI7NJNfyM6KNWlVdNUmk\nVc2mKL+E/0U8KAXPd35q7FTFZsCku+5bp+G9+N92obOlbDrjT7aVimTz5SUI\nNL0hqUmFFV92ghDZ67gg6f1Oa5wK8UaLxn4gahVTO1ohZbX4+YFPF1d/rbiW\nV5YRk/L8M/ABvHbGlwHvw8NLQXvPTyXs1QbySg0ym7uXUUvIrhZLnrW0PZTa\nLdaq9NbRuqZmnU8X2acE12MADVH816gzTyVowclFjx0oTrZRy2uufdM/x7+J\ni6Ed9FqUZ1LTif4/FDw0/dSBjXFyMDi/tmc0EYvJIDLnGggwZRkQGHY+bS3j\nLRz8MMHB9qFoyn1lgz59I0qbxe0BjGlxu9MfdpP0UXO+vLIHvKBLp38I74le\nB/HOVGx+XOpBwgUuhTM4hpGzxDOGous/cXvq5PMpRsvDJXQB8HmUSwa+0g+H\nimOcFBkGPsNbLIL7Eo2kk8IcnZI/u8L+JzoCK95glIuK8bYdX9RVag6Ez+lp\nalMKbWhQEMPdBjPAjHBuUVu6DcoRzJmaqO3SnjdlPlSV5T3vhl//9b/+kBHo\nobPGNHy6C9PaN/gVm5qMq80FtVx3GDYQHy5Pm0Ft81Z6fMGasrhPNUdkfzzN\nGWFlBo6lvSm+WT2pLn3+6xkKwBj1wV9Qh90wketipuokf/ANK0pz/zwQtMsk\nHI0y\r\n=ULxF\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"b4955aae6c129173e88a205bb29f2f1a1ae45c53","scripts":{"test":"npm run eslint && npm run nyc-coverage mocha && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha --reporter mocha-junit-reporter","start":"PORT=3000 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","credentials":"aws sts get-session-token --duration 900 > credentials.json","ncu-upgrade":"ncu --upgrade","artillery-ci":"start-server-and-test start :3000 artillery-local-3000","nyc-coverage":"MOCHA_FILE=test-results/mocha-junit.xml nyc --reporter=html --reporter=text mocha --reporter mocha-junit-reporter","artillery-ecs":"artillery run --target https://s3proxy.forkzero.com --config test/artillery-config-quick.yml test/artillery.yml","artillery-docker":"npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery-local-8080; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","artillery-perf-ecs":"artillery run --config test/artillery-config-perf-ecs.yml test/artillery.yml","dockerize-for-test":"npm run package && cd examples/docker && docker buildx build --progress plain --build-arg VERSION=$npm_package_version --target test --load -t s3proxy:test .","artillery-local-3000":"artillery run --target http://localhost:3000 --config test/artillery-config-quick.yml test/artillery.yml","artillery-local-8080":"artillery run --target http://localhost:8080 --config test/artillery-config-quick.yml test/artillery.yml","artillery-perf-apigw":"artillery run --config test/artillery-config-perf-apigw.yml test/artillery.yml","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","software-bill-of-materials":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --load --target production -t forkzero/s3proxy:$npm_package_version . && syft forkzero/s3proxy:$npm_package_version","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"8.3.0","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.1.0","dependencies":{"url":"^0.11.0","aws-sdk":"^2.1049.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.4","nock":"^13.2.1","mocha":"^9.1.3","sinon":"^12.0.1","eslint":"^8.6.0","helmet":"^5.0.1","morgan":"^1.10.0","express":"^4.17.2","wait-on":"^6.0.0","artillery":"^1.7.9","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.0.0","npm-check-updates":"^12.1.0","express-request-id":"^1.4.1","eslint-plugin-import":"^2.25.4","mocha-junit-reporter":"^2.0.2","start-server-and-test":"^1.14.0","artillery-plugin-expect":"^1.5.0","eslint-config-airbnb-base":"^15.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.6.3_1641252328794_0.6883791719941386","host":"s3://npm-registry-packages"}},"1.6.4":{"name":"s3proxy","version":"1.6.4","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.6.4","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"fbc6e23e453ce2831c648174d40558071c8ae7ca","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.6.4.tgz","fileCount":6,"integrity":"sha512-/ZpUV9/veAP1s5h4I1/nAH8xWO9qmilg3PKXahb+MKczSJa7hkQecP1/NAohrwNyXg44i4AgAT7XHyJ/8oKSig==","signatures":[{"sig":"MEYCIQDKInEDGrGYe9HZ4bLI+SWGj7ue59EHYDckik/ao+PFZQIhAObCqjD5smXX+Uoka6TtmRhFX3NGflqxGx17Uwjn740j","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37868,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjAUs3ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrBXhAAkcgFUilo1j0Mqhu05iKdVXeovo7sC9USKa3QeldoLGjwsflW\r\n9CWqd9uZEVzQjId+F+P62Yp9UfBX817KutPgqkZ5mX2nxpVAn6mMaOOCYUoN\r\nFWucddp+8xfypp+U3T53BzQyuRGL0P5HkI/pdTVHBiHqMr+Wd+sYGdjtuDuq\r\nsWYkhQoHWJvQUaDD4avN8dlF/QKuQpE9tLq6iojuNWHEbcYewXK5/ndGAZ2n\r\nF1q5irDE0gBCBpT7BsZKaZIJHLN3lJiYJcDcifAuup/I2f/8jb30YqtQHcuo\r\nh1bQ4e06fRPU0dxSl4tYewhgUebtb8y7EfDidJkEU/E8zpVDD+rW/YD8iO0v\r\nSmDCWFK4zCbbXr88wadf4uvywEzTNadDTceAm2ul38C+uSieC+8Mq1ZEPUQt\r\nY/EbWWkj5f94Qksz4j9qzPQtXgKb2vwwwalLceUYoWFQij0js7NbBo8Q4+v+\r\nEoz0WJkPBoz+mao+eOkrLUaVq9U8N7Jtoo/vBtIJeagM4a5DXR83gpQp71Vn\r\noAokQsSbS+AU1SP+Uv7I6ny+9WEjUUe0H6qgGj8sIZYptOrmgvuCUSHP7ECy\r\nOQJeWdUEWOP59jWaNypuwB0mQOK5wgHeji8V/AGZ5iR+Pvp6Hs4ECZ5dNRLS\r\noMJ6gWkSKUutNnQzy6ESRF7C4LYA/f8cJLY=\r\n=atf2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"ba1125cdf1530b1babacfe49cea43e03a6019f5d","scripts":{"test":"npm run eslint && npm run nyc-coverage && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha --reporter mocha-junit-reporter","start":"PORT=3000 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","credentials":"aws sts get-session-token --duration 900 > credentials.json","ncu-upgrade":"ncu --upgrade","artillery-ci":"start-server-and-test start :3000 artillery-local-3000","nyc-coverage":"MOCHA_FILE=test-results/mocha-junit.xml nyc --reporter=html --reporter=text mocha --reporter mocha-junit-reporter","artillery-ecs":"artillery run --target https://s3proxy.forkzero.com --config test/artillery-config-quick.yml test/artillery.yml","artillery-docker":"npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery-local-8080; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","artillery-perf-ecs":"artillery run --config test/artillery-config-perf-ecs.yml test/artillery.yml","dockerize-for-test":"npm run package && cd examples/docker && docker buildx build --progress plain --build-arg VERSION=$npm_package_version --load -t s3proxy:test .","artillery-local-3000":"artillery run --target http://localhost:3000 --config test/artillery-config-quick.yml test/artillery.yml","artillery-local-8080":"artillery run --target http://localhost:8080 --config test/artillery-config-quick.yml test/artillery.yml","artillery-perf-apigw":"artillery run --config test/artillery-config-perf-apigw.yml test/artillery.yml","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","software-bill-of-materials":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --load --target production -t forkzero/s3proxy:$npm_package_version . && syft forkzero/s3proxy:$npm_package_version","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"8.18.0","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.1.0","dependencies":{"url":"^0.11.0","aws-sdk":"^2.1199.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.6","nock":"^13.2.9","mocha":"^10.0.0","sinon":"^14.0.0","eslint":"^8.22.0","helmet":"^5.1.1","morgan":"^1.10.0","express":"^4.18.1","wait-on":"^6.0.1","artillery":"^1.7.9","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.1.1","npm-check-updates":"^16.0.5","express-request-id":"^1.4.1","eslint-plugin-import":"^2.26.0","mocha-junit-reporter":"^2.0.2","start-server-and-test":"^1.14.0","artillery-plugin-expect":"^2.1.0","eslint-config-airbnb-base":"^15.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.6.4_1661029175687_0.5809940110974399","host":"s3://npm-registry-packages"}},"1.6.5":{"name":"s3proxy","version":"1.6.5","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@1.6.5","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"ee2941e161454d9ffcbff3791007099b5649b99b","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-1.6.5.tgz","fileCount":6,"integrity":"sha512-d8w+rpbrwsWYvLb9r5NLX/n7CpcGzhh5/aBYdIgvxeQ1tNpRlceL8FZHkm7z8hgc4p25r5Fu0d2uQ3iDmtwHaA==","signatures":[{"sig":"MEYCIQCVlDupGJXfNSunaHUWXTBpX+gFHyWdi58IPRv35mOe8gIhAISlnN1awHKQNSA2C/zyUzi22gUMJf+tdPf7XCmNT5r2","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":38059,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjxG3OACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq96w//bMlSTFBrQSqbLNVJ7oQ94gmwuAy2El+ZvKA927Y0oUfC630O\r\nH4/Cnh9XEKRazZKh1OfHNsXqBNcfeAACTzlTsruTl45MI5+Dy+hKBZtfvLWw\r\nNYY+gNfoPSHFlAbdwc2hfVuLr78gpst4WjXNcWWsu/OoICsk/p6n2/2rzew5\r\nmGGtD24YE6eT86U+HxcMt+FhbflUs6AakAVsNw+Q1OU1OQNg0RL8+NzQjZ0x\r\nrQ9V+NxBt0tjGDz+upUNyMCHE6fDYDuU44f162i0/BqqCR25gYfV6lPZf5SG\r\nRnJ8ClL0wp9LI4gcMjUow4wOwO0eVjzxF2TaP7Sekl7WYoDJ81D+jNL8ZgOm\r\noJzPcPveNCyfxNFkZQErQCeTXX0iRPq697WQzyjSmhZBtbbNeyY2zZGaef+L\r\nagYXLDmohII5rHPlaTfgQ2Vjcbh8nWs0wINBqE46LePeBFHr00Pzz+Cz1k4t\r\nrf/lmj9FMAgxlaqVoeNO8rMMzc/nyUQ1IzEmLWfX+0zrMP6SwTyaR1RQzpXM\r\ns0K3ruvZ6HmQhGdHxE9dWjUBew4ETX12MWAck75fVEX/tWAi9k070A1ig+x/\r\nMa4OEtnF81x/ix4nkzZKejQaIUGl1K2LNbTCHdvzUO7hpbIYVU/H9dNRMcyQ\r\nE2YbFw0KyL5zt5HEFwY9NRLVEc1pelD8T+Y=\r\n=KWJe\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"ca4d9147d5d0d9730911f09ae1a8e4279461a2c0","scripts":{"test":"npm run eslint && npm run nyc-coverage && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha --reporter mocha-junit-reporter","start":"PORT=3000 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","credentials":"aws sts get-session-token --duration 900 > credentials.json","ncu-upgrade":"ncu --upgrade","artillery-ci":"start-server-and-test start :3000 artillery-local-3000","nyc-coverage":"MOCHA_FILE=test-results/mocha-junit.xml nyc --reporter=html --reporter=text mocha --reporter mocha-junit-reporter","artillery-ecs":"artillery run --target https://s3proxy.forkzero.com --config test/artillery-config-quick.yml test/artillery.yml","artillery-docker":"npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery-local-8080; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","artillery-perf-ecs":"artillery run --config test/artillery-config-perf-ecs.yml test/artillery.yml","dockerize-for-test":"npm run package && cd examples/docker && docker buildx build --progress plain --build-arg VERSION=$npm_package_version --load -t s3proxy:test .","artillery-local-3000":"artillery run --target http://localhost:3000 --config test/artillery-config-quick.yml test/artillery.yml","artillery-local-8080":"artillery run --target http://localhost:8080 --config test/artillery-config-quick.yml test/artillery.yml","artillery-perf-apigw":"artillery run --config test/artillery-config-perf-apigw.yml test/artillery.yml","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","software-bill-of-materials":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --load --target production -t forkzero/s3proxy:$npm_package_version . && syft forkzero/s3proxy:$npm_package_version","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"9.3.0","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.17.0","dependencies":{"url":"^0.11.0","aws-sdk":"^2.1295.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.7","nock":"^13.3.0","mocha":"^10.2.0","sinon":"^15.0.1","eslint":"^8.31.0","helmet":"^6.0.1","morgan":"^1.10.0","express":"^4.18.2","wait-on":"^7.0.1","artillery":"^1.7.9","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.1.1","npm-check-updates":"^16.6.2","express-request-id":"^1.4.1","mega-linter-runner":"^6.18.0","eslint-plugin-import":"^2.27.4","mocha-junit-reporter":"^2.2.0","start-server-and-test":"^1.15.2","artillery-plugin-expect":"^2.1.0","eslint-config-airbnb-base":"^15.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_1.6.5_1673817550794_0.05170795179030274","host":"s3://npm-registry-packages"}},"2.0.0":{"name":"s3proxy","version":"2.0.0","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@2.0.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"2d2555665bc67a66d04e85d4638b0e3af232ab98","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-2.0.0.tgz","fileCount":5,"integrity":"sha512-b2Mm2jmrF3gne/a9tzkZRFRfmv9ydh9ZwEIwVhowfhfiNIpm63HCVyAxh82qtcVSAUz21nfqHDIw5Mq4vrQ5Ug==","signatures":[{"sig":"MEQCIEkPbjS373XSL3cM+ekr2Wf21uTWr9p56+u5F77GlpCwAiA/GMonLkJfnF90uOhqT4C2kyxO4CIjOveoma8g8l60qg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37749,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkTb2wACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq9YQ/+OtXZxVbpd5C1/ag8tc2IHMcmpWXucZ1i+RqoFmy7O1ovq7zy\r\nHoC2eqykwkqLiv8XO5orqwrOjrStQ9PtDGObGg0PfN+YUIX+zcBw1NkaswIY\r\n3WvGGUNluomh4OTfnQt6MwkP3FetKoHAgWWv9MuE/+MtVfCQ9hzbAxl3tdKu\r\nA6AyVgVnd4C/gMyQyYbnTqoyLdRRqAueRm1mEz4Eef+NF0+EGXO2XNN4gpE7\r\nJBV9uJ/V55ove9TlWN9joFUbBwq5qJh+9qlcfQ8mveUMm56YytxDzdFV5Gp2\r\nAQrZpV8gH0IztDYwywD85raM/I7CGPMntWX+kSF7WH5Rq/+V8JtYcKNN9Smy\r\n3xHVCqdxq1hW25dk/JzmSoGH/ABA8a/Tgqep9XTrvvVCblU0Wazzv7L+TftC\r\njOnCwDdX3F9CZcVCOtpTnVaxFXwilxl2EmkjYx8UqXaWdN1eBNfEjT4ClV8E\r\nBOrbhORT91W/nP6bpsngI0SKXsvrVY1W8ogg4Mp+L335/yOw7rff7TSHAiM4\r\nfzL/Ls6oJzKfmwdB5K9t4mzIm3lx5E3/bOMTD3DF09vWELFqV9yEU89jjNaX\r\nYMokTCHNrZpPruggAaKScvZu0XC0dbRRx1kMizM37bCAvf26cdeIj0EcDGcH\r\nNn35XWjTaitEGxv6yyL7v/12j1gHXnqPzCo=\r\n=z7WT\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"776462a54622a22d6b038a419062ed03a8063d8b","scripts":{"test":"npm run eslint && npm run nyc-coverage && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha --reporter mocha-junit-reporter","start":"PORT=3000 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","eslint-fix":"eslint --fix *.js examples/*.js","credentials":"aws sts get-session-token --duration 900 > credentials.json","ncu-upgrade":"ncu --upgrade","artillery-ci":"start-server-and-test start :3000 artillery-local-3000","nyc-coverage":"MOCHA_FILE=test-results/mocha-junit.xml nyc --reporter=html --reporter=text mocha --reporter mocha-junit-reporter","artillery-ecs":"artillery run --target https://s3proxy.forkzero.com --config test/artillery-config-quick.yml test/artillery.yml","artillery-docker":"npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery-local-8080; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","artillery-perf-ecs":"artillery run --config test/artillery-config-perf-ecs.yml test/artillery.yml","dockerize-for-test":"npm run package && cd examples/docker && docker buildx build --progress plain --build-arg VERSION=$npm_package_version --load -t s3proxy:test .","artillery-local-3000":"artillery run --target http://localhost:3000 --config test/artillery-config-quick.yml test/artillery.yml","artillery-local-8080":"artillery run --target http://localhost:8080 --config test/artillery-config-quick.yml test/artillery.yml","artillery-perf-apigw":"artillery run --config test/artillery-config-perf-apigw.yml test/artillery.yml","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","software-bill-of-materials":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --load --target production -t forkzero/s3proxy:$npm_package_version . && syft forkzero/s3proxy:$npm_package_version","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"9.6.5","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.17.0","dependencies":{"url":"^0.11.0","@aws-sdk/client-s3":"^3.321.1"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.7","nock":"^13.3.1","mocha":"^10.2.0","sinon":"^15.0.4","eslint":"^8.39.0","helmet":"^6.1.5","morgan":"^1.10.0","express":"^4.18.2","wait-on":"^7.0.1","artillery":"^1.7.9","benchmark":"^2.1.4","chai-http":"^4.3.0","microtime":"^3.1.1","npm-check-updates":"^16.10.9","express-request-id":"^1.4.1","mega-linter-runner":"^6.22.2","eslint-plugin-import":"^2.27.5","mocha-junit-reporter":"^2.2.0","start-server-and-test":"^2.0.0","artillery-plugin-expect":"^2.2.1","eslint-config-airbnb-base":"^15.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_2.0.0_1682816432360_0.7507085310195385","host":"s3://npm-registry-packages"}},"2.0.1":{"name":"s3proxy","version":"2.0.1","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@2.0.1","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"893c5da8c76501df2a785c258641073b87b9bead","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-2.0.1.tgz","fileCount":5,"integrity":"sha512-kMvbeoFo4UQftmu0/AMHjd2gE1cfCj+oQMXZ1/FqOktgiAqSUPtEl6xGvfUexWaYBsMML5Vo3NQOvq/gZR9eOg==","signatures":[{"sig":"MEUCIGdtffiYJLWT3UXj9dSEFDuR9PtTsyvLWn+52fF19xsBAiEArW9IdyCI+5Qk04YgyuiwQrdmQxx/dhpHeQzB7WJgWro=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37816},"main":"index.js","gitHead":"2b4560c303d13006fcca6a149154baac64969934","scripts":{"test":"npm run eslint && npm run nyc-coverage && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha --reporter mocha-junit-reporter","start":"PORT=3000 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -e AWS_REGION=us-east-1 -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","eslint-fix":"eslint --fix *.js examples/*.js","credentials":"aws sts get-session-token --duration 900 > credentials.json","ncu-upgrade":"ncu --upgrade","artillery-ci":"start-server-and-test start :3000 artillery-local-3000","nyc-coverage":"MOCHA_FILE=test-results/mocha-junit.xml nyc --reporter=html --reporter=text mocha --reporter mocha-junit-reporter","artillery-ecs":"artillery run --target https://s3proxy.forkzero.com --config test/artillery-config-quick.yml test/artillery.yml","artillery-docker":"npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e AWS_REGION=us-east-1 -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery-local-8080; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","artillery-perf-ecs":"artillery run --config test/artillery-config-perf-ecs.yml test/artillery.yml","dockerize-for-test":"npm run package && cd examples/docker && docker buildx build --progress plain --build-arg VERSION=$npm_package_version --load -t s3proxy:test .","artillery-local-3000":"artillery run --target http://localhost:3000 --config test/artillery-config-quick.yml test/artillery.yml","artillery-local-8080":"artillery run --target http://localhost:8080 --config test/artillery-config-quick.yml test/artillery.yml","artillery-perf-apigw":"artillery run --config test/artillery-config-perf-apigw.yml test/artillery.yml","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","software-bill-of-materials":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --load --target production -t forkzero/s3proxy:$npm_package_version . && syft forkzero/s3proxy:$npm_package_version","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"9.6.6","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"16.17.0","dependencies":{"url":"^0.11.1","@aws-sdk/client-s3":"^3.405.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","chai":"^4.3.8","nock":"^13.3.3","mocha":"^10.2.0","sinon":"^15.2.0","eslint":"^8.48.0","helmet":"^7.0.0","morgan":"^1.10.0","express":"^4.18.2","wait-on":"^7.0.1","artillery":"^2.0.0-36","benchmark":"^2.1.4","chai-http":"^4.4.0","microtime":"^3.1.1","npm-check-updates":"^16.13.2","express-request-id":"^1.4.1","mega-linter-runner":"^7.3.0","eslint-plugin-import":"^2.28.1","mocha-junit-reporter":"^2.2.1","start-server-and-test":"^2.0.0","artillery-plugin-expect":"^2.3.2","eslint-config-airbnb-base":"^15.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_2.0.1_1693832470812_0.2926503470421322","host":"s3://npm-registry-packages"}},"2.0.2":{"name":"s3proxy","version":"2.0.2","keywords":["aws","s3","proxy","node","nodejs","http","express"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@2.0.2","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"c1fbe01d03a32371953707db29da955b5722a771","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-2.0.2.tgz","fileCount":5,"integrity":"sha512-Cn6xstcMDSnbDHgWq6w+zHJcY/Z5yoBl2Jttja5ieGExZBH0Wjssc/QCUUFD8lOETW9kN0Eaz2pn+o5ljfY4RQ==","signatures":[{"sig":"MEUCIB+RKzK7JX1FrYAKycCEXTmP4lz3Muxl1wCSFWOx+8NSAiEA5+hjAhLxZbNE3ZiVFDve0UsR2OLFt5Tein4EZNkQJsQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":37878},"main":"index.js","gitHead":"96a953d35a92d0eaef21a889ba6b1ba5bb928112","scripts":{"test":"npm run eslint && npm run nyc-coverage && npm run artillery-ci && npm run package && npm run artillery-docker","mocha":"mocha --reporter mocha-junit-reporter","start":"PORT=3000 node examples/express-basic.js","docker":"echo running s3proxy:test && npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro -p 8080:8080 -e BUCKET=s3proxy-public -e AWS_REGION=us-east-1 -t s3proxy:test; rm credentials.json","eslint":"eslint *.js examples/*.js","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","package":"npm pack && mv s3proxy-*.tgz examples/docker/","eslint-fix":"eslint --fix *.js examples/*.js","credentials":"aws sts get-session-token --duration 900 > credentials.json","ncu-upgrade":"ncu --upgrade","artillery-ci":"start-server-and-test start :3000 artillery-local-3000","nyc-coverage":"MOCHA_FILE=test-results/mocha-junit.xml nyc --reporter=html --reporter=text mocha --reporter mocha-junit-reporter","artillery-ecs":"artillery run --target https://s3proxy.forkzero.com --config test/artillery-config-quick.yml test/artillery.yml","artillery-docker":"npm run credentials && docker run -v $PWD/credentials.json:/src/credentials.json:ro --rm --name s3proxy-test -d -p 8080:8080 -e BUCKET=s3proxy-public -e AWS_REGION=us-east-1 -e PORT=8080 -t s3proxy:test && wait-on http://localhost:8080/index.html && npm run artillery-local-8080; docker kill s3proxy-test","docker-login-aws":"aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com","artillery-perf-ecs":"artillery run --config test/artillery-config-perf-ecs.yml test/artillery.yml","dockerize-for-test":"npm run package && cd examples/docker && docker buildx build --progress plain --build-arg VERSION=$npm_package_version --load -t s3proxy:test .","artillery-local-3000":"artillery run --target http://localhost:3000 --config test/artillery-config-quick.yml test/artillery.yml","artillery-local-8080":"artillery run --target http://localhost:8080 --config test/artillery-config-quick.yml test/artillery.yml","artillery-perf-apigw":"artillery run --config test/artillery-config-perf-apigw.yml test/artillery.yml","docker-login-dockerhub":"docker login --username ${DOCKERHUB_USER} --password ${DOCKERHUB_ACCESS_TOKEN}","dockerize-for-prod-aws":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:latest -t ${AWS_ACCOUNT}.dkr.ecr.us-east-1.amazonaws.com/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 .","software-bill-of-materials":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --load --target production -t forkzero/s3proxy:$npm_package_version . && syft forkzero/s3proxy:$npm_package_version","dockerize-for-prod-dockerhub":"cd examples/docker && docker buildx build --build-arg VERSION=$npm_package_version --push --target production -t forkzero/s3proxy:$npm_package_version --platform=linux/amd64,linux/arm64 ."},"_npmUser":{"name":"gmoon","email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"11.0.0","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"23.6.0","dependencies":{"url":"^0.11.1","@aws-sdk/client-s3":"^3.405.0"},"_hasShrinkwrap":false,"devDependencies":{"nyc":"^15.1.0","url":"^0.11.4","chai":"^4.5.0","nock":"^13.5.6","mocha":"^10.8.2","sinon":"^15.2.0","eslint":"^8.57.1","helmet":"^7.2.0","morgan":"^1.10.0","express":"^4.21.2","wait-on":"^7.2.0","artillery":"^2.0.21","benchmark":"^2.1.4","chai-http":"^4.4.0","microtime":"^3.1.1","npm-check-updates":"^16.14.20","@aws-sdk/client-s3":"^3.731.1","express-request-id":"^1.4.1","mega-linter-runner":"^7.13.0","eslint-plugin-import":"^2.31.0","mocha-junit-reporter":"^2.2.1","start-server-and-test":"^2.0.10","artillery-plugin-expect":"^2.16.0","eslint-config-airbnb-base":"^15.0.0"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_2.0.2_1737224909592_0.5031157506536468","host":"s3://npm-registry-packages-npm-production"}},"3.0.0":{"name":"s3proxy","version":"3.0.0","keywords":["aws","s3","proxy","node","nodejs","http","express","typescript"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@3.0.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"8e518d2e54de4349d25da5f7ce74858231f806f1","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-3.0.0.tgz","fileCount":19,"integrity":"sha512-hFMTyb/LOLCnM992P3q8JokC7LoXPlYp61sUC3wl7iETFcXLyelw/dTMBwN2Y4h26939//A2JutW9oWfNT36uw==","signatures":[{"sig":"MEYCIQDE9w2YXhFj31tLmizZlHOlk43pk+BLj1+AzZ8Hdd4nbwIhAOvFA5EU8ClN/PbEaStF1d2eO7sDt8UU7qpPrbnG/i71","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54084},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=22.13.0"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./package.json":"./package.json"},"gitHead":"da5545634b2f8c01cd73022194761cf117fb547a","scripts":{"dev":"tsx examples/fastify-basic.ts","lint":"biome check src examples test","test":"npm run test:unit","build":"echo \"export const VERSION = '$(npm pkg get version --workspaces=false | tr -d '\"')';\" > src/version.ts && tsc","clean":"rm -rf dist coverage","start":"tsx examples/fastify-basic.ts","format":"biome format --write src examples test","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","lint:fix":"biome check --write src examples test","test:unit":"vitest run","test:watch":"vitest","type-check":"tsc --noEmit && tsc --noEmit -p tsconfig.examples.json","build:watch":"tsc --watch","ncu-upgrade":"ncu --upgrade","release:local":"semantic-release --no-ci","test:coverage":"vitest run --coverage","package:verify":"npm pack --dry-run","prepublishOnly":"npm run clean && npm run build && npm run test:unit","release:dry-run":"semantic-release --dry-run","test:validation":"vitest run --config vitest.integration.config.ts","package:contents":"npm pack && tar -tzf *.tgz && rm *.tgz","test:integration":"npm run lint && npm run type-check","test:validation:watch":"vitest --config vitest.integration.config.ts"},"_npmUser":{"name":"gmoon","actor":{"name":"gmoon","type":"user","email":"george.moon@gmail.com"},"email":"george.moon@gmail.com"},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"11.4.2","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"23.6.0","dependencies":{"@aws-sdk/client-s3":"^3.832.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.3","pino":"^9.7.0","vitest":"^3.2.4","express":"^5.1.0","fastify":"^5.4.0","wait-on":"^8.0.3","artillery":"^2.0.23","pino-http":"^10.5.0","typescript":"^5.8.3","@types/node":"^24.0.3","body-parser":"^2.2.0","pino-pretty":"^13.0.0","@types/debug":"^4.1.12","@types/morgan":"^1.9.10","@biomejs/biome":"^2.0.4","@types/express":"^5.0.3","semantic-release":"^24.2.5","npm-check-updates":"^18.0.1","@aws-sdk/client-s3":"^3.832.0","@vitest/coverage-v8":"^3.2.4","aws-sdk-client-mock":"^4.1.0","@semantic-release/git":"^10.0.1","@semantic-release/npm":"^12.0.1","@semantic-release/github":"^11.0.3","@semantic-release/changelog":"^6.0.3","@semantic-release/commit-analyzer":"^13.0.1","@semantic-release/release-notes-generator":"^14.0.3"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_3.0.0_1750630159615_0.6331377728469356","host":"s3://npm-registry-packages-npm-production"}},"4.1.0":{"name":"s3proxy","version":"4.1.0","keywords":["aws","s3","proxy","node","nodejs","http","express","typescript"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@4.1.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"52981a4ebc81e0c7fdd042e4976382e65ecee655","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-4.1.0.tgz","fileCount":31,"integrity":"sha512-X5BakRUgtSEBwMY2rTt8XfB+4hTxEEiPKBsD6cKMG1Ox0xYCXq/rjlhZofUrUEjARPE3kuffWrX0xrO+SlacSg==","signatures":[{"sig":"MEUCIBiSpK6+p9VrzJxaptJQ15yFEh2xI58RcDSm1J3cZyVPAiEAu3/QjEBDtJjvez4b4T4IYOpsnRdTZqQlzMKToN0jpEY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/s3proxy@4.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":91083},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=22.13.0"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./package.json":"./package.json"},"gitHead":"fc5026e6886098b63ebceb2e7fd023dce97ecbca","scripts":{"dev":"tsx examples/fastify-basic.ts","lint":"biome check","test":"npm run test:unit","build":"tsc","clean":"rm -rf dist coverage && rm -f load-test-results-*.json artillery-report-*.json performance-test-*.json s3proxy*.tgz credentials.json","start":"tsx examples/fastify-basic.ts","format":"biome format --write","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","lint:fix":"biome check --write","test:unit":"vitest run","test:smoke":"bash scripts/smoke-examples.sh","test:watch":"vitest","type-check":"tsc --noEmit && tsc --noEmit -p tsconfig.examples.json","build:watch":"tsc --watch","ncu-upgrade":"ncu --upgrade","release:local":"semantic-release --no-ci","test:coverage":"vitest run --coverage","package:verify":"npm pack --dry-run","prepublishOnly":"npm run clean && npm run build && npm run test:unit","release:dry-run":"semantic-release --dry-run","test:validation":"vitest run --config vitest.integration.config.ts","package:contents":"npm pack && tar -tzf *.tgz && rm *.tgz","test:integration":"npm run lint && npm run type-check","clean:test-results":"rm -f load-test-results-*.json artillery-report-*.json performance-test-*.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1d91a365-92d1-4802-b11c-9c5012a102ff"}},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"12.0.1","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@aws-sdk/client-s3":"^3.832.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.3","hono":"^4.12.15","vitest":"^4.1.5","express":"^5.1.0","fastify":"^5.4.0","wait-on":"^9.0.5","artillery":"^2.0.23","typescript":"^6.0.3","@types/node":"^25.6.0","body-parser":"^2.2.0","@types/debug":"^4.1.12","@types/morgan":"^1.9.10","@biomejs/biome":"^2.0.4","@types/express":"^5.0.3","semantic-release":"^25.0.5","@hono/node-server":"^2.0.0","npm-check-updates":"^20.0.2","@aws-sdk/client-s3":"^3.832.0","@vitest/coverage-v8":"^4.1.5","aws-sdk-client-mock":"^4.1.0","@semantic-release/git":"^10.0.1","@semantic-release/npm":"^13.1.5","@semantic-release/github":"^11.0.3","@semantic-release/changelog":"^6.0.3","@semantic-release/commit-analyzer":"^13.0.1","@semantic-release/release-notes-generator":"^14.0.3"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_4.1.0_1783907050479_0.8617447127015376","host":"s3://npm-registry-packages-npm-production"}},"4.2.0":{"name":"s3proxy","version":"4.2.0","keywords":["aws","s3","proxy","node","nodejs","http","express","typescript"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","_id":"s3proxy@4.2.0","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"homepage":"https://github.com/gmoon/s3proxy#readme","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"dist":{"shasum":"565b976ba83b040101239b8718174b2893f3cafd","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-4.2.0.tgz","fileCount":31,"integrity":"sha512-P4CXF7IEJj/n8FOZSqrVrf9I1YWLFt7XQ9Ybjw0+1tbJtCs6lOWpQCaG4NnWAnptXJKlVgrRwfG3mZEbWCWu1w==","signatures":[{"sig":"MEQCIHBsqIL+sUdXB5wtV7zvApGg+T/eG01k4CixEX46ZwvZAiBMCIfPAkofbbW/VfjirIsbiJ5BFws/1K9uHd+lDud7Ag==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/s3proxy@4.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":96004},"main":"dist/src/index.js","type":"module","types":"dist/src/index.d.ts","engines":{"node":">=22.13.0"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./package.json":"./package.json"},"gitHead":"d802628a4a3653244983eaea5405869439ee8373","scripts":{"dev":"tsx examples/fastify-basic.ts","lint":"biome check","test":"npm run test:unit","build":"tsc","clean":"rm -rf dist coverage && rm -f load-test-results-*.json artillery-report-*.json performance-test-*.json s3proxy*.tgz credentials.json","start":"tsx examples/fastify-basic.ts","format":"biome format --write","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","lint:fix":"biome check --write","test:unit":"vitest run","test:smoke":"bash scripts/smoke-examples.sh","test:watch":"vitest","type-check":"tsc --noEmit && tsc --noEmit -p tsconfig.examples.json","build:watch":"tsc --watch","ncu-upgrade":"ncu --upgrade","release:local":"semantic-release --no-ci","test:coverage":"vitest run --coverage","package:verify":"npm pack --dry-run","prepublishOnly":"npm run clean && npm run build && npm run test:unit","release:dry-run":"semantic-release --dry-run","test:validation":"vitest run --config vitest.integration.config.ts","package:contents":"npm pack && tar -tzf *.tgz && rm *.tgz","test:integration":"npm run lint && npm run type-check","clean:test-results":"rm -f load-test-results-*.json artillery-report-*.json performance-test-*.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1d91a365-92d1-4802-b11c-9c5012a102ff"}},"repository":{"url":"git+https://github.com/gmoon/s3proxy.git","type":"git"},"_npmVersion":"12.0.1","description":"Streaming web proxy for AWS S3","directories":{},"_nodeVersion":"22.23.1","dependencies":{"@aws-sdk/client-s3":"^3.832.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.3","hono":"^4.12.15","vitest":"^4.1.5","express":"^5.1.0","fastify":"^5.4.0","wait-on":"^9.0.5","artillery":"^2.0.33","typescript":"^6.0.3","@types/node":"^25.6.0","body-parser":"^2.2.0","@types/debug":"^4.1.12","@types/morgan":"^1.9.10","@biomejs/biome":"^2.0.4","@types/express":"^5.0.3","semantic-release":"^25.0.5","@hono/node-server":"^2.0.0","npm-check-updates":"^20.0.2","@aws-sdk/client-s3":"^3.832.0","@vitest/coverage-v8":"^4.1.5","aws-sdk-client-mock":"^4.1.0","@semantic-release/git":"^10.0.1","@semantic-release/npm":"^13.1.5","@semantic-release/github":"^11.0.3","@semantic-release/changelog":"^6.0.3","@forkzero/s3-website-test-kit":"^0.1.0","@semantic-release/commit-analyzer":"^13.0.1","@semantic-release/release-notes-generator":"^14.0.3"},"_npmOperationalInternal":{"tmp":"tmp/s3proxy_4.2.0_1783989617621_0.8758683892448342","host":"s3://npm-registry-packages-npm-production"}},"4.2.1":{"name":"s3proxy","version":"4.2.1","description":"Streaming web proxy for AWS S3","main":"dist/src/index.js","types":"dist/src/index.d.ts","type":"module","engines":{"node":">=22.13.0"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./package.json":"./package.json"},"devDependencies":{"@aws-sdk/client-s3":"^3.832.0","@biomejs/biome":"^2.0.4","@forkzero/s3-website-test-kit":"^0.1.0","@hono/node-server":"^2.0.0","@semantic-release/changelog":"^6.0.3","@semantic-release/commit-analyzer":"^13.0.1","@semantic-release/git":"^10.0.1","@semantic-release/github":"^11.0.3","@semantic-release/npm":"^13.1.5","@semantic-release/release-notes-generator":"^14.0.3","@types/debug":"^4.1.12","@types/express":"^5.0.3","@types/morgan":"^1.9.10","@types/node":"^25.6.0","@vitest/coverage-v8":"^4.1.5","artillery":"^2.0.33","aws-sdk-client-mock":"^4.1.0","body-parser":"^2.2.0","express":"^5.1.0","fastify":"^5.4.0","hono":"^4.12.15","npm-check-updates":"^20.0.2","semantic-release":"^25.0.5","tsx":"^4.20.3","typescript":"^6.0.3","vitest":"^4.1.5","wait-on":"^9.0.5"},"dependencies":{"@aws-sdk/client-s3":"^3.832.0"},"scripts":{"build":"tsc","build:watch":"tsc --watch","dev":"tsx examples/fastify-basic.ts","start":"tsx examples/fastify-basic.ts","test":"npm run test:unit","test:unit":"vitest run","test:coverage":"vitest run --coverage","test:validation":"vitest run --config vitest.integration.config.ts","test:smoke":"bash scripts/smoke-examples.sh","test:integration":"npm run lint && npm run type-check","test:watch":"vitest","lint":"biome check","lint:fix":"biome check --write","format":"biome format --write","type-check":"tsc --noEmit && tsc --noEmit -p tsconfig.examples.json","clean":"rm -rf dist coverage && rm -f load-test-results-*.json artillery-report-*.json performance-test-*.json s3proxy*.tgz credentials.json","clean:test-results":"rm -f load-test-results-*.json artillery-report-*.json performance-test-*.json","prepublishOnly":"npm run clean && npm run build && npm run test:unit","package:verify":"npm pack --dry-run","package:contents":"npm pack && tar -tzf *.tgz && rm *.tgz","release:dry-run":"semantic-release --dry-run","release:local":"semantic-release --no-ci","cleanup":"rm -fv s3proxy*.tgz; rm -fv examples/docker/s3proxy*.tgz","ncu-upgrade":"ncu --upgrade"},"repository":{"type":"git","url":"git+https://github.com/gmoon/s3proxy.git"},"keywords":["aws","s3","proxy","node","nodejs","http","express","typescript"],"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"homepage":"https://github.com/gmoon/s3proxy#readme","gitHead":"5d935f32cfab4abc443506d9c6dc37d3551715ab","_id":"s3proxy@4.2.1","_nodeVersion":"22.23.1","_npmVersion":"12.0.1","dist":{"integrity":"sha512-63IPm1SdkU7X3TA4r0TLeI1yiFPE6eFQeibJONklojXHLSjt/wbVJiqNgyiIsno6ih98wbxheqPeCDWwAhCO+w==","shasum":"fdcac399bc69d382789ba77945d6edcc022975a9","tarball":"https://registry.npmjs.org/s3proxy/-/s3proxy-4.2.1.tgz","fileCount":31,"unpackedSize":96286,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/s3proxy@4.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCy1fgTg+GhSFLpXAD0Qv0FDI8gkP0zpfx3p5JN3vHDaAIhANRyONQrVH84IH2PgNUG1aa9hSxMLljsv85fP5TPVH7Z"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1d91a365-92d1-4802-b11c-9c5012a102ff"}},"directories":{},"maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/s3proxy_4.2.1_1784031679959_0.1586512548443193"},"_hasShrinkwrap":false}},"time":{"created":"2014-11-05T21:15:41.422Z","modified":"2026-07-14T12:21:20.412Z","0.0.1":"2014-11-05T21:15:41.422Z","0.0.2":"2014-11-06T16:38:47.008Z","1.0.0":"2017-09-15T19:28:44.633Z","1.1.0":"2017-09-21T02:05:42.656Z","1.2.0":"2017-09-23T03:47:03.521Z","1.2.1":"2017-10-17T16:23:41.870Z","1.3.0":"2018-02-06T16:16:59.349Z","1.3.1":"2019-06-28T17:56:00.400Z","1.4.0":"2020-08-16T03:44:55.980Z","1.4.1":"2020-08-16T03:49:56.988Z","1.5.0":"2021-05-13T21:27:03.368Z","1.5.1":"2021-05-18T01:31:14.637Z","1.5.2":"2021-08-28T18:20:36.528Z","1.6.0":"2021-09-04T01:14:07.831Z","1.6.1":"2021-09-07T21:15:35.891Z","1.6.2":"2021-10-15T01:39:11.356Z","1.6.3":"2022-01-03T23:25:28.925Z","1.6.4":"2022-08-20T20:59:35.888Z","1.6.5":"2023-01-15T21:19:10.956Z","2.0.0":"2023-04-30T01:00:32.576Z","2.0.1":"2023-09-04T13:01:11.009Z","2.0.2":"2025-01-18T18:28:29.790Z","3.0.0":"2025-06-22T22:09:19.799Z","4.1.0":"2026-07-13T01:44:10.614Z","4.2.0":"2026-07-14T00:40:17.768Z","4.2.1":"2026-07-14T12:21:20.109Z"},"bugs":{"url":"https://github.com/gmoon/s3proxy/issues"},"author":{"name":"George Moon","email":"george.moon@gmail.com"},"license":"Apache-2.0","homepage":"https://github.com/gmoon/s3proxy#readme","keywords":["aws","s3","proxy","node","nodejs","http","express","typescript"],"repository":{"type":"git","url":"git+https://github.com/gmoon/s3proxy.git"},"description":"Streaming web proxy for AWS S3","maintainers":[{"name":"gmoon","email":"george.moon@gmail.com"}],"readme":"# s3proxy\n[![NPM Version][npm-image]][npm-url]\n[![NPM Downloads][downloads-image]][downloads-url]\n[![Node CI][actions-image]][actions-url]\n[![Docker Pulls][dockerpulls-image]][dockerpulls-url]\n\n**Stream files directly from AWS S3 to your users without downloading them to your server first.**\n\ns3proxy turns an S3 bucket into a web server. Use it to serve static websites, file downloads, or media directly from S3 while keeping control over access, headers, and routing.\n\n## Why s3proxy?\n\n- **Zero server storage**: files stream directly from S3 to users\n- **Low latency**: no intermediate downloads or disk buffering\n- **Cost effective**: reduce server storage and bandwidth costs\n- **Scalable**: backed by S3\n- **Range requests**: partial content and resumable downloads\n- **Framework support**: Express, Fastify, Hono, and plain `node:http`\n- **TypeScript**: typed API, ESM-only\n- **Large files**: suited to AI models, datasets, and media assets\n\n## Quick Start\n\n### Breaking changes in v4.0\n\nv4 fixes the v3 error contract and replaces the response-mutating\n`proxy.get(req, res)` / `proxy.head(req, res)` / `proxy.healthCheckStream(res)`\nwrappers with a single pure entry point: **`proxy.fetch(req)`**.\n\n```typescript\n// v3.x: wrapper writes res headers as a side effect, swallows 404 as an empty 200\nconst stream = await proxy.get(req, res);\nstream.pipe(res);\n\n// v4: pure fetch, you write the response\nconst { stream, status, headers } = await proxy.fetch(req);\nres.writeHead(status, headers);\nstream.pipe(res);\n```\n\nMissing keys, AccessDenied, and InvalidRange now throw typed\n`S3NotFound` / `S3Forbidden` / `S3InvalidRange` errors instead of\nsilently returning empty 200 streams. See [MIGRATION.md](MIGRATION.md)\nfor the full v3 to v4 migration guide.\n\nESM-only since v3. No CommonJS support. For CommonJS projects, add\n`\"type\": \"module\"` to your `package.json` or use dynamic import:\n`const { S3Proxy } = await import('s3proxy');`\n\n### Requirements\n\n- **Node.js**: 22.13.0 or higher\n- **Package Type**: ESM-only (no CommonJS support)\n- **AWS SDK**: v3 (included as dependency)\n\n### Installation & Usage\n```bash\nnpm install s3proxy express\n```\n\n```javascript\nimport express from 'express';\nimport { S3Proxy } from 's3proxy';\n\nconst app = express();\nconst proxy = new S3Proxy({ bucket: 'your-bucket-name' });\n\nawait proxy.init();\n\napp.get('/*splat', async (req, res) => {\n  try {\n    const { stream, status, headers } = await proxy.fetch(req);\n    res.writeHead(status, headers);\n    stream.on('error', () => res.end()).pipe(res);\n  } catch (err) {\n    res.status(err.statusCode || 500).end();\n  }\n});\n\napp.listen(3000);\n```\n\n> **Express 5 path syntax.** The `/*splat` wildcard is Express 5's\n> `path-to-regexp` requirement; on Express 4 use `'/*'`. Mixing the\n> two forms crashes at route registration.\n\n### Simpler: `proxy.middleware()`\n\nIf you don't need a custom error page, skip the try/catch.\n`proxy.middleware()` is a handler built on `fetch()` that writes the\nstatus, headers, and body for you. Missing, forbidden, and bad-range\nrequests return the real 404/403/416 status instead of an empty 200:\n\n```javascript\napp.get('/*splat', proxy.middleware());\n```\n\nOr write to a response yourself in one call with `proxy.pipe(req, res)`:\n\n```javascript\napp.get('/*splat', (req, res) => proxy.pipe(req, res));\n```\n\nBoth resolve when the body finishes streaming, and neither rejects on a\nclassified S3 failure; they write the correct status instead. Use the\nexplicit `fetch()` + try/catch form (below) when you need a custom error\nbody (XML/HTML), structured logging, or a non-Express framework.\n\n### Static website hosting: `proxy.staticSite()`\n\n`proxy.staticSite()` reproduces the core of S3 static website hosting\n(index documents and a custom error page) on a private bucket, with your\napp in front of it:\n\n```javascript\n// / and /dir/ resolve to index.html; missing or forbidden keys serve\n// 404.html with the correct 4xx status.\nconst site = proxy.staticSite({ indexDocument: 'index.html', errorDocument: '404.html' });\napp.use((req, res) => site(req, res));   // app.use so `/` matches too\n```\n\n| Request                | Served                                        |\n|------------------------|-----------------------------------------------|\n| `/`                    | `index.html` (200)                            |\n| `/blog/`               | `blog/index.html` (200)                       |\n| `/style.css`           | `style.css` (200)                             |\n| missing / forbidden    | `404.html` with the original 404/403 status   |\n\n`indexDocument` defaults to `'index.html'` (set it to `''` to disable).\n`errorDocument` is optional; without it, 404 and 403 return a plaintext\nstatus. If the error document is itself missing, `staticSite` falls back\nto a bare status instead of looping. The core `fetch()` is unchanged and\nstill throws typed errors. Full example:\n[`examples/static-site.ts`](examples/static-site.ts).\n\nBehavior:\n\n- Handles GET and HEAD, and passes Range requests through (a range still\n  returns 206 with `Content-Range`).\n- Forwards the object's S3 response headers: `content-type`,\n  `cache-control`, `etag`, `x-amz-meta-*`, and so on.\n- Serves the error document for missing (404) and access-denied (403)\n  keys, keeping the original status.\n\nLimitations (differences from an S3 website endpoint):\n\n- A path without a trailing slash is fetched as a literal key.\n  `staticSite` does not issue S3's `/photos` to `/photos/` directory\n  redirect, which would need an extra lookup.\n- Only 404 and 403 use the error document. A 416 (bad range), 400\n  (malformed request), or 500 returns a plaintext status.\n- No routing rules.\n\n> Mount with `app.use(...)`, not `app.get('/*splat', ...)`: the Express 5\n> wildcard doesn't match the root path `/`, so index resolution for `/`\n> would be skipped.\n\n### TypeScript/ESM\n```bash\nnpm install s3proxy express\nnpm install --save-dev @types/express\n```\n\n```typescript\nimport express, { type Request, type Response } from 'express';\nimport { S3Proxy, S3ProxyError } from 's3proxy';\nimport type { HttpRequest } from 's3proxy';\n\nconst app = express();\nconst proxy = new S3Proxy({ bucket: 'your-bucket-name' });\n\nawait proxy.init();\n\napp.get('/*splat', async (req: Request, res: Response) => {\n  try {\n    const { stream, status, headers } = await proxy.fetch(req as unknown as HttpRequest);\n    res.writeHead(status, headers);\n    stream.on('error', () => res.end()).pipe(res);\n  } catch (err) {\n    const status = err instanceof S3ProxyError ? err.statusCode : 500;\n    res.status(status).end();\n  }\n});\n\napp.listen(3000);\n```\n\nNow `curl http://localhost:3000/index.html` serves `s3://your-bucket-name/index.html`\n\n## Usage Examples\n\n### Express Integration with Error Handling\n\n```typescript\nimport express, { type Request, type Response } from 'express';\nimport { S3Proxy, S3ProxyError } from 's3proxy';\nimport type { HttpRequest } from 's3proxy';\n\nconst app = express();\nconst proxy = new S3Proxy({\n  bucket: 'my-website-bucket',\n  region: 'us-west-2',\n});\n\ntry {\n  await proxy.init();\n  console.log('S3Proxy initialized successfully');\n} catch (error) {\n  console.error('Failed to initialize S3Proxy:', error);\n  process.exit(1);\n}\n\nfunction handleError(req: Request, res: Response, err: unknown): void {\n  const statusCode = err instanceof S3ProxyError ? err.statusCode : 500;\n  const code = err instanceof Error ? err.name : 'InternalError';\n  const message = err instanceof Error ? err.message : String(err);\n  const errorXml = `<?xml version=\"1.0\"?>\n<error code=\"${code}\" statusCode=\"${statusCode}\" url=\"${req.url}\">${message}</error>`;\n\n  if (res.headersSent) {\n    res.end();\n    return;\n  }\n  res.status(statusCode).type('application/xml').send(errorXml);\n}\n\napp.get('/*splat', async (req: Request, res: Response) => {\n  try {\n    const { stream, status, headers } = await proxy.fetch(req as unknown as HttpRequest);\n    res.writeHead(status, headers);\n    stream.on('error', (err) => handleError(req, res, err)).pipe(res);\n  } catch (err) {\n    handleError(req, res, err);\n  }\n});\n\napp.listen(3000);\n```\n\n### Fastify Integration\n\n```typescript\nimport Fastify from 'fastify';\nimport { S3Proxy, S3ProxyError } from 's3proxy';\nimport type { HttpRequest } from 's3proxy';\n\nconst fastify = Fastify({ logger: true });\nconst proxy = new S3Proxy({\n  bucket: 'my-website-bucket',\n  region: 'us-west-2',\n});\n\nawait proxy.init();\n\nfastify.get('/*', async (request, reply) => {\n  const { stream, status, headers } = await proxy.fetch(\n    request.raw as unknown as HttpRequest\n  );\n  reply.raw.writeHead(status, headers);\n  stream.on('error', () => reply.raw.end());\n  stream.pipe(reply.raw);\n  // Tell Fastify we've handled the response ourselves.\n  return reply.hijack();\n});\n\n// Fastify's setErrorHandler turns S3ProxyError instances into XML\n// responses with the right status code (it honors err.statusCode).\nfastify.setErrorHandler(async (error, request, reply) => {\n  const statusCode = error instanceof S3ProxyError ? error.statusCode : 500;\n  reply.status(statusCode).type('application/xml').send(`<?xml version=\"1.0\"?>\n<error code=\"${error.name}\" statusCode=\"${statusCode}\">${error.message}</error>`);\n});\n\ntry {\n  await fastify.listen({ port: 3000 });\n  console.log('Server listening on http://localhost:3000');\n} catch (err) {\n  fastify.log.error(err);\n  process.exit(1);\n}\n```\n\n### Web Standard runtimes (Hono, Bun, Workers, Deno)\n\n**`proxy.fetchWeb(request)`** is the Web-runtime convenience adapter over\n`fetch()` (the counterpart of `pipe()` / `middleware()` for Node). It takes a\nWeb `Request` and returns a Web `Response`, so it is not tied to Hono - it\nworks with any framework exposing the raw `Request`, or as a runtime's\ntop-level `fetch` handler. With Hono it is one line:\n\n```typescript\nimport { Hono } from 'hono';\nimport { S3Proxy, S3ProxyError } from 's3proxy';\n\nconst proxy = new S3Proxy({ bucket: 'my-website-bucket' });\nawait proxy.init();\n\nconst app = new Hono();\n\napp.get('/health', async (c) => {\n  await proxy.healthCheck();\n  return c.text('OK');\n});\n\n// One line: Web Request -> Web Response. fetchWeb throws the typed\n// S3ProxyError on 404/403/416, which app.onError renders below.\napp.on(['GET', 'HEAD'], '/*', (c) => proxy.fetchWeb(c.req.raw));\n\napp.onError((err) => {\n  const status = err instanceof S3ProxyError ? err.statusCode : 500;\n  return new Response(err.message, { status });\n});\n```\n\nOn other Web runtimes it is equally direct as the top-level handler:\n\n```typescript\n// Bun / Deno / Cloudflare Workers\nexport default { fetch: (req: Request) => proxy.fetchWeb(req) };\n```\n\n`fetchWeb` throws rather than rendering (it is the peer of `fetch()`, not\n`pipe()`), so your framework's error handler owns the error-body format.\nIf you need to build the `Response` yourself (custom headers or error\nbody), call `fetch()` directly and adapt the stream:\n\n```typescript\nimport { Readable } from 'node:stream';\n\nconst { stream, status, headers } = await proxy.fetch({\n  url: new URL(c.req.url).pathname,\n  method: c.req.method,\n  headers: Object.fromEntries(c.req.raw.headers),\n});\nreturn new Response(Readable.toWeb(stream) as ReadableStream, { status, headers });\n```\n\n> **Performance note.** On Node, Hono goes through `@hono/node-server`\n> which converts `IncomingMessage` and `Web Request/Response` on every\n> request, two extra layers compared with Express's direct\n> `stream.pipe(res)`. For network-bound streaming (the typical s3proxy\n> workload, where S3 round-trip time dominates) the conversion cost is\n> negligible, and the smoke test's per-example latency baseline shows\n> parity with Express and Fastify on small files. For CPU-bound paths\n> measured in microseconds, prefer the Express or Fastify examples. On\n> Bun, Workers, and Deno there is no conversion layer.\n\n### Framework Compatibility\n\ns3proxy is **framework-agnostic** and works with any Node.js HTTP framework that provides access to the underlying request and response objects:\n\n- **[Express](https://expressjs.com/)** - Fast, unopinionated web framework ✅\n- **[Fastify](https://fastify.dev/)** - Fast and low overhead web framework ✅\n- **[Hono](https://hono.dev/)** - Web Standards framework (Bun/Workers/Deno/Node) ✅\n- **[Koa](https://koajs.com/)** - Expressive middleware framework ✅\n- **[Hapi](https://hapi.dev/)** - Rich framework for building applications ✅\n- **[NestJS](https://nestjs.com/)** - Progressive Node.js framework ✅\n- **[Next.js API Routes](https://nextjs.org/)** - Full-stack React framework ✅\n- **[Nuxt.js Server API](https://nuxt.com/)** - Vue.js framework ✅\n- **[SvelteKit](https://kit.svelte.dev/)** - Web development framework ✅\n- **[Remix](https://remix.run/)** - Full stack web framework ✅\n- **[AWS Lambda](https://aws.amazon.com/lambda/)** - Serverless functions ✅\n- **[Vercel Functions](https://vercel.com/docs/functions)** - Edge and serverless functions ✅\n- **[Netlify Functions](https://www.netlify.com/products/functions/)** - Serverless functions ✅\n\n**Key requirement**: the framework must give you a request with `url`,\n`method`, and `headers` (or `path`/`query`). All of the frameworks above\nexpose this, usually as `req.raw`, `request.raw`, or `request.req`.\nSince `proxy.fetch()` returns `{ stream, status, headers }` and never\ntouches a response, you wire the response however the framework prefers\n(`res.writeHead`, a `Web Response`, `reply.send`, and so on).\n\n### Range Requests (Partial Content)\n\ns3proxy handles HTTP Range requests for efficient streaming of large files:\n\n```bash\n# Download only bytes 0-99 of a large file\ncurl --range 0-99 http://localhost:3000/large-video.mp4 -o partial.mp4\n```\n\n### Large File Streaming\n\nStream large assets without server storage:\n\n```typescript\n// Stream AI models, datasets, or media files\napp.get('/models/:version/*splat', async (req: Request, res: Response) => {\n  try {\n    const { stream, status, headers } = await proxy.fetch(req as unknown as HttpRequest);\n    res.writeHead(status, headers);\n    stream.on('error', () => res.end()).pipe(res);\n  } catch (err) {\n    res.status((err as { statusCode?: number }).statusCode || 500).end();\n  }\n});\n\n// Now serve multi-GB files without local storage:\n// GET /models/v1/llama-7b.bin streams from S3\n```\n\n### Health Checks\n\nBuilt-in health check endpoint for load balancers:\n\n```typescript\napp.get('/health', async (_req: Request, res: Response) => {\n  try {\n    await proxy.healthCheck();   // throws S3ProxyError on failure\n    res.status(200).type('text/plain').send('OK');\n  } catch (err) {\n    const status = err instanceof S3ProxyError ? err.statusCode : 503;\n    res.status(status).type('text/plain').send('unhealthy');\n  }\n});\n```\n\n## Configuration\n\n### Constructor Options\n\n```typescript\nimport { S3Proxy } from 's3proxy';\nimport type { S3ProxyConfig } from 's3proxy';\n\nconst config: S3ProxyConfig = {\n  bucket: 'my-bucket',        // Required: S3 bucket name\n  region: 'us-west-2',        // Optional: AWS region\n  credentials: {              // Optional: AWS credentials\n    accessKeyId: 'AKIA...',\n    secretAccessKey: '...'\n  },\n  endpoint: 'https://...',    // Optional: Custom S3 endpoint\n  maxAttempts: 3,            // Optional: Retry attempts\n  requestTimeout: 30000      // Optional: Request timeout in ms\n};\n\nconst proxy = new S3Proxy(config);\n```\n\n### Environment Variables\n\n- `BUCKET` - S3 bucket name\n- `PORT` - Server port (default: 3000)\n- `AWS_REGION` - AWS region\n- `NODE_ENV` - Environment (enables credential file in dev mode)\n\n## API Reference\n\n### Class: S3Proxy\n\n#### Constructor\n```typescript\nnew S3Proxy(config: S3ProxyConfig)\n```\n\n#### Methods\n\n##### `await proxy.init(): Promise<void>`\nInitialize the underlying S3 client. By default also runs\n`healthCheck()` against the bucket and rejects on failure (set\n`verifyOnInit: false` to skip the probe; see\n[verifyOnInit](#verifyoninit-for-orchestrators)).\n\n##### `await proxy.fetch(req: HttpRequest): Promise<S3FetchResponse>`\nPure fetch. Returns `{ stream, status, headers }` without touching a\nresponse. Dispatches GET vs HEAD based on `req.method` (defaults to\nGET). Throws a typed `S3ProxyError` on classified failures (404, 403,\n416, malformed request); rethrows anything else. This is the primitive\nthe convenience adapters below are built on.\n\n##### `await proxy.pipe(req: HttpRequest, res: HttpResponse): Promise<void>`\nConvenience over `fetch()`: writes status + headers and pipes the body to\n`res`. Resolves when the body finishes; writes the real 404/403/416 for a\nclassified S3 failure and does **not** reject for it. Rejects only if\n`res.writeHead` throws. Use `fetch()` directly when you need a custom\nerror body.\n\n##### `proxy.middleware(): (req, res, next?) => void`\nReturns an Express/Connect handler built on `pipe()`. Drop it straight\ninto a route: `app.get('/*splat', proxy.middleware())`. Unexpected\n(non-classified) errors are forwarded to `next` when present.\n\n##### `proxy.staticSite(options?: StaticSiteOptions): (req, res, next?) => void`\nReturns a handler that reproduces the core of S3 static website hosting\non top of `fetch()`: index-document resolution (`/` to `index.html`,\n`/dir/` to `dir/index.html`) and, when `errorDocument` is set, serving it\nwith the original status for missing (404) and forbidden (403) keys.\nHandles GET and HEAD and passes Range requests through. It does not\nperform S3's trailing-slash directory redirect, and only 404/403 use the\nerror document. Mount with `app.use(...)` so the root path `/` is matched.\nSee [Static website hosting](#static-website-hosting-proxystaticsite).\n\n##### `await proxy.fetchWeb(request: Request): Promise<Response>`\nThe Web-runtime adapter over `fetch()`: takes a Web `Request`, returns a Web\n`Response` streaming the object. The Web analog of `pipe()` / `middleware()`,\nfor any WHATWG-fetch runtime (Bun, Deno, Cloudflare Workers, Node) and any\nframework exposing the raw `Request` -\n`app.on(['GET','HEAD'], '/*', (c) => proxy.fetchWeb(c.req.raw))` or\n`export default { fetch: (req) => proxy.fetchWeb(req) }`. Unlike `pipe()` it\ndoes **not** render errors: it throws the typed `S3ProxyError` on 404/403/416,\nso your framework's error handler owns the error-body format. HEAD responses\nhave a `null` body. Uses the runtime's global `Request` / `Response`; no extra\ndependency.\n\n##### `await proxy.healthCheck(): Promise<void>`\nVerify bucket connectivity. Resolves on success, throws a typed\n`S3ProxyError` on failure. Use it from a `/health` or `/ready` handler\nand render the response yourself.\n\n##### `proxy.isInitialized(): void`\nThrows `UserException` if `init()` hasn't been called yet.\n\n#### Static Methods\n\n##### `S3Proxy.version(): string`\nThe library version.\n\n#### Free functions exported from `'s3proxy'`\n\n`parseRequest(req)`, `mapHeaderToParam(req, headerKey, paramKey)`, and\n`stripLeadingSlash(s)` are exported as free functions. They previously\nlived as `S3Proxy.parseRequest` and so on; the move makes them\ntree-shakeable for callers that just want the parser.\n\n### Types\n\n```typescript\ninterface S3ProxyConfig extends S3ClientConfig {\n  bucket: string;\n  /**\n   * If true (default), init() calls healthCheck() and rejects when\n   * the bucket is unreachable, to fail fast on misconfiguration.\n   * Set to false in orchestrator deployments (Kubernetes, ECS).\n   */\n  verifyOnInit?: boolean;\n}\n\n/** What proxy.fetch() returns. */\ninterface S3FetchResponse {\n  stream: NodeJS.ReadableStream;\n  status: number;\n  headers: Record<string, string>;\n}\n\n/**\n * Structural subset of an HTTP request that proxy.fetch() reads.\n * Express's Request, Fastify's request.raw, and Node's IncomingMessage\n * all satisfy it (with light casts).\n */\ninterface HttpRequest {\n  url: string;\n  method?: string;\n  headers: Record<string, string | string[]>;\n  path?: string;\n  query?: Record<string, string | string[]>;\n}\n\ninterface ParsedRequest {\n  key: string;\n  query: Record<string, string | string[]>;\n}\n\n/**\n * Structural response the convenience adapter (pipe/middleware/staticSite)\n * writes to. Node's ServerResponse, Express's Response, and Fastify's\n * reply.raw all satisfy it. The pure fetch() primitive never touches it.\n */\ninterface HttpResponse extends NodeJS.WritableStream {\n  writeHead(statusCode: number, headers?: Record<string, string>): unknown;\n  readonly headersSent?: boolean;\n}\n\n/** Options for proxy.staticSite(). */\ninterface StaticSiteOptions {\n  indexDocument?: string;  // default 'index.html'; '' disables\n  errorDocument?: string;  // optional; served with the original 4xx status\n}\n```\n\n### Error Handling\n\n```typescript\nimport {\n  S3ProxyError,    // base class (statusCode, code, cause)\n  S3NotFound,      // 404: NoSuchKey or NoSuchBucket\n  S3Forbidden,     // 403: AccessDenied\n  S3InvalidRange,  // 416: InvalidRange\n  // InvalidRequest: 400, thrown by parseRequest for malformed input\n} from 's3proxy';\n\ntry {\n  const { stream, status, headers } = await proxy.fetch(req);\n  res.writeHead(status, headers);\n  stream.pipe(res);\n} catch (err) {\n  if (err instanceof S3NotFound)     return send404(res);\n  if (err instanceof S3Forbidden)    return send403(res);\n  if (err instanceof S3InvalidRange) return send416(res);\n  if (err instanceof S3ProxyError)   return res.status(err.statusCode).end();\n  throw err;  // unknown: let the framework's error handler take it\n}\n```\n\nThe proxy is also an `EventEmitter`. It emits `init` when `init()`\nresolves and `error` when it rejects, which is useful for logging\ndashboards.\n\n```typescript\nproxy.on('error', (err: Error) => console.error('S3Proxy error:', err));\nproxy.on('init',  () => console.log('S3Proxy initialized'));\n```\n\n### `verifyOnInit` for orchestrators\n\nIn Kubernetes/ECS deployments, you typically want the platform's own\nreadiness probe to determine health rather than crash-looping the pod\nwhen S3 has a hiccup at boot. Pass `verifyOnInit: false` and call\n`proxy.healthCheck()` from your readiness handler instead.\n\n```typescript\nconst proxy = new S3Proxy({ bucket: 'my-bucket', verifyOnInit: false });\nawait proxy.init();   // resolves immediately, no S3 traffic\n\napp.get('/ready', async (_req, res) => {\n  try {\n    await proxy.healthCheck();\n    res.status(200).send('ready');\n  } catch (err) {\n    res.status(503).send(String(err));\n  }\n});\n```\n\n## Docker Deployment\n\nFor containerized deployments:\n\n```bash\ndocker run --env BUCKET=mybucket --env PORT=8080 --publish 8080:8080 -t forkzero/s3proxy:latest\n```\n\nThe `forkzero/s3proxy` image is published from\n[`forkzero/s3proxy-docker`](https://github.com/forkzero/s3proxy-docker) with the\ntags `X.Y.Z`, `X.Y`, and `latest`. `latest` is shown here for quick start; pin a\nspecific version for production (for example `forkzero/s3proxy:4.2`).\n\nFor local development with temporary AWS credentials, write a session\ntoken to `~/.s3proxy/credentials.json` and bind-mount it into the\ncontainer. Keeping credentials in your home directory (not the repo\nroot) avoids any chance of committing them:\n\n```bash\nmkdir -p ~/.s3proxy\naws sts get-session-token --duration 900 > ~/.s3proxy/credentials.json\ndocker run \\\n  -v ~/.s3proxy/credentials.json:/src/credentials.json:ro \\\n  -e BUCKET=mybucket \\\n  -e PORT=8080 \\\n  -e NODE_ENV=dev \\\n  -p 8080:8080 \\\n  -t forkzero/s3proxy:latest\n```\n\n## Development\n\n### TypeScript Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Development with hot reload\nnpm run dev\n\n# Build TypeScript\nnpm run build\n\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n\n# Type checking\nnpm run type-check\n```\n\n### Testing & Quality Assurance\n\nTests run across several dimensions:\n\n#### Test Coverage Matrix\n\n| **Test Type** | **Local (Makefile)** | **CI (GitHub Actions)** | **Description** |\n|---------------|----------------------|-------------------------|-----------------|\n| **Code Quality** | | | |\n| Lint | `make lint` | ✅ Node CI | Code style and quality checks |\n| Type Check | `make type-check` | ✅ Node CI | TypeScript type safety validation |\n| Security Audit | `npm audit` | ✅ Node CI | Dependency vulnerability scanning |\n| **Unit Testing** | | | |\n| Unit Tests | `make unit-tests` | ✅ Node CI | Core functionality testing |\n| Coverage | `npm run test:coverage` | ✅ Node CI | Code coverage reporting (96%+) |\n| **Integration Testing** | | | |\n| Build Verification | `make build` | ✅ Node CI | TypeScript compilation |\n| Package Verification | `make pre-release-check` | ✅ Node CI | npm package integrity |\n| **Functional Testing** | | | |\n| Validation Tests | `make test-validation-docker` | ✅ Node CI | 24 comprehensive functionality tests |\n| Binary Integrity | Included in validation | ✅ Node CI | File corruption detection |\n| Range Requests | Included in validation | ✅ Node CI | HTTP range request handling |\n| Error Handling | Included in validation | ✅ Node CI | Proper error status codes |\n| **Performance Testing** | | | |\n| Load Testing | `make artillery-docker` | ✅ Node CI | High-throughput performance |\n| Stress Testing | `make test-performance` | ✅ Node CI | Resource usage under load |\n| **Platform Testing** | | | |\n| Docker Integration | `make test-all-docker` | ✅ Node CI | Containerized deployment |\n| Multi-Node | Node 22, 23 | ✅ Node CI | Cross-version compatibility |\n\n#### Test Commands\n\n```bash\n# Run all tests locally\nmake all                    # Complete test suite\nmake test                   # Core tests (build, lint, unit)\nmake functional-tests       # Integration and Docker tests\n\n# Individual test categories\nmake test-validation-docker # 24 comprehensive validation tests\nmake artillery-docker       # Performance/load testing\n\n# Quality checks\nmake pre-release-check     # Complete pre-release verification\n```\n\n#### Continuous Integration\n\n- **Every Push**: Core tests (lint, type-check, build, unit tests)\n- **Master Branch**: Full test suite including validation and performance\n- **Pull Requests**: Complete verification before merge\n- **Releases**: Comprehensive pre-release checks\n\n### Project Structure\n\n```\nsrc/\n├── index.ts           # S3Proxy orchestrator\n├── request-parser.ts  # parseRequest, mapHeaderToParam, etc.\n├── s3-gateway.ts      # AWS SDK boundary; turns SDK output into S3FetchResponse\n├── errors.ts          # S3ProxyError + S3NotFound / S3Forbidden / S3InvalidRange / InvalidRequest\n├── UserException.ts   # Caller-misuse errors (uninitialized, missing bucket)\n├── types.ts           # Public type definitions\n└── version.ts         # Version (read from package.json at module load)\n\nexamples/\n├── express-basic.ts  # TypeScript Express example\n├── fastify-basic.ts  # TypeScript Fastify example\n├── fastify-docker.ts # Dockerized Fastify example\n├── hono-basic.ts     # Hono / Web Standards example\n├── static-site.ts    # staticSite index + error document example\n└── http.ts           # TypeScript node:http example\n\ntest/\n├── s3proxy.test.ts         # Constructor / init / healthCheck / verifyOnInit\n├── fetch.test.ts           # proxy.fetch() behavioral coverage\n├── pipe.test.ts            # proxy.pipe() and proxy.middleware()\n├── static-site.test.ts     # proxy.staticSite() behavior\n├── parse-request.test.ts   # parseRequest unit tests (incl. malformed encoding)\n├── mock-express.test.ts    # Express request-shape compatibility\n├── mock-fastify.test.ts    # Fastify request-shape compatibility\n├── streaming-memory.test.ts # 100MB synthetic body, peak RSS bound\n├── concurrent.test.ts      # 10 parallel fetch() calls\n├── version.test.ts         # Version tests\n├── imports-esm.test.ts     # ESM import tests\n├── package-exports.test.ts # Package export tests\n├── helpers/\n│   └── aws-mock.ts         # AWS SDK mocking utilities\n└── integration/\n    └── validation.test.js  # End-to-end validation tests\n```\n\n### Configuration Files\n\ns3proxy uses several configuration files for different aspects of development and deployment:\n\n#### TypeScript Configuration\n- **`tsconfig.json`** - Main TypeScript compiler configuration\n  - Compiles `src/` to `dist/src/` for npm package\n  - ES2022 target with NodeNext module resolution\n  - Strict type checking enabled\n- **`tsconfig.examples.json`** - Type checking for examples\n  - Extends main config with examples-specific settings\n  - Used by `npm run type-check` to validate examples\n  - Ensures examples stay current with API changes\n\n#### Testing & Quality\n- **`vitest.config.ts`** - Unit test configuration\n  - Unit test settings with 30s timeout\n  - Coverage reporting (text, HTML, LCOV, JSON)\n  - Coverage thresholds: branches 85%, functions 95%, lines/statements 90%\n  - Excludes integration tests and examples from unit test runs\n- **`vitest.integration.config.ts`** - Integration test configuration\n  - Runs validation tests that require a live server\n  - Used by `npm run test:validation` and Makefile targets\n  - Separate from unit tests for faster development workflow\n- **`biome.json`** - Code formatting and linting\n  - Fast alternative to ESLint + Prettier\n  - Consistent code style across the project\n  - Import organization and formatting rules\n\n#### Release & CI/CD\n- **`.releaserc.json`** - Semantic release configuration\n  - Conventional commits for automated versioning\n  - Generates CHANGELOG.md automatically\n  - Publishes to npm and creates GitHub releases\n  - Handles version bumping and git tagging\n\n#### GitHub Actions\n- **`.github/workflows/nodejs.yml`** - Main CI pipeline\n  - Core tests (lint, type-check, build, unit tests)\n  - Validation tests (24 comprehensive functionality tests)\n  - Performance testing with Artillery\n  - Package verification\n- **`.github/workflows/release.yml`** - Automated releases\n- **`.github/workflows/manual-release.yml`** - Manual release workflow\n\n#### Performance Testing\n\nArtillery load-test configs and scenarios come from\n[`@forkzero/s3-website-test-kit`](https://www.npmjs.com/package/@forkzero/s3-website-test-kit),\na devDependency shared with `forkzero/s3proxy-docker`. `make artillery-docker`\nruns the kit's `configs/load-test.yml` + `scenarios/core/load-test.yml` against\nthe container. The kit is target-agnostic (native S3 website hosting or\ns3proxy); its `scenarios/core/` are portable, and `scenarios/s3proxy/` holds the\ns3proxy-only checks (for example `/health`).\n  - `range-requests.yml` - HTTP range request testing\n\n#### Development Tools\n- **`.vscode/settings.json`** - VS Code workspace settings\n  - Disables automatic Makefile configuration prompts\n- **`.github/dependabot.yml`** - Automated dependency updates\n- **`Makefile`** - Build automation and testing orchestration\n  - Coordinates Docker and Artillery testing\n  - Provides consistent commands across environments\n\n#### AWS & Docker\n- **`examples/aws-ecs/`** - ECS deployment configurations\n  - CloudFormation templates for production deployment\n\n## Use Cases\n\n- **Static websites** - Serve React/Vue/Angular builds from S3\n- **File downloads** - Stream large files without server storage\n- **Media serving** - Video/audio streaming with range request support\n- **API backends** - Serve user uploads or generated content\n- **AI & ML workflows** - Stream models, datasets, and training data\n- **CDN alternative** - Cost-effective content delivery\n\n## Performance\n\nSee [docs/performance.md](docs/performance.md) for detailed performance testing and benchmarks.\n\n## Getting Help\n\n- [Maintenance Guide](docs/maintenance.md): for contributors and advanced usage\n- [Report issues](https://github.com/gmoon/s3proxy/issues)\n- [Discussions](https://github.com/gmoon/s3proxy/discussions)\n\n## Contributing\n\nContributions are welcome. See the [Maintenance Guide](docs/maintenance.md) for development setup and contribution guidelines.\n\n## License\n\nApache 2.0 - see [LICENSE](LICENSE) file.\n\n[npm-image]: https://img.shields.io/npm/v/s3proxy.svg\n[npm-url]: https://npmjs.org/package/s3proxy\n[downloads-image]: https://img.shields.io/npm/dm/s3proxy.svg\n[downloads-url]: https://npmjs.org/package/s3proxy\n[actions-image]: https://github.com/gmoon/s3proxy/workflows/Node%20CI/badge.svg\n[actions-url]: https://github.com/gmoon/s3proxy/actions\n[dockerpulls-image]: https://img.shields.io/docker/pulls/forkzero/s3proxy.svg\n[dockerpulls-url]: https://hub.docker.com/r/forkzero/s3proxy\n","readmeFilename":"README.md"}