import type { ProjectCIDeployConfig, ProjectCIDeployConfigBranch } from '@ones-open/cli-utils' import type { LoginRequestParamsSchema, PickteamCLIOptionsSchema } from '@ones-open/cli-utils' import { isEmpty, pick } from '@senojs/lodash' import inquirer from 'inquirer' import type { QuestionCollection } from 'inquirer' import { getCIDeploymentConfigContent, convertCIDeploymentBranchName } from '../ci' import { convertUsernameField } from '../login' function getBranchCredentialFields( branchName: string, branchConfigMap: Map, ) { const convertedBranchName = convertCIDeploymentBranchName(branchName) const branchConfig = branchConfigMap.get(convertedBranchName) if (!branchConfig) return undefined const branchCredentialFields = pick(branchConfig, ['host', 'username', 'password']) return branchCredentialFields } function checkBranchCredentialFields( branchName: string, branchConfigMap: Map, ) { const convertedBranchName = convertCIDeploymentBranchName(branchName) if (!branchConfigMap.has(convertedBranchName)) { const errorMessage = `No branch found in CI deployment config with name "${branchName}"` + `\nPlease execute "npx op ci -b ${branchName}" first` throw new Error(errorMessage) } const branchCredentialFields = getBranchCredentialFields(convertedBranchName, branchConfigMap) if (!branchCredentialFields || Object.values(branchCredentialFields).some(isEmpty)) { const errorMessage = `No user credential found in CI deployment config with branch name "${branchName}"` + `\nPlease execute "npx op ci -b ${branchName}" first` throw new Error(errorMessage) } return true } interface GetCIDeploymentConfigMapParams { config?: ProjectCIDeployConfig currentWorkingDirectory?: string } async function getCIDeploymentConfigMap(params?: GetCIDeploymentConfigMapParams) { const { config, currentWorkingDirectory } = params ?? {} const configContent = config ?? (await getCIDeploymentConfigContent(currentWorkingDirectory)) // Convert config to Map to make it easier to check const branchConfigMap = new Map( Object.entries(configContent) as [string, ProjectCIDeployConfigBranch][], ) return branchConfigMap } interface PickteamCIDeploymentConfigValidatorOptions { currentWorkingDirectory?: string config?: Map } async function validateCanPickteamForCIDeployment( params: PickteamCLIOptionsSchema, validatorOptions?: PickteamCIDeploymentConfigValidatorOptions, ) { const { currentWorkingDirectory, config } = validatorOptions ?? {} const { branchName } = params const branchConfigMap = config ?? (await getCIDeploymentConfigMap({ currentWorkingDirectory })) if (!branchConfigMap.size) { throw new Error('No branch found in CI deployment config, please execute "npx op ci" first') } if (branchName) return checkBranchCredentialFields(branchName, branchConfigMap) return true } interface ConvertCIDeploymentConfigToLoginParamsType { branchName: string config?: Map } async function convertCIDeploymentConfigToLoginParams({ branchName, config, }: ConvertCIDeploymentConfigToLoginParamsType) { const branchConfigMap = config ?? (await getCIDeploymentConfigMap()) if (!branchConfigMap.size) { throw new Error('No branch found in CI deployment config, params convert failed.') } const credentialFields = getBranchCredentialFields(branchName, branchConfigMap) if (!credentialFields) { throw new Error('No user credential found in CI deployment config, params convert failed.') } const { host: baseURL, username, password, } = credentialFields as Required const params = { baseURL, password, ...convertUsernameField(username), } return params as LoginRequestParamsSchema } interface CIDeploymentPromptsInitialAnswer { branchName: string } async function displayCIDeploymentPrompt( params: Omit, config?: Map, ) { const { branchName } = params const branchConfig = config ?? (await getCIDeploymentConfigMap()) const branchList = Array.from(branchConfig.keys()) const CIDeploymentPrompts: QuestionCollection = [ { title: 'Please select a branch that you want to pick team below:', type: 'list', name: 'branchName', choices: branchList, default: branchName, when: !branchName, askAnswered: true, }, ] const promptResult = await inquirer.prompt(CIDeploymentPrompts, { branchName }) return promptResult } export { convertCIDeploymentConfigToLoginParams, displayCIDeploymentPrompt, getCIDeploymentConfigMap, validateCanPickteamForCIDeployment, } export type { ConvertCIDeploymentConfigToLoginParamsType }