@interopio/cli
Version:
Interop.io CLI - a command line for creating Interop.io applications
93 lines (92 loc) • 5.5 kB
JavaScript
/* eslint-disable import/default */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { ux } from "@oclif/core";
import decompress from "decompress";
import fs from "fs-extra/esm";
import log4js from "log4js";
import { existsSync } from "node:fs";
import { copyFile, mkdir, rm } from "node:fs/promises";
import { join } from "node:path";
import { TEMP_ZIP_NAME } from "../../shared/constants.js";
import locatorService from "../locator.service.js";
export class BrowserClientService {
currentDir = process.cwd();
logger = log4js.getLogger("NewBrowserClientService");
async build(config) {
const { appName, template, version } = config;
this.logger.info(`Creating new ${appName} app with io.CB version ${version} and template ${template}`);
ux.info(`Creating new ${appName} app with io.CB version ${version} and template ${template}`);
const cliConfig = await locatorService.configurationService.getCliConfig();
const appDir = join(this.currentDir, appName);
this.logger.info(`Making new app directory at ${appDir}`);
await mkdir(appDir);
this.logger.info(`New app directory created at ${appDir}, proceeding with fetching ${template} template`);
const resolvedMode = await this.getZipTemplate(config, cliConfig);
this.logger.info(`Fetched ${template} template with mode ${resolvedMode}, proceeding with unpacking`);
ux.info(`Proceeding with ${resolvedMode} template`);
await this.unpackZipTemplate(appDir, template, join(appDir, TEMP_ZIP_NAME));
this.logger.info(`New ${appName} app creation complete.`);
ux.info(`New Browser Client Creation Complete. Please run "cd ./${appName}" and "npm install" to install dependencies and "npm start" to start the app.`);
}
async clean(config) {
const appDir = join(this.currentDir, config.appName);
this.logger.info(`Cleaning up the app directory at ${appDir}`);
await rm(appDir, { force: true, recursive: true });
ux.action.stop(`New "Browser Client" Creation Failed. Cleaned up the app directory.`);
this.logger.info(`Cleaned up the app directory at ${appDir}`);
}
async getZipTemplate(config, cliConfig) {
const { appName, version } = config;
const appDir = join(this.currentDir, appName);
const zipLocation = join(appDir, TEMP_ZIP_NAME);
if (cliConfig.mode === "remote") {
this.logger.info(`Fetching remote template ${version}, to zip location ${zipLocation}`);
await this.resolveRemoteZip(version, zipLocation);
this.logger.info(`Completed remote template fetch`);
return "remote";
}
if (cliConfig.mode === "offline") {
this.logger.info(`Fetching offline template ${version}, to zip location ${zipLocation}`);
await this.resolveLocalZip(version, zipLocation);
this.logger.info(`Completed local template fetch`);
return "offline";
}
try {
this.logger.info(`Fetching remote template ${version}, to zip location ${zipLocation}, with auto mode`);
await this.resolveRemoteZip(version, zipLocation);
this.logger.info(`Completed remote template fetch with auto mode`);
return "remote";
}
catch (error) {
this.logger.warn(`Could not get the remote template, falling back to the offline template. Reason: ${error.message}`);
ux.warn(`Could not get the remote template, falling back to the offline template. Reason: ${error.message}`);
await this.resolveLocalZip(version, zipLocation, `Unable to get the remote template, resolved to the offline template ${version}`);
this.logger.info(`Completed local fallback template fetch with auto mode`);
return "offline";
}
}
async resolveLocalZip(version, zipLocation, stopMessage) {
ux.action.start(`Fetching offline template ${version}`);
const verifiedVersion = await locatorService.validationService.transformVersion(version, "ioCb", "offline");
const { root } = locatorService.configurationService.directoryConfig;
const templateLocation = join(root, "templates", verifiedVersion ? `${verifiedVersion}.zip` : "latest.zip");
existsSync(templateLocation) || ux.error(`Could not find the offline template ${version}`);
await copyFile(templateLocation, zipLocation);
ux.action.stop(stopMessage);
}
async resolveRemoteZip(version, zipLocation, stopMessage) {
ux.action.start(`Downloading remote template ${version}`);
const verifiedVersion = await locatorService.validationService.transformVersion(version, "ioCb", "remote");
await locatorService.downloaderService.downloadRemoteZip(verifiedVersion, zipLocation);
ux.action.stop(stopMessage);
}
async unpackZipTemplate(appDir, template, zipLocation) {
await mkdir(join(appDir, "temp"));
await decompress(zipLocation, join(appDir, "temp"), { strip: 1 });
const source = join(appDir, "temp", `browser-client-${template}`);
existsSync(source) || ux.error(`Could not find the template ${join(appDir, "temp", `browser-client-${template}`)}`);
fs.copySync(source, appDir, { overwrite: true });
await rm(zipLocation, { force: true, recursive: true });
await rm(join(appDir, "temp"), { force: true, recursive: true });
}
}