From e3d3035a6acd3e86a5ca3f48b93999d820eeed02 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 26 Apr 2024 20:57:11 +0200 Subject: [PATCH 01/16] chore(deps): update dependency express to v4.19.2 [security] (#596) Co-authored-by: Matthew Robertson --- package-lock.json | 351 +++++++++++++++++++++------------------------- 1 file changed, 159 insertions(+), 192 deletions(-) diff --git a/package-lock.json b/package-lock.json index 41ff974b..db1aef92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1136,23 +1136,26 @@ } }, "node_modules/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "engines": { - "node": ">= 0.8" + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" } }, "node_modules/brace-expansion": { @@ -1426,17 +1429,17 @@ } }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { "node": ">= 0.6" } }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -1532,17 +1535,21 @@ } }, "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } }, "node_modules/dezalgo": { "version": "1.0.4", @@ -2215,37 +2222,38 @@ } }, "node_modules/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.2", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.2", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.7", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -2362,16 +2370,16 @@ } }, "node_modules/finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" }, "engines": { @@ -2452,21 +2460,6 @@ "url": "https://ko-fi.com/tunnckoCore/commissions" } }, - "node_modules/formidable/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2870,18 +2863,18 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" }, "node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/human-signals": { @@ -4275,9 +4268,9 @@ } }, "node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dependencies": { "ee-first": "1.1.1" }, @@ -4568,9 +4561,12 @@ } }, "node_modules/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dependencies": { + "side-channel": "^1.0.4" + }, "engines": { "node": ">=0.6" }, @@ -4625,12 +4621,12 @@ } }, "node_modules/raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, @@ -4876,23 +4872,23 @@ } }, "node_modules/send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dependencies": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" @@ -4913,14 +4909,14 @@ } }, "node_modules/serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" }, "engines": { "node": ">= 0.8.0" @@ -5081,11 +5077,11 @@ "dev": true }, "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/string-argv": { @@ -5236,21 +5232,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/superagent/node_modules/qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/supertest": { "version": "6.3.4", "resolved": "https://registry.npmjs.org/supertest/-/supertest-6.3.4.tgz", @@ -6622,20 +6603,22 @@ "dev": true }, "body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "requires": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.8.1", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.9.7", - "raw-body": "2.4.3", - "type-is": "~1.6.18" + "on-finished": "2.4.1", + "qs": "6.11.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" } }, "brace-expansion": { @@ -6851,14 +6834,14 @@ } }, "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==" }, "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==" }, "cookie-signature": { "version": "1.0.6", @@ -6935,14 +6918,14 @@ "dev": true }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" }, "dezalgo": { "version": "1.0.4", @@ -7412,37 +7395,38 @@ } }, "express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.3.tgz", - "integrity": "sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.2", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.2", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.9.7", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.17.2", - "serve-static": "1.14.2", + "send": "0.18.0", + "serve-static": "1.15.0", "setprototypeof": "1.2.0", - "statuses": "~1.5.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -7538,16 +7522,16 @@ } }, "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" } }, @@ -7608,17 +7592,6 @@ "hexoid": "^1.0.0", "once": "^1.4.0", "qs": "^6.11.0" - }, - "dependencies": { - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - } } }, "forwarded": { @@ -7901,14 +7874,14 @@ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" }, "http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "requires": { - "depd": "~1.1.2", + "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", + "statuses": "2.0.1", "toidentifier": "1.0.1" } }, @@ -8931,9 +8904,9 @@ } }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "requires": { "ee-first": "1.1.1" } @@ -9138,9 +9111,12 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "requires": { + "side-channel": "^1.0.4" + } }, "queue-microtask": { "version": "1.2.3", @@ -9169,12 +9145,12 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.3.tgz", - "integrity": "sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "requires": { "bytes": "3.1.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } @@ -9327,23 +9303,23 @@ } }, "send": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz", - "integrity": "sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.8.1", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "dependencies": { "ms": { @@ -9363,14 +9339,14 @@ } }, "serve-static": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.2.tgz", - "integrity": "sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.2" + "send": "0.18.0" } }, "setprototypeof": { @@ -9505,9 +9481,9 @@ "dev": true }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, "string-argv": { "version": "0.3.1", @@ -9612,15 +9588,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } } } }, From 6a45d57987457f08d804feab468a1b25aff7a445 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:01:20 -0700 Subject: [PATCH 02/16] chore(deps): bump express from 4.17.3 to 4.19.2 (#595) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Matthew Robertson --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index db1aef92..18c898e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1608,7 +1608,7 @@ "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } @@ -1682,7 +1682,7 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "1.0.5", @@ -5465,7 +5465,7 @@ "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } @@ -6975,7 +6975,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "error-ex": { "version": "1.3.2", @@ -7031,7 +7031,7 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "1.0.5", @@ -9762,7 +9762,7 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "uri-js": { "version": "4.4.1", From 1fe0f1d0c2b52c3b2b4cc8604e0d6c17e97bb68e Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Fri, 26 Apr 2024 21:10:12 +0200 Subject: [PATCH 03/16] chore(deps): update actions/dependency-review-action action to v4 (#590) Co-authored-by: Matthew Robertson --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 349c6834..7ecb3da7 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -24,4 +24,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4 - name: 'Dependency Review' - uses: actions/dependency-review-action@c74b580d73376b7750d3d2a50bfb8adc2c937507 # v3.1.5 + uses: actions/dependency-review-action@5bbc3ba658137598168acb2ab73b21c432dd411b # v4.2.5 From 7a538e09f07cfffde1e2ee1592f53386062639c2 Mon Sep 17 00:00:00 2001 From: Matthew Robertson Date: Fri, 26 Apr 2024 13:49:42 -0700 Subject: [PATCH 04/16] feat: AbortController to signal request timeouts (#600) --- docs/generated/api.json | 192 +++++++++++++------- docs/generated/api.md | 5 +- package-lock.json | 289 +++++++++++++++++++------------ package.json | 2 +- src/function_registry.ts | 1 + src/functions.ts | 6 +- src/main.ts | 10 +- src/middleware/timeout.ts | 37 ++++ src/options.ts | 20 +++ src/server.ts | 28 +-- src/testing.ts | 14 +- test/integration/legacy_event.ts | 33 ++-- test/middleware/timeout.ts | 58 +++++++ test/options.ts | 34 +++- 14 files changed, 514 insertions(+), 215 deletions(-) create mode 100644 src/middleware/timeout.ts create mode 100644 test/middleware/timeout.ts diff --git a/docs/generated/api.json b/docs/generated/api.json index 07d5e57f..77b0e5eb 100644 --- a/docs/generated/api.json +++ b/docs/generated/api.json @@ -1,7 +1,7 @@ { "metadata": { "toolPackage": "@microsoft/api-extractor", - "toolVersion": "7.34.4", + "toolVersion": "7.43.1", "schemaVersion": 1011, "oldestForwardsCompatibleVersion": 1001, "tsdocConfig": { @@ -173,17 +173,29 @@ "preserveMemberOrder": false, "members": [ { - "kind": "Variable", - "canonicalReference": "@google-cloud/functions-framework!cloudEvent:var", + "kind": "Function", + "canonicalReference": "@google-cloud/functions-framework!cloudEvent:function(1)", "docComment": "/**\n * Register a function that handles CloudEvents.\n *\n * @param functionName - the name of the function\n *\n * @param handler - the function to trigger when handling CloudEvents\n *\n * @public\n */\n", "excerptTokens": [ { "kind": "Content", - "text": "cloudEvent: " + "text": "cloudEvent: (functionName: string, handler: " + "text": "unknown" + }, + { + "kind": "Content", + "text": ">(functionName: " + }, + { + "kind": "Content", + "text": "string" + }, + { + "kind": "Content", + "text": ", handler: " }, { "kind": "Reference", @@ -192,17 +204,56 @@ }, { "kind": "Content", - "text": ") => void" + "text": "" + }, + { + "kind": "Content", + "text": ") => " + }, + { + "kind": "Content", + "text": "void" } ], "fileUrlPath": "src/function_registry.ts", - "isReadonly": true, + "returnTypeTokenRange": { + "startIndex": 8, + "endIndex": 9 + }, "releaseTag": "Public", - "name": "cloudEvent", - "variableTypeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "functionName", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": false + }, + { + "parameterName": "handler", + "parameterTypeTokenRange": { + "startIndex": 5, + "endIndex": 7 + }, + "isOptional": false + } + ], + "typeParameters": [ + { + "typeParameterName": "T", + "constraintTokenRange": { + "startIndex": 0, + "endIndex": 0 + }, + "defaultTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + } + ], + "name": "cloudEvent" }, { "kind": "Interface", @@ -896,17 +947,21 @@ } }, { - "kind": "Variable", - "canonicalReference": "@google-cloud/functions-framework!http:var", + "kind": "Function", + "canonicalReference": "@google-cloud/functions-framework!http:function(1)", "docComment": "/**\n * Register a function that responds to HTTP requests.\n *\n * @param functionName - the name of the function\n *\n * @param handler - the function to invoke when handling HTTP requests\n *\n * @public\n */\n", "excerptTokens": [ { "kind": "Content", - "text": "http: " + "text": "http: (functionName: " }, { "kind": "Content", - "text": "(functionName: string, handler: " + "text": "string" + }, + { + "kind": "Content", + "text": ", handler: " }, { "kind": "Reference", @@ -915,17 +970,39 @@ }, { "kind": "Content", - "text": ") => void" + "text": ") => " + }, + { + "kind": "Content", + "text": "void" } ], "fileUrlPath": "src/function_registry.ts", - "isReadonly": true, + "returnTypeTokenRange": { + "startIndex": 5, + "endIndex": 6 + }, "releaseTag": "Public", - "name": "http", - "variableTypeTokenRange": { - "startIndex": 1, - "endIndex": 4 - } + "overloadIndex": 1, + "parameters": [ + { + "parameterName": "functionName", + "parameterTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + }, + "isOptional": false + }, + { + "parameterName": "handler", + "parameterTypeTokenRange": { + "startIndex": 3, + "endIndex": 4 + }, + "isOptional": false + } + ], + "name": "http" }, { "kind": "Interface", @@ -1757,6 +1834,34 @@ "name": "Request_2", "preserveMemberOrder": false, "members": [ + { + "kind": "PropertySignature", + "canonicalReference": "@google-cloud/functions-framework!Request_2#abortController:member", + "docComment": "/**\n * An AbortController used to signal cancellation of a function invocation (e.g. in case of time out).\n */\n", + "excerptTokens": [ + { + "kind": "Content", + "text": "abortController?: " + }, + { + "kind": "Reference", + "text": "AbortController", + "canonicalReference": "!AbortController:interface" + }, + { + "kind": "Content", + "text": ";" + } + ], + "isReadonly": false, + "isOptional": true, + "releaseTag": "Public", + "name": "abortController", + "propertyTypeTokenRange": { + "startIndex": 1, + "endIndex": 2 + } + }, { "kind": "PropertySignature", "canonicalReference": "@google-cloud/functions-framework!Request_2#executionId:member", @@ -1874,47 +1979,6 @@ } ] }, - { - "kind": "Variable", - "canonicalReference": "@google-cloud/functions-framework!typed:var", - "docComment": "/**\n * Register a function that handles strongly typed invocations.\n *\n * @param functionName - the name of the function\n *\n * @param handler - the function to trigger\n */\n", - "excerptTokens": [ - { - "kind": "Content", - "text": "typed: " - }, - { - "kind": "Content", - "text": "(functionName: string, handler: " - }, - { - "kind": "Reference", - "text": "TypedFunction", - "canonicalReference": "@google-cloud/functions-framework!TypedFunction:interface" - }, - { - "kind": "Content", - "text": " | ((req: T) => U | " - }, - { - "kind": "Reference", - "text": "Promise", - "canonicalReference": "!Promise:interface" - }, - { - "kind": "Content", - "text": ")) => void" - } - ], - "fileUrlPath": "src/function_registry.ts", - "isReadonly": true, - "releaseTag": "Public", - "name": "typed", - "variableTypeTokenRange": { - "startIndex": 1, - "endIndex": 6 - } - }, { "kind": "Interface", "canonicalReference": "@google-cloud/functions-framework!TypedFunction:interface", diff --git a/docs/generated/api.md b/docs/generated/api.md index 56ea685d..105c8516 100644 --- a/docs/generated/api.md +++ b/docs/generated/api.md @@ -112,6 +112,7 @@ export interface LegacyEvent { // @public (undocumented) interface Request_2 extends Request_3 { + abortController?: AbortController; executionId?: string; rawBody?: Buffer; spanId?: string; @@ -121,7 +122,9 @@ export { Request_2 as Request } export { Response_2 as Response } -// @public +// Warning: (ae-internal-missing-underscore) The name "typed" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal export const typed: (functionName: string, handler: TypedFunction | ((req: T) => U | Promise)) => void; // @public diff --git a/package-lock.json b/package-lock.json index 18c898e6..4f380025 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "functions-framework-nodejs": "build/src/main.js" }, "devDependencies": { - "@microsoft/api-extractor": "^7.18.20", + "@microsoft/api-extractor": "^7.43.1", "@types/body-parser": "1.19.5", "@types/minimist": "1.2.5", "@types/mocha": "9.1.1", @@ -220,43 +220,56 @@ "dev": true }, "node_modules/@microsoft/api-extractor": { - "version": "7.34.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.34.4.tgz", - "integrity": "sha512-HOdcci2nT40ejhwPC3Xja9G+WSJmWhCUKKryRfQYsmE9cD+pxmBaKBKCbuS9jUcl6bLLb4Gz+h7xEN5r0QiXnQ==", + "version": "7.43.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.1.tgz", + "integrity": "sha512-ohg40SsvFFgzHFAtYq5wKJc8ZDyY46bphjtnSvhSSlXpPTG7GHwyyXkn48UZiUCBwr2WC7TRC1Jfwz7nreuiyQ==", "dev": true, "dependencies": { - "@microsoft/api-extractor-model": "7.26.4", + "@microsoft/api-extractor-model": "7.28.14", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.55.2", - "@rushstack/rig-package": "0.3.18", - "@rushstack/ts-command-line": "4.13.2", - "colors": "~1.2.1", + "@rushstack/node-core-library": "4.1.0", + "@rushstack/rig-package": "0.5.2", + "@rushstack/terminal": "0.10.1", + "@rushstack/ts-command-line": "4.19.2", "lodash": "~4.17.15", + "minimatch": "~3.0.3", "resolve": "~1.22.1", - "semver": "~7.3.0", + "semver": "~7.5.4", "source-map": "~0.6.1", - "typescript": "~4.8.4" + "typescript": "5.4.2" }, "bin": { "api-extractor": "bin/api-extractor" } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.26.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.26.4.tgz", - "integrity": "sha512-PDCgCzXDo+SLY5bsfl4bS7hxaeEtnXj7XtuzEE+BtALp7B5mK/NrS2kHWU69pohgsRmEALycQdaQPXoyT2i5MQ==", + "version": "7.28.14", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.14.tgz", + "integrity": "sha512-Bery/c8A8SsKPSvA82cTTuy/+OcxZbLRmKhPkk91/AJOQzxZsShcrmHFAGeiEqSIrv1nPZ3tKq9kfMLdCHmsqg==", "dev": true, "dependencies": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.55.2" + "@rushstack/node-core-library": "4.1.0" + } + }, + "node_modules/@microsoft/api-extractor/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, "node_modules/@microsoft/api-extractor/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -269,16 +282,16 @@ } }, "node_modules/@microsoft/api-extractor/node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/@microsoft/tsdoc": { @@ -360,17 +373,16 @@ } }, "node_modules/@rushstack/node-core-library": { - "version": "3.55.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.55.2.tgz", - "integrity": "sha512-SaLe/x/Q/uBVdNFK5V1xXvsVps0y7h1sN7aSJllQyFbugyOaxhNRF25bwEDnicARNEjJw0pk0lYnJQ9Kr6ev0A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.1.0.tgz", + "integrity": "sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==", "dev": true, "dependencies": { - "colors": "~1.2.1", "fs-extra": "~7.0.1", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", - "semver": "~7.3.0", + "semver": "~7.5.4", "z-schema": "~5.0.2" }, "peerDependencies": { @@ -383,9 +395,9 @@ } }, "node_modules/@rushstack/node-core-library/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -398,24 +410,66 @@ } }, "node_modules/@rushstack/rig-package": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.18.tgz", - "integrity": "sha512-SGEwNTwNq9bI3pkdd01yCaH+gAsHqs0uxfGvtw9b0LJXH52qooWXnrFTRRLG1aL9pf+M2CARdrA9HLHJys3jiQ==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", + "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", "dev": true, "dependencies": { "resolve": "~1.22.1", "strip-json-comments": "~3.1.1" } }, + "node_modules/@rushstack/terminal": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.1.tgz", + "integrity": "sha512-C6Vi/m/84IYJTkfzmXr1+W8Wi3MmBjVF/q3za91Gb3VYjKbpALHVxY6FgH625AnDe5Z0Kh4MHKWA3Z7bqgAezA==", + "dev": true, + "dependencies": { + "@rushstack/node-core-library": "4.1.0", + "supports-color": "~8.1.1" + }, + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@rushstack/terminal/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@rushstack/terminal/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/@rushstack/ts-command-line": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.13.2.tgz", - "integrity": "sha512-bCU8qoL9HyWiciltfzg7GqdfODUeda/JpI0602kbN5YH22rzTxyqYvv7aRLENCM7XCQ1VRs7nMkEqgJUOU8Sag==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.2.tgz", + "integrity": "sha512-cqmXXmBEBlzo9WtyUrHtF9e6kl0LvBY7aTSVX4jfnBfXWZQWnPq9JTFPlQZ+L/ZwjZ4HrNwQsOVvhe9oOucZkw==", "dev": true, "dependencies": { + "@rushstack/terminal": "0.10.1", "@types/argparse": "1.0.38", "argparse": "~1.0.9", - "colors": "~1.2.1", "string-argv": "~0.3.1" } }, @@ -1374,15 +1428,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "node_modules/colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2656,9 +2701,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "node_modules/graphemer": { @@ -5073,7 +5118,7 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "node_modules/statuses": { @@ -5085,9 +5130,9 @@ } }, "node_modules/string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, "engines": { "node": ">=0.6.19" @@ -5517,9 +5562,9 @@ } }, "node_modules/validator": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", - "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", "dev": true, "engines": { "node": ">= 0.10" @@ -5905,51 +5950,61 @@ "dev": true }, "@microsoft/api-extractor": { - "version": "7.34.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.34.4.tgz", - "integrity": "sha512-HOdcci2nT40ejhwPC3Xja9G+WSJmWhCUKKryRfQYsmE9cD+pxmBaKBKCbuS9jUcl6bLLb4Gz+h7xEN5r0QiXnQ==", + "version": "7.43.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.1.tgz", + "integrity": "sha512-ohg40SsvFFgzHFAtYq5wKJc8ZDyY46bphjtnSvhSSlXpPTG7GHwyyXkn48UZiUCBwr2WC7TRC1Jfwz7nreuiyQ==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.26.4", + "@microsoft/api-extractor-model": "7.28.14", "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.55.2", - "@rushstack/rig-package": "0.3.18", - "@rushstack/ts-command-line": "4.13.2", - "colors": "~1.2.1", + "@rushstack/node-core-library": "4.1.0", + "@rushstack/rig-package": "0.5.2", + "@rushstack/terminal": "0.10.1", + "@rushstack/ts-command-line": "4.19.2", "lodash": "~4.17.15", + "minimatch": "~3.0.3", "resolve": "~1.22.1", - "semver": "~7.3.0", + "semver": "~7.5.4", "source-map": "~0.6.1", - "typescript": "~4.8.4" + "typescript": "5.4.2" }, "dependencies": { + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true } } }, "@microsoft/api-extractor-model": { - "version": "7.26.4", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.26.4.tgz", - "integrity": "sha512-PDCgCzXDo+SLY5bsfl4bS7hxaeEtnXj7XtuzEE+BtALp7B5mK/NrS2kHWU69pohgsRmEALycQdaQPXoyT2i5MQ==", + "version": "7.28.14", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.14.tgz", + "integrity": "sha512-Bery/c8A8SsKPSvA82cTTuy/+OcxZbLRmKhPkk91/AJOQzxZsShcrmHFAGeiEqSIrv1nPZ3tKq9kfMLdCHmsqg==", "dev": true, "requires": { "@microsoft/tsdoc": "0.14.2", "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "3.55.2" + "@rushstack/node-core-library": "4.1.0" } }, "@microsoft/tsdoc": { @@ -6015,24 +6070,23 @@ "dev": true }, "@rushstack/node-core-library": { - "version": "3.55.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.55.2.tgz", - "integrity": "sha512-SaLe/x/Q/uBVdNFK5V1xXvsVps0y7h1sN7aSJllQyFbugyOaxhNRF25bwEDnicARNEjJw0pk0lYnJQ9Kr6ev0A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.1.0.tgz", + "integrity": "sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==", "dev": true, "requires": { - "colors": "~1.2.1", "fs-extra": "~7.0.1", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", - "semver": "~7.3.0", + "semver": "~7.5.4", "z-schema": "~5.0.2" }, "dependencies": { "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -6041,24 +6095,51 @@ } }, "@rushstack/rig-package": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.18.tgz", - "integrity": "sha512-SGEwNTwNq9bI3pkdd01yCaH+gAsHqs0uxfGvtw9b0LJXH52qooWXnrFTRRLG1aL9pf+M2CARdrA9HLHJys3jiQ==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", + "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", "dev": true, "requires": { "resolve": "~1.22.1", "strip-json-comments": "~3.1.1" } }, + "@rushstack/terminal": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.1.tgz", + "integrity": "sha512-C6Vi/m/84IYJTkfzmXr1+W8Wi3MmBjVF/q3za91Gb3VYjKbpALHVxY6FgH625AnDe5Z0Kh4MHKWA3Z7bqgAezA==", + "dev": true, + "requires": { + "@rushstack/node-core-library": "4.1.0", + "supports-color": "~8.1.1" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "@rushstack/ts-command-line": { - "version": "4.13.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.13.2.tgz", - "integrity": "sha512-bCU8qoL9HyWiciltfzg7GqdfODUeda/JpI0602kbN5YH22rzTxyqYvv7aRLENCM7XCQ1VRs7nMkEqgJUOU8Sag==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.2.tgz", + "integrity": "sha512-cqmXXmBEBlzo9WtyUrHtF9e6kl0LvBY7aTSVX4jfnBfXWZQWnPq9JTFPlQZ+L/ZwjZ4HrNwQsOVvhe9oOucZkw==", "dev": true, "requires": { + "@rushstack/terminal": "0.10.1", "@types/argparse": "1.0.38", "argparse": "~1.0.9", - "colors": "~1.2.1", "string-argv": "~0.3.1" } }, @@ -6791,12 +6872,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", - "dev": true - }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -7728,9 +7803,9 @@ } }, "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "graphemer": { @@ -9477,7 +9552,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "statuses": { @@ -9486,9 +9561,9 @@ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true }, "string-width": { @@ -9805,9 +9880,9 @@ } }, "validator": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", - "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", "dev": true }, "vary": { diff --git a/package.json b/package.json index 7092bfc9..f460a687 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "author": "Google Inc.", "license": "Apache-2.0", "devDependencies": { - "@microsoft/api-extractor": "^7.18.20", + "@microsoft/api-extractor": "^7.43.1", "@types/body-parser": "1.19.5", "@types/minimist": "1.2.5", "@types/mocha": "9.1.1", diff --git a/src/function_registry.ts b/src/function_registry.ts index 60261d6c..cc7038e4 100644 --- a/src/function_registry.ts +++ b/src/function_registry.ts @@ -105,6 +105,7 @@ export const cloudEvent = ( * Register a function that handles strongly typed invocations. * @param functionName - the name of the function * @param handler - the function to trigger + * @internal */ export const typed = ( functionName: string, diff --git a/src/functions.ts b/src/functions.ts index cd37b8f4..c6f1e040 100644 --- a/src/functions.ts +++ b/src/functions.ts @@ -44,6 +44,10 @@ export interface Request extends ExpressRequest { * Cloud Trace span ID. */ spanId?: string; + /** + * An AbortController used to signal cancellation of a function invocation (e.g. in case of time out). + */ + abortController?: AbortController; } /** @@ -194,7 +198,7 @@ export interface InvocationFormat { /** * Creates an instance of the request type from an invocation request. * - * @param request the request body as raw bytes + * @param request - the request body as raw bytes */ deserializeRequest(request: InvocationRequest): T | Promise; diff --git a/src/main.ts b/src/main.ts index 3dd98398..2f1684c7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -49,12 +49,12 @@ export const main = async () => { // eslint-disable-next-line no-process-exit process.exit(1); } + const {userFunction, signatureType} = loadedFunction; - const server = getServer( - userFunction!, - signatureType, - options.enableExecutionId - ); + // It is possible to overwrite the configured signature type in code so we + // reset it here based on what we loaded. + options.signatureType = signatureType; + const server = getServer(userFunction!, options); const errorHandler = new ErrorHandler(server); server .listen(options.port, () => { diff --git a/src/middleware/timeout.ts b/src/middleware/timeout.ts new file mode 100644 index 00000000..8cf202a8 --- /dev/null +++ b/src/middleware/timeout.ts @@ -0,0 +1,37 @@ +import {Request, Response} from '../functions'; +import {NextFunction} from 'express'; + +export const timeoutMiddleware = (timeoutMilliseconds: number) => { + return (req: Request, res: Response, next: NextFunction) => { + // In modern versions of Node.js that support the AbortController API we add one to + // signal function timeout. + if (timeoutMilliseconds > 0 && 'AbortController' in global) { + req.abortController = new AbortController(); + req.setTimeout(timeoutMilliseconds); + let executionComplete = false; + res.on('timeout', () => { + // This event is triggered when the underlying socket times out due to inactivity. + if (!executionComplete) { + executionComplete = true; + req.abortController?.abort('timeout'); + } + }); + req.on('close', () => { + // This event is triggered when the underlying HTTP connection is closed. This can + // happen if the data plane times out the request, the client disconnects or the + // response is complete. + if (!executionComplete) { + executionComplete = true; + req.abortController?.abort('request closed'); + } + }); + req.on('end', () => { + // This event is triggered when the function execution completes and we + // write an HTTP response. + executionComplete = true; + }); + } + // Always call next to continue middleware processing. + next(); + }; +}; diff --git a/src/options.ts b/src/options.ts index d761b86f..7f1cd7e3 100644 --- a/src/options.ts +++ b/src/options.ts @@ -52,6 +52,10 @@ export interface FrameworkOptions { * Whether or not to enable execution id support. */ enableExecutionId: boolean; + /** + * The request timeout. + */ + timeoutMilliseconds: number; } /** @@ -112,6 +116,20 @@ const SignatureOption = new ConfigurableOption( ); } ); +const TimeoutOption = new ConfigurableOption( + 'timeout', + 'CLOUD_RUN_TIMEOUT_SECONDS', + 0, + (x: string | number) => { + if (typeof x === 'string') { + x = parseInt(x, 10); + } + if (isNaN(x) || x < 0) { + throw new OptionsError('Timeout must be a positive integer'); + } + return x * 1000; + } +); export const requiredNodeJsVersionForLogExecutionID = '13.0.0'; const ExecutionIdOption = new ConfigurableOption( @@ -158,6 +176,7 @@ export const parseOptions = ( FunctionTargetOption.cliOption, SignatureOption.cliOption, SourceLocationOption.cliOption, + TimeoutOption.cliOption, ], }); return { @@ -165,6 +184,7 @@ export const parseOptions = ( target: FunctionTargetOption.parse(argv, envVars), sourceLocation: SourceLocationOption.parse(argv, envVars), signatureType: SignatureOption.parse(argv, envVars), + timeoutMilliseconds: TimeoutOption.parse(argv, envVars), printHelp: cliArgs[2] === '-h' || cliArgs[2] === '--help', enableExecutionId: ExecutionIdOption.parse(argv, envVars), }; diff --git a/src/server.ts b/src/server.ts index e4080d5c..9ce9396a 100644 --- a/src/server.ts +++ b/src/server.ts @@ -17,27 +17,27 @@ import * as express from 'express'; import * as http from 'http'; import * as onFinished from 'on-finished'; import {HandlerFunction, Request, Response} from './functions'; -import {SignatureType} from './types'; import {setLatestRes} from './invoker'; import {legacyPubSubEventMiddleware} from './pubsub_middleware'; import {cloudEventToBackgroundEventMiddleware} from './middleware/cloud_event_to_background_event'; import {backgroundEventToCloudEventMiddleware} from './middleware/background_event_to_cloud_event'; +import {timeoutMiddleware} from './middleware/timeout'; import {wrapUserFunction} from './function_wrappers'; import {asyncLocalStorageMiddleware} from './async_local_storage'; import {executionContextMiddleware} from './execution_context'; import {errorHandler} from './logger'; +import {FrameworkOptions} from './options'; /** * Creates and configures an Express application and returns an HTTP server * which will run it. * @param userFunction User's function. - * @param functionSignatureType Type of user's function signature. + * @param options the configured Function Framework options. * @return HTTP server. */ export function getServer( userFunction: HandlerFunction, - functionSignatureType: SignatureType, - enableExecutionId: boolean + options: FrameworkOptions ): http.Server { // App to use for function executions. const app = express(); @@ -89,7 +89,7 @@ export function getServer( }; // Apply middleware - if (functionSignatureType !== 'typed') { + if (options.signatureType !== 'typed') { // If the function is not typed then JSON parsing can be done automatically, otherwise the // functions format must determine deserialization. app.use(bodyParser.json(cloudEventsBodySavingOptions)); @@ -120,8 +120,8 @@ export function getServer( app.use(asyncLocalStorageMiddleware); if ( - functionSignatureType === 'event' || - functionSignatureType === 'cloudevent' + options.signatureType === 'event' || + options.signatureType === 'cloudevent' ) { // If a Pub/Sub subscription is configured to invoke a user's function directly, the request body // needs to be marshalled into the structure that wrapEventFunction expects. This unblocks local @@ -129,14 +129,14 @@ export function getServer( app.use(legacyPubSubEventMiddleware); } - if (functionSignatureType === 'event') { + if (options.signatureType === 'event') { app.use(cloudEventToBackgroundEventMiddleware); } - if (functionSignatureType === 'cloudevent') { + if (options.signatureType === 'cloudevent') { app.use(backgroundEventToCloudEventMiddleware); } - if (functionSignatureType === 'http') { + if (options.signatureType === 'http') { app.use('/favicon.ico|/robots.txt', (req, res) => { // Neither crawlers nor browsers attempting to pull the icon find the body // contents particularly useful, so we send nothing in the response body. @@ -151,16 +151,18 @@ export function getServer( }); } + app.use(timeoutMiddleware(options.timeoutMilliseconds)); + // Set up the routes for the user's function - const requestHandler = wrapUserFunction(userFunction, functionSignatureType); - if (functionSignatureType === 'http') { + const requestHandler = wrapUserFunction(userFunction, options.signatureType); + if (options.signatureType === 'http') { app.all('/*', requestHandler); } else { app.post('/*', requestHandler); } // Error Handler - if (enableExecutionId) { + if (options.enableExecutionId) { app.use(errorHandler); } diff --git a/src/testing.ts b/src/testing.ts index f66baad7..3360a000 100644 --- a/src/testing.ts +++ b/src/testing.ts @@ -48,9 +48,13 @@ export const getTestServer = (functionName: string): Server => { `The provided function "${functionName}" was not registered. Did you forget to require the module that defined it?` ); } - return getServer( - registeredFunction.userFunction, - registeredFunction.signatureType, - /*enableExecutionId=*/ false - ); + return getServer(registeredFunction.userFunction, { + signatureType: registeredFunction.signatureType, + enableExecutionId: false, + timeoutMilliseconds: 0, + port: '0', + target: '', + sourceLocation: '', + printHelp: false, + }); }; diff --git a/test/integration/legacy_event.ts b/test/integration/legacy_event.ts index 3213acd9..a25250e6 100644 --- a/test/integration/legacy_event.ts +++ b/test/integration/legacy_event.ts @@ -17,6 +17,7 @@ import * as functions from '../../src/functions'; import * as sinon from 'sinon'; import {getServer} from '../../src/server'; import * as supertest from 'supertest'; +import {SignatureType} from '../../src/types'; const TEST_CLOUD_EVENT = { specversion: '1.0', @@ -31,6 +32,16 @@ const TEST_CLOUD_EVENT = { }, }; +const testOptions = { + signatureType: 'event' as SignatureType, + enableExecutionId: false, + timeoutMilliseconds: 0, + port: '0', + target: '', + sourceLocation: '', + printHelp: false, +}; + describe('Event Function', () => { beforeEach(() => { // Prevent log spew from the PubSub emulator request. @@ -181,14 +192,10 @@ describe('Event Function', () => { it(test.name, async () => { let receivedData: {} | null = null; let receivedContext: functions.CloudFunctionsContext | null = null; - const server = getServer( - (data: {}, context: functions.Context) => { - receivedData = data; - receivedContext = context as functions.CloudFunctionsContext; - }, - 'event', - /*enableExecutionId=*/ false - ); + const server = getServer((data: {}, context: functions.Context) => { + receivedData = data; + receivedContext = context as functions.CloudFunctionsContext; + }, testOptions); const requestHeaders = { 'Content-Type': 'application/json', ...test.headers, @@ -204,13 +211,9 @@ describe('Event Function', () => { }); it('returns a 500 if the function throws an exception', async () => { - const server = getServer( - () => { - throw 'I crashed'; - }, - 'event', - /*enableExecutionId=*/ false - ); + const server = getServer(() => { + throw 'I crashed'; + }, testOptions); await supertest(server) .post('/') .send({ diff --git a/test/middleware/timeout.ts b/test/middleware/timeout.ts new file mode 100644 index 00000000..e491ca69 --- /dev/null +++ b/test/middleware/timeout.ts @@ -0,0 +1,58 @@ +import * as assert from 'assert'; +import * as sinon from 'sinon'; +import {NextFunction} from 'express'; +import {Request, Response} from '../../src/functions'; + +import {timeoutMiddleware} from '../../src/middleware/timeout'; + +describe('timeoutMiddleware', () => { + let request: Request; + let response: Response; + let next: NextFunction; + beforeEach(() => { + request = { + setTimeout: sinon.spy(), + on: sinon.spy(), + } as unknown as Request; + response = { + on: sinon.spy(), + } as unknown as Response; + next = sinon.spy(); + }); + + it('calls the next function', () => { + const middleware = timeoutMiddleware(1000); + middleware(request, response, next); + assert.strictEqual((next as sinon.SinonSpy).called, true); + }); + + it('adds an abort controller to the request', function () { + if (!('AbortController' in global)) { + this.skip(); + } + const middleware = timeoutMiddleware(1000); + middleware(request, response, next); + assert.strictEqual(!!request.abortController, true); + }); + + it('adds an abort controller to the request', function () { + if (!('AbortController' in global)) { + this.skip(); + } + const middleware = timeoutMiddleware(1000); + middleware(request, response, next); + assert.strictEqual(!!request.abortController, true); + }); + + it('sets the request timeout', function () { + if (!('AbortController' in global)) { + this.skip(); + } + const middleware = timeoutMiddleware(1000); + middleware(request, response, next); + assert.strictEqual( + (request.setTimeout as sinon.SinonSpy).calledWith(1000), + true + ); + }); +}); diff --git a/test/options.ts b/test/options.ts index e928a0e4..7193f8fc 100644 --- a/test/options.ts +++ b/test/options.ts @@ -59,6 +59,7 @@ describe('parseOptions', () => { signatureType: 'http', printHelp: false, enableExecutionId: false, + timeoutMilliseconds: 0, }, }, { @@ -72,6 +73,8 @@ describe('parseOptions', () => { '--signature-type', 'cloudevent', '--source=/source', + '--timeout', + '6', ], envVars: {}, expectedOptions: { @@ -81,6 +84,7 @@ describe('parseOptions', () => { signatureType: 'cloudevent', printHelp: false, enableExecutionId: false, + timeoutMilliseconds: 6000, }, }, { @@ -91,6 +95,7 @@ describe('parseOptions', () => { FUNCTION_TARGET: 'helloWorld', FUNCTION_SIGNATURE_TYPE: 'cloudevent', FUNCTION_SOURCE: '/source', + CLOUD_RUN_TIMEOUT_SECONDS: '2', }, expectedOptions: { port: '1234', @@ -99,6 +104,7 @@ describe('parseOptions', () => { signatureType: 'cloudevent', printHelp: false, enableExecutionId: false, + timeoutMilliseconds: 2000, }, }, { @@ -112,12 +118,14 @@ describe('parseOptions', () => { '--signature-type', 'cloudevent', '--source=/source', + '--timeout=3', ], envVars: { PORT: '4567', FUNCTION_TARGET: 'fooBar', FUNCTION_SIGNATURE_TYPE: 'event', FUNCTION_SOURCE: '/somewhere/else', + CLOUD_RUN_TIMEOUT_SECONDS: '5', }, expectedOptions: { port: '1234', @@ -126,6 +134,7 @@ describe('parseOptions', () => { signatureType: 'cloudevent', printHelp: false, enableExecutionId: false, + timeoutMilliseconds: 3000, }, }, ]; @@ -197,9 +206,28 @@ describe('parseOptions', () => { }); }); - it('throws an exception for invalid signature types', () => { - assert.throws(() => { - parseOptions(['bin/node', 'index.js', '--signature-type=monkey']); + const validationErrorTestCases: TestData[] = [ + { + name: 'signature type is invalid', + cliOpts: ['bin/node', 'index.js', '--signature-type=monkey'], + envVars: {}, + }, + { + name: 'timeout is not a number', + cliOpts: ['bin/node', '/index.js', '--timeout=foobar'], + envVars: {}, + }, + { + name: 'timeout is a negative number', + cliOpts: ['bin/node', '/index.js', '--timeout=-10'], + envVars: {}, + }, + ]; + validationErrorTestCases.forEach(testCase => { + it('throws an exception when ' + testCase.name, () => { + assert.throws(() => { + parseOptions(testCase.cliOpts, testCase.envVars); + }); }); }); }); From e172f7a9204c6eeba23f08d7e78480de7b6eccad Mon Sep 17 00:00:00 2001 From: Matthew Robertson Date: Mon, 29 Apr 2024 14:39:35 -0700 Subject: [PATCH 05/16] chore: udpate ts-doc annotations (#603) --- docs/generated/api.json | 8 ++--- src/cloud_events.ts | 6 ++-- src/function_registry.ts | 20 +++++------ src/function_wrappers.ts | 34 +++++++++---------- src/functions.ts | 6 ++-- src/invoker.ts | 8 ++--- src/loader.ts | 2 +- src/logger.ts | 6 ++-- .../background_event_to_cloud_event.ts | 18 +++++----- .../cloud_event_to_background_event.ts | 18 +++++----- src/options.ts | 6 ++-- src/pubsub_middleware.ts | 14 ++++---- src/server.ts | 12 +++---- src/testing.ts | 8 ++--- src/types.ts | 4 +-- 15 files changed, 85 insertions(+), 85 deletions(-) diff --git a/docs/generated/api.json b/docs/generated/api.json index 77b0e5eb..d5571315 100644 --- a/docs/generated/api.json +++ b/docs/generated/api.json @@ -175,7 +175,7 @@ { "kind": "Function", "canonicalReference": "@google-cloud/functions-framework!cloudEvent:function(1)", - "docComment": "/**\n * Register a function that handles CloudEvents.\n *\n * @param functionName - the name of the function\n *\n * @param handler - the function to trigger when handling CloudEvents\n *\n * @public\n */\n", + "docComment": "/**\n * Register a function that handles CloudEvents.\n *\n * @param functionName - The name of the function\n *\n * @param handler - The function to trigger when handling CloudEvents\n *\n * @public\n */\n", "excerptTokens": [ { "kind": "Content", @@ -949,7 +949,7 @@ { "kind": "Function", "canonicalReference": "@google-cloud/functions-framework!http:function(1)", - "docComment": "/**\n * Register a function that responds to HTTP requests.\n *\n * @param functionName - the name of the function\n *\n * @param handler - the function to invoke when handling HTTP requests\n *\n * @public\n */\n", + "docComment": "/**\n * Register a function that responds to HTTP requests.\n *\n * @param functionName - The name of the function\n *\n * @param handler - The function to invoke when handling HTTP requests\n *\n * @public\n */\n", "excerptTokens": [ { "kind": "Content", @@ -1125,7 +1125,7 @@ { "kind": "MethodSignature", "canonicalReference": "@google-cloud/functions-framework!InvocationFormat#deserializeRequest:member(1)", - "docComment": "/**\n * Creates an instance of the request type from an invocation request.\n *\n * @param request - the request body as raw bytes\n */\n", + "docComment": "/**\n * Creates an instance of the request type from an invocation request.\n *\n * @param request - The request body as raw bytes\n */\n", "excerptTokens": [ { "kind": "Content", @@ -1180,7 +1180,7 @@ { "kind": "MethodSignature", "canonicalReference": "@google-cloud/functions-framework!InvocationFormat#serializeResponse:member(1)", - "docComment": "/**\n * Writes the response type to the invocation result.\n *\n * @param responseWriter - interface for writing to the invocation result\n *\n * @param response - the response object\n */\n", + "docComment": "/**\n * Writes the response type to the invocation result.\n *\n * @param responseWriter - Interface for writing to the invocation result\n *\n * @param response - The response object\n */\n", "excerptTokens": [ { "kind": "Content", diff --git a/src/cloud_events.ts b/src/cloud_events.ts index 9fb6d816..cf77536d 100644 --- a/src/cloud_events.ts +++ b/src/cloud_events.ts @@ -36,7 +36,7 @@ export const CE_SERVICE = { * * {@link https://github.com/cloudevents/spec/blob/main/http-protocol-binding.md#3-http-message-mapping} * - * @param req - Express request object. + * @param req - Express request object * @return True if the request is a CloudEvents event in binary content mode, * false otherwise. */ @@ -53,8 +53,8 @@ export function isBinaryCloudEvent(req: express.Request): boolean { * Returns a CloudEvents context from the given CloudEvents request. Context * attributes are retrieved from request headers. * - * @param req Express request object. - * @return CloudEvents context. + * @param req - Express request object + * @return CloudEvents context */ export function getBinaryCloudEventContext( req: express.Request diff --git a/src/function_registry.ts b/src/function_registry.ts index cc7038e4..fe0d99b3 100644 --- a/src/function_registry.ts +++ b/src/function_registry.ts @@ -56,7 +56,7 @@ const register = ( * - must be <= 63 characters * - must start with a letter * - must end with a letter or number - * @param functionName the function name + * @param functionName - The function name * @returns true if the function name is valid */ export const isValidFunctionName = (functionName: string): boolean => { @@ -67,9 +67,9 @@ export const isValidFunctionName = (functionName: string): boolean => { /** * Get a declaratively registered function - * @param functionName the name with which the function was registered - * @returns the registered function and signature type or undefined no function matching - * the provided name has been registered. + * @param functionName - The name with which the function was registered + * @returns The registered function and signature type or undefined no function matching + * the provided name has been registered */ export const getRegisteredFunction = ( functionName: string @@ -80,8 +80,8 @@ export const getRegisteredFunction = ( /** * Register a function that responds to HTTP requests. - * @param functionName - the name of the function - * @param handler - the function to invoke when handling HTTP requests + * @param functionName - The name of the function + * @param handler - The function to invoke when handling HTTP requests * @public */ export const http = (functionName: string, handler: HttpFunction): void => { @@ -90,8 +90,8 @@ export const http = (functionName: string, handler: HttpFunction): void => { /** * Register a function that handles CloudEvents. - * @param functionName - the name of the function - * @param handler - the function to trigger when handling CloudEvents + * @param functionName - The name of the function + * @param handler - The function to trigger when handling CloudEvents * @public */ export const cloudEvent = ( @@ -103,8 +103,8 @@ export const cloudEvent = ( /** * Register a function that handles strongly typed invocations. - * @param functionName - the name of the function - * @param handler - the function to trigger + * @param functionName - The name of the function + * @param handler - The function to trigger * @internal */ export const typed = ( diff --git a/src/function_wrappers.ts b/src/function_wrappers.ts index 808baaca..03173eea 100644 --- a/src/function_wrappers.ts +++ b/src/function_wrappers.ts @@ -41,8 +41,8 @@ type OnDoneCallback = (err: Error | null, result: any) => void; /** * Get a completion handler that can be used to signal completion of an event function. - * @param res the response object of the request the completion handler is for. - * @returns an OnDoneCallback for the provided request. + * @param res - The response object of the request the completion handler is for + * @returns An OnDoneCallback for the provided request. */ const getOnDoneCallback = (res: Response): OnDoneCallback => { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -58,8 +58,8 @@ const getOnDoneCallback = (res: Response): OnDoneCallback => { /** * Helper function to parse a CloudEvent object from an HTTP request. - * @param req an Express HTTP request - * @returns a CloudEvent parsed from the request + * @param req - An Express HTTP request + * @returns A CloudEvent parsed from the request */ const parseCloudEventRequest = (req: Request): CloudEvent => { let cloudEvent = req.body; @@ -77,8 +77,8 @@ const parseCloudEventRequest = (req: Request): CloudEvent => { /** * Helper function to background event context and data payload object from an HTTP * request. - * @param req an Express HTTP request - * @returns the data playload and event context parsed from the request + * @param req - An Express HTTP request + * @returns The data playload and event context parsed from the request */ const parseBackgroundEvent = (req: Request): {data: {}; context: Context} => { const event = req.body; @@ -100,8 +100,8 @@ const parseBackgroundEvent = (req: Request): {data: {}; context: Context} => { /** * Wraps the provided function into an Express handler function with additional * instrumentation logic. - * @param execute Runs user's function. - * @return An Express handler function. + * @param execute - Runs user's function + * @return An Express handler function */ const wrapHttpFunction = (execute: HttpFunction): RequestHandler => { return (req: Request, res: Response) => { @@ -132,8 +132,8 @@ const wrapHttpFunction = (execute: HttpFunction): RequestHandler => { /** * Wraps an async CloudEvent function in an express RequestHandler. - * @param userFunction User's function. - * @return An Express hander function that invokes the user function. + * @param userFunction - User's function + * @return An Express hander function that invokes the user function */ const wrapCloudEventFunction = ( userFunction: CloudEventFunction @@ -153,8 +153,8 @@ const wrapCloudEventFunction = ( /** * Wraps callback style CloudEvent function in an express RequestHandler. - * @param userFunction User's function. - * @return An Express hander function that invokes the user function. + * @param userFunction - User's function + * @return An Express hander function that invokes the user function */ const wrapCloudEventFunctionWithCallback = ( userFunction: CloudEventFunctionWithCallback @@ -169,8 +169,8 @@ const wrapCloudEventFunctionWithCallback = ( /** * Wraps an async event function in an express RequestHandler. - * @param userFunction User's function. - * @return An Express hander function that invokes the user function. + * @param userFunction - User's function + * @return An Express hander function that invokes the user function */ const wrapEventFunction = (userFunction: EventFunction): RequestHandler => { const httpHandler = (req: Request, res: Response) => { @@ -188,8 +188,8 @@ const wrapEventFunction = (userFunction: EventFunction): RequestHandler => { /** * Wraps a callback style event function in an express RequestHandler. - * @param userFunction User's function. - * @return An Express hander function that invokes the user function. + * @param userFunction - User's function + * @return An Express hander function that invokes the user function */ const wrapEventFunctionWithCallback = ( userFunction: EventFunctionWithCallback @@ -204,7 +204,7 @@ const wrapEventFunctionWithCallback = ( /** * Wraps a typed function in an express style RequestHandler. - * @param userFunction User's function + * @param userFunction - User's function * @return An Express handler function that invokes the user function */ const wrapTypedFunction = (typedFunction: TypedFunction): RequestHandler => { diff --git a/src/functions.ts b/src/functions.ts index c6f1e040..66a4f341 100644 --- a/src/functions.ts +++ b/src/functions.ts @@ -198,15 +198,15 @@ export interface InvocationFormat { /** * Creates an instance of the request type from an invocation request. * - * @param request - the request body as raw bytes + * @param request - The request body as raw bytes */ deserializeRequest(request: InvocationRequest): T | Promise; /** * Writes the response type to the invocation result. * - * @param responseWriter interface for writing to the invocation result - * @param response the response object + * @param responseWriter - Interface for writing to the invocation result + * @param response - The response object */ serializeResponse( responseWriter: InvocationResponse, diff --git a/src/invoker.ts b/src/invoker.ts index 6d33f8a1..8c4e1883 100644 --- a/src/invoker.ts +++ b/src/invoker.ts @@ -34,9 +34,9 @@ export const setLatestRes = (res: express.Response) => { /** * Sends back a response to the incoming request. - * @param result Output from function execution. - * @param err Error from function execution. - * @param res Express response object. + * @param result - Output from function execution + * @param err - Error from function execution + * @param res - Express response object */ export function sendResponse( @@ -79,7 +79,7 @@ const killInstance = process.exit.bind(process, 16); /** * Enables registration of error handlers. - * @param server HTTP server which invokes user's function. + * @param server - HTTP server which invokes user's function * @constructor */ export class ErrorHandler { diff --git a/src/loader.ts b/src/loader.ts index b1a2d6cc..894bfce8 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -174,7 +174,7 @@ export async function getUserFunction( /** * Returns resolved path to the module containing the user function. * Returns null if the module can not be identified. - * @param codeLocation Directory with user's code. + * @param codeLocation - Directory with user's code * @return Resolved path or null. */ function getFunctionModulePath(codeLocation: string): string | null { diff --git a/src/logger.ts b/src/logger.ts index 6b2ee2e4..90595f78 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -25,9 +25,9 @@ const SEVERITY = 'severity'; /** * Logs an error message and sends back an error response to the incoming * request. - * @param err Error to be logged and sent. - * @param res Express response object. - * @param callback A function to be called synchronously. + * @param err - Error to be logged and sent + * @param res - Express response object + * @param callback - A function to be called synchronously */ export function sendCrashResponse({ err, diff --git a/src/middleware/background_event_to_cloud_event.ts b/src/middleware/background_event_to_cloud_event.ts index e23b8531..9c82a633 100644 --- a/src/middleware/background_event_to_cloud_event.ts +++ b/src/middleware/background_event_to_cloud_event.ts @@ -62,8 +62,8 @@ const CE_SERVICE_TO_RESOURCE_RE = new Map([ /** * Is this request a known GCF event that can be converted to a cloud event. - * @param req the express request object - * @returns true if this request can be converted to a CloudEvent + * @param req - The express request object + * @returns True if this request can be converted to a CloudEvent */ const isConvertableBackgroundEvent = (req: Request): boolean => { const {body} = req; @@ -79,8 +79,8 @@ const isConvertableBackgroundEvent = (req: Request): boolean => { /** * Convert the given HTTP request into the GCF Background Event data / context format. - * @param body the express request object - * @returns a marshalled background event + * @param body - The express request object + * @returns A marshalled background event */ const getBackgroundEvent = (request: Request): LegacyEvent => { let {context} = request.body; @@ -104,8 +104,8 @@ interface ParsedResource { /** * Splits a background event's resource into a CloudEvent service, resource, and subject. - * @param context the GCF event context to parse. - * @returns the CloudEvent service, resource and subject fields for the given GCF event context. + * @param context - The GCF event context to parse + * @returns The CloudEvent service, resource and subject fields for the given GCF event context */ export const splitResource = ( context: CloudFunctionsContext @@ -159,9 +159,9 @@ export const splitResource = ( /** * Express middleware to convert background GCF requests to Cloudevents. This enables functions * using the "cloudevent" signature type to accept requests from a background event producer. - * @param req express request object - * @param res express response object - * @param next function used to pass control to the next middleware function in the stack + * @param req - Express request object + * @param res - Express response object + * @param next - Function used to pass control to the next middleware function in the stack */ export const backgroundEventToCloudEventMiddleware = ( req: Request, diff --git a/src/middleware/cloud_event_to_background_event.ts b/src/middleware/cloud_event_to_background_event.ts index 80c7f8ab..f7a40f6c 100644 --- a/src/middleware/cloud_event_to_background_event.ts +++ b/src/middleware/cloud_event_to_background_event.ts @@ -62,8 +62,8 @@ const CE_SOURCE_REGEX = /\/\/([^/]+)\/(.+)/; /** * Is the given request a known CloudEvent that can be converted to a legacy event. - * @param request express request object - * @returns true if the request can be converted + * @param request - Express request object + * @returns True if the request can be converted */ const isConvertableCloudEvent = (request: Request): boolean => { if (isBinaryCloudEvent(request)) { @@ -75,8 +75,8 @@ const isConvertableCloudEvent = (request: Request): boolean => { /** * Splits a CloudEvent source string into resource and subject components. - * @param source the cloud event source - * @returns the parsed service and name components of the CE source string + * @param source - The cloud event source + * @returns The parsed service and name components of the CE source string */ export const parseSource = ( source: string @@ -95,8 +95,8 @@ export const parseSource = ( /** * Marshal a known GCP CloudEvent request the equivalent context/data legacy event format. - * @param req express request object - * @returns the request body of the equivalent legacy event request + * @param req - Express request object + * @returns The request body of the equivalent legacy event request */ const marshalConvertableCloudEvent = ( req: Request @@ -173,9 +173,9 @@ const marshalConvertableCloudEvent = ( /** * Express middleware to convert cloud event requests to legacy GCF events. This enables * functions using the "EVENT" signature type to accept requests from a cloud event producer. - * @param req express request object - * @param res express response object - * @param next function used to pass control to the next middle middleware function in the stack + * @param req - Express request object + * @param res - Express response object + * @param next - Function used to pass control to the next middle middleware function in the stack */ export const cloudEventToBackgroundEventMiddleware = ( req: Request, diff --git a/src/options.ts b/src/options.ts index 7f1cd7e3..4733868b 100644 --- a/src/options.ts +++ b/src/options.ts @@ -162,9 +162,9 @@ Documentation: /** * Parse the configurable framework options from the provided CLI arguments and * environment variables. - * @param cliArgs the raw command line arguments - * @param envVars the environment variables to parse options from - * @returns the parsed options that should be used to configure the framework. + * @param cliArgs - The raw command line arguments + * @param envVars - The environment variables to parse options from + * @returns The parsed options that should be used to configure the framework */ export const parseOptions = ( cliArgs: string[] = process.argv, diff --git a/src/pubsub_middleware.ts b/src/pubsub_middleware.ts index f8f04f45..471fffab 100644 --- a/src/pubsub_middleware.ts +++ b/src/pubsub_middleware.ts @@ -89,7 +89,7 @@ export interface MarshalledPubSubBody { /** * Type predicate that checks if a given Request is a RawPubSubRequest - * @param request a Request object to typecheck + * @param request - A Request object to typecheck * @returns true if this Request is a RawPubSubRequest */ // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -106,7 +106,7 @@ const isRawPubSubRequestBody = (body: any): body is RawPubSubBody => { /** * Extract the Pub/Sub topic name from the HTTP request path. - * @param path the URL path of the http request + * @param path - The URL path of the http request * @returns the Pub/Sub topic name if the path matches the expected format, * null otherwise */ @@ -125,8 +125,8 @@ const extractPubSubTopic = (path: string): string | null => { /** * Marshal the body of an HTTP request from a Pub/Sub subscription - * @param body an unmarshalled http request body from a Pub/Sub push subscription - * @param path the HTTP request path + * @param body - An unmarshalled http request body from a Pub/Sub push subscription + * @param path - The HTTP request path * @returns the marshalled request body expected by wrapEventFunction */ const marshalPubSubRequestBody = ( @@ -153,9 +153,9 @@ const marshalPubSubRequestBody = ( /** * Express middleware used to marshal the HTTP request body received directly from a * Pub/Sub subscription into the format that is expected downstream by wrapEventFunction - * @param req express request object - * @param res express response object - * @param next function used to pass control to the next middle middleware function in the stack + * @param req - Express request object + * @param res - Express response object + * @param next - Function used to pass control to the next middle middleware function in the stack */ export const legacyPubSubEventMiddleware = ( req: Request, diff --git a/src/server.ts b/src/server.ts index 9ce9396a..e8ce7451 100644 --- a/src/server.ts +++ b/src/server.ts @@ -31,9 +31,9 @@ import {FrameworkOptions} from './options'; /** * Creates and configures an Express application and returns an HTTP server * which will run it. - * @param userFunction User's function. - * @param options the configured Function Framework options. - * @return HTTP server. + * @param userFunction - User's function + * @param options - The configured Function Framework options + * @return HTTP server */ export function getServer( userFunction: HandlerFunction, @@ -55,9 +55,9 @@ export function getServer( * Retains a reference to the raw body buffer to allow access to the raw body * for things like request signature validation. This is used as the "verify" * function in body-parser options. - * @param req Express request object. - * @param res Express response object. - * @param buf Buffer to be saved. + * @param req - Express request object + * @param res - Express response object + * @param buf - Buffer to be saved */ function rawBodySaver(req: Request, res: Response, buf: Buffer) { req.rawBody = buf; diff --git a/src/testing.ts b/src/testing.ts index 3360a000..9cb62c9d 100644 --- a/src/testing.ts +++ b/src/testing.ts @@ -21,8 +21,8 @@ import {getServer} from './server'; /** * Testing utility for retrieving a function registered with the Functions Framework - * @param functionName the name of the function to get - * @returns a function that was registered with the Functions Framework + * @param functionName - The name of the function to get + * @returns A function that was registered with the Functions Framework * * @beta */ @@ -36,8 +36,8 @@ export const getFunction = ( * Create an Express server that is configured to invoke a function that was * registered with the Functions Framework. This is a useful utility for testing functions * using [supertest](https://www.npmjs.com/package/supertest). - * @param functionName the name of the function to wrap in the test server - * @returns a function that was registered with the Functions Framework + * @param functionName - The name of the function to wrap in the test server + * @returns A function that was registered with the Functions Framework * * @beta */ diff --git a/src/types.ts b/src/types.ts index ca0279c6..d66bd11d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -28,8 +28,8 @@ export type SignatureType = (typeof SignatureType)[number]; /** * Type guard to test if a provided value is valid SignatureType - * @param x the value to test - * @returns true if the provided value is a valid SignatureType + * @param x - The value to test + * @returns True if the provided value is a valid SignatureType */ // eslint-disable-next-line @typescript-eslint/no-explicit-any export const isValidSignatureType = (x: any): x is SignatureType => { From 0bb6efb6c6a915bc96c50ed5aeda79d7b8e3b15e Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 15:01:31 -0700 Subject: [PATCH 06/16] chore(main): release 3.4.0 (#558) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 14 ++++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 656da6ce..c9279ed8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,20 @@ [1]: https://www.npmjs.com/package/@google-cloud/functions-framework?activeTab=versions +## [3.4.0](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/compare/v3.3.0...v3.4.0) (2024-04-29) + + +### Features + +* AbortController to signal request timeouts ([#600](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/issues/600)) ([7a538e0](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/commit/7a538e09f07cfffde1e2ee1592f53386062639c2)) +* add execution id support ([#592](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/issues/592)) ([1c48074](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/commit/1c48074b749343904f07abd53328a2233eccd47b)) + + +### Bug Fixes + +* etag should not be set on any response ([#571](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/issues/571)) ([89a3abb](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/commit/89a3abb10a815eeb37bc779ae7015e751765cf62)) +* framework fails to shutdown gracefully when exit code is a string ([#545](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/issues/545)) ([5355069](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/commit/53550694b56c80cf326d21198cd65d641cfbbc17)) + ## [3.3.0](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/compare/v3.2.1...v3.3.0) (2023-06-28) diff --git a/package-lock.json b/package-lock.json index 4f380025..183ed75c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@google-cloud/functions-framework", - "version": "3.3.0", + "version": "3.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@google-cloud/functions-framework", - "version": "3.3.0", + "version": "3.4.0", "license": "Apache-2.0", "dependencies": { "@types/express": "4.17.21", diff --git a/package.json b/package.json index f460a687..f7f51353 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@google-cloud/functions-framework", - "version": "3.3.0", + "version": "3.4.0", "description": "FaaS (Function as a service) framework for writing portable Node.js functions", "engines": { "node": ">=10.0.0" From 96ae8aa74fbe6418bbf625dff69fd25c0d4ca6ea Mon Sep 17 00:00:00 2001 From: HKWinterhalter Date: Sun, 2 Jun 2024 23:47:09 -0700 Subject: [PATCH 07/16] chore: Update blunderbuss.yml (#611) --- .github/blunderbuss.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index d48dd34e..8b137891 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -1,5 +1 @@ -assign_prs: - - HKWinterhalter -assign_issues: - - HKWinterhalter From 47003fdc7c7b1315fb219233928222593d606b93 Mon Sep 17 00:00:00 2001 From: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> Date: Mon, 8 Jul 2024 13:00:02 -0700 Subject: [PATCH 08/16] fix: if execution id support requested for node 12, fail open and drop execution id support instead of crashing out (#618) --- src/options.ts | 8 ++++++-- test/options.ts | 6 ++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/options.ts b/src/options.ts index 4733868b..96de71c8 100644 --- a/src/options.ts +++ b/src/options.ts @@ -146,9 +146,13 @@ const ExecutionIdOption = new ConfigurableOption( (typeof x === 'boolean' && x) || (typeof x === 'string' && x.toLowerCase() === 'true'); if (isTrue && !isVersionSatisfied) { - throw new OptionsError( - `Execution id is only supported with Node.js versions ${requiredNodeJsVersionForLogExecutionID} and above. Your current version is ${nodeVersion}. Please upgrade.` + console.warn( + `Execution id is only supported with Node.js versions + ${requiredNodeJsVersionForLogExecutionID} and above. Your + current version is ${nodeVersion}. Please upgrade.` ); + console.warn('Proceeding with execution id support disabled...'); + return false; } return isTrue; } diff --git a/test/options.ts b/test/options.ts index 7193f8fc..bf1619d0 100644 --- a/test/options.ts +++ b/test/options.ts @@ -193,14 +193,12 @@ describe('parseOptions', () => { executionIdTestData.forEach(testCase => { it(testCase.name, () => { + const options = parseOptions(testCase.cliOpts, testCase.envVars); if ( semver.lt(process.versions.node, requiredNodeJsVersionForLogExecutionID) ) { - assert.throws(() => { - parseOptions(testCase.cliOpts, testCase.envVars); - }); + assert.strictEqual(options.enableExecutionId, false); } else { - const options = parseOptions(testCase.cliOpts, testCase.envVars); assert.strictEqual(options.enableExecutionId, true); } }); From 33a7266900a8030f4f1f7fd6b11e4293e75b4a9e Mon Sep 17 00:00:00 2001 From: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:41:46 -0700 Subject: [PATCH 09/16] fix: parse structured logs, and handle ANSI escape codes in logs (#620) `firebase-functions/logger` writes structured logs to stdout and stderr by default, and makes these pretty with ANSI color codes. When functions-framework intercepts these messages to assign execution IDs, it handles them incorrectly in two ways. First, when the log emitted on stdout or stderr is already a structured log, we override (ignore) the severity set by the logger. This commit avoids changing severity if it's already set. Second, when parsing the message and attempting to determine if it's already a json object/structured log, it doesn't handle ANSI escape codes (https://en.wikipedia.org/wiki/ANSI_escape_code) used to control color, so parsing these will fail. This means that severity handling falls back to just looking at whether the message came from stdout or stderr, so debug-level and warn-level logs aren't handled correctly. This commit strips all ANSI escape codes that control terminal color. This is a minor bummer because it's a whole lot less pretty, but color-coding and smarter color coding generally seems less important than correct log-level handling. Fixes #617. --- .eslintrc.json | 5 ++++- src/logger.ts | 21 +++++++++++++++++---- test/logger.ts | 30 ++++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index eb23147b..1281c0ee 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,3 +1,6 @@ { - "extends": "./node_modules/gts" + "extends": "./node_modules/gts", + "rules": { + "no-control-regex": 0 + } } diff --git a/src/logger.ts b/src/logger.ts index 90595f78..57da7fdf 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -127,14 +127,24 @@ export function getModifiedData( return data; } const {isJSON, processedData} = processData(data, encoding); - let dataWithContext; + + let dataWithContext: { + message: string | Uint8Array; + 'logging.googleapis.com/labels': {execution_id: string | undefined}; + 'logging.googleapis.com/trace': string | undefined; + 'logging.googleapis.com/spanId': string | undefined; + severity?: string | undefined; + }; if (isJSON) { dataWithContext = getJSONWithContext(processedData, currentContext); + if (stderr && !(SEVERITY in dataWithContext)) { + dataWithContext[SEVERITY] = 'ERROR'; + } } else { dataWithContext = getTextWithContext(processedData, currentContext); - } - if (stderr) { - dataWithContext[SEVERITY] = 'ERROR'; + if (stderr) { + dataWithContext[SEVERITY] = 'ERROR'; + } } return JSON.stringify(dataWithContext) + '\n'; @@ -178,6 +188,9 @@ function processData(data: Uint8Array | string, encoding?: BufferEncoding) { return {isJSON: false, processedData: data}; } + // strip any leading ANSI color codes from the decoded data + // to parse colored JSON objects correctly + decodedData = decodedData.replace(/\x1b[[(?);]{0,2}(;?\d)*./g, ''); try { return {isJSON: true, processedData: JSON.parse(decodedData)}; } catch (e) { diff --git a/test/logger.ts b/test/logger.ts index 732598b4..126e5cb2 100644 --- a/test/logger.ts +++ b/test/logger.ts @@ -148,4 +148,34 @@ describe('getModifiedData', () => { ) + '\n'; assert.equal(modifiedData, expectedOutput); }); + + it('parses firebase warning severity and message', () => { + const modifiedData = ( + getModifiedData( + '\u001b[33m{"severity":"WARNING","message":"testing warning log level"}\u001b[39m\n', + undefined, + true + ) + ); + assert.equal('WARNING', JSON.parse(modifiedData)['severity']); + assert.equal( + 'testing warning log level', + JSON.parse(modifiedData)['message'] + ); + }); + + it('parses firebase error severity and message', () => { + const modifiedData = ( + getModifiedData( + '\u001b[31m{"severity":"ERROR","message":"testing error log level"}\u001b[39m\n', + undefined, + true + ) + ); + assert.equal('ERROR', JSON.parse(modifiedData)['severity']); + assert.equal( + 'testing error log level', + JSON.parse(modifiedData)['message'] + ); + }); }); From 531fce25f0e06faf34a2b8ae13e4bfc7c1367706 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 17:58:09 -0700 Subject: [PATCH 10/16] chore(deps-dev): bump braces from 3.0.2 to 3.0.3 (#614) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- package-lock.json | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 183ed75c..6ae7d6ff 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1223,12 +1223,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2403,9 +2403,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -6713,12 +6713,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browser-stdout": { @@ -7588,9 +7588,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" From f419420da1d28297420ffbc2bbbdc6d8326318e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 09:18:23 -0700 Subject: [PATCH 11/16] chore(deps-dev): bump braces from 3.0.2 to 3.0.3 in /experimental/generate_cloud_events (#621) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../generate_cloud_events/package-lock.json | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/experimental/generate_cloud_events/package-lock.json b/experimental/generate_cloud_events/package-lock.json index d61b43d3..e39d0132 100644 --- a/experimental/generate_cloud_events/package-lock.json +++ b/experimental/generate_cloud_events/package-lock.json @@ -456,12 +456,23 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" + }, + "dependencies": { + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + } } }, "callsites": { @@ -997,15 +1008,6 @@ "flat-cache": "^3.0.4" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", From df37f6e9dfe43181fd912786717de1d9268d9247 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 09:26:18 -0700 Subject: [PATCH 12/16] chore(main): release 3.4.1 (#619) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- CHANGELOG.md | 8 ++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9279ed8..2d17b640 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ [1]: https://www.npmjs.com/package/@google-cloud/functions-framework?activeTab=versions +## [3.4.1](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/compare/v3.4.0...v3.4.1) (2024-07-09) + + +### Bug Fixes + +* if execution id support requested for node 12, fail open and drop execution id support instead of crashing out ([#618](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/issues/618)) ([47003fd](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/commit/47003fdc7c7b1315fb219233928222593d606b93)) +* parse structured logs, and handle ANSI escape codes in logs ([#620](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/issues/620)) ([33a7266](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/commit/33a7266900a8030f4f1f7fd6b11e4293e75b4a9e)) + ## [3.4.0](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/compare/v3.3.0...v3.4.0) (2024-04-29) diff --git a/package-lock.json b/package-lock.json index 6ae7d6ff..d69c641f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@google-cloud/functions-framework", - "version": "3.4.0", + "version": "3.4.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@google-cloud/functions-framework", - "version": "3.4.0", + "version": "3.4.1", "license": "Apache-2.0", "dependencies": { "@types/express": "4.17.21", diff --git a/package.json b/package.json index f7f51353..d8e8600c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@google-cloud/functions-framework", - "version": "3.4.0", + "version": "3.4.1", "description": "FaaS (Function as a service) framework for writing portable Node.js functions", "engines": { "node": ">=10.0.0" From 5c3dd969aa0b8323909e1af79a0c011e45767ed4 Mon Sep 17 00:00:00 2001 From: Mend Renovate Date: Tue, 9 Jul 2024 22:47:57 +0200 Subject: [PATCH 13/16] chore(deps): update dependency @types/sinon to v17 (#612) Co-authored-by: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> --- package-lock.json | 66 +++++++++++++++-------------------------------- package.json | 2 +- 2 files changed, 22 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index d69c641f..5f69b14e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "@types/node": "^20.11.24", "@types/on-finished": "2.3.4", "@types/semver": "^7.3.6", - "@types/sinon": "^10.0.0", + "@types/sinon": "^17.0.0", "@types/supertest": "2.0.16", "gts": "5.3.0", "mocha": "9.2.2", @@ -473,24 +473,6 @@ "string-argv": "~0.3.1" } }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, "node_modules/@sinonjs/samsam": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", @@ -638,14 +620,20 @@ } }, "node_modules/@types/sinon": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.6.tgz", - "integrity": "sha512-6EF+wzMWvBNeGrfP3Nx60hhx+FfwSg1JJBLAAP/IdIUq0EYkqCYf70VT3PhuhPX9eLD+Dp+lNdpb/ZeHG8Yezg==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", "dev": true, "dependencies": { - "@sinonjs/fake-timers": "^7.1.0" + "@types/sinonjs__fake-timers": "*" } }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true + }, "node_modules/@types/superagent": { "version": "4.1.13", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.13.tgz", @@ -6143,24 +6131,6 @@ "string-argv": "~0.3.1" } }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz", - "integrity": "sha512-iQADsW4LBMISqZ6Ci1dupJL9pprqwcVFTcOsEmQOEhW+KLCVn/Y4Jrvg2k19fIHCp+iFprriYPTdRcQR8NbUPg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, "@sinonjs/samsam": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", @@ -6310,14 +6280,20 @@ } }, "@types/sinon": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.6.tgz", - "integrity": "sha512-6EF+wzMWvBNeGrfP3Nx60hhx+FfwSg1JJBLAAP/IdIUq0EYkqCYf70VT3PhuhPX9eLD+Dp+lNdpb/ZeHG8Yezg==", + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", "dev": true, "requires": { - "@sinonjs/fake-timers": "^7.1.0" + "@types/sinonjs__fake-timers": "*" } }, + "@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true + }, "@types/superagent": { "version": "4.1.13", "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.13.tgz", diff --git a/package.json b/package.json index d8e8600c..052dae81 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "@types/node": "^20.11.24", "@types/on-finished": "2.3.4", "@types/semver": "^7.3.6", - "@types/sinon": "^10.0.0", + "@types/sinon": "^17.0.0", "@types/supertest": "2.0.16", "gts": "5.3.0", "mocha": "9.2.2", From 5bd82de7fff4e41967974587dbe389a1d637f78b Mon Sep 17 00:00:00 2001 From: liuyunn Date: Mon, 22 Jul 2024 13:51:50 -0700 Subject: [PATCH 14/16] fix: Don't set severity level for text log. (#625) --- src/logger.ts | 3 --- test/logger.ts | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/logger.ts b/src/logger.ts index 57da7fdf..2b144e4a 100644 --- a/src/logger.ts +++ b/src/logger.ts @@ -142,9 +142,6 @@ export function getModifiedData( } } else { dataWithContext = getTextWithContext(processedData, currentContext); - if (stderr) { - dataWithContext[SEVERITY] = 'ERROR'; - } } return JSON.stringify(dataWithContext) + '\n'; diff --git a/test/logger.ts b/test/logger.ts index 126e5cb2..52462cba 100644 --- a/test/logger.ts +++ b/test/logger.ts @@ -134,9 +134,7 @@ describe('getModifiedData', () => { it('simple text with error', () => { const modifiedData = getModifiedData(sampleText, undefined, true); const expectedOutput = - JSON.stringify( - Object.assign(JSON.parse(expectedTextOutput), {severity: 'ERROR'}) - ) + '\n'; + JSON.stringify(Object.assign(JSON.parse(expectedTextOutput))) + '\n'; assert.equal(modifiedData, expectedOutput); }); From 74c0f84d6e228e91cfb110cc4a8e1eaf20213ba9 Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 15:36:34 -0700 Subject: [PATCH 15/16] chore(main): release 3.4.2 (#626) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d17b640..28d40c8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,13 @@ [1]: https://www.npmjs.com/package/@google-cloud/functions-framework?activeTab=versions +## [3.4.2](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/compare/v3.4.1...v3.4.2) (2024-07-22) + + +### Bug Fixes + +* Don't set severity level for text log. ([#625](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/issues/625)) ([5bd82de](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/commit/5bd82de7fff4e41967974587dbe389a1d637f78b)) + ## [3.4.1](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/compare/v3.4.0...v3.4.1) (2024-07-09) diff --git a/package-lock.json b/package-lock.json index 5f69b14e..0c75ba1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@google-cloud/functions-framework", - "version": "3.4.1", + "version": "3.4.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@google-cloud/functions-framework", - "version": "3.4.1", + "version": "3.4.2", "license": "Apache-2.0", "dependencies": { "@types/express": "4.17.21", diff --git a/package.json b/package.json index 052dae81..57bb3436 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@google-cloud/functions-framework", - "version": "3.4.1", + "version": "3.4.2", "description": "FaaS (Function as a service) framework for writing portable Node.js functions", "engines": { "node": ">=10.0.0" From 45d803b41f098c7894f40df71cbdd8bf5548c094 Mon Sep 17 00:00:00 2001 From: Jeremy Fehr <117788025+jrmfg@users.noreply.github.com> Date: Wed, 18 Sep 2024 09:02:23 -0700 Subject: [PATCH 16/16] chore: Update blunderbuss.yml (#636) --- .github/blunderbuss.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/blunderbuss.yml b/.github/blunderbuss.yml index 8b137891..30123090 100644 --- a/.github/blunderbuss.yml +++ b/.github/blunderbuss.yml @@ -1 +1,11 @@ +assign_prs: + - HKwinterhalter + - jihuin + - chujchen + - liuyunnnn +assign_issues: + - HKwinterhalter + - jihuin + - chujchen + - liuyunnnn