import { getPackageJsonContent } from '@ones-open/cli-utils' import { BACKEND_PACKAGEJSON_PATH } from '@ones-open/cli-utils' import chalk from 'chalk' import enquirer from 'enquirer' import fse from 'fs-extra' import type Listr from 'listr' import { join } from 'path' import { mergeAndCheckDependency } from '../common' import type { AbilityItemInfo } from './ability-info' import type { AddAbilityTasksContext } from './index' import { cwd } from 'process' const { readdir, writeJson } = fse export interface AbilityTemplateInfo { name: string rawName: string templateName: string templateKey: string version: string yamlPath: string templatePath: string sqlTemplatePath: string packageJsonPath: string } async function getTargetAbilityTemplate( templateMap: Map, ): Promise { const templates = Array.from(templateMap.values()).map( (ability) => ability.templateName as string, ) const { targetTemplateName } = await enquirer.prompt<{ targetTemplateName: string }>({ type: 'autocomplete', name: 'targetTemplateName', message: 'Please select a template:', choices: templates, }) const targetTemplate = templateMap.get(targetTemplateName) if (!targetTemplate) throw new Error(`Template ${targetTemplateName} not found`) return targetTemplate } async function getAbilityTemplates(abilityInfo: AbilityItemInfo) { const { dirPath, version, rawName, name: abilityName } = abilityInfo const abilityDirs = await readdir(dirPath, { withFileTypes: true }) let firstTemplateName const abilityTemplatesMap = new Map() for (const dirInfo of abilityDirs) { if (!dirInfo.isDirectory()) { continue } const dirname = dirInfo.name const [abilityVersion, type] = dirname.split('-') if (abilityVersion !== version) { continue } const templatePathPrefix = join(dirPath, dirname, rawName) const templateName = dirname const packageJsonPath = join(dirPath, dirname, 'package.json') abilityTemplatesMap.set(templateName, { name: abilityName, rawName, version, templateName, templateKey: type, yamlPath: `${templatePathPrefix}.yaml`, templatePath: `${templatePathPrefix}.ts`, sqlTemplatePath: `${templatePathPrefix}.sql`, packageJsonPath, }) if (!firstTemplateName) { firstTemplateName = templateName } } if (abilityTemplatesMap.size < 2) { return abilityTemplatesMap.get(firstTemplateName) } return abilityTemplatesMap } async function updateAbilityDependencies( path: string, task: Listr.ListrTaskWrapper, ctx: AddAbilityTasksContext, ) { const backendPackageJsonPath = join(cwd(), BACKEND_PACKAGEJSON_PATH) const backendPackageContent = await getPackageJsonContent(backendPackageJsonPath) const { dependencies: abilityDependencies } = await getPackageJsonContent(path) const { dependencies: backendDependencies } = backendPackageContent const { mergedDependency, majorChanges, shouldUpdateDependency } = mergeAndCheckDependency( backendDependencies, abilityDependencies, ) ctx.shouldUpdateDependency = shouldUpdateDependency // 依赖无变化,跳过 if (!shouldUpdateDependency) { task.skip('There are no dependency changes here~') return } // 有marjor更新,提示用户注意! if (majorChanges?.length) { const changeMap: Record = {} majorChanges.forEach(async (item) => { changeMap[item.key] = `${item.before} -> ${item.after}` }) const indent = ` ` const warning = chalk.yellow( `${indent}Warning: There are some dependencies major changes, please check the changes carefully in the docs!`, ) const content = chalk.yellow( `${JSON.stringify(changeMap, null, 2) .split('\n') .map((line) => `${indent}${line}`) .join('\n')}`, ) task.title += `\n${warning}\n${content}` } backendPackageContent.dependencies = mergedDependency writeJson(backendPackageJsonPath, backendPackageContent, { spaces: 2 }) } export { getTargetAbilityTemplate, getAbilityTemplates, updateAbilityDependencies }