build method
Generates the outputs for a given BuildStep
.
Implementation
@override
Future<void> build(BuildStep b) async {
final finalAssetId = AssetId(b.inputId.package, 'lib/main.data.dart');
final infos = [
await for (final file in b.findAssets(Glob('**/*.flutter_data.info')))
await b.readAsString(file)
];
final classes = infos.fold<List<Map<String, String>>>([], (acc, line) {
for (final e in line.split(';')) {
final parts = e.split('#');
acc.add({
'className': parts[0],
'classNameLower': DataHelpers.internalTypeFor(parts[0]),
'type': parts[1],
'path': parts[2],
'remote': parts[3],
});
}
return acc;
})
..sort((a, b) => a['type']!.compareTo(b['type']!));
// if this is a library, do not generate
if (classes.any((clazz) => clazz['path']!.startsWith('asset:'))) {
return;
}
final modelImports = classes
.map((clazz) => 'import \'${clazz['path']}\';')
.toSet()
.join('\n');
final adaptersMap = {
for (final clazz in classes)
'\'${clazz['type']}\'':
'ref.watch(internal${clazz['classNameLower'].toString().capitalize()}RemoteAdapterProvider)'
};
final remotesMap = {
for (final clazz in classes) '\'${clazz['type']}\'': clazz['remote']
};
// imports
final isFlutter = await isDependency('flutter', b);
final hasPathProvider = await isDependency('path_provider', b);
final hasFlutterRiverpod = await isDependency('flutter_riverpod', b) ||
await isDependency('hooks_riverpod', b);
final flutterFoundationImport = isFlutter
? "import 'package:flutter/foundation.dart' show kIsWeb;"
: '';
final pathProviderImport = hasPathProvider
? "import 'package:path_provider/path_provider.dart';"
: '';
final riverpodFlutterImport = hasFlutterRiverpod
? "import 'package:flutter_riverpod/flutter_riverpod.dart';"
: '';
final autoBaseDirFn = hasPathProvider
? 'baseDirFn ??= () => getApplicationDocumentsDirectory().then((dir) => dir.path);'
: '';
//
String repositoryWatcherRefExtension(List<Map<String, String>> classes,
{required bool hasWidgets}) {
return '''
${hasWidgets ? '''
extension RepositoryWidgetRefX on WidgetRef {
${classes.map((clazz) => ' Repository<${clazz['className']}> get ${clazz['classNameLower']} => watch(${clazz['classNameLower']}RepositoryProvider)..remoteAdapter.internalWatch = watch;').join('\n')}
}''' : ''}
extension RepositoryRefX on ${hasWidgets ? 'Ref' : 'ProviderContainer'} {
${hasWidgets ? '' : '''
E watch<E>(ProviderListenable<E> provider) {
return readProviderElement(provider as ProviderBase<E>).readSelf();
}
'''}
${classes.map((clazz) => ' Repository<${clazz['className']}> get ${clazz['classNameLower']} => watch(${clazz['classNameLower']}RepositoryProvider)..remoteAdapter.internalWatch = watch${hasWidgets ? ' as Watcher' : ''};').join('\n')}
}''';
}
//
await b.writeAsString(
finalAssetId,
'''\n
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: directives_ordering, top_level_function_literal_block, depend_on_referenced_packages
import 'package:flutter_data/flutter_data.dart';
$flutterFoundationImport
$pathProviderImport
$riverpodFlutterImport
$modelImports
// ignore: prefer_function_declarations_over_variables
ConfigureRepositoryLocalStorage configureRepositoryLocalStorage = ({FutureFn<String>? baseDirFn, List<int>? encryptionKey, LocalStorageClearStrategy? clear}) {
${isFlutter ? 'if (!kIsWeb) {' : ''}
$autoBaseDirFn
${isFlutter ? '} else {' : ''}
${isFlutter ? ' baseDirFn ??= () => \'\';' : ''}
${isFlutter ? '}' : ''}
return hiveLocalStorageProvider.overrideWith(
(ref) => HiveLocalStorage(
hive: ref.read(hiveProvider),
baseDirFn: baseDirFn,
encryptionKey: encryptionKey,
clear: clear,
),
);
};
final repositoryProviders = <String, Provider<Repository<DataModelMixin>>>{
${classes.map((clazz) => '\'' + clazz['type']! + '\': ' + clazz['classNameLower']! + 'RepositoryProvider').join(',\n')}
};
final repositoryInitializerProvider =
FutureProvider<RepositoryInitializer>((ref) async {
${classes.map((clazz) => ' DataHelpers.setInternalType<${clazz['className']}>(\'${clazz['type']}\');').join('\n')}
final adapters = <String, RemoteAdapter>$adaptersMap;
final remotes = <String, bool>$remotesMap;
await ref.watch(graphNotifierProvider).initialize();
// initialize and register
for (final type in repositoryProviders.keys) {
final repository = ref.read(repositoryProviders[type]!);
repository.dispose();
await repository.initialize(
remote: remotes[type],
adapters: adapters,
);
internalRepositories[type] = repository;
}
return RepositoryInitializer();
});
''' +
repositoryWatcherRefExtension(classes,
hasWidgets: hasFlutterRiverpod));
}