refactor(orcad): move the Node host adapters out of orcad-entry.ts (#28530)

Fixes main's lint: #28464 left orcad-entry.ts at 301 lines (max 300). No behaviour change.
This commit is contained in:
Jinwoo Hong
2026-10-14 00:01:28 -04:00
committed by GitHub
parent ed9ada5fe9
commit 6741f4f165
5 changed files with 79 additions and 72 deletions
+4 -69
View File
@@ -11,16 +11,11 @@
* Chromium proves available at startup.
*/
import process from 'node:process'
import { describeOrcadSecretProtectionGap } from './orcad-secret-protection-gap'
import {
getAppEnvironment,
setAppEnvironment,
type AppEnvironment
} from '../../shared/app-environment'
import { setSecretStore, type SecretStore } from '../../shared/secret-store'
import { getAppEnvironment } from '../../shared/app-environment'
import type { ServeReadiness } from '../server/serve-readiness'
import { resolveOrcadInstallRoot, resolveOrcadPath, resolveUserDataPath } from './orcad-app-paths'
import { getOrcadCliLauncherPath, prepareOrcadCliLauncher } from './orcad-cli-launcher'
import { resolveOrcadInstallRoot, resolveUserDataPath } from './orcad-app-paths'
import { prepareOrcadCliLauncher } from './orcad-cli-launcher'
import { installOrcadHostAdapters, runOrcadQuitHandlers } from './orcad-host-adapters'
import { describeOrcadBindExposure, resolveOrcadBindHost } from './orcad-bind-address'
import {
flushOrcadProfileStoreForShutdown,
@@ -43,68 +38,8 @@ import { adoptWslHostLoginEnvironment } from './orcad-wsl-host-login-environment
export { parseArgs }
let runOrcadQuitHandlers = (): void => {}
let closeOrcadObservability = (): void => {}
function createNodeAppEnvironment(): AppEnvironment {
const quitHandlers: (() => void)[] = []
// The main signal handler awaits runtime and browser teardown before process.exit.
// Keep will-quit callbacks synchronous, but never let them pre-empt that async barrier.
runOrcadQuitHandlers = (): void => {
const errors: unknown[] = []
for (const handler of quitHandlers.splice(0)) {
try {
handler()
} catch (error) {
errors.push(error)
}
}
// Why throw: a quit handler that failed may leave a writer running, which keeps the lock.
if (errors.length > 0) {
throw new AggregateError(errors, 'orcad_quit_handlers_failed')
}
}
return {
getPath: resolveOrcadPath,
getAppPath: () => resolveOrcadInstallRoot(),
getVersion: () => process.env.ORCA_VERSION ?? '0.0.0-orcad',
// Why still true: consumers read this as "production build, not a dev checkout" —
// it gates HTTPS-only skill downloads, the real CLI command name, and shell-PATH
// hydration. Answering false to satisfy a path resolver would relax a security
// posture. Layout questions must ask whether the app root is an asar archive
// instead (see parcel-watcher-entry-path.ts).
isPackaged: () => true,
getCliLauncherPath: getOrcadCliLauncherPath,
onWillQuit: (handler) => quitHandlers.push(handler),
exit: (code = 0) => process.exit(code),
// Why []: there are no Chromium processes on this host to measure.
getAppMetrics: () => []
}
}
/**
* Why not silently plaintext: `isEncryptionAvailable() === false` already makes every
* caller fall back to unsealed storage, which is a security posture, not a detail.
* `describeProtectionGap()` gives the reason a client can surface.
*/
function createNodeSecretStore(): SecretStore {
return {
isEncryptionAvailable: () => false,
encryptString: () => {
throw new Error('orcad_secret_sealing_unavailable')
},
decryptString: () => {
throw new Error('orcad_secret_sealing_unavailable')
},
describeProtectionGap: () => describeOrcadSecretProtectionGap(process.platform)
}
}
export function installOrcadHostAdapters(): void {
setAppEnvironment(createNodeAppEnvironment())
setSecretStore(createNodeSecretStore())
}
export type OrcadOptions = {
port?: number
json?: boolean
@@ -13,7 +13,7 @@ import {
resolveForeignSqliteReaderEntryPath
} from '../foreign-sqlite-readers/foreign-sqlite-reader-entry-path'
import { currentWorkerEntryLayout } from '../worker-thread-entry-path'
import { installOrcadHostAdapters } from './orcad-entry'
import { installOrcadHostAdapters } from './orcad-host-adapters'
/**
* The composition, not the pieces: orcad's real host adapters against the real resolver
+72
View File
@@ -0,0 +1,72 @@
/** The Node host's stand-ins for Electron's app environment and secret store. */
import process from 'node:process'
import { setAppEnvironment, type AppEnvironment } from '../../shared/app-environment'
import { setSecretStore, type SecretStore } from '../../shared/secret-store'
import { resolveOrcadInstallRoot, resolveOrcadPath } from './orcad-app-paths'
import { getOrcadCliLauncherPath } from './orcad-cli-launcher'
import { describeOrcadSecretProtectionGap } from './orcad-secret-protection-gap'
let quitRegisteredHandlers = (): void => {}
export function runOrcadQuitHandlers(): void {
quitRegisteredHandlers()
}
function createNodeAppEnvironment(): AppEnvironment {
const quitHandlers: (() => void)[] = []
// The main signal handler awaits runtime and browser teardown before process.exit.
// Keep will-quit callbacks synchronous, but never let them pre-empt that async barrier.
quitRegisteredHandlers = (): void => {
const errors: unknown[] = []
for (const handler of quitHandlers.splice(0)) {
try {
handler()
} catch (error) {
errors.push(error)
}
}
// Why throw: a quit handler that failed may leave a writer running, which keeps the lock.
if (errors.length > 0) {
throw new AggregateError(errors, 'orcad_quit_handlers_failed')
}
}
return {
getPath: resolveOrcadPath,
getAppPath: () => resolveOrcadInstallRoot(),
getVersion: () => process.env.ORCA_VERSION ?? '0.0.0-orcad',
// Why still true: consumers read this as "production build, not a dev checkout" —
// it gates HTTPS-only skill downloads, the real CLI command name, and shell-PATH
// hydration. Answering false to satisfy a path resolver would relax a security
// posture. Layout questions must ask whether the app root is an asar archive
// instead (see parcel-watcher-entry-path.ts).
isPackaged: () => true,
getCliLauncherPath: getOrcadCliLauncherPath,
onWillQuit: (handler) => quitHandlers.push(handler),
exit: (code = 0) => process.exit(code),
// Why []: there are no Chromium processes on this host to measure.
getAppMetrics: () => []
}
}
/**
* Why not silently plaintext: `isEncryptionAvailable() === false` already makes every
* caller fall back to unsealed storage, which is a security posture, not a detail.
* `describeProtectionGap()` gives the reason a client can surface.
*/
function createNodeSecretStore(): SecretStore {
return {
isEncryptionAvailable: () => false,
encryptString: () => {
throw new Error('orcad_secret_sealing_unavailable')
},
decryptString: () => {
throw new Error('orcad_secret_sealing_unavailable')
},
describeProtectionGap: () => describeOrcadSecretProtectionGap(process.platform)
}
}
export function installOrcadHostAdapters(): void {
setAppEnvironment(createNodeAppEnvironment())
setSecretStore(createNodeSecretStore())
}
@@ -13,7 +13,7 @@ vi.mock('../startup/hydrate-shell-path', () => hydration)
import { getAppEnvironment } from '../../shared/app-environment'
import { hydrateShellPathForAgentDetection } from '../ipc/agent-detection-shell-path'
import { installOrcadHostAdapters } from './orcad-entry'
import { installOrcadHostAdapters } from './orcad-host-adapters'
describe('orcad PATH hydration on a WSL guest', () => {
const platform = process.platform
@@ -1,5 +1,5 @@
import path from 'node:path'
import { installOrcadHostAdapters } from '../../../src/main/orcad/orcad-entry'
import { installOrcadHostAdapters } from '../../../src/main/orcad/orcad-host-adapters'
import type { Store } from '../../../src/main/persistence'
import { createProfileStateStore } from '../../../src/main/persistence/profile-state/profile-state-store-factory'