ensureValidNsid function
void
ensureValidNsid(
- String nsid
)
Implementation
void ensureValidNsid(final String nsid) {
final split = nsid.split('.');
final toCheck = split.last == '*'
? split.sublist(0, split.length - 1).join('.')
: split.join('.');
if (!_allowedCharsRegExp.hasMatch(toCheck)) {
throw InvalidNsidError(
'Disallowed characters in NSID (ASCII letters, digits, dashes, '
'periods only)',
);
}
// Overall length limit is 317 characters (current atproto spec).
if (nsid.length > 317) {
throw InvalidNsidError('NSID is too long (317 chars max)');
}
final labels = toCheck.split('.');
// An NSID requires at least three segments: two (or more) domain
// authority segments and one trailing name segment. For a namespace
// glob (ending in `*`), the same applies to the authority + glob.
if (split.length < 3) {
throw InvalidNsidError('NSID needs at least three parts');
}
for (var i = 0; i < labels.length; i++) {
final label = labels[i];
if (label.isEmpty) {
throw InvalidNsidError('NSID parts can not be empty');
}
// Every segment (domain authority parts and the trailing name
// segment) is capped at 63 characters per the current atproto spec.
if (label.length > 63) {
throw InvalidNsidError('NSID part too long (max 63 chars)');
}
if (label.startsWith('-') || label.endsWith('-')) {
throw InvalidNsidError('NSID parts can not start or end with hyphen');
}
}
// Only the first segment (the TLD of the domain authority) must not
// start with a digit; other domain authority segments may (eg,
// `com.4chan.example` is valid).
if (_digitStartRegExp.hasMatch(labels.first)) {
throw InvalidNsidError('NSID first part may not start with a digit');
}
// The name segment (final label) must be ASCII letters and digits only,
// starting with a letter. This does not apply to namespace globs, where
// the trailing `*` stands in for the name segment.
if (split.last != '*' && !_nameSegmentRegExp.hasMatch(labels.last)) {
throw InvalidNsidError(
'NSID name part must be only letters and digits (and no leading digit)',
);
}
}