validate method
Validates record and returns a MetadataValidationResult.
Never throws; failures are expressed as MetadataValidationResult.invalid.
Implementation
MetadataValidationResult validate(RemoteTemplateRecord record) {
// ID
if (!_idPattern.hasMatch(record.id)) {
return MetadataValidationResult.invalid(
'Invalid template ID "${record.id}". '
'Must match ^[a-z][a-z0-9_]{0,63}\$.');
}
// Version
try {
TemplateSemVer.parse(record.version);
} catch (_) {
return MetadataValidationResult.invalid(
'Invalid semantic version "${record.version}" for template "${record.id}".');
}
// displayName
if (record.displayName.isEmpty) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has an empty displayName.');
}
if (record.displayName.length > 128) {
return MetadataValidationResult.invalid(
'Template "${record.id}" displayName exceeds 128 characters.');
}
// description
if (record.description.length > 512) {
return MetadataValidationResult.invalid(
'Template "${record.id}" description exceeds 512 characters.');
}
// projectType
if (!allowedProjectTypes.contains(record.projectType)) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has unsupported projectType '
'"${record.projectType}". Allowed: $allowedProjectTypes.');
}
// category — remote cannot claim builtin
if (!allowedRemoteCategories.contains(record.category)) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has invalid or disallowed category '
'"${record.category}". Remote registries may only use: '
'$allowedRemoteCategories.');
}
// maturity
if (record.maturity != null &&
!allowedMaturityValues.contains(record.maturity)) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has invalid maturity "${record.maturity}". '
'Allowed: $allowedMaturityValues.');
}
// tags
for (final tag in record.tags) {
if (!_tagPattern.hasMatch(tag)) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has invalid tag "$tag". '
'Tags must match ^[a-z][a-z0-9_-]{0,63}\$.');
}
}
// capabilities
for (final cap in record.capabilities) {
if (!_tagPattern.hasMatch(cap)) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has invalid capability "$cap".');
}
}
// dependencies
for (final dep in record.dependencies) {
if (!_idPattern.hasMatch(dep)) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has invalid dependency ID "$dep". '
'Must match ^[a-z][a-z0-9_]{0,63}\$.');
}
}
// documentationUrl — must be HTTPS if present
if (record.documentationUrl != null &&
record.documentationUrl!.isNotEmpty) {
try {
final uri = Uri.parse(record.documentationUrl!);
if (uri.scheme != 'https') {
return MetadataValidationResult.invalid(
'Template "${record.id}" documentationUrl must use HTTPS '
'(got "${uri.scheme}").');
}
} catch (_) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has a malformed documentationUrl.');
}
}
// downloadCount
if (record.downloadCount < 0) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has negative downloadCount.');
}
// rating
if (record.rating < 0.0 || record.rating > 5.0) {
return MetadataValidationResult.invalid(
'Template "${record.id}" rating must be between 0.0 and 5.0 '
'(got ${record.rating}).');
}
// minimumDartSdk — must look like a constraint
if (record.minimumDartSdk.isEmpty) {
return MetadataValidationResult.invalid(
'Template "${record.id}" has an empty minimumDartSdk.');
}
if (!_sdkConstraintPattern.hasMatch(record.minimumDartSdk)) {
return MetadataValidationResult.invalid(
'Template "${record.id}" minimumDartSdk '
'"${record.minimumDartSdk}" does not look like a valid SDK constraint.');
}
return MetadataValidationResult.valid(record);
}