kasy-cli 1.17.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/bin/kasy.js +16 -2
  2. package/lib/commands/add.js +7 -7
  3. package/lib/commands/configure.js +548 -0
  4. package/lib/commands/deploy.js +4 -4
  5. package/lib/commands/doctor.js +17 -0
  6. package/lib/commands/favicon.js +4 -4
  7. package/lib/commands/icon.js +5 -5
  8. package/lib/commands/new.js +483 -324
  9. package/lib/commands/run.js +17 -4
  10. package/lib/commands/splash.js +5 -5
  11. package/lib/commands/update.js +9 -9
  12. package/lib/scaffold/CHANGELOG.json +14 -0
  13. package/lib/scaffold/backends/firebase/enable-auth-via-cli.js +108 -0
  14. package/lib/scaffold/backends/firebase/setup-from-scratch.js +123 -5
  15. package/lib/scaffold/generate.js +24 -8
  16. package/lib/scaffold/shared/post-build.js +8 -0
  17. package/lib/utils/brand.js +16 -12
  18. package/lib/utils/flutter-run.js +139 -11
  19. package/lib/utils/i18n/messages-en.js +62 -5
  20. package/lib/utils/i18n/messages-es.js +62 -5
  21. package/lib/utils/i18n/messages-pt.js +63 -6
  22. package/lib/utils/ui.js +79 -4
  23. package/package.json +1 -2
  24. package/templates/firebase/README.en.md +1 -1
  25. package/templates/firebase/README.es.md +1 -1
  26. package/templates/firebase/README.md +1 -1
  27. package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/MainActivity.kt +0 -15
  28. package/templates/firebase/android/app/src/main/kotlin/com/aicrus/firebase/kit/MyWidget.kt +65 -26
  29. package/templates/firebase/android/app/src/main/res/drawable/widget_add_button.xml +2 -2
  30. package/templates/firebase/android/app/src/main/res/drawable/widget_gradient_bg.xml +7 -2
  31. package/templates/firebase/android/app/src/main/res/drawable/widget_gradient_inner.xml +6 -6
  32. package/templates/firebase/android/app/src/main/res/drawable/widget_plan_pill_bg.xml +1 -1
  33. package/templates/firebase/android/app/src/main/res/drawable/widget_preview_image.xml +2 -2
  34. package/templates/firebase/android/app/src/main/res/drawable/widget_pro_pill_bg.xml +1 -1
  35. package/templates/firebase/android/app/src/main/res/drawable-hdpi/android12splash.png +0 -0
  36. package/templates/firebase/android/app/src/main/res/drawable-hdpi/splash.png +0 -0
  37. package/templates/firebase/android/app/src/main/res/drawable-mdpi/android12splash.png +0 -0
  38. package/templates/firebase/android/app/src/main/res/drawable-mdpi/splash.png +0 -0
  39. package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/android12splash.png +0 -0
  40. package/templates/firebase/android/app/src/main/res/drawable-night-hdpi/splash.png +0 -0
  41. package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/android12splash.png +0 -0
  42. package/templates/firebase/android/app/src/main/res/drawable-night-mdpi/splash.png +0 -0
  43. package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/android12splash.png +0 -0
  44. package/templates/firebase/android/app/src/main/res/drawable-night-xhdpi/splash.png +0 -0
  45. package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png +0 -0
  46. package/templates/firebase/android/app/src/main/res/drawable-night-xxhdpi/splash.png +0 -0
  47. package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png +0 -0
  48. package/templates/firebase/android/app/src/main/res/drawable-night-xxxhdpi/splash.png +0 -0
  49. package/templates/firebase/android/app/src/main/res/drawable-xhdpi/android12splash.png +0 -0
  50. package/templates/firebase/android/app/src/main/res/drawable-xhdpi/splash.png +0 -0
  51. package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/android12splash.png +0 -0
  52. package/templates/firebase/android/app/src/main/res/drawable-xxhdpi/splash.png +0 -0
  53. package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/android12splash.png +0 -0
  54. package/templates/firebase/android/app/src/main/res/drawable-xxxhdpi/splash.png +0 -0
  55. package/templates/firebase/android/app/src/main/res/layout/widget_preview.xml +3 -3
  56. package/templates/firebase/android/app/src/main/res/values/colors.xml +32 -0
  57. package/templates/firebase/assets/images/splash_logo_dark.png +0 -0
  58. package/templates/firebase/assets/images/splash_logo_dark_android12.png +0 -0
  59. package/templates/firebase/assets/images/splash_logo_light.png +0 -0
  60. package/templates/firebase/assets/images/splash_logo_light_android12.png +0 -0
  61. package/templates/firebase/ios/HomeWidgetExtension/MyWidget.swift +75 -29
  62. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png +0 -0
  63. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png +0 -0
  64. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png +0 -0
  65. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark.png +0 -0
  66. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@2x.png +0 -0
  67. package/templates/firebase/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImageDark@3x.png +0 -0
  68. package/templates/firebase/ios/Runner/Base.lproj/LaunchScreen.storyboard +1 -1
  69. package/templates/firebase/lib/components/components.dart +1 -0
  70. package/templates/firebase/lib/components/kasy_avatar.dart +65 -17
  71. package/templates/firebase/lib/components/kasy_avatar_presets.dart +121 -97
  72. package/templates/firebase/lib/components/kasy_button.dart +8 -8
  73. package/templates/firebase/lib/components/kasy_date_picker.dart +2173 -0
  74. package/templates/firebase/lib/components/kasy_tabs.dart +214 -91
  75. package/templates/firebase/lib/components/kasy_text_area.dart +9 -4
  76. package/templates/firebase/lib/components/kasy_text_field.dart +96 -36
  77. package/templates/firebase/lib/components/kasy_text_field_otp.dart +1 -2
  78. package/templates/firebase/lib/core/bottom_menu/bottom_menu.dart +88 -35
  79. package/templates/firebase/lib/core/bottom_menu/bottom_router.dart +7 -43
  80. package/templates/firebase/lib/core/dev_inspector/dev_inspector.dart +118 -16
  81. package/templates/firebase/lib/core/dev_inspector/dev_inspector_service.dart +14 -20
  82. package/templates/firebase/lib/core/home_widgets/home_widget_mywidget_service.dart +12 -18
  83. package/templates/firebase/lib/core/security/secured_storage.dart +56 -15
  84. package/templates/firebase/lib/core/theme/providers/theme_provider.dart +3 -0
  85. package/templates/firebase/lib/core/theme/web_background_sync.dart +3 -0
  86. package/templates/firebase/lib/core/theme/web_background_sync_web.dart +18 -0
  87. package/templates/firebase/lib/core/web_device_preview/web_device_preview.dart +3 -6
  88. package/templates/firebase/lib/features/authentication/api/authentication_api.dart +6 -0
  89. package/templates/firebase/lib/features/home/home_components_page.dart +3 -2
  90. package/templates/firebase/lib/features/home/home_components_preview_registry.dart +949 -77
  91. package/templates/firebase/lib/features/home/home_page.dart +17 -40
  92. package/templates/firebase/lib/features/notifications/ui/notifications_page.dart +1 -16
  93. package/templates/firebase/lib/features/notifications/ui/widgets/empty_notifications.dart +0 -4
  94. package/templates/firebase/lib/features/settings/ui/components/language_switcher.dart +10 -5
  95. package/templates/firebase/lib/i18n/en.i18n.json +2 -1
  96. package/templates/firebase/lib/i18n/es.i18n.json +2 -1
  97. package/templates/firebase/lib/i18n/pt.i18n.json +2 -1
  98. package/templates/firebase/lib/main.dart +34 -34
  99. package/templates/firebase/pubspec.yaml +2 -1
  100. package/templates/firebase/storage.cors.json +8 -0
  101. package/templates/firebase/web/index.html +24 -2
  102. package/templates/firebase/web/splash/img/dark-1x.png +0 -0
  103. package/templates/firebase/web/splash/img/dark-2x.png +0 -0
  104. package/templates/firebase/web/splash/img/dark-3x.png +0 -0
  105. package/templates/firebase/web/splash/img/dark-4x.png +0 -0
  106. package/templates/firebase/web/splash/img/light-1x.png +0 -0
  107. package/templates/firebase/web/splash/img/light-2x.png +0 -0
  108. package/templates/firebase/web/splash/img/light-3x.png +0 -0
  109. package/templates/firebase/web/splash/img/light-4x.png +0 -0
  110. package/templates/firebase/lib/core/bottom_menu/kasy_bart_navigation.dart +0 -22
@@ -1,6 +1,8 @@
1
+ import 'package:flutter/foundation.dart';
1
2
  import 'package:flutter_riverpod/flutter_riverpod.dart';
2
3
  import 'package:flutter_secure_storage/flutter_secure_storage.dart';
3
4
  import 'package:kasy_kit/core/data/entities/user_entity.dart';
5
+ import 'package:shared_preferences/shared_preferences.dart';
4
6
 
5
7
  const _kTokenKey = "token";
6
8
  const _kUserIdKey = "userId";
@@ -9,38 +11,77 @@ final authSecuredStorageProvider = Provider<AuthSecuredStorage>(
9
11
  (ref) => AuthSecuredStorage.fromEnv(),
10
12
  );
11
13
 
12
- class AuthSecuredStorage {
13
- final FlutterSecureStorage _storage;
14
+ abstract class AuthSecuredStorage {
15
+ Future<void> write({required Credentials value});
16
+ Future<Credentials?> read();
17
+ Future<void> clear();
14
18
 
15
- AuthSecuredStorage({
16
- required FlutterSecureStorage storage,
17
- }) : _storage = storage;
19
+ // Web uses SharedPreferences (LocalStorage) because flutter_secure_storage
20
+ // has no real on-disk persistence in the browser. Mobile keeps the Keychain
21
+ // / EncryptedSharedPreferences backend it had before.
22
+ factory AuthSecuredStorage.fromEnv() {
23
+ if (kIsWeb) return _WebAuthStorage();
24
+ return _NativeAuthStorage(storage: const FlutterSecureStorage());
25
+ }
26
+ }
27
+
28
+ class _NativeAuthStorage implements AuthSecuredStorage {
29
+ final FlutterSecureStorage _storage;
18
30
 
19
- factory AuthSecuredStorage.fromEnv() => AuthSecuredStorage(
20
- storage: const FlutterSecureStorage(),
21
- );
31
+ _NativeAuthStorage({required FlutterSecureStorage storage}) : _storage = storage;
22
32
 
23
- Future<void> write({
24
- required Credentials value,
25
- }) async {
33
+ @override
34
+ Future<void> write({required Credentials value}) async {
26
35
  await _storage.write(key: _kUserIdKey, value: value.id);
27
36
  await _storage.write(key: _kTokenKey, value: value.token);
28
37
  }
29
38
 
39
+ @override
30
40
  Future<Credentials?> read() async {
31
41
  final userId = await _storage.read(key: _kUserIdKey);
32
42
  final token = await _storage.read(key: _kTokenKey);
33
43
  if (userId != null && token != null) {
34
- return Credentials(
35
- id: userId,
36
- token: token,
37
- );
44
+ return Credentials(id: userId, token: token);
38
45
  }
39
46
  return null;
40
47
  }
41
48
 
49
+ @override
42
50
  Future<void> clear() async {
43
51
  await _storage.delete(key: _kUserIdKey);
44
52
  await _storage.delete(key: _kTokenKey);
45
53
  }
46
54
  }
55
+
56
+ class _WebAuthStorage implements AuthSecuredStorage {
57
+ Future<SharedPreferences> get _prefs => SharedPreferences.getInstance();
58
+
59
+ @override
60
+ Future<void> write({required Credentials value}) async {
61
+ final prefs = await _prefs;
62
+ await prefs.setString(_kUserIdKey, value.id);
63
+ if (value.token != null) {
64
+ await prefs.setString(_kTokenKey, value.token!);
65
+ } else {
66
+ await prefs.remove(_kTokenKey);
67
+ }
68
+ }
69
+
70
+ @override
71
+ Future<Credentials?> read() async {
72
+ final prefs = await _prefs;
73
+ final userId = prefs.getString(_kUserIdKey);
74
+ final token = prefs.getString(_kTokenKey);
75
+ if (userId != null && token != null) {
76
+ return Credentials(id: userId, token: token);
77
+ }
78
+ return null;
79
+ }
80
+
81
+ @override
82
+ Future<void> clear() async {
83
+ final prefs = await _prefs;
84
+ await prefs.remove(_kUserIdKey);
85
+ await prefs.remove(_kTokenKey);
86
+ }
87
+ }
@@ -4,6 +4,8 @@ import 'package:kasy_kit/core/theme/colors.dart';
4
4
  import 'package:kasy_kit/core/theme/providers/kasy_theme.dart';
5
5
  import 'package:kasy_kit/core/theme/texts.dart';
6
6
  import 'package:kasy_kit/core/theme/theme_data/theme_data_factory.dart';
7
+ import 'package:kasy_kit/core/theme/web_background_sync.dart'
8
+ if (dart.library.js_interop) 'package:kasy_kit/core/theme/web_background_sync_web.dart';
7
9
  import 'package:shared_preferences/shared_preferences.dart';
8
10
 
9
11
  /// We use this to access the theme from the BuildContext in all our widgets
@@ -182,6 +184,7 @@ class AppTheme with ChangeNotifier, WidgetsBindingObserver {
182
184
  statusBarIconBrightness: isLight ? Brightness.dark : Brightness.light,
183
185
  ),
184
186
  );
187
+ syncWebBackgroundColor(isLight ? Brightness.light : Brightness.dark);
185
188
  }
186
189
 
187
190
  ThemeData get dark {
@@ -0,0 +1,3 @@
1
+ import 'package:flutter/material.dart';
2
+
3
+ void syncWebBackgroundColor(Brightness brightness) {}
@@ -0,0 +1,18 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'package:web/web.dart' as web;
3
+
4
+ void syncWebBackgroundColor(Brightness brightness) {
5
+ final color = brightness == Brightness.dark ? '#000000' : '#FFFFFF';
6
+ (web.document.documentElement as web.HTMLElement?)
7
+ ?.style
8
+ .setProperty('background-color', color);
9
+ web.document.body?.style.setProperty('background-color', color);
10
+ final views = web.document.querySelectorAll(
11
+ 'flutter-view, flt-glass-pane, flt-scene-host',
12
+ );
13
+ for (var i = 0; i < views.length; i++) {
14
+ (views.item(i) as web.HTMLElement?)
15
+ ?.style
16
+ .setProperty('background-color', color);
17
+ }
18
+ }
@@ -237,8 +237,7 @@ class _WebDevicePreviewState extends State<WebDevicePreview> {
237
237
  }
238
238
 
239
239
  void _toggleInspector() {
240
- WidgetsBinding.instance.debugShowWidgetInspectorOverride =
241
- !WidgetsBinding.instance.debugShowWidgetInspectorOverride;
240
+ devInspectorActiveNotifier.value = !devInspectorActiveNotifier.value;
242
241
  }
243
242
 
244
243
  void _copyInspection() {
@@ -383,8 +382,7 @@ class _WebDevicePreviewState extends State<WebDevicePreview> {
383
382
  _landscapeNotifier,
384
383
  _textScaleNotifier,
385
384
  _localeNotifier,
386
- WidgetsBinding.instance
387
- .debugShowWidgetInspectorOverrideNotifier,
385
+ devInspectorActiveNotifier,
388
386
  ]),
389
387
  builder: (context, child) => _PreviewControls(
390
388
  platform: _platform,
@@ -395,8 +393,7 @@ class _WebDevicePreviewState extends State<WebDevicePreview> {
395
393
  isLandscape: _landscapeNotifier.value,
396
394
  textScale: _textScaleNotifier.value,
397
395
  currentLocale: _localeNotifier.value,
398
- inspectorEnabled: WidgetsBinding
399
- .instance.debugShowWidgetInspectorOverride,
396
+ inspectorEnabled: devInspectorActiveNotifier.value,
400
397
  onPlatformChanged: _setPlatform,
401
398
  onPrev: _prev,
402
399
  onNext: _next,
@@ -34,6 +34,12 @@ class FirebaseAuthenticationApi implements AuthenticationApi {
34
34
 
35
35
  @override
36
36
  Future<void> init() async {
37
+ if (kIsWeb) {
38
+ // Force LOCAL persistence (IndexedDB) on web. It's the default for the JS
39
+ // SDK, but Firebase's web bootstrap sometimes resets it to SESSION when
40
+ // the page loads through a service worker — being explicit avoids that.
41
+ await _auth.setPersistence(Persistence.LOCAL);
42
+ }
37
43
  _auth.userChanges().listen((event) {
38
44
  if (!hasInit) {
39
45
  hasInit = true;
@@ -181,6 +181,7 @@ const Set<String> _kReadyComponents = <String>{
181
181
  'Button',
182
182
  'Card',
183
183
  'Checkbox',
184
+ 'DatePicker',
184
185
  'Design System',
185
186
  'Dialog',
186
187
  'Hover',
@@ -205,6 +206,7 @@ const Set<String> _kWebReadyComponents = <String>{
205
206
  'Button',
206
207
  'Card',
207
208
  'Checkbox',
209
+ 'DatePicker',
208
210
  'Design System',
209
211
  'Dialog',
210
212
  'Hover',
@@ -220,7 +222,6 @@ const Set<String> _kWebReadyComponents = <String>{
220
222
  const Set<String> _kUrgentComponents = <String>{
221
223
  'Switch',
222
224
  'Radio Group',
223
- 'DatePicker',
224
225
  };
225
226
 
226
227
  const List<_CatalogRow> _kCatalog = [
@@ -236,6 +237,7 @@ const List<_CatalogRow> _kCatalog = [
236
237
  _CatalogRow('Button'),
237
238
  _CatalogRow('Card'),
238
239
  _CatalogRow('Checkbox'),
240
+ _CatalogRow('DatePicker'),
239
241
  _CatalogRow('Dialog'),
240
242
  _CatalogRow('Hover'),
241
243
  _CatalogRow('Sidebar'),
@@ -246,7 +248,6 @@ const List<_CatalogRow> _kCatalog = [
246
248
  _CatalogRow('TextFieldOTP'),
247
249
  _CatalogRow('Toast'),
248
250
  // Prioridade: Urgente (_kUrgentComponents), A–Z
249
- _CatalogRow('DatePicker'),
250
251
  _CatalogRow('Radio Group'),
251
252
  _CatalogRow('Switch'),
252
253
  _CatalogRow('Tabs'),