create-flutterinit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/bin/index.ts +3 -0
  2. package/package.json +46 -0
  3. package/templates/base/.cursor/rules/flutter-project.mdc.hbs +132 -0
  4. package/templates/base/AGENTS.md.hbs +137 -0
  5. package/templates/base/DESIGN.md.hbs +149 -0
  6. package/templates/base/README.md.hbs +19 -0
  7. package/templates/base/SETUP.md.hbs +253 -0
  8. package/templates/base/analysis_options.yaml +88 -0
  9. package/templates/base/assets/.keep +1 -0
  10. package/templates/base/assets/icons/apple.svg +1 -0
  11. package/templates/base/assets/icons/facebook.svg +1 -0
  12. package/templates/base/assets/icons/google.svg +1 -0
  13. package/templates/base/assets/images/.gitkeep +0 -0
  14. package/templates/base/flutter_native_splash.yaml.hbs +8 -0
  15. package/templates/base/lib/main.dart.hbs +43 -0
  16. package/templates/base/lib/src/app.dart.hbs +105 -0
  17. package/templates/base/lib/src/config/app_config.dart.hbs +112 -0
  18. package/templates/base/lib/src/extensions/collection_extension.dart.hbs +55 -0
  19. package/templates/base/lib/src/extensions/context_extension.dart.hbs +167 -0
  20. package/templates/base/lib/src/extensions/date_time_extension.dart.hbs +40 -0
  21. package/templates/base/lib/src/extensions/extensions.dart.hbs +6 -0
  22. package/templates/base/lib/src/extensions/num_extension.dart.hbs +14 -0
  23. package/templates/base/lib/src/extensions/string_extension.dart.hbs +91 -0
  24. package/templates/base/lib/src/extensions/widget_extension.dart.hbs +47 -0
  25. package/templates/base/lib/src/imports/core_imports.dart.hbs +50 -0
  26. package/templates/base/lib/src/imports/imports.dart.hbs +2 -0
  27. package/templates/base/lib/src/imports/packages_imports.dart.hbs +110 -0
  28. package/templates/base/lib/src/routing/(isGetX)@app_bindings.dart.hbs +23 -0
  29. package/templates/base/lib/src/routing/app_router.dart.hbs +252 -0
  30. package/templates/base/lib/src/routing/app_routes.dart.hbs +46 -0
  31. package/templates/base/lib/src/routing/global_navigator.dart.hbs +15 -0
  32. package/templates/base/lib/src/services/auth_service.dart.hbs +78 -0
  33. package/templates/base/lib/src/services/copy_service.dart.hbs +16 -0
  34. package/templates/base/lib/src/services/internet_connection_service.dart.hbs +10 -0
  35. package/templates/base/lib/src/services/services.dart.hbs +45 -0
  36. package/templates/base/lib/src/shared/app_assets.dart.hbs +15 -0
  37. package/templates/base/lib/src/shared/enums/app_status.dart.hbs +40 -0
  38. package/templates/base/lib/src/shared/enums/button_enums.dart.hbs +22 -0
  39. package/templates/base/lib/src/shared/enums/enums.dart.hbs +3 -0
  40. package/templates/base/lib/src/shared/enums/snack_bar_type.dart.hbs +22 -0
  41. package/templates/base/lib/src/shared/helpers/format_number.dart.hbs +18 -0
  42. package/templates/base/lib/src/shared/helpers/imports.dart.hbs +3 -0
  43. package/templates/base/lib/src/shared/helpers/show_app_sheet.dart.hbs +42 -0
  44. package/templates/base/lib/src/shared/helpers/show_dialog.dart.hbs +49 -0
  45. package/templates/base/lib/src/shared/helpers/show_toast.dart.hbs +92 -0
  46. package/templates/base/lib/src/shared/hooks/hooks.dart.hbs +13 -0
  47. package/templates/base/lib/src/shared/hooks/use_copy.dart.hbs +41 -0
  48. package/templates/base/lib/src/shared/hooks/use_timer.dart.hbs +158 -0
  49. package/templates/base/lib/src/shared/shared.dart.hbs +12 -0
  50. package/templates/base/lib/src/shared/widgets/app_button.dart.hbs +144 -0
  51. package/templates/base/lib/src/shared/widgets/app_card.dart.hbs +126 -0
  52. package/templates/base/lib/src/shared/widgets/app_divider.dart.hbs +88 -0
  53. package/templates/base/lib/src/shared/widgets/app_empty_state.dart.hbs +73 -0
  54. package/templates/base/lib/src/shared/widgets/app_error_widget.dart.hbs +69 -0
  55. package/templates/base/lib/src/shared/widgets/app_icon.dart.hbs +25 -0
  56. package/templates/base/lib/src/shared/widgets/app_loading.dart.hbs +54 -0
  57. package/templates/base/lib/src/shared/widgets/app_text_field.dart.hbs +89 -0
  58. package/templates/base/lib/src/shared/widgets/app_top_bar.dart.hbs +105 -0
  59. package/templates/base/lib/src/shared/widgets/common_image.dart.hbs +120 -0
  60. package/templates/base/lib/src/shared/widgets/toast/imports.dart.hbs +4 -0
  61. package/templates/base/lib/src/shared/widgets/toast/raw_toast.dart.hbs +109 -0
  62. package/templates/base/lib/src/shared/widgets/toast/toast.dart.hbs +142 -0
  63. package/templates/base/lib/src/shared/widgets/toast/toast_card.dart.hbs +57 -0
  64. package/templates/base/lib/src/shared/widgets/widgets.dart.hbs +14 -0
  65. package/templates/base/lib/src/shared/wrappers/(isRiverpod,isProvider,isBloc,isGetX,isMobX)@state_wrapper.dart.hbs +51 -0
  66. package/templates/base/lib/src/shared/wrappers/(supportsLocalization)@localization_wrapper.dart.hbs +25 -0
  67. package/templates/base/lib/src/shared/wrappers/(usesScreenutil)@screen_util_wrapper.dart.hbs +27 -0
  68. package/templates/base/lib/src/shared/wrappers/(usesSkeletonizer)@skeleton_wrapper.dart.hbs +81 -0
  69. package/templates/base/lib/src/shared/wrappers/session_listener_wrapper.dart.hbs +258 -0
  70. package/templates/base/lib/src/shared/wrappers/wrappers.dart.hbs +15 -0
  71. package/templates/base/lib/src/theme/app_borders.dart.hbs +70 -0
  72. package/templates/base/lib/src/theme/app_curves.dart.hbs +69 -0
  73. package/templates/base/lib/src/theme/app_durations.dart.hbs +48 -0
  74. package/templates/base/lib/src/theme/app_shadows.dart.hbs +73 -0
  75. package/templates/base/lib/src/theme/app_spacing.dart.hbs +80 -0
  76. package/templates/base/lib/src/theme/color_schemes.dart.hbs +126 -0
  77. package/templates/base/lib/src/theme/text_theme.dart.hbs +167 -0
  78. package/templates/base/lib/src/theme/theme.dart.hbs +431 -0
  79. package/templates/base/lib/src/theme/theme_constants.dart.hbs +20 -0
  80. package/templates/base/lib/src/utils/app_utils.dart.hbs +46 -0
  81. package/templates/base/lib/src/utils/debouncer.dart.hbs +31 -0
  82. package/templates/base/lib/src/utils/error_handler.dart.hbs +14 -0
  83. package/templates/base/lib/src/utils/failure.dart.hbs +30 -0
  84. package/templates/base/lib/src/utils/input_formatters.dart.hbs +27 -0
  85. package/templates/base/lib/src/utils/logger.dart.hbs +37 -0
  86. package/templates/base/lib/src/utils/platform_info.dart.hbs +13 -0
  87. package/templates/base/lib/src/utils/task_runner.dart.hbs +42 -0
  88. package/templates/base/lib/src/utils/typedefs.dart.hbs +6 -0
  89. package/templates/base/lib/src/utils/utils.dart.hbs +9 -0
  90. package/templates/base/pubspec.yaml.hbs +256 -0
  91. package/templates/base/test/widget_test.dart.hbs +56 -0
  92. package/templates/overlays/architecture/clean/architecture.md +6 -0
  93. package/templates/overlays/architecture/clean/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
  94. package/templates/overlays/architecture/clean/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
  95. package/templates/overlays/architecture/clean/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
  96. package/templates/overlays/architecture/clean/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
  97. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
  98. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
  99. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
  100. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
  101. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
  102. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
  103. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
  104. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
  105. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
  106. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
  107. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
  108. package/templates/overlays/architecture/clean/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
  109. package/templates/overlays/architecture/clean/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
  110. package/templates/overlays/architecture/clean/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
  111. package/templates/overlays/architecture/feature-first/architecture.md +5 -0
  112. package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/models/user_model.dart.hbs +1 -0
  113. package/templates/overlays/architecture/feature-first/lib/src/features/auth/data/repositories/auth_repository_impl.dart.hbs +1 -0
  114. package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/entities/user.dart.hbs +1 -0
  115. package/templates/overlays/architecture/feature-first/lib/src/features/auth/domain/repositories/auth_repository.dart.hbs +1 -0
  116. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
  117. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
  118. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
  119. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
  120. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
  121. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
  122. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
  123. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
  124. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
  125. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/forgot_password_screen.dart.hbs +1 -0
  126. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/login_screen.dart.hbs +1 -0
  127. package/templates/overlays/architecture/feature-first/lib/src/features/auth/presentation/screens/signup_screen.dart.hbs +1 -0
  128. package/templates/overlays/architecture/feature-first/lib/src/features/home/presentation/screens/home_page.dart.hbs +1 -0
  129. package/templates/overlays/architecture/feature-first/lib/src/features/onboarding/presentation/screens/onboarding_page.dart.hbs +1 -0
  130. package/templates/overlays/architecture/layer-first/architecture.md +6 -0
  131. package/templates/overlays/architecture/layer-first/lib/src/data/datasources/local/.gitkeep +0 -0
  132. package/templates/overlays/architecture/layer-first/lib/src/data/datasources/remote/.gitkeep +0 -0
  133. package/templates/overlays/architecture/layer-first/lib/src/data/models/user_model.dart.hbs +1 -0
  134. package/templates/overlays/architecture/layer-first/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
  135. package/templates/overlays/architecture/layer-first/lib/src/domain/entities/user.dart.hbs +1 -0
  136. package/templates/overlays/architecture/layer-first/lib/src/domain/repositories/auth_repository.dart.hbs +1 -0
  137. package/templates/overlays/architecture/layer-first/lib/src/domain/usecases/auth/.gitkeep +0 -0
  138. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@auth_bloc.dart.hbs +1 -0
  139. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isBloc)@session_bloc.dart.hbs +1 -0
  140. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@auth_controller.dart.hbs +1 -0
  141. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isGetX)@session_controller.dart.hbs +1 -0
  142. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@auth_store.dart.hbs +1 -0
  143. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isMobX)@session_store.dart.hbs +1 -0
  144. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@auth_view_model.dart.hbs +1 -0
  145. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isNoneState)@session_manager.dart.hbs +1 -0
  146. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
  147. package/templates/overlays/architecture/layer-first/lib/src/presentation/providers/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
  148. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/forgot_password_screen.dart.hbs +1 -0
  149. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/login_screen.dart.hbs +1 -0
  150. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/auth/signup_screen.dart.hbs +1 -0
  151. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/home/home_page.dart.hbs +1 -0
  152. package/templates/overlays/architecture/layer-first/lib/src/presentation/screens/onboarding/onboarding_page.dart.hbs +1 -0
  153. package/templates/overlays/architecture/layer-first/lib/src/presentation/widgets/.gitkeep +0 -0
  154. package/templates/overlays/architecture/mvc/architecture.md +5 -0
  155. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@auth_bloc.dart.hbs +1 -0
  156. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isBloc)@session_bloc.dart.hbs +1 -0
  157. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@auth_controller.dart.hbs +1 -0
  158. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isGetX)@session_controller.dart.hbs +1 -0
  159. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@auth_store.dart.hbs +1 -0
  160. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isMobX)@session_store.dart.hbs +1 -0
  161. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isNoneState)@session_manager.dart.hbs +1 -0
  162. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@auth_provider.dart.hbs +1 -0
  163. package/templates/overlays/architecture/mvc/lib/src/controllers/auth/(isProvider,isRiverpod)@session_provider.dart.hbs +1 -0
  164. package/templates/overlays/architecture/mvc/lib/src/models/user_model.dart.hbs +1 -0
  165. package/templates/overlays/architecture/mvc/lib/src/services/auth_repository.dart.hbs +1 -0
  166. package/templates/overlays/architecture/mvc/lib/src/services/auth_repository_impl.dart.hbs +1 -0
  167. package/templates/overlays/architecture/mvc/lib/src/views/auth/forgot_password_screen.dart.hbs +1 -0
  168. package/templates/overlays/architecture/mvc/lib/src/views/auth/login_screen.dart.hbs +1 -0
  169. package/templates/overlays/architecture/mvc/lib/src/views/auth/signup_screen.dart.hbs +1 -0
  170. package/templates/overlays/architecture/mvc/lib/src/views/home/home_page.dart.hbs +1 -0
  171. package/templates/overlays/architecture/mvc/lib/src/views/onboarding/onboarding_page.dart.hbs +1 -0
  172. package/templates/overlays/architecture/mvvm/architecture.md +6 -0
  173. package/templates/overlays/architecture/mvvm/lib/src/data/models/user_model.dart.hbs +1 -0
  174. package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository.dart.hbs +1 -0
  175. package/templates/overlays/architecture/mvvm/lib/src/data/repositories/auth_repository_impl.dart.hbs +1 -0
  176. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/auth_bloc.dart.hbs +1 -0
  177. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isBloc)@bloc/session_bloc.dart.hbs +1 -0
  178. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/auth_controller.dart.hbs +1 -0
  179. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isGetX)@controllers/session_controller.dart.hbs +1 -0
  180. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/auth_store.dart.hbs +1 -0
  181. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isMobX)@stores/session_store.dart.hbs +1 -0
  182. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/auth_view_model.dart.hbs +1 -0
  183. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isNoneState)@view_models/session_manager.dart.hbs +1 -0
  184. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/auth_provider.dart.hbs +1 -0
  185. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/(isProvider,isRiverpod)@providers/session_provider.dart.hbs +1 -0
  186. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/forgot_password_screen.dart.hbs +1 -0
  187. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/login_screen.dart.hbs +1 -0
  188. package/templates/overlays/architecture/mvvm/lib/src/ui/auth/signup_screen.dart.hbs +1 -0
  189. package/templates/overlays/architecture/mvvm/lib/src/ui/home/home_page.dart.hbs +1 -0
  190. package/templates/overlays/architecture/mvvm/lib/src/ui/onboarding/onboarding_page.dart.hbs +1 -0
  191. package/templates/overlays/backend/appwrite/lib/src/services/(usesAppwriteAuth)@auth_service.dart.hbs +101 -0
  192. package/templates/overlays/backend/custom/lib/src/services/auth_service.dart.hbs +158 -0
  193. package/templates/overlays/backend/firebase/lib/src/services/(usesFirebaseAuth)@auth_service.dart.hbs +96 -0
  194. package/templates/overlays/backend/supabase/lib/src/services/(usesSupabaseAuth)@auth_service.dart.hbs +97 -0
  195. package/templates/overlays/device/app_version_update/lib/src/services/(usesAppVersionUpdate)@version_update_service.dart.hbs +118 -0
  196. package/templates/overlays/device/device_info/lib/src/services/(usesDeviceInfoPlus)@device_info_service.dart.hbs +54 -0
  197. package/templates/overlays/extras/dotenv/.env.hbs +33 -0
  198. package/templates/overlays/extras/flavors/lib/src/flavors.dart.hbs +15 -0
  199. package/templates/overlays/extras/localization/assets/translations/en.json.hbs +47 -0
  200. package/templates/overlays/media/lib/src/services/(usesImagePicker,usesFilePicker)@media_service.dart.hbs +148 -0
  201. package/templates/overlays/networking/cached_image/lib/src/shared/widgets/app_cached_image.dart.hbs +160 -0
  202. package/templates/overlays/networking/dio/lib/src/services/(usesDio)@dio_service.dart.hbs +50 -0
  203. package/templates/overlays/networking/http/lib/src/services/(usesHttp)@http_service.dart.hbs +82 -0
  204. package/templates/overlays/storage/hive/lib/src/services/(usesHive)@hive_service.dart.hbs +59 -0
  205. package/templates/overlays/storage/secure_storage/lib/src/services/(usesSecureStorage)@secure_storage_service.dart.hbs +39 -0
  206. package/templates/overlays/storage/shared_preferences/lib/src/services/(usesSharedPreferences)@storage_service.dart.hbs +53 -0
  207. package/templates/overlays/utilities/geolocator/lib/src/services/(usesGeolocator)@location_service.dart.hbs +78 -0
  208. package/templates/overlays/utilities/path_provider/lib/src/services/(usesPathProvider)@path_service.dart.hbs +30 -0
  209. package/templates/overlays/utilities/permission_handler/lib/src/services/(usesPermissionHandler)@permission_service.dart.hbs +28 -0
  210. package/templates/overlays/utilities/permission_handler/lib/src/shared/hooks/use_permission.dart.hbs +44 -0
  211. package/templates/overlays/utilities/share_plus/lib/src/services/(usesSharePlus)@share_service.dart.hbs +22 -0
  212. package/templates/overlays/utilities/share_plus/lib/src/shared/hooks/use_share.dart.hbs +26 -0
  213. package/templates/overlays/utilities/url_launcher/lib/src/services/(usesUrlLauncher)@url_launcher_service.dart.hbs +37 -0
  214. package/templates/overlays/utilities/url_launcher/lib/src/shared/hooks/use_launch_url.dart.hbs +52 -0
  215. package/templates/partials/features/auth/auth_logic.hbs +611 -0
  216. package/templates/partials/features/auth/auth_repository.hbs +32 -0
  217. package/templates/partials/features/auth/auth_repository_impl.hbs +116 -0
  218. package/templates/partials/features/auth/forgot_password_screen.hbs +368 -0
  219. package/templates/partials/features/auth/login_screen.hbs +540 -0
  220. package/templates/partials/features/auth/session_provider.hbs +437 -0
  221. package/templates/partials/features/auth/signup_screen.hbs +511 -0
  222. package/templates/partials/features/auth/user_model.hbs +23 -0
  223. package/templates/partials/features/home/home_page.hbs +156 -0
  224. package/templates/partials/features/onboarding/onboarding_page.hbs +264 -0
  225. package/templates/partials/llm/add-feature-workflow.hbs +38 -0
  226. package/templates/partials/llm/architecture-rules.hbs +92 -0
  227. package/templates/partials/llm/backend-rules.hbs +30 -0
  228. package/templates/partials/llm/build-runner-note.hbs +15 -0
  229. package/templates/partials/llm/design-quick-ref.hbs +14 -0
  230. package/templates/partials/llm/design-quick-reference.hbs +14 -0
  231. package/templates/partials/llm/navigation-rules.hbs +27 -0
  232. package/templates/partials/llm/networking-rules.hbs +16 -0
  233. package/templates/partials/llm/packages-list.hbs +26 -0
  234. package/templates/partials/llm/services-conventions.hbs +20 -0
  235. package/templates/partials/llm/stack-summary.hbs +22 -0
  236. package/templates/partials/llm/state-management-rules.hbs +40 -0
  237. package/templates/partials/state_label.hbs +1 -0
@@ -0,0 +1,611 @@
1
+ import 'package:{{flags.appSnake}}/src/imports/core_imports.dart';
2
+ {{#if (or flags.isRiverpod flags.isBloc flags.isMobX flags.isGetX)}}
3
+ import 'package:{{flags.appSnake}}/src/imports/packages_imports.dart';
4
+ {{else if (or flags.isProvider flags.isNoneState)}}
5
+ {{#if (or (eq flags.routerPackage "go_router") (eq flags.routerPackage "auto_route"))}}
6
+ import 'package:{{flags.appSnake}}/src/imports/packages_imports.dart';
7
+ {{/if}}
8
+ {{/if}}
9
+
10
+ {{#if flags.isRiverpod}}
11
+ import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}domain/repositories/{{else if (eq architecture "mvc")}}services/{{else if (eq architecture "mvvm")}}data/repositories/{{else}}features/auth/domain/repositories/{{/if}}auth_repository.dart';
12
+ import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}data/repositories/{{else if (eq architecture "mvc")}}services/{{else if (eq architecture "mvvm")}}data/repositories/{{else}}features/auth/data/repositories/{{/if}}auth_repository_impl.dart';
13
+
14
+ // Provides the single instance of AuthRepositoryImpl
15
+ final authRepositoryProvider = Provider<AuthRepository>((ref) {
16
+ return AuthRepositoryImpl();
17
+ });
18
+
19
+ final authControllerProvider = StateNotifierProvider<AuthController, bool>((ref) {
20
+ return AuthController(
21
+ repository: ref.read(authRepositoryProvider),
22
+ );
23
+ });
24
+
25
+ class AuthController extends StateNotifier<bool> {
26
+ final AuthRepository _repository;
27
+
28
+ AuthController({
29
+ required AuthRepository repository,
30
+ }) : _repository = repository,
31
+ super(false); // loading state is false
32
+
33
+ void login({required BuildContext context, required String email, required String password}) async {
34
+ state = true;
35
+
36
+ final result = await _repository.login(email: email, password: password);
37
+
38
+ state = false;
39
+ result.fold(
40
+ (failure) {
41
+ if (context.mounted) {
42
+ showToast(context, message: failure.message, status: 'error');
43
+ }
44
+ },
45
+ (user) {
46
+ if (rootContext?.mounted ?? false) {
47
+ {{#if (eq flags.routerPackage "go_router")}}
48
+ rootContext!.go(AppRoutes.home);
49
+ {{else if (eq flags.routerPackage "auto_route")}}
50
+ rootContext!.replaceRoute(const HomeRoute());
51
+ {{else}}
52
+ Navigator.pushReplacementNamed(rootContext!, AppRoutes.home);
53
+ {{/if}}
54
+ }
55
+ },
56
+ );
57
+ }
58
+
59
+ void signUp({required BuildContext context, required String name, required String email, required String password}) async {
60
+ state = true;
61
+
62
+ final result = await _repository.signUp(name: name, email: email, password: password);
63
+
64
+ state = false;
65
+ result.fold(
66
+ (failure) {
67
+ if (context.mounted) {
68
+ showToast(context, message: failure.message, status: 'error');
69
+ }
70
+ },
71
+ (user) {
72
+ if (rootContext?.mounted ?? false) {
73
+ {{#if (eq flags.routerPackage "go_router")}}
74
+ rootContext!.go(AppRoutes.home);
75
+ {{else if (eq flags.routerPackage "auto_route")}}
76
+ rootContext!.replaceRoute(const HomeRoute());
77
+ {{else}}
78
+ Navigator.pushReplacementNamed(rootContext!, AppRoutes.home);
79
+ {{/if}}
80
+ }
81
+ },
82
+ );
83
+ }
84
+
85
+ void forgotPassword({required BuildContext context, required String email}) async {
86
+ state = true;
87
+
88
+ final result = await _repository.forgotPassword(email: email);
89
+
90
+ state = false;
91
+ result.fold(
92
+ (failure) {
93
+ if (context.mounted) {
94
+ showToast(context, message: failure.message, status: 'error');
95
+ }
96
+ },
97
+ (success) {
98
+ if (context.mounted) {
99
+ showToast(context, message: 'Password reset link sent successfully', status: 'success');
100
+ }
101
+ if (context.mounted) {
102
+ {{#if (eq flags.routerPackage "go_router")}}
103
+ context.go(AppRoutes.login);
104
+ {{else if (eq flags.routerPackage "auto_route")}}
105
+ context.replaceRoute(const LoginRoute());
106
+ {{else}}
107
+ Navigator.pushReplacementNamed(context, AppRoutes.login);
108
+ {{/if}}
109
+ }
110
+ },
111
+ );
112
+ }
113
+ }
114
+ {{else if flags.isBloc}}
115
+ import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}domain/repositories/{{else if (eq architecture "mvc")}}services/{{else if (eq architecture "mvvm")}}data/repositories/{{else}}features/auth/domain/repositories/{{/if}}auth_repository.dart';
116
+
117
+ class AuthBloc extends Bloc<AuthEvent, AuthState> {
118
+ final AuthRepository _repository;
119
+
120
+ AuthBloc({required AuthRepository repository}) : _repository = repository, super(const AuthState.initial()) {
121
+ on<LoginRequested>(_onLoginRequested);
122
+ on<SignUpRequested>(_onSignUpRequested);
123
+ on<ForgotPasswordRequested>(_onForgotPasswordRequested);
124
+ }
125
+
126
+ Future<void> _onLoginRequested(
127
+ LoginRequested event,
128
+ Emitter<AuthState> emit,
129
+ ) async {
130
+ emit(state.copyWith(isLoading: true));
131
+
132
+ final result = await _repository.login(email: event.email, password: event.password);
133
+
134
+ result.fold(
135
+ (failure) {
136
+ emit(state.copyWith(isLoading: false));
137
+ if (event.context.mounted) {
138
+ showToast(event.context, message: failure.message, status: 'error');
139
+ }
140
+ },
141
+ (user) {
142
+ emit(state.copyWith(isLoading: false));
143
+ if (event.context.mounted) {
144
+ {{#if (eq flags.routerPackage "go_router")}}
145
+ event.context.go(AppRoutes.home);
146
+ {{else if (eq flags.routerPackage "auto_route")}}
147
+ event.context.replaceRoute(const HomeRoute());
148
+ {{else}}
149
+ Navigator.pushReplacementNamed(event.context, AppRoutes.home);
150
+ {{/if}}
151
+ }
152
+ },
153
+ );
154
+ }
155
+
156
+ Future<void> _onSignUpRequested(
157
+ SignUpRequested event,
158
+ Emitter<AuthState> emit,
159
+ ) async {
160
+ emit(state.copyWith(isLoading: true));
161
+
162
+ final result = await _repository.signUp(name: event.name, email: event.email, password: event.password);
163
+
164
+ result.fold(
165
+ (failure) {
166
+ emit(state.copyWith(isLoading: false));
167
+ if (event.context.mounted) {
168
+ showToast(event.context, message: failure.message, status: 'error');
169
+ }
170
+ },
171
+ (user) {
172
+ emit(state.copyWith(isLoading: false));
173
+ if (event.context.mounted) {
174
+ {{#if (eq flags.routerPackage "go_router")}}
175
+ event.context.go(AppRoutes.home);
176
+ {{else if (eq flags.routerPackage "auto_route")}}
177
+ event.context.replaceRoute(const HomeRoute());
178
+ {{else}}
179
+ Navigator.pushReplacementNamed(event.context, AppRoutes.home);
180
+ {{/if}}
181
+ }
182
+ },
183
+ );
184
+ }
185
+
186
+ Future<void> _onForgotPasswordRequested(
187
+ ForgotPasswordRequested event,
188
+ Emitter<AuthState> emit,
189
+ ) async {
190
+ emit(state.copyWith(isLoading: true));
191
+
192
+ final result = await _repository.forgotPassword(email: event.email);
193
+
194
+ result.fold(
195
+ (failure) {
196
+ emit(state.copyWith(isLoading: false));
197
+ if (event.context.mounted) {
198
+ showToast(event.context, message: failure.message, status: 'error');
199
+ }
200
+ },
201
+ (success) {
202
+ emit(state.copyWith(isLoading: false));
203
+ if (event.context.mounted) {
204
+ showToast(event.context, message: 'Password reset link sent successfully', status: 'success');
205
+ }
206
+ if (event.context.mounted) {
207
+ {{#if (eq flags.routerPackage "go_router")}}
208
+ event.context.go(AppRoutes.login);
209
+ {{else if (eq flags.routerPackage "auto_route")}}
210
+ event.context.replaceRoute(const LoginRoute());
211
+ {{else}}
212
+ Navigator.pushReplacementNamed(event.context, AppRoutes.login);
213
+ {{/if}}
214
+ }
215
+ },
216
+ );
217
+ }
218
+ }
219
+
220
+ abstract class AuthEvent extends Equatable {
221
+ const AuthEvent();
222
+ @override
223
+ List<Object> get props => [];
224
+ }
225
+
226
+ class LoginRequested extends AuthEvent {
227
+ final BuildContext context;
228
+ final String email;
229
+ final String password;
230
+ const LoginRequested({required this.context, required this.email, required this.password});
231
+ }
232
+
233
+ class SignUpRequested extends AuthEvent {
234
+ final BuildContext context;
235
+ final String name;
236
+ final String email;
237
+ final String password;
238
+ const SignUpRequested({required this.context, required this.name, required this.email, required this.password});
239
+ }
240
+
241
+ class ForgotPasswordRequested extends AuthEvent {
242
+ final BuildContext context;
243
+ final String email;
244
+ const ForgotPasswordRequested({required this.context, required this.email});
245
+ }
246
+
247
+ class AuthState extends Equatable {
248
+ final bool isLoading;
249
+ const AuthState({required this.isLoading});
250
+ const AuthState.initial() : isLoading = false;
251
+ AuthState copyWith({bool? isLoading}) {
252
+ return AuthState(isLoading: isLoading ?? this.isLoading);
253
+ }
254
+ @override
255
+ List<Object?> get props => [isLoading];
256
+ }
257
+ {{else if flags.isNoneState}}
258
+ import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}domain/repositories/{{else if (eq architecture "mvc")}}services/{{else if (eq architecture "mvvm")}}data/repositories/{{else}}features/auth/domain/repositories/{{/if}}auth_repository.dart';
259
+
260
+ class AuthViewModel extends ChangeNotifier {
261
+ final AuthRepository _repository;
262
+
263
+ AuthViewModel({required AuthRepository repository}) : _repository = repository;
264
+
265
+ bool _isLoading = false;
266
+
267
+ bool get isLoading => _isLoading;
268
+
269
+ void _setLoading(bool value) {
270
+ _isLoading = value;
271
+ notifyListeners();
272
+ }
273
+
274
+ void login({required BuildContext context, required String email, required String password}) async {
275
+ _setLoading(true);
276
+
277
+ final result = await _repository.login(email: email, password: password);
278
+
279
+ _setLoading(false);
280
+ result.fold(
281
+ (failure) {
282
+ if (context.mounted) {
283
+ showToast(context, message: failure.message, status: 'error');
284
+ }
285
+ },
286
+ (user) {
287
+ if (context.mounted) {
288
+ {{#if (eq flags.routerPackage "go_router")}}
289
+ context.go(AppRoutes.home);
290
+ {{else if (eq flags.routerPackage "auto_route")}}
291
+ context.replaceRoute(const HomeRoute());
292
+ {{else}}
293
+ Navigator.pushReplacementNamed(context, AppRoutes.home);
294
+ {{/if}}
295
+ }
296
+ },
297
+ );
298
+ }
299
+
300
+ void signUp({required BuildContext context, required String name, required String email, required String password}) async {
301
+ _setLoading(true);
302
+
303
+ final result = await _repository.signUp(name: name, email: email, password: password);
304
+
305
+ _setLoading(false);
306
+ result.fold(
307
+ (failure) {
308
+ if (context.mounted) {
309
+ showToast(context, message: failure.message, status: 'error');
310
+ }
311
+ },
312
+ (user) {
313
+ if (context.mounted) {
314
+ {{#if (eq flags.routerPackage "go_router")}}
315
+ context.go(AppRoutes.home);
316
+ {{else if (eq flags.routerPackage "auto_route")}}
317
+ context.replaceRoute(const HomeRoute());
318
+ {{else}}
319
+ Navigator.pushReplacementNamed(context, AppRoutes.home);
320
+ {{/if}}
321
+ }
322
+ },
323
+ );
324
+ }
325
+
326
+ void forgotPassword({required BuildContext context, required String email}) async {
327
+ _setLoading(true);
328
+
329
+ final result = await _repository.forgotPassword(email: email);
330
+
331
+ _setLoading(false);
332
+ result.fold(
333
+ (failure) {
334
+ if (context.mounted) {
335
+ showToast(context, message: failure.message, status: 'error');
336
+ }
337
+ },
338
+ (success) {
339
+ if (context.mounted) {
340
+ showToast(context, message: 'Password reset link sent successfully', status: 'success');
341
+ }
342
+ },
343
+ );
344
+ }
345
+ }
346
+ {{else if flags.isProvider}}
347
+ import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}domain/repositories/{{else if (eq architecture "mvc")}}services/{{else if (eq architecture "mvvm")}}data/repositories/{{else}}features/auth/domain/repositories/{{/if}}auth_repository.dart';
348
+
349
+ class AuthProvider extends ChangeNotifier {
350
+ final AuthRepository _repository;
351
+
352
+ AuthProvider({required AuthRepository repository}) : _repository = repository;
353
+
354
+ bool _isLoading = false;
355
+
356
+ bool get isLoading => _isLoading;
357
+
358
+ void _setLoading(bool value) {
359
+ _isLoading = value;
360
+ notifyListeners();
361
+ }
362
+
363
+ void login({required BuildContext context, required String email, required String password}) async {
364
+ _setLoading(true);
365
+
366
+ final result = await _repository.login(email: email, password: password);
367
+
368
+ _setLoading(false);
369
+ result.fold(
370
+ (failure) {
371
+ if (context.mounted) {
372
+ showToast(context, message: failure.message, status: 'error');
373
+ }
374
+ },
375
+ (user) {
376
+ if (context.mounted) {
377
+ {{#if (eq flags.routerPackage "go_router")}}
378
+ context.go(AppRoutes.home);
379
+ {{else if (eq flags.routerPackage "auto_route")}}
380
+ context.replaceRoute(const HomeRoute());
381
+ {{else}}
382
+ Navigator.pushReplacementNamed(context, AppRoutes.home);
383
+ {{/if}}
384
+ }
385
+ },
386
+ );
387
+ }
388
+
389
+ void signUp({required BuildContext context, required String name, required String email, required String password}) async {
390
+ _setLoading(true);
391
+
392
+ final result = await _repository.signUp(name: name, email: email, password: password);
393
+
394
+ _setLoading(false);
395
+ result.fold(
396
+ (failure) {
397
+ if (context.mounted) {
398
+ showToast(context, message: failure.message, status: 'error');
399
+ }
400
+ },
401
+ (user) {
402
+ if (context.mounted) {
403
+ {{#if (eq flags.routerPackage "go_router")}}
404
+ context.go(AppRoutes.home);
405
+ {{else if (eq flags.routerPackage "auto_route")}}
406
+ context.replaceRoute(const HomeRoute());
407
+ {{else}}
408
+ Navigator.pushReplacementNamed(context, AppRoutes.home);
409
+ {{/if}}
410
+ }
411
+ },
412
+ );
413
+ }
414
+
415
+ void forgotPassword({required BuildContext context, required String email}) async {
416
+ _setLoading(true);
417
+
418
+ final result = await _repository.forgotPassword(email: email);
419
+
420
+ _setLoading(false);
421
+ result.fold(
422
+ (failure) {
423
+ if (context.mounted) {
424
+ showToast(context, message: failure.message, status: 'error');
425
+ }
426
+ },
427
+ (success) {
428
+ if (context.mounted) {
429
+ showToast(context, message: 'Password reset link sent successfully', status: 'success');
430
+ }
431
+ if (context.mounted) {
432
+ {{#if (eq flags.routerPackage "go_router")}}
433
+ context.go(AppRoutes.login);
434
+ {{else if (eq flags.routerPackage "auto_route")}}
435
+ context.replaceRoute(const LoginRoute());
436
+ {{else}}
437
+ Navigator.pushReplacementNamed(context, AppRoutes.login);
438
+ {{/if}}
439
+ }
440
+ },
441
+ );
442
+ }
443
+ }
444
+ {{else if flags.isGetX}}
445
+ import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}domain/repositories/{{else if (eq architecture "mvc")}}services/{{else if (eq architecture "mvvm")}}data/repositories/{{else}}features/auth/domain/repositories/{{/if}}auth_repository.dart';
446
+
447
+ class AuthController extends GetxController {
448
+ final AuthRepository _repository;
449
+
450
+ AuthController({required AuthRepository repository}) : _repository = repository;
451
+
452
+ final isLoading = false.obs;
453
+
454
+ void login({required BuildContext context, required String email, required String password}) async {
455
+ isLoading.value = true;
456
+
457
+ final result = await _repository.login(email: email, password: password);
458
+
459
+ isLoading.value = false;
460
+ result.fold(
461
+ (failure) {
462
+ if (context.mounted) {
463
+ showToast(context, message: failure.message, status: 'error');
464
+ }
465
+ },
466
+ (user) {
467
+ Get.offAllNamed(AppRoutes.home);
468
+ },
469
+ );
470
+ }
471
+
472
+ void signUp({required BuildContext context, required String name, required String email, required String password}) async {
473
+ isLoading.value = true;
474
+
475
+ final result = await _repository.signUp(name: name, email: email, password: password);
476
+
477
+ isLoading.value = false;
478
+ result.fold(
479
+ (failure) {
480
+ if (context.mounted) {
481
+ showToast(context, message: failure.message, status: 'error');
482
+ }
483
+ },
484
+ (user) {
485
+ Get.offAllNamed(AppRoutes.home);
486
+ },
487
+ );
488
+ }
489
+
490
+ void forgotPassword({required BuildContext context, required String email}) async {
491
+ isLoading.value = true;
492
+
493
+ final result = await _repository.forgotPassword(email: email);
494
+
495
+ isLoading.value = false;
496
+ result.fold(
497
+ (failure) {
498
+ if (context.mounted) {
499
+ showToast(context, message: failure.message, status: 'error');
500
+ }
501
+ },
502
+ (success) {
503
+ if (context.mounted) {
504
+ showToast(context, message: 'Password reset link sent successfully', status: 'success');
505
+ }
506
+ Get.offNamed(AppRoutes.login);
507
+ },
508
+ );
509
+ }
510
+ }
511
+ {{else if flags.isMobX}}
512
+ import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}domain/repositories/{{else if (eq architecture "mvc")}}services/{{else if (eq architecture "mvvm")}}data/repositories/{{else}}features/auth/domain/repositories/{{/if}}auth_repository.dart';
513
+
514
+ part 'auth_store.g.dart';
515
+
516
+ class AuthStore = AuthStoreBase with _$AuthStore;
517
+
518
+ abstract class AuthStoreBase with Store {
519
+ final AuthRepository _repository;
520
+
521
+ AuthStoreBase({required AuthRepository repository}) : _repository = repository;
522
+
523
+ @observable
524
+ bool isLoading = false;
525
+
526
+ @action
527
+ void login({required BuildContext context, required String email, required String password}) async {
528
+ isLoading = true;
529
+
530
+ final result = await _repository.login(email: email, password: password);
531
+
532
+ isLoading = false;
533
+ result.fold(
534
+ (failure) {
535
+ if (context.mounted) {
536
+ showToast(context, message: failure.message, status: 'error');
537
+ }
538
+ },
539
+ (user) {
540
+ if (context.mounted) {
541
+ {{#if (eq flags.routerPackage "go_router")}}
542
+ context.go(AppRoutes.home);
543
+ {{else if (eq flags.routerPackage "auto_route")}}
544
+ context.replaceRoute(const HomeRoute());
545
+ {{else}}
546
+ Navigator.pushReplacementNamed(context, AppRoutes.home);
547
+ {{/if}}
548
+ }
549
+ },
550
+ );
551
+ }
552
+
553
+ @action
554
+ void signUp({required BuildContext context, required String name, required String email, required String password}) async {
555
+ isLoading = true;
556
+
557
+ final result = await _repository.signUp(name: name, email: email, password: password);
558
+
559
+ isLoading = false;
560
+ result.fold(
561
+ (failure) {
562
+ if (context.mounted) {
563
+ showToast(context, message: failure.message, status: 'error');
564
+ }
565
+ },
566
+ (user) {
567
+ if (context.mounted) {
568
+ {{#if (eq flags.routerPackage "go_router")}}
569
+ context.go(AppRoutes.home);
570
+ {{else if (eq flags.routerPackage "auto_route")}}
571
+ context.replaceRoute(const HomeRoute());
572
+ {{else}}
573
+ Navigator.pushReplacementNamed(context, AppRoutes.home);
574
+ {{/if}}
575
+ }
576
+ },
577
+ );
578
+ }
579
+
580
+ @action
581
+ void forgotPassword({required BuildContext context, required String email}) async {
582
+ isLoading = true;
583
+
584
+ final result = await _repository.forgotPassword(email: email);
585
+
586
+ isLoading = false;
587
+ result.fold(
588
+ (failure) {
589
+ if (context.mounted) {
590
+ showToast(context, message: failure.message, status: 'error');
591
+ }
592
+ },
593
+ (success) {
594
+ if (context.mounted) {
595
+ showToast(context, message: 'Password reset link sent successfully', status: 'success');
596
+ }
597
+ if (context.mounted) {
598
+ {{#if (eq flags.routerPackage "go_router")}}
599
+ context.go(AppRoutes.login);
600
+ {{else if (eq flags.routerPackage "auto_route")}}
601
+ context.replaceRoute(const LoginRoute());
602
+ {{else}}
603
+ Navigator.pushReplacementNamed(context, AppRoutes.login);
604
+ {{/if}}
605
+ }
606
+ },
607
+ );
608
+ }
609
+ }
610
+ {{/if}}
611
+
@@ -0,0 +1,32 @@
1
+ import 'package:{{flags.appSnake}}/src/utils/utils.dart';
2
+ import 'package:{{flags.appSnake}}/src/{{#if (eq architecture "layer-first")}}domain/entities/user.dart{{else if (eq architecture "mvc")}}models/user_model.dart{{else if (eq architecture "mvvm")}}data/models/user_model.dart{{else}}features/auth/domain/entities/user.dart{{/if}}';
3
+
4
+ abstract class AuthRepository {
5
+ /// Stream of auth state changes. Emits AppUser when authenticated, null when not.
6
+ Stream<AppUser?> get onAuthStateChanged;
7
+
8
+ /// Sign in with email and password
9
+ FutureEither<AppUser> login({
10
+ required String email,
11
+ required String password,
12
+ });
13
+
14
+ /// Sign up with email, password, and optional name
15
+ FutureEither<AppUser> signUp({
16
+ required String name,
17
+ required String email,
18
+ required String password,
19
+ });
20
+
21
+ /// Send a password reset email
22
+ FutureEither<void> forgotPassword({
23
+ required String email,
24
+ });
25
+
26
+ /// Sign out the current user
27
+ FutureEither<void> logout();
28
+
29
+ /// Check if the user is currently authenticated natively
30
+ FutureEither<AppUser?> checkAuthState();
31
+ }
32
+