import fs from "fs" ; import yaml from "js-yaml" ; import path from "path" ; import { logger } from "../../logger" ; import { BedrockFile , BedrockFileInfo , HelmConfig , RingConfig , Rings , } from "../../types" ; import { writeVersion , getVersion } from "../fileutils" ; import { build as buildError } from "../errorBuilder" ; import { errorStatusCode } from "../errorStatusCode" ; import { createTempDir } from "../ioUtil" ; import * as indexByNameMigration from "./migrations/service-map-to-list" ; export const YAML_NAME = "bedrock.yaml" ; export const DEFAULT_CONTENT = ( ) : BedrockFile => ( { rings : { } , services : [ ] , variableGroups : [ ] , version : getVersion ( ) , } ) ; param dir param data return export const create = ( dir ? , data ? ) : string => { dir = dir || createTempDir ( ) ; const absPath = path . resolve ( dir ) ; data = data || DEFAULT_CONTENT ( ) ; const asYaml = yaml . safeDump ( data , { lineWidth : Number . MAX_SAFE_INTEGER , } ) ; writeVersion ( path . join ( absPath , YAML_NAME ) ) ; fs . appendFileSync ( path . join ( absPath , YAML_NAME ) , asYaml ) ; return absPath ; } ; param dir return export const isExists = ( dir ) : boolean => { if ( ! dir ) { return false ; } const absPath = path . resolve ( dir ) ; const bedrockFilePath = path . join ( absPath , YAML_NAME ) ; return fs . existsSync ( bedrockFilePath ) ; } ; param dir export const read = ( dir ) : BedrockFile => { const absPath = path . resolve ( dir ) ; const file = path . join ( absPath , YAML_NAME ) ; const b = yaml . safeLoad ( fs . readFileSync ( file , "utf8" ) ) ; return indexByNameMigration . migrate ( b , dir ) ; } ; param dir param newServicePath param svcDisplayName param helmConfig param middlewares param k8sBackendPort param k8sBackend param pathPrefix param pathPrefixMajorVersion param buildVariableGroup export const addNewService = ( dir , newServicePath , svcDisplayName , helmConfig , middlewares , k8sBackendPort , k8sBackend , pathPrefix , pathPrefixMajorVersion , serviceBuildVg , serviceBuildVariables ) : void => { const absPath = path . resolve ( dir ) ; const data = read ( absPath ) ; data . services = [ ... data . services . filter ( ( s ) => s . displayName !== svcDisplayName ) , { displayName : svcDisplayName , path : "./" + newServicePath , helm : helmConfig , k8sBackend , k8sBackendPort , middlewares , pathPrefix , pathPrefixMajorVersion , serviceBuildVg , serviceBuildVariables , } , ] ; const asYaml = yaml . safeDump ( data , { lineWidth : Number . MAX_SAFE_INTEGER , } ) ; fs . writeFileSync ( path . join ( absPath , YAML_NAME ) , asYaml ) ; } ; param bedrockFile param ringName export const setDefaultRing = ( bedrockFile , ringName , dir ) : void => { const rings = Object . keys ( bedrockFile . rings ) ; if ( ! rings . includes ( ringName ) ) { throw buildError ( errorStatusCode . FILE_IO_ERR , { errorKey : "bedrock-yaml-ring-set-default-not-found" , values : [ ringName , YAML_NAME ] , } ) ; } for ( const [ name , value ] of Object . entries ( bedrockFile . rings ) ) { if ( value === null ) { bedrockFile . rings [ name ] = { } ; } const ring = bedrockFile . rings [ name ] ; if ( name === ringName ) { ring . isDefault = true ; } else { if ( typeof ring . isDefault !== "undefined" ) { delete ring . isDefault ; } } } create ( dir , bedrockFile ) ; } ; param dir param ringName export const addNewRing = ( dir , ringName ) : void => { const absPath = path . resolve ( dir ) ; const data = read ( absPath ) ; data . rings [ ringName ] = { } ; const asYaml = yaml . safeDump ( data , { lineWidth : Number . MAX_SAFE_INTEGER , } ) ; fs . writeFileSync ( path . join ( absPath , YAML_NAME ) , asYaml ) ; } ; param rootProjectPath export const fileInfo = ( rootProjectPath ? ) : BedrockFileInfo => { rootProjectPath = rootProjectPath || process . cwd ( ) ; const absProjectPath = path . resolve ( rootProjectPath ) ; try { const bedrockFile = read ( absProjectPath ) ; logger . debug ( `variableGroups length: ${ bedrockFile ?. variableGroups ?. length }` ) ; logger . verbose ( `bedrockFile: \n ${ JSON . stringify ( bedrockFile ) }` ) ; return { exist : true , hasVariableGroups : ( bedrockFile ?. variableGroups ?? [ ] ) . length > 0 , } ; } catch ( error ) { logger . error ( error ) ; return { exist : false , hasVariableGroups : false , } ; } } ; throws throws param bedrock param ringToDelete export const removeRing = ( bedrock , ringToDelete ) : BedrockFile => { const rings = Object . entries ( bedrock . rings ) . map ( ( [ name , config ] ) => ( { config , name , } ) ) ; const matchingRing = rings . find ( ( { name } ) => name === ringToDelete ) ; if ( matchingRing === undefined ) { throw buildError ( errorStatusCode . FILE_IO_ERR , { errorKey : "bedrock-yaml-ring-remove-not-found" , values : [ ringToDelete , "bedrock.yaml" ] , } ) ; } if ( matchingRing . config . isDefault ) { throw buildError ( errorStatusCode . ENV_SETTING_ERR , { errorKey : "bedrock-yaml-ring-remove-default" , values : [ matchingRing . name ] , } ) ; } const updatedRings = rings . reduce ( ( updated , ring ) => { if ( ring . name === ringToDelete ) { return updated ; } return { ... updated , [ ring . name ] : ring . config } ; } , { } ) ; const bedrockWithoutRing = { ... bedrock , rings : updatedRings , } ; return bedrockWithoutRing ; } ; param b export const getRings = ( b ) : Array < RingConfig & { name : string ; } > => { return Object . entries ( b . rings ) . map ( ( [ name , config ] ) => ( { ... config , name , isDefault : ! ! config . isDefault , } ) ) ; } ; param bedrock throws export const validateRings = ( bedrock ) : void => { const rings = getRings ( bedrock ) ; const defaultRings = rings . filter ( ( ring ) => ring . isDefault ) ; if ( defaultRings . length > 1 ) { const defaultRingsNames = defaultRings . map ( ( ring ) => ring . name ) . join ( ", " ) ; throw buildError ( errorStatusCode . ENV_SETTING_ERR , { errorKey : "bedrock-yaml-ring-validation-err-many-rings" , values : [ defaultRingsNames ] , } ) ; } } ; param bedrock param dir param variableGroupName export const addVariableGroup = ( bedrock , dir , variableGroupName ) : void => { const absProjectRoot = path . resolve ( dir ) ; logger . info ( `Setting variable group ${ variableGroupName }` ) ; logger . verbose ( `Bedrock file content in ${ dir }: \n ${ JSON . stringify ( bedrock ) }` ) ; if ( bedrock . variableGroups && bedrock . variableGroups . length > 0 ) { if ( variableGroupName in bedrock . variableGroups ) { logger . info ( `Variable group '${ variableGroupName }' already exits in '${ dir }/bedrock.yaml'.` ) ; return ; } } bedrock . variableGroups = [ ... ( bedrock . variableGroups ?? [ ] ) , variableGroupName , ] ; create ( absProjectRoot , bedrock ) ; } ;