mirror of
https://github.com/iflytek/skillhub.git
synced 2026-09-24 00:55:35 +00:00
* feat(cli): add OAuth device flow login Signed-off-by: Danny5487401 <64348131+Danny5487401@users.noreply.github.com> * fix(cli): avoid browser launch in headless login Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> * fix(cli): complete device flow runtime path Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> --------- Signed-off-by: Danny5487401 <64348131+Danny5487401@users.noreply.github.com> Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> Co-authored-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com>
56 lines
1.9 KiB
TypeScript
56 lines
1.9 KiB
TypeScript
import { existsSync } from 'node:fs'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
/**
|
|
* Spawn the CLI with a clean environment so host-shell exports like
|
|
* SKILLHUB_REGISTRY or SKILLHUB_TOKEN don't leak into the test process and
|
|
* silently override stored credentials/config. Tests can still inject any
|
|
* SKILLHUB_* variable explicitly via the `env` argument.
|
|
*/
|
|
function sanitizeProcessEnv(): Record<string, string> {
|
|
const cleaned: Record<string, string> = {}
|
|
for (const [key, value] of Object.entries(process.env)) {
|
|
if (typeof value !== 'string') continue
|
|
if (key.startsWith('SKILLHUB_')) continue
|
|
cleaned[key] = value
|
|
}
|
|
return cleaned
|
|
}
|
|
|
|
export interface RunCliOptions {
|
|
/**
|
|
* Working directory for the child process. Defaults to the CLI package root
|
|
* so `bun src/index.ts` resolves. Pass a temp dir when the command scans
|
|
* cwd (e.g. `doctor`) so tests don't leak fixtures into the repo tree.
|
|
*/
|
|
cwd?: string
|
|
}
|
|
|
|
export async function runCli(
|
|
args: string[],
|
|
env: Record<string, string> = {},
|
|
options: RunCliOptions = {}
|
|
) {
|
|
// Use Bun.which() to find bun in PATH, but verify it exists
|
|
const whichBun = await Bun.which('bun')
|
|
const bunPath = (whichBun && existsSync(whichBun)) ? whichBun : process.execPath
|
|
|
|
const cliRoot = fileURLToPath(new URL('../../', import.meta.url))
|
|
const entry = `${cliRoot}src/index.ts`
|
|
|
|
const proc = Bun.spawn({
|
|
cmd: [bunPath, entry, ...args],
|
|
cwd: options.cwd ?? cliRoot,
|
|
// Integration tests must never launch real desktop applications. Tests
|
|
// that exercise browser-launch behavior inject a fake launcher directly.
|
|
env: { ...sanitizeProcessEnv(), CI: 'true', ...env },
|
|
stdout: 'pipe',
|
|
stderr: 'pipe'
|
|
})
|
|
const [stdout, stderr, exitCode] = await Promise.all([
|
|
new Response(proc.stdout).text(),
|
|
new Response(proc.stderr).text(),
|
|
proc.exited
|
|
])
|
|
return { stdout: stdout.trim(), stderr: stderr.trim(), exitCode }
|
|
}
|