import { promises as fsp } from 'node:fs'; import { mergeWith } from 'lodash'; import path from 'node:path'; import { existsAsync } from './fs-helpers'; import { RootAPIHelper } from './root-api'; import { writeFile } from './write-file'; import { CodeDirectoryName, TopLevelDirectoryName } from '../domain/file-names'; export interface CliJsConfigs { code: Record; unitTests: Record; } const getCodeJsConfigPath = (directory: string) => path.join(directory, TopLevelDirectoryName.Code, 'jsconfig.json'); const getUnitTestsJsConfigPath = (directory: string) => path.join(directory, TopLevelDirectoryName.Code, CodeDirectoryName.UnitTests, 'jsconfig.json'); export const getJsConfigs = async (params: { host: string }): Promise => { const { host } = params; const rootApi = new RootAPIHelper({ host }); const [codeJsConfig, unitTestsJsConfig] = await Promise.all([ rootApi.send({ path: '/cli/static/code/jsconfig.json' }), rootApi.send({ path: '/cli/static/unit-tests/jsconfig.json' }), ]); if (codeJsConfig.error || unitTestsJsConfig.error) { const codeErrorMessage = codeJsConfig.error.error || codeJsConfig.error; const unitTestsErrorMessage = unitTestsJsConfig.error.error || unitTestsJsConfig.error; throw new Error(JSON.stringify(codeErrorMessage || unitTestsErrorMessage)); } return { code: codeJsConfig, unitTests: unitTestsJsConfig, }; }; const readCodeJsConfig = async (directory: string) => { const codeJsConfigPath = getCodeJsConfigPath(directory); const codeJsConfigExists = await existsAsync(codeJsConfigPath); return codeJsConfigExists ? JSON.parse(await fsp.readFile(codeJsConfigPath, { encoding: 'utf8' })) : {}; }; const readUnitTestsJsConfig = async (directory: string) => { const unitTestsJsConfigPath = getUnitTestsJsConfigPath(directory); const unitTestsJsConfigExists = await existsAsync(unitTestsJsConfigPath); return unitTestsJsConfigExists ? JSON.parse(await fsp.readFile(unitTestsJsConfigPath, { encoding: 'utf8' })) : {}; }; export const readJsConfigFiles = async (directory: string): Promise => { const [codeJsConfig, unitTestsJsConfig] = await Promise.all([ readCodeJsConfig(directory), readUnitTestsJsConfig(directory), ]); return { code: codeJsConfig, unitTests: unitTestsJsConfig, }; }; const mergeArrays = (objValue: any, srcValue: any) => { if (Array.isArray(objValue)) { return [...new Set(objValue.concat(srcValue))]; } }; export const updateJsConfigFiles = async (params: { directory: string; currentJsConfigs?: CliJsConfigs; newJsConfigs: CliJsConfigs; }) => { const { directory, currentJsConfigs, newJsConfigs } = params; const updateCodeJsConfig = async () => { const updatedCodeJsConfig = currentJsConfigs ? mergeWith(newJsConfigs.code, currentJsConfigs.code, mergeArrays) : newJsConfigs.code; await writeFile(getCodeJsConfigPath(directory), JSON.stringify(updatedCodeJsConfig, null, 2)); }; const updateUnitTestsJsConfig = async () => { if (await existsAsync(path.join(directory, TopLevelDirectoryName.Code, CodeDirectoryName.UnitTests))) { const updatedUnitTestsJsConfig = currentJsConfigs ? mergeWith(newJsConfigs.unitTests, currentJsConfigs.unitTests, mergeArrays) : newJsConfigs.unitTests; await writeFile(getUnitTestsJsConfigPath(directory), JSON.stringify(updatedUnitTestsJsConfig, null, 2)); } }; await Promise.all([updateCodeJsConfig(), updateUnitTestsJsConfig()]); };