diff --git a/.gitignore b/.gitignore index 3f68c96..768a914 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,8 @@ logs/ # macOS .DS_Store + +# OTHER +.just/ +journalapp.exe +Journal.App/node_modules.old/@rollup/.rollup-win32-x64-msvc-IjiZshxL/rollup.win32-x64-msvc.node diff --git a/Journal.App/package-lock.json b/Journal.App/package-lock.json index cd7af70..c9c5ff0 100644 --- a/Journal.App/package-lock.json +++ b/Journal.App/package-lock.json @@ -906,6 +906,7 @@ "integrity": "sha512-NXsZLvalgI3HrHG6ogoEVzjyV7bSFQNqQeekfU7nNufQFrRyV3EBDfQKEwxx50peu7spZR42JuC1PFhwxuvBrg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", @@ -948,6 +949,7 @@ "integrity": "sha512-Y1Cs7hhTc+a5E9Va/xwKlAJoariQyHY+5zBgCZg4PFWNYQ1nMN9sjK1zhw1gK69DuqVP++sht/1GZg1aRwmAXQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^4.0.1", "debug": "^4.4.1", @@ -1254,6 +1256,7 @@ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1540,6 +1543,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -1686,6 +1690,7 @@ "integrity": "sha512-pRUBr6j6uQDgBi208gHnGRMykw0Rf2Yr1HmLyRucsvcaYgIUxswJkT93WZJflsmezu5s8Lq+q78EoyLv2yaFCg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1765,6 +1770,7 @@ "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1779,6 +1785,7 @@ "integrity": "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", diff --git a/devtool.json b/devtool.json index f3b888a..62106d6 100644 --- a/devtool.json +++ b/devtool.json @@ -245,6 +245,23 @@ "workingDir": ".", "dependsOn": [] } + , + { + "id": "npm-clean", + "label": "Clean Node Modules", + "description": "Remove Journal.App node_modules (kills node/tauri first)", + "group": "System", + "command": "pwsh", + "args": [ + "-NoProfile", + "-ExecutionPolicy", + "Bypass", + "-File", + "scripts/npm-clean.ps1" + ], + "workingDir": ".", + "dependsOn": [] + } ], "env": [ { @@ -298,4 +315,4 @@ "options": [] } ] -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..1a303e4 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "journal", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} diff --git a/scripts/npm-clean.ps1 b/scripts/npm-clean.ps1 new file mode 100644 index 0000000..ce838cd --- /dev/null +++ b/scripts/npm-clean.ps1 @@ -0,0 +1,62 @@ +param( + [switch]$RemoveLockfile, + [switch]$Force +) + +$commonScript = Join-Path $PSScriptRoot "script-common.ps1" +if (-not (Test-Path $commonScript)) { + throw "Missing helper script: $commonScript" +} +. $commonScript + +$repoRoot = Resolve-JournalRepoRoot -StartPath $PSScriptRoot +$appRoot = Resolve-JournalAppRoot -RepoRoot $repoRoot + +Write-Host "Cleaning npm artifacts for Journal.App" -ForegroundColor Cyan +Write-Host "Using app root: $appRoot" -ForegroundColor DarkGray + +$processNames = @("node", "journalapp", "tauri") +Get-Process -ErrorAction SilentlyContinue | + Where-Object { $processNames -contains $_.ProcessName } | + ForEach-Object { + try { + Stop-Process -Id $_.Id -Force -ErrorAction Stop + Write-Host "Stopped process: $($_.ProcessName) ($($_.Id))" -ForegroundColor DarkGray + } + catch { + Write-Warning "Failed to stop process $($_.ProcessName) ($($_.Id)): $($_.Exception.Message)" + } + } + +Push-Location $appRoot +try { + $nodeModulesPath = Join-Path $appRoot "node_modules" + $lockfilePath = Join-Path $appRoot "package-lock.json" + + if (Test-Path $nodeModulesPath) { + if (-not $Force) { + Write-Host "Removing node_modules (use -Force to suppress prompt)..." -ForegroundColor Yellow + } + Remove-Item -Recurse -Force $nodeModulesPath + Write-Host "Removed node_modules." -ForegroundColor Green + } + else { + Write-Host "node_modules not found; nothing to remove." -ForegroundColor DarkGray + } + + if ($RemoveLockfile) { + if (Test-Path $lockfilePath) { + Remove-Item -Force $lockfilePath + Write-Host "Removed package-lock.json." -ForegroundColor Green + } + else { + Write-Host "package-lock.json not found; nothing to remove." -ForegroundColor DarkGray + } + } + else { + Write-Host "Keeping package-lock.json (pass -RemoveLockfile to delete)." -ForegroundColor DarkGray + } +} +finally { + Pop-Location +} diff --git a/scripts/publish-app.ps1 b/scripts/publish-app.ps1 index 0fbd131..7d3a783 100644 --- a/scripts/publish-app.ps1 +++ b/scripts/publish-app.ps1 @@ -40,10 +40,59 @@ if (-not (Get-Command npm -ErrorAction SilentlyContinue)) { } $nodeModulesPath = Join-Path $appRoot "node_modules" +$packageJsonPath = Join-Path $appRoot "package.json" $packageLockPath = Join-Path $appRoot "package-lock.json" +$depsHashPath = Join-Path $appRoot "node_modules\.journal-deps.sha256" + +function Get-JournalNodeDepsHash { + param( + [Parameter(Mandatory = $true)] + [string[]]$Paths + ) + + $hashLines = foreach ($path in $Paths) { + if (-not (Test-Path $path)) { + continue + } + (Get-FileHash -Algorithm SHA256 -Path $path).Hash + } + return ($hashLines -join "`n").Trim() +} + +$hashInputs = @() +if (Test-Path $packageJsonPath) { + $hashInputs += $packageJsonPath +} +if (Test-Path $packageLockPath) { + $hashInputs += $packageLockPath +} +if ($hashInputs.Count -eq 0) { + throw "package.json not found under $appRoot." +} + +$expectedDepsHash = Get-JournalNodeDepsHash -Paths $hashInputs $shouldInstall = $InstallDeps -or (-not (Test-Path $nodeModulesPath)) +$installReason = $null + +if (-not $shouldInstall -and -not $SkipInstall) { + if (-not (Test-Path $depsHashPath)) { + $shouldInstall = $true + $installReason = "dependency hash missing" + } + else { + $currentDepsHash = (Get-Content $depsHashPath -Raw).Trim() + if ($currentDepsHash -ne $expectedDepsHash) { + $shouldInstall = $true + $installReason = "package.json/lockfile changed" + } + } +} + if ($SkipInstall) { $shouldInstall = $false + if ($installReason) { + Write-Host "SkipInstall set; dependencies may be stale ($installReason)." -ForegroundColor Yellow + } } Write-Host "Building Journal.App target '$Target' ($Configuration)..." -ForegroundColor Cyan @@ -59,16 +108,26 @@ try { @("install", "--no-audit", "--fund=false") } + if ($installReason) { + Write-Host "Dependencies changed ($installReason). Installing..." -ForegroundColor Yellow + } + Write-Host "> npm $($installArgs -join ' ')" -ForegroundColor DarkGray if (-not $DryRun) { & npm @installArgs if ($LASTEXITCODE -ne 0) { throw "Dependency install failed with exit code $LASTEXITCODE." } + + $depsDir = Split-Path $depsHashPath -Parent + if (-not (Test-Path $depsDir)) { + New-Item -ItemType Directory -Force -Path $depsDir | Out-Null + } + $expectedDepsHash | Set-Content -Path $depsHashPath -NoNewline } } else { - Write-Host "Skipping dependency install (node_modules already present)." -ForegroundColor DarkGray + Write-Host "Skipping dependency install (node_modules present and deps unchanged)." -ForegroundColor DarkGray } if ($Target -eq "web") {