From 081a6143c9974abb40dce6ea56776174873ff0fd Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Tue, 20 Aug 2024 14:25:22 -0400 Subject: [PATCH 01/15] changelog Signed-off-by: Nicholas Bucher --- changelog/v0.0.34/support-for-read-only-filesystems.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changelog/v0.0.34/support-for-read-only-filesystems.yaml diff --git a/changelog/v0.0.34/support-for-read-only-filesystems.yaml b/changelog/v0.0.34/support-for-read-only-filesystems.yaml new file mode 100644 index 00000000..4906170d --- /dev/null +++ b/changelog/v0.0.34/support-for-read-only-filesystems.yaml @@ -0,0 +1,6 @@ +changelog: + - type: FIX + issueLink: https://github.com/solo-io/gloo-mesh-enterprise/issues/18336 + description: >- + Adds a server with a view engine to the project, which only is used to + serve the UI and insert configuration from environment variables. From 78703a565b59fc694d39ccbe9427836656855d9a Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Tue, 20 Aug 2024 14:27:02 -0400 Subject: [PATCH 02/15] yarn audit fix Signed-off-by: Nicholas Bucher --- changelog/v0.0.34/support-for-read-only-filesystems.yaml | 1 + projects/ui/package.json | 3 ++- projects/ui/yarn.lock | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/changelog/v0.0.34/support-for-read-only-filesystems.yaml b/changelog/v0.0.34/support-for-read-only-filesystems.yaml index 4906170d..16cc5125 100644 --- a/changelog/v0.0.34/support-for-read-only-filesystems.yaml +++ b/changelog/v0.0.34/support-for-read-only-filesystems.yaml @@ -4,3 +4,4 @@ changelog: description: >- Adds a server with a view engine to the project, which only is used to serve the UI and insert configuration from environment variables. + Also fixes a yarn audit issue with axios. diff --git a/projects/ui/package.json b/projects/ui/package.json index 7c60a4a7..17e5eeb8 100644 --- a/projects/ui/package.json +++ b/projects/ui/package.json @@ -76,6 +76,7 @@ "tar": "^6.2.1", "follow-redirects": "^1.15.6", "braces": "^3.0.3", - "ws": "^8.17.1" + "ws": "^8.17.1", + "axios": "^1.7.4" } } diff --git a/projects/ui/yarn.lock b/projects/ui/yarn.lock index fa8efa48..0b101183 100644 --- a/projects/ui/yarn.lock +++ b/projects/ui/yarn.lock @@ -3831,10 +3831,10 @@ axe-core@^4.9.1: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.9.1.tgz#fcd0f4496dad09e0c899b44f6c4bb7848da912ae" integrity sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw== -axios@^1.4.0: - version "1.6.8" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66" - integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== +axios@^1.4.0, axios@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2" + integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw== dependencies: follow-redirects "^1.15.6" form-data "^4.0.0" From d3e4315af2457320236427435ba9247645c03663 Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Wed, 21 Aug 2024 13:47:47 -0400 Subject: [PATCH 03/15] added server for config, with ejs. Signed-off-by: Nicholas Bucher --- projects/server/app.js | 33 ++ projects/server/bin/www | 83 +++++ projects/server/package.json | 15 + projects/server/yarn.lock | 600 +++++++++++++++++++++++++++++++++++ 4 files changed, 731 insertions(+) create mode 100644 projects/server/app.js create mode 100755 projects/server/bin/www create mode 100644 projects/server/package.json create mode 100644 projects/server/yarn.lock diff --git a/projects/server/app.js b/projects/server/app.js new file mode 100644 index 00000000..179b4f93 --- /dev/null +++ b/projects/server/app.js @@ -0,0 +1,33 @@ +var express = require("express"); +var path = require("path"); + +// Express and view engine setup +var app = express(); +app.set("views", path.join(__dirname, "public", "dist")); +app.set("view engine", "ejs"); + +// The environment variables that we will pass through to the React app. +var variablesInit = ` +window.__appEnvironmentVariables = ${JSON.stringify( + Object.fromEntries( + Object.entries(process.env).filter(([key, _value]) => + key.startsWith("VITE_") + ) + ) +)}; +`; + +// This renders the index.ejs file +app.get("/", (_req, res) => { + res.render("index.ejs", { VariablesInit: variablesInit }); +}); + +// This serves all static assets. +app.use(express.static(__dirname + "/public/dist")); + +// Any fallthrough routes go to index.ejs. +app.get("*", (_req, res) => { + res.render("index.ejs", { VariablesInit: variablesInit }); +}); + +module.exports = app; diff --git a/projects/server/bin/www b/projects/server/bin/www new file mode 100755 index 00000000..6f029a46 --- /dev/null +++ b/projects/server/bin/www @@ -0,0 +1,83 @@ +/** + * Module dependencies. + */ + +var app = require("../app"); +var http = require("http"); + +/** + * Get port from environment and store in Express. + */ + +var port = normalizePort(process.env.PORT || "3000"); +app.set("port", port); + +/** + * Create HTTP server. + */ + +var server = http.createServer(app); + +/** + * Listen on provided port, on all network interfaces. + */ + +server.listen(port); +server.on("error", onError); +server.on("listening", onListening); + +/** + * Normalize a port into a number, string, or false. + */ + +function normalizePort(val) { + var port = parseInt(val, 10); + + if (isNaN(port)) { + // named pipe + return val; + } + + if (port >= 0) { + // port number + return port; + } + + return false; +} + +/** + * Event listener for HTTP server "error" event. + */ + +function onError(error) { + if (error.syscall !== "listen") { + throw error; + } + + var bind = typeof port === "string" ? "Pipe " + port : "Port " + port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case "EACCES": + console.error(bind + " requires elevated privileges"); + process.exit(1); + break; + case "EADDRINUSE": + console.error(bind + " is already in use"); + process.exit(1); + break; + default: + throw error; + } +} + +/** + * Event listener for HTTP server "listening" event. + */ + +function onListening() { + var addr = server.address(); + var bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port; + console.log("Listening on " + bind); +} diff --git a/projects/server/package.json b/projects/server/package.json new file mode 100644 index 00000000..413d1f2f --- /dev/null +++ b/projects/server/package.json @@ -0,0 +1,15 @@ +{ + "name": "server", + "version": "1.0.0", + "description": "", + "main": "app.js", + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "ejs": "^3.1.10", + "express": "^4.19.2", + "http": "^0.0.1-security", + "path": "^0.12.7" + } +} diff --git a/projects/server/yarn.lock b/projects/server/yarn.lock new file mode 100644 index 00000000..373dac30 --- /dev/null +++ b/projects/server/yarn.lock @@ -0,0 +1,600 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +async@^3.2.3: + version "3.2.6" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" + integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +body-parser@1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" + +chalk@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== + dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" + gopd "^1.0.1" + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +ejs@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== + dependencies: + jake "^10.8.5" + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== + dependencies: + get-intrinsic "^1.2.4" + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +express@^4.19.2: + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.6.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +get-intrinsic@^1.1.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== + dependencies: + es-define-property "^1.0.0" + +has-proto@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +http@^0.0.1-security: + version "0.0.1-security" + resolved "https://registry.yarnpkg.com/http/-/http-0.0.1-security.tgz#3aac09129d12dc2747bbce4157afde20ad1f7995" + integrity sha512-RnDvP10Ty9FxqOtPZuxtebw1j4L/WiqNMDtuc1YMH1XQm5TgDRaR1G9u8upL6KD1bXHSp9eSXo/ED+8Q7FAr+g== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + +inherits@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +jake@^10.8.5: + version "10.9.2" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f" + integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +object-inspect@^1.13.1: + version "1.13.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.2.tgz#dea0088467fb991e67af4058147a24824a3043ff" + integrity sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path@^0.12.7: + version "0.12.7" + resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q== + dependencies: + process "^0.11.1" + util "^0.10.3" + +process@^0.11.1: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +safe-buffer@5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== + dependencies: + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" + gopd "^1.0.1" + has-property-descriptors "^1.0.2" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +side-channel@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== From 8c47f22c5103c315346bed16229e2d26207939cf Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Wed, 21 Aug 2024 16:59:50 -0400 Subject: [PATCH 04/15] Everything is ready besides a dockerfile. Added a ./scripts/startup.sh script for testing the build + run process. Signed-off-by: Nicholas Bucher --- projects/server/app.js | 2 +- projects/ui/.eslintrc.cjs | 1 + projects/ui/src/Apis/utility.ts | 5 +++- projects/ui/src/custom.d.ts | 12 +++++++++ projects/ui/src/user_variables.tmplr.ts | 18 ++++++++++++- scripts/startup.sh | 36 +++++++++++++++++++++++++ 6 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 scripts/startup.sh diff --git a/projects/server/app.js b/projects/server/app.js index 179b4f93..6dd3ef34 100644 --- a/projects/server/app.js +++ b/projects/server/app.js @@ -8,7 +8,7 @@ app.set("view engine", "ejs"); // The environment variables that we will pass through to the React app. var variablesInit = ` -window.__appEnvironmentVariables = ${JSON.stringify( +const insertedEnvironmentVariables = ${JSON.stringify( Object.fromEntries( Object.entries(process.env).filter(([key, _value]) => key.startsWith("VITE_") diff --git a/projects/ui/.eslintrc.cjs b/projects/ui/.eslintrc.cjs index 480f2140..a4ef82c6 100644 --- a/projects/ui/.eslintrc.cjs +++ b/projects/ui/.eslintrc.cjs @@ -49,6 +49,7 @@ module.exports = { }, globals: { JSX: true, + insertedEnvironmentVariables: "readonly", }, env: { es6: true, diff --git a/projects/ui/src/Apis/utility.ts b/projects/ui/src/Apis/utility.ts index 2f00fe84..ff180ea6 100644 --- a/projects/ui/src/Apis/utility.ts +++ b/projects/ui/src/Apis/utility.ts @@ -3,7 +3,10 @@ import useSWR from "swr"; import { AuthContext } from "../Context/AuthContext"; import { ErrorMessageResponse } from "./api-types"; -let _portalServerURL = import.meta.env.VITE_PORTAL_SERVER_URL; +let _portalServerURL = insertedEnvironmentVariables?.VITE_PORTAL_SERVER_URL; +if (_portalServerURL === undefined) { + _portalServerURL = import.meta.env.VITE_PORTAL_SERVER_URL; +} if ( _portalServerURL && typeof _portalServerURL === "string" && diff --git a/projects/ui/src/custom.d.ts b/projects/ui/src/custom.d.ts index c6f84684..59517d88 100644 --- a/projects/ui/src/custom.d.ts +++ b/projects/ui/src/custom.d.ts @@ -6,3 +6,15 @@ declare module "*.svg" { const src: string; export default src; } + +/** + * This is a global variable that /projects/server/index.js inserts + * into the UI build when serving it. It is used so that the + * environment variables can be dynamically updated after the + * Docker image is built. + */ +declare const insertedEnvironmentVariables: + | undefined + | { + [key: string]: string; + }; diff --git a/projects/ui/src/user_variables.tmplr.ts b/projects/ui/src/user_variables.tmplr.ts index 558b57a3..f06da005 100644 --- a/projects/ui/src/user_variables.tmplr.ts +++ b/projects/ui/src/user_variables.tmplr.ts @@ -12,7 +12,10 @@ * If it has not been transformed, the next truthy value is returned. * Otherwise, the transformed value is returned. */ -function templateString(templateString: string, ...defaultValues: string[]) { +function templateString( + templateString: string, + ...defaultValues: (string | undefined)[] +) { if (/{{.*}}$/.test(templateString)) { let defaultValue = ""; for (let i = 0; i < defaultValues.length; i++) { @@ -32,6 +35,7 @@ function templateString(templateString: string, ...defaultValues: string[]) { // export const companyName = templateString( "{{ tmplr.company_name }}", + insertedEnvironmentVariables?.VITE_COMPANY_NAME, import.meta.env.VITE_COMPANY_NAME, "Example Company" ); @@ -44,6 +48,7 @@ document.title = companyName + " Portal"; */ export const tokenEndpoint = templateString( "{{ tmplr.tokenEndpoint }}", + insertedEnvironmentVariables?.VITE_TOKEN_ENDPOINT, import.meta.env.VITE_TOKEN_ENDPOINT ); @@ -54,6 +59,7 @@ export const tokenEndpoint = templateString( */ export const authEndpoint = templateString( "{{ tmplr.authEndpoint }}", + insertedEnvironmentVariables?.VITE_AUTH_ENDPOINT, import.meta.env.VITE_AUTH_ENDPOINT ); @@ -64,6 +70,7 @@ export const authEndpoint = templateString( */ export const logoutEndpoint = templateString( "{{ tmplr.logoutEndpoint }}", + insertedEnvironmentVariables?.VITE_LOGOUT_ENDPOINT, import.meta.env.VITE_LOGOUT_ENDPOINT ); @@ -74,6 +81,7 @@ export const logoutEndpoint = templateString( */ export const clientId = templateString( "{{ tmplr.clientId }}", + insertedEnvironmentVariables?.VITE_CLIENT_ID, import.meta.env.VITE_CLIENT_ID ); @@ -83,6 +91,7 @@ export const clientId = templateString( */ export const appliedOidcAuthCodeConfig = templateString( "{{ tmplr.appliedOidcAuthCodeConfig }}", + insertedEnvironmentVariables?.VITE_APPLIED_OIDC_AUTH_CODE_CONFIG, import.meta.env.VITE_APPLIED_OIDC_AUTH_CODE_CONFIG ); @@ -93,6 +102,7 @@ export const appliedOidcAuthCodeConfig = templateString( */ export const oidcAuthCodeConfigCallbackPath = templateString( "{{ tmplr.oidcAuthCodeConfigCallbackPath }}", + insertedEnvironmentVariables?.VITE_OIDC_AUTH_CODE_CONFIG_CALLBACK_PATH, import.meta.env.VITE_OIDC_AUTH_CODE_CONFIG_CALLBACK_PATH, (import.meta.env.VITE_PORTAL_SERVER_URL ?? "") + "/login" ); @@ -104,6 +114,7 @@ export const oidcAuthCodeConfigCallbackPath = templateString( */ export const oidcAuthCodeConfigLogoutPath = templateString( "{{ tmplr.oidcAuthCodeConfigLogoutPath }}", + insertedEnvironmentVariables?.VITE_OIDC_AUTH_CODE_CONFIG_LOGOUT_PATH, import.meta.env.VITE_OIDC_AUTH_CODE_CONFIG_LOGOUT_PATH, (import.meta.env.VITE_PORTAL_SERVER_URL ?? "") + "/logout" ); @@ -113,6 +124,7 @@ export const oidcAuthCodeConfigLogoutPath = templateString( */ export const swaggerConfigURL = templateString( "{{ tmplr.swaggerConfigURL }}", + insertedEnvironmentVariables?.VITE_SWAGGER_CONFIG_URL, import.meta.env.VITE_SWAGGER_CONFIG_URL, "" ); @@ -122,6 +134,7 @@ export const swaggerConfigURL = templateString( */ export const audience = templateString( "{{ tmplr.audience }}", + insertedEnvironmentVariables?.VITE_AUDIENCE, import.meta.env.VITE_AUDIENCE, "" ); @@ -131,6 +144,7 @@ export const audience = templateString( */ export const homeImageURL = templateString( "{{ tmplr.homeImageURL }}", + insertedEnvironmentVariables?.VITE_HOME_IMAGE_URL, import.meta.env.VITE_HOME_IMAGE_URL, "" ); @@ -140,6 +154,7 @@ export const homeImageURL = templateString( */ export const apisImageURL = templateString( "{{ tmplr.apisImageURL }}", + insertedEnvironmentVariables?.VITE_APIS_IMAGE_URL, import.meta.env.VITE_APIS_IMAGE_URL, "" ); @@ -149,6 +164,7 @@ export const apisImageURL = templateString( */ export const logoImageURL = templateString( "{{ tmplr.logoImageURL }}", + insertedEnvironmentVariables?.VITE_LOGO_IMAGE_URL, import.meta.env.VITE_LOGO_IMAGE_URL, "" ); diff --git a/scripts/startup.sh b/scripts/startup.sh new file mode 100644 index 00000000..62a57940 --- /dev/null +++ b/scripts/startup.sh @@ -0,0 +1,36 @@ +############################# +# +# Builds the UI, and runs the Express server for it. +# +############################# + +############################# +# 1. Build steps +############################# + +# Build the UI. +yarn --cwd ./projects/ui build + +# Cleanup old server files if they exist. +rm -rf ./projects/server/public/dist || true + +# Move the UI build to the server. +mv ./projects/ui/dist ./projects/server/public/dist + +# Copy the index file and add in the `insertedEnvironmentVariables` variable. +cat ./projects/server/public/dist/index.html | + sed s/\/\\\<\%-\ VariablesInit\ \%\>\<\\/script\>/ \ + >./projects/server/public/dist/index.ejs + +############################# +# 2. Run steps +############################# + +# Read the environment variables. +source projects/ui/.env.local +VITE_PORTAL_SERVER_URL=${VITE_PORTAL_SERVER_URL} \ + VITE_CLIENT_ID=${VITE_CLIENT_ID} \ + VITE_TOKEN_ENDPOINT=${VITE_TOKEN_ENDPOINT} \ + VITE_AUTH_ENDPOINT=${VITE_AUTH_ENDPOINT} \ + VITE_LOGOUT_ENDPOINT=${VITE_LOGOUT_ENDPOINT} \ + yarn --cwd ./projects/server start From 8b3331f6c89a036acecc39386d620c158bd4900d Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Wed, 21 Aug 2024 17:28:43 -0400 Subject: [PATCH 05/15] notes Signed-off-by: Nicholas Bucher --- projects/server/bin/www | 6 ++++++ projects/server/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/projects/server/bin/www b/projects/server/bin/www index 6f029a46..f345b558 100755 --- a/projects/server/bin/www +++ b/projects/server/bin/www @@ -1,3 +1,9 @@ +/** + * This file was pulled from the Express generator's pug template, and does the following: + * - Creates an http server on the requested port, using the Express app from `../app.js`. + * - Adds some logging messages for different statuses. + */ + /** * Module dependencies. */ diff --git a/projects/server/package.json b/projects/server/package.json index 413d1f2f..8d5503e6 100644 --- a/projects/server/package.json +++ b/projects/server/package.json @@ -2,7 +2,7 @@ "name": "server", "version": "1.0.0", "description": "", - "main": "app.js", + "main": "./bin/www", "scripts": { "start": "node ./bin/www" }, From 2aae9073c6688c69ab1bd74e7268baf2969d8b08 Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Wed, 21 Aug 2024 17:30:14 -0400 Subject: [PATCH 06/15] comments Signed-off-by: Nicholas Bucher --- projects/ui/src/custom.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/ui/src/custom.d.ts b/projects/ui/src/custom.d.ts index 59517d88..a41abebb 100644 --- a/projects/ui/src/custom.d.ts +++ b/projects/ui/src/custom.d.ts @@ -8,7 +8,7 @@ declare module "*.svg" { } /** - * This is a global variable that /projects/server/index.js inserts + * This is a global variable that /projects/server/app.js inserts * into the UI build when serving it. It is used so that the * environment variables can be dynamically updated after the * Docker image is built. From b81fccef63b996af8f5a8a3af2a089069eef9a60 Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Wed, 21 Aug 2024 17:32:13 -0400 Subject: [PATCH 07/15] comments Signed-off-by: Nicholas Bucher --- scripts/startup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/startup.sh b/scripts/startup.sh index 62a57940..8dd6b187 100644 --- a/scripts/startup.sh +++ b/scripts/startup.sh @@ -26,7 +26,7 @@ cat ./projects/server/public/dist/index.html | # 2. Run steps ############################# -# Read the environment variables. +# Read the environment variables in and then start the server. source projects/ui/.env.local VITE_PORTAL_SERVER_URL=${VITE_PORTAL_SERVER_URL} \ VITE_CLIENT_ID=${VITE_CLIENT_ID} \ From 303a1019f6d6d3d68773bfbe06ba1667adcb9e95 Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Thu, 22 Aug 2024 12:26:20 -0400 Subject: [PATCH 08/15] added dockerfile, changed server port to 4000 Signed-off-by: Nicholas Bucher --- Dockerfile | 49 ++++++++++++++++++++++++++++++----------- projects/server/bin/www | 2 +- scripts/startup.sh | 32 ++++++++++++++------------- 3 files changed, 54 insertions(+), 29 deletions(-) diff --git a/Dockerfile b/Dockerfile index d5152a40..8bf13e59 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,34 @@ -FROM node:18.16.0 +############### +# # +# Build Stage # +# # +############### + +FROM node:18.16.0 AS build_stage +# Install global dependencies. +RUN apt-get update && apt-get install -y build-essential + +# Copy all project files. +WORKDIR /app +COPY ./projects projects +COPY ./scripts scripts + +# Run the startup script, without starting the server. +# This script: +# - Builds the UI. +# - Moves the UI build folder to the server project. +# - Inserts an EJS view engine variable into the UI build, +# so that the server can send the live environment variables +# along with the UI when the build is served. +RUN START_SERVER=false sh ./scripts/startup.sh + +############### +# # +# Serve Stage # +# # +############### + +FROM node:18.16.0 AS serve_stage ENV VITE_PORTAL_SERVER_URL=$VITE_PORTAL_SERVER_URL \ VITE_CLIENT_ID=$VITE_CLIENT_ID \ @@ -15,19 +45,12 @@ ENV VITE_PORTAL_SERVER_URL=$VITE_PORTAL_SERVER_URL \ VITE_LOGO_IMAGE_URL=$VITE_LOGO_IMAGE_URL \ VITE_COMPANY_NAME=$VITE_COMPANY_NAME -# Copy files for build +# Copy the server files, (this includes the UI build). WORKDIR /app -COPY ./projects projects -WORKDIR /app/projects/ui - -# Install global dependencies and set up for runtime -RUN apt-get update && apt-get install -y build-essential -RUN yarn install -EXPOSE 4000 +COPY --from=build_stage /app/projects/server . -# Build the app and pass in the environment variables, then start it. -# The build can't happen in 2 stages (build and runtime), -# since these variables will change when the image is deployed. +# Pass through the environment variables, and then start the server. +# These variables will change when the image is deployed. ENTRYPOINT VITE_PORTAL_SERVER_URL=$VITE_PORTAL_SERVER_URL \ VITE_CLIENT_ID=$VITE_CLIENT_ID \ VITE_TOKEN_ENDPOINT=$VITE_TOKEN_ENDPOINT \ @@ -42,4 +65,4 @@ ENTRYPOINT VITE_PORTAL_SERVER_URL=$VITE_PORTAL_SERVER_URL \ VITE_APIS_IMAGE_URL=$VITE_APIS_IMAGE_URL \ VITE_LOGO_IMAGE_URL=$VITE_LOGO_IMAGE_URL \ VITE_COMPANY_NAME=$VITE_COMPANY_NAME \ - yarn build && yarn run vite preview --port 4000 --host + yarn start diff --git a/projects/server/bin/www b/projects/server/bin/www index f345b558..7e4b92c9 100755 --- a/projects/server/bin/www +++ b/projects/server/bin/www @@ -15,7 +15,7 @@ var http = require("http"); * Get port from environment and store in Express. */ -var port = normalizePort(process.env.PORT || "3000"); +var port = normalizePort(process.env.PORT || "4000"); app.set("port", port); /** diff --git a/scripts/startup.sh b/scripts/startup.sh index 8dd6b187..25dada6b 100644 --- a/scripts/startup.sh +++ b/scripts/startup.sh @@ -1,11 +1,11 @@ -############################# -# -# Builds the UI, and runs the Express server for it. -# -############################# +########################################################## +# # +# Builds the UI, and optionally runs the Express server. # +# # +########################################################## ############################# -# 1. Build steps +# 1. Build steps # ############################# # Build the UI. @@ -23,14 +23,16 @@ cat ./projects/server/public/dist/index.html | >./projects/server/public/dist/index.ejs ############################# -# 2. Run steps +# 2. Run steps # ############################# -# Read the environment variables in and then start the server. -source projects/ui/.env.local -VITE_PORTAL_SERVER_URL=${VITE_PORTAL_SERVER_URL} \ - VITE_CLIENT_ID=${VITE_CLIENT_ID} \ - VITE_TOKEN_ENDPOINT=${VITE_TOKEN_ENDPOINT} \ - VITE_AUTH_ENDPOINT=${VITE_AUTH_ENDPOINT} \ - VITE_LOGOUT_ENDPOINT=${VITE_LOGOUT_ENDPOINT} \ - yarn --cwd ./projects/server start +if [ "$START_SERVER" != 'false' ]; then + # Read the environment variables in and then start the server. + source projects/ui/.env.local + VITE_PORTAL_SERVER_URL=${VITE_PORTAL_SERVER_URL} \ + VITE_CLIENT_ID=${VITE_CLIENT_ID} \ + VITE_TOKEN_ENDPOINT=${VITE_TOKEN_ENDPOINT} \ + VITE_AUTH_ENDPOINT=${VITE_AUTH_ENDPOINT} \ + VITE_LOGOUT_ENDPOINT=${VITE_LOGOUT_ENDPOINT} \ + yarn --cwd ./projects/server start +fi From f27369afac69f365a649a952b0c82367d99b2b1f Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Thu, 22 Aug 2024 12:26:40 -0400 Subject: [PATCH 09/15] comments Signed-off-by: Nicholas Bucher --- Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Dockerfile b/Dockerfile index 8bf13e59..00c19bd9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,7 @@ ############### FROM node:18.16.0 AS build_stage + # Install global dependencies. RUN apt-get update && apt-get install -y build-essential From 3d27129ab8598f100f059760145699cbf49af8ae Mon Sep 17 00:00:00 2001 From: Nicholas Bucher Date: Thu, 22 Aug 2024 14:08:50 -0400 Subject: [PATCH 10/15] small update Signed-off-by: Nicholas Bucher --- projects/ui/index.html | 1 + scripts/startup.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/projects/ui/index.html b/projects/ui/index.html index 943d420f..647bc39b 100644 --- a/projects/ui/index.html +++ b/projects/ui/index.html @@ -10,6 +10,7 @@