import ProjectConfig from "@dxatscale/sfpowerscripts.core/lib/project/ProjectConfig" ; import Ajv from "ajv" ; import path = require ( "path" ) ; import * as fs from "fs-extra" ; export default class ProjectValidation { private readonly projectConfig ; private ajv : Ajv ; resourcesDir : string ; constructor ( ) { this . projectConfig = ProjectConfig . getSFDXPackageManifest ( null ) ; this . ajv = new Ajv ( { allErrors : true } ) ; this . resourcesDir = path . join ( __dirname , ".." , "resources" , "schemas" ) ; } public validateSFDXProjectJSON ( ) { let schema = fs . readJSONSync ( path . join ( this . resourcesDir , `sfdx-project.schema.json` ) , { encoding : 'UTF-8' } ) ; let validator = this . ajv . compile ( schema ) ; let isSchemaValid = validator ( this . projectConfig ) ; if ( ! isSchemaValid ) { let errorMsg = `The sfdx-project.json is invalid, Please fix the following errors\n` ; validator . errors . forEach ( ( error , errorNum ) => { errorMsg += `\n${ errorNum + 1 }: ${ error . instancePath }: ${ error . message } ${ JSON . stringify ( error . params , null , 4 ) }` ; } ) ; throw new Error ( errorMsg ) ; } } public validatePackageBuildNumbers ( ) { this . projectConfig . packageDirectories . forEach ( ( pkg ) => { let packageType = ProjectConfig . getPackageType ( this . projectConfig , pkg . package ) ; let pattern = /NEXT$|LATEST$/i ; if ( pkg . versionNumber . match ( pattern ) && ( packageType === "Source" || packageType === "Data" ) ) { throw new Error ( 'sfdx-project.json validation failed for package "' + pkg [ "package" ] + '".' + ' Build-number keywords "NEXT" & "LATEST" are not supported for ' + packageType + ' packages.' + '\nTry the following:' + '\n - If package should be built as a ' + packageType + ' package, use 0 instead of NEXT/LATEST' + '\n - If package should be built as an Unlocked package, ensure the package has been created in the Devhub and the ID included in packageAliases of sfdx-project.json' ) ; } } ) ; } }