diff --git a/.github/workflows/deploy.staging.yml b/.github/workflows/deploy.staging.yml index 5a3217b..545c61c 100644 --- a/.github/workflows/deploy.staging.yml +++ b/.github/workflows/deploy.staging.yml @@ -41,6 +41,7 @@ jobs: # remove these tests in production - Anton NOTION_TEAMS_ID: ${{ secrets.NOTION_TEAMS_ID }} WEBFORMS_TOKEN: ${{ secrets.WEBFORMS_TOKEN }} NOTION_PROJECTS_ID: ${{ secrets.NOTION_PROJECTS_ID}} + NOTION_REFRESH_ID: ${{ secrets.NOTION_REFRESH_ID }} steps: - name: actions checkout v3 @@ -50,4 +51,4 @@ jobs: # remove these tests in production - Anton uses: superfly/flyctl-actions/setup-flyctl@master - name: Fly deploy - run: flyctl deploy --build-arg ANTON=${{ secrets.ANTON }} --build-arg WEBFORMS_TOKEN=${{ secrets.WEBFORMS_TOKEN }} --build-arg NOTION_MEMBERS_ID=${{ secrets.NOTION_MEMBERS_ID }} --build-arg NOTION_TOKEN=${{ secrets.NOTION_TOKEN }} --build-arg NOTION_PROJECTS_ID=${{ secrets.NOTION_PROJECTS_ID }} --build-arg NOTION_TEAMS_ID=${{ secrets.NOTION_TEAMS_ID}} --build-arg NOTION_HOMEPAGE_ID=${{ secrets.NOTION_HOMEPAGE_ID}} --remote-only --config fly.staging.toml \ No newline at end of file + run: flyctl deploy --build-arg ANTON=${{ secrets.ANTON }} --build-arg WEBFORMS_TOKEN=${{ secrets.WEBFORMS_TOKEN }} --build-arg NOTION_MEMBERS_ID=${{ secrets.NOTION_MEMBERS_ID }} --build-arg NOTION_TOKEN=${{ secrets.NOTION_TOKEN }} --build-arg NOTION_PROJECTS_ID=${{ secrets.NOTION_PROJECTS_ID }} --build-arg NOTION_TEAMS_ID=${{ secrets.NOTION_TEAMS_ID}} --build-arg NOTION_HOMEPAGE_ID=${{ secrets.NOTION_HOMEPAGE_ID}} --build-arg NOTION_REFRESH_ID=${{ secrets.NOTION_REFRESH_ID}} --remote-only --config fly.staging.toml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index c9061fd..0107ccd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,6 +22,7 @@ ARG NOTION_MEMBERS_ID ARG NOTION_PROJECTS_ID ARG NOTION_TEAMS_ID ARG NOTION_HOMEPAGE_ID +ARG NOTION_REFRESH_ID # Set build-time environment variables @@ -32,6 +33,7 @@ ENV NOTION_MEMBERS_ID=${NOTION_MEMBERS_ID} ENV NOTION_PROJECTS_ID=${NOTION_PROJECTS_ID} ENV NOTION_TEAMS_ID=${NOTION_TEAMS_ID} ENV NOTION_HOMEPAGE_ID=${NOTION_HOMEPAGE_ID} +ENV NOTION_REFRESH_ID=${NOTION_REFRESH_ID} diff --git a/package-lock.json b/package-lock.json index 781d4cd..d1525ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,11 +20,13 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "astro": "^4.4.3", + "axios": "^1.7.7", "dotenv": "^16.4.5", "notion-client": "^6.16.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-notion-x": "^6.16.0", + "sharp": "^0.33.5", "tailwindcss": "^3.4.1", "typescript": "^5.3.3", "vitest": "^1.4.0", @@ -32,6 +34,7 @@ }, "devDependencies": { "@flydotio/dockerfile": "^0.5.2", + "@types/bcrypt": "^5.0.2", "@types/node": "^20.11.30" } }, @@ -146,9 +149,10 @@ } }, "node_modules/@astrojs/node": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-8.2.0.tgz", - "integrity": "sha512-keQIPvdx8hquG+KnWoJp7io/GoczBEJer9X8WzPHK2fnVRXYDKGzXWZw3Dbg0ZhXJreVV3xzniN7nr6e7hgDXg==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/@astrojs/node/-/node-8.3.3.tgz", + "integrity": "sha512-idrKhnnPSi0ABV+PCQsRQqVNwpOvVDF/+fkwcIiE8sr9J8EMvW9g/oyAt8T4X2OBJ8FUzYPL8klfCdG7r0eB5g==", + "license": "MIT", "dependencies": { "send": "^0.18.0", "server-destroy": "^1.0.1" @@ -613,6 +617,16 @@ "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.4.tgz", "integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==" }, + "node_modules/@emnapi/runtime": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz", + "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", @@ -1131,6 +1145,367 @@ "node": ">=16.0.0" } }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -1781,6 +2156,16 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/bcrypt": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz", + "integrity": "sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/cacheable-request": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", @@ -2568,6 +2953,30 @@ "node": ">=10" } }, + "node_modules/astro/node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/astro/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -2620,6 +3029,16 @@ "postcss": "^8.1.0" } }, + "node_modules/axios": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/axobject-query": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", @@ -2632,6 +3051,7 @@ "version": "1.6.6", "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz", "integrity": "sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==", + "license": "Apache-2.0", "optional": true }, "node_modules/babel-plugin-macros": { @@ -2663,38 +3083,52 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bare-events": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.2.0.tgz", - "integrity": "sha512-Yyyqff4PIFfSuthCZqLlPISTWHmnQxoPuAvkmgzsJEmG3CesdIv6Xweayl0JkCZJSB2yYIdJyEz97tpxNhgjbg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz", + "integrity": "sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==", + "license": "Apache-2.0", "optional": true }, "node_modules/bare-fs": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.1.5.tgz", - "integrity": "sha512-5t0nlecX+N2uJqdxe9d18A98cp2u9BETelbjKpiVgQqzzmVNFYWEAjQHqS+2Khgto1vcwhik9cXucaj5ve2WWA==", + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", + "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", + "license": "Apache-2.0", "optional": true, "dependencies": { "bare-events": "^2.0.0", - "bare-os": "^2.0.0", "bare-path": "^2.0.0", - "streamx": "^2.13.0" + "bare-stream": "^2.0.0" } }, "node_modules/bare-os": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.2.0.tgz", - "integrity": "sha512-hD0rOPfYWOMpVirTACt4/nK8mC55La12K5fY1ij8HAdfQakD62M+H4o4tpfKzVGLgRDTuk3vjA4GqGXXCeFbag==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", + "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", + "license": "Apache-2.0", "optional": true }, "node_modules/bare-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.0.tgz", - "integrity": "sha512-DIIg7ts8bdRKwJRJrUMy/PICEaQZaPGZ26lsSx9MJSwIhSrcdHn7/C8W+XmnG/rKi6BaRcz+JO00CjZteybDtw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", + "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", + "license": "Apache-2.0", "optional": true, "dependencies": { "bare-os": "^2.1.0" } }, + "node_modules/bare-stream": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.0.tgz", + "integrity": "sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "b4a": "^1.6.6", + "streamx": "^2.20.0" + } + }, "node_modules/base-64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", @@ -2798,11 +3232,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -3074,6 +3509,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC", "optional": true }, "node_modules/chrome-trace-event": { @@ -3260,7 +3696,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "optional": true, "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" @@ -3289,7 +3724,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "optional": true, "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" @@ -3492,6 +3926,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", "optional": true, "engines": { "node": ">=4.0.0" @@ -3539,10 +3974,10 @@ } }, "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "optional": true, + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", "engines": { "node": ">=8" } @@ -3622,9 +4057,10 @@ } }, "node_modules/dset": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz", - "integrity": "sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", "engines": { "node": ">=4" } @@ -3640,10 +4076,11 @@ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "jake": "^10.8.5" }, @@ -3924,6 +4361,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", "optional": true, "engines": { "node": ">=6" @@ -3954,6 +4392,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT", "optional": true }, "node_modules/fast-glob": { @@ -4044,9 +4483,10 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4091,6 +4531,25 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", @@ -4143,6 +4602,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT", "optional": true }, "node_modules/fsevents": { @@ -4216,6 +4676,7 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT", "optional": true }, "node_modules/github-slugger": { @@ -4654,6 +5115,7 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC", "optional": true }, "node_modules/inline-style-prefixer": { @@ -4675,8 +5137,7 @@ "node_modules/is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "optional": true + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -4803,6 +5264,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -6131,11 +6593,12 @@ ] }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -6210,6 +6673,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "optional": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6227,6 +6691,7 @@ "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT", "optional": true }, "node_modules/mlly": { @@ -6305,6 +6770,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==", + "license": "MIT", "optional": true }, "node_modules/neo-async": { @@ -6326,9 +6792,10 @@ } }, "node_modules/node-abi": { - "version": "3.55.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.55.0.tgz", - "integrity": "sha512-uPEjtyh2tFEvWYt4Jw7McOD5FPcHkcxm/tHZc5PWaDB3JYq0rGFUbgaAK+CT5pYpQddBfsZVWI08OwoRfdfbcQ==", + "version": "3.67.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz", + "integrity": "sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==", + "license": "MIT", "optional": true, "dependencies": { "semver": "^7.3.5" @@ -6337,26 +6804,12 @@ "node": ">=10" } }, - "node_modules/node-abi/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-abi/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -6364,16 +6817,11 @@ "node": ">=10" } }, - "node_modules/node-abi/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "optional": true - }, "node_modules/node-addon-api": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "license": "MIT", "optional": true }, "node_modules/node-fetch": { @@ -6822,9 +7270,10 @@ } }, "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" }, "node_modules/path-type": { "version": "4.0.0", @@ -7097,9 +7546,10 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" }, "node_modules/prebuild-install": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", - "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz", + "integrity": "sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==", + "license": "MIT", "optional": true, "dependencies": { "detect-libc": "^2.0.0", @@ -7126,6 +7576,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", "optional": true, "dependencies": { "buffer": "^5.5.0", @@ -7151,6 +7602,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true, "dependencies": { "base64-js": "^1.3.1", @@ -7161,6 +7613,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "license": "MIT", "optional": true, "dependencies": { "chownr": "^1.1.1", @@ -7173,6 +7626,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", "optional": true, "dependencies": { "bl": "^4.0.3", @@ -7287,6 +7741,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -7327,6 +7786,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "license": "MIT", "optional": true }, "node_modules/quick-lru": { @@ -7361,6 +7821,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "optional": true, "dependencies": { "deep-extend": "^0.6.0", @@ -8429,48 +8890,49 @@ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, "node_modules/sharp": { - "version": "0.32.6", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", - "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", "hasInstallScript": true, - "optional": true, + "license": "Apache-2.0", "dependencies": { "color": "^4.2.3", - "detect-libc": "^2.0.2", - "node-addon-api": "^6.1.0", - "prebuild-install": "^7.1.1", - "semver": "^7.5.4", - "simple-get": "^4.0.1", - "tar-fs": "^3.0.4", - "tunnel-agent": "^0.6.0" + "detect-libc": "^2.0.3", + "semver": "^7.6.3" }, "engines": { - "node": ">=14.15.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, "funding": { "url": "https://opencollective.com/libvips" - } - }, - "node_modules/sharp/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "optional": true, - "dependencies": { - "yallist": "^4.0.0" }, - "engines": { - "node": ">=10" + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" } }, "node_modules/sharp/node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "optional": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -8478,12 +8940,6 @@ "node": ">=10" } }, - "node_modules/sharp/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "optional": true - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8559,6 +9015,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true }, "node_modules/simple-get": { @@ -8579,6 +9036,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "optional": true, "dependencies": { "decompress-response": "^6.0.0", @@ -8590,7 +9048,6 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "optional": true, "dependencies": { "is-arrayish": "^0.3.1" } @@ -8722,13 +9179,15 @@ } }, "node_modules/streamx": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz", - "integrity": "sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ==", + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "license": "MIT", "optional": true, "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" }, "optionalDependencies": { "bare-events": "^2.2.0" @@ -8874,6 +9333,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.10.0" @@ -9008,9 +9468,10 @@ } }, "node_modules/tar-fs": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz", - "integrity": "sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", + "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", + "license": "MIT", "optional": true, "dependencies": { "pump": "^3.0.0", @@ -9025,6 +9486,7 @@ "version": "3.1.7", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "license": "MIT", "optional": true, "dependencies": { "b4a": "^1.6.4", @@ -9090,6 +9552,16 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "peer": true }, + "node_modules/text-decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz", + "integrity": "sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "b4a": "^1.6.4" + } + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -9160,6 +9632,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -9241,6 +9714,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", "optional": true, "dependencies": { "safe-buffer": "^5.0.1" diff --git a/package.json b/package.json index 187bda8..1a28d92 100644 --- a/package.json +++ b/package.json @@ -23,11 +23,13 @@ "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "astro": "^4.4.3", + "axios": "^1.7.7", "dotenv": "^16.4.5", "notion-client": "^6.16.0", "react": "^18.3.1", "react-dom": "^18.3.1", "react-notion-x": "^6.16.0", + "sharp": "^0.33.5", "tailwindcss": "^3.4.1", "typescript": "^5.3.3", "vitest": "^1.4.0", @@ -35,6 +37,7 @@ }, "devDependencies": { "@flydotio/dockerfile": "^0.5.2", + "@types/bcrypt": "^5.0.2", "@types/node": "^20.11.30" } } diff --git a/public/homepage/carousel_item_1_image_0.webp b/public/homepage/carousel_item_1_image_0.webp new file mode 100644 index 0000000..d4d3514 Binary files /dev/null and b/public/homepage/carousel_item_1_image_0.webp differ diff --git a/public/homepage/carousel_item_2_image_0.webp b/public/homepage/carousel_item_2_image_0.webp new file mode 100644 index 0000000..5d1fbab Binary files /dev/null and b/public/homepage/carousel_item_2_image_0.webp differ diff --git a/public/homepage/carousel_item_3_image_0.webp b/public/homepage/carousel_item_3_image_0.webp new file mode 100644 index 0000000..7f95fb3 Binary files /dev/null and b/public/homepage/carousel_item_3_image_0.webp differ diff --git a/public/homepage/homepageData.json b/public/homepage/homepageData.json new file mode 100644 index 0000000..2428aa1 --- /dev/null +++ b/public/homepage/homepageData.json @@ -0,0 +1,83 @@ +{ + "About Us": { + "heading": "About Us", + "subheadings": [ + "Who we are", + "What we do" + ], + "paragraphs": [ + "A group of 26 young leaders (aged 12-24) from the Ōrākei Local Board area who are determined to make a positive impact in our community. As a group we help provide a voice to the youth in our community. The youth council is supported by the Ōrākei Local Board.", + "The Youth of Ōrākei not only organises and supports events, but they equip and engage youth. But it is also our priority to give a voice to the youth in the community for the future of Ōrākei and wider Auckland by advising and submitting on council policies.", + "", + "" + ], + "images": [] + }, + "Carousel Item #1": { + "heading": "Carousel Item #1", + "subheadings": [ + "Beach Cleanup" + ], + "paragraphs": [ + "2nd September, 12:30 - 3:30PM", + "Come join us to clean the local beach and save our environment!", + "" + ], + "images": [ + "/homepage/carousel_item_1_image_0.webp" + ] + }, + "Carousel Item #2": { + "heading": "Carousel Item #2", + "subheadings": [ + "Art Gallery" + ], + "paragraphs": [ + "2nd August, 12:30 - 3:30PM", + "Come along and view some fine art! Maybe even meet some new friends!" + ], + "images": [ + "/homepage/carousel_item_2_image_0.webp" + ] + }, + "Carousel Item #3": { + "heading": "Carousel Item #3", + "subheadings": [ + "Quiz Night" + ], + "paragraphs": [ + "2nd July 12:30 - 3:30PM", + "This is a description about quizzes at YOO. Quizzes are good to learn from." + ], + "images": [ + "/homepage/carousel_item_3_image_0.webp" + ] + }, + "Goals": { + "heading": "Goals", + "subheadings": [ + "Support", + "Connect", + "Empower" + ], + "paragraphs": [ + "We support Ōrākei youth with networks, friends, and community-building events that help both our members and the wider Ōrākei community. We represent the voice of Ōrākei youth in scenarios that involve leaders from all across Auckland.", + "We have a mission to connect young people from around the region with each other to promote learning and community. Our teams work on group activities and engagements that build positive relationships across all of Ōrākei.", + "We help empower Ōrākei youth to do amazing things, with events, activities, and meetups designed to foster positive engagement and wellbeing." + ], + "images": [] + }, + "Hero": { + "heading": "Hero", + "subheadings": [ + "Youth of Ōrākei", + "Empowering and engaging Ōrākei youth to promote their wellbeing" + ], + "paragraphs": [ + "", + "We’re the Youth of Ōrākei, a group of 26 young leaders (aged 12-24) from the Ōrākei Local Board area who are determined to make a positive impact in our community.", + "" + ], + "images": [] + } +} \ No newline at end of file diff --git a/public/members/_zzz.webp b/public/members/_zzz.webp new file mode 100644 index 0000000..1a87a0f Binary files /dev/null and b/public/members/_zzz.webp differ diff --git a/public/members/communication_team_katerina.webp b/public/members/communication_team_katerina.webp new file mode 100644 index 0000000..069664e Binary files /dev/null and b/public/members/communication_team_katerina.webp differ diff --git a/public/members/communication_team_saffron.webp b/public/members/communication_team_saffron.webp new file mode 100644 index 0000000..379ada7 Binary files /dev/null and b/public/members/communication_team_saffron.webp differ diff --git a/public/members/communication_team_stella.webp b/public/members/communication_team_stella.webp new file mode 100644 index 0000000..a5dcef4 Binary files /dev/null and b/public/members/communication_team_stella.webp differ diff --git a/public/members/communication_team_testing.webp b/public/members/communication_team_testing.webp new file mode 100644 index 0000000..15f4ab7 Binary files /dev/null and b/public/members/communication_team_testing.webp differ diff --git a/public/members/communication_team_thanishka.webp b/public/members/communication_team_thanishka.webp new file mode 100644 index 0000000..cb18e8f Binary files /dev/null and b/public/members/communication_team_thanishka.webp differ diff --git a/public/members/houston_anna.webp b/public/members/houston_anna.webp new file mode 100644 index 0000000..c10f7d1 Binary files /dev/null and b/public/members/houston_anna.webp differ diff --git a/public/members/houston_chris.webp b/public/members/houston_chris.webp new file mode 100644 index 0000000..3c0a4b5 Binary files /dev/null and b/public/members/houston_chris.webp differ diff --git a/public/members/houston_emmanuel.webp b/public/members/houston_emmanuel.webp new file mode 100644 index 0000000..d638e53 Binary files /dev/null and b/public/members/houston_emmanuel.webp differ diff --git a/public/members/leadership_team_ben.webp b/public/members/leadership_team_ben.webp new file mode 100644 index 0000000..535bfa9 Binary files /dev/null and b/public/members/leadership_team_ben.webp differ diff --git a/public/members/leadership_team_ishita.webp b/public/members/leadership_team_ishita.webp new file mode 100644 index 0000000..8e32466 Binary files /dev/null and b/public/members/leadership_team_ishita.webp differ diff --git a/public/members/leadership_team_joshua_(left).webp b/public/members/leadership_team_joshua_(left).webp new file mode 100644 index 0000000..3247637 Binary files /dev/null and b/public/members/leadership_team_joshua_(left).webp differ diff --git a/public/members/leadership_team_rashmi.webp b/public/members/leadership_team_rashmi.webp new file mode 100644 index 0000000..b4b8ea2 Binary files /dev/null and b/public/members/leadership_team_rashmi.webp differ diff --git a/public/members/leadership_team_thanishka.webp b/public/members/leadership_team_thanishka.webp new file mode 100644 index 0000000..cb18e8f Binary files /dev/null and b/public/members/leadership_team_thanishka.webp differ diff --git a/public/members/leadership_team_yixuan.webp b/public/members/leadership_team_yixuan.webp new file mode 100644 index 0000000..fc6c3e7 Binary files /dev/null and b/public/members/leadership_team_yixuan.webp differ diff --git a/public/members/membersData.json b/public/members/membersData.json new file mode 100644 index 0000000..0dcafe0 --- /dev/null +++ b/public/members/membersData.json @@ -0,0 +1,254 @@ +[ + { + "team": "Houston", + "desc": "Developer", + "name": "✨ andrew ✨", + "cover": "" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "⭐Kimberley⭐🐮", + "cover": "" + }, + { + "team": "Projects: Fermata", + "desc": "Team Lead", + "name": "Aaron", + "cover": "/members/projects_fermata_aaron.webp" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "Anna", + "cover": "/members/houston_anna.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Developer", + "name": "Anton", + "cover": "/members/projects_fermata_anton.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Project Member", + "name": "AntonCACHE", + "cover": "" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "Becky Pog", + "cover": "" + }, + { + "team": "Leadership Team", + "desc": "Treasurer", + "name": "Ben", + "cover": "/members/leadership_team_ben.webp" + }, + { + "team": "Houston", + "desc": "Exec & Tech Lead", + "name": "Chris", + "cover": "/members/houston_chris.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Project Member", + "name": "David", + "cover": "/members/projects_fermata_david.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Project Member", + "name": "Dhivya", + "cover": "/members/projects_fermata_dhivya.webp" + }, + { + "team": "Projects: Legato", + "desc": "Project Member", + "name": "Ella", + "cover": "/members/projects_legato_ella.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Project Member", + "name": "Emily", + "cover": "/members/projects_fermata_emily.webp" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "Emmanuel", + "cover": "/members/houston_emmanuel.webp" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Team Lead", + "name": "Enya", + "cover": "/members/projects_schmetterlinge_enya.webp" + }, + { + "team": "Leadership Team", + "desc": "Co-chair", + "name": "Ishita", + "cover": "/members/leadership_team_ishita.webp" + }, + { + "team": "Projects: Legato", + "desc": "Project Member", + "name": "James", + "cover": "/members/projects_legato_james.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Team Lead", + "name": "Jamie", + "cover": "/members/projects_the_gaggle_jamie.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Project Member", + "name": "Jessica", + "cover": "/members/projects_fermata_jessica.webp" + }, + { + "team": "Leadership Team", + "desc": "Co-chair", + "name": "Joshua (Left)", + "cover": "/members/leadership_team_joshua_(left).webp" + }, + { + "team": "Communication Team", + "desc": "Communications Member", + "name": "Katerina", + "cover": "/members/communication_team_katerina.webp" + }, + { + "team": "Projects: Legato", + "desc": "Project Member", + "name": "Leo", + "cover": "/members/projects_legato_leo.webp" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Project Member", + "name": "Olivia", + "cover": "/members/projects_schmetterlinge_olivia.webp" + }, + { + "team": "Projects: Legato", + "desc": "Project Member", + "name": "Olivia", + "cover": "/members/projects_legato_olivia.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Project Member", + "name": "Olivia", + "cover": "/members/projects_the_gaggle_olivia.webp" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "Owen", + "cover": "" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Project Member", + "name": "Paidashe", + "cover": "/members/projects_schmetterlinge_paidashe.webp" + }, + { + "team": "Leadership Team", + "desc": "Council Engagement Lead", + "name": "Rashmi", + "cover": "/members/leadership_team_rashmi.webp" + }, + { + "team": "Communication Team", + "desc": "Communications Member", + "name": "Saffron", + "cover": "/members/communication_team_saffron.webp" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Project Member", + "name": "Sebastian", + "cover": "/members/projects_schmetterlinge_sebastian.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Project Member", + "name": "Shreevali", + "cover": "/members/projects_the_gaggle_shreevali.webp" + }, + { + "team": "Communication Team", + "desc": "Communications Member", + "name": "Stella", + "cover": "/members/communication_team_stella.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Project Member", + "name": "Tessa", + "cover": "/members/projects_the_gaggle_tessa.webp" + }, + { + "team": "Communication Team", + "desc": "Communications Member", + "name": "testing", + "cover": "/members/communication_team_testing.webp" + }, + { + "team": "Communication Team", + "desc": "Communications Lead", + "name": "Thanishka", + "cover": "/members/communication_team_thanishka.webp" + }, + { + "team": "Leadership Team", + "desc": "Communications Lead", + "name": "Thanishka", + "cover": "/members/leadership_team_thanishka.webp" + }, + { + "team": "Projects: Legato", + "desc": "Team Lead", + "name": "Toby", + "cover": "/members/projects_legato_toby.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Project Member", + "name": "Tommy", + "cover": "/members/projects_the_gaggle_tommy.webp" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Project Member", + "name": "William", + "cover": "/members/projects_schmetterlinge_william.webp" + }, + { + "team": "Houston", + "desc": "Project Manager", + "name": "Yash the mekanic", + "cover": "" + }, + { + "team": "Leadership Team", + "desc": "Secretary", + "name": "Yixuan", + "cover": "/members/leadership_team_yixuan.webp" + }, + { + "team": "", + "desc": "", + "name": "zzz", + "cover": "/members/_zzz.webp" + } +] \ No newline at end of file diff --git a/public/members/projects_fermata_aaron.webp b/public/members/projects_fermata_aaron.webp new file mode 100644 index 0000000..f302a4f Binary files /dev/null and b/public/members/projects_fermata_aaron.webp differ diff --git a/public/members/projects_fermata_anton.webp b/public/members/projects_fermata_anton.webp new file mode 100644 index 0000000..8e26220 Binary files /dev/null and b/public/members/projects_fermata_anton.webp differ diff --git a/public/members/projects_fermata_david.webp b/public/members/projects_fermata_david.webp new file mode 100644 index 0000000..20d189e Binary files /dev/null and b/public/members/projects_fermata_david.webp differ diff --git a/public/members/projects_fermata_dhivya.webp b/public/members/projects_fermata_dhivya.webp new file mode 100644 index 0000000..a130dd0 Binary files /dev/null and b/public/members/projects_fermata_dhivya.webp differ diff --git a/public/members/projects_fermata_emily.webp b/public/members/projects_fermata_emily.webp new file mode 100644 index 0000000..20f8bbb Binary files /dev/null and b/public/members/projects_fermata_emily.webp differ diff --git a/public/members/projects_fermata_jessica.webp b/public/members/projects_fermata_jessica.webp new file mode 100644 index 0000000..1f5e02a Binary files /dev/null and b/public/members/projects_fermata_jessica.webp differ diff --git a/public/members/projects_legato_ella.webp b/public/members/projects_legato_ella.webp new file mode 100644 index 0000000..e5497c2 Binary files /dev/null and b/public/members/projects_legato_ella.webp differ diff --git a/public/members/projects_legato_james.webp b/public/members/projects_legato_james.webp new file mode 100644 index 0000000..d064792 Binary files /dev/null and b/public/members/projects_legato_james.webp differ diff --git a/public/members/projects_legato_leo.webp b/public/members/projects_legato_leo.webp new file mode 100644 index 0000000..f11d7dd Binary files /dev/null and b/public/members/projects_legato_leo.webp differ diff --git a/public/members/projects_legato_olivia.webp b/public/members/projects_legato_olivia.webp new file mode 100644 index 0000000..ee7ccf7 Binary files /dev/null and b/public/members/projects_legato_olivia.webp differ diff --git a/public/members/projects_legato_toby.webp b/public/members/projects_legato_toby.webp new file mode 100644 index 0000000..227c0f7 Binary files /dev/null and b/public/members/projects_legato_toby.webp differ diff --git a/public/members/projects_schmetterlinge_enya.webp b/public/members/projects_schmetterlinge_enya.webp new file mode 100644 index 0000000..dc66c00 Binary files /dev/null and b/public/members/projects_schmetterlinge_enya.webp differ diff --git a/public/members/projects_schmetterlinge_olivia.webp b/public/members/projects_schmetterlinge_olivia.webp new file mode 100644 index 0000000..ee7ccf7 Binary files /dev/null and b/public/members/projects_schmetterlinge_olivia.webp differ diff --git a/public/members/projects_schmetterlinge_paidashe.webp b/public/members/projects_schmetterlinge_paidashe.webp new file mode 100644 index 0000000..bc6fc4f Binary files /dev/null and b/public/members/projects_schmetterlinge_paidashe.webp differ diff --git a/public/members/projects_schmetterlinge_sebastian.webp b/public/members/projects_schmetterlinge_sebastian.webp new file mode 100644 index 0000000..cec52cd Binary files /dev/null and b/public/members/projects_schmetterlinge_sebastian.webp differ diff --git a/public/members/projects_schmetterlinge_william.webp b/public/members/projects_schmetterlinge_william.webp new file mode 100644 index 0000000..4c3a724 Binary files /dev/null and b/public/members/projects_schmetterlinge_william.webp differ diff --git a/public/members/projects_the_gaggle_jamie.webp b/public/members/projects_the_gaggle_jamie.webp new file mode 100644 index 0000000..95085cd Binary files /dev/null and b/public/members/projects_the_gaggle_jamie.webp differ diff --git a/public/members/projects_the_gaggle_olivia.webp b/public/members/projects_the_gaggle_olivia.webp new file mode 100644 index 0000000..9516969 Binary files /dev/null and b/public/members/projects_the_gaggle_olivia.webp differ diff --git a/public/members/projects_the_gaggle_shreevali.webp b/public/members/projects_the_gaggle_shreevali.webp new file mode 100644 index 0000000..06f6847 Binary files /dev/null and b/public/members/projects_the_gaggle_shreevali.webp differ diff --git a/public/members/projects_the_gaggle_tessa.webp b/public/members/projects_the_gaggle_tessa.webp new file mode 100644 index 0000000..1238266 Binary files /dev/null and b/public/members/projects_the_gaggle_tessa.webp differ diff --git a/public/members/projects_the_gaggle_tommy.webp b/public/members/projects_the_gaggle_tommy.webp new file mode 100644 index 0000000..b10085d Binary files /dev/null and b/public/members/projects_the_gaggle_tommy.webp differ diff --git a/public/membersData.json b/public/membersData.json new file mode 100644 index 0000000..28dbf17 --- /dev/null +++ b/public/membersData.json @@ -0,0 +1,254 @@ +[ + { + "team": "Houston", + "desc": "Developer", + "name": "✨ andrew ✨", + "cover": "" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "⭐Kimberley⭐🐮", + "cover": "" + }, + { + "team": "Projects: Fermata", + "desc": "Team Lead", + "name": "Aaron", + "cover": "/members/projects_fermata_aaron.webp" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "Anna", + "cover": "/members/houston_anna.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Developer", + "name": "Anton", + "cover": "/members/projects_fermata_anton.webp" + }, + { + "team": "", + "desc": "", + "name": "asdf", + "cover": "/members/_asdf.webp" + }, + { + "team": "", + "desc": "", + "name": "asdf", + "cover": "/members/_asdf.webp" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "Becky Pog", + "cover": "" + }, + { + "team": "Leadership Team", + "desc": "Treasurer", + "name": "Ben", + "cover": "/members/leadership_team_ben.webp" + }, + { + "team": "Houston", + "desc": "Exec & Tech Lead", + "name": "Chris", + "cover": "/members/houston_chris.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Project Member", + "name": "David", + "cover": "/members/projects_fermata_david.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Project Member", + "name": "Dhivya", + "cover": "/members/projects_fermata_dhivya.webp" + }, + { + "team": "Projects: Legato", + "desc": "Project Member", + "name": "Ella", + "cover": "/members/projects_legato_ella.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Project Member", + "name": "Emily", + "cover": "/members/projects_fermata_emily.webp" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "Emmanuel", + "cover": "/members/houston_emmanuel.webp" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Team Lead", + "name": "Enya", + "cover": "/members/projects_schmetterlinge_enya.webp" + }, + { + "team": "Leadership Team", + "desc": "Co-chair", + "name": "Ishita", + "cover": "/members/leadership_team_ishita.webp" + }, + { + "team": "Projects: Legato", + "desc": "Project Member", + "name": "James", + "cover": "/members/projects_legato_james.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Team Lead", + "name": "Jamie", + "cover": "/members/projects_the_gaggle_jamie.webp" + }, + { + "team": "Projects: Fermata", + "desc": "Project Member", + "name": "Jessica", + "cover": "/members/projects_fermata_jessica.webp" + }, + { + "team": "Leadership Team", + "desc": "Co-chair", + "name": "Joshua (Left)", + "cover": "/members/leadership_team_joshua_(left).webp" + }, + { + "team": "Communication Team", + "desc": "Communications Member", + "name": "Katerina", + "cover": "/members/communication_team_katerina.webp" + }, + { + "team": "Projects: Legato", + "desc": "Project Member", + "name": "Leo", + "cover": "/members/projects_legato_leo.webp" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Project Member", + "name": "Olivia", + "cover": "/members/projects_schmetterlinge_olivia.webp" + }, + { + "team": "Projects: Legato", + "desc": "Project Member", + "name": "Olivia", + "cover": "/members/projects_legato_olivia.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Project Member", + "name": "Olivia", + "cover": "/members/projects_the_gaggle_olivia.webp" + }, + { + "team": "Houston", + "desc": "Developer", + "name": "Owen", + "cover": "" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Project Member", + "name": "Paidashe", + "cover": "/members/projects_schmetterlinge_paidashe.webp" + }, + { + "team": "Leadership Team", + "desc": "Council Engagement Lead", + "name": "Rashmi", + "cover": "/members/leadership_team_rashmi.webp" + }, + { + "team": "Communication Team", + "desc": "Communications Member", + "name": "Saffron", + "cover": "/members/communication_team_saffron.webp" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Project Member", + "name": "Sebastian", + "cover": "/members/projects_schmetterlinge_sebastian.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Project Member", + "name": "Shreevali", + "cover": "/members/projects_the_gaggle_shreevali.webp" + }, + { + "team": "Communication Team", + "desc": "Communications Member", + "name": "Stella", + "cover": "/members/communication_team_stella.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Project Member", + "name": "Tessa", + "cover": "/members/projects_the_gaggle_tessa.webp" + }, + { + "team": "Communication Team", + "desc": "Communications Lead", + "name": "Thanishka", + "cover": "/members/communication_team_thanishka.webp" + }, + { + "team": "Leadership Team", + "desc": "Communications Lead", + "name": "Thanishka", + "cover": "/members/leadership_team_thanishka.webp" + }, + { + "team": "Projects: Legato", + "desc": "Team Lead", + "name": "Toby", + "cover": "/members/projects_legato_toby.webp" + }, + { + "team": "Projects: The Gaggle", + "desc": "Project Member", + "name": "Tommy", + "cover": "/members/projects_the_gaggle_tommy.webp" + }, + { + "team": "Projects: Schmetterlinge", + "desc": "Project Member", + "name": "William", + "cover": "/members/projects_schmetterlinge_william.webp" + }, + { + "team": "Houston", + "desc": "Project Manager", + "name": "Yash the mekanic", + "cover": "" + }, + { + "team": "Leadership Team", + "desc": "Secretary", + "name": "Yixuan", + "cover": "/members/leadership_team_yixuan.webp" + }, + { + "team": "", + "desc": "", + "name": "zzz", + "cover": "/members/_zzz.webp" + } +] \ No newline at end of file diff --git a/public/projects/beach_clean_up_cover.webp b/public/projects/beach_clean_up_cover.webp new file mode 100644 index 0000000..a6b6550 Binary files /dev/null and b/public/projects/beach_clean_up_cover.webp differ diff --git a/public/projects/board_game_night_cover.webp b/public/projects/board_game_night_cover.webp new file mode 100644 index 0000000..77e5f57 Binary files /dev/null and b/public/projects/board_game_night_cover.webp differ diff --git a/public/projects/careers_workshop_cover.webp b/public/projects/careers_workshop_cover.webp new file mode 100644 index 0000000..bfa5322 Binary files /dev/null and b/public/projects/careers_workshop_cover.webp differ diff --git a/public/projects/carouselList.json b/public/projects/carouselList.json new file mode 100644 index 0000000..3319aff --- /dev/null +++ b/public/projects/carouselList.json @@ -0,0 +1,41 @@ +[ + { + "heading": "Quiz Night", + "subheadings": [ + "Quiz Night" + ], + "paragraphs": [ + "2nd July 12:30 - 3:30PM", + "This is a description about quizzes at YOO. Quizzes are good to learn from." + ], + "images": [ + "/projects/carousel_content_2_image_0.webp" + ] + }, + { + "heading": "YOO meeting", + "subheadings": [ + "YOO meeting" + ], + "paragraphs": [ + "2nd July 12:30 - 3:30PM", + "This is a description about quizzes at YOO. Quizzes are good to learn from." + ], + "images": [ + "/projects/carousel_content_3_image_0.webp" + ] + }, + { + "heading": "Art Gallery", + "subheadings": [ + "Art Gallery" + ], + "paragraphs": [ + "2nd August, 12:30 - 3:30PM", + "Come along and view some fine art! Maybe even meet some new friends!" + ], + "images": [ + "/projects/carousel_content_1_image_0.webp" + ] + } +] \ No newline at end of file diff --git a/public/projects/carousel_content_1_image_0.webp b/public/projects/carousel_content_1_image_0.webp new file mode 100644 index 0000000..5d1fbab Binary files /dev/null and b/public/projects/carousel_content_1_image_0.webp differ diff --git a/public/projects/carousel_content_2_image_0.webp b/public/projects/carousel_content_2_image_0.webp new file mode 100644 index 0000000..7f95fb3 Binary files /dev/null and b/public/projects/carousel_content_2_image_0.webp differ diff --git a/public/projects/carousel_content_3_image_0.webp b/public/projects/carousel_content_3_image_0.webp new file mode 100644 index 0000000..b2a2f06 Binary files /dev/null and b/public/projects/carousel_content_3_image_0.webp differ diff --git a/public/projects/film_festival_cover.webp b/public/projects/film_festival_cover.webp new file mode 100644 index 0000000..576ee55 Binary files /dev/null and b/public/projects/film_festival_cover.webp differ diff --git a/public/projects/kahoot_games_night_cover.webp b/public/projects/kahoot_games_night_cover.webp new file mode 100644 index 0000000..9c270f6 Binary files /dev/null and b/public/projects/kahoot_games_night_cover.webp differ diff --git a/public/projects/kahoot_night_cover.webp b/public/projects/kahoot_night_cover.webp new file mode 100644 index 0000000..7330fb8 Binary files /dev/null and b/public/projects/kahoot_night_cover.webp differ diff --git a/public/projects/life_skills_workshop_cover.webp b/public/projects/life_skills_workshop_cover.webp new file mode 100644 index 0000000..aa0399f Binary files /dev/null and b/public/projects/life_skills_workshop_cover.webp differ diff --git a/public/projects/music_showcase_cover.webp b/public/projects/music_showcase_cover.webp new file mode 100644 index 0000000..9c270f6 Binary files /dev/null and b/public/projects/music_showcase_cover.webp differ diff --git a/public/projects/orakei_youth_expo_cover.webp b/public/projects/orakei_youth_expo_cover.webp new file mode 100644 index 0000000..b2a2f06 Binary files /dev/null and b/public/projects/orakei_youth_expo_cover.webp differ diff --git a/public/projects/projectsData.json b/public/projects/projectsData.json new file mode 100644 index 0000000..7ea22a7 --- /dev/null +++ b/public/projects/projectsData.json @@ -0,0 +1,169 @@ +[ + { + "title": "propject 4", + "date": "2024-09-24", + "description": "desc", + "cover": "", + "team": "tean 43", + "tags": [ + "volunteering" + ], + "id": "10339839-0b9f-8011-971c-c5ae9a87cce2" + }, + { + "title": "Board Game Night", + "date": "2024-06-09", + "description": "Placeholder project description.", + "cover": "/projects/board_game_night_cover.webp", + "team": "Team 2", + "tags": [ + "games" + ], + "id": "3d6b89d6-e7e5-4a71-a315-90ec000ba0d3" + }, + { + "title": "Quizex - Quiz Night", + "date": "2024-05-18", + "description": "Placeholder project description.", + "cover": "/projects/quizex_-_quiz_night_cover.webp", + "team": "Team 3", + "tags": [ + "games" + ], + "id": "0fe7cf87-01e8-40e8-af75-dbcd12df8bda" + }, + { + "title": "Beach clean up", + "date": "2024-05-13", + "description": "Come join us to clean the local beach and save our environment!", + "cover": "/projects/beach_clean_up_cover.webp", + "team": "Team 4", + "tags": [ + "volunteering" + ], + "id": "f75a6e96-82dc-4dc7-ad9f-d63ff136aa47" + }, + { + "title": "Kahoot Night", + "date": "2024-05-11", + "description": "Placeholder project description.", + "cover": "/projects/kahoot_night_cover.webp", + "team": "Team 1", + "tags": [ + "games" + ], + "id": "7e15c320-90b6-4bfb-bb75-c18222fb157b" + }, + { + "title": "Kahoot Games Night", + "date": "2024-05-05", + "description": "Placeholder project description.", + "cover": "/projects/kahoot_games_night_cover.webp", + "team": "Team 2", + "tags": [ + "games" + ], + "id": "256fe646-3750-48d1-9cbf-30e8ea05cd33" + }, + { + "title": "Orakei Youth Expo", + "date": "2023-12-09", + "description": "Placeholder project description.", + "cover": "/projects/orakei_youth_expo_cover.webp", + "team": "Team 3", + "tags": [ + "volunteering", + "educational" + ], + "id": "ab70378e-268f-4791-b9ac-6a286c88ff3c" + }, + { + "title": "Film Festival", + "date": "2023-09-30", + "description": "Placeholder project description.", + "cover": "/projects/film_festival_cover.webp", + "team": "Team 4", + "tags": [ + "art", + "music" + ], + "id": "dde22970-d29c-4bc8-af59-e445a4026bfe" + }, + { + "title": "Music Showcase", + "date": "2023-09-17", + "description": "Placeholder project description.", + "cover": "/projects/music_showcase_cover.webp", + "team": "Team 1", + "tags": [ + "music" + ], + "id": "dbd309c6-55ec-4149-bd83-2cc4761e4e85" + }, + { + "title": "Sportathon", + "date": "2023-09-02", + "description": "Placeholder project description.", + "cover": "/projects/sportathon_cover.webp", + "team": "Team 2", + "tags": [ + "games", + "sports" + ], + "id": "6cf27617-6cee-4af5-a1ba-c0b7cecf81f0" + }, + { + "title": "", + "date": "", + "description": "", + "cover": "", + "team": "", + "tags": [], + "id": "10339839-0b9f-8032-a51d-e9a191b15227" + }, + { + "title": "Careers Workshop", + "date": "", + "description": "Placeholder project description.", + "cover": "/projects/careers_workshop_cover.webp", + "team": "Team 3", + "tags": [ + "educational" + ], + "id": "78294581-4f99-4efa-9d4c-f88a00f6e2ae" + }, + { + "title": "Student Leadership Conference", + "date": "", + "description": "Placeholder project description.", + "cover": "/projects/student_leadership_conference_cover.webp", + "team": "Team 2", + "tags": [ + "educational", + "volunteering" + ], + "id": "9d0e4b44-04e2-41ae-9388-5bd07d91551c" + }, + { + "title": "Life Skills Workshop", + "date": "", + "description": "Placeholder project description.", + "cover": "/projects/life_skills_workshop_cover.webp", + "team": "Team 4", + "tags": [ + "educational" + ], + "id": "3d447c69-eb7b-41ce-a0f3-3651620873fe" + }, + { + "title": "Quiz Night", + "date": "", + "description": "Placeholder project description.", + "cover": "/projects/quiz_night_cover.webp", + "team": "Team 1", + "tags": [ + "games" + ], + "id": "5a11c339-08bc-4587-9417-2c3cb9ea858f" + } +] \ No newline at end of file diff --git a/public/projects/quiz_night_cover.webp b/public/projects/quiz_night_cover.webp new file mode 100644 index 0000000..34267b9 Binary files /dev/null and b/public/projects/quiz_night_cover.webp differ diff --git a/public/projects/quizex_-_quiz_night_cover.webp b/public/projects/quizex_-_quiz_night_cover.webp new file mode 100644 index 0000000..cf1e41f Binary files /dev/null and b/public/projects/quizex_-_quiz_night_cover.webp differ diff --git a/public/projects/sportathon_cover.webp b/public/projects/sportathon_cover.webp new file mode 100644 index 0000000..9937e28 Binary files /dev/null and b/public/projects/sportathon_cover.webp differ diff --git a/public/projects/student_leadership_conference_cover.webp b/public/projects/student_leadership_conference_cover.webp new file mode 100644 index 0000000..7d2d695 Binary files /dev/null and b/public/projects/student_leadership_conference_cover.webp differ diff --git a/public/webb3.jpg b/public/webb3.jpg new file mode 100644 index 0000000..e270d19 Binary files /dev/null and b/public/webb3.jpg differ diff --git a/src/components/AdminPage/RefreshSection.tsx b/src/components/AdminPage/RefreshSection.tsx new file mode 100644 index 0000000..f565828 --- /dev/null +++ b/src/components/AdminPage/RefreshSection.tsx @@ -0,0 +1,88 @@ +import { useState } from 'react'; + +interface RefreshSectionProps { + newPassword: string; + setNewPassword: (value: string) => void; + setErrorMessage: (message: string) => void; + handleKeyDown: (event: React.KeyboardEvent, formId: string) => void; + password: string; // Receive the password from LoginForm +} + +const RefreshSection = ({ + newPassword, + setNewPassword, + setErrorMessage, + handleKeyDown, + password, // Use the passed password +}: RefreshSectionProps) => { + const [passwordChanged, setPasswordChanged] = useState(false); // State for password changed message + + const handleRefresh = async () => { + const response = await fetch('/api/refresh-login', { + method: 'POST', + body: JSON.stringify({ action: 'refresh', password }), // Send stored password + headers: { + 'Content-Type': 'application/json', + }, + }); + + const result = await response.json(); + if (result.success) { + window.location.href = '/'; + } else { + setErrorMessage('Failed to refresh. Try again.'); + } + }; + + const handlePasswordChange = async (event: React.FormEvent) => { + event.preventDefault(); + + const response = await fetch('/api/refresh-login', { + method: 'POST', + body: JSON.stringify({ action: 'change-password', password, newPassword }), // Send both the stored password and the new password + headers: { + 'Content-Type': 'application/json', + }, + }); + + const result = await response.json(); + if (result.success) { + setErrorMessage('Password updated successfully.'); + setNewPassword(''); + setPasswordChanged(true); // Set password changed state to true + setTimeout(() => setPasswordChanged(false), 3000); // Reset message after 3 seconds + } else { + setErrorMessage('Failed to update password. Try again.'); + } + }; + + return ( +
+

Logged in

+
+ + setNewPassword(e.target.value)} + onKeyDown={(e) => handleKeyDown(e, 'change-password-form')} + required + className="border rounded-lg mx-2 p-2 flex-grow" + /> + + {passwordChanged && ( + Password changed! + )} +
+ +
+ ); +}; + +export default RefreshSection; diff --git a/src/components/AdminPage/loginForm.css b/src/components/AdminPage/loginForm.css new file mode 100644 index 0000000..de15c91 --- /dev/null +++ b/src/components/AdminPage/loginForm.css @@ -0,0 +1,3 @@ +@import "tailwindcss/base"; +@import "tailwindcss/components"; +@import "tailwindcss/utilities"; \ No newline at end of file diff --git a/src/components/AdminPage/loginForm.tsx b/src/components/AdminPage/loginForm.tsx new file mode 100644 index 0000000..4cb8653 --- /dev/null +++ b/src/components/AdminPage/loginForm.tsx @@ -0,0 +1,77 @@ +import { useState } from 'react'; +import './loginForm.css'; +import RefreshSection from './RefreshSection'; + +const LoginForm = () => { + const [errorMessage, setErrorMessage] = useState(''); + const [newPassword, setNewPassword] = useState(''); + const [password, setPassword] = useState(''); + const [loggedIn, setLoggedIn] = useState(false); + + const handleLogin = async (event: React.FormEvent) => { + event.preventDefault(); + const formData = new FormData(event.currentTarget); + const enteredPassword = formData.get('password') as string; + + const response = await fetch('/api/refresh-login', { + method: 'POST', + body: JSON.stringify({ action: 'login', password: enteredPassword }), + headers: { + 'Content-Type': 'application/json', + }, + }); + + const result = await response.json(); + if (result.success) { + setPassword(enteredPassword); // Store the password after login + setLoggedIn(true); // Hide login form and show "Logged in" + } else { + setErrorMessage('Invalid password. Try again.'); + } + }; + + const handleKeyDown = (event: React.KeyboardEvent, formId: string) => { + if (event.key === 'Enter') { + event.preventDefault(); + const form = document.getElementById(formId) as HTMLFormElement; + if (form) { + form.requestSubmit(); + } + } + }; + + return ( +
+
+ {!loggedIn ? ( +
+ + setPassword(e.target.value)} + onKeyDown={(e) => handleKeyDown(e, 'login-form')} + className="border rounded-lg mx-2 p-2" + /> + + {errorMessage &&

{errorMessage}

} +
+ ) : ( + + )} +
+
+ ); +}; + +export default LoginForm; diff --git a/src/components/ProjectTeam.tsx b/src/components/ProjectTeam.tsx index 0240663..dbd7dc5 100644 --- a/src/components/ProjectTeam.tsx +++ b/src/components/ProjectTeam.tsx @@ -4,6 +4,7 @@ import "../styles/members.css"; // import MembersDisplay from "../components/MembersDisplay.astro"; import PersonCard from "./PersonCard.tsx"; import type { memberData } from "../types/memberData.ts"; +import sanitizeFilename from "../utils/sanitizeFilename.ts"; type TeamDetails = { teamName: string; @@ -21,11 +22,10 @@ type ProjectTeamsProps = { }; const ProjectTeams = ({ projects }: ProjectTeamsProps) => { - const [selectedTeam, setSelectedTeam] = useState(projects[0].teamDetails.teamId); // Default state is team1 + const [selectedTeam, setSelectedTeam] = useState(projects[0].teamDetails.teamId); const [teamNumber, setTeamNumber] = useState(0); const handleTeamChange = (t: string) => { - console.log(`Changing team to: ${t}`); for (let i = 0; i < projects.length; i++) { if (projects[i].teamDetails.teamId === t) { setSelectedTeam(t); @@ -34,6 +34,7 @@ const ProjectTeams = ({ projects }: ProjectTeamsProps) => { } }; + return (
@@ -58,15 +59,17 @@ const ProjectTeams = ({ projects }: ProjectTeamsProps) => {
- {projects[teamNumber].members.map((member) => ( - - ))} + {projects[teamNumber].members.map((member) => { + return ( + + ); + })}
); diff --git a/src/components/TeamDisplayLeft.astro b/src/components/TeamDisplayLeft.astro index 4a9b2fb..9f8d65e 100644 --- a/src/components/TeamDisplayLeft.astro +++ b/src/components/TeamDisplayLeft.astro @@ -1,15 +1,7 @@ --- import "../styles/global.css"; import MembersDisplay from "./MembersDisplay.astro"; - -import { getMembers } from "../scripts/getMembers"; -let members = await getMembers(); - -import { sortMembersByTeam } from "../scripts/sortTeams.ts"; -let { leadershipTeam, communicationTeam, projects } = - sortMembersByTeam(members); -const { team, cover, name, desc } = Astro.props; -let leadership = "Leadership Team"; +const { team } = Astro.props; --- @@ -34,16 +26,14 @@ let leadership = "Leadership Team";

- { - team.map((cover: { name: any; team: any; desc: any; cover: any }) => ( - - )) - } + {team.map((member: { name: any; team: any; desc: any; cover: any; }) => ( + + ))}
diff --git a/src/components/TeamDisplayRight.astro b/src/components/TeamDisplayRight.astro index 2b069b4..738fa8f 100644 --- a/src/components/TeamDisplayRight.astro +++ b/src/components/TeamDisplayRight.astro @@ -1,9 +1,6 @@ --- import "../styles/global.css"; - -// import MembersDisplay from "./MembersDisplay.astro"; import PersonCard from "./PersonCard.tsx"; - const { team } = Astro.props; --- @@ -20,12 +17,12 @@ const { team } = Astro.props;
{ - team.map((cover: { name: any; team: any; desc: any; cover: any }) => ( + team.map((member: { name: any; team: any; desc: any; cover: any }) => ( )) } diff --git a/src/pages/api/refresh-login.ts b/src/pages/api/refresh-login.ts new file mode 100644 index 0000000..2c3014c --- /dev/null +++ b/src/pages/api/refresh-login.ts @@ -0,0 +1,99 @@ +import { Client } from "@notionhq/client"; +import { getMembers } from "../../scripts/getMembers.ts"; +import { getProjects } from "../../scripts/getProjects.ts"; +import { getHomepageDescriptions } from "../../scripts/getHomepageDescriptions.ts"; +import type { APIRoute } from 'astro'; +import type { passwordRow } from "../../types/passwordRow.ts"; + +interface NotionPassword { + password: string; + newPassword?: string; + action: 'login' | 'refresh' | 'change-password'; +} + +export const POST: APIRoute = async ({ request }) => { + const NOTION_TOKEN = process.env.NOTION_TOKEN || import.meta.env.NOTION_TOKEN; + const NOTION_REFRESH_ID = process.env.NOTION_REFRESH_ID || import.meta.env.NOTION_REFRESH_ID; + + if (!NOTION_TOKEN || !NOTION_REFRESH_ID) { + return new Response(JSON.stringify({ error: "Missing secret(s)" }), { status: 500 }); + } + + const notion = new Client({ auth: NOTION_TOKEN }); + + try { + const { password, newPassword, action } = await request.json() as NotionPassword; + + const query = await notion.databases.query({ + database_id: NOTION_REFRESH_ID, + }); + + const passwords = query.results as passwordRow[]; + + if (passwords.length === 0 || !passwords[0].properties.Password.title) { + return new Response(JSON.stringify({ error: "Password not found in Notion database" }), { status: 500 }); + } + + const notionPassword = passwords[0].properties.Password.title[0]?.text.content; + + if (!notionPassword) { + return new Response(JSON.stringify({ error: "No password stored in Notion database" }), { status: 500 }); + } + + if (action === 'login') { + if (!password) { + return new Response(JSON.stringify({ error: "Password is required" }), { status: 400 }); + } + + if (password === notionPassword) { + return new Response(JSON.stringify({ success: true }), { status: 200 }); + } else { + return new Response(JSON.stringify({ success: false, message: "Invalid password" }), { status: 401 }); + } + } else if (action === 'refresh') { + if (!password) { + return new Response(JSON.stringify({ error: "Password is required" }), { status: 400 }); + } + + if (password === notionPassword) { + try { + await getMembers(); + await getProjects(); + await getHomepageDescriptions(); + return new Response(JSON.stringify({ success: true }), { status: 200 }); + } catch (err) { + console.error("Error during refresh data:", err); + return new Response(JSON.stringify({ error: "Failed to refresh data" }), { status: 500 }); + } + } else { + return new Response(JSON.stringify({ success: false, message: "Invalid password" }), { status: 401 }); + } + } else if (action === 'change-password') { + if (!newPassword) { + return new Response(JSON.stringify({ error: "New password is required" }), { status: 400 }); + } + + await notion.pages.update({ + page_id: passwords[0].id as string, + properties: { + Password: { + title: [ + { + text: { + content: newPassword, // Store new plaintext password + }, + }, + ], + }, + }, + }); + + return new Response(JSON.stringify({ success: true }), { status: 200 }); + } else { + return new Response(JSON.stringify({ error: "Invalid action" }), { status: 400 }); + } + } catch (error) { + console.error("Error during request handling:", error); + return new Response(JSON.stringify({ error: "Internal server error" }), { status: 500 }); + } +}; diff --git a/src/pages/index.astro b/src/pages/index.astro index dfdd9c4..1675677 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -3,29 +3,23 @@ // Homepage import "../styles/global.css"; import "../styles/index.css"; -import styles from "../components/index page/index.module.css" - import Layout from '../layouts/layout.astro'; import ImageCarousel from "../components/ImageCarousel"; import IndexImage from "../components/index page/IndexImage"; import IndexAbout from "../components/index page/IndexAbout"; import IndexGoals from "../components/index page/IndexGoals"; import IndexHero from "../components/index page/IndexHero"; - import BlobBackground from "../components/BlobBackground/BlobBackground"; -import React from "react"; +import descriptions from "../../public/homepage/homepageData.json" +const aboutContent = descriptions["About Us"]; +const heroContent = descriptions["Hero"]; +const goalContent = descriptions["Goals"]; +const carousel1 = descriptions["Carousel Item #1"]; +const carousel2 = descriptions["Carousel Item #2"]; +const carousel3 = descriptions["Carousel Item #3"]; -import { getHomepageDescriptions } from "../scripts/getHomepageDescriptions"; -let descriptions = await getHomepageDescriptions() - -const aboutContent = descriptions.get("About Us") -const heroContent = descriptions.get("Hero") -const goalContent = descriptions.get("Goals") -const carousel1 = descriptions.get("Carousel Item #1") -const carousel2 = descriptions.get("Carousel Item #2") -const carousel3 = descriptions.get("Carousel Item #3") const carouselContent = [carousel1, carousel2, carousel3].filter((item): item is NonNullable => item !== undefined); // temp fix -console.log(carouselContent) + --- diff --git a/src/pages/members.astro b/src/pages/members.astro index 63f598d..dc6520a 100644 --- a/src/pages/members.astro +++ b/src/pages/members.astro @@ -1,7 +1,6 @@ --- -import { getMembers } from "../scripts/getMembers"; -let members = await getMembers(); +import members from "../../public/members/membersData.json" import { sortMembersByTeam } from "../scripts/sortTeams.ts"; let { leadershipTeam, communicationTeam, projects } = sortMembersByTeam(members); @@ -9,7 +8,6 @@ import "../styles/global.css"; import "../styles/members.css"; import Layout from "../layouts/layout.astro"; - import TeamDisplayLeft from "../components/TeamDisplayLeft.astro"; import TeamDisplayRight from "../components/TeamDisplayRight.astro"; import ProjectTeam from "../components/ProjectTeam.tsx"; @@ -25,7 +23,7 @@ import BlobBackground from "../components/BlobBackground/BlobBackground"; - Astro + Members Page
@@ -77,8 +75,6 @@ import BlobBackground from "../components/BlobBackground/BlobBackground"; } }); - - diff --git a/src/pages/projects.astro b/src/pages/projects.astro index 453c883..978315e 100644 --- a/src/pages/projects.astro +++ b/src/pages/projects.astro @@ -1,53 +1,16 @@ --- - -// import { sortProjectsByTeam } from "../scripts/sortProjects.ts"; -// let { team1, team2, team3, team4 } = sortProjectsByTeam(projects); - import "../styles/global.css"; import "../styles/index.css"; import "../styles/projects.css"; import Layout from "../layouts/layout.astro"; -import Carousel from "../components/carousel.astro"; import PastProjectsList from "../components/projects page/PastProjectsList"; import ImageCarousel from "../components/ImageCarousel"; import IndexHeading from "../components/index page/IndexHeading"; - import BlobBackground from "../components/BlobBackground/BlobBackground"; -import { fetchPageBlocks } from "../scripts/fetchPageBlocks"; - - -// Projects Page -import { getProjects } from "../scripts/getProjects.ts"; -import { Client } from "@notionhq/client"; -import { getPage } from "../scripts/getPageDescriptions"; -import { title } from "process"; - -let projects = await getProjects(); -const NOTION_TOKEN = process.env.NOTION_TOKEN || import.meta.env.NOTION_TOKEN; -const NOTION_PROJECTS_ID = process.env.NOTION_PROJECTS_ID || import.meta.env.NOTION_PROJECTS_ID ; - -if (!NOTION_TOKEN || !NOTION_PROJECTS_ID) throw new Error("Missing secret(s)"); - -const notion = new Client({ auth: NOTION_TOKEN }); -let carouselList: { heading: string; subheadings: string[]; paragraphs: string[]; images: string[] }[] = []; - -for (const project of projects) { - if (project.title.toLowerCase().includes("carousel content")) { - const pageId: string = project.id; - const blocks = await fetchPageBlocks(notion, pageId); - const { subheadings, paragraphs, images } = await getPage(blocks); - - carouselList.push({ - heading: subheadings[0], - subheadings, - paragraphs, - images - }); - } -} -projects = projects.filter((project) => !project.title.toLowerCase().includes("carousel content")); -console.log(carouselList) +// Read the JSON files from the public folder +import projects from "../../public/projects/projectsData.json" +import carouselList from "../../public/projects/carouselList.json" --- @@ -70,6 +33,6 @@ console.log(carouselList)
- + diff --git a/src/pages/refresh.astro b/src/pages/refresh.astro new file mode 100644 index 0000000..24a53d6 --- /dev/null +++ b/src/pages/refresh.astro @@ -0,0 +1,5 @@ +--- +import LoginForm from "../components/AdminPage/loginForm" +--- + + diff --git a/src/scripts/getHomepageDescriptions.ts b/src/scripts/getHomepageDescriptions.ts index f55c9d7..2498359 100644 --- a/src/scripts/getHomepageDescriptions.ts +++ b/src/scripts/getHomepageDescriptions.ts @@ -1,16 +1,58 @@ +import fs from 'fs'; +import path from 'path'; +import axios from 'axios'; +import sharp from 'sharp'; import { Client } from "@notionhq/client"; import { fetchPageBlocks } from "./fetchPageBlocks.ts"; import { getPage } from "./getPageDescriptions.ts"; +import sanitizeFilename from '../utils/sanitizeFilename.ts'; -export async function getHomepageDescriptions(): Promise> { - let descriptions = new Map(); +type Description = { + heading: string; + subheadings: string[]; + paragraphs: string[]; + images: string[]; +}; + +async function ensureDirectoryExists(directoryPath: string): Promise { + if (!fs.existsSync(directoryPath)) { + fs.mkdirSync(directoryPath, { recursive: true }); + console.log(`Directory ${directoryPath} created.`); + } +} + +async function downloadAndProcessImage(imageUrl: string, folderPath: string, fileName: string): Promise { + const imagePath = path.join(folderPath, `${fileName}.webp`); + + // Check if the image already exists + if (!fs.existsSync(imagePath)) { + const response = await axios.get(imageUrl, { responseType: 'arraybuffer' }); + const compressedImageBuffer = await sharp(response.data) + .webp({ quality: 80 }) + .toBuffer(); + fs.writeFileSync(imagePath, new Uint8Array(compressedImageBuffer)); + console.log(`Image ${fileName}.webp downloaded, compressed, and saved.`); + } else { + console.log(`Image ${fileName}.webp already exists.`); + } + + return `/homepage/${fileName}.webp`; // Return the public path for the image +} + +export async function getHomepageDescriptions(): Promise { + const descriptions: Record = {}; const NOTION_TOKEN = process.env.NOTION_TOKEN || import.meta.env.NOTION_TOKEN; const NOTION_HOMEPAGE_ID = process.env.NOTION_HOMEPAGE_ID || import.meta.env.NOTION_HOMEPAGE_ID; if (!NOTION_TOKEN || !NOTION_HOMEPAGE_ID) throw new Error("Missing secret(s)"); - const notion = new Client({ auth: NOTION_TOKEN }); + const notion = new Client({ auth: NOTION_TOKEN }); + const publicFolderPath = path.join(process.cwd(), 'public'); + const homepageFolderPath = path.join(publicFolderPath, 'homepage'); + + // Ensure the 'homepage' directory exists + await ensureDirectoryExists(homepageFolderPath); try { const query = await notion.databases.query({ @@ -22,27 +64,35 @@ export async function getHomepageDescriptions(): Promise 0) { - const title: string = (nameProperty.title[0] as { plain_text: string }).plain_text; + const title: string = nameProperty.title[0].plain_text; const pageId: string = page.id; const blocks = await fetchPageBlocks(notion, pageId); const { subheadings, paragraphs, images } = await getPage(blocks); - descriptions.set(title, { + // Process and store images + const sanitizedTitle = sanitizeFilename(title); + const processedImages = await Promise.all( + images.map((url, idx) => + downloadAndProcessImage(url, homepageFolderPath, `${sanitizedTitle}_image_${idx}`) + ) + ); + + descriptions[title] = { heading: title, subheadings, paragraphs, - images - }); - } else { - console.warn(`Page with ID ${page.id} has no title.`); + images: processedImages // Store local paths of images + }; } } } + // Save the descriptions to a JSON file + const jsonFilePath = path.join(homepageFolderPath, 'homepageData.json'); + fs.writeFileSync(jsonFilePath, JSON.stringify(descriptions, null, 2)); + console.log(`Homepage descriptions saved to ${jsonFilePath}`); + } catch (error) { - console.error(error); - return new Map(); + console.error("Error retrieving or processing homepage descriptions:", error); } - - return descriptions; -} \ No newline at end of file +} diff --git a/src/scripts/getMembers.ts b/src/scripts/getMembers.ts index 21ad633..6207f8d 100644 --- a/src/scripts/getMembers.ts +++ b/src/scripts/getMembers.ts @@ -1,42 +1,122 @@ -import { Client } from "@notionhq/client"; -import type { GetPageResponse } from "@notionhq/client/build/src/api-endpoints"; -import type { memberRow } from "../types/memberRow" +import fs from 'fs'; +import path from 'path'; +import axios from 'axios'; +import sharp from 'sharp'; +import sanitizeFilename from '../utils/sanitizeFilename'; +import { Client } from "@notionhq/client"; // Notion API client +import type { memberRow } from "../types/memberRow"; +interface Member { + team: string; + name: string; + desc: string; + cover: string; // This will store the local file path +} + +// Helper function to ensure the directory exists +async function ensureDirectoryExists(directoryPath: string): Promise { + if (!fs.existsSync(directoryPath)) { + fs.mkdirSync(directoryPath, { recursive: true }); + console.log(`Directory ${directoryPath} created.`); + } +} -type MemberData = { - team: string; - desc: string; - name: string; - cover: string; - url?: string; +// Helper function to clean up old images not part of the current member list +async function cleanupOldImages(membersFolderPath: string, validImageNames: string[]): Promise { + const files = fs.readdirSync(membersFolderPath); + files.forEach((file: string) => { + if (!validImageNames.includes(file)) { + const filePath = path.join(membersFolderPath, file); + fs.unlinkSync(filePath); + console.log(`Deleted old image: ${file}`); + } + }); } -export async function getMembers(): Promise { +// Main function to get members, update covers, and return the sanitized members data +export async function getMembers(): Promise { const NOTION_TOKEN = process.env.NOTION_TOKEN || import.meta.env.NOTION_TOKEN; const NOTION_MEMBERS_ID = process.env.NOTION_MEMBERS_ID || import.meta.env.NOTION_MEMBERS_ID; if (!NOTION_TOKEN || !NOTION_MEMBERS_ID) - throw new Error("Missing secret(s)"); + throw new Error("Missing secret(s)"); - const notion = new Client({ auth: NOTION_TOKEN}); + const notion = new Client({ auth: NOTION_TOKEN }); const query = await notion.databases.query({ database_id: NOTION_MEMBERS_ID, sorts: [{ - property: 'Name', - direction: 'ascending' + property: 'Name', + direction: 'ascending' }] - }); - + }); + const memberspages = query.results as memberRow[]; - const members: MemberData[] = memberspages.map((row) => { - return { - team: row.properties.Team.rich_text[0] ? row.properties.Team.rich_text[0].plain_text : "", - desc: row.properties.Description.rich_text[0] ? row.properties.Description.rich_text[0].plain_text : "", - name: row.properties.Name.title[0] ? row.properties.Name.title[0].plain_text : "", - cover: row.cover?.type == "external" ? row.cover?.external.url : row.cover?.file.url ?? "" - }; - }); - - return members; -} \ No newline at end of file + const members: Member[] = memberspages.map((row) => { + return { + team: row.properties.Team.rich_text[0] ? row.properties.Team.rich_text[0].plain_text : "", + desc: row.properties.Description.rich_text[0] ? row.properties.Description.rich_text[0].plain_text : "", + name: row.properties.Name.title[0] ? row.properties.Name.title[0].plain_text : "", + cover: row.cover?.type == "external" ? row.cover?.external.url : row.cover?.file.url ?? "" + }; + }); + + const publicFolderPath = path.join(process.cwd(), 'public'); + const membersFolderPath = path.join(publicFolderPath, 'members'); // Path for storing member images + const jsonFilePath = path.join(membersFolderPath, 'membersData.json'); // Path for storing members data in JSON + + // Ensure the 'members' directory exists + await ensureDirectoryExists(membersFolderPath); + + // Filter members that have cover images + const membersWithCover = members.filter(member => member.cover); + + // Generate the list of valid image filenames + const validImageNames = membersWithCover.map((member) => { + const sanitizedFileName = sanitizeFilename(`${member.team}_${member.name}`); + return `${sanitizedFileName}.webp`; + }); + + // Clean up old images not in the current list + await cleanupOldImages(membersFolderPath, validImageNames); + + // Process each member's cover image + const downloadPromises = membersWithCover.map(async (member) => { + const sanitizedFileName = sanitizeFilename(`${member.team}_${member.name}`); + const imageName = `${sanitizedFileName}.webp`; + const imagePath = path.join(membersFolderPath, imageName); + + // Check if the image already exists, if not download and convert + if (!fs.existsSync(imagePath)) { + const response = await axios({ + url: member.cover, + method: 'GET', + responseType: 'arraybuffer', + }); + + // Convert to WebP format and save locally + const compressedImageBuffer = await sharp(response.data) + .webp({ quality: 60 }) + .resize({ width: 500 }) + .toBuffer(); + + fs.writeFileSync(imagePath, new Uint8Array(compressedImageBuffer)); + console.log(`Image ${imageName} downloaded and saved.`); + } + + // Update the member's cover to point to the local file path + member.cover = `/members/${imageName}`; + }); + + // Wait for all images to be downloaded and processed + await Promise.all(downloadPromises); + + console.log('All images downloaded and processed.'); + + // Write members to a JSON file + fs.writeFileSync(jsonFilePath, JSON.stringify(members, null, 2)); + console.log(`Members data saved to ${jsonFilePath}`); + + // Return the updated members array + return members; +} diff --git a/src/scripts/getProjects.ts b/src/scripts/getProjects.ts index 256a094..d39c997 100644 --- a/src/scripts/getProjects.ts +++ b/src/scripts/getProjects.ts @@ -1,7 +1,12 @@ +import fs from 'fs'; +import path from 'path'; +import axios from 'axios'; +import sharp from 'sharp'; import { Client } from "@notionhq/client"; -import type { GetPageResponse } from "@notionhq/client/build/src/api-endpoints"; -import type { projectRow } from "../types/projectRow"; -import type { multiselect } from "../types/multiselect"; +import { fetchPageBlocks } from "./fetchPageBlocks.ts"; +import { getPage } from "./getPageDescriptions.ts"; +import type { projectRow } from '../types/projectRow.ts'; +import sanitizeFilename from '../utils/sanitizeFilename.ts'; type ProjectData = { title: string; @@ -9,11 +14,42 @@ type ProjectData = { description: string; cover: string; team: string; - tags?: string[]; + tags: string[]; // Make tags required as an empty array id: string; } -export async function getProjects(): Promise { +type CarouselItem = { + heading: string; + subheadings: string[]; + paragraphs: string[]; + images: string[]; +}; + +async function ensureDirectoryExists(directoryPath: string): Promise { + if (!fs.existsSync(directoryPath)) { + fs.mkdirSync(directoryPath, { recursive: true }); + console.log(`Directory ${directoryPath} created.`); + } +} + +async function downloadAndProcessImage(imageUrl: string, folderPath: string, fileName: string): Promise { + const imagePath = path.join(folderPath, `${fileName}.webp`); + + if (!fs.existsSync(imagePath)) { + const response = await axios.get(imageUrl, { responseType: 'arraybuffer' }); + const compressedImageBuffer = await sharp(response.data) + .webp({ quality: 80 }) + .toBuffer(); + fs.writeFileSync(imagePath, new Uint8Array(compressedImageBuffer)); + console.log(`Image ${fileName}.webp downloaded, compressed, and saved.`); + } else { + console.log(`Image ${fileName}.webp already exists.`); + } + + return `/projects/${fileName}.webp`; // Return the public path for the image +} + +export async function getProjects(): Promise<{ projects: ProjectData[], carouselList: CarouselItem[] }> { const NOTION_TOKEN = process.env.NOTION_TOKEN || import.meta.env.NOTION_TOKEN; const NOTION_PROJECTS_ID = process.env.NOTION_PROJECTS_ID || import.meta.env.NOTION_PROJECTS_ID; @@ -22,27 +58,78 @@ export async function getProjects(): Promise { } const notion = new Client({ auth: NOTION_TOKEN }); + const publicFolderPath = path.join(process.cwd(), 'public'); + const projectsFolderPath = path.join(publicFolderPath, 'projects'); + + await ensureDirectoryExists(projectsFolderPath); const query = await notion.databases.query({ database_id: NOTION_PROJECTS_ID, - sorts: [{ - property: 'Date', - direction: 'descending' - }] + sorts: [{ property: 'Date', direction: 'descending' }] }); const projectsRows = query.results as projectRow[]; - const projects: ProjectData[] = projectsRows.map((row) => { + const carouselList: CarouselItem[] = []; + + const projectPromises = projectsRows.map(async (row) => { + const title = row.properties.Name.title[0] ? row.properties.Name.title[0].plain_text : ""; + const date = row.properties.Date.date ? row.properties.Date.date.start : ""; + const description = row.properties.Description.rich_text[0] ? row.properties.Description.rich_text[0].plain_text : ""; + const coverUrl = row.cover?.type === "external" ? row.cover?.external.url : row.cover?.file.url ?? ""; + const team = row.properties.Team.rich_text[0] ? row.properties.Team.rich_text[0].plain_text : ""; + const tags = row.properties.Tags?.multi_select.map((tag) => tag.name) || []; // Ensure tags is always an array + const id = row.id || ""; + + let coverPath = ""; + + if (coverUrl) { + coverPath = await downloadAndProcessImage(coverUrl, projectsFolderPath, sanitizeFilename(title) + "_cover"); + } + + if (title.toLowerCase().includes("carousel content")) { + const pageId: string = id; + const blocks = await fetchPageBlocks(notion, pageId); + const { subheadings, paragraphs, images } = await getPage(blocks); + + carouselList.push({ + heading: subheadings[0], + subheadings, + paragraphs, + images: await Promise.all( + images.map((url, idx) => + downloadAndProcessImage(url, projectsFolderPath, `${sanitizeFilename(title)}_image_${idx}`) + ) + ) + }); + + return null; // Filter out carousel content from main projects list + } + return { - title: row.properties.Name.title[0] ? row.properties.Name.title[0].plain_text : "", - date: row.properties.Date.date ? row.properties.Date.date.start : "", - description: row.properties.Description.rich_text[0] ? row.properties.Description.rich_text[0].plain_text : "", - cover: row.cover?.type == "external" ? row.cover?.external.url : row.cover?.file.url ?? "", - team: row.properties.Team.rich_text[0] ? row.properties.Team.rich_text[0].plain_text : "", - tags: row.properties.Tags.multi_select.map((tag) => tag.name), - id: row.id || "" + title, + date, + description, + cover: coverPath, // Updated to point to the local path + team, + tags, // No need for type assertion here + id }; }); - return projects; + // Filter out null values and await all async operations + const filteredProjects = (await Promise.all(projectPromises)).filter((project): project is ProjectData => project !== null); + + // Save the projects and carousel list to JSON files + const projectsJsonPath = path.join(projectsFolderPath, 'projectsData.json'); + fs.writeFileSync(projectsJsonPath, JSON.stringify(filteredProjects, null, 2)); + console.log(`Projects data saved to ${projectsJsonPath}`); + + const carouselJsonPath = path.join(projectsFolderPath, 'carouselList.json'); + fs.writeFileSync(carouselJsonPath, JSON.stringify(carouselList, null, 2)); + console.log(`Carousel list data saved to ${carouselJsonPath}`); + + return { + projects: filteredProjects, + carouselList + }; } diff --git a/src/styles/global.css b/src/styles/global.css index 5fcba4f..a96bdf7 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -1,3 +1,5 @@ + + @import url('https://fonts.googleapis.com/css2?family=Overpass:ital,wght@0,100..900;1,100..900&display=swap'); :root { diff --git a/src/styles/members.css b/src/styles/members.css index 1b16b5f..a225b0e 100644 --- a/src/styles/members.css +++ b/src/styles/members.css @@ -92,7 +92,7 @@ } .section-background { - background-image: url('../public/assets/YOO_members_bg.svg'); + background-image: url('/assets/YOO_members_bg.svg'); background-repeat: no-repeat; background-size: cover; width: 100%; diff --git a/src/types/passwordRow.ts b/src/types/passwordRow.ts new file mode 100644 index 0000000..f1078c0 --- /dev/null +++ b/src/types/passwordRow.ts @@ -0,0 +1,28 @@ +import type { RichTextItemResponse } from "@notionhq/client/build/src/api-endpoints"; +import type { rich_text } from "./richText"; +import type { cover } from "./cover"; + +export type passwordRow = { + object: string, + id: string, + created_time: string, + last_edited_time: string, + created_by: { object: string, id: string }, + last_edited_by: { object: string, id: string }, + cover: cover, + icon: null, + parent: { + type: string, + database_id: string + }, + archived: boolean, + in_trash: boolean, + properties: { + Password: { id: string, type: string, title: rich_text[] } + }, + url: string, + public_url: string, + title: Array, + description: Array, + is_inline: boolean, + }; \ No newline at end of file diff --git a/src/utils/getSanitizedImagePath.ts b/src/utils/getSanitizedImagePath.ts new file mode 100644 index 0000000..1f03d42 --- /dev/null +++ b/src/utils/getSanitizedImagePath.ts @@ -0,0 +1,8 @@ +import sanitizeFilename from "./sanitizeFilename"; + +export default function getSanitizedImagePath (team: string, name: string) { + const sanitizedTeam = sanitizeFilename(team); + const sanitizedName = sanitizeFilename(name); + const imageFilename = `${sanitizedTeam}_${sanitizedName}.webp`; // Construct the image filename + return `/members/${imageFilename}`; // Return the path + }; \ No newline at end of file diff --git a/src/utils/sanitizeFilename.ts b/src/utils/sanitizeFilename.ts new file mode 100644 index 0000000..08fefce --- /dev/null +++ b/src/utils/sanitizeFilename.ts @@ -0,0 +1,7 @@ +export default function sanitizeFilename(name: string): string { + return name + .replace(/[:\/\\?*|"<>#]/g, '_') // Replace invalid characters including # + .replace(/\s+/g, '_') // Replace spaces with underscores + .replace(/_+/g, '_') // Replace multiple underscores with a single underscore + .toLowerCase(); // Optionally, convert to lowercase +} diff --git a/yarn.lock b/yarn.lock index 18d5d70..0ea298a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -79,9 +79,9 @@ vfile "^6.0.1" "@astrojs/node@^8.2.0": - version "8.2.0" - resolved "https://registry.npmjs.org/@astrojs/node/-/node-8.2.0.tgz" - integrity sha512-keQIPvdx8hquG+KnWoJp7io/GoczBEJer9X8WzPHK2fnVRXYDKGzXWZw3Dbg0ZhXJreVV3xzniN7nr6e7hgDXg== + version "8.3.3" + resolved "https://registry.npmjs.org/@astrojs/node/-/node-8.3.3.tgz" + integrity sha512-idrKhnnPSi0ABV+PCQsRQqVNwpOvVDF/+fkwcIiE8sr9J8EMvW9g/oyAt8T4X2OBJ8FUzYPL8klfCdG7r0eB5g== dependencies: send "^0.18.0" server-destroy "^1.0.1" @@ -478,6 +478,11 @@ shell-quote "^1.8.1" yargs "^17.7.2" +"@img/sharp-win32-x64@0.33.5": + version "0.33.5" + resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz" + integrity sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" @@ -720,6 +725,13 @@ dependencies: "@babel/types" "^7.20.7" +"@types/bcrypt@^5.0.2": + version "5.0.2" + resolved "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.2.tgz" + integrity sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ== + dependencies: + "@types/node" "*" + "@types/cacheable-request@^6.0.1": version "6.0.3" resolved "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz" @@ -1371,6 +1383,15 @@ autoprefixer@^10.4.15: picocolors "^1.0.0" postcss-value-parser "^4.2.0" +axios@^1.7.7: + version "1.7.7" + resolved "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz" + integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz" @@ -1378,7 +1399,7 @@ axobject-query@^4.0.0: dependencies: dequal "^2.0.3" -b4a@^1.6.4: +b4a@^1.6.4, b4a@^1.6.6: version "1.6.6" resolved "https://registry.npmjs.org/b4a/-/b4a-1.6.6.tgz" integrity sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg== @@ -1403,32 +1424,39 @@ balanced-match@^1.0.0: integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== bare-events@^2.0.0, bare-events@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/bare-events/-/bare-events-2.2.0.tgz" - integrity sha512-Yyyqff4PIFfSuthCZqLlPISTWHmnQxoPuAvkmgzsJEmG3CesdIv6Xweayl0JkCZJSB2yYIdJyEz97tpxNhgjbg== + version "2.4.2" + resolved "https://registry.npmjs.org/bare-events/-/bare-events-2.4.2.tgz" + integrity sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q== bare-fs@^2.1.1: - version "2.1.5" - resolved "https://registry.npmjs.org/bare-fs/-/bare-fs-2.1.5.tgz" - integrity sha512-5t0nlecX+N2uJqdxe9d18A98cp2u9BETelbjKpiVgQqzzmVNFYWEAjQHqS+2Khgto1vcwhik9cXucaj5ve2WWA== + version "2.3.5" + resolved "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz" + integrity sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw== dependencies: bare-events "^2.0.0" - bare-os "^2.0.0" bare-path "^2.0.0" - streamx "^2.13.0" + bare-stream "^2.0.0" -bare-os@^2.0.0, bare-os@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/bare-os/-/bare-os-2.2.0.tgz" - integrity sha512-hD0rOPfYWOMpVirTACt4/nK8mC55La12K5fY1ij8HAdfQakD62M+H4o4tpfKzVGLgRDTuk3vjA4GqGXXCeFbag== +bare-os@^2.1.0: + version "2.4.4" + resolved "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz" + integrity sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ== bare-path@^2.0.0, bare-path@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/bare-path/-/bare-path-2.1.0.tgz" - integrity sha512-DIIg7ts8bdRKwJRJrUMy/PICEaQZaPGZ26lsSx9MJSwIhSrcdHn7/C8W+XmnG/rKi6BaRcz+JO00CjZteybDtw== + version "2.1.3" + resolved "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz" + integrity sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA== dependencies: bare-os "^2.1.0" +bare-stream@^2.0.0: + version "2.3.0" + resolved "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.0.tgz" + integrity sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA== + dependencies: + b4a "^1.6.6" + streamx "^2.20.0" + base-64@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz" @@ -1496,12 +1524,12 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +braces@^3.0.3, braces@~3.0.2: + version "3.0.3" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: - fill-range "^7.0.1" + fill-range "^7.1.1" browserslist@^4.21.10, browserslist@^4.22.2, browserslist@^4.23.1, "browserslist@>= 4.21.0": version "4.23.3" @@ -1928,10 +1956,10 @@ destroy@1.2.0: resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -detect-libc@^2.0.0, detect-libc@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== +detect-libc@^2.0.0, detect-libc@^2.0.2, detect-libc@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz" + integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== deterministic-object-hash@^2.0.1: version "2.0.2" @@ -1986,9 +2014,9 @@ dotenv@^16.4.5: integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== dset@^3.1.2, dset@^3.1.3: - version "3.1.3" - resolved "https://registry.npmjs.org/dset/-/dset-3.1.3.tgz" - integrity sha512-20TuZZHCEZ2O71q9/+8BwKwZ0QtD9D8ObhrihJPr+vLLYlSuAU3/zL4cSlgbfeoGHTjCSJBa7NGcrF9/Bx/WJQ== + version "3.1.4" + resolved "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz" + integrity sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA== eastasianwidth@^0.2.0: version "0.2.0" @@ -2001,9 +2029,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== ejs@^3.1.9: - version "3.1.9" - resolved "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + version "3.1.10" + resolved "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== dependencies: jake "^10.8.5" @@ -2261,7 +2289,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-fifo@^1.1.0, fast-fifo@^1.2.0: +fast-fifo@^1.2.0, fast-fifo@^1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz" integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== @@ -2314,10 +2342,10 @@ filelist@^1.0.4: dependencies: minimatch "^5.0.1" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" @@ -2355,6 +2383,11 @@ flattie@^1.1.0: resolved "https://registry.npmjs.org/flattie/-/flattie-1.1.0.tgz" integrity sha512-xU99gDEnciIwJdGcBmNHnzTJ/w5AT+VFJOu6sTB6WM8diOYNA3Sa+K1DiEBQ7XH4QikQq3iFW1U+jRVcotQnBw== +follow-redirects@^1.15.6: + version "1.15.9" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + foreground-child@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" @@ -3555,11 +3588,11 @@ micromark@^4.0.0: micromark-util-types "^2.0.0" micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + version "4.0.8" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: - braces "^3.0.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.52.0: @@ -3716,9 +3749,9 @@ nlcst-to-string@^3.0.0: "@types/nlcst" "^1.0.0" node-abi@^3.3.0: - version "3.55.0" - resolved "https://registry.npmjs.org/node-abi/-/node-abi-3.55.0.tgz" - integrity sha512-uPEjtyh2tFEvWYt4Jw7McOD5FPcHkcxm/tHZc5PWaDB3JYq0rGFUbgaAK+CT5pYpQddBfsZVWI08OwoRfdfbcQ== + version "3.67.0" + resolved "https://registry.npmjs.org/node-abi/-/node-abi-3.67.0.tgz" + integrity sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw== dependencies: semver "^7.3.5" @@ -3995,9 +4028,9 @@ path-scurry@^1.10.1: minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-to-regexp@^6.2.1: - version "6.2.1" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz" - integrity sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw== + version "6.3.0" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz" + integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== path-type@^4.0.0: version "4.0.0" @@ -4114,9 +4147,9 @@ postcss@^8.0.0, postcss@^8.1.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.2 source-map-js "^1.2.0" prebuild-install@^7.1.1: - version "7.1.1" - resolved "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz" - integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== + version "7.1.2" + resolved "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.2.tgz" + integrity sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ== dependencies: detect-libc "^2.0.0" expand-template "^2.0.3" @@ -4177,6 +4210,11 @@ property-information@^6.0.0: resolved "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz" integrity sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w== +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + pump@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" @@ -4672,11 +4710,9 @@ semver@^6.3.1: integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.3.5: - version "7.6.0" - resolved "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" + version "7.6.3" + resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== semver@^7.3.8: version "7.6.0" @@ -4692,6 +4728,11 @@ semver@^7.5.4: dependencies: lru-cache "^6.0.0" +semver@^7.6.3: + version "7.6.3" + resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + send@^0.18.0: version "0.18.0" resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" @@ -4747,6 +4788,35 @@ sharp@^0.32.6: tar-fs "^3.0.4" tunnel-agent "^0.6.0" +sharp@^0.33.5: + version "0.33.5" + resolved "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz" + integrity sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw== + dependencies: + color "^4.2.3" + detect-libc "^2.0.3" + semver "^7.6.3" + optionalDependencies: + "@img/sharp-darwin-arm64" "0.33.5" + "@img/sharp-darwin-x64" "0.33.5" + "@img/sharp-libvips-darwin-arm64" "1.0.4" + "@img/sharp-libvips-darwin-x64" "1.0.4" + "@img/sharp-libvips-linux-arm" "1.0.5" + "@img/sharp-libvips-linux-arm64" "1.0.4" + "@img/sharp-libvips-linux-s390x" "1.0.4" + "@img/sharp-libvips-linux-x64" "1.0.4" + "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" + "@img/sharp-libvips-linuxmusl-x64" "1.0.4" + "@img/sharp-linux-arm" "0.33.5" + "@img/sharp-linux-arm64" "0.33.5" + "@img/sharp-linux-s390x" "0.33.5" + "@img/sharp-linux-x64" "0.33.5" + "@img/sharp-linuxmusl-arm64" "0.33.5" + "@img/sharp-linuxmusl-x64" "0.33.5" + "@img/sharp-wasm32" "0.33.5" + "@img/sharp-win32-ia32" "0.33.5" + "@img/sharp-win32-x64" "0.33.5" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -4911,13 +4981,14 @@ stdin-discarder@^0.1.0: dependencies: bl "^5.0.0" -streamx@^2.13.0, streamx@^2.15.0: - version "2.16.1" - resolved "https://registry.npmjs.org/streamx/-/streamx-2.16.1.tgz" - integrity sha512-m9QYj6WygWyWa3H1YY69amr4nVgy61xfjys7xO7kviL5rfIEc2naf+ewFiOA+aEJD7y0JO3h2GoiUv4TDwEGzQ== +streamx@^2.15.0, streamx@^2.20.0: + version "2.20.1" + resolved "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz" + integrity sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA== dependencies: - fast-fifo "^1.1.0" + fast-fifo "^1.3.2" queue-tick "^1.0.1" + text-decoder "^1.1.0" optionalDependencies: bare-events "^2.2.0" @@ -5140,9 +5211,9 @@ tar-fs@^2.0.0: tar-stream "^2.1.4" tar-fs@^3.0.4: - version "3.0.5" - resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.5.tgz" - integrity sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg== + version "3.0.6" + resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz" + integrity sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w== dependencies: pump "^3.0.0" tar-stream "^3.1.5" @@ -5191,6 +5262,13 @@ terser@^5.26.0, terser@^5.4.0: commander "^2.20.0" source-map-support "~0.5.20" +text-decoder@^1.1.0: + version "1.2.0" + resolved "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.0.tgz" + integrity sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg== + dependencies: + b4a "^1.6.4" + thenify-all@^1.0.0: version "1.6.0" resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz"