diff --git a/.dockerignore b/.dockerignore index a4e242a99..2ceb847c9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -34,6 +34,7 @@ npm-debug.log # exceptions !/bin/copy-dist.ts +!/bin/electron-forge/sign-windows.cjs # temporary exception to make copy-dist inside Docker build not fail # TriliumNextTODO: make copy-dist *not* requiring to copy this file for builds other than electron-forge diff --git a/.github/actions/build-electron/action.yml b/.github/actions/build-electron/action.yml index 51b022bed..6c1b6d819 100644 --- a/.github/actions/build-electron/action.yml +++ b/.github/actions/build-electron/action.yml @@ -8,8 +8,11 @@ inputs: arch: description: "The architecture to build for: x64, arm64" required: true - extension: - description: "Platform specific extensions to copy in the output: dmg, deb, rpm, exe, zip" + shell: + description: "Which shell to use" + required: true + forge_platform: + description: "The --platform to pass to Electron Forge" required: true runs: @@ -38,21 +41,21 @@ runs: - name: Verify certificates if: inputs.os == 'macos' - shell: bash + shell: ${{ inputs.shell }} run: | echo "Available signing identities:" security find-identity -v -p codesigning build.keychain - name: Set up Python and other macOS dependencies if: ${{ inputs.os == 'macos' }} - shell: bash + shell: ${{ inputs.shell }} run: | brew install python-setuptools brew install create-dmg - name: Install dependencies for RPM and Flatpak package building if: ${{ inputs.os == 'linux' }} - shell: bash + shell: ${{ inputs.shell }} run: | sudo apt-get update && sudo apt-get install rpm flatpak-builder elfutils flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo @@ -62,39 +65,32 @@ runs: # Build setup - name: Install dependencies - shell: bash + shell: ${{ inputs.shell }} run: npm ci - name: Update build info - shell: bash + shell: ${{ inputs.shell }} run: npm run chore:update-build-info # Critical debugging configuration - name: Run electron-forge build with enhanced logging - shell: bash + shell: ${{ inputs.shell }} env: # Pass through required environment variables for signing and notarization APPLE_TEAM_ID: ${{ env.APPLE_TEAM_ID }} APPLE_ID: ${{ env.APPLE_ID }} APPLE_ID_PASSWORD: ${{ env.APPLE_ID_PASSWORD }} + WINDOWS_SIGN_EXECUTABLE: ${{ env.WINDOWS_SIGN_EXECUTABLE }} + TRILIUM_ARTIFACT_NAME_HINT: TriliumNextNotes ${{ inputs.os }} ${{ inputs.arch }} run: | - # Map OS names to Electron Forge platform names - if [ "${{ inputs.os }}" = "macos" ]; then - PLATFORM="darwin" - elif [ "${{ inputs.os }}" = "windows" ]; then - PLATFORM="win32" - else - PLATFORM="${{ inputs.os }}" - fi - npm run electron-forge:make -- \ --arch=${{ inputs.arch }} \ - --platform=$PLATFORM + --platform=${{ inputs.forge_platform }} # Add DMG signing step - name: Sign DMG if: inputs.os == 'macos' - shell: bash + shell: ${{ inputs.shell }} run: | echo "Signing DMG file..." dmg_file=$(find ./dist -name "*.dmg" -print -quit) @@ -119,7 +115,7 @@ runs: - name: Verify code signing if: inputs.os == 'macos' - shell: bash + shell: ${{ inputs.shell }} run: | echo "Verifying code signing for all artifacts..." @@ -165,49 +161,3 @@ runs: echo "Found ZIP: $zip_file" echo "Note: ZIP files are not code signed, but their contents should be" fi - - - name: Prepare artifacts - shell: bash - run: | - mkdir -p upload - - if [ "${{ inputs.os }}" = "macos" ]; then - # For macOS, we need to look in specific directories based on the maker - echo "Collecting macOS artifacts..." - - # Look for DMG files recursively - echo "Looking for DMG files..." - dmg_file=$(find ./dist -name "*.dmg" -print -quit) - if [ -n "$dmg_file" ]; then - echo "Found DMG: $dmg_file" - cp "$dmg_file" "upload/TriliumNextNotes-${{ github.ref_name }}-macos-${{ inputs.arch }}.dmg" - else - echo "Warning: No DMG file found" - fi - - # Look for ZIP files recursively - echo "Looking for ZIP files..." - zip_file=$(find ./dist -name "*.zip" -print -quit) - if [ -n "$zip_file" ]; then - echo "Found ZIP: $zip_file" - cp "$zip_file" "upload/TriliumNextNotes-${{ github.ref_name }}-macos-${{ inputs.arch }}.zip" - else - echo "Warning: No ZIP file found" - fi - else - # For other platforms, use the existing logic but with better error handling - echo "Collecting artifacts for ${{ inputs.os }}..." - for ext in ${{ inputs.extension }}; do - echo "Looking for .$ext files..." - file=$(find ./dist -name "*.$ext" -print -quit) - if [ -n "$file" ]; then - echo "Found $file for extension $ext" - cp "$file" "upload/TriliumNextNotes-${{ github.ref_name }}-${{ inputs.os }}-${{ inputs.arch }}.$ext" - else - echo "Warning: No file found with extension .$ext" - fi - done - fi - - echo "Final contents of upload directory:" - ls -la upload/ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 1acdf4709..000000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Main -on: - push: - branches: - - "feature/update**" - - "feature/server_esm**" - paths-ignore: - - "docs/**" - - ".github/workflows/main-docker.yml" - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - make-electron: - name: Make Electron - strategy: - fail-fast: false - matrix: - arch: [x64, arm64] - os: - - name: macos - image: macos-latest - extension: [dmg, zip] - - name: linux - image: ubuntu-latest - extension: [deb, rpm, zip, flatpak] - - name: windows - image: windows-latest - extension: [exe, zip] - runs-on: ${{ matrix.os.image }} - steps: - - uses: actions/checkout@v4 - - name: Set up node & dependencies - uses: actions/setup-node@v4 - with: - node-version: 20 - - name: Run the build - uses: ./.github/actions/build-electron - with: - os: ${{ matrix.os.name }} - arch: ${{ matrix.arch }} - extension: ${{ matrix.os.extension }} - env: - APPLE_APP_CERTIFICATE_BASE64: ${{ secrets.APPLE_APP_CERTIFICATE_BASE64 }} - APPLE_APP_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_APP_CERTIFICATE_PASSWORD }} - APPLE_INSTALLER_CERTIFICATE_BASE64: ${{ secrets.APPLE_INSTALLER_CERTIFICATE_BASE64 }} - APPLE_INSTALLER_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_INSTALLER_CERTIFICATE_PASSWORD }} - APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} - - # Clean up keychain after build - - name: Clean up keychain - if: matrix.os.name == 'macos' && always() - run: | - security delete-keychain build.keychain - - - name: Publish artifacts - uses: actions/upload-artifact@v4 - with: - name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}.zip - path: upload/*.zip - - name: Publish installer artifacts - uses: actions/upload-artifact@v4 - with: - name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }}.${{matrix.os.extension}} - path: upload/*.${{ matrix.os.extension }} - - build_linux_server: - name: Build Linux Server - strategy: - fail-fast: false - matrix: - arch: [x64, arm64] - include: - - arch: x64 - runs-on: ubuntu-latest - - arch: arm64 - runs-on: ubuntu-24.04-arm - runs-on: ${{ matrix.runs-on }} - steps: - - uses: actions/checkout@v4 - - name: Run the build - uses: ./.github/actions/build-server - with: - arch: ${{ matrix.arch }} - - uses: actions/upload-artifact@v4 - with: - name: TriliumNextNotes linux server ${{ matrix.arch }} - path: upload/TriliumNextNotes-linux-${{ matrix.arch }}-${{ github.ref_name }}.tar.xz diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 184f69c93..d3f051b68 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -26,13 +26,16 @@ jobs: os: - name: macos image: macos-latest - extension: [dmg, zip] + shell: bash + forge_platform: darwin - name: linux image: ubuntu-latest - extension: [deb, rpm, zip, flatpak] + shell: bash + forge_platform: linux - name: windows - image: windows-latest - extension: [exe, zip] + image: win-signing + shell: cmd + forge_platform: win32 runs-on: ${{ matrix.os.image }} steps: - uses: actions/checkout@v4 @@ -41,7 +44,6 @@ jobs: with: node-version: 20 - name: Install dependencies - shell: bash run: npm ci - name: Update nightly version run: npm run chore:ci-update-nightly-version @@ -50,7 +52,8 @@ jobs: with: os: ${{ matrix.os.name }} arch: ${{ matrix.arch }} - extension: ${{ join(matrix.os.extension, ' ') }} + shell: ${{ matrix.os.shell }} + forge_platform: ${{ matrix.os.forge_platform }} env: APPLE_APP_CERTIFICATE_BASE64: ${{ secrets.APPLE_APP_CERTIFICATE_BASE64 }} APPLE_APP_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_APP_CERTIFICATE_PASSWORD }} @@ -59,6 +62,7 @@ jobs: APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} + WINDOWS_SIGN_EXECUTABLE: ${{ vars.WINDOWS_SIGN_EXECUTABLE }} - name: Publish release uses: softprops/action-gh-release@v2 @@ -72,35 +76,9 @@ jobs: tag_name: nightly name: Nightly Build - nightly-server: - name: Deploy server nightly - strategy: - fail-fast: false - matrix: - arch: [x64, arm64] - include: - - arch: x64 - runs-on: ubuntu-latest - - arch: arm64 - runs-on: ubuntu-24.04-arm - runs-on: ${{ matrix.runs-on }} - steps: - - uses: actions/checkout@v4 - - - name: Run the build - uses: ./.github/actions/build-server + - name: Publish artifacts + uses: actions/upload-artifact@v4 + if: ${{ github.event_name == 'pull_request' }} with: - os: linux - arch: ${{ matrix.arch }} - - - name: Publish release - uses: softprops/action-gh-release@v2 - if: ${{ github.event_name != 'pull_request' }} - with: - make_latest: false - prerelease: true - draft: false - fail_on_unmatched_files: true - files: upload/*.* - tag_name: nightly - name: Nightly Build + name: TriliumNextNotes ${{ matrix.os.name }} ${{ matrix.arch }} + path: upload diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dc523893b..4f791bda0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,13 +20,16 @@ jobs: os: - name: macos image: macos-latest - extension: [dmg, zip] + shell: bash + forge_platform: darwin - name: linux image: ubuntu-latest - extension: [deb, rpm, zip, flatpak] + shell: bash + forge_platform: linux - name: windows - image: windows-latest - extension: [exe, zip] + image: win-signing + shell: cmd + forge_platform: win32 runs-on: ${{ matrix.os.image }} steps: - uses: actions/checkout@v4 @@ -39,7 +42,8 @@ jobs: with: os: ${{ matrix.os.name }} arch: ${{ matrix.arch }} - extension: ${{ join(matrix.os.extension, ' ') }} + shell: ${{ matrix.os.shell }} + forge_platform: ${{ matrix.os.forge_platform }} env: APPLE_APP_CERTIFICATE_BASE64: ${{ secrets.APPLE_APP_CERTIFICATE_BASE64 }} APPLE_APP_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_APP_CERTIFICATE_PASSWORD }} @@ -48,6 +52,7 @@ jobs: APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} + WINDOWS_SIGN_EXECUTABLE: ${{ vars.WINDOWS_SIGN_EXECUTABLE }} - name: Publish release uses: softprops/action-gh-release@v2 diff --git a/bin/copy-dist.ts b/bin/copy-dist.ts index 2c071142c..eaa79808e 100644 --- a/bin/copy-dist.ts +++ b/bin/copy-dist.ts @@ -21,6 +21,7 @@ function copyNodeModuleFileOrFolder(source: string) { try { const assetsToCopy = new Set([ + "./node_modules", "./images", "./libraries", "./translations", @@ -33,6 +34,7 @@ try { "./forge.config.cjs", "./bin/tpl/", "./bin/electron-forge/desktop.ejs", + "./bin/electron-forge/sign-windows.cjs", "./src/views/", "./src/etapi/etapi.openapi.yaml", "./src/routes/api/openapi.json", diff --git a/bin/electron-forge/sign-windows.cjs b/bin/electron-forge/sign-windows.cjs new file mode 100644 index 000000000..527a27dc6 --- /dev/null +++ b/bin/electron-forge/sign-windows.cjs @@ -0,0 +1,14 @@ +const child_process = require("child_process"); + +module.exports = function (filePath) { + const { WINDOWS_SIGN_EXECUTABLE } = process.env; + + if (!WINDOWS_SIGN_EXECUTABLE) { + console.warn("[Sign] Skip signing due to missing environment variable."); + return; + } + + const command = `${WINDOWS_SIGN_EXECUTABLE} --executable "${filePath}"`; + console.log(`[Sign] ${command}`); + child_process.execSync(command); +} \ No newline at end of file diff --git a/forge.config.cjs b/forge.config.cjs index dabcd7ca4..ba3d8c3ff 100644 --- a/forge.config.cjs +++ b/forge.config.cjs @@ -2,13 +2,17 @@ const path = require("path"); const fs = require("fs-extra"); const APP_NAME = "TriliumNext Notes"; +const BIN_PATH = path.normalize("./bin/electron-forge"); const extraResourcesForPlatform = getExtraResourcesForPlatform(); const baseLinuxMakerConfigOptions = { icon: "./images/app-icons/png/128x128.png", - desktopTemplate: path.resolve("./bin/electron-forge/desktop.ejs"), + desktopTemplate: path.resolve(path.join(BIN_PATH, "desktop.ejs")), categories: ["Office", "Utility"] }; +const windowsSignConfiguration = process.env.WINDOWS_SIGN_EXECUTABLE ? { + hookModulePath: path.join(BIN_PATH, "sign-windows.cjs") +} : undefined; module.exports = { // we run electron-forge inside the ./build folder, @@ -26,6 +30,7 @@ module.exports = { appleIdPassword: process.env.APPLE_ID_PASSWORD, teamId: process.env.APPLE_TEAM_ID }, + windowsSign: windowsSignConfiguration, extraResource: [ // All resources should stay in Resources directory for macOS ...(process.platform === "darwin" ? [] : extraResourcesForPlatform), @@ -105,7 +110,8 @@ module.exports = { config: { iconUrl: "https://raw.githubusercontent.com/TriliumNext/Notes/develop/images/app-icons/icon.ico", setupIcon: "./images/app-icons/win/setup.ico", - loadingGif: "./images/app-icons/win/setup-banner.gif" + loadingGif: "./images/app-icons/win/setup-banner.gif", + windowsSign: windowsSignConfiguration } }, { @@ -129,7 +135,33 @@ module.exports = { name: "@electron-forge/plugin-auto-unpack-natives", config: {} } - ] + ], + hooks: { + postMake(_, makeResults) { + const outputDir = path.join(__dirname, "..", "upload"); + fs.mkdirp(outputDir); + for (const makeResult of makeResults) { + for (const artifactPath of makeResult.artifacts) { + // Ignore certain artifacts. + let fileName = path.basename(artifactPath); + const extension = path.extname(fileName); + if (fileName === "RELEASES" || extension === ".nupkg") { + continue; + } + + // Override the extension for the CI. + const { TRILIUM_ARTIFACT_NAME_HINT } = process.env; + if (TRILIUM_ARTIFACT_NAME_HINT) { + fileName = TRILIUM_ARTIFACT_NAME_HINT + extension; + } + + const outputPath = path.join(outputDir, fileName); + console.log(`[Artifact] ${artifactPath} -> ${outputPath}`); + fs.copyFile(artifactPath, outputPath); + } + } + } + } }; function getExtraResourcesForPlatform() { diff --git a/package-lock.json b/package-lock.json index dbd375048..de26d7dd2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -142,8 +142,8 @@ "@types/leaflet-gpx": "1.3.7", "@types/mime-types": "2.1.4", "@types/multer": "1.4.12", - "@types/node": "22.13.11", - "@types/react": "18.3.19", + "@types/node": "22.13.13", + "@types/react": "18.3.20", "@types/react-dom": "18.3.5", "@types/safe-compare": "1.1.2", "@types/sanitize-html": "2.13.0", @@ -152,7 +152,7 @@ "@types/session-file-store": "1.2.5", "@types/source-map-support": "0.5.10", "@types/stream-throttle": "0.1.4", - "@types/supertest": "6.0.2", + "@types/supertest": "6.0.3", "@types/swagger-ui-express": "4.1.8", "@types/tmp": "0.2.6", "@types/turndown": "5.0.5", @@ -192,7 +192,7 @@ "tsx": "4.19.3", "typedoc": "0.28.1", "typescript": "5.8.2", - "typescript-eslint": "8.27.0", + "typescript-eslint": "8.28.0", "vitest": "3.0.9", "webpack": "5.98.0", "webpack-cli": "6.0.1", @@ -5926,9 +5926,9 @@ } }, "node_modules/@types/node": { - "version": "22.13.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.11.tgz", - "integrity": "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==", + "version": "22.13.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.13.tgz", + "integrity": "sha512-ClsL5nMwKaBRwPcCvH8E7+nU4GxHVx1axNvMZTFHMEfNI7oahimt26P5zjVCRrjiIWj6YFXfE1v3dEp94wLcGQ==", "license": "MIT", "dependencies": { "undici-types": "~6.20.0" @@ -5956,9 +5956,9 @@ "license": "MIT" }, "node_modules/@types/react": { - "version": "18.3.19", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.19.tgz", - "integrity": "sha512-fcdJqaHOMDbiAwJnXv6XCzX0jDW77yI3tJqYh1Byn8EL5/S628WRx9b/y3DnNe55zTukUQKrfYxiZls2dHcUMw==", + "version": "18.3.20", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.20.tgz", + "integrity": "sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6107,9 +6107,9 @@ } }, "node_modules/@types/supertest": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz", - "integrity": "sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.3.tgz", + "integrity": "sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==", "dev": true, "license": "MIT", "dependencies": { @@ -6211,17 +6211,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.27.0.tgz", - "integrity": "sha512-4henw4zkePi5p252c8ncBLzLce52SEUz2Ebj8faDnuUXz2UuHEONYcJ+G0oaCF+bYCWVZtrGzq3FD7YXetmnSA==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.28.0.tgz", + "integrity": "sha512-lvFK3TCGAHsItNdWZ/1FkvpzCxTHUVuFrdnOGLMa0GGCFIbCgQWVk3CzCGdA7kM3qGVc+dfW9tr0Z/sHnGDFyg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.27.0", - "@typescript-eslint/type-utils": "8.27.0", - "@typescript-eslint/utils": "8.27.0", - "@typescript-eslint/visitor-keys": "8.27.0", + "@typescript-eslint/scope-manager": "8.28.0", + "@typescript-eslint/type-utils": "8.28.0", + "@typescript-eslint/utils": "8.28.0", + "@typescript-eslint/visitor-keys": "8.28.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -6241,16 +6241,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.27.0.tgz", - "integrity": "sha512-XGwIabPallYipmcOk45DpsBSgLC64A0yvdAkrwEzwZ2viqGqRUJ8eEYoPz0CWnutgAFbNMPdsGGvzjSmcWVlEA==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.28.0.tgz", + "integrity": "sha512-LPcw1yHD3ToaDEoljFEfQ9j2xShY367h7FZ1sq5NJT9I3yj4LHer1Xd1yRSOdYy9BpsrxU7R+eoDokChYM53lQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.27.0", - "@typescript-eslint/types": "8.27.0", - "@typescript-eslint/typescript-estree": "8.27.0", - "@typescript-eslint/visitor-keys": "8.27.0", + "@typescript-eslint/scope-manager": "8.28.0", + "@typescript-eslint/types": "8.28.0", + "@typescript-eslint/typescript-estree": "8.28.0", + "@typescript-eslint/visitor-keys": "8.28.0", "debug": "^4.3.4" }, "engines": { @@ -6266,14 +6266,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.27.0.tgz", - "integrity": "sha512-8oI9GwPMQmBryaaxG1tOZdxXVeMDte6NyJA4i7/TWa4fBwgnAXYlIQP+uYOeqAaLJ2JRxlG9CAyL+C+YE9Xknw==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.28.0.tgz", + "integrity": "sha512-u2oITX3BJwzWCapoZ/pXw6BCOl8rJP4Ij/3wPoGvY8XwvXflOzd1kLrDUUUAIEdJSFh+ASwdTHqtan9xSg8buw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.27.0", - "@typescript-eslint/visitor-keys": "8.27.0" + "@typescript-eslint/types": "8.28.0", + "@typescript-eslint/visitor-keys": "8.28.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6284,14 +6284,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.27.0.tgz", - "integrity": "sha512-wVArTVcz1oJOIEJxui/nRhV0TXzD/zMSOYi/ggCfNq78EIszddXcJb7r4RCp/oBrjt8n9A0BSxRMKxHftpDxDA==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.28.0.tgz", + "integrity": "sha512-oRoXu2v0Rsy/VoOGhtWrOKDiIehvI+YNrDk5Oqj40Mwm0Yt01FC/Q7nFqg088d3yAsR1ZcZFVfPCTTFCe/KPwg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.27.0", - "@typescript-eslint/utils": "8.27.0", + "@typescript-eslint/typescript-estree": "8.28.0", + "@typescript-eslint/utils": "8.28.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.1" }, @@ -6308,9 +6308,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.27.0.tgz", - "integrity": "sha512-/6cp9yL72yUHAYq9g6DsAU+vVfvQmd1a8KyA81uvfDE21O2DwQ/qxlM4AR8TSdAu+kJLBDrEHKC5/W2/nxsY0A==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.28.0.tgz", + "integrity": "sha512-bn4WS1bkKEjx7HqiwG2JNB3YJdC1q6Ue7GyGlwPHyt0TnVq6TtD/hiOdTZt71sq0s7UzqBFXD8t8o2e63tXgwA==", "dev": true, "license": "MIT", "engines": { @@ -6322,14 +6322,14 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.27.0.tgz", - "integrity": "sha512-BnKq8cqPVoMw71O38a1tEb6iebEgGA80icSxW7g+kndx0o6ot6696HjG7NdgfuAVmVEtwXUr3L8R9ZuVjoQL6A==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.28.0.tgz", + "integrity": "sha512-H74nHEeBGeklctAVUvmDkxB1mk+PAZ9FiOMPFncdqeRBXxk1lWSYraHw8V12b7aa6Sg9HOBNbGdSHobBPuQSuA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.27.0", - "@typescript-eslint/visitor-keys": "8.27.0", + "@typescript-eslint/types": "8.28.0", + "@typescript-eslint/visitor-keys": "8.28.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -6375,16 +6375,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.27.0.tgz", - "integrity": "sha512-njkodcwH1yvmo31YWgRHNb/x1Xhhq4/m81PhtvmRngD8iHPehxffz1SNCO+kwaePhATC+kOa/ggmvPoPza5i0Q==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.28.0.tgz", + "integrity": "sha512-OELa9hbTYciYITqgurT1u/SzpQVtDLmQMFzy/N8pQE+tefOyCWT79jHsav294aTqV1q1u+VzqDGbuujvRYaeSQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.27.0", - "@typescript-eslint/types": "8.27.0", - "@typescript-eslint/typescript-estree": "8.27.0" + "@typescript-eslint/scope-manager": "8.28.0", + "@typescript-eslint/types": "8.28.0", + "@typescript-eslint/typescript-estree": "8.28.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -6399,13 +6399,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.27.0.tgz", - "integrity": "sha512-WsXQwMkILJvffP6z4U3FYJPlbf/j07HIxmDjZpbNvBJkMfvwXj5ACRkkHwBDvLBbDbtX5TdU64/rcvKJ/vuInQ==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.28.0.tgz", + "integrity": "sha512-hbn8SZ8w4u2pRwgQ1GlUrPKE+t2XvcCW5tTRF7j6SMYIuYG37XuzIW44JCZPa36evi0Oy2SnM664BlIaAuQcvg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.27.0", + "@typescript-eslint/types": "8.28.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -20682,15 +20682,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.27.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.27.0.tgz", - "integrity": "sha512-ZZ/8+Y0rRUMuW1gJaPtLWe4ryHbsPLzzibk5Sq+IFa2aOH1Vo0gPr1fbA6pOnzBke7zC2Da4w8AyCgxKXo3lqA==", + "version": "8.28.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.28.0.tgz", + "integrity": "sha512-jfZtxJoHm59bvoCMYCe2BM0/baMswRhMmYhy+w6VfcyHrjxZ0OJe0tGasydCpIpA+A/WIJhTyZfb3EtwNC/kHQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.27.0", - "@typescript-eslint/parser": "8.27.0", - "@typescript-eslint/utils": "8.27.0" + "@typescript-eslint/eslint-plugin": "8.28.0", + "@typescript-eslint/parser": "8.28.0", + "@typescript-eslint/utils": "8.28.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" diff --git a/package.json b/package.json index ec3db7f27..19c46f806 100644 --- a/package.json +++ b/package.json @@ -38,9 +38,9 @@ "electron:switch": "electron-rebuild", "docs:edit": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data-docs TRILIUM_ENV=dev TRILIUM_PORT=37741 electron ./electron-docs-main.ts .", "docs:edit-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data-docs TRILIUM_PORT=37741 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-docs-main.ts .\"", - "electron-forge:prepare": "npm run build:prepare-dist && cp -r node_modules ./build", + "electron-forge:prepare": "npm run build:prepare-dist", "electron-forge:start": "npm run electron-forge:prepare && cd ./build && electron-forge start", - "electron-forge:make": "npm run electron-forge:prepare && cd ./build && electron-forge make", + "electron-forge:make": "npm run electron-forge:prepare && cross-env DEBUG=electron-windows-installer:* electron-forge make ./build", "electron-forge:package": "npm run electron-forge:prepare && cd ./build && electron-forge package", "docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts", "docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js", @@ -199,8 +199,8 @@ "@types/leaflet-gpx": "1.3.7", "@types/mime-types": "2.1.4", "@types/multer": "1.4.12", - "@types/node": "22.13.11", - "@types/react": "18.3.19", + "@types/node": "22.13.13", + "@types/react": "18.3.20", "@types/react-dom": "18.3.5", "@types/safe-compare": "1.1.2", "@types/sanitize-html": "2.13.0", @@ -209,7 +209,7 @@ "@types/session-file-store": "1.2.5", "@types/source-map-support": "0.5.10", "@types/stream-throttle": "0.1.4", - "@types/supertest": "6.0.2", + "@types/supertest": "6.0.3", "@types/swagger-ui-express": "4.1.8", "@types/tmp": "0.2.6", "@types/turndown": "5.0.5", @@ -249,7 +249,7 @@ "tsx": "4.19.3", "typedoc": "0.28.1", "typescript": "5.8.2", - "typescript-eslint": "8.27.0", + "typescript-eslint": "8.28.0", "vitest": "3.0.9", "webpack": "5.98.0", "webpack-cli": "6.0.1", diff --git a/src/services/backup.ts b/src/services/backup.ts index 8e9851602..5a4b1077d 100644 --- a/src/services/backup.ts +++ b/src/services/backup.ts @@ -76,6 +76,10 @@ async function backupNow(name: string) { return await syncMutexService.doExclusively(async () => { const backupFile = `${dataDir.BACKUP_DIR}/backup-${name}.db`; + if (!fs.existsSync(dataDir.BACKUP_DIR)) { + fs.mkdirSync(dataDir.BACKUP_DIR, 0o700); + } + await sql.copyDatabase(backupFile); log.info(`Created backup at ${backupFile}`); @@ -83,11 +87,6 @@ async function backupNow(name: string) { return backupFile; }); } - -if (!fs.existsSync(dataDir.BACKUP_DIR)) { - fs.mkdirSync(dataDir.BACKUP_DIR, 0o700); -} - export default { getExistingBackups, backupNow,