diff --git a/.nx/version-plans/version-plan-1768086780974.md b/.nx/version-plans/version-plan-1768086780974.md new file mode 100644 index 000000000..536989d1a --- /dev/null +++ b/.nx/version-plans/version-plan-1768086780974.md @@ -0,0 +1,5 @@ +--- +desktop: patch +--- + +Revert to manual ASAR binary unpacking and execution due to issues on Windows and MacOS diff --git a/apps/desktop/build.ts b/apps/desktop/build.ts index e7c3d8980..c0ae75b8c 100644 --- a/apps/desktop/build.ts +++ b/apps/desktop/build.ts @@ -6,7 +6,11 @@ import { fileURLToPath } from 'node:url'; const config: Configuration = { artifactName: '${productName}-${version}-${platform}-${arch}.${ext}', - asarUnpack: ['resources/**'], + asarUnpack: [ + 'resources/**', + '**/node_modules/@the-dev-tools/server/dist/server', + '**/node_modules/@the-dev-tools/cli/dist/cli', + ], extraMetadata: { name: 'DevTools', }, diff --git a/apps/desktop/src/main/index.ts b/apps/desktop/src/main/index.ts index 1e37e2cd9..8f2075cb2 100644 --- a/apps/desktop/src/main/index.ts +++ b/apps/desktop/src/main/index.ts @@ -1,10 +1,9 @@ import { Command, FetchHttpClient, Path, Url } from '@effect/platform'; import * as NodeContext from '@effect/platform-node/NodeContext'; import * as NodeRuntime from '@effect/platform-node/NodeRuntime'; -import { Config, Console, Effect, pipe, Runtime } from 'effect'; +import { Config, Console, Effect, pipe, Runtime, String } from 'effect'; import { app, BrowserWindow, dialog, Dialog, globalShortcut, ipcMain, protocol, shell } from 'electron'; import { autoUpdater } from 'electron-updater'; -import child_process from 'node:child_process'; import os from 'node:os'; import { Agent } from 'undici'; import { CustomUpdateProvider, UpdateOptions } from './update'; @@ -99,19 +98,6 @@ const createWindow = Effect.gen(function* () { } }); -// Only 'child_process.execFile' is supported for executing binaries inside ASAR archives -// https://www.electronjs.org/docs/latest/tutorial/asar-archives#executing-binaries-inside-asar-archive -const execFile = (file: string, args?: string[], options?: child_process.ExecFileOptions) => - Effect.async((resume) => { - child_process.execFile(file, args, options, (error, stdout, stderr) => { - Effect.gen(function* () { - if (stdout) console.log(stdout); - if (stderr) console.error(stderr); - if (error) yield* Effect.fail(error); - }).pipe(resume); - }); - }); - const server = pipe( Effect.gen(function* () { const path = yield* Path.Path; @@ -122,16 +108,22 @@ const server = pipe( Effect.flatMap(path.fromFileUrl), ); - yield* execFile(path.join(dist, 'server'), undefined, { - env: { + yield* pipe( + path.join(dist, 'server'), + String.replaceAll('app.asar', 'app.asar.unpacked'), + Command.make, + Command.env({ // TODO: we probably shouldn't encrypt local database DB_ENCRYPTION_KEY: 'secret', DB_MODE: 'local', DB_NAME: 'state', DB_PATH: app.getPath('userData'), HMAC_SECRET: 'secret', - }, - }); + }), + Command.stdout('inherit'), + Command.stderr('inherit'), + Command.exitCode, + ); yield* Effect.interrupt; }), @@ -266,7 +258,9 @@ const cli = pipe( Effect.flatMap(path.fromFileUrl), ); - yield* execFile(path.join(dist, 'cli'), args); + const bin = pipe(path.join(dist, 'cli'), String.replaceAll('app.asar', 'app.asar.unpacked')); + + yield* pipe(Command.make(bin, ...args), Command.stdout('inherit'), Command.stderr('inherit'), Command.exitCode); app.quit(); }), diff --git a/tools/eslint/config.ts b/tools/eslint/config.ts index 1e01a13f7..641d485b9 100644 --- a/tools/eslint/config.ts +++ b/tools/eslint/config.ts @@ -97,7 +97,6 @@ const rules = defineConfig({ rules: { '@typescript-eslint/no-confusing-void-expression': ['error', { ignoreVoidOperator: true }], '@typescript-eslint/no-empty-object-type': ['error', { allowInterfaces: 'with-single-extends' }], - '@typescript-eslint/no-invalid-void-type': 'off', // re-enable once improved https://github.com/typescript-eslint/typescript-eslint/issues/8113 '@typescript-eslint/no-meaningless-void-operator': 'off', '@typescript-eslint/no-misused-promises': ['error', { checksVoidReturn: false }], '@typescript-eslint/no-non-null-assertion': 'off', // in protobuf everything is optional, requiring assertions