|
|
|
@ -81,6 +81,13 @@ export function serializeEidosConfig(options: EidosConfig): string {
|
|
|
|
export function validateEidosConfig(options: EidosConfig): EidosValidationReport {
|
|
|
|
export function validateEidosConfig(options: EidosConfig): EidosValidationReport {
|
|
|
|
const issues: EidosValidationIssue[] = []
|
|
|
|
const issues: EidosValidationIssue[] = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!validateEidosConfigShape(options, issues)) {
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
ok: false,
|
|
|
|
|
|
|
|
issues
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
validateColorScales(options, issues)
|
|
|
|
validateColorScales(options, issues)
|
|
|
|
validateColorRoles(options, issues)
|
|
|
|
validateColorRoles(options, issues)
|
|
|
|
validateTypography(options, issues)
|
|
|
|
validateTypography(options, issues)
|
|
|
|
@ -117,6 +124,61 @@ export function assertValidEidosConfig(options: EidosConfig): void {
|
|
|
|
throw new EidosConfigValidationError(report.issues)
|
|
|
|
throw new EidosConfigValidationError(report.issues)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function validateEidosConfigShape(
|
|
|
|
|
|
|
|
options: EidosConfig,
|
|
|
|
|
|
|
|
issues: EidosValidationIssue[]
|
|
|
|
|
|
|
|
): options is EidosConfig {
|
|
|
|
|
|
|
|
const input = options as unknown
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!isPlainRecord(input)) {
|
|
|
|
|
|
|
|
issues.push({
|
|
|
|
|
|
|
|
path: '',
|
|
|
|
|
|
|
|
message: 'Eidos config must be a plain object'
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let ok = true
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!isPlainRecord(input.primitives)) {
|
|
|
|
|
|
|
|
issues.push({
|
|
|
|
|
|
|
|
path: 'primitives',
|
|
|
|
|
|
|
|
message: 'Eidos config must define a primitives object'
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
ok = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const semantics = input.semantics
|
|
|
|
|
|
|
|
const color = isPlainRecord(semantics) ? semantics.color : undefined
|
|
|
|
|
|
|
|
const roles = isPlainRecord(color) ? color.roles : undefined
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!isPlainRecord(roles)) {
|
|
|
|
|
|
|
|
issues.push({
|
|
|
|
|
|
|
|
path: 'semantics.color.roles',
|
|
|
|
|
|
|
|
message: 'Eidos config must define semantic color roles'
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
ok = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (input.themes !== undefined && !isPlainRecord(input.themes)) {
|
|
|
|
|
|
|
|
issues.push({
|
|
|
|
|
|
|
|
path: 'themes',
|
|
|
|
|
|
|
|
message: 'Eidos config themes must be a plain object'
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
ok = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (input.recipes !== undefined && !isPlainRecord(input.recipes)) {
|
|
|
|
|
|
|
|
issues.push({
|
|
|
|
|
|
|
|
path: 'recipes',
|
|
|
|
|
|
|
|
message: 'Eidos config recipes must be a plain object'
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
ok = false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ok
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function listEidosColorScales(options: EidosConfig): readonly string[] {
|
|
|
|
export function listEidosColorScales(options: EidosConfig): readonly string[] {
|
|
|
|
return Object.keys(options.primitives.color?.scales ?? {})
|
|
|
|
return Object.keys(options.primitives.color?.scales ?? {})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|