Fix TypeScript compilation errors for Koyeb deployment

This commit is contained in:
patdelphi
2025-08-19 17:26:03 +08:00
parent 16661debfc
commit e60e32830a
9 changed files with 120 additions and 23 deletions

View File

@@ -0,0 +1,88 @@
Build ready to start ▶️
>> Cloning github.com/patdelphi/suanming.git commit sha 5c10fe8d3842c2ec55f29cfb9b1e7c2aefff584e into /builder/workspace
Initialized empty Git repository in /builder/workspace/.git/
From https://github.com/patdelphi/suanming
* branch 5c10fe8d3842c2ec55f29cfb9b1e7c2aefff584e -> FETCH_HEAD
HEAD is now at 5c10fe8 修复Koyeb部署问题添加packageManager字段指定pnpm版本
Starting Docker daemon...
Waiting for the Docker daemon to start...
done
Timer: Analyzer started at 2025-08-19T09:02:34Z
Image with name "registry01.prod.koyeb.com/k-8e751168-cf22-413e-ad8f-1dedf498563a/b5220413-de00-4b69-8514-51ef422bdcaa" not found
Timer: Analyzer ran for 258.636887ms and ended at 2025-08-19T09:02:34Z
Timer: Detector started at 2025-08-19T09:02:37Z
3 of 4 buildpacks participating
heroku/nodejs-engine 3.6.5
heroku/nodejs-corepack 3.6.5
heroku/nodejs-pnpm-install 3.6.5
Timer: Detector ran for 115.628657ms and ended at 2025-08-19T09:02:37Z
Timer: Restorer started at 2025-08-19T09:02:38Z
Layer cache not found
Timer: Restorer ran for 194.782532ms and ended at 2025-08-19T09:02:38Z
Timer: Builder started at 2025-08-19T09:02:38Z
## Heroku Node.js Engine
- Checking Node.js version
- Node.js version not specified, using `22.x`
- Resolved Node.js version: `22.15.1`
- Installing Node.js distribution
- Downloading Node.js `22.15.1 (linux-amd64)` from https://nodejs.org/download/release/v22.15.1/node-v22.15.1-linux-x64.tar.gz ... (< 0.1s)
- Verifying checksum
- Extracting Node.js `22.15.1 (linux-amd64)`
- Installing Node.js `22.15.1 (linux-amd64)` ... (< 0.1s)
- Done (finished in 1.4s)
## Heroku Node.js Corepack
- Using Corepack version `0.32.0`
- Found `packageManager` set to `pnpm@9.0.0` in `package.json`
- Enabling Corepack
- Creating Corepack shims
- Executing `corepack enable --install-directory /layers/heroku_nodejs-corepack/shim/bin pnpm`
- Installing `pnpm@9.0.0`
- Creating Corepack package manager
- Running `corepack prepare`
Preparing pnpm@9.0.0...
- Done (0.4s)
- Done (finished in 0.5s)
## Heroku Node.js pnpm Install
- Setting up pnpm dependency store
- Creating new pnpm content-addressable store
- Creating pnpm virtual store
- Installing dependencies
- Running `pnpm install --frozen-lockfile`
ERR_PNPM_OUTDATED_LOCKFILE Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with package.json
Note that in CI environments this setting is true by default. If you still need to run install in such cases, use "pnpm install --no-frozen-lockfile"
Failure reason:
specifiers in the lockfile ({"@hookform/resolvers":"^3.10.0","@radix-ui/react-accordion":"^1.2.2","@radix-ui/react-alert-dialog":"^1.1.4","@radix-ui/react-aspect-ratio":"^1.1.1","@radix-ui/react-avatar":"^1.1.2","@radix-ui/react-checkbox":"^1.1.3","@radix-ui/react-collapsible":"^1.1.2","@radix-ui/react-context-menu":"^2.2.4","@radix-ui/react-dialog":"^1.1.4","@radix-ui/react-dropdown-menu":"^2.1.4","@radix-ui/react-hover-card":"^1.1.4","@radix-ui/react-label":"^2.1.1","@radix-ui/react-menubar":"^1.1.4","@radix-ui/react-navigation-menu":"^1.2.3","@radix-ui/react-popover":"^1.1.4","@radix-ui/react-progress":"^1.1.1","@radix-ui/react-radio-group":"^1.2.2","@radix-ui/react-scroll-area":"^1.2.2","@radix-ui/react-select":"^2.1.4","@radix-ui/react-separator":"^1.1.1","@radix-ui/react-slider":"^1.2.2","@radix-ui/react-slot":"^1.1.1","@radix-ui/react-switch":"^1.1.2","@radix-ui/react-tabs":"^1.1.2","@radix-ui/react-toast":"^1.2.4","@radix-ui/react-toggle":"^1.1.1","@radix-ui/react-toggle-group":"^1.1.1","@radix-ui/react-tooltip":"^1.1.6","@supabase/supabase-js":"^2.55.0","class-variance-authority":"^0.7.1","clsx":"^2.1.1","cmdk":"1.0.0","date-fns":"^3.0.0","embla-carousel-react":"^8.5.2","input-otp":"^1.4.2","lucide-react":"^0.364.0","next-themes":"^0.4.4","react":"^18.3.1","react-day-picker":"8.10.1","react-dom":"^18.3.1","react-hook-form":"^7.54.2","react-resizable-panels":"^2.1.7","react-router-dom":"^6","recharts":"^2.12.4","sonner":"^1.7.2","tailwind-merge":"^2.6.0","tailwindcss-animate":"^1.0.7","vaul":"^1.1.2","zod":"^3.24.1","@eslint/js":"^9.15.0","@types/node":"^22.10.7","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@types/react-router-dom":"^5","@vitejs/plugin-react":"^4.3.4","autoprefixer":"10.4.20","eslint":"^9.15.0","eslint-plugin-react-hooks":"^5.0.0","eslint-plugin-react-refresh":"^0.4.14","globals":"^15.12.0","postcss":"8.4.49","tailwindcss":"v3.4.16","typescript":"~5.6.2","typescript-eslint":"^8.15.0","vite":"^6.0.1","vite-plugin-source-info":"^1.0.0"}) don't match specs in package.json ({"@eslint/js":"^9.15.0","@types/bcryptjs":"^2.4.6","@types/cors":"^2.8.17","@types/express":"^4.17.21","@types/jsonwebtoken":"^9.0.5","@types/node":"^22.10.7","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@types/react-router-dom":"^5","@vitejs/plugin-react":"^4.3.4","autoprefixer":"10.4.20","eslint":"^9.15.0","eslint-plugin-react-hooks":"^5.0.0","eslint-plugin-react-refresh":"^0.4.14","globals":"^15.12.0","postcss":"8.4.49","tailwindcss":"v3.4.16","typescript":"~5.6.2","typescript-eslint":"^8.15.0","vite":"^6.0.1","vite-plugin-source-info":"^1.0.0","@hookform/resolvers":"^3.10.0","@radix-ui/react-accordion":"^1.2.2","@radix-ui/react-alert-dialog":"^1.1.4","@radix-ui/react-aspect-ratio":"^1.1.1","@radix-ui/react-avatar":"^1.1.2","@radix-ui/react-checkbox":"^1.1.3","@radix-ui/react-collapsible":"^1.1.2","@radix-ui/react-context-menu":"^2.2.4","@radix-ui/react-dialog":"^1.1.4","@radix-ui/react-dropdown-menu":"^2.1.4","@radix-ui/react-hover-card":"^1.1.4","@radix-ui/react-label":"^2.1.1","@radix-ui/react-menubar":"^1.1.4","@radix-ui/react-navigation-menu":"^1.2.3","@radix-ui/react-popover":"^1.1.4","@radix-ui/react-progress":"^1.1.1","@radix-ui/react-radio-group":"^1.2.2","@radix-ui/react-scroll-area":"^1.2.2","@radix-ui/react-select":"^2.1.4","@radix-ui/react-separator":"^1.1.1","@radix-ui/react-slider":"^1.2.2","@radix-ui/react-slot":"^1.1.1","@radix-ui/react-switch":"^1.1.2","@radix-ui/react-tabs":"^1.1.2","@radix-ui/react-toast":"^1.2.4","@radix-ui/react-toggle":"^1.1.1","@radix-ui/react-toggle-group":"^1.1.1","@radix-ui/react-tooltip":"^1.1.6","bcryptjs":"^2.4.3","better-sqlite3":"^12.2.0","class-variance-authority":"^0.7.1","clsx":"^2.1.1","cmdk":"1.0.0","concurrently":"^8.2.2","cors":"^2.8.5","date-fns":"^3.0.0","embla-carousel-react":"^8.5.2","express":"^4.18.2","helmet":"^7.1.0","input-otp":"^1.4.2","jsonwebtoken":"^9.0.2","lucide-react":"^0.364.0","next-themes":"^0.4.4","node-fetch":"^2.7.0","nodemon":"^3.0.2","react":"^18.3.1","react-day-picker":"8.10.1","react-dom":"^18.3.1","react-hook-form":"^7.54.2","react-resizable-panels":"^2.1.7","react-router-dom":"^6","recharts":"^2.12.4","sonner":"^1.7.2","tailwind-merge":"^2.6.0","tailwindcss-animate":"^1.0.7","vaul":"^1.1.2","zod":"^3.24.1"})
- Done (0.2s)
- Debug Info:
- Command failed `pnpm install --frozen-lockfile`
exit status: 1
stdout: <see above>
stderr: <see above>
! Failed to install Node modules
!
! The Heroku Node.js pnpm Install buildpack uses the command `pnpm install --frozen-lockfile` to install your Node modules. This command failed and the buildpack cannot continue. This error can occur due to an unstable network connection. See the log output above for more information.
!
! Suggestions:
! - Ensure that this command runs locally without error (exit status = 0).
! - Check the status of the upstream Node module repository service at https://status.npmjs.org/
!
! Use the debug information above to troubleshoot and retry your build.
Timer: Builder ran for 3.429800265s and ended at 2025-08-19T09:02:42Z
ERROR: failed to build: exit status 1
Build failed ❌

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -10,6 +10,8 @@ interface AnalysisResultDisplayProps {
birthDate?: {
date: string;
time: string;
name?: string;
gender?: string;
};
question?: string;
userId?: string;

View File

@@ -188,28 +188,34 @@ const BaziAnalysisDisplay: React.FC<BaziAnalysisDisplayProps> = ({ birthDate })
if (wuxingAnalysis) {
// 构造五行分析数据
const elements = wuxingAnalysis.distribution || {};
const total = Object.values(elements).reduce((sum: number, count: any) => sum + (typeof count === 'number' ? count : 0), 0);
const total = Object.values(elements).reduce((sum: number, count: any) => sum + (typeof count === 'number' ? count : 0), 0) as number;
const wuxingData = {
bazi: baziChart,
wuxingCount: elements,
wuxingPercentage: Object.fromEntries(
Object.entries(elements).map(([key, value]) => [
key,
total > 0 ? Math.round(((value as number) / total) * 100) : 0
])
Object.entries(elements).map(([key, value]) => {
const numValue = typeof value === 'number' ? value : 0;
return [key, total > 0 ? Math.round((numValue / total) * 100) : 0];
})
),
wuxingWithStrength: Object.entries(elements).map(([element, count]) => ({
element,
count: count as number,
percentage: total > 0 ? Math.round(((count as number) / total) * 100) : 0,
strength: (count as number) >= 3 ? '旺' : (count as number) >= 2 ? '中' : '弱'
})),
radarData: Object.entries(elements).map(([element, count]) => ({
element,
value: count as number,
fullMark: 5
})),
wuxingWithStrength: Object.entries(elements).map(([element, count]) => {
const numCount = typeof count === 'number' ? count : 0;
return {
element,
count: numCount,
percentage: total > 0 ? Math.round((numCount / total) * 100) : 0,
strength: numCount >= 3 ? '旺' : numCount >= 2 ? '中' : '弱'
};
}),
radarData: Object.entries(elements).map(([element, count]) => {
const numCount = typeof count === 'number' ? count : 0;
return {
element,
value: numCount,
fullMark: 5
};
}),
balanceAnalysis: wuxingAnalysis.detailed_analysis || '五行分析',
suggestions: [wuxingAnalysis.improvement_suggestions || '建议保持平衡'],
dominantElement: Object.entries(elements).reduce((a, b) => (elements[a[0]] as number) > (elements[b[0]] as number) ? a : b)[0],

View File

@@ -233,20 +233,21 @@ const CompleteBaziAnalysis: React.FC<CompleteBaziAnalysisProps> = ({ birthDate,
if (!analysisData.wuxing_analysis?.element_distribution) return null;
const elements = analysisData.wuxing_analysis.element_distribution;
const total = Object.values(elements).reduce((sum: number, count: any) => sum + (typeof count === 'number' ? count : 0), 0);
const total = Object.values(elements).reduce((sum: number, count: any) => sum + (typeof count === 'number' ? count : 0), 0) as number;
return (
<div className="grid grid-cols-5 gap-4">
{Object.entries(elements).map(([element, count]) => {
const percentage = total > 0 ? Math.round(((count as number) / total) * 100) : 0;
const strength = (count as number) >= 3 ? '旺' : (count as number) >= 2 ? '中' : '弱';
const numCount = typeof count === 'number' ? count : 0;
const percentage = total > 0 ? Math.round((numCount / total) * 100) : 0;
const strength = numCount >= 3 ? '旺' : numCount >= 2 ? '中' : '弱';
return (
<Card key={element} className="text-center hover:shadow-xl transition-all duration-300 chinese-card-decoration border-2 border-yellow-400">
<CardContent className="p-4">
<div className="text-3xl mb-2">{elementSymbols[element]}</div>
<h3 className="font-bold text-red-800 text-lg mb-2 chinese-text-shadow">{element}</h3>
<div className="text-2xl font-bold text-yellow-600 mb-1">{count}</div>
<div className="text-2xl font-bold text-yellow-600 mb-1">{numCount}</div>
<div className="text-sm text-gray-600 mb-2">{percentage}%</div>
<div className={`text-sm font-medium mb-2 ${
strength === '旺' ? 'text-green-600' :

View File

@@ -358,7 +358,7 @@ const AnalysisPage: React.FC = () => {
analysisType={analysisType}
birthDate={memoizedBirthDate}
question={analysisType === 'yijing' ? formData.question : undefined}
userId={user?.id}
userId={user?.id?.toString()}
divinationMethod="time"
/>
)}

View File

@@ -21,7 +21,7 @@ const BaziDetailsPage: React.FC = () => {
const [birthData, setBirthData] = useState<BirthData>({
date: '',
time: '12:00',
name: user?.name || '',
name: '',
gender: 'male'
});
@@ -59,7 +59,7 @@ const BaziDetailsPage: React.FC = () => {
setBirthData({
date: '',
time: '12:00',
name: user?.name || '',
name: '',
gender: 'male'
});
setShowAnalysis(false);