import { merge } from '@senojs/lodash' import fse, { pathExists } from 'fs-extra' import { dump, load } from 'js-yaml' import { dirname, join } from 'path' import { fileURLToPath } from 'url' import type { PackageJson } from '../types' import { isFilePath } from '../utils' const { readFile, writeFile, readJson, writeJson, readdir, rename } = fse function getPackageInNodeModulesDir(cwd: string, packageName: string) { const nodeModulesDir = join(cwd, 'node_modules') const packagePath = packageName.split('/') const packageDir = join(nodeModulesDir, ...packagePath) return packageDir } /** * Rename the file name to underline to point * * e.g: `_npmrc` -> `.npmrc` * * @param {string} dirPath */ async function renameHiddenTemplateFiles(dirPath: string) { const dirFiles = await readdir(dirPath) const renameTasks = dirFiles.map(async (file) => { if (/^_/.test(file)) { const currentFilePath = join(dirPath, file) const newFilePath = join(dirPath, file.replace(/^_/, '.')) await rename(currentFilePath, newFilePath) } }) await Promise.all(renameTasks) } async function mergeTemplateJsonIntoPackageJson(templateJsonPath: string, packageJsonPath: string) { const templateJson = await readJson(templateJsonPath) const packageJson = await readJson(packageJsonPath) const mergedJson = merge(packageJson, templateJson) await writeJson(packageJsonPath, mergedJson, { spaces: 2 }) } async function mergeFieldsIntoPackageJson( packageJsonPath: string, fields: Record, ) { const packageJson = await readJson(packageJsonPath) const mergedJson = merge(packageJson, fields) await writeJson(packageJsonPath, mergedJson, { spaces: 2 }) } async function checkFileExists( filePath: string, { ignoreError }: { ignoreError?: boolean } = { ignoreError: false }, ) { const isFileExist = await pathExists(filePath) if (ignoreError) return isFileExist if (!isFileExist) throw new Error(`${filePath} not exists`) return isFileExist } async function getYamlConfigContent( configPath: string, { enableFileExistsCheck }: { enableFileExistsCheck?: boolean } = { enableFileExistsCheck: false }, ) { if (enableFileExistsCheck) { await checkFileExists(configPath) } const rawYamlContent = await readFile(configPath, 'utf-8') const rawPluginConfig = load(rawYamlContent) as T return rawPluginConfig } async function updateYamlConfigContent( configPath: string, content: unknown, options?: { enableFileExistsCheck?: boolean; schemaComment?: string }, ) { const { enableFileExistsCheck = false, schemaComment = '' } = options || {} if (enableFileExistsCheck) { await checkFileExists(configPath) } const yamlContent = schemaComment + dump(content) await writeFile(configPath, yamlContent) } async function checkProjectFilesExists( currentWorkingDirectory: string, relativePath: string | string[], { ignoreError }: { ignoreError?: boolean } = { ignoreError: false }, ) { const paths = Array.isArray(relativePath) ? relativePath : [relativePath] const checkTasks = paths.map((path) => { const filePath = join(currentWorkingDirectory, path) return checkFileExists(filePath, { ignoreError }) }) const checkResults = await Promise.all(checkTasks) const isValidated = checkResults.every((exists) => exists) return isValidated } async function getPackageJsonContent(path: string) { let packageJsonPath = path let packageJsonContent if (isFilePath(path)) { const __filename = fileURLToPath(path) packageJsonPath = join(dirname(__filename), '../package.json') } try { packageJsonContent = (await readJson(packageJsonPath)) as PackageJson } catch { packageJsonContent = {} as PackageJson } return packageJsonContent } async function getCliVersionByMetaPath(metaPath: string) { const packageJsonContent = await getPackageJsonContent(metaPath) return packageJsonContent?.version } export { renameHiddenTemplateFiles, getPackageInNodeModulesDir, getYamlConfigContent, getPackageJsonContent, getCliVersionByMetaPath, updateYamlConfigContent, mergeTemplateJsonIntoPackageJson, mergeFieldsIntoPackageJson, checkFileExists, checkProjectFilesExists, }