From b089f2045062ed315eca6808d21f7952ebdb3543 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Fri, 4 Nov 2022 14:14:15 -0300 Subject: [PATCH 01/46] add RE2 --- npm-shrinkwrap.json | 205 +++++++++----------------------------------- package.json | 1 + 2 files changed, 43 insertions(+), 163 deletions(-) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index a8c9e68dfb4..91f09f8e0a4 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -50,6 +50,7 @@ "portfinder": "^1.0.32", "progress": "^2.0.3", "proxy-agent": "^5.0.0", + "re2": "^1.17.7", "request": "^2.87.0", "retry": "^0.13.1", "rimraf": "^3.0.0", @@ -1425,8 +1426,7 @@ "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "optional": true + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" }, "node_modules/@google-cloud/common": { "version": "3.5.0", @@ -2190,7 +2190,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "optional": true, "dependencies": { "@gar/promisify": "^1.1.3", "semver": "^7.3.5" @@ -2203,7 +2202,6 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "optional": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -2218,7 +2216,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "optional": true, "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -2231,7 +2228,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "optional": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -3382,8 +3378,7 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "optional": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/abort-controller": { "version": "3.0.0", @@ -3472,7 +3467,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", - "optional": true, "dependencies": { "debug": "^4.1.0", "depd": "^1.1.2", @@ -3486,7 +3480,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, "dependencies": { "ms": "2.1.2" }, @@ -3502,14 +3495,12 @@ "node_modules/agentkeepalive/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "devOptional": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -3663,8 +3654,7 @@ "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "optional": true + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" }, "node_modules/archiver": { "version": "5.3.1", @@ -3732,7 +3722,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "optional": true, "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -4262,7 +4251,6 @@ "version": "16.1.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "optional": true, "dependencies": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", @@ -4291,7 +4279,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "optional": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -4300,7 +4287,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "optional": true, "engines": { "node": ">=10" } @@ -4309,7 +4295,6 @@ "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "optional": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4328,7 +4313,6 @@ "version": "7.14.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", - "optional": true, "engines": { "node": ">=12" } @@ -4337,7 +4321,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "optional": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4349,7 +4332,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "optional": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -4361,7 +4343,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "optional": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -4628,7 +4609,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "devOptional": true, "engines": { "node": ">=6" } @@ -4779,7 +4759,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "optional": true, "bin": { "color-support": "bin.js" } @@ -4977,8 +4956,7 @@ "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "optional": true + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "node_modules/content-disposition": { "version": "0.5.3", @@ -5336,8 +5314,7 @@ "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "optional": true + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, "node_modules/depd": { "version": "1.1.2", @@ -5571,7 +5548,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "optional": true, "engines": { "node": ">=6" } @@ -5584,8 +5560,7 @@ "node_modules/err-code": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "optional": true + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" }, "node_modules/error-ex": { "version": "1.3.2", @@ -7093,7 +7068,6 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "optional": true, "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", @@ -8043,8 +8017,7 @@ "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "optional": true + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, "node_modules/has-yarn": { "version": "2.1.0", @@ -8228,7 +8201,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "optional": true, "dependencies": { "ms": "^2.0.0" } @@ -8314,7 +8286,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "devOptional": true, "engines": { "node": ">=8" } @@ -8322,8 +8293,7 @@ "node_modules/infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "optional": true + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" }, "node_modules/inflight": { "version": "1.0.6", @@ -8461,7 +8431,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.1.tgz", "integrity": "sha512-3l3Bymg2eKDsN5wQuMfgGEj2x6l5MCAv0zPL6rxHESufFVlEAKW/6oY9F1aGgvY/EgWm5+eWGRjINveL4X7Hgg==", - "optional": true, "bin": { "install-from-cache": "bin/install-from-cache.js", "save-to-github-cache": "bin/save-to-github-cache.js" @@ -8581,8 +8550,7 @@ "node_modules/is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "optional": true + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" }, "node_modules/is-npm": { "version": "4.0.0", @@ -9633,7 +9601,6 @@ "version": "10.2.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "optional": true, "dependencies": { "agentkeepalive": "^4.2.1", "cacache": "^16.1.0", @@ -9660,7 +9627,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "optional": true, "engines": { "node": ">= 10" } @@ -9669,7 +9635,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, "dependencies": { "ms": "2.1.2" }, @@ -9686,7 +9651,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "optional": true, "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -9700,7 +9664,6 @@ "version": "7.14.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", - "optional": true, "engines": { "node": ">=12" } @@ -9708,14 +9671,12 @@ "node_modules/make-fetch-happen/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/make-fetch-happen/node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "optional": true, "engines": { "node": ">= 0.6" } @@ -9724,7 +9685,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "optional": true, "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -9992,7 +9952,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -10004,7 +9963,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", - "optional": true, "dependencies": { "minipass": "^3.1.6", "minipass-sized": "^1.0.3", @@ -10021,7 +9979,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -10033,7 +9990,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -10045,7 +10001,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -10280,8 +10235,7 @@ "node_modules/nan": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", - "optional": true + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" }, "node_modules/nanoid": { "version": "3.2.0", @@ -10493,7 +10447,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.1.0.tgz", "integrity": "sha512-HkmN0ZpQJU7FLbJauJTHkHlSVAXlNGDAzH/VYFZGDOnFyn/Na3GlNJfkudmufOdS6/jNFhy88ObzL7ERz9es1g==", - "optional": true, "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", @@ -10517,7 +10470,6 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "optional": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -10532,7 +10484,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "optional": true, "dependencies": { "isexe": "^2.0.0" }, @@ -10607,7 +10558,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "optional": true, "dependencies": { "abbrev": "1" }, @@ -10650,7 +10600,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "optional": true, "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", @@ -11639,8 +11588,7 @@ "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "optional": true + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" }, "node_modules/promise-polyfill": { "version": "8.1.3", @@ -11652,7 +11600,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "optional": true, "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -11665,7 +11612,6 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "optional": true, "engines": { "node": ">= 4" } @@ -12010,7 +11956,6 @@ "resolved": "https://registry.npmjs.org/re2/-/re2-1.17.7.tgz", "integrity": "sha512-X8GSuiBoVWwcjuppqSjsIkRxNUKDdjhkO9SBekQbZ2ksqWUReCy7DQPWOVpoTnpdtdz5PIpTTxTFzvJv5UMfjA==", "hasInstallScript": true, - "optional": true, "dependencies": { "install-artifact-from-github": "^1.3.1", "nan": "^2.16.0", @@ -12633,8 +12578,7 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "devOptional": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "node_modules/setimmediate": { "version": "1.0.5", @@ -13011,7 +12955,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "optional": true, "dependencies": { "minipass": "^3.1.1" }, @@ -14193,7 +14136,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "optional": true, "dependencies": { "unique-slug": "^3.0.0" }, @@ -14205,7 +14147,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "optional": true, "dependencies": { "imurmurhash": "^0.1.4" }, @@ -14787,7 +14728,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "optional": true, "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } @@ -16175,8 +16115,7 @@ "@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "optional": true + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" }, "@google-cloud/common": { "version": "3.5.0", @@ -16772,7 +16711,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "optional": true, "requires": { "@gar/promisify": "^1.1.3", "semver": "^7.3.5" @@ -16782,7 +16720,6 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "optional": true, "requires": { "lru-cache": "^6.0.0" } @@ -16793,7 +16730,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "optional": true, "requires": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -16802,8 +16738,7 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "optional": true + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" } } }, @@ -17789,8 +17724,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "optional": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "abort-controller": { "version": "3.0.0", @@ -17853,7 +17787,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", - "optional": true, "requires": { "debug": "^4.1.0", "depd": "^1.1.2", @@ -17864,7 +17797,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, "requires": { "ms": "2.1.2" } @@ -17872,8 +17804,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -17881,7 +17812,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "devOptional": true, "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -17993,8 +17923,7 @@ "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "optional": true + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" }, "archiver": { "version": "5.3.1", @@ -18060,7 +17989,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "optional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -18461,7 +18389,6 @@ "version": "16.1.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "optional": true, "requires": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", @@ -18487,7 +18414,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "optional": true, "requires": { "balanced-match": "^1.0.0" } @@ -18495,14 +18421,12 @@ "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "optional": true + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, "glob": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", - "optional": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -18514,14 +18438,12 @@ "lru-cache": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", - "optional": true + "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==" }, "minimatch": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "optional": true, "requires": { "brace-expansion": "^2.0.1" } @@ -18529,14 +18451,12 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "optional": true + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "optional": true, "requires": { "aggregate-error": "^3.0.0" } @@ -18731,8 +18651,7 @@ "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "devOptional": true + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" }, "cli-boxes": { "version": "2.2.1", @@ -18843,8 +18762,7 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "optional": true + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, "colorette": { "version": "2.0.19", @@ -19004,8 +18922,7 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "optional": true + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "content-disposition": { "version": "0.5.3", @@ -19282,8 +19199,7 @@ "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "optional": true + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, "depd": { "version": "1.1.2", @@ -19493,8 +19409,7 @@ "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "optional": true + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" }, "env-variable": { "version": "0.0.6", @@ -19504,8 +19419,7 @@ "err-code": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "optional": true + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" }, "error-ex": { "version": "1.3.2", @@ -20637,7 +20551,6 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "optional": true, "requires": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", @@ -21400,8 +21313,7 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "optional": true + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, "has-yarn": { "version": "2.1.0", @@ -21556,7 +21468,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "optional": true, "requires": { "ms": "^2.0.0" } @@ -21609,14 +21520,12 @@ "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "devOptional": true + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "optional": true + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" }, "inflight": { "version": "1.0.6", @@ -21719,8 +21628,7 @@ "install-artifact-from-github": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.1.tgz", - "integrity": "sha512-3l3Bymg2eKDsN5wQuMfgGEj2x6l5MCAv0zPL6rxHESufFVlEAKW/6oY9F1aGgvY/EgWm5+eWGRjINveL4X7Hgg==", - "optional": true + "integrity": "sha512-3l3Bymg2eKDsN5wQuMfgGEj2x6l5MCAv0zPL6rxHESufFVlEAKW/6oY9F1aGgvY/EgWm5+eWGRjINveL4X7Hgg==" }, "ip": { "version": "1.1.5", @@ -21803,8 +21711,7 @@ "is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "optional": true + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" }, "is-npm": { "version": "4.0.0", @@ -22681,7 +22588,6 @@ "version": "10.2.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "optional": true, "requires": { "agentkeepalive": "^4.2.1", "cacache": "^16.1.0", @@ -22704,14 +22610,12 @@ "@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "optional": true + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "optional": true, "requires": { "ms": "2.1.2" } @@ -22720,7 +22624,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "optional": true, "requires": { "@tootallnate/once": "2", "agent-base": "6", @@ -22730,26 +22633,22 @@ "lru-cache": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", - "optional": true + "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==" }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "optional": true + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "socks-proxy-agent": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "optional": true, "requires": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -22941,7 +22840,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "optional": true, "requires": { "minipass": "^3.0.0" } @@ -22950,7 +22848,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", - "optional": true, "requires": { "encoding": "^0.1.13", "minipass": "^3.1.6", @@ -22962,7 +22859,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "optional": true, "requires": { "minipass": "^3.0.0" } @@ -22971,7 +22867,6 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "optional": true, "requires": { "minipass": "^3.0.0" } @@ -22980,7 +22875,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "optional": true, "requires": { "minipass": "^3.0.0" } @@ -23154,8 +23048,7 @@ "nan": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", - "optional": true + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" }, "nanoid": { "version": "3.2.0", @@ -23305,7 +23198,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.1.0.tgz", "integrity": "sha512-HkmN0ZpQJU7FLbJauJTHkHlSVAXlNGDAzH/VYFZGDOnFyn/Na3GlNJfkudmufOdS6/jNFhy88ObzL7ERz9es1g==", - "optional": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", @@ -23323,7 +23215,6 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "optional": true, "requires": { "lru-cache": "^6.0.0" } @@ -23332,7 +23223,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "optional": true, "requires": { "isexe": "^2.0.0" } @@ -23393,7 +23283,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "optional": true, "requires": { "abbrev": "1" } @@ -23424,7 +23313,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "optional": true, "requires": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", @@ -24178,8 +24066,7 @@ "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "optional": true + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" }, "promise-polyfill": { "version": "8.1.3", @@ -24191,7 +24078,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "optional": true, "requires": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -24200,8 +24086,7 @@ "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "optional": true + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" } } }, @@ -24472,7 +24357,6 @@ "version": "1.17.7", "resolved": "https://registry.npmjs.org/re2/-/re2-1.17.7.tgz", "integrity": "sha512-X8GSuiBoVWwcjuppqSjsIkRxNUKDdjhkO9SBekQbZ2ksqWUReCy7DQPWOVpoTnpdtdz5PIpTTxTFzvJv5UMfjA==", - "optional": true, "requires": { "install-artifact-from-github": "^1.3.1", "nan": "^2.16.0", @@ -24954,8 +24838,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "devOptional": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "setimmediate": { "version": "1.0.5", @@ -25272,7 +25155,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "optional": true, "requires": { "minipass": "^3.1.1" } @@ -26161,7 +26043,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "optional": true, "requires": { "unique-slug": "^3.0.0" } @@ -26170,7 +26051,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "optional": true, "requires": { "imurmurhash": "^0.1.4" } @@ -26573,7 +26453,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "optional": true, "requires": { "string-width": "^1.0.2 || 2 || 3 || 4" } diff --git a/package.json b/package.json index 93cb8e3fa86..769a6d44df6 100644 --- a/package.json +++ b/package.json @@ -134,6 +134,7 @@ "portfinder": "^1.0.32", "progress": "^2.0.3", "proxy-agent": "^5.0.0", + "re2": "^1.17.7", "request": "^2.87.0", "retry": "^0.13.1", "rimraf": "^3.0.0", From c5bf20477603d462c91975b98f6425439095018e Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Fri, 4 Nov 2022 14:21:55 -0300 Subject: [PATCH 02/46] filter out rewrites not supported by RE2 --- src/frameworks/next/index.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index e13ba65b00e..6ad82f38328 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -6,6 +6,7 @@ import type { NextConfig } from "next"; import { copy, mkdirp, pathExists } from "fs-extra"; import { pathToFileURL, parse } from "url"; import { existsSync } from "fs"; +import RE2 from "re2"; import { BuildResult, @@ -149,11 +150,21 @@ export async function build(dir: string): Promise { const nextJsRewritesToUse = Array.isArray(nextJsRewrites) ? nextJsRewrites : nextJsRewrites.beforeFiles || []; + const rewrites = nextJsRewritesToUse .map(({ source, destination, has }) => { // Can we change i18n into Firebase settings? if (has) return undefined; - return { source, destination }; + + try { + new RE2(source); + new RE2(destination); + + return { source, destination }; + } catch (error) { + // regex not supported by RE2 cannot be transformed into firebase.json rewrites + return undefined; + } }) .filter((it) => it); From 9998dd88f8e71fb1d6a27b7731893f191449f216 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Fri, 4 Nov 2022 14:35:22 -0300 Subject: [PATCH 03/46] filter out rewrites to third parties --- src/frameworks/next/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 6ad82f38328..8e21a1632aa 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -154,7 +154,11 @@ export async function build(dir: string): Promise { const rewrites = nextJsRewritesToUse .map(({ source, destination, has }) => { // Can we change i18n into Firebase settings? - if (has) return undefined; + if ( + has || + destination.includes("http") // filter out rewrites to third parties + ) + return undefined; try { new RE2(source); From 28495f1c89ae0ded9a37e3d55926d4a04fbe36b9 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 7 Nov 2022 15:46:03 -0300 Subject: [PATCH 04/46] check rewrites, redirects and headers w/ same fn --- src/frameworks/next/index.ts | 54 ++++++++++++++++++++++++------------ src/frameworks/utils.ts | 22 +++++++++++++++ 2 files changed, 58 insertions(+), 18 deletions(-) create mode 100644 src/frameworks/utils.ts diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 8e21a1632aa..5e00e7fa832 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -6,7 +6,6 @@ import type { NextConfig } from "next"; import { copy, mkdirp, pathExists } from "fs-extra"; import { pathToFileURL, parse } from "url"; import { existsSync } from "fs"; -import RE2 from "re2"; import { BuildResult, @@ -23,6 +22,7 @@ import { IncomingMessage, ServerResponse } from "http"; import { logger } from "../../logger"; import { FirebaseError } from "../../error"; import { fileExistsSync } from "../../fsutils"; +import { isThirdPartyUrl, supportsFrameworkRegex } from "../utils"; // Next.js's exposed interface is incomplete here // TODO see if there's a better way to grab this @@ -143,34 +143,52 @@ export async function build(dir: string): Promise { redirects: nextJsRedirects = [], rewrites: nextJsRewrites = [], } = manifest; - const headers = nextJsHeaders.map(({ source, headers }) => ({ source, headers })); + + const headers = nextJsHeaders + .filter(({ source }) => { + if (supportsFrameworkRegex(source)) { + return true; + } else { + wantsBackend = true; + return false; + } + }) + .map(({ source, headers }) => ({ source, headers })); + const redirects = nextJsRedirects - .filter(({ internal }: any) => !internal) + .filter(({ internal, source, destination }: any) => { + if (internal) return false; + + if (supportsFrameworkRegex(source) && supportsFrameworkRegex(destination)) { + return true; + } else { + wantsBackend = true; + return false; + } + }) .map(({ source, destination, statusCode: type }) => ({ source, destination, type })); + const nextJsRewritesToUse = Array.isArray(nextJsRewrites) ? nextJsRewrites : nextJsRewrites.beforeFiles || []; const rewrites = nextJsRewritesToUse - .map(({ source, destination, has }) => { + .filter(({ source, destination, has }) => { // Can we change i18n into Firebase settings? - if ( - has || - destination.includes("http") // filter out rewrites to third parties - ) - return undefined; + if (has) return false; - try { - new RE2(source); - new RE2(destination); - - return { source, destination }; - } catch (error) { - // regex not supported by RE2 cannot be transformed into firebase.json rewrites - return undefined; + if ( + supportsFrameworkRegex(source) && + supportsFrameworkRegex(destination) && + isThirdPartyUrl(destination) === false + ) { + return true; + } else { + wantsBackend = true; + return false; } }) - .filter((it) => it); + .map(({ source, destination }) => ({ source, destination })); return { wantsBackend, headers, redirects, rewrites }; } diff --git a/src/frameworks/utils.ts b/src/frameworks/utils.ts new file mode 100644 index 00000000000..946a21f23f6 --- /dev/null +++ b/src/frameworks/utils.ts @@ -0,0 +1,22 @@ +import RE2 from "re2"; + +/** + * Whether the given regex is supported by RE2. If it is firebase.json can use it, + * otherwise the framework server will handle it. + */ +export function supportsFrameworkRegex(regex: string): boolean { + try { + new RE2(regex); + + return true; + } catch (error) { + return false; + } +} + +/** + * Wheter the given URL is an external URL. + */ +export function isThirdPartyUrl(url: string): boolean { + return url.includes("http"); +} From 279012ed2b24267af53ace938a32553ef7134e25 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 7 Nov 2022 16:29:22 -0300 Subject: [PATCH 05/46] isThirdPartyUrl > isUrl, .includes > .startsWith --- src/frameworks/next/index.ts | 4 ++-- src/frameworks/utils.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 5e00e7fa832..034b9e8e5fa 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -22,7 +22,7 @@ import { IncomingMessage, ServerResponse } from "http"; import { logger } from "../../logger"; import { FirebaseError } from "../../error"; import { fileExistsSync } from "../../fsutils"; -import { isThirdPartyUrl, supportsFrameworkRegex } from "../utils"; +import { isUrl, supportsFrameworkRegex } from "../utils"; // Next.js's exposed interface is incomplete here // TODO see if there's a better way to grab this @@ -180,7 +180,7 @@ export async function build(dir: string): Promise { if ( supportsFrameworkRegex(source) && supportsFrameworkRegex(destination) && - isThirdPartyUrl(destination) === false + isUrl(destination) === false ) { return true; } else { diff --git a/src/frameworks/utils.ts b/src/frameworks/utils.ts index 946a21f23f6..b21a192558d 100644 --- a/src/frameworks/utils.ts +++ b/src/frameworks/utils.ts @@ -15,8 +15,8 @@ export function supportsFrameworkRegex(regex: string): boolean { } /** - * Wheter the given URL is an external URL. + * Whether the given string is a URL. */ -export function isThirdPartyUrl(url: string): boolean { - return url.includes("http"); +export function isUrl(url: string): boolean { + return url.startsWith("http"); } From 0352221c326d87d2feec61fa0b7af73a306bd84f Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Tue, 15 Nov 2022 13:39:07 -0300 Subject: [PATCH 06/46] remove RE2, detect regex as stated in Next.js docs also, clean escaped chars from supported `sources` --- npm-shrinkwrap.json | 205 ++++++++++++++++++++++++++++------- package.json | 1 - src/frameworks/next/index.ts | 50 +++++---- src/frameworks/next/utils.ts | 26 +++++ src/frameworks/utils.ts | 16 --- 5 files changed, 219 insertions(+), 79 deletions(-) create mode 100644 src/frameworks/next/utils.ts diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index f134e1db4c1..db6a738cd42 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -50,7 +50,6 @@ "portfinder": "^1.0.32", "progress": "^2.0.3", "proxy-agent": "^5.0.0", - "re2": "^1.17.7", "request": "^2.87.0", "retry": "^0.13.1", "rimraf": "^3.0.0", @@ -1426,7 +1425,8 @@ "node_modules/@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "optional": true }, "node_modules/@google-cloud/common": { "version": "3.5.0", @@ -2190,6 +2190,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "optional": true, "dependencies": { "@gar/promisify": "^1.1.3", "semver": "^7.3.5" @@ -2202,6 +2203,7 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "optional": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -2216,6 +2218,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "optional": true, "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -2228,6 +2231,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -3378,7 +3382,8 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true }, "node_modules/abort-controller": { "version": "3.0.0", @@ -3467,6 +3472,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", + "optional": true, "dependencies": { "debug": "^4.1.0", "depd": "^1.1.2", @@ -3480,6 +3486,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, "dependencies": { "ms": "2.1.2" }, @@ -3495,12 +3502,14 @@ "node_modules/agentkeepalive/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true }, "node_modules/aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "devOptional": true, "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -3654,7 +3663,8 @@ "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true }, "node_modules/archiver": { "version": "5.3.1", @@ -3722,6 +3732,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "optional": true, "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -4251,6 +4262,7 @@ "version": "16.1.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "optional": true, "dependencies": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", @@ -4279,6 +4291,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "optional": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -4287,6 +4300,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true, "engines": { "node": ">=10" } @@ -4295,6 +4309,7 @@ "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "optional": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4313,6 +4328,7 @@ "version": "7.14.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "optional": true, "engines": { "node": ">=12" } @@ -4321,6 +4337,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "optional": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4332,6 +4349,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -4343,6 +4361,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "optional": true, "dependencies": { "aggregate-error": "^3.0.0" }, @@ -4609,6 +4628,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "devOptional": true, "engines": { "node": ">=6" } @@ -4759,6 +4779,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true, "bin": { "color-support": "bin.js" } @@ -4956,7 +4977,8 @@ "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true }, "node_modules/content-disposition": { "version": "0.5.3", @@ -5314,7 +5336,8 @@ "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true }, "node_modules/depd": { "version": "1.1.2", @@ -5548,6 +5571,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, "engines": { "node": ">=6" } @@ -5560,7 +5584,8 @@ "node_modules/err-code": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "optional": true }, "node_modules/error-ex": { "version": "1.3.2", @@ -7068,6 +7093,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "optional": true, "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", @@ -8017,7 +8043,8 @@ "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true }, "node_modules/has-yarn": { "version": "2.1.0", @@ -8201,6 +8228,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "optional": true, "dependencies": { "ms": "^2.0.0" } @@ -8286,6 +8314,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "devOptional": true, "engines": { "node": ">=8" } @@ -8293,7 +8322,8 @@ "node_modules/infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "optional": true }, "node_modules/inflight": { "version": "1.0.6", @@ -8431,6 +8461,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.1.tgz", "integrity": "sha512-3l3Bymg2eKDsN5wQuMfgGEj2x6l5MCAv0zPL6rxHESufFVlEAKW/6oY9F1aGgvY/EgWm5+eWGRjINveL4X7Hgg==", + "optional": true, "bin": { "install-from-cache": "bin/install-from-cache.js", "save-to-github-cache": "bin/save-to-github-cache.js" @@ -8550,7 +8581,8 @@ "node_modules/is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "optional": true }, "node_modules/is-npm": { "version": "4.0.0", @@ -9601,6 +9633,7 @@ "version": "10.2.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "optional": true, "dependencies": { "agentkeepalive": "^4.2.1", "cacache": "^16.1.0", @@ -9627,6 +9660,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "optional": true, "engines": { "node": ">= 10" } @@ -9635,6 +9669,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, "dependencies": { "ms": "2.1.2" }, @@ -9651,6 +9686,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "optional": true, "dependencies": { "@tootallnate/once": "2", "agent-base": "6", @@ -9664,6 +9700,7 @@ "version": "7.14.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "optional": true, "engines": { "node": ">=12" } @@ -9671,12 +9708,14 @@ "node_modules/make-fetch-happen/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true }, "node_modules/make-fetch-happen/node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "optional": true, "engines": { "node": ">= 0.6" } @@ -9685,6 +9724,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "optional": true, "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -9952,6 +9992,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -9963,6 +10004,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "optional": true, "dependencies": { "minipass": "^3.1.6", "minipass-sized": "^1.0.3", @@ -9979,6 +10021,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -9990,6 +10033,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -10001,6 +10045,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "optional": true, "dependencies": { "minipass": "^3.0.0" }, @@ -10235,7 +10280,8 @@ "node_modules/nan": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "optional": true }, "node_modules/nanoid": { "version": "3.2.0", @@ -10447,6 +10493,7 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.1.0.tgz", "integrity": "sha512-HkmN0ZpQJU7FLbJauJTHkHlSVAXlNGDAzH/VYFZGDOnFyn/Na3GlNJfkudmufOdS6/jNFhy88ObzL7ERz9es1g==", + "optional": true, "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", @@ -10470,6 +10517,7 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "optional": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -10484,6 +10532,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "optional": true, "dependencies": { "isexe": "^2.0.0" }, @@ -10558,6 +10607,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, "dependencies": { "abbrev": "1" }, @@ -10600,6 +10650,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "optional": true, "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", @@ -11588,7 +11639,8 @@ "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "optional": true }, "node_modules/promise-polyfill": { "version": "8.1.3", @@ -11600,6 +11652,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "optional": true, "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -11612,6 +11665,7 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "optional": true, "engines": { "node": ">= 4" } @@ -11956,6 +12010,7 @@ "resolved": "https://registry.npmjs.org/re2/-/re2-1.17.7.tgz", "integrity": "sha512-X8GSuiBoVWwcjuppqSjsIkRxNUKDdjhkO9SBekQbZ2ksqWUReCy7DQPWOVpoTnpdtdz5PIpTTxTFzvJv5UMfjA==", "hasInstallScript": true, + "optional": true, "dependencies": { "install-artifact-from-github": "^1.3.1", "nan": "^2.16.0", @@ -12578,7 +12633,8 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "devOptional": true }, "node_modules/setimmediate": { "version": "1.0.5", @@ -12955,6 +13011,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "optional": true, "dependencies": { "minipass": "^3.1.1" }, @@ -14136,6 +14193,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "optional": true, "dependencies": { "unique-slug": "^3.0.0" }, @@ -14147,6 +14205,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "optional": true, "dependencies": { "imurmurhash": "^0.1.4" }, @@ -14728,6 +14787,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } @@ -16115,7 +16175,8 @@ "@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "optional": true }, "@google-cloud/common": { "version": "3.5.0", @@ -16711,6 +16772,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "optional": true, "requires": { "@gar/promisify": "^1.1.3", "semver": "^7.3.5" @@ -16720,6 +16782,7 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "optional": true, "requires": { "lru-cache": "^6.0.0" } @@ -16730,6 +16793,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "optional": true, "requires": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -16738,7 +16802,8 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true } } }, @@ -17724,7 +17789,8 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true }, "abort-controller": { "version": "3.0.0", @@ -17787,6 +17853,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", + "optional": true, "requires": { "debug": "^4.1.0", "depd": "^1.1.2", @@ -17797,6 +17864,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, "requires": { "ms": "2.1.2" } @@ -17804,7 +17872,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true } } }, @@ -17812,6 +17881,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "devOptional": true, "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -17923,7 +17993,8 @@ "aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "optional": true }, "archiver": { "version": "5.3.1", @@ -17989,6 +18060,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "optional": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" @@ -18389,6 +18461,7 @@ "version": "16.1.3", "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "optional": true, "requires": { "@npmcli/fs": "^2.1.0", "@npmcli/move-file": "^2.0.0", @@ -18414,6 +18487,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "optional": true, "requires": { "balanced-match": "^1.0.0" } @@ -18421,12 +18495,14 @@ "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "optional": true }, "glob": { "version": "8.0.3", "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz", "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==", + "optional": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -18438,12 +18514,14 @@ "lru-cache": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==" + "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "optional": true }, "minimatch": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", + "optional": true, "requires": { "brace-expansion": "^2.0.1" } @@ -18451,12 +18529,14 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "optional": true }, "p-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "optional": true, "requires": { "aggregate-error": "^3.0.0" } @@ -18651,7 +18731,8 @@ "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "devOptional": true }, "cli-boxes": { "version": "2.2.1", @@ -18762,7 +18843,8 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "optional": true }, "colorette": { "version": "2.0.19", @@ -18922,7 +19004,8 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "optional": true }, "content-disposition": { "version": "0.5.3", @@ -19199,7 +19282,8 @@ "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "optional": true }, "depd": { "version": "1.1.2", @@ -19409,7 +19493,8 @@ "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true }, "env-variable": { "version": "0.0.6", @@ -19419,7 +19504,8 @@ "err-code": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "optional": true }, "error-ex": { "version": "1.3.2", @@ -20551,6 +20637,7 @@ "version": "4.0.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "optional": true, "requires": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", @@ -21313,7 +21400,8 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "optional": true }, "has-yarn": { "version": "2.1.0", @@ -21468,6 +21556,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "optional": true, "requires": { "ms": "^2.0.0" } @@ -21520,12 +21609,14 @@ "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "devOptional": true }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "optional": true }, "inflight": { "version": "1.0.6", @@ -21628,7 +21719,8 @@ "install-artifact-from-github": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/install-artifact-from-github/-/install-artifact-from-github-1.3.1.tgz", - "integrity": "sha512-3l3Bymg2eKDsN5wQuMfgGEj2x6l5MCAv0zPL6rxHESufFVlEAKW/6oY9F1aGgvY/EgWm5+eWGRjINveL4X7Hgg==" + "integrity": "sha512-3l3Bymg2eKDsN5wQuMfgGEj2x6l5MCAv0zPL6rxHESufFVlEAKW/6oY9F1aGgvY/EgWm5+eWGRjINveL4X7Hgg==", + "optional": true }, "ip": { "version": "1.1.5", @@ -21711,7 +21803,8 @@ "is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "optional": true }, "is-npm": { "version": "4.0.0", @@ -22588,6 +22681,7 @@ "version": "10.2.1", "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "optional": true, "requires": { "agentkeepalive": "^4.2.1", "cacache": "^16.1.0", @@ -22610,12 +22704,14 @@ "@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==" + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "optional": true }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "optional": true, "requires": { "ms": "2.1.2" } @@ -22624,6 +22720,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "optional": true, "requires": { "@tootallnate/once": "2", "agent-base": "6", @@ -22633,22 +22730,26 @@ "lru-cache": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.14.0.tgz", - "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==" + "integrity": "sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==", + "optional": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "optional": true }, "socks-proxy-agent": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "optional": true, "requires": { "agent-base": "^6.0.2", "debug": "^4.3.3", @@ -22840,6 +22941,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "optional": true, "requires": { "minipass": "^3.0.0" } @@ -22848,6 +22950,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "optional": true, "requires": { "encoding": "^0.1.13", "minipass": "^3.1.6", @@ -22859,6 +22962,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "optional": true, "requires": { "minipass": "^3.0.0" } @@ -22867,6 +22971,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "optional": true, "requires": { "minipass": "^3.0.0" } @@ -22875,6 +22980,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "optional": true, "requires": { "minipass": "^3.0.0" } @@ -23048,7 +23154,8 @@ "nan": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.16.0.tgz", - "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==" + "integrity": "sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA==", + "optional": true }, "nanoid": { "version": "3.2.0", @@ -23198,6 +23305,7 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.1.0.tgz", "integrity": "sha512-HkmN0ZpQJU7FLbJauJTHkHlSVAXlNGDAzH/VYFZGDOnFyn/Na3GlNJfkudmufOdS6/jNFhy88ObzL7ERz9es1g==", + "optional": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", @@ -23215,6 +23323,7 @@ "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "optional": true, "requires": { "lru-cache": "^6.0.0" } @@ -23223,6 +23332,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "optional": true, "requires": { "isexe": "^2.0.0" } @@ -23283,6 +23393,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, "requires": { "abbrev": "1" } @@ -23313,6 +23424,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "optional": true, "requires": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", @@ -24066,7 +24178,8 @@ "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "optional": true }, "promise-polyfill": { "version": "8.1.3", @@ -24078,6 +24191,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "optional": true, "requires": { "err-code": "^2.0.2", "retry": "^0.12.0" @@ -24086,7 +24200,8 @@ "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "optional": true } } }, @@ -24357,6 +24472,7 @@ "version": "1.17.7", "resolved": "https://registry.npmjs.org/re2/-/re2-1.17.7.tgz", "integrity": "sha512-X8GSuiBoVWwcjuppqSjsIkRxNUKDdjhkO9SBekQbZ2ksqWUReCy7DQPWOVpoTnpdtdz5PIpTTxTFzvJv5UMfjA==", + "optional": true, "requires": { "install-artifact-from-github": "^1.3.1", "nan": "^2.16.0", @@ -24838,7 +24954,8 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "devOptional": true }, "setimmediate": { "version": "1.0.5", @@ -25155,6 +25272,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "optional": true, "requires": { "minipass": "^3.1.1" } @@ -26043,6 +26161,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "optional": true, "requires": { "unique-slug": "^3.0.0" } @@ -26051,6 +26170,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "optional": true, "requires": { "imurmurhash": "^0.1.4" } @@ -26453,6 +26573,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "optional": true, "requires": { "string-width": "^1.0.2 || 2 || 3 || 4" } diff --git a/package.json b/package.json index 00ca87ecb00..3ccb1fc8118 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,6 @@ "portfinder": "^1.0.32", "progress": "^2.0.3", "proxy-agent": "^5.0.0", - "re2": "^1.17.7", "request": "^2.87.0", "retry": "^0.13.1", "rimraf": "^3.0.0", diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 034b9e8e5fa..2b4fba3d403 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -1,8 +1,8 @@ import { execSync } from "child_process"; import { readFile, mkdir, copyFile } from "fs/promises"; import { dirname, join } from "path"; -import type { Header, Rewrite, Redirect } from "next/dist/lib/load-custom-routes"; import type { NextConfig } from "next"; +import type { Header, Rewrite, Redirect } from "next/dist/lib/load-custom-routes"; import { copy, mkdirp, pathExists } from "fs-extra"; import { pathToFileURL, parse } from "url"; import { existsSync } from "fs"; @@ -22,7 +22,8 @@ import { IncomingMessage, ServerResponse } from "http"; import { logger } from "../../logger"; import { FirebaseError } from "../../error"; import { fileExistsSync } from "../../fsutils"; -import { isUrl, supportsFrameworkRegex } from "../utils"; +import { isUrl } from "../utils"; +import { cleanEscapedChars, pathHasRegex } from "./utils"; // Next.js's exposed interface is incomplete here // TODO see if there's a better way to grab this @@ -137,7 +138,7 @@ export async function build(dir: string): Promise { } const manifestBuffer = await readFile(join(dir, distDir, "routes-manifest.json")); - const manifest: Manifest = JSON.parse(manifestBuffer.toString()); + const manifest = JSON.parse(manifestBuffer.toString()) as Manifest; const { headers: nextJsHeaders = [], redirects: nextJsRedirects = [], @@ -146,27 +147,36 @@ export async function build(dir: string): Promise { const headers = nextJsHeaders .filter(({ source }) => { - if (supportsFrameworkRegex(source)) { - return true; - } else { + if (pathHasRegex(source)) { wantsBackend = true; return false; + } else { + return true; } }) - .map(({ source, headers }) => ({ source, headers })); + .map(({ source, headers }) => ({ + // clean up unnecessary escaping + source: cleanEscapedChars(source), + headers, + })); const redirects = nextJsRedirects - .filter(({ internal, source, destination }: any) => { + .filter(({ internal, source }: any) => { if (internal) return false; - if (supportsFrameworkRegex(source) && supportsFrameworkRegex(destination)) { - return true; - } else { + if (pathHasRegex(source)) { wantsBackend = true; return false; + } else { + return true; } }) - .map(({ source, destination, statusCode: type }) => ({ source, destination, type })); + .map(({ source, destination, statusCode: type }) => ({ + // clean up unnecessary escaping + source: cleanEscapedChars(source), + destination, + type, + })); const nextJsRewritesToUse = Array.isArray(nextJsRewrites) ? nextJsRewrites @@ -177,18 +187,18 @@ export async function build(dir: string): Promise { // Can we change i18n into Firebase settings? if (has) return false; - if ( - supportsFrameworkRegex(source) && - supportsFrameworkRegex(destination) && - isUrl(destination) === false - ) { - return true; - } else { + if (pathHasRegex(source) || isUrl(destination)) { wantsBackend = true; return false; + } else { + return true; } }) - .map(({ source, destination }) => ({ source, destination })); + .map(({ source, destination }) => ({ + // clean up unnecessary escaping + source: cleanEscapedChars(source), + destination, + })); return { wantsBackend, headers, redirects, rewrites }; } diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts new file mode 100644 index 00000000000..c0ae5c675da --- /dev/null +++ b/src/frameworks/next/utils.ts @@ -0,0 +1,26 @@ +/** + * Whether the given path has a regex or not. + * According to the Next.js documentation: + * ```md + * To match a regex path you can wrap the regex in parentheses + * after a parameter, for example /post/:slug(\\d{1,}) will match /post/123 + * but not /post/abc. + * ``` + * See: https://nextjs.org/docs/api-reference/next.config.js/redirects#regex-path-matching + */ +export function pathHasRegex(path: string): boolean { + for (let i = 0; i < path.length; i++) { + if (path[i] === "(" && path[i - 1] !== "\\") { + return true; + } + } + + return false; +} + +/** + * Remove double backslashes from a string + */ +export function cleanEscapedChars(path: string): string { + return path.replaceAll("\\", ""); +} diff --git a/src/frameworks/utils.ts b/src/frameworks/utils.ts index b21a192558d..bc20af2ad23 100644 --- a/src/frameworks/utils.ts +++ b/src/frameworks/utils.ts @@ -1,19 +1,3 @@ -import RE2 from "re2"; - -/** - * Whether the given regex is supported by RE2. If it is firebase.json can use it, - * otherwise the framework server will handle it. - */ -export function supportsFrameworkRegex(regex: string): boolean { - try { - new RE2(regex); - - return true; - } catch (error) { - return false; - } -} - /** * Whether the given string is a URL. */ From 00f3fb1d72ad6800321af226613d0da062bd86de Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Tue, 15 Nov 2022 13:43:03 -0300 Subject: [PATCH 07/46] add unit tests for Next.js utils --- src/test/frameworks/next/utils.spec.ts | 29 ++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/frameworks/next/utils.spec.ts diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts new file mode 100644 index 00000000000..811f037ce3d --- /dev/null +++ b/src/test/frameworks/next/utils.spec.ts @@ -0,0 +1,29 @@ +import { expect } from "chai"; + +import { cleanEscapedChars, pathHasRegex } from "../../../frameworks/next/utils"; + +describe("Next.js utils", () => { + const pathWithRegex = "/post/:slug(\\d{1,})"; + const pathWithEscapedChars = "/post\\(someStringBetweenParentheses\\)/:slug"; + const pathWithRegexAndEscapedChars = "/post/\\(escapedparentheses\\)/:slug(\\d{1,})"; + + describe("pathHasRegex", () => { + it("should identify regex", () => { + expect(pathHasRegex(pathWithRegex)).to.be.true; + }); + + it("should not identify escaped parentheses", () => { + expect(pathHasRegex(pathWithEscapedChars)).to.be.false; + }); + + it("should identify regex along with escaped parentheses", () => { + expect(pathHasRegex(pathWithRegexAndEscapedChars)).to.be.true; + }); + }); + + describe("cleanEscapedChars", () => { + it("should clean escaped chars", () => { + expect(cleanEscapedChars(pathWithRegexAndEscapedChars).includes("\\")).to.be.false; + }); + }); +}); From 54611e9dce77305c9e763c517cc0679af42ef082 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Tue, 15 Nov 2022 13:45:17 -0300 Subject: [PATCH 08/46] add unit tests for frameworks/utils --- src/test/frameworks/utils.spec.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/frameworks/utils.spec.ts diff --git a/src/test/frameworks/utils.spec.ts b/src/test/frameworks/utils.spec.ts new file mode 100644 index 00000000000..93fbca85b13 --- /dev/null +++ b/src/test/frameworks/utils.spec.ts @@ -0,0 +1,19 @@ +import { expect } from "chai"; + +import { isUrl } from "../../frameworks/utils"; + +describe("Frameworks utils", () => { + describe("isUrl", () => { + it("should identify http URL", () => { + expect(isUrl("http://firebase.google.com")).to.be.true; + }); + + it("should identify https URL", () => { + expect(isUrl("https://firebase.google.com")).to.be.true; + }); + + it("should ignore URL within path", () => { + expect(isUrl("path/?url=https://firebase.google.com")).to.be.false; + }); + }); +}); From cc1d0800cb17b1a213b93953a0df85b5dc0b2b29 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Tue, 15 Nov 2022 14:14:18 -0300 Subject: [PATCH 09/46] `replaceAll` > `replace` `replaceAll` is not supported by Node.js 14 --- src/frameworks/next/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index c0ae5c675da..81a9957afd6 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -22,5 +22,5 @@ export function pathHasRegex(path: string): boolean { * Remove double backslashes from a string */ export function cleanEscapedChars(path: string): string { - return path.replaceAll("\\", ""); + return path.replace(/\\/g, ""); } From 7f9a58e9e0eca006eed73ea8fe73a2164d5d4fab Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Tue, 15 Nov 2022 19:55:49 -0300 Subject: [PATCH 10/46] header/redirects/rewrites checks as reusable utils --- src/frameworks/next/index.ts | 41 +++++++++++++++++++++--------------- src/frameworks/next/utils.ts | 36 +++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 2b4fba3d403..ee8b6e594ff 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -22,8 +22,12 @@ import { IncomingMessage, ServerResponse } from "http"; import { logger } from "../../logger"; import { FirebaseError } from "../../error"; import { fileExistsSync } from "../../fsutils"; -import { isUrl } from "../utils"; -import { cleanEscapedChars, pathHasRegex } from "./utils"; +import { + cleanEscapedChars, + isHeaderSupportedByFirebase, + isRedirectSupportedByFirebase, + isRewriteSupportedByFirebase, +} from "./utils"; // Next.js's exposed interface is incomplete here // TODO see if there's a better way to grab this @@ -31,7 +35,10 @@ interface Manifest { distDir?: string; basePath?: string; headers?: (Header & { regex: string })[]; - redirects?: (Redirect & { regex: string })[]; + redirects?: (Redirect & { + internal: boolean; + regex: string; + })[]; rewrites?: | (Rewrite & { regex: string })[] | { @@ -146,12 +153,12 @@ export async function build(dir: string): Promise { } = manifest; const headers = nextJsHeaders - .filter(({ source }) => { - if (pathHasRegex(source)) { + .filter((header) => { + if (isHeaderSupportedByFirebase(header)) { + return true; + } else { wantsBackend = true; return false; - } else { - return true; } }) .map(({ source, headers }) => ({ @@ -161,14 +168,14 @@ export async function build(dir: string): Promise { })); const redirects = nextJsRedirects - .filter(({ internal, source }: any) => { - if (internal) return false; + .filter((redirect) => { + if (redirect.internal) return false; - if (pathHasRegex(source)) { + if (isRedirectSupportedByFirebase(redirect)) { + return true; + } else { wantsBackend = true; return false; - } else { - return true; } }) .map(({ source, destination, statusCode: type }) => ({ @@ -183,15 +190,15 @@ export async function build(dir: string): Promise { : nextJsRewrites.beforeFiles || []; const rewrites = nextJsRewritesToUse - .filter(({ source, destination, has }) => { + .filter((rewrite) => { // Can we change i18n into Firebase settings? - if (has) return false; + if (rewrite.has) return false; - if (pathHasRegex(source) || isUrl(destination)) { + if (isRewriteSupportedByFirebase(rewrite)) { + return true; + } else { wantsBackend = true; return false; - } else { - return true; } }) .map(({ source, destination }) => ({ diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 81a9957afd6..d53b60bd88c 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -1,3 +1,6 @@ +import type { Header, Redirect, Rewrite } from "next/dist/lib/load-custom-routes"; +import { isUrl } from "../utils"; + /** * Whether the given path has a regex or not. * According to the Next.js documentation: @@ -24,3 +27,36 @@ export function pathHasRegex(path: string): boolean { export function cleanEscapedChars(path: string): string { return path.replace(/\\/g, ""); } + +/** + * Whether a Next.js rewrite is supported by Firebase. + */ +export function isRewriteSupportedByFirebase(rewrite: Rewrite): boolean { + if (rewrite.has || pathHasRegex(rewrite.source) || isUrl(rewrite.destination)) { + return false; + } + + return true; +} + +/** + * Whether a Next.js redirect is supported by Firebase. + */ +export function isRedirectSupportedByFirebase(redirect: Redirect): boolean { + if (pathHasRegex(redirect.source) || "internal" in redirect) { + return false; + } + + return true; +} + +/** + * Whether a Next.js header is supported by Firebase. + */ +export function isHeaderSupportedByFirebase(header: Header): boolean { + if (pathHasRegex(header.source)) { + return false; + } + + return true; +} From dc5fdcc1933636ec29a54569a8e4018d9b6121d8 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Wed, 16 Nov 2022 12:08:24 -0300 Subject: [PATCH 11/46] replace for loop with regex --- src/frameworks/next/utils.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index d53b60bd88c..52060ecba5a 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -12,10 +12,11 @@ import { isUrl } from "../utils"; * See: https://nextjs.org/docs/api-reference/next.config.js/redirects#regex-path-matching */ export function pathHasRegex(path: string): boolean { - for (let i = 0; i < path.length; i++) { - if (path[i] === "(" && path[i - 1] !== "\\") { - return true; - } + // finds parentheses that are not preceded by double backslashes + const regex = /(? Date: Wed, 16 Nov 2022 12:35:22 -0300 Subject: [PATCH 12/46] `.exec` > `.test` --- src/frameworks/next/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 52060ecba5a..2b1286f0fce 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -15,7 +15,7 @@ export function pathHasRegex(path: string): boolean { // finds parentheses that are not preceded by double backslashes const regex = /(? Date: Wed, 16 Nov 2022 17:34:53 -0300 Subject: [PATCH 13/46] `has` should also require backend --- src/frameworks/next/index.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index ee8b6e594ff..7dc84037c61 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -189,11 +189,9 @@ export async function build(dir: string): Promise { ? nextJsRewrites : nextJsRewrites.beforeFiles || []; + // Can we change i18n into Firebase settings? const rewrites = nextJsRewritesToUse .filter((rewrite) => { - // Can we change i18n into Firebase settings? - if (rewrite.has) return false; - if (isRewriteSupportedByFirebase(rewrite)) { return true; } else { From 72771d06da4801cb37ba1e903c036ab9212788a1 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Wed, 16 Nov 2022 19:54:32 -0300 Subject: [PATCH 14/46] reduce `pathHasRegex` verbosity --- src/frameworks/next/utils.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 2b1286f0fce..3ab20c4e7df 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -13,13 +13,7 @@ import { isUrl } from "../utils"; */ export function pathHasRegex(path: string): boolean { // finds parentheses that are not preceded by double backslashes - const regex = /(? Date: Wed, 16 Nov 2022 20:14:23 -0300 Subject: [PATCH 15/46] fix `isUrl`, more test cases --- src/frameworks/utils.ts | 4 ++-- src/test/frameworks/utils.spec.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/frameworks/utils.ts b/src/frameworks/utils.ts index bc20af2ad23..39bb79fab26 100644 --- a/src/frameworks/utils.ts +++ b/src/frameworks/utils.ts @@ -1,6 +1,6 @@ /** - * Whether the given string is a URL. + * Whether the given string starts with http:// or https:// */ export function isUrl(url: string): boolean { - return url.startsWith("http"); + return /^https?:\/\//.test(url); } diff --git a/src/test/frameworks/utils.spec.ts b/src/test/frameworks/utils.spec.ts index 93fbca85b13..d691a14aadf 100644 --- a/src/test/frameworks/utils.spec.ts +++ b/src/test/frameworks/utils.spec.ts @@ -15,5 +15,13 @@ describe("Frameworks utils", () => { it("should ignore URL within path", () => { expect(isUrl("path/?url=https://firebase.google.com")).to.be.false; }); + + it("should ignore path starting with http but without protocol", () => { + expect(isUrl("httpendpoint/foo/bar")).to.be.false; + }); + + it("should ignore path starting with https but without protocol", () => { + expect(isUrl("httpsendpoint/foo/bar")).to.be.false; + }); }); }); From 6c079ab3ae284627f33029a41254c8a2e1b077fd Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Thu, 17 Nov 2022 17:15:31 -0300 Subject: [PATCH 16/46] require backend if rewrites afterFiles or fallback --- src/frameworks/next/index.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 7dc84037c61..5163c097496 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -185,10 +185,19 @@ export async function build(dir: string): Promise { type, })); - const nextJsRewritesToUse = Array.isArray(nextJsRewrites) + const isNextjsRewritesArray = Array.isArray(nextJsRewrites); + const nextJsRewritesToUse = isNextjsRewritesArray ? nextJsRewrites : nextJsRewrites.beforeFiles || []; + // rewrites.afterFiles / rewrites.fallback are not supported by firebase.json + if ( + !isNextjsRewritesArray && + (nextJsRewrites.afterFiles?.length || nextJsRewrites.fallback?.length) + ) { + wantsBackend = true; + } + // Can we change i18n into Firebase settings? const rewrites = nextJsRewritesToUse .filter((rewrite) => { From 750f2faaa154a169e356d2af37baf212a7b4e644 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Thu, 17 Nov 2022 20:49:22 -0300 Subject: [PATCH 17/46] filter prerendered routes that matches custom ... ... routes regexes from CDN additionally more reusable utils and types --- src/frameworks/next/index.ts | 83 ++++++++++++++++++++++++++++++------ src/frameworks/next/utils.ts | 10 +++++ 2 files changed, 79 insertions(+), 14 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 5163c097496..72884d43c8e 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -24,14 +24,16 @@ import { FirebaseError } from "../../error"; import { fileExistsSync } from "../../fsutils"; import { cleanEscapedChars, + getNextjsRewritesToUse, isHeaderSupportedByFirebase, isRedirectSupportedByFirebase, isRewriteSupportedByFirebase, } from "./utils"; +export type RoutesManifestRewrite = Rewrite & { regex: string }; // Next.js's exposed interface is incomplete here // TODO see if there's a better way to grab this -interface Manifest { +export interface Manifest { distDir?: string; basePath?: string; headers?: (Header & { regex: string })[]; @@ -40,11 +42,11 @@ interface Manifest { regex: string; })[]; rewrites?: - | (Rewrite & { regex: string })[] + | RoutesManifestRewrite[] | { - beforeFiles?: (Rewrite & { regex: string })[]; - afterFiles?: (Rewrite & { regex: string })[]; - fallback?: (Rewrite & { regex: string })[]; + beforeFiles?: RoutesManifestRewrite[]; + afterFiles?: RoutesManifestRewrite[]; + fallback?: RoutesManifestRewrite[]; }; } @@ -185,19 +187,16 @@ export async function build(dir: string): Promise { type, })); - const isNextjsRewritesArray = Array.isArray(nextJsRewrites); - const nextJsRewritesToUse = isNextjsRewritesArray - ? nextJsRewrites - : nextJsRewrites.beforeFiles || []; - // rewrites.afterFiles / rewrites.fallback are not supported by firebase.json if ( - !isNextjsRewritesArray && + !Array.isArray(nextJsRewrites) && (nextJsRewrites.afterFiles?.length || nextJsRewrites.fallback?.length) ) { wantsBackend = true; } + const nextJsRewritesToUse = getNextjsRewritesToUse(nextJsRewrites); + // Can we change i18n into Firebase settings? const rewrites = nextJsRewritesToUse .filter((rewrite) => { @@ -267,10 +266,37 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin } } - const prerenderManifestBuffer = await readFile( - join(sourceDir, distDir, "prerender-manifest.json") - ); + const [prerenderManifestBuffer, routesManifestBuffer] = await Promise.all([ + readFile( + join( + sourceDir, + distDir, + "prerender-manifest.json" // TODO: get this from next/constants + ) + ), + readFile( + join( + sourceDir, + distDir, + "routes-manifest.json" // TODO: get this from next/constants + ) + ), + ]); + const prerenderManifest = JSON.parse(prerenderManifestBuffer.toString()); + const routesManifest = JSON.parse(routesManifestBuffer.toString()) as Manifest; + + const rewritesToUse = getNextjsRewritesToUse(routesManifest.rewrites); + const rewritesNotSupportedByFirebase = rewritesToUse?.filter( + (rewrite) => isRewriteSupportedByFirebase(rewrite) === false + ); + const redirectsNotSupportedByFirebase = routesManifest.redirects?.filter( + (redirect) => isRedirectSupportedByFirebase(redirect) === false + ); + const headersNotSupportedByFirebase = routesManifest.headers?.filter( + (header) => isHeaderSupportedByFirebase(header) === false + ); + for (const path in prerenderManifest.routes) { if (prerenderManifest.routes[path]) { // Skip ISR in the deploy to hosting @@ -279,6 +305,35 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin continue; } + if (rewritesNotSupportedByFirebase) { + const routeMatchUnsuportedRewrite = rewritesNotSupportedByFirebase.some( + // TODO: double check if `path` is appropriate for this in all cases + // or if we can get pathname from elsewhere + (rewrite) => new RegExp(rewrite.regex).test(path) + ); + + if (routeMatchUnsuportedRewrite) continue; + } + + if (redirectsNotSupportedByFirebase) { + const routeMatchUnsupportedRedirect = redirectsNotSupportedByFirebase.some( + // TODO: double check if `path` is appropriate for this in all cases + // or if we can get pathname from elsewhere + (redirect) => new RegExp(redirect.regex).test(path) + ); + + if (routeMatchUnsupportedRedirect) continue; + } + + if (headersNotSupportedByFirebase) { + const routeMatchUnsupportedHeader = headersNotSupportedByFirebase.some( + // TODO: double check if `path` is appropriate for this in all cases + // or if we can get pathname from elsewhere + (header) => new RegExp(header.regex).test(path) + ); + + if (routeMatchUnsupportedHeader) continue; + } // TODO(jamesdaniels) explore oppertunity to simplify this now that we // are defaulting cleanURLs to true for frameworks diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 3ab20c4e7df..c3004dd1f6d 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -1,4 +1,5 @@ import type { Header, Redirect, Rewrite } from "next/dist/lib/load-custom-routes"; +import type { Manifest, RoutesManifestRewrite } from "."; import { isUrl } from "../utils"; /** @@ -55,3 +56,12 @@ export function isHeaderSupportedByFirebase(header: Header): boolean { return true; } + +/** + * Firebase Rewrites that can be supported by firebase.json. + */ +export function getNextjsRewritesToUse( + nextJsRewrites: Manifest["rewrites"] +): RoutesManifestRewrite[] { + return Array.isArray(nextJsRewrites) ? nextJsRewrites : nextJsRewrites?.beforeFiles || []; +} From 13462a5f02eee9037dbb2a073122545151355714 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Fri, 18 Nov 2022 16:14:29 -0300 Subject: [PATCH 18/46] remove TODO --- src/frameworks/next/index.ts | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 72884d43c8e..39d682bb4fb 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -306,30 +306,24 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin } if (rewritesNotSupportedByFirebase) { - const routeMatchUnsuportedRewrite = rewritesNotSupportedByFirebase.some( - // TODO: double check if `path` is appropriate for this in all cases - // or if we can get pathname from elsewhere - (rewrite) => new RegExp(rewrite.regex).test(path) + const routeMatchUnsuportedRewrite = rewritesNotSupportedByFirebase.some((rewrite) => + new RegExp(rewrite.regex).test(path) ); if (routeMatchUnsuportedRewrite) continue; } if (redirectsNotSupportedByFirebase) { - const routeMatchUnsupportedRedirect = redirectsNotSupportedByFirebase.some( - // TODO: double check if `path` is appropriate for this in all cases - // or if we can get pathname from elsewhere - (redirect) => new RegExp(redirect.regex).test(path) + const routeMatchUnsupportedRedirect = redirectsNotSupportedByFirebase.some((redirect) => + new RegExp(redirect.regex).test(path) ); if (routeMatchUnsupportedRedirect) continue; } if (headersNotSupportedByFirebase) { - const routeMatchUnsupportedHeader = headersNotSupportedByFirebase.some( - // TODO: double check if `path` is appropriate for this in all cases - // or if we can get pathname from elsewhere - (header) => new RegExp(header.regex).test(path) + const routeMatchUnsupportedHeader = headersNotSupportedByFirebase.some((header) => + new RegExp(header.regex).test(path) ); if (routeMatchUnsupportedHeader) continue; From 7bc13398c2681ed448b333531a2f111927d7c394 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Fri, 18 Nov 2022 16:33:19 -0300 Subject: [PATCH 19/46] `rewrite.has` > `"has" in rewrite` --- src/frameworks/next/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index c3004dd1f6d..eb4ee1dd44f 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -28,7 +28,7 @@ export function cleanEscapedChars(path: string): string { * Whether a Next.js rewrite is supported by Firebase. */ export function isRewriteSupportedByFirebase(rewrite: Rewrite): boolean { - if (rewrite.has || pathHasRegex(rewrite.source) || isUrl(rewrite.destination)) { + if ("has" in rewrite || pathHasRegex(rewrite.source) || isUrl(rewrite.destination)) { return false; } From b07c6c32d59e8f2f3263323e483a242ea24f2915 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 16:55:55 -0300 Subject: [PATCH 20/46] move Next.js types to interfaces.ts --- src/frameworks/next/index.ts | 22 +--------------------- src/frameworks/next/interfaces.ts | 29 +++++++++++++++++++++++++++++ src/frameworks/next/utils.ts | 2 +- 3 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 src/frameworks/next/interfaces.ts diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 39d682bb4fb..0d444aa9e96 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -2,7 +2,6 @@ import { execSync } from "child_process"; import { readFile, mkdir, copyFile } from "fs/promises"; import { dirname, join } from "path"; import type { NextConfig } from "next"; -import type { Header, Rewrite, Redirect } from "next/dist/lib/load-custom-routes"; import { copy, mkdirp, pathExists } from "fs-extra"; import { pathToFileURL, parse } from "url"; import { existsSync } from "fs"; @@ -29,26 +28,7 @@ import { isRedirectSupportedByFirebase, isRewriteSupportedByFirebase, } from "./utils"; - -export type RoutesManifestRewrite = Rewrite & { regex: string }; -// Next.js's exposed interface is incomplete here -// TODO see if there's a better way to grab this -export interface Manifest { - distDir?: string; - basePath?: string; - headers?: (Header & { regex: string })[]; - redirects?: (Redirect & { - internal: boolean; - regex: string; - })[]; - rewrites?: - | RoutesManifestRewrite[] - | { - beforeFiles?: RoutesManifestRewrite[]; - afterFiles?: RoutesManifestRewrite[]; - fallback?: RoutesManifestRewrite[]; - }; -} +import type { Manifest } from "./interfaces"; const CLI_COMMAND = join( "node_modules", diff --git a/src/frameworks/next/interfaces.ts b/src/frameworks/next/interfaces.ts new file mode 100644 index 00000000000..395270fb815 --- /dev/null +++ b/src/frameworks/next/interfaces.ts @@ -0,0 +1,29 @@ +import type { Header, Rewrite, Redirect } from "next/dist/lib/load-custom-routes"; + +export type RoutesManifestRedirect = Redirect & { + regex: string; + internal?: boolean; +}; +export type RoutesManifestRedirects = RoutesManifestRedirect[]; + +export type RoutesManifestRewrite = Rewrite & { regex: string }; +export type RoutesManifestRewriteArray = RoutesManifestRewrite[]; +export type RoutesManifestRewriteObject = { + beforeFiles?: RoutesManifestRewrite[]; + afterFiles?: RoutesManifestRewrite[]; + fallback?: RoutesManifestRewrite[]; +}; + +export type RoutesManifestHeader = Header & { regex: string }; +export type RoutesManifestHeaders = RoutesManifestHeader[]; + +// Next.js's exposed interface is incomplete here +// TODO see if there's a better way to grab this +// TODO: rename to RoutesManifest as Next.js has other types of manifests +export interface Manifest { + distDir?: string; + basePath?: string; + headers?: RoutesManifestHeaders; + redirects?: RoutesManifestRedirects; + rewrites?: RoutesManifestRewriteArray | RoutesManifestRewriteObject; +} diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index eb4ee1dd44f..3df867dcb11 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -1,5 +1,5 @@ import type { Header, Redirect, Rewrite } from "next/dist/lib/load-custom-routes"; -import type { Manifest, RoutesManifestRewrite } from "."; +import type { Manifest, RoutesManifestRewrite } from "./interfaces"; import { isUrl } from "../utils"; /** From d1abbbb47b42ba9ed65b680a4152c65d5c030e13 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 16:56:25 -0300 Subject: [PATCH 21/46] filter out redirects with `has` --- src/frameworks/next/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 3df867dcb11..268281e0ec8 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -39,7 +39,7 @@ export function isRewriteSupportedByFirebase(rewrite: Rewrite): boolean { * Whether a Next.js redirect is supported by Firebase. */ export function isRedirectSupportedByFirebase(redirect: Redirect): boolean { - if (pathHasRegex(redirect.source) || "internal" in redirect) { + if ("has" in redirect || pathHasRegex(redirect.source) || "internal" in redirect) { return false; } From 9c6aac34fe21618ad9a4f82ced6cb15f2eecab12 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 17:07:10 -0300 Subject: [PATCH 22/46] filter out headers with `has` --- src/frameworks/next/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 268281e0ec8..bf448a5b010 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -50,7 +50,7 @@ export function isRedirectSupportedByFirebase(redirect: Redirect): boolean { * Whether a Next.js header is supported by Firebase. */ export function isHeaderSupportedByFirebase(header: Header): boolean { - if (pathHasRegex(header.source)) { + if ("has" in header || pathHasRegex(header.source)) { return false; } From 7437cb0983edf93015fee33eb8a499673af36402 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 17:38:10 -0300 Subject: [PATCH 23/46] add paths for tests, adjust pathHasRegex tests --- src/test/frameworks/next/helpers/index.ts | 1 + src/test/frameworks/next/helpers/paths.ts | 90 +++++++++++++++++++++++ src/test/frameworks/next/utils.spec.ts | 34 ++++++--- 3 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 src/test/frameworks/next/helpers/index.ts create mode 100644 src/test/frameworks/next/helpers/paths.ts diff --git a/src/test/frameworks/next/helpers/index.ts b/src/test/frameworks/next/helpers/index.ts new file mode 100644 index 00000000000..7fb78827481 --- /dev/null +++ b/src/test/frameworks/next/helpers/index.ts @@ -0,0 +1 @@ +export * from "./paths"; diff --git a/src/test/frameworks/next/helpers/paths.ts b/src/test/frameworks/next/helpers/paths.ts new file mode 100644 index 00000000000..2b5c3e3f881 --- /dev/null +++ b/src/test/frameworks/next/helpers/paths.ts @@ -0,0 +1,90 @@ +export const pathsWithRegex = [ + "/(.*)", + "/post/:slug(\\d{1,})", + "/:path((?!another-page$).*)", + "/api-hello-regex/:first(.*)", + "/unnamed-params/nested/(.*)/:test/(.*)", +] as const; + +export const pathsWithEscapedChars = [ + `/post\\(someStringBetweenParentheses\\)/:slug`, + `/english\\(default\\)/:slug`, + `/post/\\(es\\?cap\\Wed\\*p\\{ar\\}en\\:th\\eses\\)`, +] as const; + +export const pathsWithRegexAndEscapedChars = [ + `/post/\\(escapedparentheses\\)/:slug(\\d{1,})`, + `/post/\\(es\\?cap\\Wed\\*p\\{ar\\}en\\:th\\eses\\)/:slug(\\d{1,})`, +] as const; + +export const pathsAsGlobs = [ + "/specific/:path*", + "/another/:path*", + "/about", + "/", + "/old-blog/:path*", + "/blog/:path*", + "/to-websocket", + "/to-nowhere", + "/rewriting-to-auto-export", + "/rewriting-to-another-auto-export/:path*", + "/to-another", + "/another/one", + "/nav", + "/404", + "/hello-world", + "/static/hello.txt", + "/another", + "/multi-rewrites", + "/first", + "/hello", + "/second", + "/hello-again", + "/to-hello", + "/hello", + "/blog/post-1", + "/blog/post-2", + "/test/:path", + "/:path", + "/test-overwrite/:something/:another", + "/params/this-should-be-the-value", + "/params/:something", + "/with-params", + "/query-rewrite/:section/:name", + "/hidden/_next/:path*", + "/_next/:path*", + "/proxy-me/:path*", + "/api-hello", + "/api/hello", + "/api/hello?name=:first*", + "/api-hello-param/:name", + "/api/hello?hello=:name", + "/api-dynamic-param/:name", + "/api/dynamic/:name?hello=:name", + "/:path/post-321", + "/with-params", + "/with-params", + "/catchall-rewrite/:path*", + "/with-params", + "/catchall-query/:path*", + "/has-rewrite-1", + "/has-rewrite-2", + "/has-rewrite-3", + "/has-rewrite-4", + "/has-rewrite-5", + "/:hasParam", + "/has-rewrite-6", + "/with-params", + "/has-rewrite-7", + "/has-rewrite-8", + "/blog-catchall/:post", + "/missing-rewrite-1", + "/with-params", + "/missing-rewrite-2", + "/with-params", + "/missing-rewrite-3", + "/overridden/:path*", +] as const; + +export const supportedPaths = [...pathsWithEscapedChars, ...pathsAsGlobs] as const; +export const unsupportedPaths = [...pathsWithRegex, ...pathsWithRegexAndEscapedChars] as const; diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts index 811f037ce3d..741992f4efc 100644 --- a/src/test/frameworks/next/utils.spec.ts +++ b/src/test/frameworks/next/utils.spec.ts @@ -1,23 +1,37 @@ import { expect } from "chai"; -import { cleanEscapedChars, pathHasRegex } from "../../../frameworks/next/utils"; +import { pathHasRegex, cleanEscapedChars } from "../../../frameworks/next/utils"; +import { + pathsAsGlobs, + pathsWithEscapedChars, + pathsWithRegex, + pathsWithRegexAndEscapedChars, +} from "./helpers"; describe("Next.js utils", () => { - const pathWithRegex = "/post/:slug(\\d{1,})"; - const pathWithEscapedChars = "/post\\(someStringBetweenParentheses\\)/:slug"; - const pathWithRegexAndEscapedChars = "/post/\\(escapedparentheses\\)/:slug(\\d{1,})"; - describe("pathHasRegex", () => { it("should identify regex", () => { - expect(pathHasRegex(pathWithRegex)).to.be.true; + for (const path of pathsWithRegex) { + expect(pathHasRegex(path)).to.be.true; + } + }); + + it("should not identify escaped parentheses as regex", () => { + for (const path of pathsWithEscapedChars) { + expect(pathHasRegex(path)).to.be.false; + } }); - it("should not identify escaped parentheses", () => { - expect(pathHasRegex(pathWithEscapedChars)).to.be.false; + it("should identify regex along with escaped chars", () => { + for (const path of pathsWithRegexAndEscapedChars) { + expect(pathHasRegex(path)).to.be.true; + } }); - it("should identify regex along with escaped parentheses", () => { - expect(pathHasRegex(pathWithRegexAndEscapedChars)).to.be.true; + it("should not identify globs as regex", () => { + for (const path of pathsAsGlobs) { + expect(pathHasRegex(path)).to.be.false; + } }); }); From e31f094af774df66e79793ad4757a925f1b41dfd Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 17:53:53 -0300 Subject: [PATCH 24/46] tests for supported rewrites --- src/test/frameworks/next/helpers/index.ts | 1 + src/test/frameworks/next/helpers/rewrites.ts | 85 ++++++++++++++++++++ src/test/frameworks/next/utils.spec.ts | 26 +++++- 3 files changed, 110 insertions(+), 2 deletions(-) create mode 100644 src/test/frameworks/next/helpers/rewrites.ts diff --git a/src/test/frameworks/next/helpers/index.ts b/src/test/frameworks/next/helpers/index.ts index 7fb78827481..c562eec2fb1 100644 --- a/src/test/frameworks/next/helpers/index.ts +++ b/src/test/frameworks/next/helpers/index.ts @@ -1 +1,2 @@ export * from "./paths"; +export * from "./rewrites"; diff --git a/src/test/frameworks/next/helpers/rewrites.ts b/src/test/frameworks/next/helpers/rewrites.ts new file mode 100644 index 00000000000..a412fcf73be --- /dev/null +++ b/src/test/frameworks/next/helpers/rewrites.ts @@ -0,0 +1,85 @@ +import type { + RoutesManifestRewriteArray, + RoutesManifestRewriteObject, +} from "../../../../frameworks/next/interfaces"; +import { supportedPaths, unsupportedPaths } from "./paths"; + +export const supportedRewritesArray: RoutesManifestRewriteArray = supportedPaths.map((path) => ({ + source: path, + destination: `${path}/rewrite`, + regex: "", +})); + +export const unsupportedRewritesArray: RoutesManifestRewriteArray = [ + ...unsupportedPaths.map((path) => ({ + source: path, + destination: `/${path}/rewrite`, + regex: "", + })), + // external http URL + { + source: "/:path*", + destination: "http://firebase.google.com", + regex: "", + }, + // external https URL + { + source: "/:path*", + destination: "https://firebase.google.com", + regex: "", + }, + // with has + { + source: "/specific/:path*", + destination: "/some/specific/:path", + regex: "", + has: [ + { type: "query", key: "overrideMe" }, + { + type: "header", + key: "x-rewrite-me", + }, + ], + }, + // with has + { + source: "/specific/:path*", + destination: "/some/specific/:path", + regex: "", + has: [ + { + type: "query", + key: "page", + // the page value will not be available in the + // destination since value is provided and doesn't + // use a named capture group e.g. (?home) + value: "home", + }, + ], + }, + // with has + { + source: "/specific/:path*", + destination: "/some/specific/:path", + regex: "", + has: [ + { + type: "cookie", + key: "authorized", + value: "true", + }, + ], + }, +]; + +export const supportedRewritesObject: RoutesManifestRewriteObject = { + afterFiles: unsupportedRewritesArray, // should be ignored, only beforeFiles is used + beforeFiles: supportedRewritesArray, + fallback: unsupportedRewritesArray, // should be ignored, only beforeFiles is used +}; + +export const unsupportedRewritesObject: RoutesManifestRewriteObject = { + afterFiles: unsupportedRewritesArray, // should be ignored, only beforeFiles is used + beforeFiles: unsupportedRewritesArray, + fallback: unsupportedRewritesArray, // should be ignored, only beforeFiles is used +}; diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts index 741992f4efc..0ccf7bf3915 100644 --- a/src/test/frameworks/next/utils.spec.ts +++ b/src/test/frameworks/next/utils.spec.ts @@ -1,11 +1,17 @@ import { expect } from "chai"; -import { pathHasRegex, cleanEscapedChars } from "../../../frameworks/next/utils"; +import { + pathHasRegex, + cleanEscapedChars, + isRewriteSupportedByFirebase, +} from "../../../frameworks/next/utils"; import { pathsAsGlobs, pathsWithEscapedChars, pathsWithRegex, pathsWithRegexAndEscapedChars, + supportedRewritesArray, + unsupportedRewritesArray, } from "./helpers"; describe("Next.js utils", () => { @@ -37,7 +43,23 @@ describe("Next.js utils", () => { describe("cleanEscapedChars", () => { it("should clean escaped chars", () => { - expect(cleanEscapedChars(pathWithRegexAndEscapedChars).includes("\\")).to.be.false; + for (const path of pathsWithRegexAndEscapedChars) { + expect(cleanEscapedChars(path).includes("\\")).to.be.false; + } + }); + }); + + describe("isRewriteSupportedByFirebase", () => { + it("should allow supported rewrites", () => { + for (const rewrite of supportedRewritesArray) { + expect(isRewriteSupportedByFirebase(rewrite)).to.be.true; + } + }); + + it("should disallow unsupported rewrites", () => { + for (const rewrite of unsupportedRewritesArray) { + expect(isRewriteSupportedByFirebase(rewrite)).to.be.false; + } }); }); }); From d649f02549a1da8c71cfbdc48c9ef72ff0a1151f Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 17:55:16 -0300 Subject: [PATCH 25/46] tests for supported redirects --- src/test/frameworks/next/helpers/index.ts | 1 + src/test/frameworks/next/helpers/redirects.ts | 105 ++++++++++++++++++ src/test/frameworks/next/utils.spec.ts | 18 +++ 3 files changed, 124 insertions(+) create mode 100644 src/test/frameworks/next/helpers/redirects.ts diff --git a/src/test/frameworks/next/helpers/index.ts b/src/test/frameworks/next/helpers/index.ts index c562eec2fb1..7f4fad7494e 100644 --- a/src/test/frameworks/next/helpers/index.ts +++ b/src/test/frameworks/next/helpers/index.ts @@ -1,2 +1,3 @@ export * from "./paths"; +export * from "./redirects"; export * from "./rewrites"; diff --git a/src/test/frameworks/next/helpers/redirects.ts b/src/test/frameworks/next/helpers/redirects.ts new file mode 100644 index 00000000000..0afa1d45c49 --- /dev/null +++ b/src/test/frameworks/next/helpers/redirects.ts @@ -0,0 +1,105 @@ +import type { RoutesManifestRedirects } from "../../../../frameworks/next/interfaces"; +import { supportedPaths, unsupportedPaths } from "./paths"; + +export const supportedRedirects: RoutesManifestRedirects = supportedPaths.map((path) => ({ + source: path, + destination: `${path}/redirect`, + regex: "", + statusCode: 301, +})); + +export const unsupportedRedirects: RoutesManifestRedirects = [ + ...unsupportedPaths.map((path) => ({ + source: path, + destination: `/${path}/redirect`, + regex: "", + statusCode: 301, + })), + { + source: "/has-redirect-1", + has: [ + { + type: "header", + key: "x-my-header", + value: "(?.*)", + }, + ], + destination: "/another?myHeader=:myHeader", + permanent: false, + regex: "", + }, + { + source: "/has-redirect-2", + has: [ + { + type: "query", + key: "my-query", + }, + ], + destination: "/another?value=:myquery", + permanent: false, + regex: "", + }, + { + source: "/has-redirect-3", + has: [ + { + type: "cookie", + key: "loggedIn", + value: "true", + }, + ], + destination: "/another?authorized=1", + permanent: false, + regex: "", + }, + { + source: "/has-redirect-4", + has: [ + { + type: "host", + value: "example.com", + }, + ], + destination: "/another?host=1", + permanent: false, + regex: "", + }, + { + source: "/:path/has-redirect-5", + has: [ + { + type: "header", + key: "x-test-next", + }, + ], + destination: "/somewhere", + permanent: false, + regex: "", + }, + { + source: "/has-redirect-6", + has: [ + { + type: "host", + value: "(?.*)-test.example.com", + }, + ], + destination: "https://:subdomain.example.com/some-path/end?a=b", + permanent: false, + regex: "", + }, + { + source: "/has-redirect-7", + has: [ + { + type: "query", + key: "hello", + value: "(?.*)", + }, + ], + destination: "/somewhere?value=:hello", + permanent: false, + regex: "", + }, +]; diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts index 0ccf7bf3915..77641bd6fd6 100644 --- a/src/test/frameworks/next/utils.spec.ts +++ b/src/test/frameworks/next/utils.spec.ts @@ -4,13 +4,16 @@ import { pathHasRegex, cleanEscapedChars, isRewriteSupportedByFirebase, + isRedirectSupportedByFirebase, } from "../../../frameworks/next/utils"; import { pathsAsGlobs, pathsWithEscapedChars, pathsWithRegex, pathsWithRegexAndEscapedChars, + supportedRedirects, supportedRewritesArray, + unsupportedRedirects, unsupportedRewritesArray, } from "./helpers"; @@ -62,4 +65,19 @@ describe("Next.js utils", () => { } }); }); + + describe("isRedirectSupportedByFirebase", () => { + it("should allow supported redirects", () => { + for (const redirect of supportedRedirects) { + expect(isRedirectSupportedByFirebase(redirect)).to.be.true; + } + }); + + it("should disallow unsupported redirects", () => { + for (const redirect of unsupportedRedirects) { + expect(isRedirectSupportedByFirebase(redirect)).to.be.false; + } + }); + }); + }); From 2d9fee1e85889f40dde336f89e978be1cd088ca3 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 17:56:07 -0300 Subject: [PATCH 26/46] tests for supported headers --- src/test/frameworks/next/helpers/headers.ts | 292 ++++++++++++++++++++ src/test/frameworks/next/helpers/index.ts | 1 + src/test/frameworks/next/utils.spec.ts | 17 ++ 3 files changed, 310 insertions(+) create mode 100644 src/test/frameworks/next/helpers/headers.ts diff --git a/src/test/frameworks/next/helpers/headers.ts b/src/test/frameworks/next/helpers/headers.ts new file mode 100644 index 00000000000..aeb107b181d --- /dev/null +++ b/src/test/frameworks/next/helpers/headers.ts @@ -0,0 +1,292 @@ +import type { RoutesManifestHeaders } from "../../../../frameworks/next/interfaces"; +import { supportedPaths, unsupportedPaths } from "./paths"; + +export const supportedHeaders: RoutesManifestHeaders = [ + ...supportedPaths.map((path) => ({ + source: path, + regex: "", + headers: [ + { + key: "x-path", + value: ":path", + }, + { + key: "some:path", + value: "hi", + }, + { + key: "x-test", + value: "some:value*", + }, + { + key: "x-test-2", + value: "value*", + }, + { + key: "x-test-3", + value: ":value?", + }, + { + key: "x-test-4", + value: ":value+", + }, + { + key: "x-test-5", + value: "something https:", + }, + { + key: "x-test-6", + value: ":hello(world)", + }, + { + key: "x-test-7", + value: "hello(world)", + }, + { + key: "x-test-8", + value: "hello{1,}", + }, + { + key: "x-test-9", + value: ":hello{1,2}", + }, + { + key: "content-security-policy", + value: + "default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com/:path", + }, + ], + })), + { + regex: "", + source: "/add-header", + headers: [ + { + key: "x-custom-header", + value: "hello world", + }, + { + key: "x-another-header", + value: "hello again", + }, + ], + }, + { + regex: "", + source: "/my-other-header/:path", + headers: [ + { + key: "x-path", + value: ":path", + }, + { + key: "some:path", + value: "hi", + }, + { + key: "x-test", + value: "some:value*", + }, + { + key: "x-test-2", + value: "value*", + }, + { + key: "x-test-3", + value: ":value?", + }, + { + key: "x-test-4", + value: ":value+", + }, + { + key: "x-test-5", + value: "something https:", + }, + { + key: "x-test-6", + value: ":hello(world)", + }, + { + key: "x-test-7", + value: "hello(world)", + }, + { + key: "x-test-8", + value: "hello{1,}", + }, + { + key: "x-test-9", + value: ":hello{1,2}", + }, + { + key: "content-security-policy", + value: + "default-src 'self'; img-src *; media-src media1.com media2.com; script-src userscripts.example.com/:path", + }, + ], + }, + { + regex: "", + source: "/without-params/url", + headers: [ + { + key: "x-origin", + value: "https://example.com", + }, + ], + }, + { + regex: "", + source: "/with-params/url/:path*", + headers: [ + { + key: "x-url", + value: "https://example.com/:path*", + }, + ], + }, + { + regex: "", + source: "/with-params/url2/:path*", + headers: [ + { + key: "x-url", + value: "https://example.com:8080?hello=:path*", + }, + ], + }, + { + regex: "", + source: "/:path*", + headers: [ + { + key: "x-something", + value: "applied-everywhere", + }, + ], + }, + { + regex: "", + source: "/catchall-header/:path*", + headers: [ + { + key: "x-value", + value: ":path*", + }, + ], + }, +]; + +export const unsupportedHeaders: RoutesManifestHeaders = [ + ...unsupportedPaths.map((path) => ({ + source: path, + regex: "", + headers: [ + { + key: "x-custom-header", + value: "hello world", + }, + { + key: "x-another-header", + value: "hello again", + }, + ], + })), + { + regex: "", + source: "/named-pattern/:path(.*)", + headers: [ + { + key: "x-something", + value: "value=:path", + }, + { + key: "path-:path", + value: "end", + }, + ], + }, + + { + regex: "", + source: "/my-headers/(.*)", + headers: [ + { + key: "x-first-header", + value: "first", + }, + { + key: "x-second-header", + value: "second", + }, + ], + }, + + { + regex: "", + source: "/has-header-1", + has: [ + { + type: "header", + key: "x-my-header", + value: "(?.*)", + }, + ], + headers: [ + { + key: "x-another", + value: "header", + }, + ], + }, + { + regex: "", + source: "/has-header-2", + has: [ + { + type: "query", + key: "my-query", + }, + ], + headers: [ + { + key: "x-added", + value: "value", + }, + ], + }, + { + regex: "", + source: "/has-header-3", + has: [ + { + type: "cookie", + key: "loggedIn", + value: "true", + }, + ], + headers: [ + { + key: "x-is-user", + value: "yuuuup", + }, + ], + }, + { + regex: "", + source: "/has-header-4", + has: [ + { + type: "host", + value: "example.com", + }, + ], + headers: [ + { + key: "x-is-host", + value: "yuuuup", + }, + ], + }, +]; diff --git a/src/test/frameworks/next/helpers/index.ts b/src/test/frameworks/next/helpers/index.ts index 7f4fad7494e..83772e4ea98 100644 --- a/src/test/frameworks/next/helpers/index.ts +++ b/src/test/frameworks/next/helpers/index.ts @@ -1,3 +1,4 @@ export * from "./paths"; +export * from "./headers"; export * from "./redirects"; export * from "./rewrites"; diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts index 77641bd6fd6..eb8a297de75 100644 --- a/src/test/frameworks/next/utils.spec.ts +++ b/src/test/frameworks/next/utils.spec.ts @@ -5,14 +5,17 @@ import { cleanEscapedChars, isRewriteSupportedByFirebase, isRedirectSupportedByFirebase, + isHeaderSupportedByFirebase, } from "../../../frameworks/next/utils"; import { pathsAsGlobs, pathsWithEscapedChars, pathsWithRegex, pathsWithRegexAndEscapedChars, + supportedHeaders, supportedRedirects, supportedRewritesArray, + unsupportedHeaders, unsupportedRedirects, unsupportedRewritesArray, } from "./helpers"; @@ -80,4 +83,18 @@ describe("Next.js utils", () => { }); }); + describe("isHeaderSupportedByFirebase", () => { + it("should allow supported headers", () => { + for (const header of supportedHeaders) { + expect(isHeaderSupportedByFirebase(header)).to.be.true; + } + }); + + it("should disallow unsupported headers", () => { + for (const header of unsupportedHeaders) { + expect(isHeaderSupportedByFirebase(header)).to.be.false; + } + }); + }); + }); From 1ab51c0e2ec0ed87e7dd18dab0b45bea5c03686e Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 18:04:06 -0300 Subject: [PATCH 27/46] tests for `getNextjsRewritesToUse` --- src/test/frameworks/next/utils.spec.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts index eb8a297de75..7f893ffc41d 100644 --- a/src/test/frameworks/next/utils.spec.ts +++ b/src/test/frameworks/next/utils.spec.ts @@ -6,6 +6,7 @@ import { isRewriteSupportedByFirebase, isRedirectSupportedByFirebase, isHeaderSupportedByFirebase, + getNextjsRewritesToUse, } from "../../../frameworks/next/utils"; import { pathsAsGlobs, @@ -15,6 +16,7 @@ import { supportedHeaders, supportedRedirects, supportedRewritesArray, + supportedRewritesObject, unsupportedHeaders, unsupportedRedirects, unsupportedRewritesArray, @@ -97,4 +99,24 @@ describe("Next.js utils", () => { }); }); + describe("getNextjsRewritesToUse", () => { + it("should use only beforeFiles", () => { + if (!supportedRewritesObject?.beforeFiles?.length) { + throw new Error("beforeFiles must have rewrites"); + } + + const rewritesToUse = getNextjsRewritesToUse(supportedRewritesObject); + + for (const [i, rewrite] of supportedRewritesObject.beforeFiles.entries()) { + expect(rewrite.source).to.equal(rewritesToUse[i].source); + expect(rewrite.destination).to.equal(rewritesToUse[i].destination); + } + }); + + it("should return all rewrites if in array format", () => { + const rewritesToUse = getNextjsRewritesToUse(supportedRewritesArray); + + expect(rewritesToUse).to.have.length(supportedRewritesArray.length); + }); + }); }); From 71226bb85d041479c125499fdb6fb0d2e40ef1a5 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 18:05:23 -0300 Subject: [PATCH 28/46] temporarily disable `cleanEscapedChars` tests --- src/test/frameworks/next/utils.spec.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts index 7f893ffc41d..ac530e7dfe1 100644 --- a/src/test/frameworks/next/utils.spec.ts +++ b/src/test/frameworks/next/utils.spec.ts @@ -49,13 +49,14 @@ describe("Next.js utils", () => { }); }); - describe("cleanEscapedChars", () => { - it("should clean escaped chars", () => { - for (const path of pathsWithRegexAndEscapedChars) { - expect(cleanEscapedChars(path).includes("\\")).to.be.false; - } - }); - }); + // FIXME: function should be fixed for the tests to work + // describe("cleanEscapedChars", () => { + // it("should clean escaped chars", () => { + // for (const path of pathsWithRegexAndEscapedChars) { + // expect(cleanEscapedChars(path).includes("\\")).to.be.false; + // } + // }); + // }); describe("isRewriteSupportedByFirebase", () => { it("should allow supported rewrites", () => { From 7895769b27d2e4ee01763118c886e6125716e9b5 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 21 Nov 2022 18:07:33 -0300 Subject: [PATCH 29/46] comment out unused import --- src/test/frameworks/next/utils.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts index ac530e7dfe1..aee925e50a3 100644 --- a/src/test/frameworks/next/utils.spec.ts +++ b/src/test/frameworks/next/utils.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { pathHasRegex, - cleanEscapedChars, + // cleanEscapedChars, // FIXME: function should be fixed for the tests to work isRewriteSupportedByFirebase, isRedirectSupportedByFirebase, isHeaderSupportedByFirebase, From 99238602b35bd141fe1229d622f2d997ae6809f2 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 28 Nov 2022 14:49:53 -0300 Subject: [PATCH 30/46] replace types with interfaces --- src/frameworks/next/interfaces.ts | 28 ++++++++++--------- src/test/frameworks/next/helpers/headers.ts | 6 ++-- src/test/frameworks/next/helpers/redirects.ts | 18 ++++++------ src/test/frameworks/next/helpers/rewrites.ts | 6 ++-- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/frameworks/next/interfaces.ts b/src/frameworks/next/interfaces.ts index 395270fb815..e012402b9fb 100644 --- a/src/frameworks/next/interfaces.ts +++ b/src/frameworks/next/interfaces.ts @@ -1,21 +1,18 @@ import type { Header, Rewrite, Redirect } from "next/dist/lib/load-custom-routes"; -export type RoutesManifestRedirect = Redirect & { +export interface RoutesManifestRewrite extends Rewrite { regex: string; - internal?: boolean; -}; -export type RoutesManifestRedirects = RoutesManifestRedirect[]; +} -export type RoutesManifestRewrite = Rewrite & { regex: string }; -export type RoutesManifestRewriteArray = RoutesManifestRewrite[]; -export type RoutesManifestRewriteObject = { +export interface RoutesManifestRewriteObject { beforeFiles?: RoutesManifestRewrite[]; afterFiles?: RoutesManifestRewrite[]; fallback?: RoutesManifestRewrite[]; -}; +} -export type RoutesManifestHeader = Header & { regex: string }; -export type RoutesManifestHeaders = RoutesManifestHeader[]; +export interface RoutesManifestHeader extends Header { + regex: string; +} // Next.js's exposed interface is incomplete here // TODO see if there's a better way to grab this @@ -23,7 +20,12 @@ export type RoutesManifestHeaders = RoutesManifestHeader[]; export interface Manifest { distDir?: string; basePath?: string; - headers?: RoutesManifestHeaders; - redirects?: RoutesManifestRedirects; - rewrites?: RoutesManifestRewriteArray | RoutesManifestRewriteObject; + headers?: RoutesManifestHeader[]; + redirects?: Array< + Redirect & { + regex: string; + internal?: boolean; + } + >; + rewrites?: RoutesManifestRewrite[] | RoutesManifestRewriteObject; } diff --git a/src/test/frameworks/next/helpers/headers.ts b/src/test/frameworks/next/helpers/headers.ts index aeb107b181d..8f8bb447006 100644 --- a/src/test/frameworks/next/helpers/headers.ts +++ b/src/test/frameworks/next/helpers/headers.ts @@ -1,7 +1,7 @@ -import type { RoutesManifestHeaders } from "../../../../frameworks/next/interfaces"; +import type { RoutesManifestHeader } from "../../../../frameworks/next/interfaces"; import { supportedPaths, unsupportedPaths } from "./paths"; -export const supportedHeaders: RoutesManifestHeaders = [ +export const supportedHeaders: RoutesManifestHeader[] = [ ...supportedPaths.map((path) => ({ source: path, regex: "", @@ -178,7 +178,7 @@ export const supportedHeaders: RoutesManifestHeaders = [ }, ]; -export const unsupportedHeaders: RoutesManifestHeaders = [ +export const unsupportedHeaders: RoutesManifestHeader[] = [ ...unsupportedPaths.map((path) => ({ source: path, regex: "", diff --git a/src/test/frameworks/next/helpers/redirects.ts b/src/test/frameworks/next/helpers/redirects.ts index 0afa1d45c49..d67394951f2 100644 --- a/src/test/frameworks/next/helpers/redirects.ts +++ b/src/test/frameworks/next/helpers/redirects.ts @@ -1,14 +1,16 @@ -import type { RoutesManifestRedirects } from "../../../../frameworks/next/interfaces"; +import type { Manifest } from "../../../../frameworks/next/interfaces"; import { supportedPaths, unsupportedPaths } from "./paths"; -export const supportedRedirects: RoutesManifestRedirects = supportedPaths.map((path) => ({ - source: path, - destination: `${path}/redirect`, - regex: "", - statusCode: 301, -})); +export const supportedRedirects: NonNullable = supportedPaths.map( + (path) => ({ + source: path, + destination: `${path}/redirect`, + regex: "", + statusCode: 301, + }) +); -export const unsupportedRedirects: RoutesManifestRedirects = [ +export const unsupportedRedirects: NonNullable = [ ...unsupportedPaths.map((path) => ({ source: path, destination: `/${path}/redirect`, diff --git a/src/test/frameworks/next/helpers/rewrites.ts b/src/test/frameworks/next/helpers/rewrites.ts index a412fcf73be..cc55dde9669 100644 --- a/src/test/frameworks/next/helpers/rewrites.ts +++ b/src/test/frameworks/next/helpers/rewrites.ts @@ -1,16 +1,16 @@ import type { - RoutesManifestRewriteArray, + RoutesManifestRewrite, RoutesManifestRewriteObject, } from "../../../../frameworks/next/interfaces"; import { supportedPaths, unsupportedPaths } from "./paths"; -export const supportedRewritesArray: RoutesManifestRewriteArray = supportedPaths.map((path) => ({ +export const supportedRewritesArray: RoutesManifestRewrite[] = supportedPaths.map((path) => ({ source: path, destination: `${path}/rewrite`, regex: "", })); -export const unsupportedRewritesArray: RoutesManifestRewriteArray = [ +export const unsupportedRewritesArray: RoutesManifestRewrite[] = [ ...unsupportedPaths.map((path) => ({ source: path, destination: `/${path}/rewrite`, From f0533e6c90e5192af35b50d61e3485b802424eaf Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Fri, 2 Dec 2022 13:37:43 -0300 Subject: [PATCH 31/46] changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d018fea5c2..22a5dbdf043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,3 +5,5 @@ - Support the x-goog-api-key header in auth emulator. (#5249) - Fix bug in deploying web frameworks when a predeploy hook was configured in firebase.json (#5199) - Fix bug where function deployments using --only filter sometimes failed deployments. (#5280) +- Handle Next.js rewrites/redirects/headers incompatible with `firebase.json` in Cloud Functions (#5212) +- Filter out Next.js prerendered routes that matches rewrites/redirects/headers rules from SSG content directory (#5212) From 75ba873cf7434f180b163e307e3d23bc785ebdc7 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 13:36:50 -0300 Subject: [PATCH 32/46] remove side effects from custom routes filters --- src/frameworks/next/index.ts | 46 ++++++++++++++---------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 0d444aa9e96..2b42d4f6269 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -134,32 +134,24 @@ export async function build(dir: string): Promise { rewrites: nextJsRewrites = [], } = manifest; + const hasUnsupportedHeader = nextJsHeaders.some((header) => !isHeaderSupportedByFirebase(header)); + if (hasUnsupportedHeader) wantsBackend = true; + const headers = nextJsHeaders - .filter((header) => { - if (isHeaderSupportedByFirebase(header)) { - return true; - } else { - wantsBackend = true; - return false; - } - }) + .filter((header) => isHeaderSupportedByFirebase(header)) .map(({ source, headers }) => ({ // clean up unnecessary escaping source: cleanEscapedChars(source), headers, })); + const hasUnsupportedRedirect = nextJsRedirects.some( + (redirect) => !isRedirectSupportedByFirebase(redirect) + ); + if (hasUnsupportedRedirect) wantsBackend = true; + const redirects = nextJsRedirects - .filter((redirect) => { - if (redirect.internal) return false; - - if (isRedirectSupportedByFirebase(redirect)) { - return true; - } else { - wantsBackend = true; - return false; - } - }) + .filter((redirect) => isRedirectSupportedByFirebase(redirect)) .map(({ source, destination, statusCode: type }) => ({ // clean up unnecessary escaping source: cleanEscapedChars(source), @@ -167,26 +159,24 @@ export async function build(dir: string): Promise { type, })); + const nextJsRewritesToUse = getNextjsRewritesToUse(nextJsRewrites); + // rewrites.afterFiles / rewrites.fallback are not supported by firebase.json if ( !Array.isArray(nextJsRewrites) && (nextJsRewrites.afterFiles?.length || nextJsRewrites.fallback?.length) ) { wantsBackend = true; + } else { + const hasUnsupportedRewrite = nextJsRewritesToUse.some( + (rewrite) => !isRewriteSupportedByFirebase(rewrite) + ); + if (hasUnsupportedRewrite) wantsBackend = true; } - const nextJsRewritesToUse = getNextjsRewritesToUse(nextJsRewrites); - // Can we change i18n into Firebase settings? const rewrites = nextJsRewritesToUse - .filter((rewrite) => { - if (isRewriteSupportedByFirebase(rewrite)) { - return true; - } else { - wantsBackend = true; - return false; - } - }) + .filter((rewrite) => isRewriteSupportedByFirebase(rewrite)) .map(({ source, destination }) => ({ // clean up unnecessary escaping source: cleanEscapedChars(source), From 93119741b50a9575c3ebf4bc1435bd0f94b65ece Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 13:48:26 -0300 Subject: [PATCH 33/46] refactor `getNextjsRewritesToUse` --- src/frameworks/next/utils.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index bf448a5b010..395cd2b939c 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -63,5 +63,13 @@ export function isHeaderSupportedByFirebase(header: Header): boolean { export function getNextjsRewritesToUse( nextJsRewrites: Manifest["rewrites"] ): RoutesManifestRewrite[] { - return Array.isArray(nextJsRewrites) ? nextJsRewrites : nextJsRewrites?.beforeFiles || []; + if (Array.isArray(nextJsRewrites)) { + return nextJsRewrites; + } + + if (nextJsRewrites?.beforeFiles) { + return nextJsRewrites.beforeFiles; + } + + return []; } From 6984b5f0b8be8448136a8a8eebbb1ed24602870e Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 13:55:01 -0300 Subject: [PATCH 34/46] `=== false` > `!` --- src/frameworks/next/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 2b42d4f6269..d30bb20582c 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -258,13 +258,13 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin const rewritesToUse = getNextjsRewritesToUse(routesManifest.rewrites); const rewritesNotSupportedByFirebase = rewritesToUse?.filter( - (rewrite) => isRewriteSupportedByFirebase(rewrite) === false + (rewrite) => !isRewriteSupportedByFirebase(rewrite) ); const redirectsNotSupportedByFirebase = routesManifest.redirects?.filter( - (redirect) => isRedirectSupportedByFirebase(redirect) === false + (redirect) => !isRedirectSupportedByFirebase(redirect) ); const headersNotSupportedByFirebase = routesManifest.headers?.filter( - (header) => isHeaderSupportedByFirebase(header) === false + (header) => !isHeaderSupportedByFirebase(header) ); for (const path in prerenderManifest.routes) { From 49a958b1f86360cdf282c9225ed12c32212ba264 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 14:07:37 -0300 Subject: [PATCH 35/46] destructure with defaults, reduce ?, reduce ifs --- src/frameworks/next/index.ts | 42 ++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index d30bb20582c..37ec5862363 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -256,14 +256,16 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin const prerenderManifest = JSON.parse(prerenderManifestBuffer.toString()); const routesManifest = JSON.parse(routesManifestBuffer.toString()) as Manifest; - const rewritesToUse = getNextjsRewritesToUse(routesManifest.rewrites); - const rewritesNotSupportedByFirebase = rewritesToUse?.filter( + const { redirects = [], rewrites = [], headers = [] } = routesManifest; + + const rewritesToUse = getNextjsRewritesToUse(rewrites); + const rewritesNotSupportedByFirebase = rewritesToUse.filter( (rewrite) => !isRewriteSupportedByFirebase(rewrite) ); - const redirectsNotSupportedByFirebase = routesManifest.redirects?.filter( + const redirectsNotSupportedByFirebase = redirects.filter( (redirect) => !isRedirectSupportedByFirebase(redirect) ); - const headersNotSupportedByFirebase = routesManifest.headers?.filter( + const headersNotSupportedByFirebase = headers.filter( (header) => !isHeaderSupportedByFirebase(header) ); @@ -275,29 +277,21 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin continue; } - if (rewritesNotSupportedByFirebase) { - const routeMatchUnsuportedRewrite = rewritesNotSupportedByFirebase.some((rewrite) => - new RegExp(rewrite.regex).test(path) - ); - - if (routeMatchUnsuportedRewrite) continue; - } - - if (redirectsNotSupportedByFirebase) { - const routeMatchUnsupportedRedirect = redirectsNotSupportedByFirebase.some((redirect) => - new RegExp(redirect.regex).test(path) - ); + const routeMatchUnsupportedRewrite = rewritesNotSupportedByFirebase.some((rewrite) => + new RegExp(rewrite.regex).test(path) + ); + if (routeMatchUnsupportedRewrite) continue; - if (routeMatchUnsupportedRedirect) continue; - } + const routeMatchUnsupportedRedirect = redirectsNotSupportedByFirebase.some((redirect) => + new RegExp(redirect.regex).test(path) + ); + if (routeMatchUnsupportedRedirect) continue; - if (headersNotSupportedByFirebase) { - const routeMatchUnsupportedHeader = headersNotSupportedByFirebase.some((header) => - new RegExp(header.regex).test(path) - ); + const routeMatchUnsupportedHeader = headersNotSupportedByFirebase.some((header) => + new RegExp(header.regex).test(path) + ); + if (routeMatchUnsupportedHeader) continue; - if (routeMatchUnsupportedHeader) continue; - } // TODO(jamesdaniels) explore oppertunity to simplify this now that we // are defaulting cleanURLs to true for frameworks From c2560bc0bbe4c8a31c2944f37cf8b9aaf9a48ac4 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 15:00:02 -0300 Subject: [PATCH 36/46] simplify isSupported... utils --- src/frameworks/next/utils.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 395cd2b939c..68cf5b88dfe 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -28,33 +28,21 @@ export function cleanEscapedChars(path: string): string { * Whether a Next.js rewrite is supported by Firebase. */ export function isRewriteSupportedByFirebase(rewrite: Rewrite): boolean { - if ("has" in rewrite || pathHasRegex(rewrite.source) || isUrl(rewrite.destination)) { - return false; - } - - return true; + return !("has" in rewrite || pathHasRegex(rewrite.source) || isUrl(rewrite.destination)); } /** * Whether a Next.js redirect is supported by Firebase. */ export function isRedirectSupportedByFirebase(redirect: Redirect): boolean { - if ("has" in redirect || pathHasRegex(redirect.source) || "internal" in redirect) { - return false; - } - - return true; + return !("has" in redirect || pathHasRegex(redirect.source) || "internal" in redirect); } /** * Whether a Next.js header is supported by Firebase. */ export function isHeaderSupportedByFirebase(header: Header): boolean { - if ("has" in header || pathHasRegex(header.source)) { - return false; - } - - return true; + return !("has" in header || pathHasRegex(header.source)); } /** From ba9fec95d5f6a2644729fc11af389e29797371a6 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 15:04:28 -0300 Subject: [PATCH 37/46] simplify custom routes filters --- src/frameworks/next/index.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 37ec5862363..a0c75b58843 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -137,13 +137,11 @@ export async function build(dir: string): Promise { const hasUnsupportedHeader = nextJsHeaders.some((header) => !isHeaderSupportedByFirebase(header)); if (hasUnsupportedHeader) wantsBackend = true; - const headers = nextJsHeaders - .filter((header) => isHeaderSupportedByFirebase(header)) - .map(({ source, headers }) => ({ - // clean up unnecessary escaping - source: cleanEscapedChars(source), - headers, - })); + const headers = nextJsHeaders.filter(isHeaderSupportedByFirebase).map(({ source, headers }) => ({ + // clean up unnecessary escaping + source: cleanEscapedChars(source), + headers, + })); const hasUnsupportedRedirect = nextJsRedirects.some( (redirect) => !isRedirectSupportedByFirebase(redirect) @@ -151,7 +149,7 @@ export async function build(dir: string): Promise { if (hasUnsupportedRedirect) wantsBackend = true; const redirects = nextJsRedirects - .filter((redirect) => isRedirectSupportedByFirebase(redirect)) + .filter(isRedirectSupportedByFirebase) .map(({ source, destination, statusCode: type }) => ({ // clean up unnecessary escaping source: cleanEscapedChars(source), @@ -176,7 +174,7 @@ export async function build(dir: string): Promise { // Can we change i18n into Firebase settings? const rewrites = nextJsRewritesToUse - .filter((rewrite) => isRewriteSupportedByFirebase(rewrite)) + .filter(isRewriteSupportedByFirebase) .map(({ source, destination }) => ({ // clean up unnecessary escaping source: cleanEscapedChars(source), From 3a91834f72f763e283fe09673b6ba57d9cd7f1a9 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 15:12:39 -0300 Subject: [PATCH 38/46] instantiate regexes before loop --- src/frameworks/next/index.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index a0c75b58843..90ec27c143a 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -260,12 +260,23 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin const rewritesNotSupportedByFirebase = rewritesToUse.filter( (rewrite) => !isRewriteSupportedByFirebase(rewrite) ); + const rewritesRegexesNotSupportedByFirebase = rewritesNotSupportedByFirebase.map( + (rewrite) => new RegExp(rewrite.regex) + ); + const redirectsNotSupportedByFirebase = redirects.filter( (redirect) => !isRedirectSupportedByFirebase(redirect) ); + const redirectsRegexesNotSupportedByFirebase = redirectsNotSupportedByFirebase.map( + (redirect) => new RegExp(redirect.regex) + ); + const headersNotSupportedByFirebase = headers.filter( (header) => !isHeaderSupportedByFirebase(header) ); + const headersRegexesNotSupportedByFirebase = headersNotSupportedByFirebase.map( + (header) => new RegExp(header.regex) + ); for (const path in prerenderManifest.routes) { if (prerenderManifest.routes[path]) { @@ -275,18 +286,18 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin continue; } - const routeMatchUnsupportedRewrite = rewritesNotSupportedByFirebase.some((rewrite) => - new RegExp(rewrite.regex).test(path) + const routeMatchUnsupportedRewrite = rewritesRegexesNotSupportedByFirebase.some( + (rewriteRegex) => rewriteRegex.test(path) ); if (routeMatchUnsupportedRewrite) continue; - const routeMatchUnsupportedRedirect = redirectsNotSupportedByFirebase.some((redirect) => - new RegExp(redirect.regex).test(path) + const routeMatchUnsupportedRedirect = redirectsRegexesNotSupportedByFirebase.some( + (redirectRegex) => redirectRegex.test(path) ); if (routeMatchUnsupportedRedirect) continue; - const routeMatchUnsupportedHeader = headersNotSupportedByFirebase.some((header) => - new RegExp(header.regex).test(path) + const routeMatchUnsupportedHeader = headersRegexesNotSupportedByFirebase.some( + (headerRegex) => headerRegex.test(path) ); if (routeMatchUnsupportedHeader) continue; From db8c39819b9f78b862fd369ef4eda60df4dfd5e1 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 15:19:14 -0300 Subject: [PATCH 39/46] replace some with every, check negation --- src/frameworks/next/index.ts | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 90ec27c143a..ee23f3c272b 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -134,8 +134,8 @@ export async function build(dir: string): Promise { rewrites: nextJsRewrites = [], } = manifest; - const hasUnsupportedHeader = nextJsHeaders.some((header) => !isHeaderSupportedByFirebase(header)); - if (hasUnsupportedHeader) wantsBackend = true; + const isEveryHeaderSupported = nextJsHeaders.every(isHeaderSupportedByFirebase); + if (!isEveryHeaderSupported) wantsBackend = true; const headers = nextJsHeaders.filter(isHeaderSupportedByFirebase).map(({ source, headers }) => ({ // clean up unnecessary escaping @@ -143,10 +143,8 @@ export async function build(dir: string): Promise { headers, })); - const hasUnsupportedRedirect = nextJsRedirects.some( - (redirect) => !isRedirectSupportedByFirebase(redirect) - ); - if (hasUnsupportedRedirect) wantsBackend = true; + const isEveryRedirectSupported = nextJsRedirects.every(isRedirectSupportedByFirebase); + if (!isEveryRedirectSupported) wantsBackend = true; const redirects = nextJsRedirects .filter(isRedirectSupportedByFirebase) @@ -166,10 +164,8 @@ export async function build(dir: string): Promise { ) { wantsBackend = true; } else { - const hasUnsupportedRewrite = nextJsRewritesToUse.some( - (rewrite) => !isRewriteSupportedByFirebase(rewrite) - ); - if (hasUnsupportedRewrite) wantsBackend = true; + const isEveryRewriteSupported = nextJsRewritesToUse.every(isRewriteSupportedByFirebase); + if (!isEveryRewriteSupported) wantsBackend = true; } // Can we change i18n into Firebase settings? From 9a230e3a36439f4f93810054107cfad9269f9cc1 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 15:56:54 -0300 Subject: [PATCH 40/46] improve Next.js utils documentation --- src/frameworks/next/utils.ts | 48 +++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 68cf5b88dfe..6b4773c9db9 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -25,28 +25,68 @@ export function cleanEscapedChars(path: string): string { } /** - * Whether a Next.js rewrite is supported by Firebase. + * Whether a Next.js rewrite is supported by `firebase.json`. + * + * See: https://firebase.google.com/docs/hosting/full-config#rewrites + * + * Next.js unsupported rewrites includes: + * - Rewrites with the `has` property that is used by Next.js for Header, + * Cookie, and Query Matching. + * - https://nextjs.org/docs/api-reference/next.config.js/rewrites#header-cookie-and-query-matching + * + * - Rewrites using regex for path matching. + * - https://nextjs.org/docs/api-reference/next.config.js/rewrites#regex-path-matching + * + * - Rewrites to external URLs */ export function isRewriteSupportedByFirebase(rewrite: Rewrite): boolean { return !("has" in rewrite || pathHasRegex(rewrite.source) || isUrl(rewrite.destination)); } /** - * Whether a Next.js redirect is supported by Firebase. + * Whether a Next.js redirect is supported by `firebase.json`. + * + * See: https://firebase.google.com/docs/hosting/full-config#redirects + * + * Next.js unsupported redirects includes: + * - Redirects with the `has` property that is used by Next.js for Header, + * Cookie, and Query Matching. + * - https://nextjs.org/docs/api-reference/next.config.js/redirects#header-cookie-and-query-matching + * + * - Redirects using regex for path matching. + * - https://nextjs.org/docs/api-reference/next.config.js/redirects#regex-path-matching + * + * - Next.js internal redirects */ export function isRedirectSupportedByFirebase(redirect: Redirect): boolean { return !("has" in redirect || pathHasRegex(redirect.source) || "internal" in redirect); } /** - * Whether a Next.js header is supported by Firebase. + * Whether a Next.js custom header is supported by `firebase.json`. + * + * See: https://firebase.google.com/docs/hosting/full-config#headers + * + * Next.js unsupported headers includes: + * - Custom header with the `has` property that is used by Next.js for Header, + * Cookie, and Query Matching. + * - https://nextjs.org/docs/api-reference/next.config.js/headers#header-cookie-and-query-matching + * + * - Custom header using regex for path matching. + * - https://nextjs.org/docs/api-reference/next.config.js/headers#regex-path-matching */ export function isHeaderSupportedByFirebase(header: Header): boolean { return !("has" in header || pathHasRegex(header.source)); } /** - * Firebase Rewrites that can be supported by firebase.json. + * Get which Next.js rewrites will be used before checking supported items individually. + * + * Next.js rewrites can be arrays or objects: + * - For arrays, all supported items can be used. + * - For objects only `beforeFiles` can be used. + * + * See: https://nextjs.org/docs/api-reference/next.config.js/rewrites */ export function getNextjsRewritesToUse( nextJsRewrites: Manifest["rewrites"] From a0f4c057ee8640d654d820c4dae22361f6f8c7fb Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 19:02:49 -0300 Subject: [PATCH 41/46] readJSON util with type --- src/frameworks/utils.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/frameworks/utils.ts b/src/frameworks/utils.ts index 39bb79fab26..4111e6f5b06 100644 --- a/src/frameworks/utils.ts +++ b/src/frameworks/utils.ts @@ -1,6 +1,19 @@ +import { readJSON as originalReadJSON } from "fs-extra"; +import type { ReadOptions } from "fs-extra"; + /** * Whether the given string starts with http:// or https:// */ export function isUrl(url: string): boolean { return /^https?:\/\//.test(url); } + +/** + * add type to readJSON + */ +export function readJSON( + file: string, + options?: ReadOptions | BufferEncoding | string +): Promise { + return originalReadJSON(file, options) as Promise; +} From 425fa5d0d91f9a82a7b1761f9b36233d6edb1dba Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Mon, 5 Dec 2022 19:04:06 -0300 Subject: [PATCH 42/46] replace readFile/JSON.parse with typed readJSON --- src/frameworks/next/index.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index ee23f3c272b..1b2db350f03 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -29,6 +29,7 @@ import { isRewriteSupportedByFirebase, } from "./utils"; import type { Manifest } from "./interfaces"; +import { readJSON } from "../utils"; const CLI_COMMAND = join( "node_modules", @@ -230,15 +231,15 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin } } - const [prerenderManifestBuffer, routesManifestBuffer] = await Promise.all([ - readFile( + const [prerenderManifest, routesManifest] = await Promise.all([ + readJSON( join( sourceDir, distDir, "prerender-manifest.json" // TODO: get this from next/constants ) ), - readFile( + readJSON( join( sourceDir, distDir, @@ -247,9 +248,6 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin ), ]); - const prerenderManifest = JSON.parse(prerenderManifestBuffer.toString()); - const routesManifest = JSON.parse(routesManifestBuffer.toString()) as Manifest; - const { redirects = [], rewrites = [], headers = [] } = routesManifest; const rewritesToUse = getNextjsRewritesToUse(rewrites); From f3b4a445e516ec17b90d19b7ca6ec0ca83ed5ae4 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Thu, 8 Dec 2022 20:10:50 -0300 Subject: [PATCH 43/46] fix cleanEscapedChars, improve function doc thanks @jamesdaniels --- src/frameworks/next/utils.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/frameworks/next/utils.ts b/src/frameworks/next/utils.ts index 6b4773c9db9..040f06adedb 100644 --- a/src/frameworks/next/utils.ts +++ b/src/frameworks/next/utils.ts @@ -18,10 +18,21 @@ export function pathHasRegex(path: string): boolean { } /** - * Remove double backslashes from a string + * Remove escaping from characters used for Regex patch matching that Next.js + * requires. As Firebase Hosting does not require escaping for those charachters, + * we remove them. + * + * According to the Next.js documentation: + * ```md + * The following characters (, ), {, }, :, *, +, ? are used for regex path + * matching, so when used in the source as non-special values they must be + * escaped by adding \\ before them. + * ``` + * + * See: https://nextjs.org/docs/api-reference/next.config.js/rewrites#regex-path-matching */ export function cleanEscapedChars(path: string): string { - return path.replace(/\\/g, ""); + return path.replace(/\\([(){}:+?*])/g, (a, b: string) => b); } /** From c2a9c4a217d543f024298b9ded4d13dfc727f808 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Thu, 8 Dec 2022 20:11:41 -0300 Subject: [PATCH 44/46] fix `cleanEscapedChars` test --- src/test/frameworks/next/utils.spec.ts | 40 ++++++++++++++++++++------ 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/src/test/frameworks/next/utils.spec.ts b/src/test/frameworks/next/utils.spec.ts index aee925e50a3..06c0e995b25 100644 --- a/src/test/frameworks/next/utils.spec.ts +++ b/src/test/frameworks/next/utils.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { pathHasRegex, - // cleanEscapedChars, // FIXME: function should be fixed for the tests to work + cleanEscapedChars, isRewriteSupportedByFirebase, isRedirectSupportedByFirebase, isHeaderSupportedByFirebase, @@ -49,14 +49,36 @@ describe("Next.js utils", () => { }); }); - // FIXME: function should be fixed for the tests to work - // describe("cleanEscapedChars", () => { - // it("should clean escaped chars", () => { - // for (const path of pathsWithRegexAndEscapedChars) { - // expect(cleanEscapedChars(path).includes("\\")).to.be.false; - // } - // }); - // }); + describe("cleanEscapedChars", () => { + it("should clean escaped chars", () => { + // path containing all escaped chars + const testPath = "/\\(\\)\\{\\}\\:\\+\\?\\*/:slug"; + + expect(testPath.includes("\\(")).to.be.true; + expect(cleanEscapedChars(testPath).includes("\\(")).to.be.false; + + expect(testPath.includes("\\)")).to.be.true; + expect(cleanEscapedChars(testPath).includes("\\)")).to.be.false; + + expect(testPath.includes("\\{")).to.be.true; + expect(cleanEscapedChars(testPath).includes("\\{")).to.be.false; + + expect(testPath.includes("\\}")).to.be.true; + expect(cleanEscapedChars(testPath).includes("\\}")).to.be.false; + + expect(testPath.includes("\\:")).to.be.true; + expect(cleanEscapedChars(testPath).includes("\\:")).to.be.false; + + expect(testPath.includes("\\+")).to.be.true; + expect(cleanEscapedChars(testPath).includes("\\+")).to.be.false; + + expect(testPath.includes("\\?")).to.be.true; + expect(cleanEscapedChars(testPath).includes("\\?")).to.be.false; + + expect(testPath.includes("\\*")).to.be.true; + expect(cleanEscapedChars(testPath).includes("\\*")).to.be.false; + }); + }); describe("isRewriteSupportedByFirebase", () => { it("should allow supported rewrites", () => { From fa809ef3882eab2b8457f650b6a06cf6bf57df1b Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Thu, 8 Dec 2022 20:14:57 -0300 Subject: [PATCH 45/46] replace as Manifest with typed readJSON --- src/frameworks/next/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 1b2db350f03..9e4a3e0c2fa 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -127,8 +127,8 @@ export async function build(dir: string): Promise { } } - const manifestBuffer = await readFile(join(dir, distDir, "routes-manifest.json")); - const manifest = JSON.parse(manifestBuffer.toString()) as Manifest; + const manifest = await readJSON(join(dir, distDir, "routes-manifest.json")); + const { headers: nextJsHeaders = [], redirects: nextJsRedirects = [], From 44e0148aafc34b20eaf60e4975a001d4bb708a36 Mon Sep 17 00:00:00 2001 From: Leonardo Ortiz Date: Thu, 8 Dec 2022 20:17:42 -0300 Subject: [PATCH 46/46] typed readJSON defaulting to `any` --- src/frameworks/next/index.ts | 2 +- src/frameworks/utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index 9e4a3e0c2fa..4c715d84c95 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -232,7 +232,7 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin } const [prerenderManifest, routesManifest] = await Promise.all([ - readJSON( + readJSON( join( sourceDir, distDir, diff --git a/src/frameworks/utils.ts b/src/frameworks/utils.ts index 4111e6f5b06..d95484cbebf 100644 --- a/src/frameworks/utils.ts +++ b/src/frameworks/utils.ts @@ -11,7 +11,7 @@ export function isUrl(url: string): boolean { /** * add type to readJSON */ -export function readJSON( +export function readJSON( file: string, options?: ReadOptions | BufferEncoding | string ): Promise {