UNPKG

@leanix/reporting-cli

Version:

Command line interface to develop custom reports for LeanIX EAM

125 lines (104 loc) 4.15 kB
import type { LxrConfig } from './interfaces' import { join } from 'node:path' import chalk from 'chalk' import { spawn } from 'cross-spawn' import opn from 'opn' import { ApiTokenResolver } from './api-token-resolver' import { loadLxrConfig } from './file.helpers' import { getJwtClaims } from './helpers' interface DevServerStartResult { launchUrl: string localhostUrl: string } export class DevStarter { public async start(): Promise<void> { const config = loadLxrConfig() const accessToken = await this.getAccessToken(config) const result = await this.startLocalServer(config, accessToken) this.openUrlInBrowser(result.launchUrl) console.log(`${chalk.green(`Open the following url to test your report:\n${result.launchUrl}`)}\n`) console.log( chalk.yellow( `If your report is not being loaded, please check if it opens outside of LeanIX via this url:\n${result.localhostUrl}` ) ) } private async startLocalServer(config: LxrConfig, accessToken: string): Promise<DevServerStartResult> { const port = config.localPort || 8080 const localhostUrl = `https://localhost:${port}` const urlEncoded = encodeURIComponent(localhostUrl) const claims = getJwtClaims(accessToken) const instanceUrl = claims.instanceUrl const workspace = claims.principal.permission.workspaceName console.log(chalk.green(`Your workspace is ${workspace}`)) const launchUrl = new URL(`${instanceUrl}/${workspace}/reports/dev?url=${urlEncoded}`) launchUrl.hash = `access_token=${accessToken}` console.log(chalk.green(`Starting development server and launching with url: ${launchUrl}`)) const wpMajorVersion = await this.getCurrentWebpackMajorVersion() const args = ['--port', `${port}`] if (wpMajorVersion < 5) { args.push('--https') } if (config.ssl && config.ssl.cert && config.ssl.key) { args.push(`--cert=${config.ssl.cert}`) args.push(`--key=${config.ssl.key}`) } console.log(`${args.join(' ')}`) let projectRunning = false const webpackCmd = join( ...(wpMajorVersion === 5 ? ['node_modules', '.bin', 'webpack'] : ['node_modules', '.bin', 'webpack-dev-server']) ) const serverProcess = wpMajorVersion === 5 ? spawn(webpackCmd, ['serve', ...args]) : spawn(webpackCmd, args) serverProcess.stdout.on('data', (data) => { console.log(data.toString()) }) // output errors from webpack serverProcess.stderr.on('data', (data) => { const output: string = data.toString() if (output.includes('Project is running')) { projectRunning = true } console.error(chalk.red(data.toString())) }) return new Promise<DevServerStartResult>((resolve) => { serverProcess.on('error', (err) => { console.error(err) }) serverProcess.stdout.on('data', (data) => { const output: string = data.toString() if (output.includes('Project is running')) { projectRunning = true } if (projectRunning && output.toLowerCase().includes('compiled successfully')) { resolve({ launchUrl: launchUrl.toString(), localhostUrl }) } }) }) } private getCurrentWebpackMajorVersion(): Promise<number> { return new Promise((resolve) => { const webpackVersion = spawn(join(...['node_modules', '.bin', 'webpack']), ['-v']) webpackVersion.stdout.on('data', (data) => { const output: string = data.toString() const matches = output.match(/(\d+)\.\d+\.\d+/) const majorVersion = Number.parseInt(matches[0]) resolve(majorVersion) }) }) } private async getAccessToken(config: LxrConfig): Promise<string> { if (!config.apitoken) { throw new Error('no api token provided, please include it in the lxr.json file') } const token = await ApiTokenResolver.getAccessToken(`https://${config.host}`, config.apitoken, config.proxyURL) return token } private openUrlInBrowser(url: string) { try { opn(url) } catch (err) { console.error(`Unable to open your browser: ${err}`) } } }