@vtex/fsp-cli
Version:
A VTEX CLI
128 lines (98 loc) • 3.32 kB
text/typescript
import { writeFile } from 'node:fs/promises'
import path from 'node:path'
import { cwd } from 'node:process'
import { input, select } from '@inquirer/prompts'
import { Args, Command } from '@oclif/core'
import { loadConfig } from '@vtex/fsp-config'
import { availableModules, load, moduleCliMap } from '../modules.js'
export class Create extends Command {
static ACCOUNT_PROMPT = 'What is the account name?'
static MODULE_PROMPT = 'Which module do you want to initialize?'
static PATH_PROMPT = (moduleName: string) => {
return `What should be the path to initialize ${moduleName}?`
}
static args = {
account: Args.string({
required: false,
description: 'Name of the account to be initialized',
}),
moduleName: Args.string({
required: false,
description: 'Name of the module to be initialized',
}),
path: Args.string({
required: false,
description: 'Path of where to initialize the module',
}),
}
static description = 'Add a new faststore module on the monorepo.'
static examples = ['<%= config.bin %> <%= command.id %>']
static flags = {}
async run(): Promise<void> {
const { args } = await this.parse(Create)
let account = args.account
if (!account) {
account = await input({ message: Create.ACCOUNT_PROMPT })
}
let moduleName = args.moduleName
if (!moduleName) {
moduleName = await select({
message: Create.MODULE_PROMPT,
choices: availableModules.map((module) => ({
name: module,
value: module,
})),
})
}
let modulePath = args.path
if (!modulePath) {
modulePath = await input({
message: Create.PATH_PROMPT(moduleName),
default: `./packages/${moduleName}`,
})
}
const currentConfig = await loadConfig()
currentConfig.stores = currentConfig.stores ?? {}
if (currentConfig.stores?.[account]?.[moduleName]) {
this.error(`${moduleName} has already been initialized for ${account}.`, {
code: 'Already Initialized Module',
exit: 1,
})
}
const accountConfig = currentConfig.stores[account] ?? {}
const hasModules = Object.keys(accountConfig).length > 0
/**
* The module port is initally 3001.
* We must find the correct port later on.
*/
let modulePort = 3001
/**
* If there are already modules in the store we search for the largest port number available.
* The new module port will be the largestPort + 1
*/
if (hasModules) {
let largestPort = modulePort
for (const module of Object.keys(accountConfig)) {
const port = accountConfig[module].port
if (port && port > largestPort) {
largestPort = port
}
}
modulePort = largestPort + 1
}
currentConfig.stores[account] = {
...accountConfig,
[moduleName]: {
path: modulePath,
port: modulePort,
},
}
this.log(`Initializing ${moduleName} for ${account} in ${modulePath}`)
const cli = await load({ cli: moduleCliMap[moduleName], path: modulePath })
await cli.commands.create.run([modulePath])
await writeFile(
path.join(cwd(), 'faststore.json'),
`${JSON.stringify(currentConfig, undefined, 2)}\n`
)
}
}