UNPKG

@holochain/hc-spin

Version:

CLI to run Holochain apps during development.

109 lines (101 loc) 3.36 kB
import fs from 'fs'; import path from 'path'; import { UISource } from './windows'; export type CliOpts = { appId?: string; holochainPath?: string; numAgents?: number; networkSeed?: string; targetArcFactor?: number; uiPath?: string; uiPort?: number; relayUrl?: string; bootstrapUrl?: string; openDevtools?: boolean; }; export type CliOptsValidated = { appId: string; holochainPath: string | undefined; numAgents: number; networkSeed: string | undefined; targetArcFactor: number | undefined; uiSource: UISource; relayUrl: string | undefined; bootstrapUrl: string | undefined; happOrWebhappPath: HappOrWebhappPath; openDevtools: boolean; }; export type HappOrWebhappPath = { type: 'happ' | 'webhapp'; path: string; }; export function validateCliArgs( cliArgs: string[], cliOpts: CliOpts, appDataRootDir: string, ): CliOptsValidated { if (cliArgs.length !== 1) { throw new Error( `hc spin takes exactly one argument (the path to the .happ or .webhapp file) but got ${cliArgs.length} arguments: ${cliArgs}`, ); } const happOrWebhappPath = cliArgs[0]; if (!happOrWebhappPath.endsWith('.happ') && !happOrWebhappPath.endsWith('.webhapp')) { throw new Error( `The path passed to hc spin must either be a .happ or a .webhapp file but got path '${happOrWebhappPath}'`, ); } if (!fs.existsSync(happOrWebhappPath)) { throw new Error( `Path to .happ or .webhapp file passed as argument does not exist: ${happOrWebhappPath}`, ); } if ( cliOpts.numAgents !== undefined && (typeof cliOpts.numAgents !== 'number' || Number.isNaN(cliOpts.numAgents)) ) { throw new Error( `The --num-agents (-n) option must be of type number but got: ${cliOpts.numAgents}`, ); } if ( cliOpts.targetArcFactor !== undefined && (typeof cliOpts.targetArcFactor !== 'number' || Number.isNaN(cliOpts.targetArcFactor)) ) { throw new Error( `The --target-arc-factor (-t) option must be a valid number but got: ${cliOpts.targetArcFactor}`, ); } const isHapp = happOrWebhappPath.endsWith('.happ'); if (isHapp && !cliOpts.uiPath && !cliOpts.uiPort) { throw new Error( 'If you pass a .happ file as argument, you must also provide either the --ui-port or the --ui-path option pointing to the UI assets.', ); } if (cliOpts.uiPath && cliOpts.uiPort) { throw new Error( 'Only one of --ui-port and --ui-path is allowed at the same time but got values for both.', ); } const appId = cliOpts.appId ? cliOpts.appId : path.parse(path.basename(cliArgs[0])).name; const holochainPath = cliOpts.holochainPath; const numAgents = cliOpts.numAgents ? cliOpts.numAgents : 2; return { appId, holochainPath, numAgents, networkSeed: cliOpts.networkSeed, targetArcFactor: cliOpts.targetArcFactor, uiSource: cliOpts.uiPath ? { type: 'path', path: cliOpts.uiPath } : cliOpts.uiPort ? { type: 'port', port: cliOpts.uiPort } : { type: 'path', path: path.join(appDataRootDir, 'apps', appId, 'ui') }, relayUrl: cliOpts.relayUrl, bootstrapUrl: cliOpts.bootstrapUrl, happOrWebhappPath: isHapp ? { type: 'happ', path: happOrWebhappPath } : { type: 'webhapp', path: happOrWebhappPath }, openDevtools: cliOpts.openDevtools ? true : false, }; }