Compare commits

...

15 Commits

Author SHA1 Message Date
Michel Roegl-Brunner
5d5eba72de fix: detect script changes from remote repository
- Add refetchOnMount and staleTime: 0 to compareScriptContent query to bypass React Query cache
- Add visible refresh button in script detail modal to manually check for updates
- Improve comparison error handling and logging for better debugging
- Display error messages in UI when comparison fails
- Ensure comparison always checks remote repository when modal opens
2025-11-26 08:32:13 +01:00
Michel Roegl-Brunner
577b96518e package-lock.json 2025-11-26 08:19:39 +01:00
Michel Roegl-Brunner
c6c27271d6 Merge pull request #342 from community-scripts/node24_securityfix 2025-11-24 21:34:06 +01:00
ProxmoxVE Developer
72c0246d8c chore(deps): upgrade to Next.js 16, Vitest 4, and Node.js 24
BREAKING CHANGES:
- Upgrade Next.js from 15.1.6 to 16.0.4
- Use Webpack instead of Turbopack for compatibility with server-side modules
- Upgrade Node.js requirement to >=24.0.0

FEATURES:
- Upgrade Vitest to 4.0.13 with improved testing capabilities
- Update all vitest-related packages (@vitest/ui, @vitest/coverage-v8)
- Upgrade react-syntax-highlighter to 16.1.0
- Update node-cron to 4.2.1
- Update lucide-react to 0.554.0

SECURITY:
- Resolve glob command injection vulnerability (CVE) via v10.5.0
- Fix all npm audit vulnerabilities (0 vulnerabilities found)
- Update prisma/client to 6.19.0
- Update all dependencies to latest secure versions

FIXES:
- Configure next.config.js for webpack with proper server-side module handling
- Update tsconfig.json for Next.js 16 compatibility (jsx: react-jsx)
- Add engines field to require Node.js >=24.0.0
- Remove deprecated webpack config in favor of Next.js 16 compatibility
2025-11-24 21:27:38 +01:00
github-actions[bot]
06d4786e0a chore: add VERSION v0.4.13 (#341)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-24 20:08:21 +00:00
CanbiZ
bc31896586 core: remove uv cache clean | remove log rotation (#340)
* core: remove uv cache clean

* Initialize functions on core.func source

Added function initialization call when sourcing core.func
2025-11-24 20:52:31 +01:00
github-actions[bot]
213a606fc0 chore: add VERSION v0.4.12 (#336)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-11-20 17:59:41 +00:00
CanbiZ
3579f2258e Update supported Proxmox VE versions to include 9.1 (#335)
The pve_check function now allows Proxmox VE 9.1 in addition to 9.0 and 8.x. Error messages and comments have been updated to reflect the expanded support.
2025-11-20 18:57:55 +01:00
Michel Roegl-Brunner
5b861ade05 add missing api.func to FUNCTIONS_FILE_PATH 2025-11-18 09:26:39 +01:00
Michel Roegl-Brunner
553eae6ce7 docs: add LXC Backups section to help modal 2025-11-18 09:22:13 +01:00
Michel Roegl-Brunner
c2ca88f033 Merge pull request #328 from community-scripts/dependabot/npm_and_yarn/types/node-24.10.1
build(deps-dev): Bump @types/node from 24.9.1 to 24.10.1
2025-11-18 09:20:49 +01:00
Michel Roegl-Brunner
67d44a6a5f Merge pull request #329 from community-scripts/dependabot/npm_and_yarn/eslint-9.39.1
build(deps-dev): Bump eslint from 9.38.0 to 9.39.1
2025-11-18 09:20:40 +01:00
Michel Roegl-Brunner
fe6cca5c63 Merge pull request #331 from community-scripts/feat/lxc_backups
feat: Add LXC container backup functionality
2025-11-18 09:20:21 +01:00
dependabot[bot]
014e5b69e9 build(deps-dev): Bump eslint from 9.38.0 to 9.39.1
Bumps [eslint](https://github.com/eslint/eslint) from 9.38.0 to 9.39.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.38.0...v9.39.1)

---
updated-dependencies:
- dependency-name: eslint
  dependency-version: 9.39.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-17 19:48:23 +00:00
dependabot[bot]
f37b2cb26f build(deps-dev): Bump @types/node from 24.9.1 to 24.10.1
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.9.1 to 24.10.1.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@types/node"
  dependency-version: 24.10.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-17 19:48:15 +00:00
10 changed files with 1315 additions and 1758 deletions

View File

@@ -1 +1 @@
0.4.11
0.4.13

View File

@@ -43,6 +43,10 @@ const config = {
'http://192.168.*',
],
turbopack: {
// Disable Turbopack and use Webpack instead for compatibility
// This is necessary for server-side code that uses child_process
},
webpack: (config, { dev, isServer }) => {
if (dev && !isServer) {
config.watchOptions = {
@@ -50,12 +54,15 @@ const config = {
aggregateTimeout: 300,
};
}
// Handle server-side modules
if (isServer) {
config.externals = config.externals || [];
if (!config.externals.includes('child_process')) {
config.externals.push('child_process');
}
}
return config;
},
// Ignore ESLint errors during build (they can be fixed separately)
eslint: {
ignoreDuringBuilds: true,
},
// Ignore TypeScript errors during build (they can be fixed separately)
typescript: {
ignoreBuildErrors: true,

2746
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,11 +4,11 @@
"private": true,
"type": "module",
"scripts": {
"build": "next build",
"build": "next build --webpack",
"check": "next lint && tsc --noEmit",
"dev": "next dev",
"dev": "next dev --webpack",
"dev:server": "node server.js",
"dev:next": "next dev",
"dev:next": "next dev --webpack",
"format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
"format:write": "prettier --write \"**/*.{ts,tsx,js,jsx,mdx}\" --cache",
"lint": "next lint",
@@ -22,7 +22,7 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@prisma/client": "^6.18.0",
"@prisma/client": "^6.19.0",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-slot": "^1.2.3",
"@t3-oss/env-nextjs": "^0.13.8",
@@ -43,14 +43,14 @@
"cron-validator": "^1.2.0",
"dotenv": "^17.2.3",
"jsonwebtoken": "^9.0.2",
"lucide-react": "^0.553.0",
"next": "^15.1.6",
"node-cron": "^3.0.3",
"lucide-react": "^0.554.0",
"next": "^16.0.4",
"node-cron": "^4.2.1",
"node-pty": "^1.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-markdown": "^10.1.0",
"react-syntax-highlighter": "^15.6.6",
"react-syntax-highlighter": "^16.1.0",
"refractor": "^5.0.0",
"remark-gfm": "^4.0.1",
"server-only": "^0.0.1",
@@ -69,15 +69,15 @@
"@types/bcryptjs": "^3.0.0",
"@types/better-sqlite3": "^7.6.8",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "^24.9.1",
"@types/node": "^24.10.1",
"@types/node-cron": "^3.0.11",
"@types/react": "^19.2.4",
"@types/react-dom": "^19.2.2",
"@vitejs/plugin-react": "^5.1.0",
"@vitest/coverage-v8": "^3.2.4",
"@vitest/ui": "^3.2.4",
"eslint": "^9.38.0",
"eslint-config-next": "^15.1.6",
"@vitest/coverage-v8": "^4.0.13",
"@vitest/ui": "^4.0.13",
"eslint": "^9.39.1",
"eslint-config-next": "^16.0.4",
"jsdom": "^27.2.0",
"postcss": "^8.5.3",
"prettier": "^3.5.3",
@@ -86,13 +86,16 @@
"tailwindcss": "^4.1.17",
"typescript": "^5.8.2",
"typescript-eslint": "^8.46.2",
"vitest": "^3.2.4"
"vitest": "^4.0.13"
},
"ct3aMetadata": {
"initVersion": "7.39.3"
},
"packageManager": "npm@10.9.3",
"engines": {
"node": ">=24.0.0"
},
"overrides": {
"prismjs": "^1.30.0"
}
}
}

View File

@@ -60,7 +60,7 @@ root_check() {
}
# This function checks the version of Proxmox Virtual Environment (PVE) and exits if the version is not supported.
# Supported: Proxmox VE 8.0.x 8.9.x and 9.0 (NOT 9.1+)
# Supported: Proxmox VE 8.0.x 8.9.x, 9.0 and 9.1
pve_check() {
local PVE_VER
PVE_VER="$(pveversion | awk -F'/' '{print $2}' | awk -F'-' '{print $1}')"
@@ -76,12 +76,12 @@ pve_check() {
return 0
fi
# Check for Proxmox VE 9.x: allow ONLY 9.0
# Check for Proxmox VE 9.x: allow 9.0 and 9.1
if [[ "$PVE_VER" =~ ^9\.([0-9]+) ]]; then
local MINOR="${BASH_REMATCH[1]}"
if ((MINOR != 0)); then
msg_error "This version of Proxmox VE is not yet supported."
msg_error "Supported: Proxmox VE version 9.0"
if ((MINOR < 0 || MINOR > 1)); then
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported: Proxmox VE version 9.0 9.1"
exit 1
fi
return 0
@@ -89,7 +89,7 @@ pve_check() {
# All other unsupported versions
msg_error "This version of Proxmox VE is not supported."
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0"
msg_error "Supported versions: Proxmox VE 8.0 8.x or 9.0 9.1"
exit 1
}
@@ -1323,9 +1323,9 @@ EOF'
msg_ok "Customized LXC Container"
if [ "$var_os" == "alpine" ]; then
FUNCTIONS_FILE_PATH="$(cat "$CORE_DIR/core.func" && echo && cat "$CORE_DIR/tools.func" && echo && cat "$CORE_DIR/alpine-install.func")"
FUNCTIONS_FILE_PATH="$(cat "$CORE_DIR/core.func" && echo && cat "$CORE_DIR/tools.func" && echo && cat "$CORE_DIR/api.func" && echo && cat "$CORE_DIR/alpine-install.func")"
else
FUNCTIONS_FILE_PATH="$(cat "$CORE_DIR/core.func" && echo && cat "$CORE_DIR/tools.func" && echo && cat "$CORE_DIR/install.func")"
FUNCTIONS_FILE_PATH="$(cat "$CORE_DIR/core.func" && echo && cat "$CORE_DIR/tools.func" && echo && cat "$CORE_DIR/api.func" && echo && cat "$CORE_DIR/install.func")"
fi
FUNCTIONS_FILE="/tmp/functions.sh"

View File

@@ -392,8 +392,6 @@ cleanup_lxc() {
# Python pip
if command -v pip &>/dev/null; then $STD pip cache purge || true; fi
# Python uv
if command -v uv &>/dev/null; then $STD uv cache clear || true; fi
# Node.js npm
if command -v npm &>/dev/null; then $STD npm cache clean --force || true; fi
# Node.js yarn
@@ -410,7 +408,6 @@ cleanup_lxc() {
if command -v composer &>/dev/null; then $STD composer clear-cache || true; fi
if command -v journalctl &>/dev/null; then
$STD journalctl --rotate || true
$STD journalctl --vacuum-time=10m || true
fi
msg_ok "Cleaned"

View File

@@ -2,7 +2,7 @@
import { useState } from 'react';
import { Button } from './ui/button';
import { HelpCircle, Server, Settings, RefreshCw, Clock, Package, HardDrive, FolderOpen, Search, Download, Lock, GitBranch } from 'lucide-react';
import { HelpCircle, Server, Settings, RefreshCw, Clock, Package, HardDrive, FolderOpen, Search, Download, Lock, GitBranch, Archive } from 'lucide-react';
import { useRegisterModal } from './modal/ModalStackProvider';
interface HelpModalProps {
@@ -11,7 +11,7 @@ interface HelpModalProps {
initialSection?: string;
}
type HelpSection = 'server-settings' | 'general-settings' | 'auth-settings' | 'sync-button' | 'auto-sync' | 'available-scripts' | 'downloaded-scripts' | 'installed-scripts' | 'lxc-settings' | 'update-system' | 'repositories';
type HelpSection = 'server-settings' | 'general-settings' | 'auth-settings' | 'sync-button' | 'auto-sync' | 'available-scripts' | 'downloaded-scripts' | 'installed-scripts' | 'lxc-settings' | 'update-system' | 'repositories' | 'backups';
export function HelpModal({ isOpen, onClose, initialSection = 'server-settings' }: HelpModalProps) {
useRegisterModal(isOpen, { id: 'help-modal', allowEscape: true, onClose });
@@ -30,6 +30,7 @@ export function HelpModal({ isOpen, onClose, initialSection = 'server-settings'
{ id: 'downloaded-scripts' as HelpSection, label: 'Downloaded Scripts', icon: HardDrive },
{ id: 'installed-scripts' as HelpSection, label: 'Installed Scripts', icon: FolderOpen },
{ id: 'lxc-settings' as HelpSection, label: 'LXC Settings', icon: Settings },
{ id: 'backups' as HelpSection, label: 'LXC Backups', icon: Archive },
{ id: 'update-system' as HelpSection, label: 'Update System', icon: Download },
];
@@ -925,6 +926,144 @@ export function HelpModal({ isOpen, onClose, initialSection = 'server-settings'
</div>
);
case 'backups':
return (
<div className="space-y-6">
<div>
<h3 className="text-xl font-semibold text-foreground mb-4">LXC Backups</h3>
<p className="text-muted-foreground mb-6">
Create backups of your LXC containers before updates or on-demand. Backups are created using Proxmox VE&apos;s built-in backup system and can be stored on any backup-capable storage.
</p>
</div>
<div className="space-y-4">
<div className="p-4 border border-border rounded-lg bg-primary/10 border-primary/20">
<h4 className="font-medium text-foreground mb-2">Overview</h4>
<p className="text-sm text-muted-foreground mb-3">
The backup feature allows you to create snapshots of your LXC containers before performing updates or at any time. Backups are created using the <code className="bg-muted px-1 rounded">vzdump</code> command via SSH and stored on your configured Proxmox storage.
</p>
<ul className="text-sm text-muted-foreground space-y-1">
<li> <strong>Pre-Update Backups:</strong> Automatically create backups before updating containers</li>
<li> <strong>Standalone Backups:</strong> Create backups on-demand from the Actions menu</li>
<li> <strong>Storage Selection:</strong> Choose from available backup-capable storages</li>
<li> <strong>Real-Time Progress:</strong> View backup progress in the terminal output</li>
</ul>
</div>
<div className="p-4 border border-border rounded-lg">
<h4 className="font-medium text-foreground mb-2">Backup Before Update</h4>
<p className="text-sm text-muted-foreground mb-3">
When updating an LXC container, you can choose to create a backup first:
</p>
<ol className="text-sm text-muted-foreground space-y-2 list-decimal list-inside">
<li>Click the &quot;Update&quot; button for an installed script</li>
<li>Confirm that you want to update the container</li>
<li>Choose whether to create a backup before updating</li>
<li>If yes, select a backup-capable storage from the list</li>
<li>The backup will be created, then the update will proceed automatically</li>
</ol>
<div className="mt-3 p-3 bg-info/10 rounded-md">
<h5 className="font-medium text-info-foreground mb-2">Backup Failure Handling</h5>
<p className="text-xs text-info/80">
If a backup fails, you&apos;ll be warned but can still choose to proceed with the update. This ensures updates aren&apos;t blocked by backup issues.
</p>
</div>
</div>
<div className="p-4 border border-border rounded-lg">
<h4 className="font-medium text-foreground mb-2">Standalone Backup</h4>
<p className="text-sm text-muted-foreground mb-3">
Create a backup at any time without updating:
</p>
<ol className="text-sm text-muted-foreground space-y-2 list-decimal list-inside">
<li>Open the Actions dropdown menu for an installed script</li>
<li>Click &quot;Backup&quot;</li>
<li>Select a backup-capable storage from the list</li>
<li>Watch the backup progress in the terminal output</li>
</ol>
<p className="text-xs text-muted-foreground mt-2">
<strong>Note:</strong> Standalone backups are only available for SSH-enabled scripts with valid container IDs.
</p>
</div>
<div className="p-4 border border-border rounded-lg">
<h4 className="font-medium text-foreground mb-2">Storage Selection</h4>
<p className="text-sm text-muted-foreground mb-3">
The system automatically discovers backup-capable storages from your Proxmox servers:
</p>
<ul className="text-sm text-muted-foreground space-y-2">
<li> <strong>Automatic Discovery:</strong> Storages are fetched from <code className="bg-muted px-1 rounded">/etc/pve/storage.cfg</code> on each server</li>
<li> <strong>Backup-Capable Only:</strong> Only storages with &quot;backup&quot; in their content are shown</li>
<li> <strong>Cached Results:</strong> Storage lists are cached for 1 hour to improve performance</li>
<li> <strong>Manual Refresh:</strong> Use the &quot;Fetch Storages&quot; button to refresh the list if needed</li>
</ul>
<div className="mt-3 p-3 bg-muted/30 rounded-md">
<h5 className="font-medium text-foreground mb-1">Storage Types</h5>
<ul className="text-xs text-muted-foreground space-y-1">
<li> <strong>Local:</strong> Backups stored on the Proxmox host</li>
<li> <strong>Storage:</strong> Network-attached storage (NFS, CIFS, etc.)</li>
<li> <strong>PBS:</strong> Proxmox Backup Server storage</li>
</ul>
</div>
</div>
<div className="p-4 border border-border rounded-lg">
<h4 className="font-medium text-foreground mb-2">Viewing Available Storages</h4>
<p className="text-sm text-muted-foreground mb-3">
You can view all storages for a server, including which ones support backups:
</p>
<ol className="text-sm text-muted-foreground space-y-2 list-decimal list-inside">
<li>Go to the Server Settings section</li>
<li>Find the server you want to check</li>
<li>Click the &quot;View Storages&quot; button (database icon)</li>
<li>See all storages with backup-capable ones highlighted</li>
</ol>
<p className="text-xs text-muted-foreground mt-2">
This helps you identify which storages are available for backups before starting a backup operation.
</p>
</div>
<div className="p-4 border border-border rounded-lg">
<h4 className="font-medium text-foreground mb-2">Backup Process</h4>
<p className="text-sm text-muted-foreground mb-3">
When a backup is initiated, the following happens:
</p>
<ul className="text-sm text-muted-foreground space-y-2">
<li> <strong>SSH Connection:</strong> Connects to the Proxmox server via SSH</li>
<li> <strong>Command Execution:</strong> Runs <code className="bg-muted px-1 rounded">vzdump &lt;CTID&gt; --storage &lt;STORAGE&gt; --mode snapshot</code></li>
<li> <strong>Real-Time Output:</strong> Backup progress is streamed to the terminal</li>
<li> <strong>Completion:</strong> Backup completes and shows success/failure status</li>
<li> <strong>Sequential Execution:</strong> If part of update flow, update proceeds after backup completes</li>
</ul>
</div>
<div className="p-4 border border-border rounded-lg bg-warning/10 border-warning/20">
<h4 className="font-medium text-warning-foreground mb-2"> Important Notes</h4>
<ul className="text-sm text-warning/80 space-y-2">
<li> <strong>Storage Requirements:</strong> Ensure you have sufficient storage space for backups</li>
<li> <strong>Backup Duration:</strong> Backup time depends on container size and storage speed</li>
<li> <strong>Snapshot Mode:</strong> Backups use snapshot mode, which requires sufficient disk space</li>
<li> <strong>SSH Access:</strong> Backups require valid SSH credentials configured for the server</li>
<li> <strong>Container State:</strong> Containers can be running or stopped during backup</li>
</ul>
</div>
<div className="p-4 border border-border rounded-lg">
<h4 className="font-medium text-foreground mb-2">Backup Storage Cache</h4>
<p className="text-sm text-muted-foreground mb-3">
Storage information is cached to improve performance:
</p>
<ul className="text-sm text-muted-foreground space-y-1">
<li> <strong>Cache Duration:</strong> Storage lists are cached for 1 hour</li>
<li> <strong>Automatic Refresh:</strong> Cache expires and refreshes automatically</li>
<li> <strong>Manual Refresh:</strong> Use &quot;Fetch Storages&quot; button to force refresh</li>
<li> <strong>Per-Server Cache:</strong> Each server has its own cached storage list</li>
</ul>
</div>
</div>
</div>
);
default:
return null;
}

View File

@@ -61,7 +61,11 @@ export function ScriptDetailModal({
isLoading: comparisonLoading,
} = api.scripts.compareScriptContent.useQuery(
{ slug: script?.slug ?? "" },
{ enabled: !!script && isOpen },
{
enabled: !!script && isOpen,
refetchOnMount: true,
staleTime: 0,
},
);
// Load script mutation
@@ -547,19 +551,60 @@ export function ScriptDetailModal({
</div>
{scriptFilesData?.success &&
(scriptFilesData.ctExists ||
scriptFilesData.installExists) &&
comparisonData?.success &&
!comparisonLoading && (
scriptFilesData.installExists) && (
<div className="flex items-center space-x-2">
<div
className={`h-2 w-2 rounded-full ${comparisonData.hasDifferences ? "bg-warning" : "bg-success"}`}
></div>
<span>
Status:{" "}
{comparisonData.hasDifferences
? "Update available"
: "Up to date"}
</span>
{comparisonData?.success ? (
<>
<div
className={`h-2 w-2 rounded-full ${comparisonData.hasDifferences ? "bg-warning" : "bg-success"}`}
></div>
<span>
Status:{" "}
{comparisonData.hasDifferences
? "Update available"
: "Up to date"}
</span>
</>
) : comparisonLoading ? (
<>
<div className="h-2 w-2 rounded-full bg-muted animate-pulse"></div>
<span>Checking for updates...</span>
</>
) : comparisonData?.error ? (
<>
<div className="h-2 w-2 rounded-full bg-destructive"></div>
<span className="text-destructive">Error: {comparisonData.error}</span>
</>
) : (
<>
<div className="h-2 w-2 rounded-full bg-muted"></div>
<span>Status: Unknown</span>
</>
)}
<button
onClick={() => void refetchComparison()}
disabled={comparisonLoading}
className="ml-2 p-1.5 rounded-md hover:bg-accent transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center"
title="Refresh comparison"
>
{comparisonLoading ? (
<div className="h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent"></div>
) : (
<svg
className="h-4 w-4 text-muted-foreground hover:text-foreground"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"
/>
</svg>
)}
</button>
</div>
)}
</div>

View File

@@ -519,13 +519,16 @@ export class ScriptDownloaderService {
comparisonPromises.push(
this.compareSingleFile(script, scriptPath, `${finalTargetDir}/${fileName}`)
.then(result => {
if (result.error) {
console.error(`[Comparison] Error comparing ${result.filePath}: ${result.error}`);
}
if (result.hasDifferences) {
hasDifferences = true;
differences.push(result.filePath);
}
})
.catch(() => {
// Don't add to differences if there's an error reading files
.catch((error) => {
console.error(`[Comparison] Promise error for ${scriptPath}:`, error);
})
);
}
@@ -541,13 +544,16 @@ export class ScriptDownloaderService {
comparisonPromises.push(
this.compareSingleFile(script, installScriptPath, installScriptPath)
.then(result => {
if (result.error) {
console.error(`[Comparison] Error comparing ${result.filePath}: ${result.error}`);
}
if (result.hasDifferences) {
hasDifferences = true;
differences.push(result.filePath);
}
})
.catch(() => {
// Don't add to differences if there's an error reading files
.catch((error) => {
console.error(`[Comparison] Promise error for ${installScriptPath}:`, error);
})
);
}
@@ -567,13 +573,16 @@ export class ScriptDownloaderService {
comparisonPromises.push(
this.compareSingleFile(script, alpineInstallScriptPath, alpineInstallScriptPath)
.then(result => {
if (result.error) {
console.error(`[Comparison] Error comparing ${result.filePath}: ${result.error}`);
}
if (result.hasDifferences) {
hasDifferences = true;
differences.push(result.filePath);
}
})
.catch(() => {
// Don't add to differences if there's an error reading files
.catch((error) => {
console.error(`[Comparison] Promise error for ${alpineInstallScriptPath}:`, error);
})
);
} catch {
@@ -584,10 +593,11 @@ export class ScriptDownloaderService {
// Wait for all comparisons to complete
await Promise.all(comparisonPromises);
console.log(`[Comparison] Completed comparison for ${script.slug}: hasDifferences=${hasDifferences}, differences=${differences.length}`);
return { hasDifferences, differences };
} catch (error) {
console.error('Error comparing script content:', error);
return { hasDifferences: false, differences: [] };
console.error(`[Comparison] Error comparing script content for ${script.slug}:`, error);
return { hasDifferences: false, differences: [], error: error.message };
}
}
@@ -597,16 +607,21 @@ export class ScriptDownloaderService {
const repoUrl = this.getRepoUrlForScript(script);
const branch = process.env.REPO_BRANCH || 'main';
console.log(`[Comparison] Comparing ${filePath} from ${repoUrl} (branch: ${branch})`);
// Read local content
const localContent = await readFile(localPath, 'utf-8');
console.log(`[Comparison] Local file size: ${localContent.length} bytes`);
// Download remote content from the script's repository
const remoteContent = await this.downloadFileFromGitHub(repoUrl, remotePath, branch);
console.log(`[Comparison] Remote file size: ${remoteContent.length} bytes`);
// Apply modification only for CT scripts, not for other script types
let modifiedRemoteContent;
if (remotePath.startsWith('ct/')) {
modifiedRemoteContent = this.modifyScriptContent(remoteContent);
console.log(`[Comparison] Applied CT script modifications`);
} else {
modifiedRemoteContent = remoteContent; // Don't modify tools or vm scripts
}
@@ -614,10 +629,17 @@ export class ScriptDownloaderService {
// Compare content
const hasDifferences = localContent !== modifiedRemoteContent;
if (hasDifferences) {
console.log(`[Comparison] Differences found in ${filePath}`);
} else {
console.log(`[Comparison] No differences in ${filePath}`);
}
return { hasDifferences, filePath };
} catch (error) {
console.error(`Error comparing file ${filePath}:`, error);
return { hasDifferences: false, filePath };
console.error(`[Comparison] Error comparing file ${filePath}:`, error.message);
// Return error information so it can be handled upstream
return { hasDifferences: false, filePath, error: error.message };
}
}

View File

@@ -22,7 +22,7 @@
"noEmit": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "preserve",
"jsx": "react-jsx",
"plugins": [
{
"name": "next"