Repository navigation
Expand file tree
/
Copy pathlauncher.ts
More file actions
executable file
·52 lines (45 loc) · 1.57 KB
/
Copy pathlauncher.ts
File metadata and controls
executable file
·52 lines (45 loc) · 1.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/env bun
interface ModuleResolutionError {
code?: unknown
message?: unknown
}
function asModuleResolutionError(error: unknown): ModuleResolutionError | null {
return typeof error === 'object' && error !== null ? error : null
}
/** Identifies dependency-resolution failures without masking setup/configuration errors. */
export function isMissingDependencyError(error: unknown): boolean {
const candidate = asModuleResolutionError(error)
if (candidate?.code !== 'ERR_MODULE_NOT_FOUND' && candidate?.code !== 'MODULE_NOT_FOUND') {
return false
}
return (
typeof candidate.message === 'string' &&
/Cannot find (?:package|module) ['"][^./][^'"]*['"]/.test(candidate.message)
)
}
/** Reconstructs the public command instead of exposing the internal launcher path. */
export function retrySetupCommand(args: readonly string[]): string {
if (args[0] === 'setup') return ['bun run setup', ...args.slice(1)].join(' ')
return ['bun run sim', ...args].join(' ')
}
export function missingDependenciesMessage(retryCommand: string): string {
return [
'',
'✗ Setup dependencies are missing or out of date.',
'',
' Run: bun install',
` Then retry: ${retryCommand}`,
].join('\n')
}
export async function launchSetupCli(
args: readonly string[] = process.argv.slice(2)
): Promise<void> {
try {
await import('./index.ts')
} catch (error) {
if (!isMissingDependencyError(error)) throw error
console.error(missingDependenciesMessage(retrySetupCommand(args)))
process.exitCode = 1
}
}
if (import.meta.main) await launchSetupCli()