kasy-cli 1.2.1

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 (735) hide show
  1. package/README.md +56 -0
  2. package/bin/kasy.js +529 -0
  3. package/docs/cli-reference.md +251 -0
  4. package/lib/commands/add.js +777 -0
  5. package/lib/commands/check.js +240 -0
  6. package/lib/commands/codemagic.js +161 -0
  7. package/lib/commands/deploy.js +257 -0
  8. package/lib/commands/docs.js +47 -0
  9. package/lib/commands/doctor.js +227 -0
  10. package/lib/commands/features.js +36 -0
  11. package/lib/commands/ios.js +206 -0
  12. package/lib/commands/new.js +1870 -0
  13. package/lib/commands/notifications.js +207 -0
  14. package/lib/commands/remove.js +466 -0
  15. package/lib/commands/run.js +75 -0
  16. package/lib/commands/update.js +382 -0
  17. package/lib/commands/validate.js +131 -0
  18. package/lib/scaffold/CHANGELOG.json +6 -0
  19. package/lib/scaffold/backends/api/.flutter-plugins-dependencies +1 -0
  20. package/lib/scaffold/backends/api/analysis_options.yaml +5 -0
  21. package/lib/scaffold/backends/api/generator.js +76 -0
  22. package/lib/scaffold/backends/api/patch/README.md +85 -0
  23. package/lib/scaffold/backends/api/patch/android/app/src/main/AndroidManifest.xml +87 -0
  24. package/lib/scaffold/backends/api/patch/ios/Runner/AppDelegate.swift +61 -0
  25. package/lib/scaffold/backends/api/patch/lib/core/data/api/meta_ads_api.dart +80 -0
  26. package/lib/scaffold/backends/api/patch/lib/core/data/api/storage_api.dart +117 -0
  27. package/lib/scaffold/backends/api/patch/lib/core/data/api/user_api.dart +148 -0
  28. package/lib/scaffold/backends/api/patch/lib/core/data/entities/json_converters.dart +35 -0
  29. package/lib/scaffold/backends/api/patch/lib/core/data/entities/user_entity.dart +48 -0
  30. package/lib/scaffold/backends/api/patch/lib/core/rating/widgets/review_popup.dart +211 -0
  31. package/lib/scaffold/backends/api/patch/lib/environnements.dart +151 -0
  32. package/lib/scaffold/backends/api/patch/lib/features/authentication/api/authentication_api.dart +303 -0
  33. package/lib/scaffold/backends/api/patch/lib/features/authentication/api/authentication_api_interface.dart +80 -0
  34. package/lib/scaffold/backends/api/patch/lib/features/authentication/repositories/authentication_repository.dart +406 -0
  35. package/lib/scaffold/backends/api/patch/lib/features/camera/xfile_extension.dart +6 -0
  36. package/lib/scaffold/backends/api/patch/lib/features/feedbacks/api/entities/feature_request_entity.dart +24 -0
  37. package/lib/scaffold/backends/api/patch/lib/features/feedbacks/api/entities/feature_vote_entity.dart +21 -0
  38. package/lib/scaffold/backends/api/patch/lib/features/feedbacks/api/feature_request_api.dart +52 -0
  39. package/lib/scaffold/backends/api/patch/lib/features/feedbacks/api/feature_vote_api.dart +60 -0
  40. package/lib/scaffold/backends/api/patch/lib/features/llm_chat/api/llm_chat_api.dart +58 -0
  41. package/lib/scaffold/backends/api/patch/lib/features/llm_chat/api/llm_chat_message_entity.dart +29 -0
  42. package/lib/scaffold/backends/api/patch/lib/features/notifications/api/device_api.dart +398 -0
  43. package/lib/scaffold/backends/api/patch/lib/features/notifications/api/entities/device_entity.dart +39 -0
  44. package/lib/scaffold/backends/api/patch/lib/features/notifications/api/entities/notifications_entity.dart +23 -0
  45. package/lib/scaffold/backends/api/patch/lib/features/notifications/api/notifications_api.dart +333 -0
  46. package/lib/scaffold/backends/api/patch/lib/features/notifications/providers/models/notification.dart +185 -0
  47. package/lib/scaffold/backends/api/patch/lib/features/onboarding/api/entities/user_info_entity.dart +26 -0
  48. package/lib/scaffold/backends/api/patch/lib/features/onboarding/api/user_infos_api.dart +107 -0
  49. package/lib/scaffold/backends/api/patch/lib/features/onboarding/models/user_info.dart +94 -0
  50. package/lib/scaffold/backends/api/patch/lib/features/onboarding/repositories/user_infos_repository.dart +29 -0
  51. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/animations/movefade_anim.dart +34 -0
  52. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/components/onboarding_att_setup.dart +66 -0
  53. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +73 -0
  54. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +173 -0
  55. package/lib/scaffold/backends/api/patch/lib/features/settings/ui/widgets/avatar_utils.dart +33 -0
  56. package/lib/scaffold/backends/api/patch/lib/features/subscription/api/entities/subscription_entity.dart +34 -0
  57. package/lib/scaffold/backends/api/patch/lib/features/subscription/api/subscription_api.dart +49 -0
  58. package/lib/scaffold/backends/api/patch/lib/features/subscription/shared/maybeshow_premium.dart +88 -0
  59. package/lib/scaffold/backends/api/patch/lib/main.dart +256 -0
  60. package/lib/scaffold/backends/api/patch/lib/router.dart +133 -0
  61. package/lib/scaffold/backends/api/pubspec.yaml.tpl +108 -0
  62. package/lib/scaffold/backends/firebase/deploy.js +1006 -0
  63. package/lib/scaffold/backends/firebase/generator.js +24 -0
  64. package/lib/scaffold/backends/firebase/setup-from-scratch.js +1008 -0
  65. package/lib/scaffold/backends/firebase/tokens.js +113 -0
  66. package/lib/scaffold/backends/supabase/.flutter-plugins-dependencies +1 -0
  67. package/lib/scaffold/backends/supabase/analysis_options.yaml +5 -0
  68. package/lib/scaffold/backends/supabase/config.toml +34 -0
  69. package/lib/scaffold/backends/supabase/deploy.js +485 -0
  70. package/lib/scaffold/backends/supabase/edge-functions/delete-user-account/README.md +15 -0
  71. package/lib/scaffold/backends/supabase/edge-functions/delete-user-account/index.ts +97 -0
  72. package/lib/scaffold/backends/supabase/edge-functions/llm-chat/index.ts +156 -0
  73. package/lib/scaffold/backends/supabase/edge-functions/meta-track-event/index.ts +292 -0
  74. package/lib/scaffold/backends/supabase/edge-functions/revenuecat-webhook/README.md +30 -0
  75. package/lib/scaffold/backends/supabase/edge-functions/revenuecat-webhook/index.ts +488 -0
  76. package/lib/scaffold/backends/supabase/edge-functions/send-push-notification/README.md +35 -0
  77. package/lib/scaffold/backends/supabase/edge-functions/send-push-notification/index.ts +314 -0
  78. package/lib/scaffold/backends/supabase/generator.js +108 -0
  79. package/lib/scaffold/backends/supabase/migrations/20240101000001_initial_schema.sql +149 -0
  80. package/lib/scaffold/backends/supabase/migrations/20240101000002_storage_bucket.sql +40 -0
  81. package/lib/scaffold/backends/supabase/migrations/20240101000005_vote_triggers.sql +34 -0
  82. package/lib/scaffold/backends/supabase/migrations/20240101000006_notification_webhook.sql +36 -0
  83. package/lib/scaffold/backends/supabase/migrations/20240101000007_welcome_notification.sql +64 -0
  84. package/lib/scaffold/backends/supabase/migrations/20240101000008_user_feature_requests.sql +2 -0
  85. package/lib/scaffold/backends/supabase/migrations/20240101000009_llm_messages.sql +22 -0
  86. package/lib/scaffold/backends/supabase/migrations/20240101000010_notification_image.sql +2 -0
  87. package/lib/scaffold/backends/supabase/patch/README.md +121 -0
  88. package/lib/scaffold/backends/supabase/patch/android/app/src/main/AndroidManifest.xml +87 -0
  89. package/lib/scaffold/backends/supabase/patch/ios/Runner/AppDelegate.swift +61 -0
  90. package/lib/scaffold/backends/supabase/patch/lib/core/data/api/meta_ads_api.dart +75 -0
  91. package/lib/scaffold/backends/supabase/patch/lib/core/data/api/storage_api.dart +83 -0
  92. package/lib/scaffold/backends/supabase/patch/lib/core/data/api/user_api.dart +143 -0
  93. package/lib/scaffold/backends/supabase/patch/lib/core/data/entities/json_converters.dart +35 -0
  94. package/lib/scaffold/backends/supabase/patch/lib/core/data/entities/user_entity.dart +48 -0
  95. package/lib/scaffold/backends/supabase/patch/lib/core/rating/widgets/review_popup.dart +211 -0
  96. package/lib/scaffold/backends/supabase/patch/lib/environnements.dart +149 -0
  97. package/lib/scaffold/backends/supabase/patch/lib/features/authentication/api/authentication_api.dart +546 -0
  98. package/lib/scaffold/backends/supabase/patch/lib/features/authentication/repositories/authentication_repository.dart +410 -0
  99. package/lib/scaffold/backends/supabase/patch/lib/features/camera/xfile_extension.dart +6 -0
  100. package/lib/scaffold/backends/supabase/patch/lib/features/feedbacks/api/entities/feature_request_entity.dart +25 -0
  101. package/lib/scaffold/backends/supabase/patch/lib/features/feedbacks/api/entities/feature_vote_entity.dart +21 -0
  102. package/lib/scaffold/backends/supabase/patch/lib/features/feedbacks/api/feature_request_api.dart +59 -0
  103. package/lib/scaffold/backends/supabase/patch/lib/features/feedbacks/api/feature_vote_api.dart +85 -0
  104. package/lib/scaffold/backends/supabase/patch/lib/features/feedbacks/ui/component/add_feature_form.dart +199 -0
  105. package/lib/scaffold/backends/supabase/patch/lib/features/llm_chat/api/llm_chat_api.dart +47 -0
  106. package/lib/scaffold/backends/supabase/patch/lib/features/llm_chat/api/llm_chat_message_entity.dart +30 -0
  107. package/lib/scaffold/backends/supabase/patch/lib/features/llm_chat/providers/llm_chat_notifier.dart +266 -0
  108. package/lib/scaffold/backends/supabase/patch/lib/features/notifications/api/device_api.dart +410 -0
  109. package/lib/scaffold/backends/supabase/patch/lib/features/notifications/api/entities/device_entity.dart +51 -0
  110. package/lib/scaffold/backends/supabase/patch/lib/features/notifications/api/entities/notifications_entity.dart +26 -0
  111. package/lib/scaffold/backends/supabase/patch/lib/features/notifications/api/notifications_api.dart +317 -0
  112. package/lib/scaffold/backends/supabase/patch/lib/features/notifications/providers/models/notification.dart +174 -0
  113. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/api/entities/user_info_entity.dart +26 -0
  114. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/api/user_infos_api.dart +90 -0
  115. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/models/user_info.dart +94 -0
  116. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/repositories/user_infos_repository.dart +29 -0
  117. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/animations/movefade_anim.dart +34 -0
  118. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/components/onboarding_att_setup.dart +66 -0
  119. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +73 -0
  120. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +173 -0
  121. package/lib/scaffold/backends/supabase/patch/lib/features/settings/ui/widgets/avatar_utils.dart +35 -0
  122. package/lib/scaffold/backends/supabase/patch/lib/features/subscription/api/entities/subscription_entity.dart +35 -0
  123. package/lib/scaffold/backends/supabase/patch/lib/features/subscription/api/subscription_api.dart +44 -0
  124. package/lib/scaffold/backends/supabase/patch/lib/features/subscription/shared/maybeshow_premium.dart +85 -0
  125. package/lib/scaffold/backends/supabase/patch/lib/google_auth_options.dart +23 -0
  126. package/lib/scaffold/backends/supabase/patch/lib/main.dart +288 -0
  127. package/lib/scaffold/backends/supabase/patch/lib/router.dart +133 -0
  128. package/lib/scaffold/backends/supabase/pubspec.yaml.tpl +110 -0
  129. package/lib/scaffold/backends/supabase/tokens.js +9 -0
  130. package/lib/scaffold/catalog.js +177 -0
  131. package/lib/scaffold/engine.js +230 -0
  132. package/lib/scaffold/features/README.md +152 -0
  133. package/lib/scaffold/features/analytics/lib/core/data/api/analytics_api.dart +124 -0
  134. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.es.md +35 -0
  135. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.md +35 -0
  136. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/BUG.pt.md +35 -0
  137. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.es.md +12 -0
  138. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.md +12 -0
  139. package/lib/scaffold/features/ci/.github/ISSUE_TEMPLATE/feature_request.pt.md +12 -0
  140. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.es.md +17 -0
  141. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.md +17 -0
  142. package/lib/scaffold/features/ci/.github/PULL_REQUEST_TEMPLATE.pt.md +17 -0
  143. package/lib/scaffold/features/ci/.github/dependabot.yml +16 -0
  144. package/lib/scaffold/features/ci/.github/workflows/app.yml +20 -0
  145. package/lib/scaffold/features/ci/.gitlab/templates/deploy.yaml +14 -0
  146. package/lib/scaffold/features/ci/.gitlab/templates/dropbox.yaml +19 -0
  147. package/lib/scaffold/features/ci/.gitlab/templates/flutter.yaml +163 -0
  148. package/lib/scaffold/features/ci/.gitlab/templates/mailgun.yaml +28 -0
  149. package/lib/scaffold/features/ci/.gitlab-ci.yml +37 -0
  150. package/lib/scaffold/features/ci/codemagic.yaml +157 -0
  151. package/lib/scaffold/features/facebook/lib/core/data/api/tracking_api.dart +111 -0
  152. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_request_entity.dart +27 -0
  153. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/entities/feature_vote_entity.dart +27 -0
  154. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_request_api.dart +50 -0
  155. package/lib/scaffold/features/feedback/lib/features/feedbacks/api/feature_vote_api.dart +79 -0
  156. package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feature_requests.dart +48 -0
  157. package/lib/scaffold/features/feedback/lib/features/feedbacks/models/feedback_state.dart +42 -0
  158. package/lib/scaffold/features/feedback/lib/features/feedbacks/providers/feedback_page_notifier.dart +147 -0
  159. package/lib/scaffold/features/feedback/lib/features/feedbacks/repositories/feature_request_repository.dart +95 -0
  160. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/component/add_feature_form.dart +199 -0
  161. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/feedback_page.dart +175 -0
  162. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/add_feature_button.dart +76 -0
  163. package/lib/scaffold/features/feedback/lib/features/feedbacks/ui/widgets/feature_card.dart +279 -0
  164. package/lib/scaffold/features/ios-release/.kasy/apple.env.example +8 -0
  165. package/lib/scaffold/features/ios-release/.kasy/codemagic.env.example +7 -0
  166. package/lib/scaffold/features/ios-release/docs/codemagic-release.en.md +50 -0
  167. package/lib/scaffold/features/ios-release/docs/codemagic-release.es.md +50 -0
  168. package/lib/scaffold/features/ios-release/docs/codemagic-release.pt.md +50 -0
  169. package/lib/scaffold/features/ios-release/docs/ios-release.en.md +41 -0
  170. package/lib/scaffold/features/ios-release/docs/ios-release.es.md +41 -0
  171. package/lib/scaffold/features/ios-release/docs/ios-release.pt.md +41 -0
  172. package/lib/scaffold/features/ios-release/scripts/bump-ios-version.js +38 -0
  173. package/lib/scaffold/features/ios-release/scripts/release-ios.sh +137 -0
  174. package/lib/scaffold/features/llm_chat/lib/features/llm_chat/llm_chat_page.dart +301 -0
  175. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/providers/reminder_notifier.dart +81 -0
  176. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/repositories/reminder_preferences.dart +76 -0
  177. package/lib/scaffold/features/local_notifications/lib/features/local_reminder/ui/reminder_page.dart +282 -0
  178. package/lib/scaffold/features/onboarding/lib/features/onboarding/api/entities/user_info_entity.dart +24 -0
  179. package/lib/scaffold/features/onboarding/lib/features/onboarding/api/user_infos_api.dart +71 -0
  180. package/lib/scaffold/features/onboarding/lib/features/onboarding/models/user_info.dart +92 -0
  181. package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_model.dart +15 -0
  182. package/lib/scaffold/features/onboarding/lib/features/onboarding/providers/onboarding_provider.dart +78 -0
  183. package/lib/scaffold/features/onboarding/lib/features/onboarding/repositories/user_infos_repository.dart +29 -0
  184. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/animations/page_transitions.dart +30 -0
  185. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_att_setup.dart +66 -0
  186. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_features.dart +72 -0
  187. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_loader.dart +92 -0
  188. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +73 -0
  189. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/components/onboarding_questions.dart +89 -0
  190. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/onboarding_page.dart +94 -0
  191. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_background.dart +80 -0
  192. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_feature.dart +139 -0
  193. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +110 -0
  194. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_progress.dart +84 -0
  195. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +173 -0
  196. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_reassurance.dart +45 -0
  197. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/onboarding_sticky_footer.dart +77 -0
  198. package/lib/scaffold/features/onboarding/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +392 -0
  199. package/lib/scaffold/features/revenuecat/lib/core/data/api/tracking_api.dart +116 -0
  200. package/lib/scaffold/features/revenuecat/lib/core/data/models/subscription.dart +322 -0
  201. package/lib/scaffold/features/revenuecat/lib/core/home_widgets/home_widget_background_task.dart +41 -0
  202. package/lib/scaffold/features/revenuecat/lib/core/states/user_state_notifier.dart +305 -0
  203. package/lib/scaffold/features/widget/lib/core/home_widgets/home_widget_background_task.dart +41 -0
  204. package/lib/scaffold/features/widget/lib/core/home_widgets/home_widget_mywidget_service.dart +57 -0
  205. package/lib/scaffold/features/widget/lib/core/home_widgets/home_widget_service.dart +54 -0
  206. package/lib/scaffold/features/widget/lib/features/settings/ui/components/admin/admin_home_widgets.dart +32 -0
  207. package/lib/scaffold/generate.js +370 -0
  208. package/lib/scaffold/patch.js +395 -0
  209. package/lib/scaffold/shared/backend-config.js +74 -0
  210. package/lib/scaffold/shared/fcm-service-account.js +126 -0
  211. package/lib/scaffold/shared/generator-utils.js +1664 -0
  212. package/lib/scaffold/shared/post-build.js +809 -0
  213. package/lib/scaffold/shared/template-strings.js +112 -0
  214. package/lib/utils/apple-release.js +273 -0
  215. package/lib/utils/checks.js +319 -0
  216. package/lib/utils/codemagic-release.js +127 -0
  217. package/lib/utils/fs.js +122 -0
  218. package/lib/utils/i18n.js +2123 -0
  219. package/lib/utils/license-gate.js +72 -0
  220. package/lib/utils/license.js +64 -0
  221. package/lib/utils/prompts.js +213 -0
  222. package/lib/utils/updates.js +97 -0
  223. package/package.json +55 -0
  224. package/templates/firebase/.env.example +24 -0
  225. package/templates/firebase/.firebaserc +5 -0
  226. package/templates/firebase/.kasy/apple.env.example +8 -0
  227. package/templates/firebase/.kasy/codemagic.env.example +7 -0
  228. package/templates/firebase/.metadata +30 -0
  229. package/templates/firebase/.windsurfrules +95 -0
  230. package/templates/firebase/Makefile +30 -0
  231. package/templates/firebase/README.en.md +180 -0
  232. package/templates/firebase/README.es.md +180 -0
  233. package/templates/firebase/README.md +180 -0
  234. package/templates/firebase/analysis_options.yaml +37 -0
  235. package/templates/firebase/android/app/build.gradle.kts +80 -0
  236. package/templates/firebase/android/app/src/debug/AndroidManifest.xml +7 -0
  237. package/templates/firebase/android/app/src/main/AndroidManifest.xml +93 -0
  238. package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/MainActivity.kt +36 -0
  239. package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/MyWidget.kt +50 -0
  240. package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/MyWidgetReceiver.kt +7 -0
  241. package/templates/firebase/android/app/src/main/res/drawable/background.png +0 -0
  242. package/templates/firebase/android/app/src/main/res/drawable/launch_background.xml +9 -0
  243. package/templates/firebase/android/app/src/main/res/drawable-hdpi/splash.png +0 -0
  244. package/templates/firebase/android/app/src/main/res/drawable-mdpi/splash.png +0 -0
  245. package/templates/firebase/android/app/src/main/res/drawable-v21/background.png +0 -0
  246. package/templates/firebase/android/app/src/main/res/drawable-v21/launch_background.xml +9 -0
  247. package/templates/firebase/android/app/src/main/res/drawable-xhdpi/splash.png +0 -0
  248. package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/splash.png +0 -0
  249. package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/splash.png +0 -0
  250. package/templates/firebase/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  251. package/templates/firebase/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  252. package/templates/firebase/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  253. package/templates/firebase/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  254. package/templates/firebase/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  255. package/templates/firebase/android/app/src/main/res/values/strings.xml +6 -0
  256. package/templates/firebase/android/app/src/main/res/values/styles.xml +22 -0
  257. package/templates/firebase/android/app/src/main/res/values-night/styles.xml +22 -0
  258. package/templates/firebase/android/app/src/main/res/values-night-v31/styles.xml +20 -0
  259. package/templates/firebase/android/app/src/main/res/values-v31/styles.xml +20 -0
  260. package/templates/firebase/android/app/src/main/res/xml/locales_config.xml +7 -0
  261. package/templates/firebase/android/app/src/main/res/xml/mywidget_info.xml +11 -0
  262. package/templates/firebase/android/app/src/profile/AndroidManifest.xml +7 -0
  263. package/templates/firebase/android/build.gradle.kts +28 -0
  264. package/templates/firebase/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  265. package/templates/firebase/android/gradle.properties +2 -0
  266. package/templates/firebase/android/settings.gradle.kts +29 -0
  267. package/templates/firebase/assets/icons/apple.png +0 -0
  268. package/templates/firebase/assets/icons/facebook.png +0 -0
  269. package/templates/firebase/assets/icons/google.png +0 -0
  270. package/templates/firebase/assets/icons/google_play_games.png +0 -0
  271. package/templates/firebase/assets/images/app_icon.png +0 -0
  272. package/templates/firebase/assets/images/empty_notifications.jpg +0 -0
  273. package/templates/firebase/assets/images/icon.png +0 -0
  274. package/templates/firebase/assets/images/onboarding/authentication-login-template.jpg +0 -0
  275. package/templates/firebase/assets/images/onboarding/img1.jpg +0 -0
  276. package/templates/firebase/assets/images/onboarding/img2.jpg +0 -0
  277. package/templates/firebase/assets/images/onboarding/img3.jpg +0 -0
  278. package/templates/firebase/assets/images/onboarding/notifications.png +0 -0
  279. package/templates/firebase/assets/images/onboarding/onboarding.png +0 -0
  280. package/templates/firebase/assets/images/onboarding/purchase.png +0 -0
  281. package/templates/firebase/assets/images/premium-bg.jpg +0 -0
  282. package/templates/firebase/assets/images/premium-switch-header.png +0 -0
  283. package/templates/firebase/assets/images/review.png +0 -0
  284. package/templates/firebase/assets/images/splashscreen.png +0 -0
  285. package/templates/firebase/assets/images/update.png +0 -0
  286. package/templates/firebase/build.yaml +13 -0
  287. package/templates/firebase/devtools_options.yaml +3 -0
  288. package/templates/firebase/docs/auth-setup.en.md +145 -0
  289. package/templates/firebase/docs/auth-setup.es.md +145 -0
  290. package/templates/firebase/docs/auth-setup.pt.md +145 -0
  291. package/templates/firebase/docs/codemagic-release.en.md +50 -0
  292. package/templates/firebase/docs/codemagic-release.es.md +50 -0
  293. package/templates/firebase/docs/codemagic-release.pt.md +50 -0
  294. package/templates/firebase/docs/ios-release.en.md +41 -0
  295. package/templates/firebase/docs/ios-release.es.md +41 -0
  296. package/templates/firebase/docs/ios-release.pt.md +54 -0
  297. package/templates/firebase/docs/navigation-transitions.md +80 -0
  298. package/templates/firebase/docs/revenuecat-setup.es.md +341 -0
  299. package/templates/firebase/docs/revenuecat-setup.pt.md +341 -0
  300. package/templates/firebase/firebase.json +1 -0
  301. package/templates/firebase/firestore.indexes.json +25 -0
  302. package/templates/firebase/firestore.rules +51 -0
  303. package/templates/firebase/functions/.eslintrc.js +45 -0
  304. package/templates/firebase/functions/jest.config.js +16 -0
  305. package/templates/firebase/functions/package-lock.json +6876 -0
  306. package/templates/firebase/functions/package.json +33 -0
  307. package/templates/firebase/functions/src/authentication/functions.ts +30 -0
  308. package/templates/firebase/functions/src/authentication/triggers.ts +103 -0
  309. package/templates/firebase/functions/src/core/api/meta_ads_api.ts +390 -0
  310. package/templates/firebase/functions/src/core/data/entities/entity_utils.ts +87 -0
  311. package/templates/firebase/functions/src/core/data/entities/notification_entity.ts +74 -0
  312. package/templates/firebase/functions/src/core/data/entities/page.ts +4 -0
  313. package/templates/firebase/functions/src/core/data/entities/subscription_entity.ts +76 -0
  314. package/templates/firebase/functions/src/core/data/entities/user_device_entity.ts +64 -0
  315. package/templates/firebase/functions/src/core/data/entities/user_entity.ts +43 -0
  316. package/templates/firebase/functions/src/core/data/repositories/repositories.ts +16 -0
  317. package/templates/firebase/functions/src/core/data/repositories/subscription_repository.ts +42 -0
  318. package/templates/firebase/functions/src/core/data/repositories/user_device_repository.ts +31 -0
  319. package/templates/firebase/functions/src/core/data/repositories/user_notifications_repository.ts +58 -0
  320. package/templates/firebase/functions/src/core/data/repositories/user_repository.ts +84 -0
  321. package/templates/firebase/functions/src/core/logger/logger.ts +13 -0
  322. package/templates/firebase/functions/src/core/storage/storage_manager.ts +52 -0
  323. package/templates/firebase/functions/src/core/utils/async_utils.ts +5 -0
  324. package/templates/firebase/functions/src/feature_requests/triggers.ts +3 -0
  325. package/templates/firebase/functions/src/index.ts +24 -0
  326. package/templates/firebase/functions/src/llm_chat/index.ts +181 -0
  327. package/templates/firebase/functions/src/notifications/admin_functions.ts +91 -0
  328. package/templates/firebase/functions/src/notifications/models/notification.ts +61 -0
  329. package/templates/firebase/functions/src/notifications/notifications_api.ts +147 -0
  330. package/templates/firebase/functions/src/notifications/triggers.ts +102 -0
  331. package/templates/firebase/functions/src/subscriptions/models/revenuecat_events.ts +162 -0
  332. package/templates/firebase/functions/src/subscriptions/models/subscription_status.ts +18 -0
  333. package/templates/firebase/functions/src/subscriptions/models/subscriptions.ts +173 -0
  334. package/templates/firebase/functions/src/subscriptions/subscriptions_functions.ts +135 -0
  335. package/templates/firebase/functions/src/subscriptions/triggers.ts +35 -0
  336. package/templates/firebase/functions/src/test/core/data/entities/entity_utils.spec.ts +44 -0
  337. package/templates/firebase/functions/tsconfig.dev.json +5 -0
  338. package/templates/firebase/functions/tsconfig.json +18 -0
  339. package/templates/firebase/home_widget_config.json +30 -0
  340. package/templates/firebase/ios/Flutter/AppFrameworkInfo.plist +24 -0
  341. package/templates/firebase/ios/Flutter/Debug.xcconfig +2 -0
  342. package/templates/firebase/ios/Flutter/Profile.xcconfig +2 -0
  343. package/templates/firebase/ios/Flutter/Release.xcconfig +2 -0
  344. package/templates/firebase/ios/HomeWidgetExtension/HomeWidgetBundle.swift +13 -0
  345. package/templates/firebase/ios/HomeWidgetExtension/Info.plist +29 -0
  346. package/templates/firebase/ios/HomeWidgetExtension/MyWidget.swift +86 -0
  347. package/templates/firebase/ios/HomeWidgetExtension.entitlements +10 -0
  348. package/templates/firebase/ios/NotificationService/Info.plist +31 -0
  349. package/templates/firebase/ios/NotificationService/NotificationService.swift +76 -0
  350. package/templates/firebase/ios/Podfile +111 -0
  351. package/templates/firebase/ios/Runner/AppDelegate.swift +75 -0
  352. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +1 -0
  353. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png +0 -0
  354. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png +0 -0
  355. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png +0 -0
  356. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png +0 -0
  357. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png +0 -0
  358. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png +0 -0
  359. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png +0 -0
  360. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png +0 -0
  361. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png +0 -0
  362. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png +0 -0
  363. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png +0 -0
  364. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png +0 -0
  365. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png +0 -0
  366. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png +0 -0
  367. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png +0 -0
  368. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png +0 -0
  369. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png +0 -0
  370. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png +0 -0
  371. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png +0 -0
  372. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png +0 -0
  373. package/templates/firebase/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png +0 -0
  374. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json +21 -0
  375. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png +0 -0
  376. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +23 -0
  377. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +0 -0
  378. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +0 -0
  379. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +0 -0
  380. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +5 -0
  381. package/templates/firebase/ios/Runner/Base.lproj/LaunchScreen.storyboard +44 -0
  382. package/templates/firebase/ios/Runner/Base.lproj/Main.storyboard +26 -0
  383. package/templates/firebase/ios/Runner/Info.plist +132 -0
  384. package/templates/firebase/ios/Runner/Runner-Bridging-Header.h +1 -0
  385. package/templates/firebase/ios/Runner/Runner.entitlements +14 -0
  386. package/templates/firebase/ios/Runner/es.lproj/InfoPlist.strings +10 -0
  387. package/templates/firebase/ios/Runner/pt-BR.lproj/InfoPlist.strings +10 -0
  388. package/templates/firebase/ios/Runner/pt.lproj/InfoPlist.strings +10 -0
  389. package/templates/firebase/ios/Runner.xcodeproj/project.pbxproj +1108 -0
  390. package/templates/firebase/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  391. package/templates/firebase/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  392. package/templates/firebase/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
  393. package/templates/firebase/ios/Runner.xcodeproj/xcshareddata/xcschemes/NotificationService.xcscheme +58 -0
  394. package/templates/firebase/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +101 -0
  395. package/templates/firebase/ios/Runner.xcworkspace/contents.xcworkspacedata +10 -0
  396. package/templates/firebase/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  397. package/templates/firebase/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +8 -0
  398. package/templates/firebase/ios/RunnerTests/RunnerTests.swift +12 -0
  399. package/templates/firebase/lib/components/components.dart +27 -0
  400. package/templates/firebase/lib/components/kasy_accordion.dart +384 -0
  401. package/templates/firebase/lib/components/kasy_alert.dart +266 -0
  402. package/templates/firebase/lib/components/kasy_app_bar.dart +536 -0
  403. package/templates/firebase/lib/components/kasy_avatar.dart +549 -0
  404. package/templates/firebase/lib/components/kasy_avatar_presets.dart +104 -0
  405. package/templates/firebase/lib/components/kasy_badge.dart +278 -0
  406. package/templates/firebase/lib/components/kasy_bottom_sheet.dart +338 -0
  407. package/templates/firebase/lib/components/kasy_button.dart +926 -0
  408. package/templates/firebase/lib/components/kasy_card.dart +128 -0
  409. package/templates/firebase/lib/components/kasy_checkbox.dart +429 -0
  410. package/templates/firebase/lib/components/kasy_chip.dart +83 -0
  411. package/templates/firebase/lib/components/kasy_dialog.dart +789 -0
  412. package/templates/firebase/lib/components/kasy_otp_verification_bottom_sheet.dart +233 -0
  413. package/templates/firebase/lib/components/kasy_skeleton.dart +225 -0
  414. package/templates/firebase/lib/components/kasy_text_area.dart +392 -0
  415. package/templates/firebase/lib/components/kasy_text_field.dart +591 -0
  416. package/templates/firebase/lib/components/kasy_text_field_otp.dart +532 -0
  417. package/templates/firebase/lib/components/kasy_toast.dart +803 -0
  418. package/templates/firebase/lib/core/ads/ads_provider.dart +136 -0
  419. package/templates/firebase/lib/core/ads/ads_state.dart +15 -0
  420. package/templates/firebase/lib/core/animations/bottomfade_anim.dart +37 -0
  421. package/templates/firebase/lib/core/animations/movefade_anim.dart +34 -0
  422. package/templates/firebase/lib/core/animations/slideright_anim.dart +38 -0
  423. package/templates/firebase/lib/core/bottom_menu/bart_inner_paths.dart +5 -0
  424. package/templates/firebase/lib/core/bottom_menu/bottom_menu.dart +127 -0
  425. package/templates/firebase/lib/core/bottom_menu/bottom_router.dart +281 -0
  426. package/templates/firebase/lib/core/bottom_menu/kasy_bart_navigation.dart +22 -0
  427. package/templates/firebase/lib/core/bottom_menu/kasy_bottom_bar_factory.dart +127 -0
  428. package/templates/firebase/lib/core/bottom_menu/notification_bottom_item.dart +48 -0
  429. package/templates/firebase/lib/core/config/app_env.dart +100 -0
  430. package/templates/firebase/lib/core/config/features.dart +15 -0
  431. package/templates/firebase/lib/core/data/api/analytics_api.dart +124 -0
  432. package/templates/firebase/lib/core/data/api/base_api_exceptions.dart +28 -0
  433. package/templates/firebase/lib/core/data/api/firestore_retry.dart +29 -0
  434. package/templates/firebase/lib/core/data/api/http_client.dart +38 -0
  435. package/templates/firebase/lib/core/data/api/image.dart +52 -0
  436. package/templates/firebase/lib/core/data/api/remote_config_api.dart +170 -0
  437. package/templates/firebase/lib/core/data/api/storage_api.dart +115 -0
  438. package/templates/firebase/lib/core/data/api/tracking_api.dart +119 -0
  439. package/templates/firebase/lib/core/data/api/user_api.dart +115 -0
  440. package/templates/firebase/lib/core/data/entities/json_converters.dart +39 -0
  441. package/templates/firebase/lib/core/data/entities/upload_result.dart +48 -0
  442. package/templates/firebase/lib/core/data/entities/user_entity.dart +54 -0
  443. package/templates/firebase/lib/core/data/models/pageable.dart +12 -0
  444. package/templates/firebase/lib/core/data/models/subscription.dart +322 -0
  445. package/templates/firebase/lib/core/data/models/user.dart +107 -0
  446. package/templates/firebase/lib/core/data/repositories/user_repository.dart +130 -0
  447. package/templates/firebase/lib/core/dev_inspector/dev_inspector.dart +464 -0
  448. package/templates/firebase/lib/core/dev_inspector/dev_inspector_highlight.dart +88 -0
  449. package/templates/firebase/lib/core/dev_inspector/dev_inspector_info.dart +70 -0
  450. package/templates/firebase/lib/core/dev_inspector/dev_inspector_panel.dart +204 -0
  451. package/templates/firebase/lib/core/dev_inspector/dev_inspector_service.dart +321 -0
  452. package/templates/firebase/lib/core/extensions/date.ext.dart +32 -0
  453. package/templates/firebase/lib/core/guards/authenticated_guard.dart +37 -0
  454. package/templates/firebase/lib/core/guards/guard.dart +68 -0
  455. package/templates/firebase/lib/core/guards/user_info_guard.dart +55 -0
  456. package/templates/firebase/lib/core/haptics/haptic_feedback_notifier.dart +19 -0
  457. package/templates/firebase/lib/core/haptics/kasy_haptics.dart +27 -0
  458. package/templates/firebase/lib/core/home_widgets/home_widget_background_task.dart +41 -0
  459. package/templates/firebase/lib/core/home_widgets/home_widget_mywidget_service.dart +57 -0
  460. package/templates/firebase/lib/core/home_widgets/home_widget_service.dart +54 -0
  461. package/templates/firebase/lib/core/icons/kasy_icons.dart +86 -0
  462. package/templates/firebase/lib/core/initializer/models/run_state.dart +14 -0
  463. package/templates/firebase/lib/core/initializer/onstart_service.dart +38 -0
  464. package/templates/firebase/lib/core/initializer/onstart_widget.dart +83 -0
  465. package/templates/firebase/lib/core/initializer/pending_notification_handler.dart +48 -0
  466. package/templates/firebase/lib/core/keyboard_fix/keyboard_flicker_fix.dart +164 -0
  467. package/templates/firebase/lib/core/navigation/kasy_fade_page_transitions_builder.dart +34 -0
  468. package/templates/firebase/lib/core/navigation/kasy_material_page_route.dart +41 -0
  469. package/templates/firebase/lib/core/navigation/kasy_navigation_config.dart +29 -0
  470. package/templates/firebase/lib/core/navigation/kasy_page_transition.dart +40 -0
  471. package/templates/firebase/lib/core/navigation/kasy_route_transition.dart +68 -0
  472. package/templates/firebase/lib/core/navigation/kasy_transition_kind.dart +17 -0
  473. package/templates/firebase/lib/core/navigation/navigation.dart +6 -0
  474. package/templates/firebase/lib/core/rating/api/rating_api.dart +99 -0
  475. package/templates/firebase/lib/core/rating/models/rating.dart +52 -0
  476. package/templates/firebase/lib/core/rating/models/review.dart +70 -0
  477. package/templates/firebase/lib/core/rating/providers/rating_repository.dart +75 -0
  478. package/templates/firebase/lib/core/rating/widgets/rate_banner.dart +190 -0
  479. package/templates/firebase/lib/core/rating/widgets/rate_popup.dart +54 -0
  480. package/templates/firebase/lib/core/rating/widgets/review_popup.dart +175 -0
  481. package/templates/firebase/lib/core/security/biometric_copy_slot.dart +20 -0
  482. package/templates/firebase/lib/core/security/biometric_guard.dart +114 -0
  483. package/templates/firebase/lib/core/security/biometric_preference_notifier.dart +17 -0
  484. package/templates/firebase/lib/core/security/biometric_service.dart +79 -0
  485. package/templates/firebase/lib/core/security/biometric_ui_bundle.dart +136 -0
  486. package/templates/firebase/lib/core/security/secured_storage.dart +46 -0
  487. package/templates/firebase/lib/core/shared_preferences/shared_preferences.dart +70 -0
  488. package/templates/firebase/lib/core/sidebar/kasy_sidebar.dart +2021 -0
  489. package/templates/firebase/lib/core/states/components/maybe_ask_biometric_setup.dart +88 -0
  490. package/templates/firebase/lib/core/states/components/maybe_ask_rating.dart +49 -0
  491. package/templates/firebase/lib/core/states/components/maybe_show_update_bottom_sheet.dart +86 -0
  492. package/templates/firebase/lib/core/states/components/maybeshow_component.dart +110 -0
  493. package/templates/firebase/lib/core/states/events_dispatcher.dart +103 -0
  494. package/templates/firebase/lib/core/states/models/event_model.dart +118 -0
  495. package/templates/firebase/lib/core/states/models/user_state.dart +22 -0
  496. package/templates/firebase/lib/core/states/notifications_dispatcher.dart +81 -0
  497. package/templates/firebase/lib/core/states/translations.dart +11 -0
  498. package/templates/firebase/lib/core/states/user_state_notifier.dart +321 -0
  499. package/templates/firebase/lib/core/theme/colors.dart +262 -0
  500. package/templates/firebase/lib/core/theme/extensions/theme_extension.dart +48 -0
  501. package/templates/firebase/lib/core/theme/providers/kasy_theme.dart +76 -0
  502. package/templates/firebase/lib/core/theme/providers/theme_provider.dart +212 -0
  503. package/templates/firebase/lib/core/theme/radius.dart +33 -0
  504. package/templates/firebase/lib/core/theme/shadows.dart +64 -0
  505. package/templates/firebase/lib/core/theme/spacing.dart +44 -0
  506. package/templates/firebase/lib/core/theme/texts.dart +176 -0
  507. package/templates/firebase/lib/core/theme/theme.dart +24 -0
  508. package/templates/firebase/lib/core/theme/theme_data/theme_data.dart +32 -0
  509. package/templates/firebase/lib/core/theme/theme_data/theme_data_factory.dart +15 -0
  510. package/templates/firebase/lib/core/theme/universal_theme.dart +210 -0
  511. package/templates/firebase/lib/core/toast/toast_service.dart +55 -0
  512. package/templates/firebase/lib/core/ui/app_dialog.dart +26 -0
  513. package/templates/firebase/lib/core/web_device_preview/web_device_preview.dart +1126 -0
  514. package/templates/firebase/lib/core/widgets/debouncer.dart +31 -0
  515. package/templates/firebase/lib/core/widgets/kasy_hover.dart +166 -0
  516. package/templates/firebase/lib/core/widgets/kasy_pressable.dart +2 -0
  517. package/templates/firebase/lib/core/widgets/kasy_pressable_depth.dart +161 -0
  518. package/templates/firebase/lib/core/widgets/kasy_scroll_behavior.dart +17 -0
  519. package/templates/firebase/lib/core/widgets/keyboard_visibility.dart +75 -0
  520. package/templates/firebase/lib/core/widgets/page_background.dart +71 -0
  521. package/templates/firebase/lib/core/widgets/page_not_found.dart +15 -0
  522. package/templates/firebase/lib/core/widgets/responsive_layout.dart +215 -0
  523. package/templates/firebase/lib/core/widgets/update_bottom_sheet.dart +192 -0
  524. package/templates/firebase/lib/environnements.dart +160 -0
  525. package/templates/firebase/lib/features/authentication/api/authentication_api.dart +528 -0
  526. package/templates/firebase/lib/features/authentication/api/authentication_api_interface.dart +84 -0
  527. package/templates/firebase/lib/features/authentication/providers/models/email.dart +36 -0
  528. package/templates/firebase/lib/features/authentication/providers/models/password.dart +37 -0
  529. package/templates/firebase/lib/features/authentication/providers/models/phone_signin_state.dart +21 -0
  530. package/templates/firebase/lib/features/authentication/providers/models/recover_state.dart +21 -0
  531. package/templates/firebase/lib/features/authentication/providers/models/signin_state.dart +20 -0
  532. package/templates/firebase/lib/features/authentication/providers/models/signup_state.dart +20 -0
  533. package/templates/firebase/lib/features/authentication/providers/phone_auth_notifier.dart +132 -0
  534. package/templates/firebase/lib/features/authentication/providers/recover_provider.dart +51 -0
  535. package/templates/firebase/lib/features/authentication/providers/signin_state_provider.dart +166 -0
  536. package/templates/firebase/lib/features/authentication/providers/signup_state_provider.dart +67 -0
  537. package/templates/firebase/lib/features/authentication/repositories/authentication_repository.dart +399 -0
  538. package/templates/firebase/lib/features/authentication/repositories/exceptions/authentication_exceptions.dart +85 -0
  539. package/templates/firebase/lib/features/authentication/ui/components/apple_signin.dart +19 -0
  540. package/templates/firebase/lib/features/authentication/ui/components/facebook_signin.dart +19 -0
  541. package/templates/firebase/lib/features/authentication/ui/components/google_signin.dart +32 -0
  542. package/templates/firebase/lib/features/authentication/ui/components/otp_verification.dart +100 -0
  543. package/templates/firebase/lib/features/authentication/ui/components/phone_input.dart +109 -0
  544. package/templates/firebase/lib/features/authentication/ui/phone_auth_page.dart +60 -0
  545. package/templates/firebase/lib/features/authentication/ui/recover_password_page.dart +101 -0
  546. package/templates/firebase/lib/features/authentication/ui/signin_page.dart +321 -0
  547. package/templates/firebase/lib/features/authentication/ui/signup_page.dart +310 -0
  548. package/templates/firebase/lib/features/authentication/ui/widgets/auth_brand.dart +35 -0
  549. package/templates/firebase/lib/features/authentication/ui/widgets/auth_page_back_button.dart +149 -0
  550. package/templates/firebase/lib/features/authentication/ui/widgets/otp_input.dart +194 -0
  551. package/templates/firebase/lib/features/authentication/ui/widgets/recover_password_result.dart +62 -0
  552. package/templates/firebase/lib/features/authentication/ui/widgets/round_signin.dart +73 -0
  553. package/templates/firebase/lib/features/authentication/ui/widgets/social_separator.dart +26 -0
  554. package/templates/firebase/lib/features/dev/keyboard_test_page.dart +93 -0
  555. package/templates/firebase/lib/features/feedbacks/api/entities/feature_request_entity.dart +27 -0
  556. package/templates/firebase/lib/features/feedbacks/api/entities/feature_vote_entity.dart +27 -0
  557. package/templates/firebase/lib/features/feedbacks/api/feature_request_api.dart +51 -0
  558. package/templates/firebase/lib/features/feedbacks/api/feature_vote_api.dart +79 -0
  559. package/templates/firebase/lib/features/feedbacks/models/feature_requests.dart +48 -0
  560. package/templates/firebase/lib/features/feedbacks/models/feedback_state.dart +43 -0
  561. package/templates/firebase/lib/features/feedbacks/providers/feedback_page_notifier.dart +147 -0
  562. package/templates/firebase/lib/features/feedbacks/repositories/feature_request_repository.dart +92 -0
  563. package/templates/firebase/lib/features/feedbacks/ui/component/add_feature_form.dart +112 -0
  564. package/templates/firebase/lib/features/feedbacks/ui/feedback_page.dart +184 -0
  565. package/templates/firebase/lib/features/feedbacks/ui/widgets/add_feature_button.dart +66 -0
  566. package/templates/firebase/lib/features/feedbacks/ui/widgets/feature_card.dart +266 -0
  567. package/templates/firebase/lib/features/home/design_system_page.dart +552 -0
  568. package/templates/firebase/lib/features/home/home_components_page.dart +314 -0
  569. package/templates/firebase/lib/features/home/home_components_preview_page.dart +791 -0
  570. package/templates/firebase/lib/features/home/home_components_preview_registry.dart +7712 -0
  571. package/templates/firebase/lib/features/home/home_features_page.dart +207 -0
  572. package/templates/firebase/lib/features/home/home_page.dart +348 -0
  573. package/templates/firebase/lib/features/llm_chat/api/llm_chat_api.dart +50 -0
  574. package/templates/firebase/lib/features/llm_chat/api/llm_chat_message_entity.dart +35 -0
  575. package/templates/firebase/lib/features/llm_chat/llm_chat_page.dart +352 -0
  576. package/templates/firebase/lib/features/llm_chat/providers/llm_chat_notifier.dart +315 -0
  577. package/templates/firebase/lib/features/llm_chat/ui/widgets/llm_chat_avatars.dart +148 -0
  578. package/templates/firebase/lib/features/llm_chat/ui/widgets/llm_chat_composer.dart +124 -0
  579. package/templates/firebase/lib/features/local_reminder/providers/reminder_notifier.dart +81 -0
  580. package/templates/firebase/lib/features/local_reminder/repositories/reminder_preferences.dart +76 -0
  581. package/templates/firebase/lib/features/local_reminder/ui/reminder_page.dart +288 -0
  582. package/templates/firebase/lib/features/notifications/api/device_api.dart +433 -0
  583. package/templates/firebase/lib/features/notifications/api/entities/device_entity.dart +62 -0
  584. package/templates/firebase/lib/features/notifications/api/entities/notifications_entity.dart +35 -0
  585. package/templates/firebase/lib/features/notifications/api/local_notifier.dart +409 -0
  586. package/templates/firebase/lib/features/notifications/api/notifications_api.dart +319 -0
  587. package/templates/firebase/lib/features/notifications/providers/models/device.dart +27 -0
  588. package/templates/firebase/lib/features/notifications/providers/models/notification.dart +196 -0
  589. package/templates/firebase/lib/features/notifications/providers/models/notification_list.dart +38 -0
  590. package/templates/firebase/lib/features/notifications/providers/notifications_provider.dart +120 -0
  591. package/templates/firebase/lib/features/notifications/repositories/background_notification_handler.dart +13 -0
  592. package/templates/firebase/lib/features/notifications/repositories/device_repository.dart +137 -0
  593. package/templates/firebase/lib/features/notifications/repositories/notifications_repository.dart +214 -0
  594. package/templates/firebase/lib/features/notifications/shared/att_permission.dart +75 -0
  595. package/templates/firebase/lib/features/notifications/shared/notification_permission_bottom_sheet.dart +144 -0
  596. package/templates/firebase/lib/features/notifications/ui/components/notification_settings_sheet.dart +169 -0
  597. package/templates/firebase/lib/features/notifications/ui/components/notification_tile.dart +46 -0
  598. package/templates/firebase/lib/features/notifications/ui/components/notifications_header.dart +32 -0
  599. package/templates/firebase/lib/features/notifications/ui/components/push_notification_switcher.dart +106 -0
  600. package/templates/firebase/lib/features/notifications/ui/notifications_page.dart +202 -0
  601. package/templates/firebase/lib/features/notifications/ui/request_notification_permission.dart +84 -0
  602. package/templates/firebase/lib/features/notifications/ui/widgets/empty_notifications.dart +73 -0
  603. package/templates/firebase/lib/features/notifications/ui/widgets/notification_tile.dart +362 -0
  604. package/templates/firebase/lib/features/onboarding/api/entities/user_info_entity.dart +24 -0
  605. package/templates/firebase/lib/features/onboarding/api/user_infos_api.dart +71 -0
  606. package/templates/firebase/lib/features/onboarding/models/user_info.dart +92 -0
  607. package/templates/firebase/lib/features/onboarding/providers/onboarding_model.dart +15 -0
  608. package/templates/firebase/lib/features/onboarding/providers/onboarding_provider.dart +78 -0
  609. package/templates/firebase/lib/features/onboarding/repositories/user_infos_repository.dart +29 -0
  610. package/templates/firebase/lib/features/onboarding/ui/animations/page_transitions.dart +33 -0
  611. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_att_setup.dart +66 -0
  612. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_features.dart +76 -0
  613. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_loader.dart +92 -0
  614. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +76 -0
  615. package/templates/firebase/lib/features/onboarding/ui/components/onboarding_questions.dart +89 -0
  616. package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +108 -0
  617. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_background.dart +80 -0
  618. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_feature.dart +145 -0
  619. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +125 -0
  620. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_progress.dart +84 -0
  621. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +173 -0
  622. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_reassurance.dart +44 -0
  623. package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_sticky_footer.dart +77 -0
  624. package/templates/firebase/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +392 -0
  625. package/templates/firebase/lib/features/settings/settings_page.dart +460 -0
  626. package/templates/firebase/lib/features/settings/ui/components/admin/admin_bottom_sheet.dart +301 -0
  627. package/templates/firebase/lib/features/settings/ui/components/admin/admin_home_widgets.dart +38 -0
  628. package/templates/firebase/lib/features/settings/ui/components/admin/admin_paywalls.dart +53 -0
  629. package/templates/firebase/lib/features/settings/ui/components/admin/admin_routes.dart +22 -0
  630. package/templates/firebase/lib/features/settings/ui/components/admin/send_push_notification_page.dart +366 -0
  631. package/templates/firebase/lib/features/settings/ui/components/admin/send_push_notifier.dart +40 -0
  632. package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +430 -0
  633. package/templates/firebase/lib/features/settings/ui/components/delete_user_component.dart +28 -0
  634. package/templates/firebase/lib/features/settings/ui/components/language_switcher.dart +163 -0
  635. package/templates/firebase/lib/features/settings/ui/widgets/admin_card.dart +59 -0
  636. package/templates/firebase/lib/features/settings/ui/widgets/avatar_utils.dart +51 -0
  637. package/templates/firebase/lib/features/settings/ui/widgets/round_progress.dart +151 -0
  638. package/templates/firebase/lib/features/settings/ui/widgets/settings_bottom_sheet_option_tile.dart +52 -0
  639. package/templates/firebase/lib/features/settings/ui/widgets/settings_tile.dart +163 -0
  640. package/templates/firebase/lib/features/subscription/api/entities/subscription_entity.dart +40 -0
  641. package/templates/firebase/lib/features/subscription/api/inapp_subscription_api.dart +389 -0
  642. package/templates/firebase/lib/features/subscription/api/subscription_api.dart +39 -0
  643. package/templates/firebase/lib/features/subscription/providers/models/premium_state.dart +35 -0
  644. package/templates/firebase/lib/features/subscription/providers/premium_page_provider.dart +259 -0
  645. package/templates/firebase/lib/features/subscription/repositories/subscription_repository.dart +177 -0
  646. package/templates/firebase/lib/features/subscription/shared/maybeshow_premium.dart +85 -0
  647. package/templates/firebase/lib/features/subscription/ui/component/active_premium_content.dart +171 -0
  648. package/templates/firebase/lib/features/subscription/ui/component/paywall_minimal.dart +146 -0
  649. package/templates/firebase/lib/features/subscription/ui/component/paywall_row.dart +332 -0
  650. package/templates/firebase/lib/features/subscription/ui/component/paywall_with_switch.dart +207 -0
  651. package/templates/firebase/lib/features/subscription/ui/component/premium_content.dart +157 -0
  652. package/templates/firebase/lib/features/subscription/ui/component/premium_page_factory.dart +161 -0
  653. package/templates/firebase/lib/features/subscription/ui/premium_page.dart +139 -0
  654. package/templates/firebase/lib/features/subscription/ui/widgets/comparison_table.dart +346 -0
  655. package/templates/firebase/lib/features/subscription/ui/widgets/feature_line.dart +131 -0
  656. package/templates/firebase/lib/features/subscription/ui/widgets/paywall_empty_state.dart +68 -0
  657. package/templates/firebase/lib/features/subscription/ui/widgets/premium_background.dart +63 -0
  658. package/templates/firebase/lib/features/subscription/ui/widgets/premium_background_gradient.dart +53 -0
  659. package/templates/firebase/lib/features/subscription/ui/widgets/premium_banner.dart +80 -0
  660. package/templates/firebase/lib/features/subscription/ui/widgets/premium_bottom_menu.dart +102 -0
  661. package/templates/firebase/lib/features/subscription/ui/widgets/premium_card.dart +26 -0
  662. package/templates/firebase/lib/features/subscription/ui/widgets/premium_close_button.dart +61 -0
  663. package/templates/firebase/lib/features/subscription/ui/widgets/premium_feature.dart +39 -0
  664. package/templates/firebase/lib/features/subscription/ui/widgets/selectable_col.dart +377 -0
  665. package/templates/firebase/lib/features/subscription/ui/widgets/selectable_row.dart +436 -0
  666. package/templates/firebase/lib/features/subscription/ui/widgets/trial_switcher.dart +85 -0
  667. package/templates/firebase/lib/features/subscription/ui/widgets/unsubscribe_feedback_popup.dart +123 -0
  668. package/templates/firebase/lib/firebase_options.dart +75 -0
  669. package/templates/firebase/lib/google_auth_options.dart +10 -0
  670. package/templates/firebase/lib/i18n/app_locale_display.dart +17 -0
  671. package/templates/firebase/lib/i18n/en.i18n.json +514 -0
  672. package/templates/firebase/lib/i18n/es.i18n.json +514 -0
  673. package/templates/firebase/lib/i18n/pt.i18n.json +514 -0
  674. package/templates/firebase/lib/i18n/widgets/locale_code_badge.dart +47 -0
  675. package/templates/firebase/lib/main.dart +263 -0
  676. package/templates/firebase/lib/router.dart +226 -0
  677. package/templates/firebase/login-redesign-preview.png +0 -0
  678. package/templates/firebase/pubspec.yaml +177 -0
  679. package/templates/firebase/scripts/bump-ios-version.js +38 -0
  680. package/templates/firebase/scripts/release-ios.sh +137 -0
  681. package/templates/firebase/slang.yaml +7 -0
  682. package/templates/firebase/storage.rules +12 -0
  683. package/templates/firebase/test/core/data/api/analytics_api_fake.dart +25 -0
  684. package/templates/firebase/test/core/data/api/fake_remote_config_api.dart +45 -0
  685. package/templates/firebase/test/core/data/api/storage_api_fake.dart +28 -0
  686. package/templates/firebase/test/core/data/models/subscription_test.dart +42 -0
  687. package/templates/firebase/test/core/data/repositories/user_repository_test.dart +56 -0
  688. package/templates/firebase/test/core/guards/guard_test.dart +78 -0
  689. package/templates/firebase/test/core/navigation/kasy_page_transition_test.dart +30 -0
  690. package/templates/firebase/test/core/onstart_service_test.dart +18 -0
  691. package/templates/firebase/test/core/rating/rating_api_fake.dart +58 -0
  692. package/templates/firebase/test/core/rating/rating_banner_test.dart +117 -0
  693. package/templates/firebase/test/core/rating/rating_test.dart +60 -0
  694. package/templates/firebase/test/core/security/secured_storage_fake.dart +33 -0
  695. package/templates/firebase/test/core/states/event_dispatcher_test.dart +269 -0
  696. package/templates/firebase/test/core/states/user_state_notifier_test.dart +244 -0
  697. package/templates/firebase/test/core/widgets/responsive_layout_test.dart +50 -0
  698. package/templates/firebase/test/device_test_utils.dart +98 -0
  699. package/templates/firebase/test/features/authentication/data/api/auth_api_fake.dart +169 -0
  700. package/templates/firebase/test/features/authentication/data/api/user_api_fake.dart +86 -0
  701. package/templates/firebase/test/features/authentication/lost_password_page_test.dart +59 -0
  702. package/templates/firebase/test/features/authentication/repositories/authentication_repository_test.dart +88 -0
  703. package/templates/firebase/test/features/authentication/signin_page_test.dart +133 -0
  704. package/templates/firebase/test/features/authentication/signup_page_test.dart +136 -0
  705. package/templates/firebase/test/features/notifications/data/device_api_fake.dart +66 -0
  706. package/templates/firebase/test/features/notifications/data/fake_facebook_api.dart +40 -0
  707. package/templates/firebase/test/features/notifications/data/local_notifier_fake.dart +59 -0
  708. package/templates/firebase/test/features/notifications/data/notifications_api_fake.dart +120 -0
  709. package/templates/firebase/test/features/notifications/data/notifications_settings_fake.dart +34 -0
  710. package/templates/firebase/test/features/notifications/providers/device_repository_test.dart +68 -0
  711. package/templates/firebase/test/features/notifications/providers/notifications_repository_test.dart +74 -0
  712. package/templates/firebase/test/features/notifications/ui/notifications_page_test.dart +69 -0
  713. package/templates/firebase/test/features/subscription/api/fake_inapp_subscription_api.dart +85 -0
  714. package/templates/firebase/test/features/subscription/api/fake_revenuecat_product.dart +186 -0
  715. package/templates/firebase/test/features/subscription/api/fake_subscription_api.dart +11 -0
  716. package/templates/firebase/test/features/subscription/subscription_page_test.dart +119 -0
  717. package/templates/firebase/test/firebase_test_utils.dart +25 -0
  718. package/templates/firebase/test/test_utils.dart +272 -0
  719. package/templates/firebase/web/favicon.png +0 -0
  720. package/templates/firebase/web/firebase-messaging-sw.js +27 -0
  721. package/templates/firebase/web/icons/Icon-192.png +0 -0
  722. package/templates/firebase/web/icons/Icon-512.png +0 -0
  723. package/templates/firebase/web/icons/Icon-maskable-192.png +0 -0
  724. package/templates/firebase/web/icons/Icon-maskable-512.png +0 -0
  725. package/templates/firebase/web/index.html +110 -0
  726. package/templates/firebase/web/local_notifications.js +31 -0
  727. package/templates/firebase/web/manifest.json +35 -0
  728. package/templates/firebase/web/splash/img/dark-1x.png +0 -0
  729. package/templates/firebase/web/splash/img/dark-2x.png +0 -0
  730. package/templates/firebase/web/splash/img/dark-3x.png +0 -0
  731. package/templates/firebase/web/splash/img/dark-4x.png +0 -0
  732. package/templates/firebase/web/splash/img/light-1x.png +0 -0
  733. package/templates/firebase/web/splash/img/light-2x.png +0 -0
  734. package/templates/firebase/web/splash/img/light-3x.png +0 -0
  735. package/templates/firebase/web/splash/img/light-4x.png +0 -0
@@ -0,0 +1,322 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'package:freezed_annotation/freezed_annotation.dart';
3
+ import 'package:kasy_kit/i18n/translations.g.dart';
4
+ import 'package:kasy_kit/features/subscription/api/entities/subscription_entity.dart';
5
+ import 'package:purchases_flutter/purchases_flutter.dart';
6
+
7
+ part 'subscription.freezed.dart';
8
+
9
+ abstract class SubscriptionProduct {
10
+ /// Unique identifier of the product in the store
11
+ String get skuId;
12
+
13
+ /// Unique identifier
14
+ String get id;
15
+
16
+ /// Description of the subscription from your app
17
+ String get description;
18
+
19
+ /// Label of the subscription from the package in revenue cat
20
+ String get label;
21
+
22
+ /// Price of the subscription
23
+ double get price;
24
+
25
+ /// Duration of the subscription
26
+ Duration get duration;
27
+
28
+ /// Promotion of the subscription (configure it in the revenue cat offering json)
29
+ String? get promotion;
30
+
31
+ /// Formatted price with duration from the user locale
32
+ String formattedPrice(BuildContext context);
33
+
34
+ /// Duration type of the subscription (week, month, year, ...)
35
+ DurationType get durationType;
36
+
37
+ /// Title of the offer
38
+ String? get title;
39
+
40
+ /// Trial days of the offer
41
+ int? get trialDays;
42
+
43
+ /// Features textes of the offer
44
+ List<String>? get features;
45
+
46
+ /// Price of the subscription in string
47
+ String get priceString;
48
+
49
+ String get currency;
50
+
51
+ /// Shows the price per month (only if the duration is not monthly)
52
+ String pricePerMonth(BuildContext context);
53
+
54
+ /// Shows the price per year (only if the duration is not yearly)
55
+ String? pricePerYear(BuildContext context);
56
+ }
57
+
58
+ class RevenueCatProduct implements SubscriptionProduct {
59
+ final Offering revenueCatOffer;
60
+ final Package revenueCatPackage;
61
+
62
+ RevenueCatProduct({
63
+ required this.revenueCatOffer,
64
+ required this.revenueCatPackage,
65
+ });
66
+
67
+ @override
68
+ String get skuId => revenueCatPackage.identifier;
69
+
70
+ @override
71
+ String get id => revenueCatOffer.identifier;
72
+
73
+ @override
74
+ String get description => revenueCatOffer.serverDescription;
75
+
76
+ @override
77
+ String get label =>
78
+ revenueCatPackage.presentedOfferingContext.offeringIdentifier;
79
+
80
+ @override
81
+ double get price => revenueCatPackage.storeProduct.price;
82
+
83
+ @override
84
+ String get currency => revenueCatPackage.storeProduct.currencyCode;
85
+
86
+ @override
87
+ int? get trialDays {
88
+ final introductory = revenueCatPackage.storeProduct.introductoryPrice;
89
+ if (introductory == null) {
90
+ return null;
91
+ }
92
+ if (introductory.price == 0) {
93
+ final unit = introductory.periodUnit;
94
+ switch (unit) {
95
+ case PeriodUnit.day:
96
+ return introductory.periodNumberOfUnits;
97
+ case PeriodUnit.week:
98
+ return introductory.periodNumberOfUnits * 7;
99
+ case PeriodUnit.month:
100
+ return introductory.periodNumberOfUnits * 30;
101
+ case PeriodUnit.year:
102
+ return introductory.periodNumberOfUnits * 365;
103
+ default:
104
+ return null;
105
+ }
106
+ }
107
+ return null;
108
+ }
109
+
110
+ @override
111
+ String? get promotion {
112
+ if (revenueCatOffer.metadata["promotions"] == null) {
113
+ return null;
114
+ }
115
+ final data =
116
+ revenueCatOffer.metadata["promotions"]! as Map<Object?, Object?>;
117
+ final locale = LocaleSettings.currentLocale.languageCode;
118
+ final id = skuId;
119
+ if (data.containsKey(id)) {
120
+ final promotion = data[id]! as Map<Object?, Object?>;
121
+ return promotion[locale]! as String;
122
+ }
123
+ return null;
124
+ }
125
+
126
+ @override
127
+ String? get title {
128
+ return revenueCatPackage.storeProduct.title;
129
+ }
130
+
131
+ @override
132
+ List<String>? get features {
133
+ final locale = LocaleSettings.currentLocale.languageCode;
134
+ if (revenueCatOffer.metadata[locale] == null) {
135
+ return null;
136
+ }
137
+ final data = revenueCatOffer.metadata[locale]! as Map<Object?, Object?>;
138
+ final featuerObj = data["features"]! as List<Object?>;
139
+ return featuerObj.map((e) => e! as String).toList();
140
+ }
141
+
142
+ @override
143
+ String get priceString {
144
+ return revenueCatPackage.storeProduct.priceString;
145
+ }
146
+
147
+ @override
148
+ Duration get duration =>
149
+ switch (revenueCatPackage.storeProduct.subscriptionPeriod) {
150
+ 'P1W' => const Duration(days: 7),
151
+ 'P1M' => const Duration(days: 30),
152
+ 'P3M' => const Duration(days: 90),
153
+ 'P6M' => const Duration(days: 180),
154
+ 'P1Y' => const Duration(days: 365),
155
+ _ => Duration.zero,
156
+ };
157
+
158
+ @override
159
+ DurationType get durationType {
160
+ final durationCpy = duration;
161
+ if (durationCpy.inDays == 7) {
162
+ return DurationType.week;
163
+ } else if (durationCpy.inDays == 30) {
164
+ return DurationType.month;
165
+ } else if (durationCpy.inDays == 90) {
166
+ return DurationType.threeMonth;
167
+ } else if (durationCpy.inDays == 180) {
168
+ return DurationType.sixMonth;
169
+ } else if (durationCpy.inDays == 365) {
170
+ return DurationType.year;
171
+ }
172
+ return DurationType.lifetime;
173
+ }
174
+
175
+ @override
176
+ String formattedPrice(BuildContext context) {
177
+ final translatedDuration = switch (durationType) {
178
+ DurationType.week => Translations.of(context).premium.duration_weekly,
179
+ DurationType.year => Translations.of(context).premium.duration_annual,
180
+ DurationType.month => Translations.of(context).premium.duration_monthly,
181
+ DurationType.lifetime => Translations.of(
182
+ context,
183
+ ).premium.duration_lifetime,
184
+ _ => "",
185
+ };
186
+ return "${revenueCatPackage.storeProduct.priceString} $translatedDuration";
187
+ }
188
+
189
+ @override
190
+ String pricePerMonth(BuildContext context) {
191
+ final translatedDuration = Translations.of(
192
+ context,
193
+ ).premium.duration_monthly;
194
+ if (durationType == DurationType.lifetime) {
195
+ return revenueCatPackage.storeProduct.priceString;
196
+ }
197
+ final pricePerMonth = switch (durationType) {
198
+ DurationType.year => price / 12,
199
+ DurationType.threeMonth => price / 3,
200
+ DurationType.sixMonth => price / 6,
201
+ DurationType.week => (price * 4) / 12,
202
+ _ => 1,
203
+ };
204
+ final pricePerMonthString = pricePerMonth.toStringAsFixed(2);
205
+ final money = revenueCatPackage.storeProduct.currencyCode;
206
+ if (money == "USD") {
207
+ return "\$$pricePerMonthString/$translatedDuration";
208
+ } else if (money == "EUR") {
209
+ return "$pricePerMonthString/$translatedDuration";
210
+ }
211
+ return "$pricePerMonthString $money/$translatedDuration";
212
+ }
213
+
214
+ @override
215
+ String? pricePerYear(BuildContext context) {
216
+ final translatedDuration = Translations.of(context).premium.duration_annual;
217
+ if (durationType == DurationType.lifetime) {
218
+ return revenueCatPackage.storeProduct.priceString;
219
+ }
220
+ final pricePerMonth = switch (durationType) {
221
+ DurationType.year => price,
222
+ DurationType.threeMonth => price * 4,
223
+ DurationType.sixMonth => price * 2,
224
+ DurationType.week => (price * 4) * 12,
225
+ _ => 1,
226
+ };
227
+ final pricePerMonthString = pricePerMonth.toStringAsFixed(2);
228
+ final money = revenueCatPackage.storeProduct.currencyCode;
229
+ if (money == "USD") {
230
+ return "\$$pricePerMonthString/$translatedDuration";
231
+ } else if (money == "EUR") {
232
+ return "$pricePerMonthString/$translatedDuration";
233
+ }
234
+ return "$pricePerMonthString $money/$translatedDuration";
235
+ }
236
+ }
237
+
238
+ enum DurationType { week, month, threeMonth, sixMonth, year, lifetime }
239
+
240
+ @freezed
241
+ sealed class Subscription with _$Subscription {
242
+ const factory Subscription.active({
243
+ SubscriptionProduct? activeOffer,
244
+ List<EntitlementInfo>? entitlements,
245
+ }) = SubscriptionStateData;
246
+
247
+ const factory Subscription.inactive({
248
+ required int hoursBetweenTwoRequests,
249
+ DateTime? lastAskingDate,
250
+ }) = SubscriptionInactiveStateData;
251
+
252
+ const factory Subscription.loading() = SubscriptionStateLoading;
253
+
254
+ const Subscription._();
255
+
256
+ factory Subscription.fromEntity(
257
+ SubscriptionEntity? entity,
258
+ DateTime? lastAskingDate, {
259
+ int hoursBetweenTwoRequests = 24,
260
+ }) {
261
+ if (entity == null ||
262
+ (entity.periodEndDate != null &&
263
+ entity.periodEndDate!.isBefore(DateTime.now()))) {
264
+ return Subscription.inactive(
265
+ hoursBetweenTwoRequests: hoursBetweenTwoRequests,
266
+ lastAskingDate: lastAskingDate,
267
+ );
268
+ }
269
+ return const Subscription.active();
270
+ }
271
+
272
+ bool get canPurchase => switch (this) {
273
+ SubscriptionStateData() => false,
274
+ SubscriptionInactiveStateData() => true,
275
+ SubscriptionStateLoading() => false,
276
+ };
277
+
278
+ bool get isActive => switch (this) {
279
+ SubscriptionStateData() => true,
280
+ SubscriptionInactiveStateData() => false,
281
+ SubscriptionStateLoading() => false,
282
+ };
283
+
284
+ bool get isInTrial => switch (this) {
285
+ SubscriptionStateData(:final entitlements) =>
286
+ entitlements?.firstOrNull?.periodType == PeriodType.trial,
287
+ SubscriptionInactiveStateData() => false,
288
+ SubscriptionStateLoading() => false,
289
+ };
290
+
291
+ bool get hasRenewal => switch (this) {
292
+ SubscriptionStateData(:final entitlements) =>
293
+ entitlements?.firstOrNull?.willRenew == true,
294
+ SubscriptionInactiveStateData() => false,
295
+ SubscriptionStateLoading() => false,
296
+ };
297
+
298
+ bool get isLifetime => switch (this) {
299
+ SubscriptionStateData(:final activeOffer) =>
300
+ activeOffer?.durationType == DurationType.lifetime,
301
+ SubscriptionInactiveStateData() => false,
302
+ SubscriptionStateLoading() => false,
303
+ };
304
+
305
+ bool get shouldAskForSubscription {
306
+ final now = DateTime.now();
307
+ final (lastAskingDate, hoursBetweenTwoRequests) = switch (this) {
308
+ SubscriptionStateData() => (null, null),
309
+ SubscriptionInactiveStateData(
310
+ :final lastAskingDate,
311
+ :final hoursBetweenTwoRequests,
312
+ ) =>
313
+ (lastAskingDate, hoursBetweenTwoRequests),
314
+ SubscriptionStateLoading() => (null, null),
315
+ };
316
+ if (lastAskingDate == null) {
317
+ return true;
318
+ }
319
+ final diff = now.difference(lastAskingDate);
320
+ return diff.inHours >= hoursBetweenTwoRequests!;
321
+ }
322
+ }
@@ -0,0 +1,41 @@
1
+ import 'package:flutter_riverpod/flutter_riverpod.dart';
2
+ import 'package:logger/logger.dart';
3
+ import 'package:kasy_kit/core/home_widgets/home_widget_mywidget_service.dart';
4
+ import 'package:kasy_kit/core/shared_preferences/shared_preferences.dart';
5
+ import 'package:kasy_kit/core/states/user_state_notifier.dart';
6
+ import 'package:kasy_kit/features/authentication/api/authentication_api.dart';
7
+ import 'package:kasy_kit/features/subscription/repositories/subscription_repository.dart';
8
+
9
+ /// Generated by Kasy CLI
10
+ /// ----
11
+ /// Background task callback for workmanager
12
+ /// This allows updating home widgets even when the app is in the background
13
+ @pragma('vm:entry-point')
14
+ Future<void> homeWidgetCallbackDispatcher() async {
15
+ try {
16
+ Logger().i('🔄 Home Widget background task triggered');
17
+ final globalContainer = ProviderContainer();
18
+ final sharedPreferences = globalContainer.read(sharedPreferencesProvider);
19
+ await sharedPreferences.init();
20
+ await globalContainer.read(authenticationApiProvider).init();
21
+ await globalContainer.read(subscriptionRepositoryProvider).init();
22
+ await globalContainer.read(userStateNotifierProvider.notifier).init();
23
+
24
+ /// If you want to restric the background task to only run when the user is subscribed,
25
+ /// you can use the subscription variable here.
26
+ // final subscription = globalContainer
27
+ // .read(userStateNotifierProvider)
28
+ // .subscription;
29
+
30
+ final myWidgetWidget = globalContainer.read(
31
+ myWidgetHomeWidgetProvider.notifier,
32
+ );
33
+ await myWidgetWidget.update();
34
+
35
+ globalContainer.dispose();
36
+ return;
37
+ } catch (e) {
38
+ Logger().e('Error in background task: $e');
39
+ return;
40
+ }
41
+ }
@@ -0,0 +1,305 @@
1
+ import 'package:flutter/foundation.dart';
2
+ import 'package:logger/logger.dart';
3
+ import 'package:kasy_kit/core/config/features.dart';
4
+ import 'package:kasy_kit/core/data/models/subscription.dart';
5
+ import 'package:kasy_kit/core/data/models/user.dart';
6
+ import 'package:kasy_kit/core/data/repositories/user_repository.dart';
7
+ import 'package:kasy_kit/core/initializer/onstart_service.dart';
8
+ import 'package:kasy_kit/core/states/models/user_state.dart';
9
+ import 'package:kasy_kit/environnements.dart';
10
+ import 'package:kasy_kit/features/authentication/repositories/authentication_repository.dart';
11
+ import 'package:kasy_kit/features/notifications/providers/models/device.dart';
12
+ import 'package:kasy_kit/features/notifications/repositories/device_repository.dart';
13
+ import 'package:purchases_flutter/models/entitlement_info_wrapper.dart';
14
+ import 'package:riverpod_annotation/riverpod_annotation.dart';
15
+
16
+ part 'user_state_notifier.g.dart';
17
+
18
+ /// Use this provider to access the user state (legacy name)
19
+ final userStateNotifierProvider = userStateProvider;
20
+
21
+ /// This enum is used to parameter the list of the authentication mode
22
+ ///
23
+ /// Most of apps try to not force user to create an account to access the app
24
+ /// But you may want to force the user to be authenticated to access the app
25
+ enum AuthenticationMode {
26
+ /// By default the user will be authenticated anonymously
27
+ /// This means that the user can access your app without login
28
+ /// He will be able to link his account later to an email or social login
29
+ anonymous,
30
+
31
+ /// The user requires to be authenticated to access the app
32
+ /// By default the user won't have any identity
33
+ authRequired,
34
+ }
35
+
36
+ /// This class is responsible for managing the state of the user over the app.
37
+ /// It will be used to know if the user is connected or not and to get the user
38
+ @Riverpod(keepAlive: true)
39
+ class UserStateNotifier extends _$UserStateNotifier implements OnStartService {
40
+ Logger get _logger => Logger();
41
+
42
+ AuthenticationRepository get _authenticationRepository =>
43
+ ref.read(authRepositoryProvider);
44
+
45
+ DeviceRepository get _deviceRepository => ref.read(deviceRepositoryProvider);
46
+
47
+ UserRepository get _userRepository => ref.read(userRepositoryProvider);
48
+
49
+ /// The authentication mode of the app.
50
+ /// On web (when withWeb is true), always require explicit auth —
51
+ /// anonymous accounts are not used on web.
52
+ /// see [AuthenticationMode]
53
+ AuthenticationMode get mode {
54
+ if (kIsWeb && withWeb) return AuthenticationMode.authRequired;
55
+ return ref.read(environmentProvider).authenticationMode;
56
+ }
57
+
58
+ @override
59
+ UserState build() {
60
+ return const UserState(user: User.loading());
61
+ }
62
+
63
+ @override
64
+ Future<void> init() async {
65
+ try {
66
+ await _loadState();
67
+ } catch (e, stacktrace) {
68
+ _logger.e(e, stackTrace: stacktrace);
69
+ if(kDebugMode) {
70
+ // we automatically logout the user if an error occurs in debug mode
71
+ // customize this behavior to fit your needs
72
+ _authenticationRepository.logout();
73
+ }
74
+ rethrow;
75
+ }
76
+ assert(state.user is! LoadingUserData, 'UserStateNotifier is not ready');
77
+ await _initDeviceRegistration();
78
+ _deviceRepository.onTokenUpdate(_onUpdateToken);
79
+ }
80
+
81
+ /// This function is called when the user click on the signin button
82
+ /// It will load the user state and register the device to the notification service
83
+ /// It will also load the subscription state
84
+ Future<void> onSignin() async {
85
+ state = const UserState(
86
+ user: User.loading(),
87
+ );
88
+ await _loadState();
89
+ await _initDeviceRegistration();
90
+ }
91
+
92
+ /// Set the user as onboarded in the database
93
+ /// This function is called when the user has completed the onboarding
94
+ Future<void> onOnboarded() async {
95
+ if (state.user.idOrNull == null) {
96
+ // Guest with no account: persist onboarding in local state only.
97
+ // No Firestore document exists yet — no write needed.
98
+ state = state.copyWith(user: const User.anonymous(onboarded: true));
99
+ return;
100
+ }
101
+ final newUser = await _userRepository.setOnboarded(state.user);
102
+ state = state.copyWith(user: newUser);
103
+ }
104
+
105
+ /// This function is called when the user click on the logout button
106
+ /// It will unregister the device from the notification service
107
+ /// and logout the user
108
+ Future<void> onLogout() async {
109
+ final userId = state.user.idOrThrow;
110
+ _deviceRepository.removeTokenUpdateListener();
111
+ await _deviceRepository.unregister(userId);
112
+ await _authenticationRepository.logout();
113
+ state = const UserState(
114
+ user: User.anonymous(),
115
+ );
116
+ if (mode == AuthenticationMode.anonymous) {
117
+ await _loadAnonymousState();
118
+ }
119
+ }
120
+
121
+ /// Refresh the user
122
+ Future<void> onUpdateAvatar() async {
123
+ await refresh();
124
+ }
125
+
126
+ /// Refresh the user
127
+ Future<void> refresh() async {
128
+ final id = state.user.idOrNull;
129
+ if (id == null) return; // Guest: no Firestore document, nothing to refresh
130
+ final user = await _userRepository.get(id);
131
+ state = state.copyWith(user: user ?? const User.anonymous());
132
+ }
133
+
134
+ /// This function is called after a user successfuly purchased a subscription
135
+ /// It will refresh the subscription state without waiting for the webhook
136
+ /// (which can take some time and could show a wrong state to the user)
137
+ /// On next app start, the subscription will be refreshed from the webhook result
138
+ Future<void> refreshSubscription({
139
+ SubscriptionProduct? product,
140
+ List<EntitlementInfo>? entitlements,
141
+ }) async {
142
+ if (product != null) {
143
+ final newUser = switch (state.user) {
144
+ final AuthenticatedUserData user => user.copyWith(
145
+ subscription: Subscription.active(
146
+ activeOffer: product,
147
+ entitlements: entitlements,
148
+ ),
149
+ ),
150
+ final AnonymousUserData user => user.copyWith(
151
+ subscription: Subscription.active(
152
+ activeOffer: product,
153
+ entitlements: entitlements,
154
+ ),
155
+ ),
156
+ final LoadingUserData _ => throw 'User is not connected',
157
+ };
158
+ state = state.copyWith(user: newUser);
159
+ return;
160
+ }
161
+ await Future.delayed(const Duration(seconds: 2));
162
+ await _loadState();
163
+ }
164
+
165
+ /// Apple store and Google play stores requires you to be able to delete a user account on demand
166
+ /// Here is the function to do it.
167
+ /// It will delete the user account and logout the user
168
+ Future<void> deleteAccount() async {
169
+ try {
170
+ final userId = state.user.idOrThrow;
171
+ _deviceRepository.removeTokenUpdateListener();
172
+ await _deviceRepository.unregister(userId);
173
+ await _userRepository.delete();
174
+ await _authenticationRepository.logout();
175
+ } catch (e) {
176
+ _logger.e(e);
177
+ }
178
+ state = const UserState(
179
+ user: User.anonymous(),
180
+ );
181
+
182
+ if (mode == AuthenticationMode.anonymous) {
183
+ await _loadAnonymousState();
184
+ }
185
+ }
186
+
187
+ // -------------------------------
188
+ // PRIVATES
189
+ // -------------------------------
190
+
191
+ /// load anonymous state for the user
192
+ Future<void> _loadAnonymousState() async {
193
+ await _authenticationRepository.signupAnonymously();
194
+ await Future.delayed(const Duration(seconds: 1));
195
+ final credentials = await _authenticationRepository.get();
196
+ var user = await _userRepository.get(credentials!.id);
197
+ // We retry to get the user 3 times (sometimes the user creation trigger is not fast enough)
198
+ var retry = 0;
199
+ while (user == null && retry < 3) {
200
+ await Future.delayed(const Duration(seconds: 1));
201
+ user = await _userRepository.get(credentials.id);
202
+ retry++;
203
+ }
204
+ if (user == null) {
205
+ // Backend not deployed yet: the Cloud Function onUserRegistration has not
206
+ // created the Firestore document. Log the issue for the developer and fall
207
+ // back to a local anonymous state so the app still opens.
208
+ _logger.e(
209
+ '⚠️ User profile not found in database.\n'
210
+ ' The backend may not be deployed yet.\n'
211
+ ' Run: kasy deploy\n'
212
+ ' Then restart the app.',
213
+ );
214
+ state = state.copyWith(user: User.anonymous(id: credentials.id));
215
+ return;
216
+ }
217
+ state = state.copyWith(user: user);
218
+ }
219
+
220
+ /// Load the state of the user
221
+ Future<void> _loadState() async {
222
+ final credentials = await _authenticationRepository.get();
223
+
224
+ if (credentials == null && mode == AuthenticationMode.anonymous) {
225
+ _logger.i('Anonymous user mode activated, signup anonymously');
226
+ await _loadAnonymousState();
227
+ } else if (credentials == null && mode == AuthenticationMode.authRequired) {
228
+ _logger.i('Authentification required, user is not connected');
229
+ state = state.copyWith(user: const User.anonymous());
230
+ } else if (credentials != null) {
231
+ _logger.i('User is connected with id ${credentials.id}');
232
+ var user = await _userRepository.get(credentials.id);
233
+ // Retry a few times: the Cloud Function onUserRegistration may not have
234
+ // finished creating the Firestore document yet (race condition on first login).
235
+ var retry = 0;
236
+ while (user == null && retry < 3) {
237
+ await Future.delayed(const Duration(seconds: 1));
238
+ user = await _userRepository.get(credentials.id);
239
+ retry++;
240
+ }
241
+ if (user == null) {
242
+ // User document not found after login. Possible causes:
243
+ // - Firebase: onUserRegistration Cloud Function not deployed or failed
244
+ // - Supabase: handle_new_user trigger not run yet (race) or failed
245
+ // - User was deleted but session was still cached
246
+ // Logout to clear invalid session, then create new anonymous user if applicable.
247
+ _logger.e(
248
+ '⚠️ User profile not found in database after sign-in.\n'
249
+ ' Logging out and creating new anonymous user.',
250
+ );
251
+ await _authenticationRepository.logout();
252
+ state = state.copyWith(user: const User.anonymous());
253
+ if (mode == AuthenticationMode.anonymous) {
254
+ await _loadAnonymousState();
255
+ }
256
+ return;
257
+ }
258
+ // If the Firestore document is anonymous (no email) but Firebase Auth
259
+ // already has an email (happens after linkWithProvider — Google, email, etc.),
260
+ // sync the email and name so the user is properly recognised as authenticated.
261
+ if (user is AnonymousUserData) {
262
+ final authEmail = await _authenticationRepository.getCurrentUserEmail();
263
+ if (authEmail != null && authEmail.isNotEmpty) {
264
+ final authName = await _authenticationRepository.getCurrentUserDisplayName();
265
+ await _userRepository.updateEmailAndName(
266
+ userId: credentials.id,
267
+ email: authEmail,
268
+ name: authName,
269
+ );
270
+ final syncedUser = await _userRepository.get(credentials.id);
271
+ state = state.copyWith(user: syncedUser ?? user);
272
+ return;
273
+ }
274
+ }
275
+ state = state.copyWith(user: user);
276
+ }
277
+ }
278
+
279
+ /// If user has an ID we will register his device to send notifications from
280
+ /// the server to the device (only if user has accepted them)
281
+ /// Maybe save your device in UserState if you need it in your app
282
+ Future<void> _initDeviceRegistration() async {
283
+ if (kIsWeb) return;
284
+ final userId = state.user.idOrNull;
285
+ if (userId == null) {
286
+ return;
287
+ }
288
+ try {
289
+ final _ = await _deviceRepository.register(userId);
290
+ } catch (err, stacktrace) {
291
+ _logger.e(err, stackTrace: stacktrace);
292
+ _logger.e('''
293
+ ❌ Your device seems not to be registered.
294
+ Check that you correctly setup a device registration API
295
+ see: `lib/features/notifications/api/device_api.dart`
296
+ ''');
297
+ }
298
+ }
299
+
300
+ /// This function is called when the device token is updated
301
+ /// It will update the token in the database
302
+ Future<void> _onUpdateToken(Device device) async {
303
+ await _deviceRepository.updateToken(device.token);
304
+ }
305
+ }