diff --git a/.gitea/workflows/ci-pipeline.yml b/.gitea/workflows/ci-pipeline.yml index 96bb521f6..f544f473c 100755 --- a/.gitea/workflows/ci-pipeline.yml +++ b/.gitea/workflows/ci-pipeline.yml @@ -1100,7 +1100,7 @@ jobs: -e PLAYWRIGHT_HEADLESS=1 \ -w /workspace/apps/web \ git.xiaoxiajianji.com/xiaoxia/base/playwright:v1.45.0-jammy \ - sh -lc "npm ci && npx playwright test --reporter=line --project=chromium e2e/auth.spec.ts e2e/auth-guard.spec.ts e2e/core-upload.spec.ts e2e/core-generation.spec.ts" + sh -lc "npm ci --registry=https://registry.npmmirror.com && npx playwright test --reporter=line --project=chromium e2e/auth.spec.ts e2e/auth-guard.spec.ts e2e/core-upload.spec.ts e2e/core-generation.spec.ts" docker cp apps "$CONTAINER_NAME:/workspace/" docker cp package-lock.json "$CONTAINER_NAME:/workspace/" 2>/dev/null || true docker start -a "$CONTAINER_NAME" @@ -1162,7 +1162,7 @@ jobs: -e E2E_API_BASE=https://staging-api.xiaoxiajianji.com/api/v1 \ -w /workspace/apps/web \ git.xiaoxiajianji.com/xiaoxia/base/playwright:v1.45.0-jammy \ - sh -lc 'npm ci && npx playwright test --reporter=line e2e/test_auth.spec.ts e2e/test_asset.spec.ts e2e/test_project.spec.ts' + sh -lc 'npm ci --registry=https://registry.npmmirror.com && npx playwright test --reporter=line e2e/test_auth.spec.ts e2e/test_asset.spec.ts e2e/test_project.spec.ts' docker cp apps "$CONTAINER_NAME:/workspace/" docker cp package-lock.json "$CONTAINER_NAME:/workspace/" 2>/dev/null || true docker start -a "$CONTAINER_NAME" @@ -1506,7 +1506,7 @@ jobs: -v "$PWD:/workspace" \ -w /workspace/apps/web \ git.xiaoxiajianji.com/xiaoxia/base/playwright:v1.45.0-jammy \ - sh -lc 'npm ci && npx playwright test --reporter=line --project=chromium e2e/auth.spec.ts e2e/auth-guard.spec.ts e2e/core-upload.spec.ts e2e/core-generation.spec.ts e2e/core-titles.spec.ts' + sh -lc 'npm ci --registry=https://registry.npmmirror.com && npx playwright test --reporter=line --project=chromium e2e/auth.spec.ts e2e/auth-guard.spec.ts e2e/core-upload.spec.ts e2e/core-generation.spec.ts e2e/core-titles.spec.ts' - name: Job duration summary if: always() diff --git a/.gitea/workflows/preview-deploy.yml b/.gitea/workflows/preview-deploy.yml index 167a23bed..57c7ded14 100755 --- a/.gitea/workflows/preview-deploy.yml +++ b/.gitea/workflows/preview-deploy.yml @@ -95,12 +95,9 @@ jobs: set -eu cd apps/web - # Config npm mirror for speed - npm config set registry https://registry.npmmirror.com - # Install dependencies with retry for i in 1 2 3; do - npm ci --no-audit --no-fund && break + npm ci --registry=https://registry.npmmirror.com --no-audit --no-fund && break echo "npm install failed, retry $i/3..." [ $i -eq 3 ] && exit 1 rm -rf node_modules @@ -109,12 +106,12 @@ jobs: # TypeScript check echo "=== TypeScript check ===" - npx --no-install tsc --noEmit + ./node_modules/.bin/tsc --noEmit # Vite build echo "=== Vite build ===" export VITE_API_URL=https://staging-api.xiaoxiajianji.com - npx --no-install vite build + ./node_modules/.bin/vite build echo "=== Build completed ===" ls -la dist/ diff --git a/apps/web/package-lock.json b/apps/web/package-lock.json index dbfb18f95..31ff631bd 100644 --- a/apps/web/package-lock.json +++ b/apps/web/package-lock.json @@ -1845,6 +1845,27 @@ "react": "^18 || ^19" } }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmmirror.com/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@testing-library/jest-dom": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", @@ -1914,6 +1935,14 @@ "@testing-library/dom": ">=7.21.4" } }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmmirror.com/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1980,14 +2009,14 @@ "version": "15.7.15", "resolved": "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.15.tgz", "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@types/react": { "version": "18.3.31", "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.3.31.tgz", "integrity": "sha512-vfEqpXTvwT91yhmwdfouStN2hSKwTvyRs8qpLfADyrq/kxDw0hZM7Wk9Ug1FELj8hIby+S/+kQCSRFF32nv2Qw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@types/prop-types": "*", @@ -3081,6 +3110,14 @@ "node": ">=6.0.0" } }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmmirror.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -4417,6 +4454,17 @@ "yallist": "^3.0.2" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -4948,6 +4996,36 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", @@ -5645,6 +5723,14 @@ "react": "^18.3.1" } }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/react-refresh": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", diff --git a/apps/web/src/pages/voices/components/upload-voice-modal/FormFields.tsx b/apps/web/src/pages/voices/components/upload-voice-modal/FormFields.tsx index 42c56322e..e0bf744ae 100755 --- a/apps/web/src/pages/voices/components/upload-voice-modal/FormFields.tsx +++ b/apps/web/src/pages/voices/components/upload-voice-modal/FormFields.tsx @@ -35,7 +35,6 @@ const focusStyle: React.CSSProperties = { boxShadow: "0 0 0 2px var(--primary-soft, rgba(22, 119, 255, 0.12))", } - const FormFields: React.FC = ({ name, desc, diff --git a/infra/docker/web.Dockerfile b/infra/docker/web.Dockerfile index 12fe02505..6465e56fe 100755 --- a/infra/docker/web.Dockerfile +++ b/infra/docker/web.Dockerfile @@ -11,8 +11,7 @@ WORKDIR /app/apps/web # 安装依赖:node_modules写入镜像layer,走ACR缓存保证完整性 # /root/.npm 保留cache mount加速下载(不影响构建正确性) RUN --mount=type=cache,target=/root/.npm,sharing=locked \ - npm config set registry https://registry.npmmirror.com \ - && npm ci + npm ci --registry=https://registry.npmmirror.com # 再拷源码 COPY apps/web/ ./ @@ -21,8 +20,8 @@ COPY apps/web/ ./ # node_modules直接使用镜像中已安装的(layer缓存保证完整性) RUN --mount=type=cache,target=/app/apps/web/.tscache,sharing=locked \ mkdir -p .tscache \ - && npx tsc --incremental --tsBuildInfoFile .tscache/tsconfig.tsbuildinfo \ - && npx vite build + && ./node_modules/.bin/tsc --incremental --tsBuildInfoFile .tscache/tsconfig.tsbuildinfo \ + && ./node_modules/.bin/vite build # Production stage with nginx FROM git.xiaoxiajianji.com/xiaoxia/base/nginx:alpine AS runner diff --git a/scripts/ci/step_frontend_install.sh b/scripts/ci/step_frontend_install.sh index 8d1729b02..630c267f6 100755 --- a/scripts/ci/step_frontend_install.sh +++ b/scripts/ci/step_frontend_install.sh @@ -9,10 +9,7 @@ echo "=== 前端依赖安装开始 (模式: $MODE) ===" cd apps/web -# 配置国内镜像源加速 -npm config set registry https://registry.npmmirror.com - -# 安装依赖 -npm ci --no-audit --no-fund +# 安装依赖(使用国内镜像加速) +npm ci --registry=https://registry.npmmirror.com --no-audit --no-fund echo "=== 前端依赖安装完成 ===" diff --git a/tests/unit/test_wave78_duplication_domain.py b/tests/unit/test_wave78_duplication_domain.py index cf940e4ed..ec1e2d71c 100755 --- a/tests/unit/test_wave78_duplication_domain.py +++ b/tests/unit/test_wave78_duplication_domain.py @@ -462,7 +462,7 @@ class TestQuotaTiers: def test_all_tiers_exist(self): from packages.domain.quota import QUOTA_TIERS - assert set(QUOTA_TIERS.keys()) == {"free", "basic", "premium"} + assert set(QUOTA_TIERS.keys()) == {"free", "basic", "premium", "pro"} # ============================================================ @@ -688,7 +688,7 @@ class TestQuotaRegistry: reg = QuotaRegistry() tiers = reg.list_tiers() - assert set(tiers) == {"free", "basic", "premium"} + assert set(tiers) == {"free", "basic", "premium", "pro"} def test_register_new_dimension(self): from packages.domain.quota import QuotaRegistry