parseExport static method
Parse raw export text (JSON, CSV, or newline-delimited URLs) into links.
Implementation
static List<Map<String, dynamic>> parseExport(String raw) {
final text = raw.trim();
if (text.isEmpty) throw FdlParseError('Export is empty.');
// Try JSON first.
if (text[0] == '{' || text[0] == '[') {
final dynamic json;
try {
json = jsonDecode(text);
} catch (e) {
throw FdlParseError('Export looks like JSON but failed to parse: $e');
}
final List<dynamic> arr;
if (json is List) {
arr = json;
} else if (json is Map && json['links'] is List) {
arr = json['links'] as List;
} else if (json is Map && json['shortLinks'] is List) {
arr = json['shortLinks'] as List;
} else {
arr = [json];
}
if (arr.isEmpty) throw FdlParseError('Export contained zero links.');
final out = <Map<String, dynamic>>[];
for (var i = 0; i < arr.length; i++) {
try {
out.add(_normalizeObject(arr[i]));
} on FdlParseError catch (e) {
throw FdlParseError('Link #${i + 1}: ${e.message}');
}
}
return out;
}
// Otherwise treat as newline-delimited content (ignore blanks/# comments).
final lines = text
.split(RegExp(r'\r?\n'))
.map((l) => l.trim())
.where((l) => l.isNotEmpty && !l.startsWith('#'))
.toList();
if (lines.isEmpty) throw FdlParseError('Export contained zero links.');
// A CSV export has a header row: the first content line has a comma and does
// NOT start with a URL (header cells are column names). A bare-URL list and
// an FDL long-link list both start with `http`, so they stay on the URL path
// even though long links contain commas in their query values.
final first = lines[0];
if (first.contains(',') &&
!RegExp(r'^https?://', caseSensitive: false).hasMatch(first)) {
return parseCsv(lines);
}
final out = <Map<String, dynamic>>[];
for (var i = 0; i < lines.length; i++) {
try {
out.add(parseUrl(lines[i]));
} on FdlParseError catch (e) {
throw FdlParseError('Line #${i + 1}: ${e.message}');
}
}
return out;
}