diff --git a/.commitlintrc.js b/.commitlintrc.js index de29163bdae..12831151091 100644 --- a/.commitlintrc.js +++ b/.commitlintrc.js @@ -68,6 +68,7 @@ module.exports = { "flat-pages", "pnpm", "server", + "dmg", ], ], "scope-case": [2, "always", ["lower-case", "kebab-case"]], diff --git a/.github/workflows/check-code.yml b/.github/workflows/check-code.yml index 29710003d1d..cd0f383c9d9 100644 --- a/.github/workflows/check-code.yml +++ b/.github/workflows/check-code.yml @@ -28,7 +28,7 @@ jobs: - name: Install PNPM uses: pnpm/action-setup@v2 with: - version: latest + version: 9.9.0 - name: Restore Cache uses: actions/setup-node@v3 diff --git a/.github/workflows/deploy-storybook.yml b/.github/workflows/deploy-storybook.yml index d81202906fb..0c8c1f1fa99 100644 --- a/.github/workflows/deploy-storybook.yml +++ b/.github/workflows/deploy-storybook.yml @@ -20,7 +20,7 @@ jobs: - name: Install PNPM uses: pnpm/action-setup@v2 with: - version: 9 + version: 9.9.0 - name: Restore Cache uses: actions/setup-node@v3 diff --git a/.github/workflows/deploy-web-dev-cn.yml b/.github/workflows/deploy-web-dev-cn.yml index d39bf006977..daf10fe5900 100644 --- a/.github/workflows/deploy-web-dev-cn.yml +++ b/.github/workflows/deploy-web-dev-cn.yml @@ -20,7 +20,7 @@ jobs: - name: Install PNPM uses: pnpm/action-setup@v2 with: - version: 9 + version: 9.9.0 - name: Restore Cache uses: actions/setup-node@v3 @@ -31,8 +31,12 @@ jobs: - name: Install dependencies env: FLAT_AGREEMENT_URL: ${{ vars.FLAT_AGREEMENT_URL }} + FLAT_WEB_ALIYUN_PREFIX: ${{ vars.FLAT_WEB_ALIYUN_PREFIX }} + FLAT_WEB_SCENE_ID: ${{ vars.FLAT_WEB_SCENE_ID }} run: | echo "FLAT_AGREEMENT_URL=$FLAT_AGREEMENT_URL" >> config/CN/.env.development + echo "FLAT_WEB_ALIYUN_PREFIX=$FLAT_WEB_ALIYUN_PREFIX" >> config/CN/.env.development + echo "FLAT_WEB_SCENE_ID=$FLAT_WEB_SCENE_ID" >> config/CN/.env.development node ./scripts/ci/remove-workspace-packages.js web node ./scripts/ci/remove-package-scripts-hooks.js # failure automatically retries 3 times diff --git a/.github/workflows/deploy-web-dev-sg.yml b/.github/workflows/deploy-web-dev-sg.yml index 5120efcc1f3..c7bfacac863 100644 --- a/.github/workflows/deploy-web-dev-sg.yml +++ b/.github/workflows/deploy-web-dev-sg.yml @@ -20,7 +20,7 @@ jobs: - name: Install PNPM uses: pnpm/action-setup@v2 with: - version: 9 + version: 9.9.0 - name: Restore Cache uses: actions/setup-node@v3 @@ -29,7 +29,12 @@ jobs: cache: "pnpm" - name: Install dependencies + env: + FLAT_WEB_ALIYUN_PREFIX: ${{ vars.FLAT_WEB_ALIYUN_PREFIX }} + FLAT_WEB_SCENE_ID: ${{ vars.FLAT_WEB_SCENE_ID }} run: | + echo "FLAT_WEB_ALIYUN_PREFIX=$FLAT_WEB_ALIYUN_PREFIX" >> config/CN/.env.development + echo "FLAT_WEB_SCENE_ID=$FLAT_WEB_SCENE_ID" >> config/CN/.env.development node ./scripts/ci/remove-workspace-packages.js web node ./scripts/ci/remove-package-scripts-hooks.js # failure automatically retries 3 times diff --git a/.github/workflows/deploy-web-prod-cn.yml b/.github/workflows/deploy-web-prod-cn.yml deleted file mode 100644 index 5cb1295a106..00000000000 --- a/.github/workflows/deploy-web-prod-cn.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Deploy Flat Web Prod -on: - push: - branches: - - "stable" - - "only-deploy-prod-web" - -jobs: - deploy-flat-web-prod: - environment: production - env: - FLAT_UA: ${{ secrets.FLAT_UA }} - - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Install PNPM - uses: pnpm/action-setup@v2 - with: - version: 9 - - - name: Install dependencies - env: - FLAT_AGREEMENT_URL: ${{ vars.FLAT_AGREEMENT_URL }} - run: | - echo "FLAT_AGREEMENT_URL=$FLAT_AGREEMENT_URL" >> config/CN/.env.production - node ./scripts/ci/remove-workspace-packages.js web - node ./scripts/ci/remove-package-scripts-hooks.js - # failure automatically retries 3 times - pnpm i || pnpm i || pnpm i - - - name: Build flat web production - run: pnpm -F flat-web build:cn -m production - - - name: Log in to Docker Hub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Reset dockerignore - run: | - echo "*" > .dockerignore - echo "!web/flat-web/dist" >> .dockerignore - echo "!web/flat-web/deploy/nginx" >> .dockerignore - - - name: Build and push images production - env: - COMMIT_SHA_TAG: production-${{ github.sha }} - LATEST_PROD_TAG: latest - PRIVATE_DOCKERHUB_REGISTRY: ${{ secrets.PRIVATE_DOCKERHUB_REGISTRY }} - PRIVATE_DOCKERHUB_USERNAME: ${{ secrets.PRIVATE_DOCKERHUB_USERNAME }} - PRIVATE_DOCKERHUB_PASSWORD: ${{ secrets.PRIVATE_DOCKERHUB_PASSWORD }} - run: | - docker build . -f web/flat-web/deploy/Dockerfile -t agoraflat/flat-web:$COMMIT_SHA_TAG -t agoraflat/flat-web:$LATEST_PROD_TAG -t $PRIVATE_DOCKERHUB_REGISTRY/agoraflat/flat-web:$COMMIT_SHA_TAG -t $PRIVATE_DOCKERHUB_REGISTRY/agoraflat/flat-web:$LATEST_PROD_TAG - docker push agoraflat/flat-web:$COMMIT_SHA_TAG - docker push agoraflat/flat-web:$LATEST_PROD_TAG - - docker login -u $PRIVATE_DOCKERHUB_USERNAME -p $PRIVATE_DOCKERHUB_PASSWORD $PRIVATE_DOCKERHUB_REGISTRY - docker push $PRIVATE_DOCKERHUB_REGISTRY/agoraflat/flat-web:$COMMIT_SHA_TAG - docker push $PRIVATE_DOCKERHUB_REGISTRY/agoraflat/flat-web:$LATEST_PROD_TAG - - - name: Prep helm chart - env: - DOCKER_IMAGE_NAME: ${{ secrets.PRIVATE_DOCKERHUB_REGISTRY }}/agoraflat/flat-web - DOCKER_IMAGE_TAG: production-${{ github.sha }} - run: | - export APPVERSION=production-${{ github.sha }} - export CHART=./web/flat-web/helm/Chart.yaml - sed -i "s/^appVersion:.*$/appVersion: $APPVERSION/" $CHART - - export VALUE=./web/flat-web/helm/values.yaml - sed -i "s|DOCKER_IMAGE_NAME|$DOCKER_IMAGE_NAME|" $VALUE - sed -i "s|DOCKER_IMAGE_TAG|$DOCKER_IMAGE_TAG|" $VALUE - - - name: Deploy - uses: WyriHaximus/github-action-helm3@v2 - with: - exec: helm upgrade flat-web ./web/flat-web/helm --install --wait --atomic --namespace=default - kubeconfig: "${{ secrets.KUBECONFIG }}" diff --git a/.github/workflows/deploy-web-prod-sg.yml b/.github/workflows/deploy-web-prod-sg.yml index 3b0d3c7d173..72343997831 100644 --- a/.github/workflows/deploy-web-prod-sg.yml +++ b/.github/workflows/deploy-web-prod-sg.yml @@ -20,10 +20,15 @@ jobs: - name: Install PNPM uses: pnpm/action-setup@v2 with: - version: 9 + version: 9.9.0 - name: Install dependencies + env: + FLAT_WEB_ALIYUN_PREFIX: ${{ vars.FLAT_WEB_ALIYUN_PREFIX }} + FLAT_WEB_SCENE_ID: ${{ vars.FLAT_WEB_SCENE_ID }} run: | + echo "FLAT_WEB_ALIYUN_PREFIX=$FLAT_WEB_ALIYUN_PREFIX" >> config/CN/.env.production + echo "FLAT_WEB_SCENE_ID=$FLAT_WEB_SCENE_ID" >> config/CN/.env.production node ./scripts/ci/remove-workspace-packages.js web node ./scripts/ci/remove-package-scripts-hooks.js # failure automatically retries 3 times diff --git a/cspell.config.js b/cspell.config.js index e5af436ab0e..357b30c9097 100644 --- a/cspell.config.js +++ b/cspell.config.js @@ -9,6 +9,7 @@ module.exports = { "courseware", "PPTURL", "aliyun", + "nypf9bgg", // aliyun captcha scene ID "regx", "bootup", "btns", @@ -79,6 +80,7 @@ module.exports = { "unhide", "nsis", "respawn", + "UDZO", // electron-builder DMG format // file type "avif", diff --git a/desktop/main-app/electron-builder/CN.yml b/desktop/main-app/electron-builder/CN.yml index 75b21729b0f..053b5493328 100644 --- a/desktop/main-app/electron-builder/CN.yml +++ b/desktop/main-app/electron-builder/CN.yml @@ -44,6 +44,7 @@ mas: gatekeeperAssess: true dmg: + format: UDZO contents: - { x: 130, y: 220 } - { x: 410, y: 220, type: link, path: /Applications } diff --git a/desktop/main-app/electron-builder/SG.yml b/desktop/main-app/electron-builder/SG.yml index 8104d097f59..9125c3e1056 100644 --- a/desktop/main-app/electron-builder/SG.yml +++ b/desktop/main-app/electron-builder/SG.yml @@ -36,6 +36,7 @@ mac: - arm64 dmg: + format: UDZO contents: - { x: 130, y: 220 } - { x: 410, y: 220, type: link, path: /Applications } diff --git a/desktop/renderer-app/index.html b/desktop/renderer-app/index.html index d4c3dd67b46..22751b31b32 100644 --- a/desktop/renderer-app/index.html +++ b/desktop/renderer-app/index.html @@ -5,6 +5,19 @@ Flat + + diff --git a/desktop/renderer-app/scripts/vite-plugin-html-env.ts b/desktop/renderer-app/scripts/vite-plugin-html-env.ts new file mode 100644 index 00000000000..bfca4d1e1da --- /dev/null +++ b/desktop/renderer-app/scripts/vite-plugin-html-env.ts @@ -0,0 +1,81 @@ +import type { Plugin } from "vite"; +import { configRegion } from "../../../scripts/utils/auto-choose-config"; +import dotenvReal from "dotenv"; +import { expand } from "dotenv-expand"; +import fs from "fs"; +import path from "path"; + +// 使用 require 导入 CommonJS 模块 +const { configPath } = require("../../../scripts/constants"); + +/** + * 替换 HTML 中的 process.env.XXX 为实际值 + * 因为 Vite 的 define 只替换模块代码,不替换 HTML 中的内联脚本 + */ +export function injectHtmlEnv(): Plugin { + return { + name: "flat:html-env", + enforce: "pre", + transformIndexHtml: { + enforce: "pre", + transform(originalHTML) { + const envVars = getEnvVars(); + let html = originalHTML; + + // 替换所有 process.env.XXX 为实际值 + for (const [key, value] of Object.entries(envVars)) { + const regex = new RegExp(`process\\.env\\.${key}`, "g"); + html = html.replace(regex, JSON.stringify(value)); + } + + return { + html, + tags: [], + }; + }, + }, + }; +} + +function getEnvVars(): Record { + const envVars: Record = {}; + const mode = process.env.NODE_ENV === "production" ? "production" : "development"; + const envDir = path.join(configPath, configRegion()); + const envConfigContent = getEnvConfigContent(envDir, mode); + + // 设置 FLAT_REGION + envVars.FLAT_REGION = configRegion(); + + if (envConfigContent) { + const parsed = dotenvReal.parse(envConfigContent); + expand({ parsed }); + const env = { ...parsed }; + + // 从环境变量文件中读取的值 + for (const [key, value] of Object.entries(env)) { + envVars[key] = value; + } + } + + // 如果环境变量文件中有 FLAT_WEB_ALIYUN_PREFIX,使用它;否则使用默认值 + if (!envVars.FLAT_WEB_ALIYUN_PREFIX) { + envVars.FLAT_WEB_ALIYUN_PREFIX = "195gxh"; + } + + return envVars; +} + +function getEnvConfigContent(envDir: string, mode: string): string | null { + const configFileList = [ + path.join(envDir, `.env.${mode}.local`), + path.join(envDir, `.env.${mode}`), + ]; + + for (const filepath of configFileList) { + if (fs.existsSync(filepath) && fs.statSync(filepath).isFile()) { + return fs.readFileSync(filepath, "utf-8"); + } + } + + return null; +} diff --git a/desktop/renderer-app/vite.config.ts b/desktop/renderer-app/vite.config.ts index 5a9adb201d2..cb08022f4a7 100644 --- a/desktop/renderer-app/vite.config.ts +++ b/desktop/renderer-app/vite.config.ts @@ -8,6 +8,7 @@ import { dotenv } from "@netless/flat-vite-plugins/dotenv"; import { reactVirtualized } from "@netless/flat-vite-plugins/react-virtualized"; import { electron } from "./scripts/vite-plugin-electron"; import { injectGtag } from "./scripts/vite-plugin-html-gtag"; +import { injectHtmlEnv } from "./scripts/vite-plugin-html-env"; import { rootNodeModules, rendererPath } from "../../scripts/constants"; import { autoChooseConfig } from "../../scripts/utils/auto-choose-config"; @@ -27,6 +28,7 @@ export default defineConfig((): UserConfig => { const plugins: PluginOption[] = [ reactPlugin, dotenv(autoChooseConfig()), + injectHtmlEnv(), reactVirtualized(), injectGtag(), copy({ diff --git a/package.json b/package.json index a5ccce9bc18..9055ff725d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "name": "flat-monorepo", "private": true, + "packageManager": "pnpm@9.9.0", "scripts": { "preinstall": "npx only-allow pnpm", "prepare": "husky install", diff --git a/packages/flat-components/src/components/LoginPage/BindingPhonePanel/index.tsx b/packages/flat-components/src/components/LoginPage/BindingPhonePanel/index.tsx index 305fd31f56c..19a47796b4f 100644 --- a/packages/flat-components/src/components/LoginPage/BindingPhonePanel/index.tsx +++ b/packages/flat-components/src/components/LoginPage/BindingPhonePanel/index.tsx @@ -18,6 +18,7 @@ export interface BindingPhonePanelProps { sendBindingPhoneCode: ( countryCode: string, phone: string, + captchaVerifyParam?: string, ) => Promise; needRebindingPhone: (phone: string) => void; } @@ -111,6 +112,7 @@ export const BindingPhonePanel: React.FC = ({ Promise; + sendVerificationCode: ( + captchaVerifyParam?: string, + ) => Promise; // for rebinding phone onRebinding?: () => void; } export const LoginSendCode: React.FC = ({ + isCaptcha = false, type, isAccountValidated, sendVerificationCode, @@ -32,12 +40,21 @@ export const LoginSendCode: React.FC = ({ const [countdown, setCountdown] = useState(0); const [sendingCode, setSendingCode] = useState(false); + const captchaRef = useRef(null); + const captchaVerifyParam = useRef(undefined); + const isAccountValidatedRef = useRef(isAccountValidated); + const initCaptchaRef = useRef<((_isCaptcha: boolean) => void) | null>(null); + + // 保持 ref 与 prop 同步 + useEffect(() => { + isAccountValidatedRef.current = isAccountValidated; + }, [isAccountValidated]); const sendCode = useCallback(async () => { - if (isAccountValidated) { + if (isAccountValidatedRef.current) { try { setSendingCode(true); - const sent = await sp(sendVerificationCode()); + const sent = await sp(sendVerificationCode(captchaVerifyParam.current)); setSendingCode(false); if (sent) { @@ -58,15 +75,24 @@ export const LoginSendCode: React.FC = ({ setCountdown(--count); if (count === 0) { clearInterval(timer); + if (initCaptchaRef.current) { + initCaptchaRef.current(isCaptcha); + } } }, 1000); } else { + if (initCaptchaRef.current) { + initCaptchaRef.current(isCaptcha); + } message.error(t("send-verify-code-failed")); } } catch (error) { if (!isUnMountRef.current) { setSendingCode(false); } + if (initCaptchaRef.current) { + initCaptchaRef.current(isCaptcha); + } // we say the phone is already binding when error message contains `RequestErrorCode.SMSAlreadyBinding` // and then we can enter rebinding page to rebind. @@ -74,11 +100,70 @@ export const LoginSendCode: React.FC = ({ onRebinding(); return; } - errorTips(error); } } - }, [isAccountValidated, sp, sendVerificationCode, t, type, isUnMountRef, onRebinding]); + }, [sp, sendVerificationCode, t, type, isUnMountRef, onRebinding]); + + const getInstance = (instance: any): void => { + captchaRef.current = instance; + }; + + const success = useCallback( + async (_captchaVerifyParam: string): Promise => { + captchaVerifyParam.current = _captchaVerifyParam; + sendCode(); + }, + [sendCode], + ); + + // 验证码验证不通过回调函数 + const fail = useCallback( + (error: any) => { + console.error(error); + }, + [isCaptcha], + ); + + const initCaptcha = useCallback( + (_isCaptcha: boolean) => { + if (_isCaptcha && (window as any).initAliyunCaptcha) { + const region = process.env.FLAT_REGION || "CN"; + (window as any).initAliyunCaptcha({ + SceneId: FLAT_WEB_SCENE_ID || "nypf9bgg", // 场景ID。根据步骤二新建验证场景后,您可以在验证码场景列表,获取该场景的场景ID + mode: "popup", // 验证码模式。popup表示要集成的验证码模式为弹出式。无需修改 + element: "#captcha-element", // 页面上预留的渲染验证码的元素,与原代码中预留的页面元素保持一致。 + button: "#send-verify-code-phone", // 触发验证码弹窗的元素。 + success: success, + fail: fail, + getInstance: getInstance, // 绑定验证码实例函数,无需修改 + slideStyle: { + width: 360, + height: 40, + }, // 滑块验证码样式,支持自定义宽度和高度,单位为px。其中,width最小值为320 px + language: region === "CN" ? "cn" : "en", // 验证码语言类型,支持简体中文(cn)、繁体中文(tw)、英文(en) + }); + } else { + document + .getElementById("send-verify-code-email") + ?.addEventListener("click", sendCode); + } + }, + [success, fail, sendCode], + ); + + // 更新 ref,以便 fail 回调可以访问 + useEffect(() => { + initCaptchaRef.current = initCaptcha; + }, [initCaptcha]); + + const verifyBtnClick = useCallback(() => { + if (type === PasswordLoginType.Email) { + sendCode(); + } else if (isCaptcha && type === PasswordLoginType.Phone && captchaRef.current) { + document.getElementById("send-verify-code-phone")?.click(); + } + }, [sendCode, type, isCaptcha]); // Workaround to prevent browser auto complete this field // however, it still cannot prevent auto complete panel from showing up @@ -86,34 +171,40 @@ export const LoginSendCode: React.FC = ({ useEffect(() => { const ticket = setTimeout(() => { setReadOnly(false); + initCaptcha(isCaptcha); }, 1000); return () => clearTimeout(ticket); - }, []); + }, [initCaptcha, isCaptcha]); return ( - } - readOnly={readOnly} - suffix={ - countdown > 0 ? ( - - {t("seconds-to-resend", { seconds: countdown })} - - ) : ( - - ) - } - {...restProps} - /> + <> + } + readOnly={readOnly} + suffix={ + countdown > 0 ? ( + + {t("seconds-to-resend", { seconds: countdown })} + + ) : ( + + ) + } + {...restProps} + /> + {isCaptcha && ( + + )} + ); }; diff --git a/packages/flat-components/src/components/LoginPage/LoginWithCode/index.tsx b/packages/flat-components/src/components/LoginPage/LoginWithCode/index.tsx index 8ece3d82ac1..20ef421cc1d 100644 --- a/packages/flat-components/src/components/LoginPage/LoginWithCode/index.tsx +++ b/packages/flat-components/src/components/LoginPage/LoginWithCode/index.tsx @@ -23,7 +23,11 @@ export interface LoginWithCodeProps { privacyURL?: LoginAgreementProps["privacyURL"]; serviceURL?: LoginAgreementProps["serviceURL"]; onClickButton: LoginButtonsProps["onClick"]; - sendVerificationCode: (countryCode: string, phone: string) => Promise; + sendVerificationCode: ( + countryCode: string, + phone: string, + captchaVerifyParam?: string, + ) => Promise; loginOrRegister: (countryCode: string, phone: string, code: string) => Promise; loginWithPassword: () => void; } @@ -115,9 +119,9 @@ export const LoginWithCode: React.FC = ({ [agreed, onClickButton, privacyURL, serviceURL, t], ); - const handleSendVerificationCode = async (): Promise => { + const handleSendVerificationCode = async (captchaVerifyParam?: string): Promise => { const { phone } = form.getFieldsValue(); - return sendVerificationCode(countryCode, phone); + return sendVerificationCode(countryCode, phone, captchaVerifyParam); }; const formValidateStatus = useCallback(() => { @@ -125,7 +129,6 @@ export const LoginWithCode: React.FC = ({ form.getFieldsError().every(field => field.errors.length <= 0) && Object.values(form.getFieldsValue()).every(v => !!v), ); - if (form.getFieldValue("phone") && !form.getFieldError("phone").length) { setIsAccountValidated(true); } else { @@ -182,6 +185,7 @@ export const LoginWithCode: React.FC = ({ diff --git a/packages/flat-components/src/components/LoginPage/LoginWithPassword/LoginWithPassword.stories.tsx b/packages/flat-components/src/components/LoginPage/LoginWithPassword/LoginWithPassword.stories.tsx index 3c3d141be20..86da1355def 100644 --- a/packages/flat-components/src/components/LoginPage/LoginWithPassword/LoginWithPassword.stories.tsx +++ b/packages/flat-components/src/components/LoginPage/LoginWithPassword/LoginWithPassword.stories.tsx @@ -46,8 +46,15 @@ Overview.args = { loginWithVerificationCode: () => { message.info("login with verification code"); }, - sendVerificationCode: (type: PasswordLoginType, key: string) => { - message.info("send code with " + type + " to " + key); + sendVerificationCode: (type: PasswordLoginType, key: string, captchaVerifyParam?: string) => { + message.info( + "send code with " + + type + + " to " + + key + + ". And the captchaVerifyParam is: " + + captchaVerifyParam, + ); return new Promise(resolve => setTimeout(() => resolve(false), 1000)); }, resetPassword: (type: PasswordLoginType, { key }, code: string, password: string) => { diff --git a/packages/flat-components/src/components/LoginPage/LoginWithPassword/index.tsx b/packages/flat-components/src/components/LoginPage/LoginWithPassword/index.tsx index 8a033a66a6f..2f227477746 100644 --- a/packages/flat-components/src/components/LoginPage/LoginWithPassword/index.tsx +++ b/packages/flat-components/src/components/LoginPage/LoginWithPassword/index.tsx @@ -46,7 +46,11 @@ export interface LoginWithPasswordProps { register: () => void; onClickButton: LoginButtonsProps["onClick"]; loginWithVerificationCode: () => void; - sendVerificationCode: (type: PasswordLoginType, key: string) => Promise; + sendVerificationCode: ( + type: PasswordLoginType, + key: string, + captchaVerifyParam?: string, + ) => Promise; resetPassword: ( type: PasswordLoginType, key: LoginKeyType, @@ -169,10 +173,14 @@ export const LoginWithPassword: React.FC = ({ setClickedReset(false); }, [countryCode, form, phone, resetPassword, sp, t, type]); - const handleSendVerificationCode = async (): Promise => { + const handleSendVerificationCode = async (captchaVerifyParam?: string): Promise => { const { key: keyValue } = form.getFieldsValue(); - return sendVerificationCode(type, phone ? countryCode + keyValue : keyValue); + return sendVerificationCode( + type, + phone ? countryCode + keyValue : keyValue, + captchaVerifyParam, + ); }; const onClick = useCallback( @@ -341,7 +349,7 @@ export interface ResetPasswordPageProps { t: FlatI18nTFunction; setType: (type: PasswordLoginType) => void; setCountryCode: (code: string) => void; - handleSendVerificationCode: () => Promise; + handleSendVerificationCode: (captchaVerifyParam?: string) => Promise; setPage: (page: PasswordLoginPageType) => void; doReset: () => void; } @@ -390,6 +398,7 @@ export function resetPasswordPage({ diff --git a/packages/flat-components/src/components/LoginPage/RebindingPhonePanel/index.tsx b/packages/flat-components/src/components/LoginPage/RebindingPhonePanel/index.tsx index c9840d7d037..637fbd6717a 100644 --- a/packages/flat-components/src/components/LoginPage/RebindingPhonePanel/index.tsx +++ b/packages/flat-components/src/components/LoginPage/RebindingPhonePanel/index.tsx @@ -15,7 +15,11 @@ export interface RebindingPhonePanelProps { defaultPhone: string; cancelRebindingPhone: () => void; rebindingPhone: (countryCode: string, phone: string, code: string) => Promise; - sendRebindingPhoneCode: (countryCode: string, phone: string) => Promise; + sendRebindingPhoneCode: ( + countryCode: string, + phone: string, + captchaVerifyParam?: string, + ) => Promise; } interface RebindingFormValues { @@ -100,6 +104,7 @@ export const RebindingPhonePanel: React.FC = ({ diff --git a/packages/flat-components/src/components/RegisterModal/RegisterModal.stories.tsx b/packages/flat-components/src/components/RegisterModal/RegisterModal.stories.tsx index 7263a79c5d8..528af397279 100644 --- a/packages/flat-components/src/components/RegisterModal/RegisterModal.stories.tsx +++ b/packages/flat-components/src/components/RegisterModal/RegisterModal.stories.tsx @@ -32,8 +32,15 @@ Overview.args = { ); return new Promise(resolve => setTimeout(() => resolve(password === "123456"), 1000)); }, - sendVerificationCode: (type: PasswordLoginType, key: string) => { - message.info("send code. current type: " + type + ". value is: " + key); + sendVerificationCode: (type: PasswordLoginType, key: string, captchaVerifyParam?: string) => { + message.info( + "send code. current type: " + + type + + ". value is: " + + key + + ". And the captchaVerifyParam is: " + + captchaVerifyParam, + ); return new Promise(resolve => setTimeout(() => resolve(true), 1000)); }, backToLogin: () => { diff --git a/packages/flat-components/src/components/RegisterModal/index.tsx b/packages/flat-components/src/components/RegisterModal/index.tsx index 9d90b34e4e3..0ee5bec1fcb 100644 --- a/packages/flat-components/src/components/RegisterModal/index.tsx +++ b/packages/flat-components/src/components/RegisterModal/index.tsx @@ -34,7 +34,11 @@ export interface RegisterProps { privacyURL?: LoginAgreementProps["privacyURL"]; serviceURL?: LoginAgreementProps["serviceURL"]; onClickButton: LoginButtonsProps["onClick"]; - sendVerificationCode: (type: PasswordLoginType, key: string) => Promise; + sendVerificationCode: ( + type: PasswordLoginType, + key: string, + captchaVerifyParam?: string, + ) => Promise; register: ( type: PasswordLoginType, key: LoginKeyType, @@ -87,10 +91,14 @@ export const RegisterModal: React.FC = ({ const phone = type === PasswordLoginType.Phone; - const handleSendVerificationCode = async (): Promise => { + const handleSendVerificationCode = async (captchaVerifyParam?: string): Promise => { const { key: keyValue } = form.getFieldsValue(); - return sendVerificationCode(type, phone ? countryCode + keyValue : keyValue); + return sendVerificationCode( + type, + phone ? countryCode + keyValue : keyValue, + captchaVerifyParam, + ); }; const doRegister = useCallback(async () => { @@ -180,6 +188,7 @@ export const RegisterModal: React.FC = ({ diff --git a/packages/flat-i18n/locales/en.json b/packages/flat-i18n/locales/en.json index c4870df1b3f..617381ec561 100644 --- a/packages/flat-i18n/locales/en.json +++ b/packages/flat-i18n/locales/en.json @@ -197,6 +197,9 @@ "privacy-agreement": "Privacy Policy", "service-policy": "Term of Service", "app-welcome": "Welcome to {{appName}}", + "captcha-failed": "Captcha failed", + "captcha-invalid": "Captcha invalid", + "captcha-required": "Captcha required", "back": "Back", "also-cancel-the-series-of-periodic-rooms": "At the same time cancel the series of periodic rooms", "cancel-of-periodic-rooms": "Cancel", @@ -595,6 +598,7 @@ "wait-for-teacher-to-enter": "The room hasn't started yet. Please wait for the teacher to enter", "the-pmi-room-already-exists": "The PMI room already exists", "user-pmi-drained": "User PMI used up, please contact the administrator", + "user-blacklisted": "This account has been frozen. Please contact the administrator", "pmi-room-exist": "PMI room already exists, please cancel existing PMI room first", "pmi-help": "Your own room number, you can use this fixed number to create a room", "personal-room-id": "PMI", @@ -824,7 +828,6 @@ "agree": "agree", "disagree": "disagree" }, - "collect-media-options": "Audio and video data acquisition", "collect-media-turn-on": "Turn on", "collect-media-turn-off": "Turn off" } diff --git a/packages/flat-i18n/locales/zh-CN.json b/packages/flat-i18n/locales/zh-CN.json index 6073a126311..4391a51cc94 100644 --- a/packages/flat-i18n/locales/zh-CN.json +++ b/packages/flat-i18n/locales/zh-CN.json @@ -198,6 +198,9 @@ "bind-phone": "绑定手机号", "rebinding-phone": "合并账号", "need-bind-phone": "根据相关政策法规,需要绑定手机号", + "captcha-failed": "验证码校验错误", + "captcha-invalid": "当前验证码无效", + "captcha-required": "这步操作需要验证码校验", "back": "返回", "remove-room": "移除房间", "cancel-room": "取消房间", @@ -595,6 +598,7 @@ "wait-for-teacher-to-enter": "房间未开始,请等待老师进入", "the-pmi-room-already-exists": "PMI房间已存在", "user-pmi-drained": "用户PMI已分配完,请联系管理员", + "user-blacklisted": "该账号已停用,请联系管理员", "pmi-room-exist": "个人房间已存在,请先取消已存在的房间", "pmi-help": "你的专属房间号,可使用该固定号码创建房间", "personal-room-id": "个人房间号", @@ -824,7 +828,6 @@ "agree": "同意", "disagree": "取消" }, - "collect-media-options": "音视频数据采集", "collect-media-turn-on": "开启", "collect-media-turn-off": "关闭" } diff --git a/packages/flat-pages/src/HomePage/MainRoomMenu/index.tsx b/packages/flat-pages/src/HomePage/MainRoomMenu/index.tsx index 9e3320f79ca..1dd85df54b5 100644 --- a/packages/flat-pages/src/HomePage/MainRoomMenu/index.tsx +++ b/packages/flat-pages/src/HomePage/MainRoomMenu/index.tsx @@ -2,10 +2,10 @@ /* eslint-disable react-hooks/exhaustive-deps */ import "./MainRoomMenu.less"; -import React, { FC, useContext, useMemo } from "react"; +import React, { FC, useContext } from "react"; import { Col, Row } from "antd"; import { Region } from "flat-components"; -import { AILanguage, AIRole, AIScene, RoomType } from "@netless/flat-server-api"; +import { RoomType } from "@netless/flat-server-api"; import { GlobalStoreContext, RoomStoreContext } from "../../components/StoreProvider"; import { RouteNameType, usePushHistory } from "../../utils/routes"; import { CreateRoomBox } from "./CreateRoomBox"; @@ -13,7 +13,7 @@ import { JoinRoomBox } from "./JoinRoomBox"; import { ScheduleRoomBox } from "./ScheduleRoomBox"; import { joinRoomHandler } from "../../utils/join-room-handler"; import { errorTips } from "flat-components"; -import CreateAIRoomBox from "./CreateAIRoomBox"; +// import CreateAIRoomBox from "./CreateAIRoomBox"; export const MainRoomMenu: FC = () => { const roomStore = useContext(RoomStoreContext); const globalStore = useContext(GlobalStoreContext); @@ -27,27 +27,27 @@ export const MainRoomMenu: FC = () => { } }; - const AIRoomBox = useMemo(() => { - const isCnWeb = window.location.host.includes(".apprtc.cn"); - if (!isCnWeb) { - return ; - } - return null; - }, [window.location.host]); + // const AIRoomBox = useMemo(() => { + // const isCnWeb = window.location.host.includes(".apprtc.cn"); + // if (!isCnWeb) { + // return ; + // } + // return null; + // }, [window.location.host]); return (
- + - + - + - {AIRoomBox} + {/* {AIRoomBox} */}
); @@ -67,32 +67,6 @@ export const MainRoomMenu: FC = () => { pmi: !!pmi, }); - await onJoinRoom(roomUUID); - } catch (e) { - errorTips(e); - } - } - async function createAIRoom( - title: string, - type: RoomType, - region: Region, - role: AIRole, - scene: AIScene, - language: AILanguage, - ): Promise { - try { - const roomUUID = await roomStore.createAIRoom({ - title, - type, - beginTime: Date.now(), - region, - pmi: false, - isAI: true, - role, - scene, - language, - }); - await onJoinRoom(roomUUID); } catch (e) { errorTips(e); diff --git a/packages/flat-pages/src/LoginPage/index.tsx b/packages/flat-pages/src/LoginPage/index.tsx index efef124f3ec..f639aa68771 100644 --- a/packages/flat-pages/src/LoginPage/index.tsx +++ b/packages/flat-pages/src/LoginPage/index.tsx @@ -98,8 +98,10 @@ export const LoginPage = observer(function LoginPage() { wrap(loginPhone(countryCode + phone, Number(code)).then(onLoginResult)) } loginWithPassword={() => setCurrentState("SWITCH_TO_PASSWORD")} - sendVerificationCode={async (countryCode, phone) => - wrap(loginPhoneSendCode(countryCode + phone)) + sendVerificationCode={async (countryCode, phone, captchaVerifyParam) => + loginPhoneSendCode(countryCode + phone, captchaVerifyParam).then( + () => true, + ) } /> ); @@ -133,12 +135,11 @@ export const LoginPage = observer(function LoginPage() { }), ) } - sendVerificationCode={async (type, key) => - wrap( - type === PasswordLoginType.Email - ? registerEmailSendCode(key, emailLanguage) - : registerPhoneSendCode(key), - ) + sendVerificationCode={async (type, key, captchaVerifyParam) => + (type === PasswordLoginType.Email + ? registerEmailSendCode(key, emailLanguage) + : registerPhoneSendCode(key, captchaVerifyParam) + ).then(() => true) } /> ); @@ -241,12 +242,11 @@ export const LoginPage = observer(function LoginPage() { }), ) } - sendVerificationCode={async (type, key) => - wrap( - type === PasswordLoginType.Email - ? resetEmailSendCode(key, emailLanguage) - : resetPhoneSendCode(key), - ) + sendVerificationCode={async (type, key, captchaVerifyParam) => + (type === PasswordLoginType.Email + ? resetEmailSendCode(key, emailLanguage) + : resetPhoneSendCode(key, captchaVerifyParam) + ).then(() => true) } /> ); diff --git a/packages/flat-pages/src/LoginPage/utils/state.ts b/packages/flat-pages/src/LoginPage/utils/state.ts index 3c0db9601ae..5d5c0b33a09 100644 --- a/packages/flat-pages/src/LoginPage/utils/state.ts +++ b/packages/flat-pages/src/LoginPage/utils/state.ts @@ -1,4 +1,5 @@ import { useRef, useEffect, useCallback, useState, useContext } from "react"; +import { message } from "antd"; import { Account, globalStore } from "@netless/flat-stores"; import { RouteNameType } from "../../route-config"; import { joinRoomHandler } from "../../utils/join-room-handler"; @@ -13,6 +14,7 @@ import { LoginProcessResult } from "@netless/flat-server-api"; import { LoginButtonProviderType } from "flat-components"; import { LoginDisposer } from "./disposer"; import { NODE_ENV } from "../../constants/process"; +import { useTranslate } from "@netless/flat-i18n"; export function useMachine(): [any, (type: ToggleEventsType) => void] { const { initialState } = loginMachine; @@ -57,6 +59,7 @@ export interface LoginState { export function useLoginState(): LoginState { const pushHistory = usePushHistory(); + const t = useTranslate(); const urlParams = useURLParams(); const windowsBtn = useContext(WindowsSystemBtnContext); @@ -71,6 +74,13 @@ export function useLoginState(): LoginState { const [currentState, setCurrentState] = useMachine(); + useEffect(() => { + const errorReason = new URLSearchParams(window.location.search).get("error"); + if (errorReason === "blacklisted") { + message.error(t("user-blacklisted")); + } + }, [t]); + useEffect(() => { // update state to binding phone // we can not update state to binding phone here if state have already been binding phone state or rebinding phone state diff --git a/packages/flat-pages/src/SensitivePage/index.tsx b/packages/flat-pages/src/SensitivePage/index.tsx index 39b0464ef69..45c0fda766f 100644 --- a/packages/flat-pages/src/SensitivePage/index.tsx +++ b/packages/flat-pages/src/SensitivePage/index.tsx @@ -142,6 +142,13 @@ export const SensitivePage = observer(function SensitivePage() { [t], ); + useEffect(() => { + document.getElementById("app")?.style.setProperty("overflow-y", "scroll"); + return () => { + document.getElementById("app")?.style.removeProperty("overflow-y"); + }; + }, []); + if (!token) { return ; } diff --git a/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/UpdateEmailModel.tsx b/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/UpdateEmailModel.tsx index 03745a12d61..f2766d714cf 100644 --- a/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/UpdateEmailModel.tsx +++ b/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/UpdateEmailModel.tsx @@ -124,6 +124,7 @@ export const UpdateEmailModel: React.FC = ({ diff --git a/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/UpdatePhoneModel.tsx b/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/UpdatePhoneModel.tsx index db41db732a0..dc6906620ff 100644 --- a/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/UpdatePhoneModel.tsx +++ b/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/UpdatePhoneModel.tsx @@ -129,6 +129,7 @@ export const UpdatePhoneModel: React.FC = ({ diff --git a/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/index.tsx b/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/index.tsx index 224b007471a..4be2aeeedbe 100644 --- a/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/index.tsx +++ b/packages/flat-pages/src/UserSettingPage/GeneralSettingPage/index.tsx @@ -23,11 +23,9 @@ import { LoginPlatform, deleteAccount, deleteAccountValidate, - getCollectionAgreement, loginCheck, removeBinding, rename, - setCollectionAgreement, } from "@netless/flat-server-api"; import { PreferencesStoreContext, GlobalStoreContext } from "../../components/StoreProvider"; @@ -45,43 +43,13 @@ import { BindGitHub } from "./binding/GitHub"; import { BindGoogle } from "./binding/Google"; import { BindingField } from "./BindingField"; import { useBindingList } from "./binding"; -import { Region } from "../../utils/join-room-handler"; +// import { Region } from "../../utils/join-room-handler"; enum SelectLanguage { Chinese, English, } -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -const CollectionAgreement = () => { - const [isAgree, setAgree] = useState(true); - const t = useTranslate(); - const sp = useSafePromise(); - useEffect(() => { - sp(getCollectionAgreement()).then(res => { - setAgree(res.isAgree); - }); - }, [sp]); - async function changeCollectMediaState(event: CheckboxChangeEvent): Promise { - const isAgree = Boolean(event.target.value); - await sp(setCollectionAgreement(isAgree)); - setAgree(isAgree); - } - return ( -
-
{t("collect-media-options")}
- - - {t("collect-media-turn-on")} - - - {t("collect-media-turn-off")} - - -
- ); -}; - export const GeneralSettingPage = observer(function GeneralSettingPage() { const globalStore = useContext(GlobalStoreContext); const preferencesStore = useContext(PreferencesStoreContext); @@ -106,10 +74,6 @@ export const GeneralSettingPage = observer(function GeneralSettingPage() { () => `${FLAT_WEB_BASE_URL}/join/${globalStore.pmi}`, [globalStore.pmi], ); - const serverRegion = useMemo( - () => globalStore.serverRegionConfig?.server.region, - [globalStore.serverRegionConfig?.server.region], - ); const loginButtons = useMemo( () => process.env.LOGIN_METHODS.split(",") as LoginButtonProviderType[], [], @@ -438,12 +402,12 @@ export const GeneralSettingPage = observer(function GeneralSettingPage() {
- {serverRegion === Region.CN_HZ && ( + {/* {serverRegion === Region.CN_HZ && ( <>
- )} + )} */}
{t("delete-account")} diff --git a/packages/flat-server-api/src/constants.ts b/packages/flat-server-api/src/constants.ts index 94b01af6791..43035eaf06a 100644 --- a/packages/flat-server-api/src/constants.ts +++ b/packages/flat-server-api/src/constants.ts @@ -6,6 +6,9 @@ export const SERVER_DOMAINS = process.env.FLAT_SERVER_DOMAINS as unknown as Reco export const CURRENT_SERVER_DOMAIN = process.env.FLAT_SERVER_DOMAIN; export const FLAT_AGREEMENT_URL = process.env.FLAT_AGREEMENT_URL; +export const FLAT_WEB_ALIYUN_PREFIX = process.env.FLAT_WEB_ALIYUN_PREFIX; +export const FLAT_WEB_SCENE_ID = process.env.FLAT_WEB_SCENE_ID; + export const COOKIE_DOMAIN = CURRENT_SERVER_DOMAIN ? CURRENT_SERVER_DOMAIN.slice(CURRENT_SERVER_DOMAIN.indexOf(".") + 1) : ""; diff --git a/packages/flat-server-api/src/error.ts b/packages/flat-server-api/src/error.ts index 82f5c5e6b75..75e7221518b 100644 --- a/packages/flat-server-api/src/error.ts +++ b/packages/flat-server-api/src/error.ts @@ -47,6 +47,7 @@ export enum RequestErrorCode { UserPasswordIncorrect, // user password (for update) incorrect UserOrPasswordIncorrect, // user or password (for login) incorrect UserPmiDrained, // user pmi drained + UserBlacklisted, // user is blacklisted, login/register rejected RecordNotFound = 500000, @@ -84,6 +85,10 @@ export enum RequestErrorCode { OAuthUUIDNotFound = 130000, // oauth uuid not found OAuthClientIDNotFound, // oauth client id not found OAuthSecretUUIDNotFound, // oauth secret uuid not found + + CaptchaFailed = 150000, // captcha failed + CaptchaInvalid, // captcha invalid + CaptchaRequired, // captcha required } export const RequestErrorMessage = { @@ -138,6 +143,7 @@ export const RequestErrorMessage = { [RequestErrorCode.UserPasswordIncorrect]: "user-password-incorrect", [RequestErrorCode.UserOrPasswordIncorrect]: "user-account-or-password-incorrect", [RequestErrorCode.UserPmiDrained]: "user-pmi-drained", + [RequestErrorCode.UserBlacklisted]: "user-blacklisted", [RequestErrorCode.RecordNotFound]: "replay-does-not-exist", @@ -175,6 +181,10 @@ export const RequestErrorMessage = { [RequestErrorCode.OAuthUUIDNotFound]: "oauth-uuid-not-found", [RequestErrorCode.OAuthClientIDNotFound]: "oauth-client-id-not-found", [RequestErrorCode.OAuthSecretUUIDNotFound]: "oauth-secret-uuid-not-found", + + [RequestErrorCode.CaptchaFailed]: "captcha-failed", + [RequestErrorCode.CaptchaInvalid]: "captcha-invalid", + [RequestErrorCode.CaptchaRequired]: "captcha-required", }; export class ServerRequestError extends Error { diff --git a/packages/flat-server-api/src/login.ts b/packages/flat-server-api/src/login.ts index f764f3a0e21..5db88aea81b 100644 --- a/packages/flat-server-api/src/login.ts +++ b/packages/flat-server-api/src/login.ts @@ -70,14 +70,22 @@ export async function agoraSSOLoginCheck(loginID: string): Promise { - return await postNotAuth("login/phone/sendMessage", { - phone, - }); +export async function loginPhoneSendCode( + phone: string, + captchaVerifyParam?: string, +): Promise { + return await postNotAuth( + "login/phone/sendMessage/captcha", + { + phone, + captchaVerifyParam, + }, + ); } export interface LoginPhonePayload { @@ -143,11 +151,15 @@ export async function registerPhone( }); } -export async function registerPhoneSendCode(phone: string): Promise { +export async function registerPhoneSendCode( + phone: string, + captchaVerifyParam?: string, +): Promise { return await postV2NotAuth( - "register/phone/send-message", + "register/phone/send-message/captcha", { phone, + captchaVerifyParam, }, ); } @@ -231,11 +243,15 @@ export async function resetPwdWithPhone( }); } -export async function resetPhoneSendCode(phone: string): Promise { +export async function resetPhoneSendCode( + phone: string, + captchaVerifyParam?: string, +): Promise { return await postV2NotAuth( - "reset/phone/send-message", + "reset/phone/send-message/captcha", { phone, + captchaVerifyParam, }, ); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a72c9f33e71..c9dfca15360 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,7 +85,7 @@ importers: version: 8.5.0(eslint@8.23.1) eslint-config-react-app: specifier: ^7.0.1 - version: 7.0.1(@babel/plugin-syntax-flow@7.16.7(@babel/core@7.19.1))(@babel/plugin-transform-react-jsx@7.19.0(@babel/core@7.19.1))(eslint@8.23.1)(typescript@4.8.3) + version: 7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.19.1))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.19.1))(eslint@8.23.1)(jest@27.5.1(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)))(typescript@4.8.3) eslint-define-config: specifier: ^1.7.0 version: 1.7.0 @@ -242,7 +242,7 @@ importers: version: 0.1.2(@netless/window-manager@1.0.0-canary.79(white-web-sdk@2.16.52)) '@netless/app-selector': specifier: ^0.0.3 - version: 0.0.3(autoprefixer@9.8.8)(postcss@8.4.28)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) + version: 0.0.3(autoprefixer@10.4.20(postcss@8.5.3))(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) '@netless/app-slide': specifier: 0.3.0-canary.21 version: 0.3.0-canary.21 @@ -1072,7 +1072,7 @@ importers: version: 0.1.2(@netless/window-manager@1.0.0-canary.79(white-web-sdk@2.16.52)) '@netless/app-selector': specifier: ^0.0.3 - version: 0.0.3(autoprefixer@9.8.8)(postcss@8.4.28)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) + version: 0.0.3(autoprefixer@10.4.20(postcss@8.5.3))(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) '@netless/app-slide': specifier: 0.3.0-canary.21 version: 0.3.0-canary.21 @@ -1215,6 +1215,9 @@ importers: mrmime: specifier: ^1.0.1 version: 1.0.1 + vite: + specifier: ^3.2.7 + version: 3.2.7(@types/node@22.13.8)(less@4.1.3)(sass@1.54.8)(terser@5.39.0) vite-plugin-compression: specifier: ^0.5.1 version: 0.5.1(vite@3.2.7(@types/node@22.13.8)(less@4.1.3)(sass@1.54.8)(terser@5.39.0)) @@ -16558,79 +16561,79 @@ snapshots: '@csstools/normalize.css@12.1.1': {} - '@csstools/postcss-cascade-layers@1.1.1(postcss@8.4.28)': + '@csstools/postcss-cascade-layers@1.1.1(postcss@8.5.3)': dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.1.2) - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - '@csstools/postcss-color-function@1.1.1(postcss@8.4.28)': + '@csstools/postcss-color-function@1.1.1(postcss@8.5.3)': dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.28) - postcss: 8.4.28 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-font-format-keywords@1.0.1(postcss@8.4.28)': + '@csstools/postcss-font-format-keywords@1.0.1(postcss@8.5.3)': dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-hwb-function@1.0.2(postcss@8.4.28)': + '@csstools/postcss-hwb-function@1.0.2(postcss@8.5.3)': dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-ic-unit@1.0.1(postcss@8.4.28)': + '@csstools/postcss-ic-unit@1.0.1(postcss@8.5.3)': dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.28) - postcss: 8.4.28 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.4.28)': + '@csstools/postcss-is-pseudo-class@2.0.7(postcss@8.5.3)': dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.1.2) - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - '@csstools/postcss-nested-calc@1.0.0(postcss@8.4.28)': + '@csstools/postcss-nested-calc@1.0.0(postcss@8.5.3)': dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-normalize-display-values@1.0.1(postcss@8.4.28)': + '@csstools/postcss-normalize-display-values@1.0.1(postcss@8.5.3)': dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-oklab-function@1.1.1(postcss@8.4.28)': + '@csstools/postcss-oklab-function@1.1.1(postcss@8.5.3)': dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.28) - postcss: 8.4.28 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.4.28)': + '@csstools/postcss-progressive-custom-properties@1.3.0(postcss@8.5.3)': dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.4.28)': + '@csstools/postcss-stepped-value-functions@1.0.1(postcss@8.5.3)': dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-text-decoration-shorthand@1.0.0(postcss@8.4.28)': + '@csstools/postcss-text-decoration-shorthand@1.0.0(postcss@8.5.3)': dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.4.28)': + '@csstools/postcss-trigonometric-functions@1.0.2(postcss@8.5.3)': dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - '@csstools/postcss-unset-value@1.0.2(postcss@8.4.28)': + '@csstools/postcss-unset-value@1.0.2(postcss@8.5.3)': dependencies: - postcss: 8.4.28 + postcss: 8.5.3 '@csstools/selector-specificity@2.2.0(postcss-selector-parser@6.1.2)': dependencies: @@ -16805,7 +16808,7 @@ snapshots: '@jest/console@27.5.1': dependencies: '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 chalk: 4.1.2 jest-message-util: 27.5.1 jest-util: 27.5.1 @@ -16814,7 +16817,7 @@ snapshots: '@jest/console@28.1.3': dependencies: '@jest/types': 28.1.3 - '@types/node': 22.13.8 + '@types/node': 17.0.45 chalk: 4.1.2 jest-message-util: 28.1.3 jest-util: 28.1.3 @@ -16827,7 +16830,7 @@ snapshots: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.8.1 @@ -16861,14 +16864,14 @@ snapshots: dependencies: '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 jest-mock: 27.5.1 '@jest/fake-timers@27.5.1': dependencies: '@jest/types': 27.5.1 '@sinonjs/fake-timers': 8.1.0 - '@types/node': 22.13.8 + '@types/node': 17.0.45 jest-message-util: 27.5.1 jest-mock: 27.5.1 jest-util: 27.5.1 @@ -16886,7 +16889,7 @@ snapshots: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -16994,7 +16997,7 @@ snapshots: dependencies: '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/yargs': 16.0.9 chalk: 4.1.2 @@ -17003,7 +17006,7 @@ snapshots: '@jest/schemas': 28.1.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -17164,11 +17167,11 @@ snapshots: transitivePeerDependencies: - '@netless/window-manager' - '@netless/app-selector@0.0.3(autoprefixer@9.8.8)(postcss@8.4.28)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3))': + '@netless/app-selector@0.0.3(autoprefixer@10.4.20(postcss@8.5.3))(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3))': dependencies: antd: 4.23.2(react-dom@17.0.2(react@17.0.2))(react@17.0.2) clsx: 1.2.1 - daisyui: 2.24.0(autoprefixer@9.8.8)(postcss@8.4.28)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) + daisyui: 2.24.0(autoprefixer@10.4.20(postcss@8.5.3))(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) dayjs: 1.11.5 preact: 10.10.6 react: 17.0.2 @@ -18624,11 +18627,11 @@ snapshots: '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/braces@3.0.1': {} @@ -18647,11 +18650,11 @@ snapshots: '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.0.6 - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/connect@3.4.38': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/debug@4.1.7': dependencies: @@ -18675,14 +18678,14 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 '@types/express-serve-static-core@5.0.6': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/qs': 6.9.18 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -18717,7 +18720,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/hast@2.3.4': dependencies: @@ -18733,7 +18736,7 @@ snapshots: '@types/http-proxy@1.17.16': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/is-function@1.0.1': {} @@ -18810,7 +18813,7 @@ snapshots: '@types/node-forge@1.3.11': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/node@12.20.24': {} @@ -18821,6 +18824,7 @@ snapshots: '@types/node@22.13.8': dependencies: undici-types: 6.20.0 + optional: true '@types/normalize-package-data@2.4.1': {} @@ -18897,7 +18901,7 @@ snapshots: '@types/resolve@1.17.1': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/responselike@1.0.0': dependencies: @@ -18914,7 +18918,7 @@ snapshots: '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/serve-index@1.9.4': dependencies: @@ -18923,14 +18927,14 @@ snapshots: '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/send': 0.17.4 '@types/shallowequal@1.1.1': {} '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/source-list-map@0.1.2': {} @@ -18970,7 +18974,7 @@ snapshots: '@types/ws@8.5.14': dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 '@types/yargs-parser@21.0.0': {} @@ -19919,14 +19923,14 @@ snapshots: atob@2.1.2: {} - autoprefixer@10.4.20(postcss@8.4.28): + autoprefixer@10.4.20(postcss@8.5.3): dependencies: browserslist: 4.24.4 caniuse-lite: 1.0.30001701 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 autoprefixer@9.8.8: @@ -20688,7 +20692,7 @@ snapshots: caniuse-api@3.0.0: dependencies: - browserslist: 4.21.4 + browserslist: 4.24.4 caniuse-lite: 1.0.30001701 lodash.memoize: 4.1.2 lodash.uniq: 4.5.0 @@ -21360,18 +21364,18 @@ snapshots: transitivePeerDependencies: - encoding - css-blank-pseudo@3.0.3(postcss@8.4.28): + css-blank-pseudo@3.0.3(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - css-declaration-sorter@6.4.1(postcss@8.4.28): + css-declaration-sorter@6.4.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - css-has-pseudo@3.0.4(postcss@8.4.28): + css-has-pseudo@3.0.4(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 css-in-js-utils@2.0.1: @@ -21441,9 +21445,9 @@ snapshots: css-minimizer-webpack-plugin@3.4.1(esbuild@0.15.18)(webpack@5.74.0(esbuild@0.15.18)): dependencies: - cssnano: 5.1.15(postcss@8.4.28) + cssnano: 5.1.15(postcss@8.5.3) jest-worker: 27.5.1 - postcss: 8.4.28 + postcss: 8.5.3 schema-utils: 4.3.0 serialize-javascript: 6.0.2 source-map: 0.6.1 @@ -21451,9 +21455,9 @@ snapshots: optionalDependencies: esbuild: 0.15.18 - css-prefers-color-scheme@6.0.3(postcss@8.4.28): + css-prefers-color-scheme@6.0.3(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 css-select-base-adapter@0.1.1: {} @@ -21503,48 +21507,48 @@ snapshots: cssesc@3.0.0: {} - cssnano-preset-default@5.2.14(postcss@8.4.28): + cssnano-preset-default@5.2.14(postcss@8.5.3): dependencies: - css-declaration-sorter: 6.4.1(postcss@8.4.28) - cssnano-utils: 3.1.0(postcss@8.4.28) - postcss: 8.4.28 - postcss-calc: 8.2.4(postcss@8.4.28) - postcss-colormin: 5.3.1(postcss@8.4.28) - postcss-convert-values: 5.1.3(postcss@8.4.28) - postcss-discard-comments: 5.1.2(postcss@8.4.28) - postcss-discard-duplicates: 5.1.0(postcss@8.4.28) - postcss-discard-empty: 5.1.1(postcss@8.4.28) - postcss-discard-overridden: 5.1.0(postcss@8.4.28) - postcss-merge-longhand: 5.1.7(postcss@8.4.28) - postcss-merge-rules: 5.1.4(postcss@8.4.28) - postcss-minify-font-values: 5.1.0(postcss@8.4.28) - postcss-minify-gradients: 5.1.1(postcss@8.4.28) - postcss-minify-params: 5.1.4(postcss@8.4.28) - postcss-minify-selectors: 5.2.1(postcss@8.4.28) - postcss-normalize-charset: 5.1.0(postcss@8.4.28) - postcss-normalize-display-values: 5.1.0(postcss@8.4.28) - postcss-normalize-positions: 5.1.1(postcss@8.4.28) - postcss-normalize-repeat-style: 5.1.1(postcss@8.4.28) - postcss-normalize-string: 5.1.0(postcss@8.4.28) - postcss-normalize-timing-functions: 5.1.0(postcss@8.4.28) - postcss-normalize-unicode: 5.1.1(postcss@8.4.28) - postcss-normalize-url: 5.1.0(postcss@8.4.28) - postcss-normalize-whitespace: 5.1.1(postcss@8.4.28) - postcss-ordered-values: 5.1.3(postcss@8.4.28) - postcss-reduce-initial: 5.1.2(postcss@8.4.28) - postcss-reduce-transforms: 5.1.0(postcss@8.4.28) - postcss-svgo: 5.1.0(postcss@8.4.28) - postcss-unique-selectors: 5.1.1(postcss@8.4.28) - - cssnano-utils@3.1.0(postcss@8.4.28): + css-declaration-sorter: 6.4.1(postcss@8.5.3) + cssnano-utils: 3.1.0(postcss@8.5.3) + postcss: 8.5.3 + postcss-calc: 8.2.4(postcss@8.5.3) + postcss-colormin: 5.3.1(postcss@8.5.3) + postcss-convert-values: 5.1.3(postcss@8.5.3) + postcss-discard-comments: 5.1.2(postcss@8.5.3) + postcss-discard-duplicates: 5.1.0(postcss@8.5.3) + postcss-discard-empty: 5.1.1(postcss@8.5.3) + postcss-discard-overridden: 5.1.0(postcss@8.5.3) + postcss-merge-longhand: 5.1.7(postcss@8.5.3) + postcss-merge-rules: 5.1.4(postcss@8.5.3) + postcss-minify-font-values: 5.1.0(postcss@8.5.3) + postcss-minify-gradients: 5.1.1(postcss@8.5.3) + postcss-minify-params: 5.1.4(postcss@8.5.3) + postcss-minify-selectors: 5.2.1(postcss@8.5.3) + postcss-normalize-charset: 5.1.0(postcss@8.5.3) + postcss-normalize-display-values: 5.1.0(postcss@8.5.3) + postcss-normalize-positions: 5.1.1(postcss@8.5.3) + postcss-normalize-repeat-style: 5.1.1(postcss@8.5.3) + postcss-normalize-string: 5.1.0(postcss@8.5.3) + postcss-normalize-timing-functions: 5.1.0(postcss@8.5.3) + postcss-normalize-unicode: 5.1.1(postcss@8.5.3) + postcss-normalize-url: 5.1.0(postcss@8.5.3) + postcss-normalize-whitespace: 5.1.1(postcss@8.5.3) + postcss-ordered-values: 5.1.3(postcss@8.5.3) + postcss-reduce-initial: 5.1.2(postcss@8.5.3) + postcss-reduce-transforms: 5.1.0(postcss@8.5.3) + postcss-svgo: 5.1.0(postcss@8.5.3) + postcss-unique-selectors: 5.1.1(postcss@8.5.3) + + cssnano-utils@3.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - cssnano@5.1.15(postcss@8.4.28): + cssnano@5.1.15(postcss@8.5.3): dependencies: - cssnano-preset-default: 5.2.14(postcss@8.4.28) + cssnano-preset-default: 5.2.14(postcss@8.5.3) lilconfig: 2.1.0 - postcss: 8.4.28 + postcss: 8.5.3 yaml: 1.10.2 csso@4.2.0: @@ -21570,14 +21574,14 @@ snapshots: es5-ext: 0.10.61 type: 1.2.0 - daisyui@2.24.0(autoprefixer@9.8.8)(postcss@8.4.28)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)): + daisyui@2.24.0(autoprefixer@10.4.20(postcss@8.5.3))(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)): dependencies: - autoprefixer: 9.8.8 + autoprefixer: 10.4.20(postcss@8.5.3) color: 4.2.3 css-selector-tokenizer: 0.8.0 - postcss: 8.4.28 - postcss-js: 4.0.0(postcss@8.4.28) - tailwindcss: 3.1.8(postcss@8.4.28)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) + postcss: 8.5.3 + postcss-js: 4.0.0(postcss@8.5.3) + tailwindcss: 3.1.8(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) transitivePeerDependencies: - ts-node @@ -22527,33 +22531,6 @@ snapshots: dependencies: eslint: 8.23.1 - eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.16.7(@babel/core@7.19.1))(@babel/plugin-transform-react-jsx@7.19.0(@babel/core@7.19.1))(eslint@8.23.1)(typescript@4.8.3): - dependencies: - '@babel/core': 7.19.1 - '@babel/eslint-parser': 7.17.0(@babel/core@7.19.1)(eslint@8.23.1) - '@rushstack/eslint-patch': 1.1.3 - '@typescript-eslint/eslint-plugin': 5.38.0(@typescript-eslint/parser@5.38.0(eslint@8.23.1)(typescript@4.8.3))(eslint@8.23.1)(typescript@4.8.3) - '@typescript-eslint/parser': 5.38.0(eslint@8.23.1)(typescript@4.8.3) - babel-preset-react-app: 10.0.1 - confusing-browser-globals: 1.0.11 - eslint: 8.23.1 - eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.16.7(@babel/core@7.19.1))(@babel/plugin-transform-react-jsx@7.19.0(@babel/core@7.19.1))(eslint@8.23.1) - eslint-plugin-import: 2.26.0(@typescript-eslint/parser@5.38.0(eslint@8.23.1)(typescript@4.8.3))(eslint@8.23.1) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.38.0(@typescript-eslint/parser@5.38.0(eslint@8.23.1)(typescript@4.8.3))(eslint@8.23.1)(typescript@4.8.3))(eslint@8.23.1)(jest@27.5.1(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)))(typescript@4.8.3) - eslint-plugin-jsx-a11y: 6.6.1(eslint@8.23.1) - eslint-plugin-react: 7.31.8(eslint@8.23.1) - eslint-plugin-react-hooks: 4.5.0(eslint@8.23.1) - eslint-plugin-testing-library: 5.3.1(eslint@8.23.1)(typescript@4.8.3) - optionalDependencies: - typescript: 4.8.3 - transitivePeerDependencies: - - '@babel/plugin-syntax-flow' - - '@babel/plugin-transform-react-jsx' - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - jest - - supports-color - eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.19.1))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.19.1))(eslint@8.23.1)(jest@27.5.1(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)))(typescript@4.8.3): dependencies: '@babel/core': 7.19.1 @@ -22616,14 +22593,6 @@ snapshots: eslint: 8.23.1 ignore: 5.2.0 - eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.16.7(@babel/core@7.19.1))(@babel/plugin-transform-react-jsx@7.19.0(@babel/core@7.19.1))(eslint@8.23.1): - dependencies: - '@babel/plugin-syntax-flow': 7.16.7(@babel/core@7.19.1) - '@babel/plugin-transform-react-jsx': 7.19.0(@babel/core@7.19.1) - eslint: 8.23.1 - lodash: 4.17.21 - string-natural-compare: 3.0.1 - eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.26.0(@babel/core@7.19.1))(@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.19.1))(eslint@8.23.1): dependencies: '@babel/plugin-syntax-flow': 7.26.0(@babel/core@7.19.1) @@ -24885,7 +24854,7 @@ snapshots: '@jest/environment': 27.5.1 '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 @@ -24983,7 +24952,7 @@ snapshots: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 jest-mock: 27.5.1 jest-util: 27.5.1 jsdom: 16.7.0 @@ -24998,7 +24967,7 @@ snapshots: '@jest/environment': 27.5.1 '@jest/fake-timers': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 jest-mock: 27.5.1 jest-util: 27.5.1 @@ -25028,7 +24997,7 @@ snapshots: dependencies: '@jest/types': 27.5.1 '@types/graceful-fs': 4.1.9 - '@types/node': 22.13.8 + '@types/node': 17.0.45 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -25047,7 +25016,7 @@ snapshots: '@jest/source-map': 27.5.1 '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 chalk: 4.1.2 co: 4.6.0 expect: 27.5.1 @@ -25102,7 +25071,7 @@ snapshots: jest-mock@27.5.1: dependencies: '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 jest-pnp-resolver@1.2.3(jest-resolve@27.5.1): optionalDependencies: @@ -25142,7 +25111,7 @@ snapshots: '@jest/test-result': 27.5.1 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 chalk: 4.1.2 emittery: 0.8.1 graceful-fs: 4.2.11 @@ -25198,7 +25167,7 @@ snapshots: jest-serializer@27.5.1: dependencies: - '@types/node': 22.13.8 + '@types/node': 17.0.45 graceful-fs: 4.2.11 jest-snapshot@27.5.1: @@ -25240,7 +25209,7 @@ snapshots: jest-util@27.5.1: dependencies: '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -25249,7 +25218,7 @@ snapshots: jest-util@28.1.3: dependencies: '@jest/types': 28.1.3 - '@types/node': 22.13.8 + '@types/node': 17.0.45 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -25279,7 +25248,7 @@ snapshots: dependencies: '@jest/test-result': 27.5.1 '@jest/types': 27.5.1 - '@types/node': 22.13.8 + '@types/node': 17.0.45 ansi-escapes: 4.3.2 chalk: 4.1.2 jest-util: 27.5.1 @@ -25289,7 +25258,7 @@ snapshots: dependencies: '@jest/test-result': 28.1.3 '@jest/types': 28.1.3 - '@types/node': 22.13.8 + '@types/node': 17.0.45 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.10.2 @@ -26929,137 +26898,137 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-attribute-case-insensitive@5.0.2(postcss@8.4.28): + postcss-attribute-case-insensitive@5.0.2(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-browser-comments@4.0.0(browserslist@4.21.4)(postcss@8.4.28): + postcss-browser-comments@4.0.0(browserslist@4.24.4)(postcss@8.5.3): dependencies: - browserslist: 4.21.4 - postcss: 8.4.28 + browserslist: 4.24.4 + postcss: 8.5.3 - postcss-calc@8.2.4(postcss@8.4.28): + postcss-calc@8.2.4(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - postcss-clamp@4.1.0(postcss@8.4.28): + postcss-clamp@4.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-color-functional-notation@4.2.4(postcss@8.4.28): + postcss-color-functional-notation@4.2.4(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-color-hex-alpha@8.0.4(postcss@8.4.28): + postcss-color-hex-alpha@8.0.4(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-color-rebeccapurple@7.1.1(postcss@8.4.28): + postcss-color-rebeccapurple@7.1.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-colormin@5.3.1(postcss@8.4.28): + postcss-colormin@5.3.1(postcss@8.5.3): dependencies: - browserslist: 4.21.4 + browserslist: 4.24.4 caniuse-api: 3.0.0 colord: 2.9.3 - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-convert-values@5.1.3(postcss@8.4.28): + postcss-convert-values@5.1.3(postcss@8.5.3): dependencies: - browserslist: 4.21.4 - postcss: 8.4.28 + browserslist: 4.24.4 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-custom-media@8.0.2(postcss@8.4.28): + postcss-custom-media@8.0.2(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-custom-properties@12.1.11(postcss@8.4.28): + postcss-custom-properties@12.1.11(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-custom-selectors@6.0.3(postcss@8.4.28): + postcss-custom-selectors@6.0.3(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-dir-pseudo-class@6.0.5(postcss@8.4.28): + postcss-dir-pseudo-class@6.0.5(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-discard-comments@5.1.2(postcss@8.4.28): + postcss-discard-comments@5.1.2(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-discard-duplicates@5.1.0(postcss@8.4.28): + postcss-discard-duplicates@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-discard-empty@5.1.1(postcss@8.4.28): + postcss-discard-empty@5.1.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-discard-overridden@5.1.0(postcss@8.4.28): + postcss-discard-overridden@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-double-position-gradients@3.1.2(postcss@8.4.28): + postcss-double-position-gradients@3.1.2(postcss@8.5.3): dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.28) - postcss: 8.4.28 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-env-function@4.0.6(postcss@8.4.28): + postcss-env-function@4.0.6(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 postcss-flexbugs-fixes@4.2.1: dependencies: postcss: 7.0.39 - postcss-flexbugs-fixes@5.0.2(postcss@8.4.28): + postcss-flexbugs-fixes@5.0.2(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-focus-visible@6.0.4(postcss@8.4.28): + postcss-focus-visible@6.0.4(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-focus-within@5.0.4(postcss@8.4.28): + postcss-focus-within@5.0.4(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-font-variant@5.0.0(postcss@8.4.28): + postcss-font-variant@5.0.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-gap-properties@3.0.5(postcss@8.4.28): + postcss-gap-properties@3.0.5(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-image-set-function@4.0.7(postcss@8.4.28): + postcss-image-set-function@4.0.7(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-import@14.1.0(postcss@8.4.28): + postcss-import@14.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.1 @@ -27071,32 +27040,32 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.10 - postcss-initial@4.0.1(postcss@8.4.28): + postcss-initial@4.0.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-js@4.0.0(postcss@8.4.28): + postcss-js@4.0.0(postcss@8.5.3): dependencies: camelcase-css: 2.0.1 - postcss: 8.4.28 + postcss: 8.5.3 postcss-js@4.0.1(postcss@8.5.3): dependencies: camelcase-css: 2.0.1 postcss: 8.5.3 - postcss-lab-function@4.2.1(postcss@8.4.28): + postcss-lab-function@4.2.1(postcss@8.5.3): dependencies: - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.28) - postcss: 8.4.28 + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-load-config@3.1.4(postcss@8.4.28)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)): + postcss-load-config@3.1.4(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)): dependencies: lilconfig: 2.0.6 yaml: 1.10.2 optionalDependencies: - postcss: 8.4.28 + postcss: 8.5.3 ts-node: 10.9.1(@types/node@22.13.8)(typescript@4.8.3) postcss-load-config@4.0.2(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)): @@ -27117,58 +27086,58 @@ snapshots: semver: 7.3.7 webpack: 4.46.0 - postcss-loader@6.2.1(postcss@8.4.28)(webpack@5.74.0(esbuild@0.15.18)): + postcss-loader@6.2.1(postcss@8.5.3)(webpack@5.74.0(esbuild@0.15.18)): dependencies: cosmiconfig: 7.1.0 klona: 2.0.6 - postcss: 8.4.28 + postcss: 8.5.3 semver: 7.7.1 webpack: 5.74.0(esbuild@0.15.18) - postcss-logical@5.0.4(postcss@8.4.28): + postcss-logical@5.0.4(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-media-minmax@5.0.0(postcss@8.4.28): + postcss-media-minmax@5.0.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-merge-longhand@5.1.7(postcss@8.4.28): + postcss-merge-longhand@5.1.7(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - stylehacks: 5.1.1(postcss@8.4.28) + stylehacks: 5.1.1(postcss@8.5.3) - postcss-merge-rules@5.1.4(postcss@8.4.28): + postcss-merge-rules@5.1.4(postcss@8.5.3): dependencies: - browserslist: 4.21.4 + browserslist: 4.24.4 caniuse-api: 3.0.0 - cssnano-utils: 3.1.0(postcss@8.4.28) - postcss: 8.4.28 + cssnano-utils: 3.1.0(postcss@8.5.3) + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-minify-font-values@5.1.0(postcss@8.4.28): + postcss-minify-font-values@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-minify-gradients@5.1.1(postcss@8.4.28): + postcss-minify-gradients@5.1.1(postcss@8.5.3): dependencies: colord: 2.9.3 - cssnano-utils: 3.1.0(postcss@8.4.28) - postcss: 8.4.28 + cssnano-utils: 3.1.0(postcss@8.5.3) + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-minify-params@5.1.4(postcss@8.4.28): + postcss-minify-params@5.1.4(postcss@8.5.3): dependencies: - browserslist: 4.21.4 - cssnano-utils: 3.1.0(postcss@8.4.28) - postcss: 8.4.28 + browserslist: 4.24.4 + cssnano-utils: 3.1.0(postcss@8.5.3) + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-minify-selectors@5.2.1(postcss@8.4.28): + postcss-minify-selectors@5.2.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 postcss-modules-extract-imports@2.0.0: @@ -27234,9 +27203,9 @@ snapshots: icss-utils: 5.1.0(postcss@8.5.3) postcss: 8.5.3 - postcss-nested@5.0.6(postcss@8.4.28): + postcss-nested@5.0.6(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.0.10 postcss-nested@6.2.0(postcss@8.5.3): @@ -27244,166 +27213,166 @@ snapshots: postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-nesting@10.2.0(postcss@8.4.28): + postcss-nesting@10.2.0(postcss@8.5.3): dependencies: '@csstools/selector-specificity': 2.2.0(postcss-selector-parser@6.1.2) - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-normalize-charset@5.1.0(postcss@8.4.28): + postcss-normalize-charset@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-normalize-display-values@5.1.0(postcss@8.4.28): + postcss-normalize-display-values@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-positions@5.1.1(postcss@8.4.28): + postcss-normalize-positions@5.1.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@5.1.1(postcss@8.4.28): + postcss-normalize-repeat-style@5.1.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-string@5.1.0(postcss@8.4.28): + postcss-normalize-string@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@5.1.0(postcss@8.4.28): + postcss-normalize-timing-functions@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-unicode@5.1.1(postcss@8.4.28): + postcss-normalize-unicode@5.1.1(postcss@8.5.3): dependencies: - browserslist: 4.21.4 - postcss: 8.4.28 + browserslist: 4.24.4 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-url@5.1.0(postcss@8.4.28): + postcss-normalize-url@5.1.0(postcss@8.5.3): dependencies: normalize-url: 6.1.0 - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@5.1.1(postcss@8.4.28): + postcss-normalize-whitespace@5.1.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-normalize@10.0.1(browserslist@4.21.4)(postcss@8.4.28): + postcss-normalize@10.0.1(browserslist@4.24.4)(postcss@8.5.3): dependencies: '@csstools/normalize.css': 12.1.1 - browserslist: 4.21.4 - postcss: 8.4.28 - postcss-browser-comments: 4.0.0(browserslist@4.21.4)(postcss@8.4.28) + browserslist: 4.24.4 + postcss: 8.5.3 + postcss-browser-comments: 4.0.0(browserslist@4.24.4)(postcss@8.5.3) sanitize.css: 13.0.0 - postcss-opacity-percentage@1.1.3(postcss@8.4.28): + postcss-opacity-percentage@1.1.3(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-ordered-values@5.1.3(postcss@8.4.28): + postcss-ordered-values@5.1.3(postcss@8.5.3): dependencies: - cssnano-utils: 3.1.0(postcss@8.4.28) - postcss: 8.4.28 + cssnano-utils: 3.1.0(postcss@8.5.3) + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-overflow-shorthand@3.0.4(postcss@8.4.28): + postcss-overflow-shorthand@3.0.4(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-page-break@3.0.4(postcss@8.4.28): + postcss-page-break@3.0.4(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-place@7.0.5(postcss@8.4.28): + postcss-place@7.0.5(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-preset-env@7.8.3(postcss@8.4.28): - dependencies: - '@csstools/postcss-cascade-layers': 1.1.1(postcss@8.4.28) - '@csstools/postcss-color-function': 1.1.1(postcss@8.4.28) - '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.4.28) - '@csstools/postcss-hwb-function': 1.0.2(postcss@8.4.28) - '@csstools/postcss-ic-unit': 1.0.1(postcss@8.4.28) - '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.4.28) - '@csstools/postcss-nested-calc': 1.0.0(postcss@8.4.28) - '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.4.28) - '@csstools/postcss-oklab-function': 1.1.1(postcss@8.4.28) - '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.4.28) - '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.4.28) - '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.4.28) - '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.4.28) - '@csstools/postcss-unset-value': 1.0.2(postcss@8.4.28) - autoprefixer: 10.4.20(postcss@8.4.28) - browserslist: 4.21.4 - css-blank-pseudo: 3.0.3(postcss@8.4.28) - css-has-pseudo: 3.0.4(postcss@8.4.28) - css-prefers-color-scheme: 6.0.3(postcss@8.4.28) + postcss-preset-env@7.8.3(postcss@8.5.3): + dependencies: + '@csstools/postcss-cascade-layers': 1.1.1(postcss@8.5.3) + '@csstools/postcss-color-function': 1.1.1(postcss@8.5.3) + '@csstools/postcss-font-format-keywords': 1.0.1(postcss@8.5.3) + '@csstools/postcss-hwb-function': 1.0.2(postcss@8.5.3) + '@csstools/postcss-ic-unit': 1.0.1(postcss@8.5.3) + '@csstools/postcss-is-pseudo-class': 2.0.7(postcss@8.5.3) + '@csstools/postcss-nested-calc': 1.0.0(postcss@8.5.3) + '@csstools/postcss-normalize-display-values': 1.0.1(postcss@8.5.3) + '@csstools/postcss-oklab-function': 1.1.1(postcss@8.5.3) + '@csstools/postcss-progressive-custom-properties': 1.3.0(postcss@8.5.3) + '@csstools/postcss-stepped-value-functions': 1.0.1(postcss@8.5.3) + '@csstools/postcss-text-decoration-shorthand': 1.0.0(postcss@8.5.3) + '@csstools/postcss-trigonometric-functions': 1.0.2(postcss@8.5.3) + '@csstools/postcss-unset-value': 1.0.2(postcss@8.5.3) + autoprefixer: 10.4.20(postcss@8.5.3) + browserslist: 4.24.4 + css-blank-pseudo: 3.0.3(postcss@8.5.3) + css-has-pseudo: 3.0.4(postcss@8.5.3) + css-prefers-color-scheme: 6.0.3(postcss@8.5.3) cssdb: 7.11.2 - postcss: 8.4.28 - postcss-attribute-case-insensitive: 5.0.2(postcss@8.4.28) - postcss-clamp: 4.1.0(postcss@8.4.28) - postcss-color-functional-notation: 4.2.4(postcss@8.4.28) - postcss-color-hex-alpha: 8.0.4(postcss@8.4.28) - postcss-color-rebeccapurple: 7.1.1(postcss@8.4.28) - postcss-custom-media: 8.0.2(postcss@8.4.28) - postcss-custom-properties: 12.1.11(postcss@8.4.28) - postcss-custom-selectors: 6.0.3(postcss@8.4.28) - postcss-dir-pseudo-class: 6.0.5(postcss@8.4.28) - postcss-double-position-gradients: 3.1.2(postcss@8.4.28) - postcss-env-function: 4.0.6(postcss@8.4.28) - postcss-focus-visible: 6.0.4(postcss@8.4.28) - postcss-focus-within: 5.0.4(postcss@8.4.28) - postcss-font-variant: 5.0.0(postcss@8.4.28) - postcss-gap-properties: 3.0.5(postcss@8.4.28) - postcss-image-set-function: 4.0.7(postcss@8.4.28) - postcss-initial: 4.0.1(postcss@8.4.28) - postcss-lab-function: 4.2.1(postcss@8.4.28) - postcss-logical: 5.0.4(postcss@8.4.28) - postcss-media-minmax: 5.0.0(postcss@8.4.28) - postcss-nesting: 10.2.0(postcss@8.4.28) - postcss-opacity-percentage: 1.1.3(postcss@8.4.28) - postcss-overflow-shorthand: 3.0.4(postcss@8.4.28) - postcss-page-break: 3.0.4(postcss@8.4.28) - postcss-place: 7.0.5(postcss@8.4.28) - postcss-pseudo-class-any-link: 7.1.6(postcss@8.4.28) - postcss-replace-overflow-wrap: 4.0.0(postcss@8.4.28) - postcss-selector-not: 6.0.1(postcss@8.4.28) + postcss: 8.5.3 + postcss-attribute-case-insensitive: 5.0.2(postcss@8.5.3) + postcss-clamp: 4.1.0(postcss@8.5.3) + postcss-color-functional-notation: 4.2.4(postcss@8.5.3) + postcss-color-hex-alpha: 8.0.4(postcss@8.5.3) + postcss-color-rebeccapurple: 7.1.1(postcss@8.5.3) + postcss-custom-media: 8.0.2(postcss@8.5.3) + postcss-custom-properties: 12.1.11(postcss@8.5.3) + postcss-custom-selectors: 6.0.3(postcss@8.5.3) + postcss-dir-pseudo-class: 6.0.5(postcss@8.5.3) + postcss-double-position-gradients: 3.1.2(postcss@8.5.3) + postcss-env-function: 4.0.6(postcss@8.5.3) + postcss-focus-visible: 6.0.4(postcss@8.5.3) + postcss-focus-within: 5.0.4(postcss@8.5.3) + postcss-font-variant: 5.0.0(postcss@8.5.3) + postcss-gap-properties: 3.0.5(postcss@8.5.3) + postcss-image-set-function: 4.0.7(postcss@8.5.3) + postcss-initial: 4.0.1(postcss@8.5.3) + postcss-lab-function: 4.2.1(postcss@8.5.3) + postcss-logical: 5.0.4(postcss@8.5.3) + postcss-media-minmax: 5.0.0(postcss@8.5.3) + postcss-nesting: 10.2.0(postcss@8.5.3) + postcss-opacity-percentage: 1.1.3(postcss@8.5.3) + postcss-overflow-shorthand: 3.0.4(postcss@8.5.3) + postcss-page-break: 3.0.4(postcss@8.5.3) + postcss-place: 7.0.5(postcss@8.5.3) + postcss-pseudo-class-any-link: 7.1.6(postcss@8.5.3) + postcss-replace-overflow-wrap: 4.0.0(postcss@8.5.3) + postcss-selector-not: 6.0.1(postcss@8.5.3) postcss-value-parser: 4.2.0 - postcss-pseudo-class-any-link@7.1.6(postcss@8.4.28): + postcss-pseudo-class-any-link@7.1.6(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 - postcss-reduce-initial@5.1.2(postcss@8.4.28): + postcss-reduce-initial@5.1.2(postcss@8.5.3): dependencies: - browserslist: 4.21.4 + browserslist: 4.24.4 caniuse-api: 3.0.0 - postcss: 8.4.28 + postcss: 8.5.3 - postcss-reduce-transforms@5.1.0(postcss@8.4.28): + postcss-reduce-transforms@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 - postcss-replace-overflow-wrap@4.0.0(postcss@8.4.28): + postcss-replace-overflow-wrap@4.0.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 - postcss-selector-not@6.0.1(postcss@8.4.28): + postcss-selector-not@6.0.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.0.10: @@ -27421,15 +27390,15 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-svgo@5.1.0(postcss@8.4.28): + postcss-svgo@5.1.0(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-value-parser: 4.2.0 svgo: 2.8.0 - postcss-unique-selectors@5.1.1(postcss@8.4.28): + postcss-unique-selectors@5.1.1(postcss@8.5.3): dependencies: - postcss: 8.4.28 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 postcss-value-parser@4.2.0: {} @@ -27583,7 +27552,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.13.8 + '@types/node': 17.0.45 long: 5.3.1 proxy-addr@2.0.7: @@ -28166,7 +28135,7 @@ snapshots: dependencies: '@babel/code-frame': 7.26.2 address: 1.2.2 - browserslist: 4.21.4 + browserslist: 4.24.4 chalk: 4.1.2 cross-spawn: 7.0.6 detect-port-alt: 1.1.6 @@ -28380,7 +28349,7 @@ snapshots: babel-plugin-named-asset-import: 0.3.8(@babel/core@7.26.9) babel-preset-react-app: 10.1.0 bfj: 7.1.0 - browserslist: 4.21.4 + browserslist: 4.24.4 camelcase: 6.3.0 case-sensitive-paths-webpack-plugin: 2.4.0 css-loader: 6.11.0(webpack@5.74.0(esbuild@0.15.18)) @@ -28398,11 +28367,11 @@ snapshots: jest-resolve: 27.5.1 jest-watch-typeahead: 1.1.0(jest@27.5.1(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3))) mini-css-extract-plugin: 2.9.2(webpack@5.74.0(esbuild@0.15.18)) - postcss: 8.4.28 - postcss-flexbugs-fixes: 5.0.2(postcss@8.4.28) - postcss-loader: 6.2.1(postcss@8.4.28)(webpack@5.74.0(esbuild@0.15.18)) - postcss-normalize: 10.0.1(browserslist@4.21.4)(postcss@8.4.28) - postcss-preset-env: 7.8.3(postcss@8.4.28) + postcss: 8.5.3 + postcss-flexbugs-fixes: 5.0.2(postcss@8.5.3) + postcss-loader: 6.2.1(postcss@8.5.3)(webpack@5.74.0(esbuild@0.15.18)) + postcss-normalize: 10.0.1(browserslist@4.24.4)(postcss@8.5.3) + postcss-preset-env: 7.8.3(postcss@8.5.3) prompts: 2.4.2 react: 17.0.2 react-app-polyfill: 3.0.0 @@ -29935,10 +29904,10 @@ snapshots: style-value-types: 3.2.0 tslib: 1.14.1 - stylehacks@5.1.1(postcss@8.4.28): + stylehacks@5.1.1(postcss@8.5.3): dependencies: - browserslist: 4.21.4 - postcss: 8.4.28 + browserslist: 4.24.4 + postcss: 8.5.3 postcss-selector-parser: 6.1.2 stylis@4.1.1: {} @@ -30039,7 +30008,7 @@ snapshots: tachyons@4.12.0: {} - tailwindcss@3.1.8(postcss@8.4.28)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)): + tailwindcss@3.1.8(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)): dependencies: arg: 5.0.2 chokidar: 3.6.0 @@ -30054,11 +30023,11 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.28 - postcss-import: 14.1.0(postcss@8.4.28) - postcss-js: 4.0.0(postcss@8.4.28) - postcss-load-config: 3.1.4(postcss@8.4.28)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) - postcss-nested: 5.0.6(postcss@8.4.28) + postcss: 8.5.3 + postcss-import: 14.1.0(postcss@8.5.3) + postcss-js: 4.0.0(postcss@8.5.3) + postcss-load-config: 3.1.4(postcss@8.5.3)(ts-node@10.9.1(@types/node@22.13.8)(typescript@4.8.3)) + postcss-nested: 5.0.6(postcss@8.5.3) postcss-selector-parser: 6.0.10 postcss-value-parser: 4.2.0 quick-lru: 5.1.1 @@ -30573,7 +30542,8 @@ snapshots: object.reduce: 1.0.1 undertaker-registry: 1.0.1 - undici-types@6.20.0: {} + undici-types@6.20.0: + optional: true unescape@1.0.1: dependencies: diff --git a/web/flat-web/index.html b/web/flat-web/index.html index 097882708a8..82ef0e0f202 100644 --- a/web/flat-web/index.html +++ b/web/flat-web/index.html @@ -7,10 +7,24 @@ Flat + +
+
diff --git a/web/flat-web/package.json b/web/flat-web/package.json index d8f25273b9c..a942af1e431 100644 --- a/web/flat-web/package.json +++ b/web/flat-web/package.json @@ -71,6 +71,7 @@ "dotenv-expand": "^9.0.0", "eslint-loader": "^4.0.2", "mrmime": "^1.0.1", + "vite": "^3.2.7", "vite-plugin-compression": "^0.5.1" } } diff --git a/web/flat-web/scripts/vite-plugin-html-env.ts b/web/flat-web/scripts/vite-plugin-html-env.ts new file mode 100644 index 00000000000..bfca4d1e1da --- /dev/null +++ b/web/flat-web/scripts/vite-plugin-html-env.ts @@ -0,0 +1,81 @@ +import type { Plugin } from "vite"; +import { configRegion } from "../../../scripts/utils/auto-choose-config"; +import dotenvReal from "dotenv"; +import { expand } from "dotenv-expand"; +import fs from "fs"; +import path from "path"; + +// 使用 require 导入 CommonJS 模块 +const { configPath } = require("../../../scripts/constants"); + +/** + * 替换 HTML 中的 process.env.XXX 为实际值 + * 因为 Vite 的 define 只替换模块代码,不替换 HTML 中的内联脚本 + */ +export function injectHtmlEnv(): Plugin { + return { + name: "flat:html-env", + enforce: "pre", + transformIndexHtml: { + enforce: "pre", + transform(originalHTML) { + const envVars = getEnvVars(); + let html = originalHTML; + + // 替换所有 process.env.XXX 为实际值 + for (const [key, value] of Object.entries(envVars)) { + const regex = new RegExp(`process\\.env\\.${key}`, "g"); + html = html.replace(regex, JSON.stringify(value)); + } + + return { + html, + tags: [], + }; + }, + }, + }; +} + +function getEnvVars(): Record { + const envVars: Record = {}; + const mode = process.env.NODE_ENV === "production" ? "production" : "development"; + const envDir = path.join(configPath, configRegion()); + const envConfigContent = getEnvConfigContent(envDir, mode); + + // 设置 FLAT_REGION + envVars.FLAT_REGION = configRegion(); + + if (envConfigContent) { + const parsed = dotenvReal.parse(envConfigContent); + expand({ parsed }); + const env = { ...parsed }; + + // 从环境变量文件中读取的值 + for (const [key, value] of Object.entries(env)) { + envVars[key] = value; + } + } + + // 如果环境变量文件中有 FLAT_WEB_ALIYUN_PREFIX,使用它;否则使用默认值 + if (!envVars.FLAT_WEB_ALIYUN_PREFIX) { + envVars.FLAT_WEB_ALIYUN_PREFIX = "195gxh"; + } + + return envVars; +} + +function getEnvConfigContent(envDir: string, mode: string): string | null { + const configFileList = [ + path.join(envDir, `.env.${mode}.local`), + path.join(envDir, `.env.${mode}`), + ]; + + for (const filepath of configFileList) { + if (fs.existsSync(filepath) && fs.statSync(filepath).isFile()) { + return fs.readFileSync(filepath, "utf-8"); + } + } + + return null; +} diff --git a/web/flat-web/vite.config.ts b/web/flat-web/vite.config.ts index 498a9a6246d..af5f50decb5 100644 --- a/web/flat-web/vite.config.ts +++ b/web/flat-web/vite.config.ts @@ -3,6 +3,7 @@ import { defineConfig } from "vite"; import { dotenv } from "@netless/flat-vite-plugins/dotenv"; import { reactVirtualized } from "@netless/flat-vite-plugins/react-virtualized"; import { injectHtmlHash } from "./scripts/vite-plugin-html-hash"; +import { injectHtmlEnv } from "./scripts/vite-plugin-html-env"; import { inlineAssets } from "./scripts/vite-plugin-inline-assets"; import { injectGtag } from "./scripts/vite-plugin-html-gtag"; import { generateFavicon } from "./scripts/vite-plugin-favicon"; @@ -29,6 +30,7 @@ export default defineConfig({ plugins: [ reactPlugin, dotenv(autoChooseConfig()), + injectHtmlEnv(), injectGtag(), injectHtmlHash(), inlineAssets(),