import fs from 'fs'; import path from 'path'; import { parse, stringify } from 'yaml'; import { variablesYaml } from '../components/variables'; import fg from 'fast-glob'; import { getGlobalConfig, getProjectPath } from './cluserHelper'; import Fuse from 'fuse.js'; import chalk from 'chalk'; import { Dictionary } from 'tsyringe/dist/typings/types'; import { IExternalReplacement } from './@types/IExternalReplacement'; export function getVariablesPath(componentPath: string = '') { componentPath = componentPath || getProjectPath(); var variablesPath = path.join(componentPath, 'variables.yaml'); if (!fs.existsSync(variablesPath)) { fs.writeFileSync(variablesPath, variablesYaml()); } return variablesPath; } export function createVariable(key: string, value: any) { var variables = getVariables()?.variables || {}; key = `**${key}**`; if (variables[key]) { return key; } variables[key] = value; var cfg = getGlobalConfig(); const variablesFilePath = path.join(cfg.componentPath, 'variables.yaml'); fs.writeFileSync( variablesFilePath, stringify( { variables: variables }, { keepSourceTokens: true, lineWidth: 0 }, ), ); return key; } export function saveVariables(variables: any) { var results = { ...variables }; if (!variables.variables) { results = { variables: variables }; } const componentPath = getProjectPath(); const variablesFilePath = path.join(componentPath, 'variables.yaml'); fs.writeFileSync( variablesFilePath, stringify(results, { keepSourceTokens: true, lineWidth: 0 }), ); } export function appendVariables(variables: any, key: string, value: any) { if (variables[key]) { return variables; } variables[key] = value; return variables; } export function getVariables(componentPath: string = ''): any { const filePath = getVariablesPath(componentPath); var yml = parse(fs.readFileSync(filePath, 'utf8')) as any; return { ...yml, __file_path: filePath, }; } export function readVariableKey( value: string, fromPath: string = '', variables: Dictionary = {}, ): string { if (!value) { // console.error(`${chalk.red("✗")} Variable value is empty`); return ''; } if (variables && variables.variables) { variables = variables.variables || {}; } if (!variables || Object.keys(variables).length === 0) { variables = getVariables(fromPath)?.variables || {}; } var result = Object.keys(variables).find((k) => variables[k] === value); return result || value; } export function readVariableValue( variableKey: string, fromPath: string = '', variables: Dictionary = {}, ): string | number | null { if (!variableKey) { // console.error(`${chalk.red("✗")} Variable key is empty`); return ''; } if (variables && variables.variables) { variables = variables.variables || {}; } if (!variables || Object.keys(variables).length === 0) { variables = getVariables(fromPath)?.variables || {}; } return Object.prototype.hasOwnProperty.call(variables, variableKey) ? variables[variableKey] : variableKey; } export function mergeVariables( variables: Array<{ key: string; value: any }>, override: boolean = true, ) { let componentVariables = getVariables()?.variables || {}; for (var i = 0; i < variables.length; i++) { const variableItem = variables[i]; if (!!componentVariables[variableItem.key] && !override) { continue; } componentVariables[variableItem.key] = variableItem.value; } saveVariables(componentVariables); } export function transferVariables( variableKeys: string[], fromPath: string, toPath: string, replacements: IExternalReplacement[] = [], ) { const variableArr: { key: string; value: any }[] = [] as Array; for (var i = 0; i < variableKeys.length; i++) { let key: string = variableKeys[i]; let value = readVariableValue(key, fromPath); const replacement = replacements.find((r) => r.fromKey === key); if (replacement) { key = replacement.toKey; value = replacement.value; } variableArr.push({ key, value }); } mergeVariables(variableArr, false); } export function searchVariableKeysByValue(value: string): string[] { var variablesDict = getVariables()?.variables || {}; var variables = Object.keys(variablesDict) .filter( (k) => !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test( variablesDict[k], ) && (isNaN(variablesDict[k]) || isNaN(parseFloat(variablesDict[k]))), ) .map((k) => { return { key: k, value: variablesDict[k] }; }); const fuse = new Fuse(variables, { includeScore: true, keys: [ 'key', // will be assigned a `weight` of 1 'value', ], }); const searchResult = fuse .search(value) .sort((a: any, b: any) => parseFloat(a.score) - parseFloat(b.score)) .map((r: any) => r.item.key); return searchResult; } export async function fixVariables() { // 1. Get all the files using fast-glob **/*.yaml // 2. Parse the file using yaml and check if there is a variables key // 3. If there is a variables key, check if the variables key is an object, != null and Object.keys(variables).length > 0 // 4. Merge all the variables and save to path.join(getProjectPath(), "variables.yaml") const projectPath = getProjectPath(); const stream = fg.stream(`${projectPath.replace(/\\/g, '/')}/**/*.yaml`, { onlyFiles: true, }); var variables: any = {}; var filesToDelete: string[] = []; for await (const s of stream) { var filePath = s as string; const fileContent = fs.readFileSync(filePath, 'utf8'); const jsonObject = parse(fileContent); if ( jsonObject.variables && typeof jsonObject.variables === 'object' && Object.keys(jsonObject.variables).length > 0 ) { if (filePath.replace(projectPath, '') !== '/variables.yaml') { console.log( `${chalk.green('✓')} Found Variables in ${chalk.gray(filePath.replace(projectPath, ''))}`, ); filesToDelete.push(filePath); } variables = { ...variables, ...jsonObject.variables }; } } for (const file of filesToDelete) { const fileContent = fs.readFileSync(file, 'utf8'); const jsonObject = parse(fileContent); if (Object.keys(jsonObject).length === 1 && jsonObject.variables) { // delete the file console.log( `${chalk.red('✗')} Deleting Variables in ${chalk.gray(file.replace(projectPath, ''))}`, ); fs.unlinkSync(file); } else { // remove the variables key and write back to file delete jsonObject.variables; fs.writeFileSync( file, stringify(jsonObject, { keepSourceTokens: true, lineWidth: 0 }), ); console.log( `${chalk.yellow('!')} Removed variables key from ${chalk.gray(file.replace(projectPath, ''))}`, ); } } if (filesToDelete.length === 0) { console.log( `${chalk.green('✓')} No incorrect variables found in this project`, ); return; } console.log( `${chalk.green('✓')} Writting Variables to ${chalk.green(path.join(projectPath, 'variables.yaml'))}`, ); fs.writeFileSync( path.join(projectPath, 'variables.yaml'), stringify( { variables: variables }, { keepSourceTokens: true, lineWidth: 0 }, ), ); }