diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c8189d0..3973392 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,12 +20,22 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + submodules: recursive - name: Setup Mise uses: immich-app/devtools/actions/use-mise@7b8610a904d57da241e4ddba17fa62b62b15aed4 # use-mise-action-v2.0.2 with: github-token: ${{ secrets.GITHUB_TOKEN }} + - name: Install pipewire library + run: sudo apt install -y libpipewire-0.3-dev + + - name: Install rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - name: Checkout assets run: mise assets diff --git a/.github/workflows/multiplatform_build.yml b/.github/workflows/multiplatform_build.yml index c1e883a..4a01a6d 100644 --- a/.github/workflows/multiplatform_build.yml +++ b/.github/workflows/multiplatform_build.yml @@ -42,7 +42,7 @@ jobs: cache: "pnpm" - name: Install dependencies - run: pnpm ci + run: pnpm ci -F stoat-desktop - name: Build run: pnpm package \ No newline at end of file diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index b6d3ef7..aadf908 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -48,6 +48,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + submodules: recursive - name: Checkout assets run: git -c submodule."assets".update=checkout submodule update --init assets @@ -63,8 +65,22 @@ jobs: node-version: 26 cache: "pnpm" + - name: Install Flatpak Tooling and Runtimes and Pipewire dev + if: matrix.os == 'ubuntu-latest' + run: | + sudo apt-get update + sudo apt-get install -y flatpak flatpak-builder libpipewire-0.3-dev + flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo + flatpak install -y --user flathub org.freedesktop.Platform//25.08 org.freedesktop.Sdk//25.08 + flatpak install -y --user flathub org.electronjs.Electron2.BaseApp//stable + - name: Install dependencies - run: pnpm install + if: matrix.os == 'ubuntu-latest' + run: pnpm ci + + - name: Install dependencies + if: matrix.os != 'ubuntu-latest' + run: pnpm ci -F stoat-desktop - name: Publish run: | @@ -80,15 +96,6 @@ jobs: PLATFORM: ${{ matrix.os }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Install Flatpak Tooling and Runtimes - if: matrix.os == 'ubuntu-latest' - run: | - sudo apt-get update - sudo apt-get install -y flatpak flatpak-builder - flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo - flatpak install -y --user flathub org.freedesktop.Platform//25.08 org.freedesktop.Sdk//25.08 - flatpak install -y --user flathub org.electronjs.Electron2.BaseApp//stable - - name: Publish Linux arm64 if: matrix.os == 'ubuntu-latest' run: pnpm run publish --arch=arm64 diff --git a/.gitmodules b/.gitmodules index cc8d24a..bc7eaea 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,7 @@ [submodule "assets"] path = assets url = https://github.com/stoatchat/assets - update = none \ No newline at end of file + update = none +[submodule "node-pipewire"] + path = node-pipewire + url = git@github.com:Dadadah/node-pipewire.git diff --git a/.mise/tasks/build/_default b/.mise/tasks/build/_default index 17d5956..35e9208 100755 --- a/.mise/tasks/build/_default +++ b/.mise/tasks/build/_default @@ -2,4 +2,4 @@ #MISE description="Build desktop app" set -e -pnpm run package \ No newline at end of file +pnpm run -F stoat-desktop package \ No newline at end of file diff --git a/.mise/tasks/build/deps b/.mise/tasks/build/deps new file mode 100755 index 0000000..62bc410 --- /dev/null +++ b/.mise/tasks/build/deps @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +#MISE description="Build node-pipewire dependency" +set -e + +pnpm -F node-pipewire build-release diff --git a/README.md b/README.md index 3768ea8..4b8cc4d 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Before getting started, you'll want to install: - [Git](https://git-scm.com/install/) - [mise-en-place](https://mise.jdx.dev/getting-started.html) +- rust Then proceed to setup: @@ -45,6 +46,9 @@ mise install # install all packages mise install:frozen +# build the dependencies +mise build:deps + # start the application mise dev # ... or build the bundle diff --git a/node-pipewire b/node-pipewire new file mode 160000 index 0000000..b6d06b1 --- /dev/null +++ b/node-pipewire @@ -0,0 +1 @@ +Subproject commit b6d06b12259cc7929520b8f09261b96efc28abc9 diff --git a/package.json b/package.json index 0be1d25..d18a88b 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "@electron-forge/maker-flatpak": "^7.11.2", "@electron-forge/maker-squirrel": "^7.11.2", "@electron-forge/maker-zip": "^7.11.2", - "@electron-forge/plugin-auto-unpack-natives": "^7.11.2", "@electron-forge/plugin-fuses": "^7.11.2", "@electron-forge/plugin-vite": "^7.11.2", "@electron-forge/publisher-github": "^7.11.2", @@ -40,7 +39,7 @@ "@types/electron-squirrel-startup": "^1.0.2", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", - "electron": "^40.8.3", + "electron": "^43.2.0", "electron-vite": "^5.0.0", "electron-windows-store": "^2.1.0", "eslint": "^8.57.1", @@ -49,7 +48,8 @@ "lodash": "^4.17.21", "prettier": "^3.6.2", "typescript": "~4.5.4", - "vite": "^5.4.20" + "vite": "^5.4.20", + "vite-plugin-native-modules": "^2.3.1" }, "dependencies": { "@homebridge/dbus-native": "^0.7.2", @@ -61,5 +61,8 @@ "update-electron-app": "^3.1.1", "utf-8-validate": "^6.0.5" }, + "optionalDependencies": { + "node-pipewire": "workspace:^" + }, "packageManager": "pnpm@11.17.0+sha512.cca3cea332ad254bb84145f966d19f4879615210346fc92c79a047f23a0d7b3cca3c3792f0076ba1f1831d277efbcf0a9119b31a9a60eca7fb3d6231f331ef72" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c6b163b..72d997f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,9 +54,6 @@ importers: '@electron-forge/maker-zip': specifier: ^7.11.2 version: 7.11.2(bluebird@3.7.2)(supports-color@8.1.1) - '@electron-forge/plugin-auto-unpack-natives': - specifier: ^7.11.2 - version: 7.11.2(bluebird@3.7.2)(supports-color@8.1.1) '@electron-forge/plugin-fuses': specifier: ^7.11.2 version: 7.11.2(@electron/fuses@1.8.0)(bluebird@3.7.2)(supports-color@8.1.1) @@ -88,8 +85,8 @@ importers: specifier: ^5.62.0 version: 5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.5.5) electron: - specifier: ^40.8.3 - version: 40.8.3(supports-color@8.1.1) + specifier: ^43.2.0 + version: 43.2.0(supports-color@8.1.1) electron-vite: specifier: ^5.0.0 version: 5.0.0(supports-color@8.1.1)(vite@5.4.20(@types/node@24.10.13)(terser@5.49.0)) @@ -117,6 +114,41 @@ importers: vite: specifier: ^5.4.20 version: 5.4.20(@types/node@24.10.13)(terser@5.49.0) + vite-plugin-native-modules: + specifier: ^2.3.1 + version: 2.3.1(vite@5.4.20(@types/node@24.10.13)(terser@5.49.0)) + optionalDependencies: + node-pipewire: + specifier: workspace:^ + version: link:node-pipewire + + node-pipewire: + dependencies: + '@mapbox/node-pre-gyp': + specifier: ^1.0.10 + version: 1.0.11(encoding@0.1.13)(supports-color@8.1.1) + cargo-cp-artifact: + specifier: ^0.1.9 + version: 0.1.9 + typescript: + specifier: ^4.8.4 + version: 4.9.5 + devDependencies: + '@types/node': + specifier: ^18.11.9 + version: 18.19.130 + '@typescript-eslint/eslint-plugin': + specifier: ^5.42.1 + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5))(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: ^5.42.1 + version: 5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5) + eslint: + specifier: ^8.27.0 + version: 8.57.1(supports-color@8.1.1) + node-pre-gyp-github: + specifier: ^1.4.4 + version: 1.4.6 packages: @@ -271,10 +303,6 @@ packages: resolution: {integrity: sha512-FWnOm2MORX/nt8psnEtID3Vnt8Blby1NkzjU3KjXBPF9kave71C3lI8KbBbCeKKyTQ/S00i2FiglKdRWQ1WNTw==} engines: {node: '>= 16.4.0'} - '@electron-forge/plugin-auto-unpack-natives@7.11.2': - resolution: {integrity: sha512-ktMQxO80vGjqVXVSFha+kWJscBmJaWud4Kqu7rKkbrCphr1zqaG+8EDNbkpGzV/+mhKOLuA5qII1hJ69gFNpdA==} - engines: {node: '>= 16.4.0'} - '@electron-forge/plugin-base@7.11.2': resolution: {integrity: sha512-tIFzEE2+D9NnCAn/rLwSkh8H59IqN+G973JNl7xmCzquO6qa7/veitZOQFGO79Zmmgkc8R/fmiCbh7LIdLS9Tg==} engines: {node: '>= 16.4.0'} @@ -325,6 +353,10 @@ packages: resolution: {integrity: sha512-U8j5Hyj2Zt7I5PciJvPJfmEv69Gb/Da9v+k655z3Jj1cuY0UnToEJ61IhXrzlTYqo+jUKC+fgAjDJ6vltJTS0A==} engines: {node: '>= 14.17.5'} + '@electron-internal/extract-zip@1.0.5': + resolution: {integrity: sha512-+bqFCP98pLI0Tt0XQo1TmlXtwjWchISndDOxCkEcIuUgXWpBnLyRI+2DU+mesvnMMX6L1XDqYNA0lXNDHd/yiA==} + engines: {node: '>=22.12.0'} + '@electron/asar@3.4.1': resolution: {integrity: sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==} engines: {node: '>=10.12.0'} @@ -334,14 +366,14 @@ packages: resolution: {integrity: sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==} hasBin: true - '@electron/get@2.0.3': - resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} - engines: {node: '>=12'} - '@electron/get@3.1.0': resolution: {integrity: sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==} engines: {node: '>=14'} + '@electron/get@5.1.0': + resolution: {integrity: sha512-3kSBtG8ObcTVfXanm5vVJ6UnBLEVmVsRk1M+vGqCuMBV+XLCbJYuWQful+yIy0GQDsSlK0kHEriEHn7SPk4EnA==} + engines: {node: '>=22.12.0'} + '@electron/node-gyp@https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2': resolution: {gitHosted: true, tarball: https://codeload.github.com/electron/node-gyp/tar.gz/06b29aafb7708acef8b3669835c8a7857ebc92d2} version: 10.2.0-electron.1 @@ -811,6 +843,10 @@ packages: resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} engines: {node: '>= 10.0.0'} + '@mapbox/node-pre-gyp@1.0.11': + resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} + hasBin: true + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -854,6 +890,12 @@ packages: '@octokit/openapi-types@24.2.0': resolution: {integrity: sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg==} + '@octokit/plugin-paginate-rest@11.3.1': + resolution: {integrity: sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '5' + '@octokit/plugin-paginate-rest@11.4.4-cjs.2': resolution: {integrity: sha512-2dK6z8fhs8lla5PaOTgqfCGBxgAv/le+EhPs27KklPhm1bKObpu6lXzwfUEQ16ajXzqNrKMujsFyo9K2eaoISw==} engines: {node: '>= 18'} @@ -866,6 +908,12 @@ packages: peerDependencies: '@octokit/core': '5' + '@octokit/plugin-rest-endpoint-methods@13.2.2': + resolution: {integrity: sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': ^5 + '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1': resolution: {integrity: sha512-VUjIjOOvF2oELQmiFpWA1aOPdawpyaCUqcEBc/UOUnj3Xp6DJGrJ1+bjUIIDzdHjnFNO6q57ODMfdEZnoBkCwQ==} engines: {node: '>= 18'} @@ -886,6 +934,10 @@ packages: resolution: {integrity: sha512-qnB2+SY3hkCmBxZsR/MPCybNmbJe4KAlfWErXq+rBKkQJlbjdJeS85VI9r8UqeLYLvnAenU8Q1okM/0MBsAGXw==} engines: {node: '>= 18'} + '@octokit/rest@20.1.1': + resolution: {integrity: sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==} + engines: {node: '>= 18'} + '@octokit/rest@20.1.2': resolution: {integrity: sha512-GmYiltypkHHtihFwPRxlaorG5R9VAHuk/vbszVoRTGXnAsY60wYLkh/E2XiFmdZmqrisw+9FaazS1i5SbdWYgA==} engines: {node: '>= 18'} @@ -1084,15 +1136,15 @@ packages: '@types/mute-stream@0.0.4': resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + '@types/node@18.19.130': + resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + '@types/node@22.18.6': resolution: {integrity: sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==} '@types/node@24.10.13': resolution: {integrity: sha512-oH72nZRfDv9lADUBSo104Aq7gPHpQZc4BTx38r9xf9pg5LfP6EzSyH2n7qFmmxRQXh7YlUXODcYsg6PuTDSxGg==} - '@types/node@24.5.2': - resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} - '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} @@ -1332,6 +1384,14 @@ packages: applescript@1.0.0: resolution: {integrity: sha512-yvtNHdWvtbYEiIazXAdp/NY+BBb65/DAseqlNiJQjOx9DynuzOYDbVLBJvuc0ve0VL9x6B3OHF6eH52y9hCBtQ==} + aproba@2.1.0: + resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} + + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1476,6 +1536,10 @@ packages: caniuse-lite@1.0.30001806: resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} + cargo-cp-artifact@0.1.9: + resolution: {integrity: sha512-6F+UYzTaGB+awsTXg0uSJA1/b/B3DDJzpKVRu0UmyI7DmNeaAl2RFHuTGIN6fEgpadRxoXGb7gbC1xo4C3IdyA==} + hasBin: true + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1553,6 +1617,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -1560,6 +1628,10 @@ packages: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} + commander@12.0.0: + resolution: {integrity: sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==} + engines: {node: '>=18'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1582,6 +1654,9 @@ packages: resolution: {integrity: sha512-L6BuueHTRuJHQvQVc6YXYZRtN5vJUtOdCTLn0tRYYV5azfbAFcPghB5zEE40mVrV6w7slMTqUfkDomutIK14fw==} engines: {node: '>=20'} + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -1663,6 +1738,9 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + deprecation@2.3.1: resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} @@ -1745,9 +1823,9 @@ packages: resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} engines: {node: '>=8.0.0'} - electron@40.8.3: - resolution: {integrity: sha512-MH6LK4xM6VVmmtz0nRE0Fe8l2jTKSYTvH1t0ZfbNLw3o6dlBCVTRqQha6uL8ZQVoMy74JyLguGwK7dU7rCKIhw==} - engines: {node: '>= 12.20.55'} + electron@43.2.0: + resolution: {integrity: sha512-80zvrgG7ZRXD+tD0IyLvrnN9n+veSxadMRsMaC9wKKP3iUbtC7rGM8+dVuCmOb0Rrwwv8ESW4awnUZh9Hbp1fA==} + engines: {node: '>= 22.12.0'} hasBin: true emoji-regex@8.0.0: @@ -2060,6 +2138,11 @@ packages: resolution: {integrity: sha512-w4n9cPWyP7aHxKxYHFQMegj7WIAsL/YX/C4Bs5Rr8s1H9M1rNtRWRsw+ovYMkXDQ5S4ZbYHsHAPmevPjPgw44w==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -2177,6 +2260,9 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -2536,6 +2622,10 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + make-fetch-happen@10.2.1: resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -2762,10 +2852,20 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true + node-pre-gyp-github@1.4.6: + resolution: {integrity: sha512-+s+4hEv0O/AsmV+96O7Pkw5/82IipeW4SQ84pNudF42jy6Ec38KCe29t55y+TbJqvgfTbWVHVrg+yb89ef/1XA==} + deprecated: Since Node.js v18 is now required this version introduces breaking changes, so we are moving this to v2.0.0. + hasBin: true + node-releases@2.0.51: resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} engines: {node: '>=18'} + nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -2782,6 +2882,14 @@ packages: resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} engines: {node: '>=4'} + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + object-inspect@1.13.4: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} @@ -3154,6 +3262,9 @@ packages: resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} engines: {node: '>=10'} + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -3457,6 +3568,11 @@ packages: engines: {node: '>=4.2.0'} hasBin: true + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + typescript@5.4.5: resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} engines: {node: '>=14.17'} @@ -3470,15 +3586,19 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.12.0: - resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} - undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici@7.29.0: + resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} + engines: {node: '>=20.18.1'} + unique-filename@2.0.1: resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -3528,6 +3648,11 @@ packages: validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vite-plugin-native-modules@2.3.1: + resolution: {integrity: sha512-Vm/nJAuvUrE4XnjvqhDlFKRUNCPytylyr/2rivF0pXC3Vdg1r5jW3JbbR1PKefKoyVrTwU1F0vHruCFUhicflw==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vite@5.4.20: resolution: {integrity: sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==} engines: {node: ^18.0.0 || >=20.0.0} @@ -3614,6 +3739,9 @@ packages: engines: {node: '>= 8'} hasBin: true + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + winreg@1.2.4: resolution: {integrity: sha512-IHpzORub7kYlb8A43Iig3reOvlcBJGX9gZ0WycHhghHtA65X0LYnMRuJs+aH1abVnMJztQkvQNlltnbPi5aGIA==} @@ -4023,14 +4151,6 @@ snapshots: - bluebird - supports-color - '@electron-forge/plugin-auto-unpack-natives@7.11.2(bluebird@3.7.2)(supports-color@8.1.1)': - dependencies: - '@electron-forge/plugin-base': 7.11.2(bluebird@3.7.2)(supports-color@8.1.1) - '@electron-forge/shared-types': 7.11.2(bluebird@3.7.2)(supports-color@8.1.1) - transitivePeerDependencies: - - bluebird - - supports-color - '@electron-forge/plugin-base@7.11.2(bluebird@3.7.2)(supports-color@8.1.1)': dependencies: '@electron-forge/shared-types': 7.11.2(bluebird@3.7.2)(supports-color@8.1.1) @@ -4162,6 +4282,8 @@ snapshots: dependencies: chrome-trace-event: 1.0.4 + '@electron-internal/extract-zip@1.0.5': {} + '@electron/asar@3.4.1': dependencies: commander: 5.1.0 @@ -4174,7 +4296,7 @@ snapshots: fs-extra: 9.1.0 minimist: 1.2.8 - '@electron/get@2.0.3(supports-color@8.1.1)': + '@electron/get@3.1.0(supports-color@8.1.1)': dependencies: debug: 4.4.3(supports-color@8.1.1) env-paths: 2.2.1 @@ -4188,17 +4310,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@electron/get@3.1.0(supports-color@8.1.1)': + '@electron/get@5.1.0(supports-color@8.1.1)': dependencies: debug: 4.4.3(supports-color@8.1.1) - env-paths: 2.2.1 - fs-extra: 8.1.0 - got: 11.8.6 + env-paths: 3.0.0 + graceful-fs: 4.2.11 progress: 2.0.3 - semver: 6.3.1 + semver: 7.7.2 sumchecker: 3.0.1(supports-color@8.1.1) optionalDependencies: - global-agent: 3.0.0 + undici: 7.29.0 transitivePeerDependencies: - supports-color @@ -4658,6 +4779,21 @@ snapshots: - supports-color optional: true + '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)(supports-color@8.1.1)': + dependencies: + detect-libc: 2.1.1 + https-proxy-agent: 5.0.1(supports-color@8.1.1) + make-dir: 3.1.0 + node-fetch: 2.7.0(encoding@0.1.13) + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.7.2 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -4707,6 +4843,11 @@ snapshots: '@octokit/openapi-types@24.2.0': {} + '@octokit/plugin-paginate-rest@11.3.1(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 13.10.0 + '@octokit/plugin-paginate-rest@11.4.4-cjs.2(@octokit/core@5.2.2)': dependencies: '@octokit/core': 5.2.2 @@ -4716,6 +4857,11 @@ snapshots: dependencies: '@octokit/core': 5.2.2 + '@octokit/plugin-rest-endpoint-methods@13.2.2(@octokit/core@5.2.2)': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/types': 13.10.0 + '@octokit/plugin-rest-endpoint-methods@13.3.2-cjs.1(@octokit/core@5.2.2)': dependencies: '@octokit/core': 5.2.2 @@ -4741,6 +4887,13 @@ snapshots: '@octokit/types': 13.10.0 universal-user-agent: 6.0.1 + '@octokit/rest@20.1.1': + dependencies: + '@octokit/core': 5.2.2 + '@octokit/plugin-paginate-rest': 11.3.1(@octokit/core@5.2.2) + '@octokit/plugin-request-log': 4.0.1(@octokit/core@5.2.2) + '@octokit/plugin-rest-endpoint-methods': 13.2.2(@octokit/core@5.2.2) + '@octokit/rest@20.1.2': dependencies: '@octokit/core': 5.2.2 @@ -4850,7 +5003,7 @@ snapshots: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 24.5.2 + '@types/node': 24.10.13 '@types/responselike': 1.0.3 '@types/discord-rpc@4.0.9': @@ -4882,6 +5035,10 @@ snapshots: dependencies: '@types/node': 24.10.13 + '@types/node@18.19.130': + dependencies: + undici-types: 5.26.5 + '@types/node@22.18.6': dependencies: undici-types: 6.21.0 @@ -4890,13 +5047,9 @@ snapshots: dependencies: undici-types: 7.16.0 - '@types/node@24.5.2': - dependencies: - undici-types: 7.12.0 - '@types/responselike@1.0.3': dependencies: - '@types/node': 24.5.2 + '@types/node': 24.10.13 '@types/semver@7.7.1': {} @@ -4926,6 +5079,25 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5))(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5) + debug: 4.4.3(supports-color@8.1.1) + eslint: 8.57.1(supports-color@8.1.1) + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.7.2 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.5.5)': dependencies: '@typescript-eslint/scope-manager': 5.62.0 @@ -4938,6 +5110,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(supports-color@8.1.1)(typescript@4.9.5) + debug: 4.4.3(supports-color@8.1.1) + eslint: 8.57.1(supports-color@8.1.1) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/scope-manager@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -4955,6 +5139,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(supports-color@8.1.1)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5) + debug: 4.4.3(supports-color@8.1.1) + eslint: 8.57.1(supports-color@8.1.1) + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/types@5.62.0': {} '@typescript-eslint/typescript-estree@5.62.0(supports-color@8.1.1)(typescript@4.5.5)': @@ -4971,6 +5167,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/typescript-estree@5.62.0(supports-color@8.1.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.4.3(supports-color@8.1.1) + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.7.2 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/utils@5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.5.5)': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1(supports-color@8.1.1)) @@ -4986,6 +5196,21 @@ snapshots: - supports-color - typescript + '@typescript-eslint/utils@5.62.0(eslint@8.57.1(supports-color@8.1.1))(supports-color@8.1.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/eslint-utils': 4.9.0(eslint@8.57.1(supports-color@8.1.1)) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.1 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(supports-color@8.1.1)(typescript@4.9.5) + eslint: 8.57.1(supports-color@8.1.1) + eslint-scope: 5.1.1 + semver: 7.7.2 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/visitor-keys@5.62.0': dependencies: '@typescript-eslint/types': 5.62.0 @@ -5163,6 +5388,13 @@ snapshots: applescript@1.0.0: {} + aproba@2.1.0: {} + + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + argparse@2.0.1: {} array-buffer-byte-length@1.0.2: @@ -5356,6 +5588,8 @@ snapshots: caniuse-lite@1.0.30001806: {} + cargo-cp-artifact@0.1.9: {} + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -5429,10 +5663,14 @@ snapshots: color-name@1.1.4: {} + color-support@1.1.3: {} + colorette@2.0.20: {} commander@11.1.0: {} + commander@12.0.0: {} + commander@2.20.3: {} commander@5.1.0: {} @@ -5455,6 +5693,8 @@ snapshots: semver: 7.7.2 uint8array-extras: 1.5.0 + console-control-strings@1.1.0: {} + convert-source-map@2.0.0: {} cross-dirname@0.1.0: {} @@ -5539,6 +5779,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + delegates@1.0.0: {} + deprecation@2.3.1: {} detect-libc@2.1.1: {} @@ -5671,11 +5913,11 @@ snapshots: - supports-color optional: true - electron@40.8.3(supports-color@8.1.1): + electron@43.2.0(supports-color@8.1.1): dependencies: - '@electron/get': 2.0.3(supports-color@8.1.1) + '@electron-internal/extract-zip': 1.0.5 + '@electron/get': 5.1.0(supports-color@8.1.1) '@types/node': 24.10.13 - extract-zip: 2.0.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -6158,6 +6400,18 @@ snapshots: gar@1.0.4: optional: true + gauge@3.0.2: + dependencies: + aproba: 2.1.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} @@ -6310,6 +6564,8 @@ snapshots: dependencies: has-symbols: 1.1.0 + has-unicode@2.0.1: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -6656,6 +6912,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + make-fetch-happen@10.2.1(bluebird@3.7.2)(supports-color@8.1.1): dependencies: agentkeepalive: 4.6.0 @@ -6833,8 +7093,17 @@ snapshots: node-gyp-build@4.8.4: {} + node-pre-gyp-github@1.4.6: + dependencies: + '@octokit/rest': 20.1.1 + commander: 12.0.0 + node-releases@2.0.51: {} + nopt@5.0.0: + dependencies: + abbrev: 1.1.1 + nopt@6.0.0: dependencies: abbrev: 1.1.1 @@ -6852,6 +7121,15 @@ snapshots: dependencies: path-key: 2.0.1 + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + + object-assign@4.1.1: {} + object-inspect@1.13.4: {} object-keys@1.1.1: {} @@ -7245,6 +7523,8 @@ snapshots: type-fest: 0.13.1 optional: true + set-blocking@2.0.0: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -7538,6 +7818,11 @@ snapshots: tslib: 1.14.1 typescript: 4.5.5 + tsutils@3.21.0(typescript@4.9.5): + dependencies: + tslib: 1.14.1 + typescript: 4.9.5 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -7588,6 +7873,8 @@ snapshots: typescript@4.5.5: {} + typescript@4.9.5: {} + typescript@5.4.5: {} uint8array-extras@1.5.0: {} @@ -7599,12 +7886,15 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 + undici-types@5.26.5: {} + undici-types@6.21.0: {} - undici-types@7.12.0: {} - undici-types@7.16.0: {} + undici@7.29.0: + optional: true + unique-filename@2.0.1: dependencies: unique-slug: 3.0.0 @@ -7652,6 +7942,10 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 + vite-plugin-native-modules@2.3.1(vite@5.4.20(@types/node@24.10.13)(terser@5.49.0)): + dependencies: + vite: 5.4.20(@types/node@24.10.13)(terser@5.49.0) + vite@5.4.20(@types/node@24.10.13)(terser@5.49.0): dependencies: esbuild: 0.21.5 @@ -7768,6 +8062,10 @@ snapshots: dependencies: isexe: 2.0.0 + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + winreg@1.2.4: {} word-wrap@1.2.5: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e09a7ca..70cb75d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,6 @@ +packages: + - 'node-pipewire' + allowBuilds: bufferutil: true electron: true @@ -8,8 +11,8 @@ allowBuilds: nodeLinker: hoisted -blockExoticSubdeps: false # required to make discord-rpc work +blockExoticSubdeps: false # required to make discord-rpc work # Override for node 26 bug overrides: - yauzl: ^3.3.1 \ No newline at end of file + yauzl: ^3.3.1 diff --git a/src/constants.ts b/src/constants.ts new file mode 100644 index 0000000..e61cea8 --- /dev/null +++ b/src/constants.ts @@ -0,0 +1,2 @@ +export const sinkName = "stoat-virtual-sink"; +export const sourceName = "stoat-virtual-source"; diff --git a/src/main.ts b/src/main.ts index 60bed38..7698078 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,6 +6,7 @@ import started from "electron-squirrel-startup"; import { config } from "./native/config"; import { initDiscordRpc } from "./native/discordRpc"; import { initTray } from "./native/tray"; +import { initVirtualMic } from "./native/virtualMic"; import { BUILD_URL, createMainWindow, mainWindow } from "./native/window"; // Squirrel-specific logic @@ -51,6 +52,7 @@ if (acquiredLock) { initTray(); initDiscordRpc(); + initVirtualMic(); // Windows specific fix for notifications if (process.platform === "win32") { diff --git a/src/native/virtualMic.ts b/src/native/virtualMic.ts new file mode 100644 index 0000000..98a0626 --- /dev/null +++ b/src/native/virtualMic.ts @@ -0,0 +1,139 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +// Disable any checks because node-pipewire doesn't have types for our submodule +import { app, ipcMain } from "electron"; + +import { sinkName, sourceName } from "../constants"; + +const delay = (ms: number) => new Promise((res) => setTimeout(res, ms)); + +function getPids() { + return app.getAppMetrics().map((proc) => proc.pid ?? -1); +} + +export const isWayland = + process.platform === "linux" && + (process.env.XDG_SESSION_TYPE === "wayland" || !!process.env.WAYLAND_DISPLAY); + +ipcMain.handle("getIsWayland", () => isWayland); + +export async function initVirtualMic() { + // Only available on Wayland + if (!isWayland) return; + + try { + const { + createPwThread, + createSink, + createSource, + getClients, + getNodes, + linkNodesNameToId, + //@ts-expect-error This module may not be found on non-linux builds. + } = await import("node-pipewire"); //eslint-disable-line + + createPwThread(); + + // Wait for pipewire thread to start and gather neccessary data + await delay(100); + + let nodes = getNodes(); + + let sinkFound = false; + let sourceFound = false; + for (const node of nodes) { + if (node.name === sinkName) { + sinkFound = true; + } + if (node.name === sourceName) { + sourceFound = true; + } + } + + if (!sinkFound) { + createSink(sinkName, ["FL", "FR"], false); + } + + if (!sourceFound) { + createSource(sourceName, ["FL", "FR"], false); + } + + // Wait for source and sink to save + await delay(100); + + const appName = app.getName(); + + nodes = getNodes(); + const savedNodes: Record = {}; + const sourceNode = nodes.filter((node: any) => node.name === sourceName)[0]; + const sinkNode = nodes.filter((node: any) => node.name === sinkName)[0]; + + linkNodesNameToId(sinkNode.name, sourceNode.id, false); + + setInterval(() => { + const ourClients: Record = {}; + const paClients: any[] = []; + + const pids = getPids(); + const clients = getClients(); + for (const client of clients) { + // If the client belongs to one of the electton processes + if (pids.includes(client.pid)) { + ourClients[client.pid] = client; + } + // If the client is a pulse audio client made on behalf of this app + if (client.application_name === appName) { + paClients.push(client); + } + } + + nodes = getNodes() + // Only choose output streams + .filter( + (node: any) => node.props["media.class"] === "Stream/Output/Audio", + ) + // Ignore any nodes from electron's processes + .filter( + (node: any) => + !Object.values(ourClients) + .map((client) => client.id) + .includes(Number(node.props["client.id"])), + ) + // Ignore any nodes from pulse audio processes for the app + .filter( + (node: any) => + !paClients + .map((client) => client.id) + .includes(Number(node.props["client.id"])), + ); + + for (const node of nodes) { + const idAsNum = Number(node.id); + // If this node hasn't been seen before (ie. new node) + if (!savedNodes[idAsNum]) { + // Link all of the new node's outputs to our virtual sink + linkNodesNameToId(node.name, sinkNode.id, false); + savedNodes[idAsNum] = node; + } + } + + // Cleanup savedNodes for nodes that are gone + for (const id in savedNodes) { + const asNum = Number(id); + let found = false; + for (const node of nodes) { + if (node.id === asNum) { + found = true; + break; + } + } + if (!found) { + savedNodes[asNum] = void 0; + } + } + }, 1000); + } catch { + console.log( + "node-pipewire failed to load. Screen share audio will not work on linux wayland.", + ); + } +} diff --git a/src/native/window.ts b/src/native/window.ts index d183972..a5e2f29 100644 --- a/src/native/window.ts +++ b/src/native/window.ts @@ -200,8 +200,6 @@ export function createMainWindow() { .then((sources) => { // Shortcut for linux wayland. if (sources.length == 1) { - // TODO: Get audio to work with wayland - // See vencord for an implementation using a virtual microphone. request.audioRequested ? callback({ video: sources[0], diff --git a/src/world/window.ts b/src/world/window.ts index 9995b6d..f7832db 100644 --- a/src/world/window.ts +++ b/src/world/window.ts @@ -32,4 +32,6 @@ contextBridge.exposeInMainWorld("native", { }, screenPickerCallback: (idx: number, audio: boolean) => ipcRenderer.send("screenPickerCallback", idx, audio), + + isWayland: () => ipcRenderer.invoke("getIsWayland"), }); diff --git a/vite.main.config.ts b/vite.main.config.ts index fbf7eda..ca30a7a 100644 --- a/vite.main.config.ts +++ b/vite.main.config.ts @@ -1,4 +1,15 @@ import { defineConfig } from "vite"; +import nativePlugin from "vite-plugin-native-modules"; // https://vitejs.dev/config -export default defineConfig({}); +export default defineConfig({ + plugins: [nativePlugin()], + build: { + commonjsOptions: { + include: [/node-pipewire/, /node_modules/], + }, + rollupOptions: { + external: ["node-pipewire"], + }, + }, +});