diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml
index 2efeb0174..ce07892bc 100644
--- a/.github/workflows/nightly-build.yml
+++ b/.github/workflows/nightly-build.yml
@@ -94,7 +94,6 @@ jobs:
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install -y rpm
- yarn build:npm linux
yarn build:linux
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -107,7 +106,6 @@ jobs:
- name: Build Mac
if: matrix.os == 'macos-latest'
run: |
- yarn build:npm mac
yarn build:mac
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
@@ -125,7 +123,6 @@ jobs:
- name: Build Windows
if: matrix.os == 'windows-latest'
run: |
- yarn build:npm windows
yarn build:win
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index b59cccd50..7428aa031 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -80,7 +80,6 @@ jobs:
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt-get install -y rpm
- yarn build:npm linux
yarn build:linux
env:
@@ -95,7 +94,6 @@ jobs:
if: matrix.os == 'macos-latest'
run: |
sudo -H pip install setuptools
- yarn build:npm mac
yarn build:mac
env:
CSC_LINK: ${{ secrets.CSC_LINK }}
@@ -113,7 +111,6 @@ jobs:
- name: Build Windows
if: matrix.os == 'windows-latest'
run: |
- yarn build:npm windows
yarn build:win
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/build/entitlements.mac.plist b/build/entitlements.mac.plist
index 38c887b21..6bc22e913 100644
--- a/build/entitlements.mac.plist
+++ b/build/entitlements.mac.plist
@@ -8,5 +8,7 @@
com.apple.security.cs.allow-dyld-environment-variables
+ com.apple.security.cs.disable-library-validation
+
diff --git a/electron-builder.yml b/electron-builder.yml
index e67ed2315..1f6dce36b 100644
--- a/electron-builder.yml
+++ b/electron-builder.yml
@@ -114,6 +114,7 @@ publish:
url: https://releases.cherry-ai.com
electronDownload:
mirror: https://npmmirror.com/mirrors/electron/
+beforePack: scripts/before-pack.js
afterPack: scripts/after-pack.js
afterSign: scripts/notarize.js
artifactBuildCompleted: scripts/artifact-build-completed.js
diff --git a/package.json b/package.json
index 694f88af9..35e85d175 100644
--- a/package.json
+++ b/package.json
@@ -40,7 +40,6 @@
"build:linux": "dotenv npm run build && electron-builder --linux --x64 --arm64",
"build:linux:arm64": "dotenv npm run build && electron-builder --linux --arm64",
"build:linux:x64": "dotenv npm run build && electron-builder --linux --x64",
- "build:npm": "node scripts/build-npm.js",
"release": "node scripts/version.js",
"publish": "yarn build:check && yarn release patch push",
"pulish:artifacts": "cd packages/artifacts && npm publish && cd -",
@@ -74,7 +73,6 @@
"@libsql/client": "0.14.0",
"@libsql/win32-x64-msvc": "^0.4.7",
"@napi-rs/system-ocr": "^1.0.2",
- "@strongtz/win32-arm64-msvc": "^0.4.7",
"graceful-fs": "^4.2.11",
"jsdom": "26.1.0",
"node-stream-zip": "^1.15.0",
diff --git a/scripts/after-pack.js b/scripts/after-pack.js
index 21bef1782..b8e4c8af1 100644
--- a/scripts/after-pack.js
+++ b/scripts/after-pack.js
@@ -1,104 +1,10 @@
-const { Arch } = require('electron-builder')
const fs = require('fs')
const path = require('path')
exports.default = async function (context) {
const platform = context.packager.platform.name
- const arch = context.arch
-
- if (platform === 'mac') {
- const node_modules_path = path.join(
- context.appOutDir,
- 'Cherry Studio.app',
- 'Contents',
- 'Resources',
- 'app.asar.unpacked',
- 'node_modules'
- )
-
- keepPackageNodeFiles(node_modules_path, '@libsql', arch === Arch.arm64 ? ['darwin-arm64'] : ['darwin-x64'])
-
- keepPackageNodeFiles(
- node_modules_path,
- '@img',
- arch === Arch.arm64
- ? ['sharp-darwin-arm64', 'sharp-libvips-darwin-arm64']
- : ['sharp-darwin-x64', 'sharp-libvips-darwin-x64']
- )
-
- keepPackageNodeFiles(
- node_modules_path,
- '@napi-rs',
- arch === Arch.arm64 ? ['system-ocr-darwin-arm64'] : ['system-ocr-darwin-x64']
- )
- }
-
- if (platform === 'linux') {
- const node_modules_path = path.join(context.appOutDir, 'resources', 'app.asar.unpacked', 'node_modules')
- const _arch = arch === Arch.arm64 ? ['linux-arm64-gnu', 'linux-arm64-musl'] : ['linux-x64-gnu', 'linux-x64-musl']
- keepPackageNodeFiles(node_modules_path, '@libsql', _arch)
-
- keepPackageNodeFiles(
- node_modules_path,
- '@img',
- arch === Arch.arm64
- ? ['sharp-libvips-linux-arm64', 'sharp-linux-arm64']
- : ['sharp-libvips-linux-x64', 'sharp-linux-x64']
- )
- }
-
- if (platform === 'windows') {
- const node_modules_path = path.join(context.appOutDir, 'resources', 'app.asar.unpacked', 'node_modules')
- if (arch === Arch.arm64) {
- keepPackageNodeFiles(node_modules_path, '@strongtz', ['win32-arm64-msvc'])
- keepPackageNodeFiles(node_modules_path, '@libsql', ['win32-arm64-msvc'])
- }
- if (arch === Arch.x64) {
- keepPackageNodeFiles(node_modules_path, '@strongtz', ['win32-x64-msvc'])
- keepPackageNodeFiles(node_modules_path, '@libsql', ['win32-x64-msvc'])
- }
-
- keepPackageNodeFiles(
- node_modules_path,
- '@img',
- arch === Arch.arm64
- ? ['sharp-win32-arm64', 'sharp-libvips-win32-arm64']
- : ['sharp-win32-x64', 'sharp-libvips-win32-x64']
- )
-
- keepPackageNodeFiles(
- node_modules_path,
- '@napi-rs',
- arch === Arch.arm64 ? ['system-ocr-win32-arm64-msvc'] : ['system-ocr-win32-x64-msvc']
- )
- }
-
if (platform === 'windows') {
fs.rmSync(path.join(context.appOutDir, 'LICENSE.electron.txt'), { force: true })
fs.rmSync(path.join(context.appOutDir, 'LICENSES.chromium.html'), { force: true })
}
}
-
-/**
- * 使用指定架构的 node_modules 文件
- * @param {*} nodeModulesPath
- * @param {*} packageName
- * @param {*} arch
- * @returns
- */
-function keepPackageNodeFiles(nodeModulesPath, packageName, arch) {
- const modulePath = path.join(nodeModulesPath, packageName)
-
- if (!fs.existsSync(modulePath)) {
- console.log(`[After Pack] Directory does not exist: ${modulePath}`)
- return
- }
-
- const dirs = fs.readdirSync(modulePath)
- dirs
- .filter((dir) => !arch.includes(dir))
- .forEach((dir) => {
- fs.rmSync(path.join(modulePath, dir), { recursive: true, force: true })
- console.log(`[After Pack] Removed dir: ${dir}`, arch)
- })
-}
diff --git a/scripts/before-pack.js b/scripts/before-pack.js
new file mode 100644
index 000000000..f0d4bdb09
--- /dev/null
+++ b/scripts/before-pack.js
@@ -0,0 +1,97 @@
+const { Arch } = require('electron-builder')
+const { downloadNpmPackage } = require('./utils')
+
+// if you want to add new prebuild binaries packages with different architectures, you can add them here
+// please add to allX64 and allArm64 from yarn.lock
+const allArm64 = {
+ '@img/sharp-darwin-arm64': '0.34.3',
+ '@img/sharp-win32-arm64': '0.34.3',
+ '@img/sharp-linux-arm64': '0.34.3',
+ '@img/sharp-linuxmusl-arm64': '0.34.3',
+
+ '@img/sharp-libvips-darwin-arm64': '1.2.0',
+ '@img/sharp-libvips-linux-arm64': '1.2.0',
+ '@img/sharp-libvips-linuxmusl-arm64': '1.2.0',
+
+ '@libsql/darwin-arm64': '0.4.7',
+ '@libsql/linux-arm64-gnu': '0.4.7',
+ '@libsql/linux-arm64-musl': '0.4.7',
+ '@strongtz/win32-arm64-msvc': '0.4.7',
+
+ '@napi-rs/system-ocr-darwin-arm64': '1.0.2',
+ '@napi-rs/system-ocr-win32-arm64-msvc': '1.0.2'
+}
+
+const allX64 = {
+ '@img/sharp-darwin-x64': '0.34.3',
+ '@img/sharp-linux-x64': '0.34.3',
+ '@img/sharp-linuxmusl-x64': '0.34.3',
+ '@img/sharp-win32-x64': '0.34.3',
+
+ '@img/sharp-libvips-darwin-x64': '1.2.0',
+ '@img/sharp-libvips-linux-x64': '1.2.0',
+ '@img/sharp-libvips-linuxmusl-x64': '1.2.0',
+
+ '@libsql/darwin-x64': '0.4.7',
+ '@libsql/linux-x64-gnu': '0.4.7',
+ '@libsql/linux-x64-musl': '0.4.7',
+ '@libsql/win32-x64-msvc': '0.4.7',
+
+ '@napi-rs/system-ocr-darwin-x64': '1.0.2',
+ '@napi-rs/system-ocr-win32-x64-msvc': '1.0.2'
+}
+
+const platformToArch = {
+ mac: 'darwin',
+ windows: 'win32',
+ linux: 'linux'
+}
+
+exports.default = async function (context) {
+ const arch = context.arch
+ const archType = arch === Arch.arm64 ? 'arm64' : 'x64'
+ const platform = context.packager.platform.name
+
+ const arm64Filters = Object.keys(allArm64).map((f) => '!node_modules/' + f + '/**')
+ const x64Filters = Object.keys(allX64).map((f) => '!node_modules/' + f + '/*')
+
+ const downloadPackages = async (packages) => {
+ console.log('downloading packages ......')
+ const downloadPromises = []
+
+ for (const name of Object.keys(packages)) {
+ if (name.includes(`${platformToArch[platform]}`) && name.includes(`-${archType}`)) {
+ downloadPromises.push(
+ downloadNpmPackage(
+ name,
+ `https://registry.npmjs.org/${name}/-/${name.split('/').pop()}-${packages[name]}.tgz`
+ )
+ )
+ }
+ }
+
+ await Promise.all(downloadPromises)
+ }
+
+ const changeFilters = async (packages, filtersToExclude, filtersToInclude) => {
+ await downloadPackages(packages)
+ // remove filters for the target architecture (allow inclusion)
+
+ let filters = context.packager.config.files[0].filter
+ filters = filters.filter((filter) => !filtersToInclude.includes(filter))
+ // add filters for other architectures (exclude them)
+ filters.push(...filtersToExclude)
+
+ context.packager.config.files[0].filter = filters
+ }
+
+ if (arch === Arch.arm64) {
+ await changeFilters(allArm64, x64Filters, arm64Filters)
+ return
+ }
+
+ if (arch === Arch.x64) {
+ await changeFilters(allX64, arm64Filters, x64Filters)
+ return
+ }
+}
diff --git a/scripts/build-npm.js b/scripts/build-npm.js
deleted file mode 100644
index c3a63d522..000000000
--- a/scripts/build-npm.js
+++ /dev/null
@@ -1,105 +0,0 @@
-const { downloadNpmPackage } = require('./utils')
-
-async function downloadNpm(platform) {
- if (!platform || platform === 'mac') {
- downloadNpmPackage(
- '@libsql/darwin-arm64',
- 'https://registry.npmjs.org/@libsql/darwin-arm64/-/darwin-arm64-0.4.7.tgz'
- )
- downloadNpmPackage('@libsql/darwin-x64', 'https://registry.npmjs.org/@libsql/darwin-x64/-/darwin-x64-0.4.7.tgz')
-
- // sharp for macOS
- downloadNpmPackage(
- '@img/sharp-darwin-arm64',
- 'https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz'
- )
- downloadNpmPackage(
- '@img/sharp-darwin-x64',
- 'https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz'
- )
- downloadNpmPackage(
- '@img/sharp-libvips-darwin-arm64',
- 'https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz'
- )
- downloadNpmPackage(
- '@img/sharp-libvips-darwin-x64',
- 'https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz'
- )
- downloadNpmPackage(
- '@napi-rs/system-ocr-darwin-arm64',
- 'https://registry.npmjs.org/@napi-rs/system-ocr-darwin-arm64/-/system-ocr-darwin-arm64-1.0.2.tgz'
- )
- downloadNpmPackage(
- '@napi-rs/system-ocr-darwin-x64',
- 'https://registry.npmjs.org/@napi-rs/system-ocr-darwin-x64/-/system-ocr-darwin-x64-1.0.2.tgz'
- )
- }
-
- if (!platform || platform === 'linux') {
- downloadNpmPackage(
- '@libsql/linux-arm64-gnu',
- 'https://registry.npmjs.org/@libsql/linux-arm64-gnu/-/linux-arm64-gnu-0.4.7.tgz'
- )
- downloadNpmPackage(
- '@libsql/linux-arm64-musl',
- 'https://registry.npmjs.org/@libsql/linux-arm64-musl/-/linux-arm64-musl-0.4.7.tgz'
- )
- downloadNpmPackage(
- '@libsql/linux-x64-gnu',
- 'https://registry.npmjs.org/@libsql/linux-x64-gnu/-/linux-x64-gnu-0.4.7.tgz'
- )
- downloadNpmPackage(
- '@libsql/linux-x64-musl',
- 'https://registry.npmjs.org/@libsql/linux-x64-musl/-/linux-x64-musl-0.4.7.tgz'
- )
-
- downloadNpmPackage(
- '@img/sharp-libvips-linux-arm64',
- 'https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz'
- )
- downloadNpmPackage(
- '@img/sharp-libvips-linux-x64',
- 'https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz'
- )
- downloadNpmPackage(
- '@img/sharp-libvips-linuxmusl-arm64',
- 'https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz'
- )
- downloadNpmPackage(
- '@img/sharp-libvips-linuxmusl-x64',
- 'https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz'
- )
- }
-
- if (!platform || platform === 'windows') {
- downloadNpmPackage(
- '@libsql/win32-x64-msvc',
- 'https://registry.npmjs.org/@libsql/win32-x64-msvc/-/win32-x64-msvc-0.4.7.tgz'
- )
- downloadNpmPackage(
- '@strongtz/win32-arm64-msvc',
- 'https://registry.npmjs.org/@strongtz/win32-arm64-msvc/-/win32-arm64-msvc-0.4.7.tgz'
- )
-
- downloadNpmPackage(
- '@img/sharp-win32-arm64',
- 'https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz'
- )
- downloadNpmPackage(
- '@img/sharp-win32-x64',
- 'https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz'
- )
-
- downloadNpmPackage(
- '@napi-rs/system-ocr-win32-arm64-msvc',
- 'https://registry.npmjs.org/@napi-rs/system-ocr-win32-arm64-msvc/-/system-ocr-win32-arm64-msvc-1.0.2.tgz'
- )
- downloadNpmPackage(
- '@napi-rs/system-ocr-win32-x64-msvc',
- 'https://registry.npmjs.org/@napi-rs/system-ocr-win32-x64-msvc/-/system-ocr-win32-x64-msvc-1.0.2.tgz'
- )
- }
-}
-
-const platformArg = process.argv[2]
-downloadNpm(platformArg)
diff --git a/scripts/utils.js b/scripts/utils.js
index 6cb5b35c3..cafa07b68 100644
--- a/scripts/utils.js
+++ b/scripts/utils.js
@@ -1,12 +1,15 @@
const fs = require('fs')
const path = require('path')
const os = require('os')
+const zlib = require('zlib')
+const tar = require('tar')
+const { pipeline } = require('stream/promises')
-function downloadNpmPackage(packageName, url) {
+async function downloadNpmPackage(packageName, url) {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'npm-download-'))
-
const targetDir = path.join('./node_modules/', packageName)
- const filename = packageName.replace('/', '-') + '.tgz'
+ const filename = path.join(tempDir, packageName.replace('/', '-') + '.tgz')
+ const extractDir = path.join(tempDir, 'extract')
// Skip if directory already exists
if (fs.existsSync(targetDir)) {
@@ -16,23 +19,44 @@ function downloadNpmPackage(packageName, url) {
try {
console.log(`Downloading ${packageName}...`, url)
- const { execSync } = require('child_process')
- execSync(`curl --fail -o ${filename} ${url}`)
+
+ // Download file using fetch API
+ const response = await fetch(url)
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`)
+ }
+
+ const fileStream = fs.createWriteStream(filename)
+ await pipeline(response.body, fileStream)
console.log(`Extracting ${filename}...`)
- execSync(`tar -xvf ${filename}`)
- execSync(`rm -rf ${filename}`)
- execSync(`mkdir -p ${targetDir}`)
- execSync(`mv package/* ${targetDir}/`)
+
+ // Create extraction directory
+ fs.mkdirSync(extractDir, { recursive: true })
+
+ // Extract tar.gz file using Node.js streams
+ await pipeline(fs.createReadStream(filename), zlib.createGunzip(), tar.extract({ cwd: extractDir }))
+
+ // Remove the downloaded file
+ fs.rmSync(filename, { force: true })
+
+ // Create target directory
+ fs.mkdirSync(targetDir, { recursive: true })
+
+ // Move extracted package contents to target directory
+ const packageDir = path.join(extractDir, 'package')
+ if (fs.existsSync(packageDir)) {
+ fs.cpSync(packageDir, targetDir, { recursive: true })
+ }
} catch (error) {
console.error(`Error processing ${packageName}: ${error.message}`)
- if (fs.existsSync(filename)) {
- fs.unlinkSync(filename)
- }
throw error
+ } finally {
+ // Clean up temp directory
+ if (fs.existsSync(tempDir)) {
+ fs.rmSync(tempDir, { recursive: true, force: true })
+ }
}
-
- fs.rmSync(tempDir, { recursive: true, force: true })
}
module.exports = {
diff --git a/yarn.lock b/yarn.lock
index 96f37725a..dc40f695a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7034,14 +7034,6 @@ __metadata:
languageName: node
linkType: hard
-"@strongtz/win32-arm64-msvc@npm:^0.4.7":
- version: 0.4.7
- resolution: "@strongtz/win32-arm64-msvc@npm:0.4.7"
- checksum: 10c0/21946f2ed43ff0b2381f945e22cf7f5ef6de412347c36523ed1d72f33591b2b85bf4cc9dd493f0eab95ed5e152d3944a2329791c3d8ed88c7ad450ccd9078015
- conditions: os=win32 & cpu=arm64
- languageName: node
- linkType: hard
-
"@swc/core-darwin-arm64@npm:1.11.21":
version: 1.11.21
resolution: "@swc/core-darwin-arm64@npm:1.11.21"
@@ -9417,7 +9409,6 @@ __metadata:
"@playwright/test": "npm:^1.52.0"
"@reduxjs/toolkit": "npm:^2.2.5"
"@shikijs/markdown-it": "npm:^3.12.0"
- "@strongtz/win32-arm64-msvc": "npm:^0.4.7"
"@swc/plugin-styled-components": "npm:^7.1.5"
"@tanstack/react-query": "npm:^5.85.5"
"@tanstack/react-virtual": "npm:^3.13.12"