kasy-cli 1.5.0 → 1.5.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.
@@ -12,6 +12,7 @@ const { createTranslator, detectDefaultLanguage } = require('../utils/i18n');
12
12
  const {
13
13
  AVAILABLE_FEATURES,
14
14
  BASE_COMPONENT_FILES,
15
+ CORE_FILES,
15
16
  CORE_SOURCE_DIR,
16
17
  FEATURES_PATCH_DIR,
17
18
  normalizeFeature,
@@ -29,6 +30,7 @@ const NEEDS_BUILD_RUNNER = [
29
30
  'revenuecat', 'analytics', 'sentry', 'onboarding', 'llm_chat', 'feedback',
30
31
  ];
31
32
  const COMPONENTS_UPDATE_TARGET = 'components';
33
+ const CORE_UPDATE_TARGET = 'core';
32
34
  const IOS_RELEASE_UPDATE_TARGET = 'ios-release';
33
35
 
34
36
  // ── Helpers ──────────────────────────────────────────────────────────────────
@@ -80,6 +82,10 @@ function normalizeUpdateTarget(value) {
80
82
  if (componentAliases.has(normalized)) {
81
83
  return COMPONENTS_UPDATE_TARGET;
82
84
  }
85
+ const coreAliases = new Set(['core', 'core_files', 'corefiles']);
86
+ if (coreAliases.has(normalized)) {
87
+ return CORE_UPDATE_TARGET;
88
+ }
83
89
  const iosAliases = new Set(['ios_release', 'iosrelease']);
84
90
  if (iosAliases.has(normalized) || normalized === 'ios-release') {
85
91
  return IOS_RELEASE_UPDATE_TARGET;
@@ -87,9 +93,9 @@ function normalizeUpdateTarget(value) {
87
93
  return null;
88
94
  }
89
95
 
90
- async function applyBaseComponents(projectDir) {
96
+ async function applyFileList(fileList, projectDir) {
91
97
  let filesApplied = 0;
92
- for (const relativePath of BASE_COMPONENT_FILES) {
98
+ for (const relativePath of fileList) {
93
99
  const sourcePath = path.join(CORE_SOURCE_DIR, relativePath);
94
100
  if (!(await fs.pathExists(sourcePath))) {
95
101
  continue;
@@ -102,6 +108,14 @@ async function applyBaseComponents(projectDir) {
102
108
  return filesApplied;
103
109
  }
104
110
 
111
+ function applyBaseComponents(projectDir) {
112
+ return applyFileList(BASE_COMPONENT_FILES, projectDir);
113
+ }
114
+
115
+ function applyCoreFiles(projectDir) {
116
+ return applyFileList(CORE_FILES, projectDir);
117
+ }
118
+
105
119
  /** Same detection logic used by add.js and remove.js. */
106
120
  async function getActiveModules(kitSetup, projectDir) {
107
121
  const modules = [];
@@ -203,6 +217,49 @@ async function runUpdate(module, options = {}) {
203
217
  return;
204
218
  }
205
219
 
220
+ if (normalizedTarget === CORE_UPDATE_TARGET) {
221
+ if (!options.yes) {
222
+ console.log(kleur.yellow(`\n ⚠ ${t('update.warn.commitComponents')}\n`));
223
+ const { confirmed } = await prompts(
224
+ { type: 'confirm', name: 'confirmed', message: t('update.confirmCore'), initial: false },
225
+ { onCancel: () => { throw new Error(t('update.cancelled')); } }
226
+ );
227
+ if (!confirmed) {
228
+ console.log(kleur.dim(`\n${t('update.cancelled')}\n`));
229
+ return;
230
+ }
231
+ }
232
+
233
+ console.log('');
234
+ const spinner = ora(t('update.applyingCore')).start();
235
+ try {
236
+ const filesApplied = await applyCoreFiles(projectDir);
237
+ if (filesApplied === 0) {
238
+ spinner.warn(t('update.noComponentFiles'));
239
+ return;
240
+ }
241
+ spinner.succeed(t('update.appliedCore', { count: filesApplied }));
242
+ } catch (err) {
243
+ spinner.fail(t('update.applyComponentsFailed'));
244
+ throw err;
245
+ }
246
+
247
+ {
248
+ const spinnerPubGet = ora(t('update.pubGet')).start();
249
+ try {
250
+ await execAsync('flutter pub get', { cwd: projectDir, timeout: 300_000 });
251
+ spinnerPubGet.succeed(t('update.pubGetDone'));
252
+ } catch {
253
+ spinnerPubGet.warn(t('update.pubGetFailed'));
254
+ }
255
+ }
256
+
257
+ kitSetup.cliVersion = currentVersion;
258
+ await fs.outputFile(kitSetupPath, JSON.stringify(kitSetup, null, 2) + '\n', 'utf8');
259
+ console.log(kleur.green(`\n✓ ${t('update.coreSuccess')}\n`));
260
+ return;
261
+ }
262
+
206
263
  if (normalizedTarget === IOS_RELEASE_UPDATE_TARGET) {
207
264
  const patchDir = path.join(FEATURES_PATCH_DIR, 'ios-release');
208
265
  if (!(await fs.pathExists(patchDir))) {
@@ -249,7 +306,7 @@ async function runUpdate(module, options = {}) {
249
306
  throw new Error(
250
307
  t('update.error.unknownTarget', {
251
308
  module,
252
- list: [...AVAILABLE_FEATURES, COMPONENTS_UPDATE_TARGET, IOS_RELEASE_UPDATE_TARGET].join(', '),
309
+ list: [...AVAILABLE_FEATURES, COMPONENTS_UPDATE_TARGET, CORE_UPDATE_TARGET, IOS_RELEASE_UPDATE_TARGET].join(', '),
253
310
  })
254
311
  );
255
312
  }
@@ -335,7 +392,7 @@ async function runUpdate(module, options = {}) {
335
392
 
336
393
  // ── Mode B: show status ──────────────────────────────────────────────────────
337
394
  const alreadyUpToDate = projectVersion && !isNewer(currentVersion, projectVersion);
338
- const modulesForChangelog = [...new Set([...activeModules, COMPONENTS_UPDATE_TARGET])];
395
+ const modulesForChangelog = [...new Set([...activeModules, COMPONENTS_UPDATE_TARGET, CORE_UPDATE_TARGET])];
339
396
  const changes = getChangesSince(changelog, projectVersion, modulesForChangelog, options.language);
340
397
 
341
398
  // Modules in this project that have patch dirs (can be re-applied)
@@ -74,6 +74,54 @@ const DEFAULT_FEATURES = [...AVAILABLE_FEATURES];
74
74
  * shared widgets); keep this list in sync with `Firebase/lib/components/` and
75
75
  * the home component catalog.
76
76
  */
77
+ const CORE_FILES = [
78
+ // Dev tools
79
+ 'lib/core/web_device_preview/web_device_preview.dart',
80
+ 'lib/core/dev_inspector/dev_inspector.dart',
81
+ 'lib/core/dev_inspector/dev_inspector_highlight.dart',
82
+ 'lib/core/dev_inspector/dev_inspector_info.dart',
83
+ 'lib/core/dev_inspector/dev_inspector_panel.dart',
84
+ 'lib/core/dev_inspector/dev_inspector_service.dart',
85
+ 'lib/core/keyboard_fix/keyboard_flicker_fix.dart',
86
+ // Animations
87
+ 'lib/core/animations/bottomfade_anim.dart',
88
+ 'lib/core/animations/movefade_anim.dart',
89
+ 'lib/core/animations/slideright_anim.dart',
90
+ // Core widgets (pure utilities, never user-modified)
91
+ 'lib/core/widgets/debouncer.dart',
92
+ 'lib/core/widgets/kasy_hover.dart',
93
+ 'lib/core/widgets/kasy_pressable.dart',
94
+ 'lib/core/widgets/kasy_scroll_behavior.dart',
95
+ 'lib/core/widgets/keyboard_visibility.dart',
96
+ 'lib/core/widgets/page_background.dart',
97
+ 'lib/core/widgets/page_not_found.dart',
98
+ 'lib/core/widgets/responsive_layout.dart',
99
+ 'lib/core/widgets/update_bottom_sheet.dart',
100
+ // Page transitions (pure utilities)
101
+ 'lib/core/navigation/kasy_fade_page_transitions_builder.dart',
102
+ 'lib/core/navigation/kasy_material_page_route.dart',
103
+ 'lib/core/navigation/kasy_page_transition.dart',
104
+ 'lib/core/navigation/kasy_route_transition.dart',
105
+ 'lib/core/navigation/kasy_transition_kind.dart',
106
+ // Utilities
107
+ 'lib/core/toast/toast_service.dart',
108
+ 'lib/core/ui/app_dialog.dart',
109
+ 'lib/core/icons/kasy_icons.dart',
110
+ 'lib/core/haptics/kasy_haptics.dart',
111
+ 'lib/core/haptics/haptic_feedback_notifier.dart',
112
+ // Theme (colors.dart and shadows.dart are in BASE_COMPONENT_FILES)
113
+ 'lib/core/theme/spacing.dart',
114
+ 'lib/core/theme/texts.dart',
115
+ 'lib/core/theme/radius.dart',
116
+ 'lib/core/theme/theme.dart',
117
+ 'lib/core/theme/theme_data/theme_data.dart',
118
+ 'lib/core/theme/theme_data/theme_data_factory.dart',
119
+ 'lib/core/theme/extensions/theme_extension.dart',
120
+ 'lib/core/theme/providers/kasy_theme.dart',
121
+ 'lib/core/theme/providers/theme_provider.dart',
122
+ 'lib/core/theme/universal_theme.dart',
123
+ ];
124
+
77
125
  const BASE_COMPONENT_FILES = [
78
126
  'lib/core/theme/colors.dart',
79
127
  'lib/core/theme/shadows.dart',
@@ -170,6 +218,7 @@ module.exports = {
170
218
  AVAILABLE_FEATURES,
171
219
  DEFAULT_FEATURES,
172
220
  BASE_COMPONENT_FILES,
221
+ CORE_FILES,
173
222
  normalizeBackend,
174
223
  normalizeFeature,
175
224
  parseFeatureList,
package/lib/utils/i18n.js CHANGED
@@ -698,11 +698,14 @@ const MESSAGES = {
698
698
  'update.warn.commitComponents': 'This will overwrite base component files. Make sure you have committed your changes first.',
699
699
  'update.confirm': 'Overwrite feature "{module}" files with the latest version?',
700
700
  'update.confirmComponents': 'Overwrite base component files with the latest version?',
701
+ 'update.confirmCore': 'Overwrite core files (animations, widgets, theme, dev tools) with the latest version?',
701
702
  'update.cancelled': 'Cancelled.',
702
703
  'update.applying': 'Applying update for feature: {module}',
703
704
  'update.applyingComponents': 'Applying update for base components...',
705
+ 'update.applyingCore': 'Applying update for core files...',
704
706
  'update.applied': 'Feature {module} updated',
705
707
  'update.appliedComponents': '{count} base component files updated',
708
+ 'update.appliedCore': '{count} core files updated',
706
709
  'update.applyFailed': 'Failed to apply update for feature {module}',
707
710
  'update.applyComponentsFailed': 'Failed to apply update for base components',
708
711
  'update.noPatch': 'Feature "{module}" has no files to update (configuration-only feature).',
@@ -715,6 +718,7 @@ const MESSAGES = {
715
718
  'update.buildRunnerFailed': 'build_runner failed — run it manually',
716
719
  'update.success': 'Feature "{module}" updated successfully.',
717
720
  'update.componentsSuccess': 'Base components updated successfully.',
721
+ 'update.coreSuccess': 'Core files updated successfully.',
718
722
  },
719
723
  pt: {
720
724
  'cli.tagline': 'Crie apps móveis sem dor de configuração',
@@ -1409,11 +1413,14 @@ const MESSAGES = {
1409
1413
  'update.warn.commitComponents': 'Isso vai sobrescrever arquivos dos componentes base. Faca commit de tudo antes de continuar.',
1410
1414
  'update.confirm': 'Sobrescrever arquivos da feature "{module}" com a versao mais recente?',
1411
1415
  'update.confirmComponents': 'Sobrescrever arquivos dos componentes base com a versao mais recente?',
1416
+ 'update.confirmCore': 'Sobrescrever arquivos do core (animacoes, widgets, tema, ferramentas de dev) com a versao mais recente?',
1412
1417
  'update.cancelled': 'Cancelado.',
1413
1418
  'update.applying': 'Aplicando atualizacao da feature: {module}',
1414
1419
  'update.applyingComponents': 'Aplicando atualizacao dos componentes base...',
1420
+ 'update.applyingCore': 'Aplicando atualizacao dos arquivos de core...',
1415
1421
  'update.applied': 'Feature {module} atualizada',
1416
1422
  'update.appliedComponents': '{count} arquivos de componentes base atualizados',
1423
+ 'update.appliedCore': '{count} arquivos de core atualizados',
1417
1424
  'update.applyFailed': 'Falha ao aplicar atualizacao da feature {module}',
1418
1425
  'update.applyComponentsFailed': 'Falha ao aplicar atualizacao dos componentes base',
1419
1426
  'update.noPatch': 'Feature "{module}" nao tem arquivos para atualizar (feature so de configuracao).',
@@ -1426,6 +1433,7 @@ const MESSAGES = {
1426
1433
  'update.buildRunnerFailed': 'build_runner falhou — execute manualmente',
1427
1434
  'update.success': 'Feature "{module}" atualizada com sucesso.',
1428
1435
  'update.componentsSuccess': 'Componentes base atualizados com sucesso.',
1436
+ 'update.coreSuccess': 'Arquivos de core atualizados com sucesso.',
1429
1437
  },
1430
1438
  es: {
1431
1439
  'cli.tagline': 'Crea apps móviles sin dolor de configuración',
@@ -2120,11 +2128,14 @@ const MESSAGES = {
2120
2128
  'update.warn.commitComponents': 'Esto sobreescribira archivos de los componentes base. Asegurate de haber hecho commit antes.',
2121
2129
  'update.confirm': 'Sobreescribir archivos de la feature "{module}" con la version mas reciente?',
2122
2130
  'update.confirmComponents': 'Sobreescribir archivos de los componentes base con la version mas reciente?',
2131
+ 'update.confirmCore': 'Sobreescribir archivos de core (animaciones, widgets, tema, herramientas dev) con la version mas reciente?',
2123
2132
  'update.cancelled': 'Cancelado.',
2124
2133
  'update.applying': 'Aplicando actualizacion de la feature: {module}',
2125
2134
  'update.applyingComponents': 'Aplicando actualizacion de componentes base...',
2135
+ 'update.applyingCore': 'Aplicando actualizacion de archivos de core...',
2126
2136
  'update.applied': 'Feature {module} actualizada',
2127
2137
  'update.appliedComponents': '{count} archivos de componentes base actualizados',
2138
+ 'update.appliedCore': '{count} archivos de core actualizados',
2128
2139
  'update.applyFailed': 'Error al aplicar actualizacion de la feature {module}',
2129
2140
  'update.applyComponentsFailed': 'Error al aplicar actualizacion de componentes base',
2130
2141
  'update.noPatch': 'La feature "{module}" no tiene archivos para actualizar (feature solo de configuracion).',
@@ -2137,6 +2148,7 @@ const MESSAGES = {
2137
2148
  'update.buildRunnerFailed': 'build_runner fallo — ejecutalo manualmente',
2138
2149
  'update.success': 'Feature "{module}" actualizada exitosamente.',
2139
2150
  'update.componentsSuccess': 'Componentes base actualizados exitosamente.',
2151
+ 'update.coreSuccess': 'Archivos de core actualizados exitosamente.',
2140
2152
  }
2141
2153
  };
2142
2154
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kasy-cli",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "CLI for scaffolding production-ready Flutter SaaS apps with Firebase, Supabase, or API REST backends.",
5
5
  "bin": {
6
6
  "kasy": "./bin/kasy.js"