checkRequiredFields function
Checks blueprintYaml against the model classes of metaJson, starting
at the root class rootClass.
Implementation
RequiredFieldsReport checkRequiredFields(
String blueprintYaml,
String metaJson, {
String rootClass = 'D00SolutionBlueprint',
}) {
final classes =
(jsonDecode(metaJson) as Map<String, dynamic>)['classes']
as Map<String, dynamic>;
final report = RequiredFieldsReport();
final doc = ((loadYaml(blueprintYaml) as YamlMap)['document'] as YamlMap)
.values
.first;
void checkForm(String path, List<dynamic> formFields, Object? value) {
report.forms++;
for (final f in formFields.cast<Map<String, dynamic>>()) {
final name = f['name'] as String;
final present = value is YamlMap && value.containsKey(name);
final v = present ? value[name] : null;
if (f['required'] == true && (!present || v == null || v == '')) {
report.missing.add('$path: $name');
}
if (!present) continue;
final text = '$v'.trim();
if (f['type'] == 'int' &&
!(v is int || RegExp(r'^-?\d+$').hasMatch(text))) {
report.badTypes.add('$path: $name = $v');
}
if (f['type'] == 'bool' &&
!(v is bool || text == 'true' || text == 'false')) {
report.badTypes.add('$path: $name = $v');
}
final enumValues = f['enumValues'] as List?;
if (enumValues != null &&
enumValues.isNotEmpty &&
!enumValues.contains(text)) {
report.badTypes.add('$path: $name = $v');
}
}
}
void walk(String cls, Object? node, String path) {
if (node is! YamlMap) return;
final byField = {for (final e in node.entries) _norm('${e.key}'): e.value};
for (final f
in ((classes[cls] as Map<String, dynamic>)['fields'] as List)
.cast<Map<String, dynamic>>()) {
final name = f['name'] as String;
if (!byField.containsKey(name)) continue;
final v = byField[name];
switch (f['kind']) {
case 'form':
checkForm('$path/$name', f['formFields'] as List, v);
case 'complex':
walk(f['type'] as String, v, '$path/$name');
case 'list':
if (f['elementIsComplex'] == true && v is YamlMap) {
v.forEach(
(k, item) => walk(f['elementType'] as String, item, '$path/$k'),
);
}
}
}
}
walk(rootClass, doc, 'SBP');
return report;
}