kasy-cli 1.21.9 → 1.23.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.
- package/lib/commands/add.js +93 -80
- package/lib/commands/configure.js +100 -32
- package/lib/commands/doctor.js +28 -2
- package/lib/commands/new.js +80 -37
- package/lib/commands/notifications.js +1 -1
- package/lib/commands/remove.js +43 -15
- package/lib/commands/run.js +2 -2
- package/lib/commands/update.js +2 -2
- package/lib/scaffold/CHANGELOG.json +14 -0
- package/lib/scaffold/backends/api/generator.js +14 -14
- package/lib/scaffold/backends/api/patch/README.md +83 -0
- package/lib/scaffold/backends/api/patch/lib/core/data/api/storage_api.dart +1 -1
- package/lib/scaffold/backends/api/patch/lib/core/data/entities/user_entity.dart +5 -0
- package/lib/scaffold/backends/api/patch/lib/{environnements.dart → environments.dart} +3 -11
- package/lib/scaffold/backends/api/patch/lib/features/ai_chat/api/ai_chat_api.dart +108 -0
- package/lib/scaffold/backends/api/patch/lib/features/ai_chat/api/ai_chat_conversation_entity.dart +51 -0
- package/lib/scaffold/backends/api/patch/lib/features/{llm_chat/api/llm_chat_message_entity.dart → ai_chat/api/ai_chat_message_entity.dart} +5 -5
- package/lib/scaffold/backends/api/patch/lib/features/{llm_chat/providers/llm_chat_notifier.dart → ai_chat/providers/ai_chat_notifier.dart} +71 -38
- package/lib/scaffold/backends/api/patch/lib/features/authentication/api/authentication_api.dart +2 -2
- package/lib/scaffold/backends/api/patch/lib/features/feedbacks/api/feature_request_api.dart +54 -0
- package/lib/scaffold/backends/api/patch/lib/features/onboarding/models/user_info.dart +16 -16
- package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/components/onboarding_att_setup.dart +4 -3
- package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +38 -28
- package/lib/scaffold/backends/api/patch/lib/features/settings/ui/components/admin/admin_users_api.dart +100 -0
- package/lib/scaffold/backends/api/patch/lib/features/{subscription → subscriptions}/api/entities/subscription_entity.dart +13 -0
- package/lib/scaffold/backends/api/patch/lib/features/subscriptions/api/stripe_backend_api.dart +60 -0
- package/lib/scaffold/backends/api/patch/lib/features/{subscription → subscriptions}/api/subscription_api.dart +1 -1
- package/lib/scaffold/backends/api/pubspec.yaml.tpl +4 -5
- package/lib/scaffold/backends/firebase/deploy.js +87 -13
- package/lib/scaffold/backends/firebase/generator.js +5 -5
- package/lib/scaffold/backends/firebase/tokens.js +4 -4
- package/lib/scaffold/backends/supabase/deploy.js +63 -11
- package/lib/scaffold/backends/supabase/edge-functions/admin-list-users/index.ts +149 -0
- package/lib/scaffold/backends/supabase/edge-functions/{llm-chat → ai-chat}/index.ts +19 -19
- package/lib/scaffold/backends/supabase/edge-functions/revenuecat-webhook/index.ts +2 -0
- package/lib/scaffold/backends/supabase/edge-functions/stripe-create-checkout-session/index.ts +123 -0
- package/lib/scaffold/backends/supabase/edge-functions/stripe-create-portal-session/index.ts +97 -0
- package/lib/scaffold/backends/supabase/edge-functions/stripe-list-prices/index.ts +83 -0
- package/lib/scaffold/backends/supabase/edge-functions/stripe-webhook/index.ts +138 -0
- package/lib/scaffold/backends/supabase/generator.js +17 -17
- package/lib/scaffold/backends/supabase/migrations/20240101000009_ai_messages.sql +50 -0
- package/lib/scaffold/backends/supabase/migrations/20240101000012_stripe_customers.sql +36 -0
- package/lib/scaffold/backends/supabase/migrations/20240101000013_admin_role.sql +62 -0
- package/lib/scaffold/backends/supabase/patch/lib/core/data/entities/user_entity.dart +4 -0
- package/lib/scaffold/backends/supabase/patch/lib/{environnements.dart → environments.dart} +3 -13
- package/lib/scaffold/backends/supabase/patch/lib/features/ai_chat/api/ai_chat_api.dart +95 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/ai_chat/api/ai_chat_conversation_entity.dart +52 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/{llm_chat/api/llm_chat_message_entity.dart → ai_chat/api/ai_chat_message_entity.dart} +6 -6
- package/lib/scaffold/backends/supabase/patch/lib/features/{llm_chat/providers/llm_chat_notifier.dart → ai_chat/providers/ai_chat_notifier.dart} +63 -35
- package/lib/scaffold/backends/supabase/patch/lib/features/authentication/api/authentication_api.dart +1 -1
- package/lib/scaffold/backends/supabase/patch/lib/features/feedbacks/api/feature_request_api.dart +46 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/models/user_info.dart +16 -16
- package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/components/onboarding_att_setup.dart +4 -3
- package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +38 -28
- package/lib/scaffold/backends/supabase/patch/lib/features/settings/ui/components/admin/admin_users_api.dart +93 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/{subscription → subscriptions}/api/entities/subscription_entity.dart +13 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/subscriptions/api/stripe_backend_api.dart +52 -0
- package/lib/scaffold/backends/supabase/patch/lib/features/{subscription → subscriptions}/api/subscription_api.dart +1 -1
- package/lib/scaffold/backends/supabase/pubspec.yaml.tpl +4 -5
- package/lib/scaffold/backends/supabase/tokens.js +3 -3
- package/lib/scaffold/catalog.js +9 -11
- package/lib/scaffold/generate.js +45 -31
- package/lib/scaffold/shared/generator-utils.js +188 -81
- package/lib/scaffold/shared/sort-imports.js +191 -0
- package/lib/scaffold/shared/template-strings.js +3 -3
- package/lib/utils/checks.js +22 -6
- package/lib/utils/env-tools.js +7 -0
- package/lib/utils/flutter-install.js +114 -0
- package/lib/utils/i18n/messages-en.js +52 -35
- package/lib/utils/i18n/messages-es.js +52 -35
- package/lib/utils/i18n/messages-pt.js +54 -37
- package/lib/utils/updates.js +15 -15
- package/package.json +1 -1
- package/templates/firebase/.env.example +2 -2
- package/templates/firebase/android/app/src/main/res/drawable/background.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night/background.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-night-v21/background.png +0 -0
- package/templates/firebase/android/app/src/main/res/drawable-v21/background.png +0 -0
- package/templates/firebase/android/app/src/main/res/values-night-v31/styles.xml +1 -1
- package/templates/firebase/android/app/src/main/res/values-v31/styles.xml +1 -1
- package/templates/firebase/assets/images/logo_wordmark_dark.png +0 -0
- package/templates/firebase/assets/images/logo_wordmark_light.png +0 -0
- package/templates/firebase/docs/revenuecat-setup.es.md +1 -1
- package/templates/firebase/docs/revenuecat-setup.pt.md +1 -1
- package/templates/firebase/firestore.rules +24 -5
- package/templates/firebase/functions/package-lock.json +22 -1
- package/templates/firebase/functions/package.json +2 -1
- package/templates/firebase/functions/src/admin/functions.ts +113 -0
- package/templates/firebase/functions/src/{llm_chat → ai_chat}/index.ts +16 -16
- package/templates/firebase/functions/src/index.ts +8 -2
- package/templates/firebase/functions/src/notifications/device_triggers.ts +2 -2
- package/templates/firebase/functions/src/notifications/triggers.ts +3 -3
- package/templates/firebase/functions/src/subscriptions/models/subscription_status.ts +2 -0
- package/templates/firebase/functions/src/subscriptions/stripe_functions.ts +222 -0
- package/templates/firebase/functions/src/subscriptions/subscriptions_functions.ts +2 -2
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png +0 -0
- package/templates/firebase/ios/Runner/Assets.xcassets/LaunchBackground.imageset/darkbackground.png +0 -0
- package/templates/firebase/lib/components/components.dart +4 -1
- package/templates/firebase/lib/components/kasy_app_bar.dart +22 -7
- package/templates/firebase/lib/components/kasy_avatar.dart +7 -6
- package/templates/firebase/lib/components/kasy_button.dart +23 -99
- package/templates/firebase/lib/components/kasy_dialog.dart +11 -11
- package/templates/firebase/lib/components/kasy_image_viewer.dart +84 -0
- package/templates/firebase/lib/components/{kasy_sidebar_pro.dart → kasy_sidebar.dart} +702 -425
- package/templates/firebase/lib/components/kasy_status_tag.dart +91 -0
- package/templates/firebase/lib/components/kasy_text_area.dart +1 -3
- package/templates/firebase/lib/components/kasy_text_field.dart +5 -6
- package/templates/firebase/lib/components/kasy_text_field_otp.dart +1 -3
- package/templates/firebase/lib/components/kasy_toast.dart +2 -2
- package/templates/firebase/lib/components/kasy_web_header.dart +209 -0
- package/templates/firebase/lib/core/ads/ads_provider.dart +1 -1
- package/templates/firebase/lib/core/bottom_menu/bottom_menu.dart +136 -23
- package/templates/firebase/lib/core/bottom_menu/bottom_router.dart +19 -91
- package/templates/firebase/lib/core/bottom_menu/kasy_bottom_bar_factory.dart +196 -96
- package/templates/firebase/lib/core/bottom_menu/web_content_wrapper.dart +54 -0
- package/templates/firebase/lib/core/config/app_env.dart +5 -11
- package/templates/firebase/lib/core/config/features.dart +5 -4
- package/templates/firebase/lib/core/data/api/analytics_api.dart +1 -1
- package/templates/firebase/lib/core/data/api/http_client.dart +1 -1
- package/templates/firebase/lib/core/data/entities/user_entity.dart +3 -0
- package/templates/firebase/lib/core/data/models/entitlement.dart +35 -0
- package/templates/firebase/lib/core/data/models/subscription.dart +13 -186
- package/templates/firebase/lib/core/data/models/user.dart +11 -0
- package/templates/firebase/lib/core/data/repositories/user_repository.dart +1 -1
- package/templates/firebase/lib/core/home_widgets/home_widget_background_task.dart +1 -1
- package/templates/firebase/lib/core/home_widgets/home_widget_mywidget_service.dart +1 -1
- package/templates/firebase/lib/core/icons/kasy_icons.dart +31 -1
- package/templates/firebase/lib/core/rating/api/rating_api.dart +2 -2
- package/templates/firebase/lib/core/states/logout_action.dart +25 -0
- package/templates/firebase/lib/core/states/user_state_notifier.dart +3 -3
- package/templates/firebase/lib/core/theme/colors.dart +488 -188
- package/templates/firebase/lib/core/theme/radius.dart +22 -11
- package/templates/firebase/lib/core/theme/shadows.dart +66 -0
- package/templates/firebase/lib/core/theme/texts.dart +75 -41
- package/templates/firebase/lib/core/theme/universal_theme.dart +9 -4
- package/templates/firebase/lib/core/web_device_preview/web_device_preview.dart +5 -4
- package/templates/firebase/lib/core/web_viewport_scale.dart +52 -0
- package/templates/firebase/lib/core/widgets/kasy_brand_badge.dart +118 -0
- package/templates/firebase/lib/core/widgets/kasy_brand_logo.dart +40 -0
- package/templates/firebase/lib/core/widgets/kasy_focus_ring.dart +125 -0
- package/templates/firebase/lib/core/widgets/kasy_hover.dart +53 -14
- package/templates/firebase/lib/core/widgets/kasy_pressable_depth.dart +18 -13
- package/templates/firebase/lib/{environnements.dart → environments.dart} +3 -14
- package/templates/firebase/lib/features/ai_chat/ai_chat_page.dart +159 -0
- package/templates/firebase/lib/features/ai_chat/api/ai_chat_api.dart +107 -0
- package/templates/firebase/lib/features/ai_chat/api/ai_chat_conversation_entity.dart +64 -0
- package/templates/firebase/lib/features/{llm_chat/api/llm_chat_message_entity.dart → ai_chat/api/ai_chat_message_entity.dart} +6 -6
- package/templates/firebase/lib/features/{llm_chat/providers/llm_chat_notifier.dart → ai_chat/providers/ai_chat_notifier.dart} +73 -38
- package/templates/firebase/lib/features/ai_chat/providers/ai_conversations_notifier.dart +103 -0
- package/templates/firebase/lib/features/{llm_chat/ui/widgets/llm_chat_avatars.dart → ai_chat/ui/widgets/ai_chat_avatars.dart} +13 -13
- package/templates/firebase/lib/features/{llm_chat/ui/widgets/llm_chat_composer.dart → ai_chat/ui/widgets/ai_chat_composer.dart} +10 -10
- package/templates/firebase/lib/features/{llm_chat/llm_chat_page.dart → ai_chat/ui/widgets/ai_chat_conversation_view.dart} +80 -67
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_list.dart +285 -0
- package/templates/firebase/lib/features/ai_chat/ui/widgets/ai_conversation_tile.dart +163 -0
- package/templates/firebase/lib/features/authentication/api/authentication_api.dart +52 -13
- package/templates/firebase/lib/features/authentication/api/popup_dismiss_watcher.dart +12 -0
- package/templates/firebase/lib/features/authentication/api/popup_dismiss_watcher_web.dart +35 -0
- package/templates/firebase/lib/features/authentication/ui/recover_password_page.dart +108 -68
- package/templates/firebase/lib/features/authentication/ui/signin_page.dart +38 -51
- package/templates/firebase/lib/features/authentication/ui/signup_page.dart +38 -51
- package/templates/firebase/lib/features/authentication/ui/widgets/auth_card_scaffold.dart +128 -0
- package/templates/firebase/lib/features/authentication/ui/widgets/recover_password_result.dart +61 -44
- package/templates/firebase/lib/features/feedbacks/api/feature_request_api.dart +32 -0
- package/templates/firebase/lib/features/feedbacks/models/feedback_state.dart +5 -5
- package/templates/firebase/lib/features/feedbacks/providers/feedback_page_notifier.dart +2 -2
- package/templates/firebase/lib/features/home/design_system_page.dart +808 -170
- package/templates/firebase/lib/features/home/home_components_page.dart +6 -3
- package/templates/firebase/lib/features/home/home_components_preview_page.dart +6 -6
- package/templates/firebase/lib/features/home/home_components_preview_registry.dart +325 -186
- package/templates/firebase/lib/features/home/home_feed.dart +289 -0
- package/templates/firebase/lib/features/home/home_image_grid.dart +355 -0
- package/templates/firebase/lib/features/home/home_page.dart +11 -250
- package/templates/firebase/lib/features/{local_reminder → local_reminders}/providers/reminder_notifier.dart +1 -1
- package/templates/firebase/lib/features/{local_reminder → local_reminders}/ui/reminder_page.dart +2 -2
- package/templates/firebase/lib/features/notifications/shared/att_permission.dart +1 -1
- package/templates/firebase/lib/features/notifications/ui/request_notification_permission.dart +25 -61
- package/templates/firebase/lib/features/notifications/ui/widgets/permission_request_view.dart +117 -0
- package/templates/firebase/lib/features/onboarding/models/user_info.dart +16 -16
- package/templates/firebase/lib/features/onboarding/ui/components/onboarding_att_setup.dart +4 -3
- package/templates/firebase/lib/features/onboarding/ui/components/onboarding_features.dart +7 -9
- package/templates/firebase/lib/features/onboarding/ui/components/onboarding_loader.dart +71 -48
- package/templates/firebase/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +3 -2
- package/templates/firebase/lib/features/onboarding/ui/components/onboarding_questions.dart +5 -5
- package/templates/firebase/lib/features/onboarding/ui/onboarding_page.dart +4 -4
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_background.dart +4 -2
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_feature.dart +39 -121
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_illustration_scaffold.dart +105 -70
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_module_mockups.dart +639 -0
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_progress.dart +62 -50
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_radio_question.dart +38 -28
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_step_header.dart +75 -0
- package/templates/firebase/lib/features/onboarding/ui/widgets/onboarding_sticky_footer.dart +16 -5
- package/templates/firebase/lib/features/onboarding/ui/widgets/selectable_row_tile.dart +26 -22
- package/templates/firebase/lib/features/settings/settings_page.dart +601 -90
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_page.dart +1193 -0
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_paywalls.dart +1 -1
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_routes.dart +2 -3
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_api.dart +86 -0
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_users_tab.dart +1215 -0
- package/templates/firebase/lib/features/settings/ui/components/admin/send_push_notification_page.dart +236 -0
- package/templates/firebase/lib/features/settings/ui/components/avatar_component.dart +3 -3
- package/templates/firebase/lib/features/settings/ui/widgets/kasy_user_avatar.dart +77 -0
- package/templates/firebase/lib/features/settings/ui/widgets/settings_tile.dart +1 -0
- package/templates/firebase/lib/features/{subscription → subscriptions}/api/entities/subscription_entity.dart +17 -0
- package/templates/firebase/lib/features/{subscription → subscriptions}/api/inapp_subscription_api.dart +67 -46
- package/templates/firebase/lib/features/subscriptions/api/revenuecat_product.dart +189 -0
- package/templates/firebase/lib/features/subscriptions/api/stripe_backend_api.dart +55 -0
- package/templates/firebase/lib/features/subscriptions/api/stripe_payment_api.dart +82 -0
- package/templates/firebase/lib/features/subscriptions/api/stripe_product.dart +178 -0
- package/templates/firebase/lib/features/{subscription → subscriptions}/api/subscription_api.dart +1 -1
- package/templates/firebase/lib/features/subscriptions/api/subscription_payment_api.dart +53 -0
- package/templates/firebase/lib/features/subscriptions/api/subscription_payment_api_provider.dart +21 -0
- package/templates/firebase/lib/features/{subscription → subscriptions}/providers/premium_page_provider.dart +9 -6
- package/templates/firebase/lib/features/{subscription → subscriptions}/repositories/subscription_repository.dart +26 -30
- package/{lib/scaffold/backends/supabase/patch/lib/features/subscription → templates/firebase/lib/features/subscriptions}/shared/maybeshow_premium.dart +0 -2
- package/templates/firebase/lib/features/subscriptions/shared/subscription_management.dart +45 -0
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/active_premium_content.dart +28 -4
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/paywall_minimal.dart +7 -7
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/paywall_row.dart +8 -8
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/paywall_with_switch.dart +7 -7
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/premium_content.dart +7 -7
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/component/premium_page_factory.dart +5 -5
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/premium_page.dart +5 -5
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/comparison_table.dart +1 -1
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/paywall_empty_state.dart +4 -4
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_bottom_menu.dart +3 -4
- package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/selectable_col.dart +1 -1
- package/templates/firebase/lib/i18n/en.i18n.json +171 -46
- package/templates/firebase/lib/i18n/es.i18n.json +175 -50
- package/templates/firebase/lib/i18n/pt.i18n.json +166 -41
- package/templates/firebase/lib/main.dart +6 -3
- package/templates/firebase/lib/router.dart +15 -23
- package/templates/firebase/pubspec.yaml +5 -6
- package/templates/firebase/test/core/data/repositories/user_repository_test.dart +3 -3
- package/templates/firebase/test/core/states/user_state_notifier_test.dart +4 -4
- package/templates/firebase/test/core/widgets/focus_ring_shape_test.dart +55 -0
- package/templates/firebase/test/features/{subscription → subscriptions}/api/fake_inapp_subscription_api.dart +11 -4
- package/templates/firebase/test/features/{subscription → subscriptions}/api/fake_revenuecat_product.dart +1 -0
- package/templates/firebase/test/features/{subscription → subscriptions}/api/fake_subscription_api.dart +2 -2
- package/templates/firebase/test/features/{subscription → subscriptions}/subscription_page_test.dart +4 -4
- package/templates/firebase/test/test_utils.dart +6 -6
- package/templates/firebase/web/index.html +5 -2
- package/lib/scaffold/backends/api/patch/lib/features/llm_chat/api/llm_chat_api.dart +0 -58
- package/lib/scaffold/backends/api/patch/lib/features/subscription/shared/maybeshow_premium.dart +0 -86
- package/lib/scaffold/backends/supabase/migrations/20240101000009_llm_messages.sql +0 -22
- package/lib/scaffold/backends/supabase/patch/lib/features/llm_chat/api/llm_chat_api.dart +0 -47
- package/templates/firebase/assets/images/onboarding/authentication-login-template.jpg +0 -0
- package/templates/firebase/assets/images/onboarding/img2.jpg +0 -0
- package/templates/firebase/assets/images/onboarding/img3.jpg +0 -0
- package/templates/firebase/assets/images/onboarding/notifications.png +0 -0
- package/templates/firebase/assets/images/onboarding/purchase.png +0 -0
- package/templates/firebase/lib/core/sidebar/kasy_sidebar.dart +0 -2021
- package/templates/firebase/lib/features/authentication/ui/widgets/auth_brand.dart +0 -35
- package/templates/firebase/lib/features/home/home_features_page.dart +0 -207
- package/templates/firebase/lib/features/llm_chat/api/llm_chat_api.dart +0 -50
- package/templates/firebase/lib/features/settings/ui/components/admin/admin_bottom_sheet.dart +0 -316
- package/templates/firebase/lib/features/subscription/shared/maybeshow_premium.dart +0 -85
- /package/templates/firebase/lib/features/{local_reminder → local_reminders}/repositories/reminder_preferences.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/providers/models/premium_state.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/feature_line.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_background.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_background_gradient.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_banner.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_card.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_close_button.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/premium_feature.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/selectable_row.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/trial_switcher.dart +0 -0
- /package/templates/firebase/lib/features/{subscription → subscriptions}/ui/widgets/unsubscribe_feedback_popup.dart +0 -0
|
@@ -43,7 +43,7 @@ module.exports = {
|
|
|
43
43
|
'cli.command.setup.langName': 'idioma',
|
|
44
44
|
'cli.command.setup.langOption': 'Idioma de prompts (en, pt, es)',
|
|
45
45
|
'cli.command.setup.backendOption': 'Adapter de backend (firebase, supabase, api)',
|
|
46
|
-
'cli.command.setup.featuresOption': 'Features opcionales separadas por coma (web,widget,
|
|
46
|
+
'cli.command.setup.featuresOption': 'Features opcionales separadas por coma (web,widget,ai_chat,revenuecat,ci)',
|
|
47
47
|
'cli.command.help.paramName': 'comando',
|
|
48
48
|
'cli.command.doctor.description': 'Verifica si tu computadora está lista para correr Kasy',
|
|
49
49
|
'cli.command.modules.description': 'Muestra lo que viene incluido y lo que puedes añadir',
|
|
@@ -109,15 +109,15 @@ module.exports = {
|
|
|
109
109
|
'modules.backend.supabase.description': 'Adapter de backend Supabase',
|
|
110
110
|
'modules.backend.api.description': 'Adapter de backend API REST/GraphQL',
|
|
111
111
|
'modules.feature.sentry.description': 'Seguimiento de errores y crashes con Sentry',
|
|
112
|
-
'modules.feature.analytics.description': 'Seguimiento de eventos de analytics (
|
|
112
|
+
'modules.feature.analytics.description': 'Seguimiento de eventos de analytics (Mixpanel)',
|
|
113
113
|
'modules.feature.facebook.description': 'Login de Facebook y seguimiento de eventos Meta Ads (siempre juntos)',
|
|
114
114
|
'modules.feature.revenuecat.description': 'Habilita pagos reales en la pantalla de Subscriptions',
|
|
115
115
|
'modules.feature.onboarding.description': 'Flujo de bienvenida mostrado en el primer acceso',
|
|
116
116
|
'modules.feature.web.description': 'Soporte Web/PWA',
|
|
117
117
|
'modules.feature.widget.description': 'Widget de pantalla inicial iOS/Android',
|
|
118
|
-
'modules.feature.
|
|
118
|
+
'modules.feature.ai_chat.description': 'Pantalla de chat con IA usando OpenAI o Gemini',
|
|
119
119
|
'modules.feature.feedback.description': 'Solicitudes y votacion de features dentro de la app',
|
|
120
|
-
'modules.feature.
|
|
120
|
+
'modules.feature.local_reminders.description': 'Recordatorios locales programados por el usuario (sin servidor)',
|
|
121
121
|
'modules.feature.ci.description': 'CI/CD: GitHub/GitLab (tests + build) + Codemagic (publicación en tiendas)',
|
|
122
122
|
'checks.checking': 'Verificando {name}...',
|
|
123
123
|
'checks.found': '{name} encontrado',
|
|
@@ -134,6 +134,8 @@ module.exports = {
|
|
|
134
134
|
'checks.thenRun': 'Luego ejecuta',
|
|
135
135
|
'checks.recheck': 'Tras instalar {name}, presiona Enter para verificar de nuevo',
|
|
136
136
|
'checks.install.confirm': '¿Instalar {name} ahora? ({cmd})',
|
|
137
|
+
'checks.install.flutterWinDesc': 'descarga el SDK oficial de Flutter + Git, ~1,8 GB',
|
|
138
|
+
'checks.install.flutterWinNote': 'Esto puede tardar unos minutos (descarga grande). Si aparece una ventana de permiso de Windows, haz clic en Sí.',
|
|
137
139
|
'checks.install.running': 'Instalando {name}…',
|
|
138
140
|
'checks.install.failedManual': 'No pude instalar {name} automáticamente. Hazlo manualmente:',
|
|
139
141
|
'checks.install.openDocs': '¿Abrir la página de instalación en el navegador?',
|
|
@@ -270,6 +272,9 @@ module.exports = {
|
|
|
270
272
|
'new.supabase.created': 'Proyecto creado correctamente.',
|
|
271
273
|
'new.supabase.createFailed': 'No se pudo crear el proyecto',
|
|
272
274
|
'new.supabase.loginHint': 'Ejecuta: supabase login. Luego ingresa la URL y clave de tu proyecto existente.',
|
|
275
|
+
'new.supabase.createFailed.freeLimit': 'Tu plan gratis de Supabase alcanzó el límite de proyectos en esta organización.',
|
|
276
|
+
'new.supabase.freeLimit.title': 'Cómo desbloquear',
|
|
277
|
+
'new.supabase.freeLimit.options': '• Borra un proyecto que ya no uses\n• Elige otra organización (si tienes más de una)\n• O mejora tu plan en el panel de Supabase\nLuego ejecuta kasy new de nuevo.',
|
|
273
278
|
'new.supabase.setup': 'Vinculando proyecto y desplegando…',
|
|
274
279
|
'new.supabase.setupManual': 'Ejecuta manualmente: supabase link, supabase db push, supabase functions deploy',
|
|
275
280
|
'new.supabase.passwordSaved': 'Contraseña de la base generada y guardada en .kasy/supabase.json (gitignored).',
|
|
@@ -347,8 +352,10 @@ module.exports = {
|
|
|
347
352
|
'configure.section.sentry': 'Sentry (Crash Reports)',
|
|
348
353
|
'configure.section.mixpanel': 'Mixpanel (Analytics)',
|
|
349
354
|
'configure.section.revenuecat': 'RevenueCat (Suscripciones)',
|
|
355
|
+
'configure.section.stripe': 'Stripe (Pagos en Web)',
|
|
356
|
+
'configure.stripe.apiNote': 'Backend API: configura STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET en tu propio servidor (ver Stripe-Guia.md). La CLI no puede guardarlas.',
|
|
350
357
|
'configure.section.facebook': 'Facebook (Login + Ads)',
|
|
351
|
-
'configure.section.
|
|
358
|
+
'configure.section.aiChat': 'AI Chat',
|
|
352
359
|
'configure.savedFacebook': 'Credenciales de Facebook escritas en Info.plist y strings.xml.',
|
|
353
360
|
'configure.facebookPlistMissing': 'ios/Runner/Info.plist no encontrado — Facebook iOS no fue actualizado.',
|
|
354
361
|
'configure.facebookStringsMissing': 'android/.../strings.xml no encontrado — Facebook Android no fue actualizado.',
|
|
@@ -503,7 +510,13 @@ module.exports = {
|
|
|
503
510
|
'doctor.revenuecat.prefixMismatch': 'Clave con prefijo incorrecto: {key} debe empezar con {expected}',
|
|
504
511
|
'doctor.revenuecat.keysTest': 'Solo claves Test Store (test_) configuradas — los releases en la tienda requieren appl_/goog_, sino el app crashea',
|
|
505
512
|
'doctor.revenuecat.webhookUrlSupabase': 'URL del webhook (pega en RevenueCat → Integrations → Webhooks)',
|
|
506
|
-
'doctor.revenuecat.webhookUrlFirebase': 'URL del webhook: Firebase Console → Functions →
|
|
513
|
+
'doctor.revenuecat.webhookUrlFirebase': 'URL del webhook: Firebase Console → Functions → subscriptions-revenuecatWebhook',
|
|
514
|
+
'doctor.stripe.title': 'Stripe (Pagos en Web)',
|
|
515
|
+
'doctor.stripe.serverSide': 'Solo en el servidor — ninguna clave Stripe va en la app (Checkout alojado).',
|
|
516
|
+
'doctor.stripe.secretsFirebase': 'Define STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET con `kasy configure stripe`, luego `kasy deploy`.',
|
|
517
|
+
'doctor.stripe.secretsSupabase': 'Secrets con `supabase secrets set` (hecho en `kasy new` si se proporcionan).',
|
|
518
|
+
'doctor.stripe.secretsApi': 'Configura STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET en tu servidor (ver Stripe-Guia.md).',
|
|
519
|
+
'doctor.stripe.webhookUrl': 'URL del webhook Stripe (agrega en Stripe → Developers → Webhooks)',
|
|
507
520
|
|
|
508
521
|
'update.iosRelease.success': 'Archivos de release iOS actualizados',
|
|
509
522
|
'add.iosRelease.success': 'Archivos de release iOS agregados',
|
|
@@ -548,14 +561,15 @@ module.exports = {
|
|
|
548
561
|
'new.modules.header.feedback': '── Feedback (Firebase + Supabase) ──',
|
|
549
562
|
'new.modules.header.ci': '── CI/CD ──',
|
|
550
563
|
'new.modules.header.monetization': '── Monetizacion ──',
|
|
551
|
-
'new.firebase.module.revenuecat': '💰 RevenueCat (
|
|
564
|
+
'new.firebase.module.revenuecat': '💰 RevenueCat (suscripciones móvil)',
|
|
565
|
+
'new.firebase.module.stripe': '🌐 Stripe (suscripciones en web)',
|
|
552
566
|
'new.firebase.module.sentry': '🚨 Crash Reports (Sentry)',
|
|
553
567
|
'new.firebase.module.analytics': '📊 Analytics (Mixpanel)',
|
|
554
568
|
'new.firebase.module.facebook': '👤 Facebook (Login + Ads)',
|
|
555
569
|
'new.firebase.module.web': '🌐 Web Support (PWA)',
|
|
556
570
|
'new.firebase.module.widget': '📱 Home Widget (iOS/Android)',
|
|
557
|
-
'new.firebase.module.
|
|
558
|
-
'new.firebase.module.
|
|
571
|
+
'new.firebase.module.ai_chat': '🤖 AI Chat (OpenAI/Gemini)',
|
|
572
|
+
'new.firebase.module.local_reminders': '🔔 Local Reminders (sin servidor)',
|
|
559
573
|
'new.firebase.module.feedback': '💬 Feature Requests (requiere Firebase o Supabase)',
|
|
560
574
|
'new.firebase.module.ci': '⚙️ CI/CD (GitHub + Codemagic)',
|
|
561
575
|
'new.firebase.module.onboarding': '👋 Onboarding (flujo de bienvenida)',
|
|
@@ -579,10 +593,12 @@ module.exports = {
|
|
|
579
593
|
'new.firebase.q.revenuecat.ios': 'Clave API RevenueCat para iOS',
|
|
580
594
|
'new.firebase.q.paywall': '¿Qué estilo de paywall?',
|
|
581
595
|
'new.firebase.q.paywall.hint': 'Layout de la pantalla de suscripciones — puedes cambiarlo después en RevenueCat',
|
|
582
|
-
'new.firebase.q.
|
|
583
|
-
'new.firebase.q.
|
|
584
|
-
'new.firebase.q.
|
|
585
|
-
'new.firebase.
|
|
596
|
+
'new.firebase.q.stripe.secretKey': 'Stripe Secret Key (sk_test_… / sk_live_…) — opcional, configurar después',
|
|
597
|
+
'new.firebase.q.stripe.webhookSecret': 'Stripe Webhook Signing Secret (whsec_…) — opcional, configurar después',
|
|
598
|
+
'new.firebase.q.stripe.webhookSecret.hint': 'En Stripe → Developers → Webhooks → tu endpoint',
|
|
599
|
+
'new.firebase.q.stripe.webhookSecret.invalid': 'El signing secret del webhook debe empezar con whsec_.',
|
|
600
|
+
'new.firebase.q.stripe.productId': 'Stripe Product ID (prod_…) — opcional, limita el paywall a un producto',
|
|
601
|
+
'new.firebase.q.stripe.productId.hint': 'Deja en blanco para listar todos los precios recurrentes activos',
|
|
586
602
|
'new.firebase.q.sentry.dsn': 'DSN de Sentry (deja en blanco para configurar después)',
|
|
587
603
|
'new.firebase.q.sentry.dsn.invalid': 'DSN inválido. Formato esperado: https://clave@host/project-id',
|
|
588
604
|
'new.firebase.q.mixpanel.token': 'Token de Mixpanel (deja en blanco para configurar después)',
|
|
@@ -594,7 +610,6 @@ module.exports = {
|
|
|
594
610
|
'new.firebase.q.revenuecat.android.required': 'Clave Android de RevenueCat es obligatoria.',
|
|
595
611
|
'new.firebase.q.revenuecat.ios.required': 'Clave iOS de RevenueCat es obligatoria.',
|
|
596
612
|
'new.firebase.q.revenuecat.metaDataset.invalid': 'Pixel ID debe ser numérico (ej: 1234567890).',
|
|
597
|
-
'new.firebase.q.revenuecat.webKey.invalid': 'La clave Web Billing debe empezar con rcb_ (ej: rcb_sb_xxx o rcb_xxx).',
|
|
598
613
|
|
|
599
614
|
'new.firebase.confirm.title': 'Resumen de configuración:',
|
|
600
615
|
'new.firebase.confirm.app': 'App',
|
|
@@ -707,6 +722,8 @@ module.exports = {
|
|
|
707
722
|
'new.outdated.upgraded': '¡kasy actualizado! Ejecuta kasy new nuevamente.',
|
|
708
723
|
'new.success.title': '¡Proyecto creado con exito!',
|
|
709
724
|
'new.success.featuresInstalled': 'Recursos activados:',
|
|
725
|
+
'new.success.bundleId': 'Identificador de la app (bundle ID)',
|
|
726
|
+
'new.success.bundleId.hint': 'Identificador único de tu app en Android, iOS y Firebase (push).',
|
|
710
727
|
'new.success.nextSteps': 'Proximos pasos:',
|
|
711
728
|
'new.success.step.cd': 'Ve a la carpeta del proyecto:',
|
|
712
729
|
'new.success.step.deploy': 'Sube el servidor a Firebase (DB + funciones):',
|
|
@@ -914,7 +931,7 @@ module.exports = {
|
|
|
914
931
|
'notifications.error.notKasyProject': 'No se encontro kit_setup.json. Ejecuta dentro de un proyecto Kasy.',
|
|
915
932
|
'notifications.error.noI18n': 'lib/i18n/*.i18n.json no encontrado en este proyecto.',
|
|
916
933
|
'notifications.error.noFeatures': 'lib/core/config/features.dart no encontrado.',
|
|
917
|
-
'notifications.error.notEnabled': 'Notificaciones locales desactivadas. Ejecuta: kasy add
|
|
934
|
+
'notifications.error.notEnabled': 'Notificaciones locales desactivadas. Ejecuta: kasy add local_reminders',
|
|
918
935
|
'notifications.error.cancelled': 'Cancelado.',
|
|
919
936
|
'notifications.prompt.intro': 'Textos de notificación local',
|
|
920
937
|
'notifications.prompt.hint': 'Demo Home = prueba instantanea en Features. Recordatorio = alerta programada en Ajustes.',
|
|
@@ -957,26 +974,26 @@ module.exports = {
|
|
|
957
974
|
// Legacy keys — kept for compatibility with old scripts.
|
|
958
975
|
'add.prompt.rcAndroidKey': 'RevenueCat Android API key (deja en blanco para configurar después):',
|
|
959
976
|
'add.prompt.rcIosKey': 'RevenueCat iOS API key (deja en blanco para configurar después):',
|
|
960
|
-
'add.note.facebook': 'Agrega tu Facebook App ID y token en .vscode/launch.json (FB_APP_ID,
|
|
961
|
-
'new.q.
|
|
962
|
-
'new.q.
|
|
963
|
-
'add.
|
|
964
|
-
'add.prompt.
|
|
965
|
-
'add.prompt.
|
|
966
|
-
'add.prompt.
|
|
967
|
-
'add.prompt.
|
|
968
|
-
'add.
|
|
969
|
-
'add.
|
|
970
|
-
'add.
|
|
971
|
-
'add.
|
|
972
|
-
'add.
|
|
973
|
-
'add.
|
|
974
|
-
'add.
|
|
975
|
-
'add.
|
|
976
|
-
'add.
|
|
977
|
-
'add.
|
|
978
|
-
'add.
|
|
979
|
-
'add.
|
|
977
|
+
'add.note.facebook': 'Agrega tu Facebook App ID y token en .vscode/launch.json (FB_APP_ID, FB_CLIENT_TOKEN).',
|
|
978
|
+
'new.q.ai_chat.configureNow': 'Configurar el agente de Chat IA ahora?',
|
|
979
|
+
'new.q.ai_chat.configureNow.hint': 'Puedes omitir y ejecutar "kasy add ai_chat" después',
|
|
980
|
+
'add.ai_chat.reconfigure': 'Feature ya activa — reconfigurando solo las credenciales.',
|
|
981
|
+
'add.prompt.aiProvider': 'Proveedor de IA:',
|
|
982
|
+
'add.prompt.aiSystemPrompt': 'Instruccion del agente — system prompt (deja en blanco para ninguna):\n Ejemplo: "Eres un asistente de soporte del app Fitsync. Solo responde sobre entrenamientos."\n >',
|
|
983
|
+
'add.prompt.aiApiKey': 'Clave de API (OpenAI o Gemini) — se guarda en el servidor, nunca en el app (deja en blanco para configurar después):',
|
|
984
|
+
'add.prompt.aiEndpoint': 'URL de tu endpoint IA (deja en blanco para configurar después):',
|
|
985
|
+
'add.ai_chat.settingSecret': 'Guardando clave de API como secret en el servidor...',
|
|
986
|
+
'add.ai_chat.secretSet': 'Clave de API guardada como secret',
|
|
987
|
+
'add.ai_chat.secretFailed': 'No se pudo guardar el secret automaticamente — configuralo manualmente (ver instrucciones abajo)',
|
|
988
|
+
'add.ai_chat.skipSecret': 'Clave de API omitida — configura antes del deploy via CLI del servidor',
|
|
989
|
+
'add.ai_chat.deploying': 'Desplegando funcion IA en el servidor...',
|
|
990
|
+
'add.ai_chat.deployed': 'Funcion IA desplegada con exito',
|
|
991
|
+
'add.ai_chat.deployFailed': 'Deploy automático fallo — despliega manualmente (ver instrucciones abajo)',
|
|
992
|
+
'add.ai_chat.nextSteps.firebase': '\n Proximos pasos:\n 1. El AI_CHAT_ENDPOINT en .vscode/launch.json ya fue pre-llenado.\n 2. Corre el app: kasy run\n',
|
|
993
|
+
'add.ai_chat.nextSteps.firebase.deployFailed': '\n Proximos pasos:\n 1. Deploy manual: firebase deploy --only functions:aiChat\n 2. El AI_CHAT_ENDPOINT en .vscode/launch.json ya fue pre-llenado.\n 3. Corre el app: kasy run\n',
|
|
994
|
+
'add.ai_chat.nextSteps.supabase': '\n Proximos pasos:\n 1. El AI_CHAT_ENDPOINT en .vscode/launch.json ya fue pre-llenado.\n 2. Corre el app: kasy run\n',
|
|
995
|
+
'add.ai_chat.nextSteps.supabase.deployFailed': '\n Proximos pasos:\n 1. Deploy manual: supabase functions deploy ai-chat --no-verify-jwt\n 2. El AI_CHAT_ENDPOINT en .vscode/launch.json ya fue pre-llenado.\n 3. Corre el app: kasy run\n',
|
|
996
|
+
'add.ai_chat.nextSteps.api': '\n Proximos pasos:\n 1. Crea un endpoint en tu servidor que acepte {message, history} y llame tu IA.\n 2. Actualiza AI_CHAT_ENDPOINT en .vscode/launch.json con la URL de tu endpoint.\n 3. Corre el app: kasy run\n',
|
|
980
997
|
'cli.command.remove.description': 'Elimina algo que ya no usas (ej: kasy remove sentry)',
|
|
981
998
|
'remove.error.noModule': 'Ingresa el nombre de la feature. Uso: kasy remove <feature>',
|
|
982
999
|
'remove.error.notKasyProject': 'kit_setup.json no encontrado. Ejecuta este comando dentro de un proyecto Kasy.',
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Kasy CLI i18n messages —
|
|
4
|
+
* Kasy CLI i18n messages — Portuguese.
|
|
5
5
|
*
|
|
6
6
|
* One entry per user-facing string. Keys are dotted paths describing
|
|
7
7
|
* where the string is used (cli.help.*, run.*, ios.*, etc.).
|
|
@@ -43,7 +43,7 @@ module.exports = {
|
|
|
43
43
|
'cli.command.setup.langName': 'idioma',
|
|
44
44
|
'cli.command.setup.langOption': 'Idioma dos prompts (en, pt, es)',
|
|
45
45
|
'cli.command.setup.backendOption': 'Adapter de backend (firebase, supabase, api)',
|
|
46
|
-
'cli.command.setup.featuresOption': 'Features opcionais separadas por virgula (web,widget,
|
|
46
|
+
'cli.command.setup.featuresOption': 'Features opcionais separadas por virgula (web,widget,ai_chat,revenuecat,ci)',
|
|
47
47
|
'cli.command.help.paramName': 'comando',
|
|
48
48
|
'cli.command.doctor.description': 'Verifica se o seu computador está pronto para rodar a Kasy',
|
|
49
49
|
'cli.command.modules.description': 'Mostra o que já vem incluso e o que você pode adicionar',
|
|
@@ -109,15 +109,15 @@ module.exports = {
|
|
|
109
109
|
'modules.backend.supabase.description': 'Adapter de backend Supabase',
|
|
110
110
|
'modules.backend.api.description': 'Adapter de backend API REST/GraphQL',
|
|
111
111
|
'modules.feature.sentry.description': 'Rastreamento de erros e crashes com Sentry',
|
|
112
|
-
'modules.feature.analytics.description': 'Rastreamento de eventos de analytics (
|
|
112
|
+
'modules.feature.analytics.description': 'Rastreamento de eventos de analytics (Mixpanel)',
|
|
113
113
|
'modules.feature.facebook.description': 'Login do Facebook e rastreamento de eventos Meta Ads (vem sempre junto)',
|
|
114
114
|
'modules.feature.revenuecat.description': 'Habilita pagamentos reais na tela de Subscriptions',
|
|
115
115
|
'modules.feature.onboarding.description': 'Fluxo de boas-vindas mostrado no primeiro acesso',
|
|
116
116
|
'modules.feature.web.description': 'Suporte Web/PWA',
|
|
117
117
|
'modules.feature.widget.description': 'Widget de tela inicial iOS/Android',
|
|
118
|
-
'modules.feature.
|
|
118
|
+
'modules.feature.ai_chat.description': 'Tela de chat com IA usando OpenAI ou Gemini',
|
|
119
119
|
'modules.feature.feedback.description': 'Pedidos e votacao de features dentro do app',
|
|
120
|
-
'modules.feature.
|
|
120
|
+
'modules.feature.local_reminders.description': 'Lembretes locais agendados pelo usuario (sem servidor)',
|
|
121
121
|
'modules.feature.ci.description': 'CI/CD: GitHub/GitLab (testes + build) + Codemagic (publicação nas lojas)',
|
|
122
122
|
'checks.checking': 'Verificando {name}...',
|
|
123
123
|
'checks.found': '{name} encontrado',
|
|
@@ -134,6 +134,8 @@ module.exports = {
|
|
|
134
134
|
'checks.thenRun': 'Depois rode',
|
|
135
135
|
'checks.recheck': 'Após instalar {name}, pressione Enter para verificar novamente',
|
|
136
136
|
'checks.install.confirm': 'Instalar {name} agora? ({cmd})',
|
|
137
|
+
'checks.install.flutterWinDesc': 'baixa o SDK oficial do Flutter + Git, ~1,8 GB',
|
|
138
|
+
'checks.install.flutterWinNote': 'Pode levar alguns minutos (download grande). Se aparecer um popup do Windows pedindo permissão, clique em Sim.',
|
|
137
139
|
'checks.install.running': 'Instalando {name}…',
|
|
138
140
|
'checks.install.failedManual': 'Não consegui instalar {name} automaticamente. Faça manualmente:',
|
|
139
141
|
'checks.install.openDocs': 'Abrir a página de instalação no navegador?',
|
|
@@ -268,6 +270,9 @@ module.exports = {
|
|
|
268
270
|
'new.supabase.created': 'Projeto criado com sucesso.',
|
|
269
271
|
'new.supabase.createFailed': 'Não foi possível criar o projeto',
|
|
270
272
|
'new.supabase.loginHint': 'Execute: supabase login. Depois informe a URL e chave do seu projeto existente.',
|
|
273
|
+
'new.supabase.createFailed.freeLimit': 'Seu plano grátis do Supabase atingiu o limite de projetos nesta organização.',
|
|
274
|
+
'new.supabase.freeLimit.title': 'Como liberar',
|
|
275
|
+
'new.supabase.freeLimit.options': '• Apague um projeto que você não usa mais\n• Escolha outra organização (se você tiver mais de uma)\n• Ou faça upgrade do plano no painel do Supabase\nDepois rode o kasy new de novo.',
|
|
271
276
|
'new.supabase.setup': 'Vinculando projeto e publicando…',
|
|
272
277
|
'new.supabase.setupManual': 'Execute manualmente: supabase link, supabase db push, supabase functions deploy',
|
|
273
278
|
'new.supabase.passwordSaved': 'Senha do banco gerada automaticamente e salva em .kasy/supabase.json (gitignorado).',
|
|
@@ -301,7 +306,7 @@ module.exports = {
|
|
|
301
306
|
'validate.fail': 'falhou',
|
|
302
307
|
'validate.passed': 'aprovado',
|
|
303
308
|
|
|
304
|
-
// ──
|
|
309
|
+
// ── Firebase flow ────────────────────────────────────────────────────
|
|
305
310
|
'cli.command.firebase.description': '🔥 Criar app Flutter completo com Firebase (recomendado)',
|
|
306
311
|
'new.banner': '✨ Novo app Flutter',
|
|
307
312
|
'new.subtitle': 'Escolha o backend: Firebase, Supabase ou API REST.',
|
|
@@ -345,8 +350,10 @@ module.exports = {
|
|
|
345
350
|
'configure.section.sentry': 'Sentry (Crash Reports)',
|
|
346
351
|
'configure.section.mixpanel': 'Mixpanel (Analytics)',
|
|
347
352
|
'configure.section.revenuecat': 'RevenueCat (Assinaturas)',
|
|
353
|
+
'configure.section.stripe': 'Stripe (Pagamentos na Web)',
|
|
354
|
+
'configure.stripe.apiNote': 'Backend API: configure STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET no seu próprio servidor (veja Stripe-Guia.md). A CLI não tem onde guardar.',
|
|
348
355
|
'configure.section.facebook': 'Facebook (Login + Ads)',
|
|
349
|
-
'configure.section.
|
|
356
|
+
'configure.section.aiChat': 'AI Chat',
|
|
350
357
|
'configure.savedFacebook': 'Credenciais do Facebook gravadas em Info.plist e strings.xml.',
|
|
351
358
|
'configure.facebookPlistMissing': 'ios/Runner/Info.plist não encontrado — Facebook iOS não foi atualizado.',
|
|
352
359
|
'configure.facebookStringsMissing': 'android/.../strings.xml não encontrado — Facebook Android não foi atualizado.',
|
|
@@ -501,7 +508,13 @@ module.exports = {
|
|
|
501
508
|
'doctor.revenuecat.prefixMismatch': 'Chave com prefixo errado: {key} deveria começar com {expected}',
|
|
502
509
|
'doctor.revenuecat.keysTest': 'Apenas chaves Test Store (test_) configuradas — releases na loja exigem appl_/goog_, senão o app crasha',
|
|
503
510
|
'doctor.revenuecat.webhookUrlSupabase': 'URL do webhook (cole no RevenueCat → Integrations → Webhooks)',
|
|
504
|
-
'doctor.revenuecat.webhookUrlFirebase': 'URL do webhook: Firebase Console → Functions →
|
|
511
|
+
'doctor.revenuecat.webhookUrlFirebase': 'URL do webhook: Firebase Console → Functions → subscriptions-revenuecatWebhook',
|
|
512
|
+
'doctor.stripe.title': 'Stripe (Pagamentos na Web)',
|
|
513
|
+
'doctor.stripe.serverSide': 'Só no servidor — nenhuma chave Stripe vai no app (Checkout hospedado).',
|
|
514
|
+
'doctor.stripe.secretsFirebase': 'Defina STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET com `kasy configure stripe`, depois `kasy deploy`.',
|
|
515
|
+
'doctor.stripe.secretsSupabase': 'Secrets via `supabase secrets set` (feito no `kasy new` se informadas).',
|
|
516
|
+
'doctor.stripe.secretsApi': 'Configure STRIPE_SECRET_KEY + STRIPE_WEBHOOK_SECRET no seu servidor (veja Stripe-Guia.md).',
|
|
517
|
+
'doctor.stripe.webhookUrl': 'URL do webhook Stripe (adicione em Stripe → Developers → Webhooks)',
|
|
505
518
|
|
|
506
519
|
'update.iosRelease.success': 'Arquivos de release iOS atualizados',
|
|
507
520
|
'add.iosRelease.success': 'Arquivos de release iOS adicionados',
|
|
@@ -548,14 +561,15 @@ module.exports = {
|
|
|
548
561
|
'new.modules.header.feedback': '── Feedback (Firebase + Supabase) ──',
|
|
549
562
|
'new.modules.header.ci': '── CI/CD ──',
|
|
550
563
|
'new.modules.header.monetization': '── Monetizacao ──',
|
|
551
|
-
'new.firebase.module.revenuecat': '💰 RevenueCat (
|
|
564
|
+
'new.firebase.module.revenuecat': '💰 RevenueCat (assinaturas mobile)',
|
|
565
|
+
'new.firebase.module.stripe': '🌐 Stripe (assinaturas na web)',
|
|
552
566
|
'new.firebase.module.sentry': '🚨 Crash Reports (Sentry)',
|
|
553
567
|
'new.firebase.module.analytics': '📊 Analytics (Mixpanel)',
|
|
554
568
|
'new.firebase.module.facebook': '👤 Facebook (Login + Ads)',
|
|
555
569
|
'new.firebase.module.web': '🌐 Web Support (PWA)',
|
|
556
570
|
'new.firebase.module.widget': '📱 Home Widget (iOS/Android)',
|
|
557
|
-
'new.firebase.module.
|
|
558
|
-
'new.firebase.module.
|
|
571
|
+
'new.firebase.module.ai_chat': '🤖 AI Chat (OpenAI/Gemini)',
|
|
572
|
+
'new.firebase.module.local_reminders': '🔔 Local Reminders (sem servidor)',
|
|
559
573
|
'new.firebase.module.feedback': '💬 Feature Requests (requer Firebase ou Supabase)',
|
|
560
574
|
'new.firebase.module.ci': '⚙️ CI/CD (GitHub + Codemagic)',
|
|
561
575
|
'new.firebase.module.onboarding': '👋 Onboarding (fluxo de boas-vindas)',
|
|
@@ -579,10 +593,12 @@ module.exports = {
|
|
|
579
593
|
'new.firebase.q.revenuecat.ios': 'Chave de API RevenueCat para iOS',
|
|
580
594
|
'new.firebase.q.paywall': 'Qual estilo de paywall?',
|
|
581
595
|
'new.firebase.q.paywall.hint': 'Layout da tela de assinaturas — pode alterar depois no RevenueCat',
|
|
582
|
-
'new.firebase.q.
|
|
583
|
-
'new.firebase.q.
|
|
584
|
-
'new.firebase.q.
|
|
585
|
-
'new.firebase.
|
|
596
|
+
'new.firebase.q.stripe.secretKey': 'Stripe Secret Key (sk_test_… / sk_live_…) — opcional, configure depois',
|
|
597
|
+
'new.firebase.q.stripe.webhookSecret': 'Stripe Webhook Signing Secret (whsec_…) — opcional, configure depois',
|
|
598
|
+
'new.firebase.q.stripe.webhookSecret.hint': 'Em Stripe → Developers → Webhooks → seu endpoint',
|
|
599
|
+
'new.firebase.q.stripe.webhookSecret.invalid': 'O signing secret do webhook deve começar com whsec_.',
|
|
600
|
+
'new.firebase.q.stripe.productId': 'Stripe Product ID (prod_…) — opcional, limita o paywall a um produto',
|
|
601
|
+
'new.firebase.q.stripe.productId.hint': 'Deixe em branco para listar todos os preços recorrentes ativos',
|
|
586
602
|
'new.firebase.q.sentry.dsn': 'DSN do Sentry (deixe em branco para configurar depois)',
|
|
587
603
|
'new.firebase.q.sentry.dsn.invalid': 'DSN inválido. Formato esperado: https://chave@host/project-id',
|
|
588
604
|
'new.firebase.q.mixpanel.token': 'Token do Mixpanel (deixe em branco para configurar depois)',
|
|
@@ -594,7 +610,6 @@ module.exports = {
|
|
|
594
610
|
'new.firebase.q.revenuecat.android.required': 'Chave Android do RevenueCat é obrigatória.',
|
|
595
611
|
'new.firebase.q.revenuecat.ios.required': 'Chave iOS do RevenueCat é obrigatória.',
|
|
596
612
|
'new.firebase.q.revenuecat.metaDataset.invalid': 'Pixel ID deve ser numerico (ex: 1234567890).',
|
|
597
|
-
'new.firebase.q.revenuecat.webKey.invalid': 'Chave Web Billing deve começar com rcb_ (ex: rcb_sb_xxx ou rcb_xxx).',
|
|
598
613
|
|
|
599
614
|
'new.firebase.confirm.title': 'Resumo da configuração:',
|
|
600
615
|
'new.firebase.confirm.app': 'App',
|
|
@@ -707,6 +722,8 @@ module.exports = {
|
|
|
707
722
|
'new.outdated.upgraded': 'kasy atualizado! Rode kasy new novamente.',
|
|
708
723
|
'new.success.title': 'Projeto criado com sucesso!',
|
|
709
724
|
'new.success.featuresInstalled': 'Recursos ativados:',
|
|
725
|
+
'new.success.bundleId': 'Identificador do app (bundle ID)',
|
|
726
|
+
'new.success.bundleId.hint': 'Identificador único do seu app no Android, iOS e Firebase (push).',
|
|
710
727
|
'new.success.nextSteps': 'Proximos passos:',
|
|
711
728
|
'new.success.step.cd': 'Entre na pasta do projeto:',
|
|
712
729
|
'new.success.step.deploy': 'Suba o servidor pro Firebase (banco + funções):',
|
|
@@ -914,7 +931,7 @@ module.exports = {
|
|
|
914
931
|
'notifications.error.notKasyProject': 'kit_setup.json não encontrado. Execute dentro de um projeto Kasy.',
|
|
915
932
|
'notifications.error.noI18n': 'lib/i18n/*.i18n.json não encontrado neste projeto.',
|
|
916
933
|
'notifications.error.noFeatures': 'lib/core/config/features.dart não encontrado.',
|
|
917
|
-
'notifications.error.notEnabled': 'Notificações locais desativadas. Execute: kasy add
|
|
934
|
+
'notifications.error.notEnabled': 'Notificações locais desativadas. Execute: kasy add local_reminders',
|
|
918
935
|
'notifications.error.cancelled': 'Cancelado.',
|
|
919
936
|
'notifications.prompt.intro': 'Textos de notificação local',
|
|
920
937
|
'notifications.prompt.hint': 'Demo Home = teste instantâneo em Features. Lembrete = alerta agendado em Configurações.',
|
|
@@ -957,26 +974,26 @@ module.exports = {
|
|
|
957
974
|
// Legacy keys — kept for compatibility with old scripts.
|
|
958
975
|
'add.prompt.rcAndroidKey': 'RevenueCat Android API key (deixe em branco para configurar depois):',
|
|
959
976
|
'add.prompt.rcIosKey': 'RevenueCat iOS API key (deixe em branco para configurar depois):',
|
|
960
|
-
'add.note.facebook': 'Adicione seu Facebook App ID e token no .vscode/launch.json (FB_APP_ID,
|
|
961
|
-
'new.q.
|
|
962
|
-
'new.q.
|
|
963
|
-
'add.
|
|
964
|
-
'add.prompt.
|
|
965
|
-
'add.prompt.
|
|
966
|
-
'add.prompt.
|
|
967
|
-
'add.prompt.
|
|
968
|
-
'add.
|
|
969
|
-
'add.
|
|
970
|
-
'add.
|
|
971
|
-
'add.
|
|
972
|
-
'add.
|
|
973
|
-
'add.
|
|
974
|
-
'add.
|
|
975
|
-
'add.
|
|
976
|
-
'add.
|
|
977
|
-
'add.
|
|
978
|
-
'add.
|
|
979
|
-
'add.
|
|
977
|
+
'add.note.facebook': 'Adicione seu Facebook App ID e token no .vscode/launch.json (FB_APP_ID, FB_CLIENT_TOKEN).',
|
|
978
|
+
'new.q.ai_chat.configureNow': 'Configurar o agente de Chat IA agora?',
|
|
979
|
+
'new.q.ai_chat.configureNow.hint': 'Pode pular e executar "kasy add ai_chat" depois',
|
|
980
|
+
'add.ai_chat.reconfigure': 'Feature já ativa — reconfigurando apenas as credenciais.',
|
|
981
|
+
'add.prompt.aiProvider': 'Provedor de IA:',
|
|
982
|
+
'add.prompt.aiSystemPrompt': 'Instrução do agente — system prompt (deixe em branco para nenhuma):\n Exemplo: "Você e um assistente de suporte do app Fitsync. Responda apenas sobre treinos."\n >',
|
|
983
|
+
'add.prompt.aiApiKey': 'Chave de API (OpenAI ou Gemini) — fica no servidor, nunca no app (deixe em branco para configurar depois):',
|
|
984
|
+
'add.prompt.aiEndpoint': 'URL do seu endpoint IA (deixe em branco para configurar depois):',
|
|
985
|
+
'add.ai_chat.settingSecret': 'Salvando chave de API como secret no servidor...',
|
|
986
|
+
'add.ai_chat.secretSet': 'Chave de API salva como secret',
|
|
987
|
+
'add.ai_chat.secretFailed': 'Não foi possível salvar o secret automaticamente — configure manualmente (veja instruções abaixo)',
|
|
988
|
+
'add.ai_chat.skipSecret': 'Chave de API ignorada — configure antes do deploy via CLI do servidor',
|
|
989
|
+
'add.ai_chat.deploying': 'Fazendo deploy da função IA no servidor...',
|
|
990
|
+
'add.ai_chat.deployed': 'Função IA deployada com sucesso',
|
|
991
|
+
'add.ai_chat.deployFailed': 'Deploy automático falhou — faca o deploy manualmente (veja instruções abaixo)',
|
|
992
|
+
'add.ai_chat.nextSteps.firebase': '\n Proximos passos:\n 1. O AI_CHAT_ENDPOINT no .vscode/launch.json já foi preenchido.\n 2. Rode o app: kasy run\n',
|
|
993
|
+
'add.ai_chat.nextSteps.firebase.deployFailed': '\n Proximos passos:\n 1. Deploy manual: firebase deploy --only functions:aiChat\n 2. O AI_CHAT_ENDPOINT no .vscode/launch.json já foi preenchido.\n 3. Rode o app: kasy run\n',
|
|
994
|
+
'add.ai_chat.nextSteps.supabase': '\n Proximos passos:\n 1. O AI_CHAT_ENDPOINT no .vscode/launch.json já foi preenchido.\n 2. Rode o app: kasy run\n',
|
|
995
|
+
'add.ai_chat.nextSteps.supabase.deployFailed': '\n Proximos passos:\n 1. Deploy manual: supabase functions deploy ai-chat --no-verify-jwt\n 2. O AI_CHAT_ENDPOINT no .vscode/launch.json já foi preenchido.\n 3. Rode o app: kasy run\n',
|
|
996
|
+
'add.ai_chat.nextSteps.api': '\n Proximos passos:\n 1. Crie um endpoint no seu servidor que aceite {message, history} e chame sua IA.\n 2. Atualize AI_CHAT_ENDPOINT no .vscode/launch.json com a URL do seu endpoint.\n 3. Rode o app: kasy run\n',
|
|
980
997
|
'cli.command.remove.description': 'Remove algo que você não usa mais (ex: kasy remove sentry)',
|
|
981
998
|
'remove.error.noModule': 'Informe o nome da feature. Uso: kasy remove <feature>',
|
|
982
999
|
'remove.error.notKasyProject': 'kit_setup.json não encontrado. Execute este comando dentro de um projeto Kasy.',
|
package/lib/utils/updates.js
CHANGED
|
@@ -8,9 +8,9 @@ const pkg = require('../../package.json');
|
|
|
8
8
|
const ui = require('./ui');
|
|
9
9
|
const { CONFIG_PATH } = require('./license');
|
|
10
10
|
|
|
11
|
-
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24
|
|
11
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
12
12
|
|
|
13
|
-
// ──
|
|
13
|
+
// ── Config helpers ────────────────────────────────────────────────────────
|
|
14
14
|
|
|
15
15
|
function readConfig() {
|
|
16
16
|
if (!existsSync(CONFIG_PATH)) return {};
|
|
@@ -22,7 +22,7 @@ function writeConfig(config) {
|
|
|
22
22
|
writeJsonSync(CONFIG_PATH, config, { spaces: 2 });
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
// ──
|
|
25
|
+
// ── Minimal semver comparison (no external deps) ─────────────────────────────
|
|
26
26
|
|
|
27
27
|
function isNewer(remote, local) {
|
|
28
28
|
const parse = (v) => String(v).replace(/^v/, '').split('.').map(Number);
|
|
@@ -33,7 +33,7 @@ function isNewer(remote, local) {
|
|
|
33
33
|
return rPat > lPat;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
// ──
|
|
36
|
+
// ── Async fetch (fires in the background) ─────────────────────────────────
|
|
37
37
|
|
|
38
38
|
function fetchLatestVersion() {
|
|
39
39
|
return new Promise((resolve) => {
|
|
@@ -54,19 +54,19 @@ function fetchLatestVersion() {
|
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
// ──
|
|
57
|
+
// ── Main function ─────────────────────────────────────────────────────────
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
60
|
+
* Shows an update notice (based on the last-check cache — zero latency).
|
|
61
|
+
* Triggers a background cache refresh if 24h have passed.
|
|
62
|
+
* Never throws — fails silently in any scenario.
|
|
63
63
|
*/
|
|
64
64
|
async function checkForUpdates() {
|
|
65
65
|
try {
|
|
66
66
|
const config = readConfig();
|
|
67
67
|
const cache = config.updateCheck || {};
|
|
68
68
|
|
|
69
|
-
//
|
|
69
|
+
// Show a notice based on the cache — does not wait for the network
|
|
70
70
|
if (cache.latestVersion && isNewer(cache.latestVersion, pkg.version)) {
|
|
71
71
|
console.log(
|
|
72
72
|
'\n' +
|
|
@@ -79,7 +79,7 @@ async function checkForUpdates() {
|
|
|
79
79
|
);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
//
|
|
82
|
+
// Refresh the cache in the background every 24h — does not block the CLI
|
|
83
83
|
const now = Date.now();
|
|
84
84
|
if (!cache.checkedAt || now - cache.checkedAt > CHECK_INTERVAL_MS) {
|
|
85
85
|
fetchLatestVersion()
|
|
@@ -91,14 +91,14 @@ async function checkForUpdates() {
|
|
|
91
91
|
.catch(() => {});
|
|
92
92
|
}
|
|
93
93
|
} catch {
|
|
94
|
-
//
|
|
94
|
+
// Never block the CLI because of an update check
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
99
|
+
* Called before kasy new. If there is a newer version in the cache,
|
|
100
|
+
* shows a notice and asks whether to continue or exit to update.
|
|
101
|
+
* Never blocks — if the user ignores it, the flow continues normally.
|
|
102
102
|
*/
|
|
103
103
|
async function warnIfOutdatedBeforeNew(t) {
|
|
104
104
|
try {
|
|
@@ -128,7 +128,7 @@ async function warnIfOutdatedBeforeNew(t) {
|
|
|
128
128
|
process.exit(result.status ?? 0);
|
|
129
129
|
}
|
|
130
130
|
} catch {
|
|
131
|
-
//
|
|
131
|
+
// Never block kasy new because of the version notice
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
package/package.json
CHANGED
|
@@ -6,8 +6,8 @@ ENV=dev
|
|
|
6
6
|
# Firebase Cloud Functions (região + project id do seu projeto)
|
|
7
7
|
BACKEND_URL=https://europe-west1-YOUR_PROJECT_ID.cloudfunctions.net
|
|
8
8
|
|
|
9
|
-
#
|
|
10
|
-
|
|
9
|
+
# AI Chat — proxy Cloud Function (AI_API_KEY fica no Firebase Secret)
|
|
10
|
+
AI_CHAT_ENDPOINT=https://europe-west1-YOUR_PROJECT_ID.cloudfunctions.net/aiChat
|
|
11
11
|
|
|
12
12
|
# RevenueCat
|
|
13
13
|
RC_ANDROID_API_KEY=YOUR_REVENUECAT_ANDROID_KEY
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<item name="android:windowFullscreen">true</item>
|
|
7
7
|
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
|
8
8
|
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
|
9
|
-
<item name="android:windowSplashScreenBackground">#
|
|
9
|
+
<item name="android:windowSplashScreenBackground">#0C0A14</item>
|
|
10
10
|
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
|
|
11
11
|
</style>
|
|
12
12
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<item name="android:windowFullscreen">true</item>
|
|
7
7
|
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
|
|
8
8
|
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
|
|
9
|
-
<item name="android:windowSplashScreenBackground">#
|
|
9
|
+
<item name="android:windowSplashScreenBackground">#FAF9FC</item>
|
|
10
10
|
<item name="android:windowSplashScreenAnimatedIcon">@drawable/android12splash</item>
|
|
11
11
|
</style>
|
|
12
12
|
<!-- Theme applied to the Android Window as soon as the process has started.
|
|
Binary file
|
|
Binary file
|
|
@@ -88,7 +88,7 @@ Encuentra la URL de la función:
|
|
|
88
88
|
| Backend | Dónde encontrar la URL |
|
|
89
89
|
|---------|------------------------|
|
|
90
90
|
| **Supabase** | `https://TU_PROJECT_REF.supabase.co/functions/v1/revenuecat-webhook` |
|
|
91
|
-
| **Firebase** | [Firebase Console → Functions](https://console.firebase.google.com/project/_/functions) → `
|
|
91
|
+
| **Firebase** | [Firebase Console → Functions](https://console.firebase.google.com/project/_/functions) → `subscriptions-revenuecatWebhook` → copia la URL |
|
|
92
92
|
|
|
93
93
|
Regístrala en RevenueCat:
|
|
94
94
|
|
|
@@ -88,7 +88,7 @@ Encontre a URL da função:
|
|
|
88
88
|
| Backend | Onde encontrar a URL |
|
|
89
89
|
|---------|---------------------|
|
|
90
90
|
| **Supabase** | `https://SEU_PROJECT_REF.supabase.co/functions/v1/revenuecat-webhook` |
|
|
91
|
-
| **Firebase** | [Firebase Console → Functions](https://console.firebase.google.com/project/_/functions) → `
|
|
91
|
+
| **Firebase** | [Firebase Console → Functions](https://console.firebase.google.com/project/_/functions) → `subscriptions-revenuecatWebhook` → copie a URL |
|
|
92
92
|
|
|
93
93
|
Registre no RevenueCat:
|
|
94
94
|
|