diff --git a/addons/api_provider/files/di_code.dart b/addons/api_provider/files/di_code.dart new file mode 100644 index 0000000..d8e672c --- /dev/null +++ b/addons/api_provider/files/di_code.dart @@ -0,0 +1,19 @@ +locator.registerLazySingleton( +() => DioConfig( +appConfig: locator(), +), +); + +locator.registerLazySingleton( +() => ErrorHandler( +eventNotifier: locator(), +), +); + +locator.registerLazySingleton( +() => ApiProvider( +dio: locator().dio, +errorHandler: locator(), +listResultField: ApiConstants.listResponseField, +), +); diff --git a/addons/api_provider/files/export.dart b/addons/api_provider/files/export.dart new file mode 100644 index 0000000..ed00a88 --- /dev/null +++ b/addons/api_provider/files/export.dart @@ -0,0 +1,4 @@ +export 'remote/http/api_provider.dart'; +export 'remote/http/request/api_request.dart'; +export 'remote/http/request/api_request_options.dart'; +export 'remote/http/request/http_method.dart'; diff --git a/data/lib/src/providers/shared/remote/http/api_provider.dart b/addons/api_provider/files/src/http/api_provider.dart similarity index 100% rename from data/lib/src/providers/shared/remote/http/api_provider.dart rename to addons/api_provider/files/src/http/api_provider.dart diff --git a/data/lib/src/providers/shared/remote/http/request/api_request.dart b/addons/api_provider/files/src/http/request/api_request.dart similarity index 100% rename from data/lib/src/providers/shared/remote/http/request/api_request.dart rename to addons/api_provider/files/src/http/request/api_request.dart diff --git a/data/lib/src/providers/shared/remote/http/request/api_request_options.dart b/addons/api_provider/files/src/http/request/api_request_options.dart similarity index 100% rename from data/lib/src/providers/shared/remote/http/request/api_request_options.dart rename to addons/api_provider/files/src/http/request/api_request_options.dart diff --git a/data/lib/src/providers/shared/remote/http/request/http_method.dart b/addons/api_provider/files/src/http/request/http_method.dart similarity index 100% rename from data/lib/src/providers/shared/remote/http/request/http_method.dart rename to addons/api_provider/files/src/http/request/http_method.dart diff --git a/addons/api_provider/script.sh b/addons/api_provider/script.sh new file mode 100755 index 0000000..83020c1 --- /dev/null +++ b/addons/api_provider/script.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +source "../shared/functions.sh" + +projectRoot="$1" +ensure_valid_project_root "$projectRoot" + +targetSrcDir="$projectRoot/data/lib/src" + +copy_source_files \ + from="files/src" \ + to="$targetSrcDir/providers/shared/remote" + +append_exports \ + from="files/export.dart" \ + to="$targetSrcDir/providers/shared/shared.dart" + +insert_code_into_method \ + file="$targetSrcDir/di/data_di.dart" \ + method="_initSharedProviders" \ + code="$((AppDatabase.new); \ No newline at end of file diff --git a/addons/drift_database/files/export.dart b/addons/drift_database/files/export.dart new file mode 100644 index 0000000..3205ade --- /dev/null +++ b/addons/drift_database/files/export.dart @@ -0,0 +1,2 @@ +export 'local/database/app_database.dart'; +export 'local/database/tables/example_table.dart'; diff --git a/addons/drift_database/files/src/database/app_database.dart b/addons/drift_database/files/src/database/app_database.dart new file mode 100644 index 0000000..f4b913a --- /dev/null +++ b/addons/drift_database/files/src/database/app_database.dart @@ -0,0 +1,19 @@ +import 'package:drift/drift.dart'; +import 'package:drift/native.dart'; +import 'package:drift_flutter/drift_flutter.dart'; + +import '../../../../../data.dart'; + +part 'app_database.g.dart'; + +@DriftDatabase(tables: [ + ExampleTable, +]) +class AppDatabase extends _$AppDatabase { + AppDatabase.memory() : super(NativeDatabase.memory()); + + AppDatabase() : super(driftDatabase(name: StorageConstants.appDatabaseName)); + + @override + int get schemaVersion => StorageConstants.appDatabaseVersion; +} diff --git a/addons/drift_database/files/src/database/tables/example_table.dart b/addons/drift_database/files/src/database/tables/example_table.dart new file mode 100644 index 0000000..600976b --- /dev/null +++ b/addons/drift_database/files/src/database/tables/example_table.dart @@ -0,0 +1,7 @@ +import 'package:drift/drift.dart'; + +class ExampleTable extends Table { + IntColumn get id => integer().autoIncrement()(); + + TextColumn get name => text().unique()(); +} diff --git a/addons/drift_database/script.sh b/addons/drift_database/script.sh new file mode 100755 index 0000000..0000dd5 --- /dev/null +++ b/addons/drift_database/script.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +set -e + +source "../shared/functions.sh" + +projectRoot="$1" +ensure_valid_project_root "$projectRoot" + +targetSrcDir="$projectRoot/data/lib/src" + +copy_source_files \ + from="files/src" \ + to="$targetSrcDir/providers/shared/local" + +append_exports \ + from="files/export.dart" \ + to="$targetSrcDir/providers/shared/shared.dart" + +insert_code_into_method \ + file="$targetSrcDir/di/data_di.dart" \ + method="_initSharedProviders" \ + code="$( to= +# =============================== +append_exports() { + local from="" + local to="" + + for arg in "$@"; do + case $arg in + from=*) + from="${arg#*=}" + ;; + to=*) + to="${arg#*=}" + ;; + *) + echo "Unknown argument: $arg" + return 1 + ;; + esac + done + + if [[ -z "$from" || -z "$to" ]]; then + echo "Usage: append_exports from= to=" + return 1 + fi + + if [ ! -f "$from" ]; then + echo "Error: Source file '$from' not found!" + return 1 + fi + + cat "$from" >> "$to" + sort "$to" -o "$to" +} + +# =============================== +# Insert Code Into Method Function +# Usage: insert_code_into_method file= method= code='' +# +# Description: +# This function inserts the provided code into the specified method of a given file. +# The insertion occurs based on method signature and braces depth, allowing it to +# handle both empty and non-empty methods correctly. It ensures the method is found +# and properly modified, with the new code inserted in the right place. +# +# Arguments: +# - file= : The path to the file where the method resides. +# - method= : The name of the method where the code will be inserted. +# - code=: The code to be inserted inside the method. +# +# Example: +# insert_code_into_method file="src/my_class.dart" method="myMethod" code="print('Hello, World!');" +# +# The code will be inserted inside the method `myMethod` in the file `src/my_class.dart`. +insert_code_into_method() { + local file="" + local method="" + local code="" + + for arg in "$@"; do + case $arg in + file=*) file="${arg#*=}" ;; + method=*) method="${arg#*=}" ;; + code=*) code="${arg#*=}" ;; + *) echo "Unknown argument: $arg" && return 1 ;; + esac + done + + if [[ -z "$file" || -z "$method" || -z "$code" ]]; then + echo "Usage: insert_code_into_method file= method= code=''" + return 1 + fi + + # Escape code block for awk + local escaped_code="" + while IFS= read -r line; do + line="${line//\\/\\\\}" + line="${line//\"/\\\"}" + escaped_code+="print \" $line\";\n" + done <<< "$code" + + awk -v method="$method" -v code_block="$escaped_code" ' + BEGIN { + in_method = 0 + brace_depth = 0 + } + + function inject_code() { + print "" + cmd = "awk '\''BEGIN{" code_block "}'\''" + while ((cmd | getline line) > 0) { + print line + } + close(cmd) + } + + { + if ($0 ~ "(void|Future) *" method "\\(.*\\) *(async)? *\\{ *\\}") { + sub(/\{\s*\}/, "{", $0) + print + inject_code() + print " }" + next + } + + if ($0 ~ "(void|Future) *" method "\\(.*\\) *(async)? *\\{") { + in_method = 1 + brace_depth = 1 + print + next + } + + if (in_method) { + if ($0 ~ /\{/) brace_depth++ + if ($0 ~ /\}/) brace_depth-- + + if (brace_depth == 0) { + inject_code() + in_method = 0 + } + print + next + } + + print + } + ' "$file" > "$file.tmp" && mv "$file.tmp" "$file" + + dart format "$file" > /dev/null +} + +# =============================== +# Copy directory contents safely +# Usage: copy_source_files from= to= +# +# Ensures the source directory exists. +# If valid, it copies all files from the source to the destination, +# creating the destination directory if it doesn't exist. +# =============================== +copy_source_files() { + local from="" + local to="" + + for arg in "$@"; do + case $arg in + from=*) from="${arg#*=}" ;; + to=*) to="${arg#*=}" ;; + *) echo "Unknown argument: $arg" && return 1 ;; + esac + done + + if [[ -z "$from" || -z "$to" ]]; then + echo "Usage: copy_source_files from= to=" + return 1 + fi + + if [ ! -d "$from" ]; then + echo "Error: Source directory '$from' not found!" + return 1 + fi + + mkdir -p "$to" + cp -r "$from"/* "$to" +} + +# =============================== +# Validate project root +# Usage: ensure_valid_project_root +# =============================== +ensure_valid_project_root() { + local project_path="$1" + + if [ -z "$project_path" ]; then + echo "Error: Specify path to a project root" + exit 1 + fi + + if [ ! -f "$project_path/pubspec.yaml" ]; then + echo "Error: pubspec.yaml not found in project root: $project_path" + exit 1 + fi +} + +# =============================== +# Add a Dart dependency to a project +# Usage: add_dependency project_dir= dependency= [--dev] +# =============================== +add_dependency() { + local project_dir="" + local dependency="" + local is_dev=false + + for arg in "$@"; do + case $arg in + project_dir=*) project_dir="${arg#*=}" ;; + dependency=*) dependency="${arg#*=}" ;; + --dev) is_dev=true ;; + *) echo "Unknown argument: $arg" && return 1 ;; + esac + done + + if [ -z "$project_dir" ] || [ -z "$dependency" ]; then + echo "Error: Both project directory and dependency are required." + return 1 + fi + + ( + cd "$project_dir" || exit + if $is_dev; then + dart pub add --dev "$dependency" > /dev/null + else + dart pub add "$dependency" > /dev/null + fi + ) +} + +## +# @function inject_member +# @brief Injects Dart member code before the last closing brace in a file. +# +# @param file="" Path to the target Dart file. +# @param code="" Code to inject (supports multi-line). +# @flag --newBlock Optional: adds a blank line before the new code. +# +# @example +# constantsCode=$(cat <&2; return 1 ;; + esac + done + + if [[ -z "$file" || -z "$code" ]]; then + echo "Missing file= or code=" >&2 + return 1 + fi + + if [[ ! -f "$file" ]]; then + echo "File not found: $file" >&2 + return 1 + fi + + local lastLineNum + lastLineNum=$(grep -n '}' "$file" | tail -n1 | cut -d: -f1) + + local i=1 + while IFS= read -r line; do + if [[ "$i" -eq "$lastLineNum" ]]; then + # Handle inline case: class A { ... } + if [[ "$line" =~ \{[^\}]*\} ]]; then + local newLine="${line%\}} $code }" + echo "$newLine" + else + if [[ "$newBlock" == true ]]; then + echo "" + fi + printf "%s\n" "$code" + echo "$line" + fi + else + echo "$line" + fi + ((i++)) + done < "$file" > "${file}.injected" + + mv "${file}.injected" "$file" +} diff --git a/addons/websocket_provider/files/di_code.dart b/addons/websocket_provider/files/di_code.dart new file mode 100644 index 0000000..3c4c706 --- /dev/null +++ b/addons/websocket_provider/files/di_code.dart @@ -0,0 +1,5 @@ +locator.registerLazySingleton( +() => WebSocketApiProvider( +baseUrl: locator().webSocketBaseUrl, +), +); \ No newline at end of file diff --git a/addons/websocket_provider/files/export.dart b/addons/websocket_provider/files/export.dart new file mode 100644 index 0000000..958e4e1 --- /dev/null +++ b/addons/websocket_provider/files/export.dart @@ -0,0 +1 @@ +export 'remote/web_socket/web_socket_api_provider.dart'; diff --git a/data/lib/src/providers/shared/remote/web_socket/web_socket_api_provider.dart b/addons/websocket_provider/files/src/web_socket/web_socket_api_provider.dart similarity index 100% rename from data/lib/src/providers/shared/remote/web_socket/web_socket_api_provider.dart rename to addons/websocket_provider/files/src/web_socket/web_socket_api_provider.dart diff --git a/addons/websocket_provider/script.sh b/addons/websocket_provider/script.sh new file mode 100755 index 0000000..a60a2b1 --- /dev/null +++ b/addons/websocket_provider/script.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +set -e + +source "../shared/functions.sh" + +projectRoot="$1" +ensure_valid_project_root "$projectRoot" + +targetSrcDir="$projectRoot/data/lib/src" + +copy_source_files \ + from="files/src" \ + to="$targetSrcDir/providers/shared/remote" + +append_exports \ + from="files/export.dart" \ + to="$targetSrcDir/providers/shared/shared.dart" + +insert_code_into_method \ + file="$targetSrcDir/di/data_di.dart" \ + method="_initSharedProviders" \ + code="$( _initSharedProviders(GetIt locator) async { - locator.registerLazySingleton( - () => DioConfig( - appConfig: locator(), - ), - ); - - locator.registerLazySingleton( - () => ErrorHandler( - eventNotifier: locator(), - ), - ); - locator.registerSingletonAsync( () async => LocalDataProvider( prefs: await SharedPreferences.getInstance(), ), ); - - locator.registerLazySingleton( - () => ApiProvider( - dio: locator().dio, - errorHandler: locator(), - listResultField: ApiConstants.listResponseField, - ), - ); - - locator.registerLazySingleton( - () => WebSocketApiProvider( - baseUrl: locator().webSocketBaseUrl, - ), - ); } static void _initProviders(GetIt locator) {} diff --git a/data/lib/src/providers/shared/shared.dart b/data/lib/src/providers/shared/shared.dart index a15f3ba..adc7596 100644 --- a/data/lib/src/providers/shared/shared.dart +++ b/data/lib/src/providers/shared/shared.dart @@ -1,5 +1 @@ export 'local/local_data_provider.dart'; -export 'remote/http/api_provider.dart'; -export 'remote/http/request/api_request.dart'; -export 'remote/http/request/api_request_options.dart'; -export 'remote/web_socket/web_socket_api_provider.dart'; diff --git a/data/pubspec.yaml b/data/pubspec.yaml index 0f597f2..40f49b4 100644 --- a/data/pubspec.yaml +++ b/data/pubspec.yaml @@ -16,7 +16,6 @@ dependencies: path: ../domain json_annotation: ^4.9.0 - web_socket_channel: ^3.0.2 shared_preferences: ^2.5.3 dev_dependencies: diff --git a/files/fast_prebuild_script_mac.sh b/files/fast_prebuild_script_mac.sh index cd1c2cd..6564ec5 100644 --- a/files/fast_prebuild_script_mac.sh +++ b/files/fast_prebuild_script_mac.sh @@ -23,7 +23,7 @@ allDirs ( cd "core" || exit echo_styled "Generating localization keys in core" 33 -dart run easy_localization:generate -f keys -o locale_keys.g.dart -O lib/src/localization/generated -S resources/lang + dart run easy_localization:generate -f keys -o locale_keys.g.dart -O lib/src/localization/generated -S resources/lang ) # Generate data layer files