diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ed992e5..4d7c78a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,4 +15,5 @@ jobs: with: node-version: 18 - run: npm ci - - run: npm test \ No newline at end of file + - run: npm test + - run: npm run test:integration:offline \ No newline at end of file diff --git a/lib/response.js b/lib/response.js index f3bf74c..45c9ee8 100644 --- a/lib/response.js +++ b/lib/response.js @@ -127,10 +127,6 @@ module.exports = class ServerlessResponse extends http.ServerResponse { return true; }, }); - - this.once('finish', () => { - this.emit('close') - }); } }; diff --git a/package-lock.json b/package-lock.json index 9eb8ddd..6f43b3d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,6 +35,8 @@ "nyc": "^15.0.0", "on-finished": "^2.3.0", "on-headers": "^1.0.2", + "pino": "^8.15.0", + "pino-http": "^8.5.0", "polka": "^0.5.2", "reflect-metadata": "^0.1.13", "restana": "^4.0.7", @@ -46,6 +48,7 @@ "serverless-plugin-include-dependencies": "^5.0.0", "sinon": "^13.0.1", "supertest": "^6.2.2", + "tree-kill": "^1.2.2", "typescript": "^4.6.3" }, "engines": { @@ -3168,6 +3171,18 @@ "es5-ext": "^0.10.47" } }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/abstract-logging": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", @@ -6479,6 +6494,15 @@ "es5-ext": "~0.10.14" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -7034,6 +7058,40 @@ "tiny-lru": "^8.0.1" } }, + "node_modules/fastify/node_modules/pino": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-6.14.0.tgz", + "integrity": "sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg==", + "dev": true, + "dependencies": { + "fast-redact": "^3.0.0", + "fast-safe-stringify": "^2.0.8", + "flatstr": "^1.0.12", + "pino-std-serializers": "^3.1.0", + "process-warning": "^1.0.0", + "quick-format-unescaped": "^4.0.3", + "sonic-boom": "^1.0.2" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/fastify/node_modules/pino-std-serializers": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz", + "integrity": "sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==", + "dev": true + }, + "node_modules/fastify/node_modules/sonic-boom": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz", + "integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0", + "flatstr": "^1.0.12" + } + }, "node_modules/fastq": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", @@ -7903,6 +7961,12 @@ "integrity": "sha512-vo76VJ44MkUBZL/BzpGXaKzMfroF4ZR6+haRuw9p+eSWfoNaH2AxVc8xmiEPC08jhzJSeM6w7/iMUGet8b4oBQ==", "dev": true }, + "node_modules/hapi/node_modules/b64": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/b64/-/b64-4.1.2.tgz", + "integrity": "sha512-+GUspBxlH3CJaxMUGUE1EBoWM6RKgWiYwUDal0qdf8m3ArnXNN1KzKVo5HOnE/FSq4HHyWf3TlHLsZI8PKQgrQ==", + "extraneous": true + }, "node_modules/hapi/node_modules/boom": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/boom/-/boom-7.3.0.tgz", @@ -7915,6 +7979,12 @@ "integrity": "sha512-3G7B8CyBnip5EahCZJjnvQ1HLyArC6P5e+xcolo13BVI9ogFaDOsNMAE7FIWliHtIkYI8/nTRCvCY9tZa3Mu4g==", "dev": true }, + "node_modules/hapi/node_modules/bourne": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bourne/-/bourne-1.1.1.tgz", + "integrity": "sha512-Ou0l3W8+n1FuTOoIfIrCk9oF9WVWc+9fKoAl67XQr9Ws0z7LgILRZ7qtc9xdT4BveSKtnYXfKPgn8pFAqeQRew==", + "extraneous": true + }, "node_modules/hapi/node_modules/call": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/call/-/call-5.0.3.tgz", @@ -7933,6 +8003,18 @@ "integrity": "sha512-ZmqNiLsYCIu9qvBJ/MQbznDV2bFH5gFiH67TgIJgSSffJFtTXArT+MM3AvJQlby9NSkLHOX4eH/uuUqnch/Ldw==", "dev": true }, + "node_modules/hapi/node_modules/content": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/content/-/content-4.0.6.tgz", + "integrity": "sha512-lR9ND3dXiMdmsE84K6l02rMdgiBVmtYWu1Vr/gfSGHcIcznBj2QxmSdUgDuNFOA+G9yrb1IIWkZ7aKtB6hDGyA==", + "extraneous": true + }, + "node_modules/hapi/node_modules/cryptiles": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-4.1.3.tgz", + "integrity": "sha512-gT9nyTMSUC1JnziQpPbxKGBbUg8VL7Zn2NB4E1cJYvuXdElHrwxrV9bmltZGDzet45zSDGyYceueke1TjynGzw==", + "extraneous": true + }, "node_modules/hapi/node_modules/heavy": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/heavy/-/heavy-6.1.2.tgz", @@ -7945,18 +8027,42 @@ "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", "dev": true }, + "node_modules/hapi/node_modules/iron": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/iron/-/iron-5.0.6.tgz", + "integrity": "sha512-zYUMOSkEXGBdwlV/AXF9zJC0aLuTJUKHkGeYS5I2g225M5i6SrxQyGJGhPgOR8BK1omL6N5i6TcwfsXbP8/Exw==", + "extraneous": true + }, "node_modules/hapi/node_modules/joi": { "version": "14.3.1", "resolved": "https://registry.npmjs.org/joi/-/joi-14.3.1.tgz", "integrity": "sha512-LQDdM+pkOrpAn4Lp+neNIFV3axv1Vna3j38bisbQhETPMANYRbFJFUyOZcOClYvM/hppMhGWuKSFEK9vjrB+bQ==", "dev": true }, + "node_modules/hapi/node_modules/mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "extraneous": true + }, "node_modules/hapi/node_modules/mimos": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/mimos/-/mimos-4.0.2.tgz", "integrity": "sha512-5XBsDqBqzSN88XPPH/TFpOalWOjHJM5Z2d3AMx/30iq+qXvYKd/8MPhqBwZDOLtoaIWInR3nLzMQcxfGK9djXA==", "dev": true }, + "node_modules/hapi/node_modules/nigel": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/nigel/-/nigel-3.0.4.tgz", + "integrity": "sha512-3SZCCS/duVDGxFpTROHEieC+itDo4UqL9JNUyQJv3rljudQbK6aqus5B4470OxhESPJLN93Qqxg16rH7DUjbfQ==", + "extraneous": true + }, + "node_modules/hapi/node_modules/pez": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pez/-/pez-4.0.5.tgz", + "integrity": "sha512-HvL8uiFIlkXbx/qw4B8jKDCWzo7Pnnd65Uvanf9OOCtb20MRcb9gtTVBf9NCnhETif1/nzbDHIjAWC/sUp7LIQ==", + "extraneous": true + }, "node_modules/hapi/node_modules/podium": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/podium/-/podium-3.2.0.tgz", @@ -7999,6 +8105,18 @@ "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", "dev": true }, + "node_modules/hapi/node_modules/vise": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/vise/-/vise-3.0.2.tgz", + "integrity": "sha512-X52VtdRQbSBXdjcazRiY3eRgV3vTQ0B+7Wh8uC9cVv7lKfML5m9+9NHlbcgCY0R9EAqD1v/v7o9mhGh2A3ANFg==", + "extraneous": true + }, + "node_modules/hapi/node_modules/wreck": { + "version": "14.1.3", + "resolved": "https://registry.npmjs.org/wreck/-/wreck-14.1.3.tgz", + "integrity": "sha512-hb/BUtjX3ObbwO3slCOLCenQ4EP8e+n8j6FmTne3VhEFp5XV1faSJojiyxVSvw34vgdeTG5baLTl4NmjwokLlw==", + "extraneous": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -11024,6 +11142,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-exit-leak-free": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", + "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==", + "dev": true + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -11698,27 +11822,152 @@ } }, "node_modules/pino": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-6.14.0.tgz", - "integrity": "sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.15.0.tgz", + "integrity": "sha512-olUADJByk4twxccmAxb1RiGKOSvddHugCV3wkqjyv+3Sooa2KLrmXrKEWOKi0XPCLasRR5jBXxioE1jxUa4KzQ==", "dev": true, "dependencies": { - "fast-redact": "^3.0.0", - "fast-safe-stringify": "^2.0.8", - "flatstr": "^1.0.12", - "pino-std-serializers": "^3.1.0", - "process-warning": "^1.0.0", + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", "quick-format-unescaped": "^4.0.3", - "sonic-boom": "^1.0.2" + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.1.0", + "thread-stream": "^2.0.0" }, "bin": { "pino": "bin.js" } }, + "node_modules/pino-abstract-transport": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", + "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "dev": true, + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-abstract-transport/node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/pino-abstract-transport/node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "dev": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/pino-abstract-transport/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/pino-http": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/pino-http/-/pino-http-8.5.0.tgz", + "integrity": "sha512-kLGKNLyfWfdmrG1Ug0YdYpCTGbNcuD/YGC3g+elRU/Cm44UTs+tj/dZTxDN3bYauekxFxdLZhJuZdKKl0cml9w==", + "dev": true, + "dependencies": { + "get-caller-file": "^2.0.5", + "pino": "^8.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0" + } + }, + "node_modules/pino-http/node_modules/process-warning": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", + "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==", + "dev": true + }, "node_modules/pino-std-serializers": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz", - "integrity": "sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", + "dev": true + }, + "node_modules/pino/node_modules/process-warning": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", + "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==", "dev": true }, "node_modules/pkg-dir": { @@ -11893,6 +12142,15 @@ "node": ">=0.8" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -12322,6 +12580,15 @@ "node": ">=8.10.0" } }, + "node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/redis": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.1.tgz", @@ -12839,6 +13106,15 @@ "ret": "~0.2.0" } }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -14407,13 +14683,12 @@ } }, "node_modules/sonic-boom": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz", - "integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", + "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", "dev": true, "dependencies": { - "atomic-sleep": "^1.0.0", - "flatstr": "^1.0.12" + "atomic-sleep": "^1.0.0" } }, "node_modules/sort-keys": { @@ -15129,6 +15404,15 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "node_modules/thread-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.0.tgz", + "integrity": "sha512-xZYtOtmnA63zj04Q+F9bdEay5r47bvpo1CaNqsKi7TpoJHcotUez8Fkfo2RJWpW91lnnaApdpRbVwCWsy+ifcw==", + "dev": true, + "dependencies": { + "real-require": "^0.2.0" + } + }, "node_modules/throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -15263,6 +15547,15 @@ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", "dev": true }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", @@ -19022,6 +19315,15 @@ "es5-ext": "^0.10.47" } }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "requires": { + "event-target-shim": "^5.0.0" + } + }, "abstract-logging": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", @@ -21608,6 +21910,12 @@ "es5-ext": "~0.10.14" } }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true + }, "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", @@ -22043,6 +22351,39 @@ "secure-json-parse": "^2.0.0", "semver": "^7.3.2", "tiny-lru": "^8.0.1" + }, + "dependencies": { + "pino": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-6.14.0.tgz", + "integrity": "sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg==", + "dev": true, + "requires": { + "fast-redact": "^3.0.0", + "fast-safe-stringify": "^2.0.8", + "flatstr": "^1.0.12", + "pino-std-serializers": "^3.1.0", + "process-warning": "^1.0.0", + "quick-format-unescaped": "^4.0.3", + "sonic-boom": "^1.0.2" + } + }, + "pino-std-serializers": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz", + "integrity": "sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==", + "dev": true + }, + "sonic-boom": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz", + "integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==", + "dev": true, + "requires": { + "atomic-sleep": "^1.0.0", + "flatstr": "^1.0.12" + } + } } }, "fastq": { @@ -22694,6 +23035,11 @@ "integrity": "sha512-vo76VJ44MkUBZL/BzpGXaKzMfroF4ZR6+haRuw9p+eSWfoNaH2AxVc8xmiEPC08jhzJSeM6w7/iMUGet8b4oBQ==", "dev": true }, + "b64": { + "version": "https://registry.npmjs.org/b64/-/b64-4.1.2.tgz", + "integrity": "sha512-+GUspBxlH3CJaxMUGUE1EBoWM6RKgWiYwUDal0qdf8m3ArnXNN1KzKVo5HOnE/FSq4HHyWf3TlHLsZI8PKQgrQ==", + "extraneous": true + }, "boom": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/boom/-/boom-7.3.0.tgz", @@ -22706,6 +23052,11 @@ "integrity": "sha512-3G7B8CyBnip5EahCZJjnvQ1HLyArC6P5e+xcolo13BVI9ogFaDOsNMAE7FIWliHtIkYI8/nTRCvCY9tZa3Mu4g==", "dev": true }, + "bourne": { + "version": "https://registry.npmjs.org/bourne/-/bourne-1.1.1.tgz", + "integrity": "sha512-Ou0l3W8+n1FuTOoIfIrCk9oF9WVWc+9fKoAl67XQr9Ws0z7LgILRZ7qtc9xdT4BveSKtnYXfKPgn8pFAqeQRew==", + "extraneous": true + }, "call": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/call/-/call-5.0.3.tgz", @@ -22724,6 +23075,16 @@ "integrity": "sha512-ZmqNiLsYCIu9qvBJ/MQbznDV2bFH5gFiH67TgIJgSSffJFtTXArT+MM3AvJQlby9NSkLHOX4eH/uuUqnch/Ldw==", "dev": true }, + "content": { + "version": "https://registry.npmjs.org/content/-/content-4.0.6.tgz", + "integrity": "sha512-lR9ND3dXiMdmsE84K6l02rMdgiBVmtYWu1Vr/gfSGHcIcznBj2QxmSdUgDuNFOA+G9yrb1IIWkZ7aKtB6hDGyA==", + "extraneous": true + }, + "cryptiles": { + "version": "https://registry.npmjs.org/cryptiles/-/cryptiles-4.1.3.tgz", + "integrity": "sha512-gT9nyTMSUC1JnziQpPbxKGBbUg8VL7Zn2NB4E1cJYvuXdElHrwxrV9bmltZGDzet45zSDGyYceueke1TjynGzw==", + "extraneous": true + }, "heavy": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/heavy/-/heavy-6.1.2.tgz", @@ -22736,18 +23097,38 @@ "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", "dev": true }, + "iron": { + "version": "https://registry.npmjs.org/iron/-/iron-5.0.6.tgz", + "integrity": "sha512-zYUMOSkEXGBdwlV/AXF9zJC0aLuTJUKHkGeYS5I2g225M5i6SrxQyGJGhPgOR8BK1omL6N5i6TcwfsXbP8/Exw==", + "extraneous": true + }, "joi": { "version": "14.3.1", "resolved": "https://registry.npmjs.org/joi/-/joi-14.3.1.tgz", "integrity": "sha512-LQDdM+pkOrpAn4Lp+neNIFV3axv1Vna3j38bisbQhETPMANYRbFJFUyOZcOClYvM/hppMhGWuKSFEK9vjrB+bQ==", "dev": true }, + "mime-db": { + "version": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "extraneous": true + }, "mimos": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/mimos/-/mimos-4.0.2.tgz", "integrity": "sha512-5XBsDqBqzSN88XPPH/TFpOalWOjHJM5Z2d3AMx/30iq+qXvYKd/8MPhqBwZDOLtoaIWInR3nLzMQcxfGK9djXA==", "dev": true }, + "nigel": { + "version": "https://registry.npmjs.org/nigel/-/nigel-3.0.4.tgz", + "integrity": "sha512-3SZCCS/duVDGxFpTROHEieC+itDo4UqL9JNUyQJv3rljudQbK6aqus5B4470OxhESPJLN93Qqxg16rH7DUjbfQ==", + "extraneous": true + }, + "pez": { + "version": "https://registry.npmjs.org/pez/-/pez-4.0.5.tgz", + "integrity": "sha512-HvL8uiFIlkXbx/qw4B8jKDCWzo7Pnnd65Uvanf9OOCtb20MRcb9gtTVBf9NCnhETif1/nzbDHIjAWC/sUp7LIQ==", + "extraneous": true + }, "podium": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/podium/-/podium-3.2.0.tgz", @@ -22789,6 +23170,16 @@ "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", "dev": true + }, + "vise": { + "version": "https://registry.npmjs.org/vise/-/vise-3.0.2.tgz", + "integrity": "sha512-X52VtdRQbSBXdjcazRiY3eRgV3vTQ0B+7Wh8uC9cVv7lKfML5m9+9NHlbcgCY0R9EAqD1v/v7o9mhGh2A3ANFg==", + "extraneous": true + }, + "wreck": { + "version": "https://registry.npmjs.org/wreck/-/wreck-14.1.3.tgz", + "integrity": "sha512-hb/BUtjX3ObbwO3slCOLCenQ4EP8e+n8j6FmTne3VhEFp5XV1faSJojiyxVSvw34vgdeTG5baLTl4NmjwokLlw==", + "extraneous": true } } }, @@ -25194,6 +25585,12 @@ "es-abstract": "^1.22.1" } }, + "on-exit-leak-free": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", + "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==", + "dev": true + }, "on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -25695,24 +26092,118 @@ } }, "pino": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-6.14.0.tgz", - "integrity": "sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.15.0.tgz", + "integrity": "sha512-olUADJByk4twxccmAxb1RiGKOSvddHugCV3wkqjyv+3Sooa2KLrmXrKEWOKi0XPCLasRR5jBXxioE1jxUa4KzQ==", "dev": true, "requires": { - "fast-redact": "^3.0.0", - "fast-safe-stringify": "^2.0.8", - "flatstr": "^1.0.12", - "pino-std-serializers": "^3.1.0", - "process-warning": "^1.0.0", + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.1.1", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "v1.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0", "quick-format-unescaped": "^4.0.3", - "sonic-boom": "^1.0.2" + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^3.1.0", + "thread-stream": "^2.0.0" + }, + "dependencies": { + "process-warning": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", + "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==", + "dev": true + } + } + }, + "pino-abstract-transport": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", + "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "dev": true, + "requires": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + }, + "dependencies": { + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "readable-stream": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "dev": true, + "requires": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + } + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "pino-http": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/pino-http/-/pino-http-8.5.0.tgz", + "integrity": "sha512-kLGKNLyfWfdmrG1Ug0YdYpCTGbNcuD/YGC3g+elRU/Cm44UTs+tj/dZTxDN3bYauekxFxdLZhJuZdKKl0cml9w==", + "dev": true, + "requires": { + "get-caller-file": "^2.0.5", + "pino": "^8.0.0", + "pino-std-serializers": "^6.0.0", + "process-warning": "^2.0.0" + }, + "dependencies": { + "process-warning": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", + "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==", + "dev": true + } } }, "pino-std-serializers": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz", - "integrity": "sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", + "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==", "dev": true }, "pkg-dir": { @@ -25842,6 +26333,12 @@ "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==", "dev": true }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -26174,6 +26671,12 @@ "picomatch": "^2.2.1" } }, + "real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "dev": true + }, "redis": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.1.tgz", @@ -26555,6 +27058,12 @@ "ret": "~0.2.0" } }, + "safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "dev": true + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -27886,13 +28395,12 @@ } }, "sonic-boom": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-1.4.1.tgz", - "integrity": "sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", + "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", "dev": true, "requires": { - "atomic-sleep": "^1.0.0", - "flatstr": "^1.0.12" + "atomic-sleep": "^1.0.0" } }, "sort-keys": { @@ -28466,6 +28974,15 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "thread-stream": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.0.tgz", + "integrity": "sha512-xZYtOtmnA63zj04Q+F9bdEay5r47bvpo1CaNqsKi7TpoJHcotUez8Fkfo2RJWpW91lnnaApdpRbVwCWsy+ifcw==", + "dev": true, + "requires": { + "real-require": "^0.2.0" + } + }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -28566,6 +29083,12 @@ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", "dev": true }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, "trim-repeated": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", diff --git a/package.json b/package.json index 5ca4412..50dddcc 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "pretest": "tsc --strict --skipLibCheck --noEmit test/typecheck.ts", "test": "nyc mocha", "posttest": "eslint lib test", - "test:integration": "mocha test/integration/test.js", + "test:integration:offline": "mocha test/integration/test-offline.js --exit", + "test:integration:aws": "mocha test/integration/test-aws.js --exit", "postpublish": "git push origin master --tags" }, "keywords": [ @@ -77,6 +78,8 @@ "nyc": "^15.0.0", "on-finished": "^2.3.0", "on-headers": "^1.0.2", + "pino": "^8.15.0", + "pino-http": "^8.5.0", "polka": "^0.5.2", "reflect-metadata": "^0.1.13", "restana": "^4.0.7", @@ -88,6 +91,7 @@ "serverless-plugin-include-dependencies": "^5.0.0", "sinon": "^13.0.1", "supertest": "^6.2.2", + "tree-kill": "^1.2.2", "typescript": "^4.6.3" } } diff --git a/serverless-http.js b/serverless-http.js index 432b776..be73960 100644 --- a/serverless-http.js +++ b/serverless-http.js @@ -18,6 +18,7 @@ module.exports = function (app, opts) { await finish(request, options.request, ...context); const response = await framework(request); await finish(response, options.response, ...context); + response.emit('close'); return response; }); }; diff --git a/serverless.yml b/serverless.yml index 8803ece..fd36c69 100644 --- a/serverless.yml +++ b/serverless.yml @@ -70,6 +70,10 @@ functions: - http: path: /binary method: ANY + pino: + handler: test/integration/pino.handler + events: + - http: ANY /pino root: handler: test/integration/root.handler events: diff --git a/test/integration/pino.js b/test/integration/pino.js new file mode 100644 index 0000000..ab04c06 --- /dev/null +++ b/test/integration/pino.js @@ -0,0 +1,18 @@ +const serverless = require('../../serverless-http'); +const express = require('express'); +const pino = require('pino'); +const pinoHttp = require('pino-http'); + +const app = express(); +const basicPinoLogger = pino({level: 'info'}); +const expressPino = pinoHttp({ + logger: basicPinoLogger +}); + +app.use(expressPino); + +app.get('/pino', (req, res) => { + return res.status(200).json({status: 'ok'}); +}); + +exports.handler = serverless(app); \ No newline at end of file diff --git a/test/integration/test-aws.js b/test/integration/test-aws.js new file mode 100644 index 0000000..485489f --- /dev/null +++ b/test/integration/test-aws.js @@ -0,0 +1,49 @@ +'use strict'; + +/* eslint-disable no-console */ + +const { URL } = require('url'); +const { execSync } = require('child_process') +const common = require('./test-common'); + +function run(cmd) { + const res = execSync(`npx serverless ${cmd}`) + return res.toString() +} + +function getEndpoints(info) { + return info.reduce((memo, msg) => { + if (msg.indexOf('endpoints') !== -1) { + msg.split('\n').slice(1).map(txt => { + if (txt) { + const endpoint = txt.replace(' ANY - ', ''); + const url = new URL(endpoint); + memo.push(url); + } + }); + } + return memo; + }, []); +} + +common.runtimes.forEach(runtime => { + describe(runtime, function () { + this.slow(5000); + this.timeout(10000); + + before(function() { + this.timeout(0); + process.env.RUNTIME = runtime + run('deploy'); + }); + + before(async function() { + this.timeout(10000); + const info = run('info'); + this.endpoints = await getEndpoints(info.split('\r?\n')); + }); + + common.shouldBehaveLikeIntegration(); + }); + +}); diff --git a/test/integration/test-common.js b/test/integration/test-common.js new file mode 100644 index 0000000..5eb5e68 --- /dev/null +++ b/test/integration/test-common.js @@ -0,0 +1,143 @@ +const { expect } = require('chai'); +const supertest = require('supertest'); +const path = require('path'); +const fs = require('fs'); + +exports.runtimes = [ + 'nodejs12.x', + 'nodejs14.x', +]; + + +exports.shouldBehaveLikeIntegration = function() { + before(function() { + this.getEndpoint = (path) => { + return this.endpoints.find(e => e.pathname === path); + }; + this.logs = ""; + if (this.subprocess !== undefined) { + this.subprocess.stdout.on("data", (data) => { + this.logs += data; + }); + this.subprocess.stderr.on("data", (data) => { + this.logs += data; + }); + } + }); + + beforeEach(function() { + this.logs = ""; // clear any previous test logs + }) + + describe('koa', function() { + it('get', function() { + const endpoint = this.getEndpoint('/dev/koa'); + + return supertest(endpoint.origin) + .get(endpoint.pathname) + .expect(200) + .expect('Content-Type', /json/) + .then(response => { + expect(response.body.url).to.equal('/koa'); + expect(response.body.method).to.equal('get'); + }); + }); + }); + + describe('express', function() { + + ['get', 'put', 'post'].forEach(method => { + it(method, function() { + const endpoint = this.getEndpoint('/dev/express'); + + return supertest(endpoint.origin)[method](endpoint.pathname) + .expect(200) + .expect('Content-Type', /json/) + .then(response => { + expect(response.body.originalUrl).to.equal('/express'); + expect(response.body.url).to.equal('/express'); + expect(response.body.method).to.equal(method); + }); + }); + }); + + it('get-with-path', function() { + const endpoint = this.getEndpoint('/dev/express'); + + return supertest(endpoint.origin) + .get(`${endpoint.pathname}/pathed/1`) + .expect(200) + .expect('Content-Type', /json/) + .then(response => { + expect(response.body.originalUrl).to.equal('/express/pathed/1'); + expect(response.body.url).to.equal('/express/pathed/1'); + expect(response.body.method).to.equal('get'); + expect(response.body.id).to.equal('1'); + }); + }); + + }); + + it('binary', function() { + const endpoint = this.getEndpoint('/dev/binary'); + + const imagePath = path.join(__dirname, 'image.png'); + const expected = fs.readFileSync(imagePath); + + return supertest(endpoint.origin) + .get(endpoint.pathname) + .set('Accept', 'image/png') // if this is image/*, APIg will not match :( + .expect(200) + .expect('Content-Type', /png/) + .then(response => { + if (Buffer.isBuffer(response.body)) { + if (response.body.equals(expected)) { + return; + } + } + + throw new Error('Binary response body was not a buffer or not equal to the expected image'); + }); + }); + + it('timer', function() { + const endpoint = this.getEndpoint('/dev/timer'); + + return supertest(endpoint.origin) + .get(endpoint.pathname) + .expect(200) + .expect('Content-Type', /json/); + }); + + it('pino', function(done) { + const endpoint = this.getEndpoint('/dev/pino'); + + supertest(endpoint.origin) + .get(endpoint.pathname) + .expect(200) + .expect('Content-Type', /json/) + .end(() => { + // In the AWS case, we have no logs + if (this.logs === "") { + return done(); + } + // Should only log once + const matchCount = (this.logs.match(/"statusCode":200/g) || []).length; + if (matchCount !==1) { + console.log("logs", this.logs); + } + expect(matchCount).to.equal(1); + return done(); + }); + }); + + // FIXME: Broken currently https://github.com/dougmoscrop/serverless-http/issues/270 + it.skip('root', function() { + const endpoint = this.getEndpoint('/dev'); + + return supertest(endpoint.origin) + .get(endpoint.pathname) + .expect(200) + .expect('Content-Type', /json/); + }); +}; \ No newline at end of file diff --git a/test/integration/test-offline.js b/test/integration/test-offline.js new file mode 100644 index 0000000..4ac6c43 --- /dev/null +++ b/test/integration/test-offline.js @@ -0,0 +1,70 @@ +'use strict'; + +/* eslint-disable no-console */ + +const common = require('./test-common'); +const { URL } = require('url'); +const { spawn } = require('child_process') +const kill = require('tree-kill'); + +function sleep(ms) { + return new Promise((resolve) => setInterval(resolve, ms)); +} + +async function runSpawned(cmd) { + const subprocess = spawn("npx", ["serverless", cmd]) + let output = ""; + subprocess.stdout.setEncoding('utf-8'); + subprocess.stdout.on('data', (data) => { + output += data; + }); + subprocess.stderr.setEncoding('utf-8'); + subprocess.stderr.on('data', (data) => { + output += data; + }); + while (!output.includes("Server ready:")) { + await sleep(500); + } + return {subprocess, output}; +} + +const endpointRegex = /ANY \| (http[^\n\r ]+)/g + +function getEndpoints(info) { + let memo = []; + const matches = info.matchAll(endpointRegex); + for (const m of matches) { + const url = new URL(m[1]); + memo.push(url); + } + return memo; +} + +common.runtimes.forEach(runtime => { + describe(runtime, function () { + this.slow(5000); + this.timeout(10000); + + before(async function() { + this.timeout(0); + process.env.RUNTIME = runtime; + const { subprocess, output } = await runSpawned('offline'); + this.endpoints = getEndpoints(output); + this.subprocess = subprocess; + }); + + after(async function() { + let done = false; + this.subprocess.on('close', () => { + done = true; + }) + kill(this.subprocess.pid); + while (!done) { + await sleep(500); + } + }); + + common.shouldBehaveLikeIntegration(); + }); + +}); diff --git a/test/integration/test.js b/test/integration/test.js deleted file mode 100644 index b2d2bf8..0000000 --- a/test/integration/test.js +++ /dev/null @@ -1,152 +0,0 @@ -'use strict'; - -/* eslint-disable no-console */ - -const { URL } = require('url'); -const path = require('path'); -const fs = require('fs'); -const { execSync } = require('child_process') - -const { expect } = require('chai'); -const supertest = require('supertest'); - -function run(cmd) { - const res = execSync(`npx serverless ${cmd}`) - return res.toString() -} - -function getEndpoints(info) { - return info.reduce((memo, msg) => { - if (msg.indexOf('endpoints') !== -1) { - msg.split('\n').slice(1).map(txt => { - if (txt) { - const endpoint = txt.replace(' ANY - ', ''); - const url = new URL(endpoint); - memo.push(url); - } - }); - } - return memo; - }, []); -} - -const runtimes = [ - 'nodejs12.x', - 'nodejs14.x', -]; - -runtimes.forEach(runtime => { - describe(runtime, function () { - this.slow(5000); - this.timeout(10000); - - let endpoints; - - function getEndpoint(path) { - return endpoints.find(e => e.pathname === path); - } - - before(async function() { - this.timeout(0); - process.env.RUNTIME = runtime - await run('deploy'); - }); - - before(async function() { - this.timeout(10000); - const info = await run('info'); - endpoints = await getEndpoints(info.split('\r?\n')); - }); - - describe('koa', () => { - - it('get', () => { - const endpoint = getEndpoint('/dev/koa'); - - return supertest(endpoint.origin) - .get(endpoint.pathname) - .expect(200) - .expect('Content-Type', /json/) - .then(response => { - expect(response.body.url).to.equal('/koa'); - expect(response.body.method).to.equal('get'); - }); - }); - }); - - describe('express', () => { - - ['get', 'put', 'post'].forEach(method => { - it(method, () => { - const endpoint = getEndpoint('/dev/express'); - - return supertest(endpoint.origin)[method](endpoint.pathname) - .expect(200) - .expect('Content-Type', /json/) - .then(response => { - expect(response.body.originalUrl).to.equal('/express'); - expect(response.body.url).to.equal('/express'); - expect(response.body.method).to.equal(method); - }); - }); - }); - - it('get-with-path', () => { - const endpoint = getEndpoint('/dev/express'); - - return supertest(endpoint.origin) - .get(`${endpoint.pathname}/pathed/1`) - .expect(200) - .expect('Content-Type', /json/) - .then(response => { - expect(response.body.originalUrl).to.equal('/express/pathed/1'); - expect(response.body.url).to.equal('/express/pathed/1'); - expect(response.body.method).to.equal('get'); - expect(response.body.id).to.equal('1'); - }); - }); - - }); - - it('binary', () => { - const endpoint = getEndpoint('/dev/binary'); - - const imagePath = path.join(__dirname, 'image.png'); - const expected = fs.readFileSync(imagePath); - - return supertest(endpoint.origin) - .get(endpoint.pathname) - .set('Accept', 'image/png') // if this is image/*, APIg will not match :( - .expect(200) - .expect('Content-Type', /png/) - .then(response => { - if (Buffer.isBuffer(response.body)) { - if (response.body.equals(expected)) { - return; - } - } - - throw new Error('Binary response body was not a buffer or not equal to the expected image'); - }); - }); - - it('timer', () => { - const endpoint = getEndpoint('/dev/timer'); - - return supertest(endpoint.origin) - .get(endpoint.pathname) - .expect(200) - .expect('Content-Type', /json/); - }); - - it('root', () => { - const endpoint = getEndpoint('/dev'); - - return supertest(endpoint.origin) - .get(endpoint.pathname) - .expect(200) - .expect('Content-Type', /json/); - }); - }); - -});