Skip to content

Commit 3061da1

Browse files
committed
Merge branch 'feat/add-linked-files' into develop
2 parents 74e6432 + ed4d755 commit 3061da1

File tree

1 file changed

+43
-15
lines changed

1 file changed

+43
-15
lines changed

lib/src/asset_loader.dart

Lines changed: 43 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ abstract class AssetLoader {
2424
/// default used is RootBundleAssetLoader which uses flutter's assetloader
2525
///
2626
class RootBundleAssetLoader extends AssetLoader {
27+
// Place inside class RootBundleAssetLoader
28+
static const int _maxLinkedDepth = 32;
29+
2730
const RootBundleAssetLoader();
2831

2932
String getLocalePath(String basePath, Locale locale) {
@@ -35,28 +38,48 @@ class RootBundleAssetLoader extends AssetLoader {
3538
}
3639

3740
Future<Map<String, dynamic>> _getLinkedTranslationFileDataFromBaseJson(
38-
String basePath, Locale locale, Map<String, dynamic> baseJson,
39-
{List<String> fileLoaded = const []}) async {
40-
Map<String, dynamic> fullJson = Map<String, dynamic>.from(baseJson);
41+
String basePath,
42+
Locale locale,
43+
Map<String, dynamic> baseJson, {
44+
required Set<String> visited,
45+
int depth = 0,
46+
}) async {
47+
if (depth > _maxLinkedDepth) {
48+
throw StateError('Maximum linked files depth ($_maxLinkedDepth) exceeded for $locale at $basePath.');
49+
}
50+
51+
final Map<String, dynamic> fullJson = Map<String, dynamic>.from(baseJson);
4152

42-
for (var entry in baseJson.entries) {
43-
var key = entry.key;
53+
for (final entry in baseJson.entries) {
54+
final key = entry.key;
4455
var value = entry.value;
4556

4657
if (value is String && value.startsWith(':/')) {
47-
String filePath = value.substring(2);
58+
final rawPath = value.substring(2).trim();
59+
final linkedAssetPath = _getLinkedLocalePath(basePath, rawPath, locale);
4860

49-
if (fileLoaded.contains(filePath)) {
50-
throw Exception('Circular reference detected: $filePath is loaded multiple times');
61+
if (visited.contains(linkedAssetPath)) {
62+
throw StateError('Cyclic linked files detected at "$linkedAssetPath" (key: "$key").');
5163
}
5264

53-
fileLoaded.add(filePath);
54-
value = json.decode(await rootBundle.loadString(_getLinkedLocalePath(basePath, filePath, locale)));
55-
}
65+
final Map<String, dynamic> linkedJson =
66+
json.decode(await rootBundle.loadString(linkedAssetPath)) as Map<String, dynamic>;
5667

57-
if (value is Map<String, dynamic>) {
58-
fullJson[key] =
59-
await _getLinkedTranslationFileDataFromBaseJson(basePath, locale, value, fileLoaded: fileLoaded);
68+
visited.add(linkedAssetPath);
69+
try {
70+
final resolved = await _getLinkedTranslationFileDataFromBaseJson(
71+
basePath,
72+
locale,
73+
linkedJson,
74+
visited: visited,
75+
depth: depth + 1,
76+
);
77+
fullJson[key] = resolved;
78+
} catch (e) {
79+
throw StateError(
80+
'Error resolving linked file "$linkedAssetPath" for key "$key": $e',
81+
);
82+
}
6083
}
6184
}
6285

@@ -69,6 +92,11 @@ class RootBundleAssetLoader extends AssetLoader {
6992
EasyLocalization.logger.debug('Load asset from $path');
7093

7194
Map<String, dynamic> baseJson = json.decode(await rootBundle.loadString(localePath));
72-
return await _getLinkedTranslationFileDataFromBaseJson(path, locale, baseJson);
95+
return await _getLinkedTranslationFileDataFromBaseJson(
96+
path,
97+
locale,
98+
baseJson,
99+
visited: <String>{},
100+
);
73101
}
74102
}

0 commit comments

Comments
 (0)