kasy-cli 1.20.0 → 1.20.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 (52) hide show
  1. package/README.md +11 -3
  2. package/lib/commands/new.js +78 -37
  3. package/lib/commands/run.js +7 -0
  4. package/lib/scaffold/backends/api/patch/lib/core/data/api/meta_ads_api.dart +1 -1
  5. package/lib/scaffold/backends/api/patch/lib/core/data/api/storage_api.dart +1 -1
  6. package/lib/scaffold/backends/api/patch/lib/core/data/entities/user_entity.dart +1 -1
  7. package/lib/scaffold/backends/api/patch/lib/features/authentication/api/authentication_api.dart +4 -5
  8. package/lib/scaffold/backends/api/patch/lib/features/feedbacks/api/feature_request_api.dart +1 -1
  9. package/lib/scaffold/backends/api/patch/lib/features/feedbacks/api/feature_vote_api.dart +1 -1
  10. package/lib/scaffold/backends/api/patch/lib/features/llm_chat/api/llm_chat_api.dart +1 -1
  11. package/lib/scaffold/backends/api/patch/lib/features/llm_chat/providers/llm_chat_notifier.dart +317 -0
  12. package/lib/scaffold/backends/api/patch/lib/features/notifications/api/device_api.dart +40 -1
  13. package/lib/scaffold/backends/api/patch/lib/features/notifications/api/entities/notifications_entity.dart +2 -0
  14. package/lib/scaffold/backends/api/patch/lib/features/onboarding/api/entities/user_info_entity.dart +1 -1
  15. package/lib/scaffold/backends/api/patch/lib/features/subscription/api/entities/subscription_entity.dart +1 -1
  16. package/lib/scaffold/backends/api/patch/lib/features/subscription/shared/maybeshow_premium.dart +0 -2
  17. package/lib/scaffold/backends/api/pubspec.yaml.tpl +2 -0
  18. package/lib/scaffold/backends/firebase/enable-auth-via-cli.js +11 -8
  19. package/lib/scaffold/backends/supabase/deploy.js +56 -3
  20. package/lib/scaffold/backends/supabase/patch/lib/core/data/api/storage_api.dart +5 -11
  21. package/lib/scaffold/backends/supabase/patch/lib/core/data/entities/user_entity.dart +2 -2
  22. package/lib/scaffold/backends/supabase/patch/lib/features/notifications/api/device_api.dart +31 -1
  23. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/api/entities/user_info_entity.dart +1 -1
  24. package/lib/scaffold/backends/supabase/patch/lib/features/subscription/api/entities/subscription_entity.dart +1 -1
  25. package/lib/scaffold/backends/supabase/pubspec.yaml.tpl +2 -0
  26. package/lib/scaffold/catalog.js +2 -2
  27. package/lib/scaffold/generate.js +19 -3
  28. package/lib/scaffold/shared/generator-utils.js +265 -55
  29. package/lib/scaffold/shared/post-build.js +11 -0
  30. package/lib/utils/i18n/messages-en.js +5 -1
  31. package/lib/utils/i18n/messages-es.js +5 -1
  32. package/lib/utils/i18n/messages-pt.js +5 -1
  33. package/package.json +1 -1
  34. package/templates/firebase/lib/components/kasy_sidebar_pro.dart +3 -1
  35. package/templates/firebase/lib/core/bottom_menu/bottom_menu.dart +38 -128
  36. package/templates/firebase/lib/core/bottom_menu/bottom_router.dart +6 -125
  37. package/templates/firebase/lib/core/states/user_state_notifier.dart +8 -10
  38. package/templates/firebase/lib/features/home/home_components_page.dart +8 -14
  39. package/templates/firebase/lib/features/home/home_page.dart +7 -8
  40. package/templates/firebase/lib/router.dart +60 -0
  41. package/templates/firebase/test/core/bottom_menu/detail_route_menu_test.dart +57 -0
  42. package/lib/scaffold/backends/api/patch/lib/core/rating/widgets/review_popup.dart +0 -211
  43. package/lib/scaffold/backends/api/patch/lib/features/notifications/providers/models/notification.dart +0 -185
  44. package/lib/scaffold/backends/api/patch/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +0 -73
  45. package/lib/scaffold/backends/api/patch/lib/main.dart +0 -275
  46. package/lib/scaffold/backends/api/patch/lib/router.dart +0 -133
  47. package/lib/scaffold/backends/supabase/patch/lib/core/rating/widgets/review_popup.dart +0 -211
  48. package/lib/scaffold/backends/supabase/patch/lib/features/feedbacks/ui/component/add_feature_form.dart +0 -199
  49. package/lib/scaffold/backends/supabase/patch/lib/features/notifications/providers/models/notification.dart +0 -174
  50. package/lib/scaffold/backends/supabase/patch/lib/features/onboarding/ui/components/onboarding_notifications_setup.dart +0 -73
  51. package/lib/scaffold/backends/supabase/patch/lib/main.dart +0 -307
  52. package/lib/scaffold/backends/supabase/patch/lib/router.dart +0 -133
@@ -1,307 +0,0 @@
1
- import 'package:device_preview/device_preview.dart';
2
- import 'package:firebase_core/firebase_core.dart';
3
- import 'package:firebase_messaging/firebase_messaging.dart';
4
- import 'package:flutter/foundation.dart';
5
- import 'package:flutter/material.dart';
6
- import 'package:flutter/services.dart';
7
- import 'package:flutter_localizations/flutter_localizations.dart';
8
- import 'package:flutter_riverpod/flutter_riverpod.dart';
9
- import 'package:jiffy/jiffy.dart';
10
- import 'package:logger/logger.dart';
11
- import 'package:kasy_kit/core/data/api/analytics_api.dart';
12
- import 'package:kasy_kit/core/data/api/remote_config_api.dart';
13
- import 'package:kasy_kit/core/data/api/tracking_api.dart';
14
- import 'package:kasy_kit/core/dev_inspector/dev_inspector.dart';
15
- import 'package:kasy_kit/core/home_widgets/home_widget_service.dart';
16
- import 'package:kasy_kit/core/web_device_preview/web_device_preview.dart';
17
- import 'package:kasy_kit/core/initializer/onstart_widget.dart';
18
- import 'package:kasy_kit/core/shared_preferences/shared_preferences.dart';
19
- import 'package:kasy_kit/core/states/user_state_notifier.dart';
20
- import 'package:kasy_kit/core/theme/colors.dart';
21
- import 'package:kasy_kit/core/theme/extensions/theme_extension.dart';
22
- import 'package:kasy_kit/core/theme/providers/theme_provider.dart';
23
- import 'package:kasy_kit/core/theme/texts.dart';
24
- import 'package:kasy_kit/core/theme/universal_theme.dart';
25
- import 'package:kasy_kit/core/config/app_env.dart';
26
- import 'package:kasy_kit/environnements.dart';
27
- import 'package:kasy_kit/firebase_options_dev.dart' as firebase_dev;
28
- import 'package:kasy_kit/i18n/translations.g.dart';
29
- import 'package:kasy_kit/features/authentication/api/authentication_api.dart';
30
- import 'package:kasy_kit/features/notifications/api/local_notifier.dart';
31
- import 'package:kasy_kit/features/notifications/repositories/background_notification_handler.dart';
32
- import 'package:kasy_kit/features/notifications/repositories/notifications_repository.dart';
33
- import 'package:kasy_kit/features/subscription/repositories/subscription_repository.dart';
34
- import 'package:kasy_kit/router.dart';
35
- import 'package:sentry_flutter/sentry_flutter.dart';
36
- import 'package:shared_preferences/shared_preferences.dart';
37
- import 'package:supabase_flutter/supabase_flutter.dart';
38
-
39
- void main() async {
40
- WidgetsFlutterBinding.ensureInitialized();
41
- await AppEnv.load();
42
- final env = Environment.fromEnv();
43
- final logger = Logger();
44
- logger.i('Starting app in ${env.name} mode');
45
- // I like to force portrait mode on mobile devices
46
- // What is the last time you used an app in landscape mode?
47
- SystemChrome.setPreferredOrientations([
48
- DeviceOrientation.portraitUp,
49
- DeviceOrientation.portraitDown,
50
- ]);
51
-
52
- // initialize shared preferences for theme and locale
53
- final sharedPrefs = await SharedPreferences.getInstance();
54
-
55
- // Restore saved locale; fall back to device locale if none saved.
56
- // Supported locales: en, pt, es. If the device locale is not one of these,
57
- // the base locale (en) is used as fallback (configured in slang.yaml).
58
- // To change the default locale, update `base_locale` in slang.yaml.
59
- final savedLocale = sharedPrefs.getString('app_locale');
60
- if (savedLocale != null) {
61
- final appLocale = AppLocale.values.firstWhere(
62
- (l) => l.languageCode == savedLocale,
63
- orElse: () => AppLocale.en,
64
- );
65
- LocaleSettings.setLocale(appLocale);
66
- } else {
67
- LocaleSettings.useDeviceLocale();
68
- }
69
- // initialize firebase app for notifications
70
- await switch(env) {
71
- DevEnvironment() => Firebase.initializeApp(
72
- options: firebase_dev.DefaultFirebaseOptions.currentPlatform,
73
- ),
74
- ProdEnvironment() => Firebase.initializeApp(
75
- // Firebase is used here only for push notifications (FCM) and Remote Config.
76
- // If you use a single Firebase project for dev and prod (most common), this is correct.
77
- // If you have a separate Firebase project for production:
78
- // 1. Run: flutterfire configure --project=YOUR_PROD_PROJECT_ID --out=lib/firebase_options_prod.dart
79
- // 2. Import it: import 'package:kasy_kit/firebase_options_prod.dart' as firebase_prod;
80
- // 3. Replace the line below with: options: firebase_prod.DefaultFirebaseOptions.currentPlatform,
81
- options: firebase_dev.DefaultFirebaseOptions.currentPlatform,
82
- ),
83
- };
84
-
85
- // initialize supabase app
86
- await switch(env) {
87
- DevEnvironment(:final backendUrl) => Supabase.initialize(
88
- url: backendUrl,
89
- anonKey: AppEnv.supabaseToken,
90
- ),
91
- ProdEnvironment(:final backendUrl) => Supabase.initialize(
92
- url: backendUrl,
93
- anonKey: AppEnv.supabaseToken,
94
- ),
95
- };
96
-
97
- // Jiffy locale must be set AFTER Firebase/Supabase init because those SDKs
98
- // reset Intl.defaultLocale internally, which would override our setting.
99
- await Jiffy.setLocale(LocaleSettings.instance.currentLocale.languageCode);
100
-
101
- // MUST be registered at the top-level BEFORE runApp().
102
- FirebaseMessaging.onBackgroundMessage(onBackgroundMessage);
103
-
104
- // initialize sentry for error reporting in production only
105
- if (env is DevEnvironment) {
106
- run(sharedPrefs);
107
- } else if (env is ProdEnvironment) {
108
- SentryFlutter.init((options) {
109
- options.dsn = env.sentryDsn;
110
- // 20% of traces will be sent to Sentry server. You should start with 1 and decrease it once you have more users.
111
- options.tracesSampleRate = 0.2;
112
- options.environment = env.name;
113
- }, appRunner: () => run(sharedPrefs));
114
- }
115
-
116
-
117
- }
118
-
119
- void run(SharedPreferences prefs) => runApp(
120
- TranslationProvider(
121
- child: ProviderScope(
122
- child: MyApp(
123
- sharedPreferences: prefs,
124
- ),
125
- ),
126
- ),
127
- );
128
-
129
-
130
- // use this if you want to define different themes for different platforms
131
- // notifier: AppTheme.adaptive(
132
- // defaultTextTheme: KasyTextTheme.build(),
133
- // ios: const IosThemeFactory(),
134
- // android: const AndroidThemeFactory(),
135
- // web: const WebThemeFactory(),
136
- // lightColors: KasyColors.light(),
137
- // darkColors: KasyColors.dark(),
138
- // mode: ThemeMode.dark,
139
- // ),
140
- // See ./docs/theme.md for more details
141
- class MyApp extends ConsumerStatefulWidget {
142
- final SharedPreferences sharedPreferences;
143
-
144
- const MyApp({
145
- super.key,
146
- required this.sharedPreferences,
147
- });
148
-
149
- @override
150
- ConsumerState<MyApp> createState() => _MyAppState();
151
- }
152
-
153
- class _MyAppState extends ConsumerState<MyApp> {
154
- late final AppTheme _appTheme;
155
-
156
- @override
157
- void initState() {
158
- super.initState();
159
- _appTheme = AppTheme.uniform(
160
- sharedPreferences: widget.sharedPreferences,
161
- themeFactory: const UniversalThemeFactory(),
162
- lightColors: KasyColors.light(),
163
- darkColors: KasyColors.dark(),
164
- textTheme: KasyTextTheme.build(),
165
- defaultMode: ThemeMode.system,
166
- );
167
- }
168
-
169
- @override
170
- void dispose() {
171
- _appTheme.dispose();
172
- super.dispose();
173
- }
174
-
175
- // This widget is the root of your application.
176
- @override
177
- Widget build(BuildContext context) {
178
- ErrorWidget.builder = (FlutterErrorDetails details) {
179
- return AppErrorWidget(error: details);
180
- };
181
- final goRouter = ref.watch(goRouterProvider);
182
-
183
- return ThemeProvider(
184
- notifier: _appTheme,
185
- child: Builder(builder: (context) {
186
- return WebDevicePreview.wrap(
187
- child: DevInspector.wrap(
188
- child: MaterialApp.router(
189
- title: 'Kasy',
190
- scaffoldMessengerKey: devInspectorRootScaffoldMessengerKey,
191
- theme: ThemeProvider.of(context).light,
192
- darkTheme: ThemeProvider.of(context).dark,
193
- themeMode: ThemeProvider.of(context).mode,
194
- routerConfig: goRouter,
195
- localizationsDelegates: const [
196
- GlobalMaterialLocalizations.delegate,
197
- GlobalWidgetsLocalizations.delegate,
198
- GlobalCupertinoLocalizations.delegate,
199
- ],
200
- locale: TranslationProvider.of(context).flutterLocale,
201
- supportedLocales: AppLocaleUtils.supportedLocales,
202
- builder: (context, child) => Initializer(
203
- services: [
204
- authenticationApiProvider,
205
- sharedPreferencesProvider,
206
- remoteConfigApiProvider,
207
- notificationsSettingsProvider,
208
- notificationRepositoryProvider,
209
- subscriptionRepositoryProvider,
210
- userStateNotifierProvider.notifier,
211
- homeWidgetsManagerProvider,
212
- analyticsApiProvider,
213
- facebookEventApiProvider,
214
- ],
215
- onReady: DevicePreview.appBuilder(context, child),
216
- onError: (_, error) => InitializationErrorPage(error: error),
217
- onLoading: Scaffold(
218
- body: Center(
219
- child: CircularProgressIndicator.adaptive(
220
- valueColor:
221
- AlwaysStoppedAnimation<Color>(context.colors.primary),
222
- ),
223
- ),
224
- ),
225
- ),
226
- ),
227
- ),
228
- );
229
- }),
230
- );
231
- }
232
- }
233
-
234
- /// This is an example of a more user friendly error widget
235
- /// By default Flutter will show a red screen with the error in debug mode
236
- /// and a grey screen in release mode
237
- class AppErrorWidget extends StatelessWidget {
238
- final FlutterErrorDetails? error;
239
-
240
- const AppErrorWidget({super.key, this.error});
241
-
242
- @override
243
- Widget build(BuildContext context) {
244
- return Container(
245
- padding: const EdgeInsets.all(16),
246
- color: Colors.orangeAccent,
247
- child: Column(
248
- mainAxisAlignment: MainAxisAlignment.center,
249
- children: [
250
- const Text(
251
- 'Oups!',
252
- style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
253
- ),
254
- const SizedBox(height: 8),
255
- const Text(
256
- 'Sorry, Something went wrong',
257
- style: TextStyle(color: Colors.white),
258
- ),
259
- const SizedBox(height: 8),
260
- Text(
261
- '${error?.exception}\n',
262
- style: const TextStyle(color: Colors.white, fontSize: 10),
263
- ),
264
- ],
265
- ),
266
- );
267
- }
268
- }
269
-
270
- class InitializationErrorPage extends StatelessWidget {
271
- final String error;
272
-
273
- const InitializationErrorPage({super.key, required this.error});
274
-
275
- @override
276
- Widget build(BuildContext context) {
277
- return Scaffold(
278
- body: Padding(
279
- padding: const EdgeInsets.all(24.0),
280
- child: Column(
281
- mainAxisAlignment: MainAxisAlignment.center,
282
- crossAxisAlignment: CrossAxisAlignment.stretch,
283
- spacing: 8,
284
- children: [
285
- Text(
286
- 'Cannot start app',
287
- style: context.textTheme.titleLarge,
288
- ),
289
- Text(
290
- 'Check your internet connection and start again',
291
- style: context.textTheme.bodyLarge?.copyWith(
292
- color: context.colors.grey3,
293
- ),
294
- ),
295
- if (kDebugMode)
296
- Text(
297
- "developper mode error: $error",
298
- style: context.textTheme.bodyLarge?.copyWith(
299
- color: context.colors.error,
300
- ),
301
- ),
302
- ],
303
- ),
304
- ),
305
- );
306
- }
307
- }
@@ -1,133 +0,0 @@
1
- import 'package:flutter/material.dart';
2
- import 'package:flutter_riverpod/flutter_riverpod.dart';
3
- import 'package:go_router/go_router.dart';
4
- import 'package:kasy_kit/core/bottom_menu/bottom_menu.dart';
5
- import 'package:kasy_kit/core/config/features.dart';
6
- import 'package:kasy_kit/core/data/api/analytics_api.dart';
7
- import 'package:kasy_kit/core/guards/user_info_guard.dart';
8
- import 'package:kasy_kit/core/widgets/page_not_found.dart';
9
- import 'package:kasy_kit/features/authentication/ui/phone_auth_page.dart';
10
- import 'package:kasy_kit/features/authentication/ui/recover_password_page.dart';
11
- import 'package:kasy_kit/features/authentication/ui/signin_page.dart';
12
- import 'package:kasy_kit/features/authentication/ui/signup_page.dart';
13
- import 'package:kasy_kit/features/feedbacks/ui/component/add_feature_form.dart';
14
- import 'package:kasy_kit/features/feedbacks/ui/feedback_page.dart';
15
- import 'package:kasy_kit/features/llm_chat/llm_chat_page.dart';
16
- import 'package:kasy_kit/features/local_reminder/ui/reminder_page.dart';
17
- import 'package:kasy_kit/features/onboarding/ui/onboarding_page.dart';
18
- import 'package:kasy_kit/features/subscription/ui/premium_page.dart';
19
-
20
- final goRouterProvider = Provider<GoRouter>(
21
- (ref) => generateRouter(),
22
- );
23
-
24
- extension GoRouterRiverpod on Ref {
25
- GoRouter get goRouter => read(goRouterProvider);
26
- }
27
-
28
- final navigatorKey = GlobalKey<NavigatorState>();
29
-
30
- GoRouter generateRouter({
31
- String? initialLocation,
32
- List<GoRoute>? additionalRoutes,
33
- List<NavigatorObserver>? observers,
34
- }) {
35
- return GoRouter(
36
- initialLocation: '/',
37
- navigatorKey: navigatorKey,
38
- errorBuilder: (context, state) => const PageNotFound(),
39
- observers: [
40
- AnalyticsObserver(
41
- analyticsApi: MixpanelAnalyticsApi.instance(),
42
- ),
43
-
44
- ...?observers,
45
- ],
46
- routes: [
47
- GoRoute(
48
- name: 'home',
49
- path: '/',
50
- builder: (context, state) => const UserInfosGuard(
51
- fallbackRoute: '/onboarding',
52
- child: BottomMenu(),
53
- ),
54
- ),
55
- GoRoute(
56
- name: 'onboarding',
57
- path: '/onboarding',
58
- builder: (context, state) => const OnboardingPage(),
59
- ),
60
- GoRoute(
61
- name: 'signup',
62
- path: '/signup',
63
- builder: (context, state) => const SignupPage(),
64
- ),
65
- GoRoute(
66
- name: 'signin',
67
- path: '/signin',
68
- builder: (context, state) => const SigninPage(),
69
- ),
70
- GoRoute(
71
- name: 'signinWithPhone',
72
- path: '/signinWithPhone',
73
- builder: (context, state) => const PhoneAuthPage(),
74
- ),
75
- GoRoute(
76
- name: 'premium',
77
- path: '/premium',
78
- builder: (context, state) => const PremiumPage(),
79
- ),
80
- if (withFeedback) ...[
81
- GoRoute(
82
- name: 'feedback',
83
- path: '/feedback',
84
- builder: (context, state) => const FeedbackPage(),
85
- ),
86
- GoRoute(
87
- name: 'feedback_new',
88
- path: '/feedback/new',
89
- builder: (context, state) => const AddFeatureComponent(),
90
- ),
91
- ],
92
- if (withLlmChat)
93
- GoRoute(
94
- name: 'assistant',
95
- path: '/assistant',
96
- builder: (context, state) => const LlmChatPage(),
97
- ),
98
- if (withLocalNotifications)
99
- GoRoute(
100
- name: 'reminder',
101
- path: '/reminder',
102
- builder: (context, state) => const ReminderPage(),
103
- ),
104
- GoRoute(
105
- name: 'notifications',
106
- path: '/notifications',
107
- builder: (context, state) => const UserInfosGuard(
108
- fallbackRoute: '/onboarding',
109
- child: BottomMenu(initialRoute: 'notifications'),
110
- ),
111
- ),
112
- GoRoute(
113
- name: 'settings',
114
- path: '/settings',
115
- builder: (context, state) => const UserInfosGuard(
116
- fallbackRoute: '/onboarding',
117
- child: BottomMenu(initialRoute: 'settings'),
118
- ),
119
- ),
120
- GoRoute(
121
- name: 'recover_password',
122
- path: '/recover_password',
123
- builder: (context, state) => const RecoverPasswordPage(),
124
- ),
125
- GoRoute(
126
- name: '404',
127
- path: '/404',
128
- builder: (context, state) => const PageNotFound(),
129
- ),
130
- ],
131
- );
132
- }
133
-