kasy-cli 1.3.1 → 1.4.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/new.js +51 -29
- package/lib/commands/update.js +7 -3
- package/lib/scaffold/CHANGELOG.json +8 -3
- package/lib/utils/i18n.js +63 -0
- package/lib/utils/license-gate.js +3 -2
- package/lib/utils/updates.js +1 -1
- package/package.json +1 -1
package/lib/commands/new.js
CHANGED
|
@@ -58,6 +58,16 @@ async function waitWithCountdown(seconds, label) {
|
|
|
58
58
|
}
|
|
59
59
|
process.stdout.write(`\r ${label} pronto! \n`);
|
|
60
60
|
}
|
|
61
|
+
|
|
62
|
+
function openUrl(url) {
|
|
63
|
+
try {
|
|
64
|
+
const { exec } = require('node:child_process');
|
|
65
|
+
const cmd = process.platform === 'darwin' ? `open "${url}"`
|
|
66
|
+
: process.platform === 'win32' ? `start "" "${url}"`
|
|
67
|
+
: `xdg-open "${url}"`;
|
|
68
|
+
exec(cmd, { shell: true });
|
|
69
|
+
} catch (_) {}
|
|
70
|
+
}
|
|
61
71
|
const prompts = require('prompts');
|
|
62
72
|
const fs = require('fs-extra');
|
|
63
73
|
const { createTranslator } = require('../utils/i18n');
|
|
@@ -334,9 +344,9 @@ const STEP_LABELS = {
|
|
|
334
344
|
|
|
335
345
|
const STEP_PROGRESS = {
|
|
336
346
|
'project-setup': { en: 'Configuring your project…', pt: 'Configurando seu projeto…', es: 'Configurando tu proyecto…' },
|
|
337
|
-
'pub-get': { en: 'Installing packages…',
|
|
338
|
-
'slang': { en: 'Generating translations…',
|
|
339
|
-
'build-runner': { en: 'Generating code (Riverpod / Freezed)…',
|
|
347
|
+
'pub-get': { en: 'Installing packages… (may take a few minutes)', pt: 'Instalando pacotes… (pode levar alguns minutos)', es: 'Instalando paquetes… (puede tardar varios minutos)' },
|
|
348
|
+
'slang': { en: 'Generating translations…', pt: 'Gerando traducoes…', es: 'Generando traducciones…' },
|
|
349
|
+
'build-runner': { en: 'Generating code (Riverpod / Freezed)… (may take a few minutes)', pt: 'Gerando codigo (Riverpod / Freezed)… (pode demorar)', es: 'Generando codigo (Riverpod / Freezed)… (puede tardar)' },
|
|
340
350
|
'flutterfire': { en: 'Connecting to Firebase…', pt: 'Conectando ao Firebase…', es: 'Conectando a Firebase…' },
|
|
341
351
|
'deploy': { en: 'Deploying backend to Firebase…', pt: 'Publicando backend no Firebase…', es: 'Desplegando backend en Firebase…' },
|
|
342
352
|
'gcp-project': { en: 'Creating GCP project…', pt: 'Criando projeto GCP…', es: 'Creando proyecto GCP…' },
|
|
@@ -372,31 +382,31 @@ function printCreateFromScratchStatus(result, tr) {
|
|
|
372
382
|
if (result.sha1Skipped) {
|
|
373
383
|
const err = (result.sha1Error || '').replace(/\s+/g, ' ').slice(0, 120);
|
|
374
384
|
if (result.sha1Skipped === 'api_failed') {
|
|
375
|
-
console.log(kleur.yellow(`
|
|
385
|
+
console.log(kleur.yellow(` ${tr('new.sha1.skipped.apiFailed', { error: err })}`));
|
|
376
386
|
} else {
|
|
377
|
-
console.log(kleur.yellow(`
|
|
387
|
+
console.log(kleur.yellow(` ${tr('new.sha1.skipped.other', { reason: result.sha1Skipped })}`));
|
|
378
388
|
}
|
|
379
|
-
console.log(kleur.yellow(`
|
|
389
|
+
console.log(kleur.yellow(` ${tr('new.sha1.addManually')}`));
|
|
380
390
|
if (result.sha1ManualUrl) console.log(kleur.cyan(` ${result.sha1ManualUrl}`));
|
|
381
391
|
} else {
|
|
382
|
-
console.log(kleur.green(`
|
|
392
|
+
console.log(kleur.green(` ${tr('new.sha1.added')}`));
|
|
383
393
|
}
|
|
384
394
|
|
|
385
395
|
if (result.firestoreCreated) {
|
|
386
|
-
console.log(kleur.green(`
|
|
396
|
+
console.log(kleur.green(` ${tr('new.firestore.created')}`));
|
|
387
397
|
} else {
|
|
388
|
-
if (result.firestoreError) console.log(kleur.yellow(`
|
|
389
|
-
else console.log(kleur.yellow(`
|
|
390
|
-
console.log(kleur.yellow(`
|
|
398
|
+
if (result.firestoreError) console.log(kleur.yellow(` ${tr('new.firestore.notCreated.error', { error: (result.firestoreError || '').slice(0, 100) })}`));
|
|
399
|
+
else console.log(kleur.yellow(` ${tr('new.firestore.notCreated')}`));
|
|
400
|
+
console.log(kleur.yellow(` ${tr('new.activateManually')}`));
|
|
391
401
|
console.log(kleur.cyan(` ${result.firestoreUrl}`));
|
|
392
402
|
}
|
|
393
403
|
|
|
394
404
|
if (result.storageCreated) {
|
|
395
|
-
console.log(kleur.green(`
|
|
405
|
+
console.log(kleur.green(` ${tr('new.storage.created')}`));
|
|
396
406
|
} else {
|
|
397
|
-
if (result.storageError) console.log(kleur.yellow(`
|
|
398
|
-
else console.log(kleur.yellow(`
|
|
399
|
-
console.log(kleur.yellow(`
|
|
407
|
+
if (result.storageError) console.log(kleur.yellow(` ${tr('new.storage.notCreated.error', { error: (result.storageError || '').slice(0, 100) })}`));
|
|
408
|
+
else console.log(kleur.yellow(` ${tr('new.storage.notCreated')}`));
|
|
409
|
+
console.log(kleur.yellow(` ${tr('new.activateManually')}`));
|
|
400
410
|
console.log(kleur.cyan(` ${result.storageUrl}`));
|
|
401
411
|
}
|
|
402
412
|
}
|
|
@@ -419,12 +429,18 @@ function printSuccessCard(tr, answers, targetDir) {
|
|
|
419
429
|
console.log(` ${kleur.dim('1.')} ${kleur.dim(tr('new.success.step.cd'))}`);
|
|
420
430
|
console.log(` ${kleur.cyan(`cd ${folderName}`)}`);
|
|
421
431
|
console.log('');
|
|
422
|
-
|
|
432
|
+
let stepNum = 2;
|
|
433
|
+
if (answers.backend === 'firebase') {
|
|
434
|
+
console.log(` ${kleur.dim(`${stepNum++}.`)} ${kleur.dim(tr('new.success.step.deploy'))}`);
|
|
435
|
+
console.log(` ${kleur.cyan('kasy deploy')}`);
|
|
436
|
+
console.log('');
|
|
437
|
+
}
|
|
438
|
+
console.log(` ${kleur.dim(`${stepNum++}.`)} ${kleur.dim(tr('new.success.step.run'))}`);
|
|
423
439
|
console.log(` ${kleur.cyan('kasy run')}`);
|
|
424
|
-
console.log(` ${kleur.dim(
|
|
440
|
+
console.log(` ${kleur.dim(tr('new.success.step.run.vscode'))}`);
|
|
425
441
|
if (consoleUrl) {
|
|
426
442
|
console.log('');
|
|
427
|
-
console.log(` ${kleur.dim(
|
|
443
|
+
console.log(` ${kleur.dim(`${stepNum}.`)} ${kleur.dim(tr('new.success.step.console'))}`);
|
|
428
444
|
console.log(` ${kleur.cyan(consoleUrl)}`);
|
|
429
445
|
}
|
|
430
446
|
console.log('');
|
|
@@ -842,6 +858,7 @@ async function runNew(directory, { language: langHint = null, backend: backendHi
|
|
|
842
858
|
console.log(kleur.bold().yellow(`\n ${tr('new.firebase.create.beforeContinue.title')}`));
|
|
843
859
|
console.log(kleur.gray(` ${tr(step1Key)}`));
|
|
844
860
|
console.log(kleur.cyan(` ${authUrl}`));
|
|
861
|
+
openUrl(authUrl);
|
|
845
862
|
const { ready } = await prompts(
|
|
846
863
|
{
|
|
847
864
|
type: 'confirm',
|
|
@@ -918,6 +935,7 @@ async function runNew(directory, { language: langHint = null, backend: backendHi
|
|
|
918
935
|
console.log(kleur.bold().yellow(`\n ${tr('new.firebase.create.beforeContinue.title')}`));
|
|
919
936
|
console.log(kleur.gray(` ${tr(step1Key)}`));
|
|
920
937
|
console.log(kleur.cyan(` ${authUrl}`));
|
|
938
|
+
openUrl(authUrl);
|
|
921
939
|
const { ready } = await prompts(
|
|
922
940
|
{
|
|
923
941
|
type: 'confirm',
|
|
@@ -1738,7 +1756,7 @@ async function runNew(directory, { language: langHint = null, backend: backendHi
|
|
|
1738
1756
|
// ── FCM Service Account key (best effort via gcloud — Firebase uses ADC, Supabase needs JSON) ──
|
|
1739
1757
|
let fcmServiceAccountJson = null;
|
|
1740
1758
|
if (answers.firebaseProjectId) {
|
|
1741
|
-
const fcmSpinner = ora(kleur.cyan(
|
|
1759
|
+
const fcmSpinner = ora(kleur.cyan(tr('new.fcm.generating'))).start();
|
|
1742
1760
|
const fcmResult = await createFcmServiceAccountKey(answers.firebaseProjectId);
|
|
1743
1761
|
if (fcmResult.ok) {
|
|
1744
1762
|
fcmServiceAccountJson = fcmResult.json;
|
|
@@ -1787,7 +1805,7 @@ async function runNew(directory, { language: langHint = null, backend: backendHi
|
|
|
1787
1805
|
|
|
1788
1806
|
// ── API: FCM Service Account key — save to .kasy/ for server configuration ──
|
|
1789
1807
|
if (backend === 'api' && answers.firebaseProjectId) {
|
|
1790
|
-
const fcmSpinner = ora(kleur.cyan(
|
|
1808
|
+
const fcmSpinner = ora(kleur.cyan(tr('new.fcm.generating'))).start();
|
|
1791
1809
|
const fcmResult = await createFcmServiceAccountKey(answers.firebaseProjectId);
|
|
1792
1810
|
if (fcmResult.ok) {
|
|
1793
1811
|
fcmSpinner.stop();
|
|
@@ -1805,7 +1823,7 @@ async function runNew(directory, { language: langHint = null, backend: backendHi
|
|
|
1805
1823
|
}
|
|
1806
1824
|
}
|
|
1807
1825
|
printStepResult({ name: 'fcm-key-saved', ok: true }, language);
|
|
1808
|
-
console.log(kleur.gray(`
|
|
1826
|
+
console.log(kleur.gray(` ${tr('new.fcm.serverConfig')}`));
|
|
1809
1827
|
} catch (_) {
|
|
1810
1828
|
printStepResult({ name: 'fcm-key-saved', ok: false, detail: 'salvar arquivo de chave falhou' }, language);
|
|
1811
1829
|
}
|
|
@@ -1823,7 +1841,7 @@ async function runNew(directory, { language: langHint = null, backend: backendHi
|
|
|
1823
1841
|
if (answers.firebaseProjectId && firebaseSetupMode === 'existing') {
|
|
1824
1842
|
const flutterfireOkForSha1 = result.steps.find((s) => s.name === 'flutterfire')?.ok;
|
|
1825
1843
|
if (flutterfireOkForSha1) {
|
|
1826
|
-
const sha1Spinner = ora(kleur.cyan(
|
|
1844
|
+
const sha1Spinner = ora(kleur.cyan(tr('new.sha1.registering'))).start();
|
|
1827
1845
|
const sha1Result = await registerDebugSha1(answers.firebaseProjectId, answers.bundleId);
|
|
1828
1846
|
sha1Spinner.stop();
|
|
1829
1847
|
if (sha1Result.ok) {
|
|
@@ -1832,9 +1850,11 @@ async function runNew(directory, { language: langHint = null, backend: backendHi
|
|
|
1832
1850
|
}
|
|
1833
1851
|
// existed === true → already registered, silent success
|
|
1834
1852
|
} else {
|
|
1835
|
-
console.
|
|
1836
|
-
console.log(kleur.yellow(`
|
|
1837
|
-
console.log(kleur.
|
|
1853
|
+
const sha1ManualUrl = `https://console.firebase.google.com/project/${answers.firebaseProjectId}/settings/general/android:${answers.bundleId}`;
|
|
1854
|
+
console.log(kleur.yellow(` ⚠ ${tr('new.sha1.failed', { error: (sha1Result.sha1Error || '').slice(0, 120) })}`));
|
|
1855
|
+
console.log(kleur.yellow(` ${tr('new.sha1.manual')}`));
|
|
1856
|
+
console.log(kleur.cyan(` ${sha1ManualUrl}`));
|
|
1857
|
+
openUrl(sha1ManualUrl);
|
|
1838
1858
|
}
|
|
1839
1859
|
}
|
|
1840
1860
|
}
|
|
@@ -1856,11 +1876,13 @@ async function runNew(directory, { language: langHint = null, backend: backendHi
|
|
|
1856
1876
|
// ── APNs reminder (all backends — required for iOS push notifications) ───────
|
|
1857
1877
|
// Cannot be automated: the .p8 key only exists in Apple Developer Portal.
|
|
1858
1878
|
if (answers.firebaseProjectId) {
|
|
1879
|
+
const apnsUrl = `https://console.firebase.google.com/project/${answers.firebaseProjectId}/settings/cloudmessaging`;
|
|
1859
1880
|
console.log('');
|
|
1860
|
-
console.log(kleur.bold().yellow(`
|
|
1861
|
-
console.log(kleur.gray(`
|
|
1862
|
-
console.log(kleur.gray(`
|
|
1863
|
-
console.log(kleur.cyan(`
|
|
1881
|
+
console.log(kleur.bold().yellow(` ${tr('new.apns.warning')}`));
|
|
1882
|
+
console.log(kleur.gray(` ${tr('new.apns.step1')}`));
|
|
1883
|
+
console.log(kleur.gray(` ${tr('new.apns.step2')}`));
|
|
1884
|
+
console.log(kleur.cyan(` ${apnsUrl}`));
|
|
1885
|
+
openUrl(apnsUrl);
|
|
1864
1886
|
}
|
|
1865
1887
|
|
|
1866
1888
|
printSuccessCard(tr, answers, targetDir);
|
package/lib/commands/update.js
CHANGED
|
@@ -46,14 +46,18 @@ function isNewer(a, b) {
|
|
|
46
46
|
* Collect changelog entries newer than `fromVersion` that affect the given modules.
|
|
47
47
|
* Returns { module: ['v1.2.0: description', ...] }
|
|
48
48
|
*/
|
|
49
|
-
function getChangesSince(changelog, fromVersion, modules) {
|
|
49
|
+
function getChangesSince(changelog, fromVersion, modules, language) {
|
|
50
|
+
const lang = (language || 'en').replace(/-.*/, '').toLowerCase();
|
|
50
51
|
const changes = {};
|
|
51
52
|
for (const [version, entry] of Object.entries(changelog)) {
|
|
52
53
|
if (!isNewer(version, fromVersion || '0.0.0')) continue;
|
|
53
54
|
for (const [mod, description] of Object.entries(entry.modules || {})) {
|
|
54
55
|
if (modules.includes(mod)) {
|
|
56
|
+
const text = typeof description === 'object'
|
|
57
|
+
? (description[lang] || description.en || description.pt || Object.values(description)[0])
|
|
58
|
+
: description;
|
|
55
59
|
if (!changes[mod]) changes[mod] = [];
|
|
56
|
-
changes[mod].push({ version, description });
|
|
60
|
+
changes[mod].push({ version, description: text });
|
|
57
61
|
}
|
|
58
62
|
}
|
|
59
63
|
}
|
|
@@ -331,7 +335,7 @@ async function runUpdate(module, options = {}) {
|
|
|
331
335
|
|
|
332
336
|
// ── Mode B: show status ──────────────────────────────────────────────────────
|
|
333
337
|
const alreadyUpToDate = projectVersion && !isNewer(currentVersion, projectVersion);
|
|
334
|
-
const changes = getChangesSince(changelog, projectVersion, activeModules);
|
|
338
|
+
const changes = getChangesSince(changelog, projectVersion, activeModules, options.language);
|
|
335
339
|
|
|
336
340
|
// Modules in this project that have patch dirs (can be re-applied)
|
|
337
341
|
const patchableModules = [];
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
"1.
|
|
3
|
-
"
|
|
4
|
-
|
|
2
|
+
"1.4.0": {
|
|
3
|
+
"modules": {
|
|
4
|
+
"components": {
|
|
5
|
+
"pt": "Melhorias no WebDevicePreview: minimizar/maximizar, orientação, locale e screenshot",
|
|
6
|
+
"en": "WebDevicePreview improvements: minimize/maximize, orientation, locale and screenshot",
|
|
7
|
+
"es": "Mejoras en WebDevicePreview: minimizar/maximizar, orientación, locale y captura de pantalla"
|
|
8
|
+
}
|
|
9
|
+
}
|
|
5
10
|
}
|
|
6
11
|
}
|
package/lib/utils/i18n.js
CHANGED
|
@@ -551,8 +551,29 @@ const MESSAGES = {
|
|
|
551
551
|
'new.success.title': 'Project created successfully!',
|
|
552
552
|
'new.success.nextSteps': 'Next steps:',
|
|
553
553
|
'new.success.step.cd': 'Go to your project folder:',
|
|
554
|
+
'new.success.step.deploy': 'Deploy your backend to Firebase:',
|
|
554
555
|
'new.success.step.run': 'Run your app (with your configured keys):',
|
|
556
|
+
'new.success.step.run.vscode': '(or F5 in VS Code)',
|
|
555
557
|
'new.success.step.console': 'Open your backend console:',
|
|
558
|
+
'new.fcm.generating': 'Generating FCM Service Account key…',
|
|
559
|
+
'new.sha1.registering': 'Registering SHA-1 for Google Sign-In (Android)…',
|
|
560
|
+
'new.sha1.failed': 'SHA-1 not added automatically: {error}',
|
|
561
|
+
'new.sha1.manual': 'Add it manually so Google Sign-In works on Android:',
|
|
562
|
+
'new.sha1.skipped.apiFailed': 'SHA-1 not added automatically. Reason: {error}',
|
|
563
|
+
'new.sha1.skipped.other': 'SHA-1 not added: {reason}',
|
|
564
|
+
'new.sha1.addManually': 'Add manually: Firebase Console → Project settings → Your apps → Android → Add fingerprint',
|
|
565
|
+
'new.sha1.added': '✓ SHA-1 added (Google Sign-In)',
|
|
566
|
+
'new.firestore.created': '✓ Firestore created automatically',
|
|
567
|
+
'new.firestore.notCreated.error': '⚠ Firestore not created. Reason: {error}',
|
|
568
|
+
'new.firestore.notCreated': '⚠ Firestore not created automatically',
|
|
569
|
+
'new.storage.created': '✓ Firebase Storage created automatically',
|
|
570
|
+
'new.storage.notCreated.error': '⚠ Storage not created. Reason: {error}',
|
|
571
|
+
'new.storage.notCreated': '⚠ Storage not created automatically',
|
|
572
|
+
'new.activateManually': 'Activate manually in the console:',
|
|
573
|
+
'new.fcm.serverConfig': 'Configure on your server: FIREBASE_SERVICE_ACCOUNT_JSON="$(cat .kasy/fcm-service-account.json)"',
|
|
574
|
+
'new.apns.warning': '⚠ iOS Push: configure the APNs Key in Firebase Console',
|
|
575
|
+
'new.apns.step1': '1. Apple Developer Portal → Keys → create APNs Key (.p8)',
|
|
576
|
+
'new.apns.step2': '2. Firebase Console → Cloud Messaging → iOS app → upload APNs Key',
|
|
556
577
|
'new.firebase.create.estimatedTime': '(usually 3–5 min — do not close the terminal)',
|
|
557
578
|
'new.internet.warning': '📶 Make sure you have a stable internet connection — this step requires network access.',
|
|
558
579
|
|
|
@@ -1240,8 +1261,29 @@ const MESSAGES = {
|
|
|
1240
1261
|
'new.success.title': 'Projeto criado com sucesso!',
|
|
1241
1262
|
'new.success.nextSteps': 'Proximos passos:',
|
|
1242
1263
|
'new.success.step.cd': 'Entre na pasta do projeto:',
|
|
1264
|
+
'new.success.step.deploy': 'Publique o backend no Firebase:',
|
|
1243
1265
|
'new.success.step.run': 'Execute o app (com suas chaves configuradas):',
|
|
1266
|
+
'new.success.step.run.vscode': '(ou F5 no VS Code)',
|
|
1244
1267
|
'new.success.step.console': 'Abra o console do backend:',
|
|
1268
|
+
'new.fcm.generating': 'Gerando chave de Service Account FCM…',
|
|
1269
|
+
'new.sha1.registering': 'Registrando SHA-1 para Google Sign-In (Android)…',
|
|
1270
|
+
'new.sha1.failed': 'SHA-1 nao adicionado automaticamente: {error}',
|
|
1271
|
+
'new.sha1.manual': 'Adicione manualmente para o Google Sign-In funcionar no Android:',
|
|
1272
|
+
'new.sha1.skipped.apiFailed': 'SHA-1 nao adicionado automaticamente. Motivo: {error}',
|
|
1273
|
+
'new.sha1.skipped.other': 'SHA-1 nao adicionado: {reason}',
|
|
1274
|
+
'new.sha1.addManually': 'Adicione manualmente: Firebase Console → Configuracoes do projeto → Seus apps → Android → Adicionar impressao digital',
|
|
1275
|
+
'new.sha1.added': '✓ SHA-1 adicionado (Google Sign-In)',
|
|
1276
|
+
'new.firestore.created': '✓ Firestore criado automaticamente',
|
|
1277
|
+
'new.firestore.notCreated.error': '⚠ Firestore nao criado. Motivo: {error}',
|
|
1278
|
+
'new.firestore.notCreated': '⚠ Firestore nao criado automaticamente',
|
|
1279
|
+
'new.storage.created': '✓ Firebase Storage criado automaticamente',
|
|
1280
|
+
'new.storage.notCreated.error': '⚠ Storage nao criado. Motivo: {error}',
|
|
1281
|
+
'new.storage.notCreated': '⚠ Storage nao criado automaticamente',
|
|
1282
|
+
'new.activateManually': 'Ative manualmente no console:',
|
|
1283
|
+
'new.fcm.serverConfig': 'Configure no servidor: FIREBASE_SERVICE_ACCOUNT_JSON="$(cat .kasy/fcm-service-account.json)"',
|
|
1284
|
+
'new.apns.warning': '⚠ Push iOS: configure a APNs Key no Firebase Console',
|
|
1285
|
+
'new.apns.step1': '1. Apple Developer Portal → Keys → criar APNs Key (.p8)',
|
|
1286
|
+
'new.apns.step2': '2. Firebase Console → Cloud Messaging → app iOS → fazer upload da APNs Key',
|
|
1245
1287
|
'new.firebase.create.estimatedTime': '(geralmente 3-5 min — nao feche o terminal)',
|
|
1246
1288
|
'new.internet.warning': '📶 Verifique se voce esta com uma internet estavel — esta etapa precisa de conexao.',
|
|
1247
1289
|
|
|
@@ -1929,8 +1971,29 @@ const MESSAGES = {
|
|
|
1929
1971
|
'new.success.title': '¡Proyecto creado con exito!',
|
|
1930
1972
|
'new.success.nextSteps': 'Proximos pasos:',
|
|
1931
1973
|
'new.success.step.cd': 'Ve a la carpeta del proyecto:',
|
|
1974
|
+
'new.success.step.deploy': 'Despliega el backend en Firebase:',
|
|
1932
1975
|
'new.success.step.run': 'Ejecuta el app (con tus claves configuradas):',
|
|
1976
|
+
'new.success.step.run.vscode': '(o F5 en VS Code)',
|
|
1933
1977
|
'new.success.step.console': 'Abre la consola del backend:',
|
|
1978
|
+
'new.fcm.generating': 'Generando clave de Service Account FCM…',
|
|
1979
|
+
'new.sha1.registering': 'Registrando SHA-1 para Google Sign-In (Android)…',
|
|
1980
|
+
'new.sha1.failed': 'SHA-1 no añadido automaticamente: {error}',
|
|
1981
|
+
'new.sha1.manual': 'Agregalo manualmente para que Google Sign-In funcione en Android:',
|
|
1982
|
+
'new.sha1.skipped.apiFailed': 'SHA-1 no añadido automáticamente. Motivo: {error}',
|
|
1983
|
+
'new.sha1.skipped.other': 'SHA-1 no añadido: {reason}',
|
|
1984
|
+
'new.sha1.addManually': 'Agrega manualmente: Firebase Console → Configuración del proyecto → Tus apps → Android → Agregar huella digital',
|
|
1985
|
+
'new.sha1.added': '✓ SHA-1 añadido (Google Sign-In)',
|
|
1986
|
+
'new.firestore.created': '✓ Firestore creado automáticamente',
|
|
1987
|
+
'new.firestore.notCreated.error': '⚠ Firestore no creado. Motivo: {error}',
|
|
1988
|
+
'new.firestore.notCreated': '⚠ Firestore no creado automáticamente',
|
|
1989
|
+
'new.storage.created': '✓ Firebase Storage creado automáticamente',
|
|
1990
|
+
'new.storage.notCreated.error': '⚠ Storage no creado. Motivo: {error}',
|
|
1991
|
+
'new.storage.notCreated': '⚠ Storage no creado automáticamente',
|
|
1992
|
+
'new.activateManually': 'Activa manualmente en la consola:',
|
|
1993
|
+
'new.fcm.serverConfig': 'Configura en tu servidor: FIREBASE_SERVICE_ACCOUNT_JSON="$(cat .kasy/fcm-service-account.json)"',
|
|
1994
|
+
'new.apns.warning': '⚠ Push iOS: configura la APNs Key en Firebase Console',
|
|
1995
|
+
'new.apns.step1': '1. Apple Developer Portal → Keys → crear APNs Key (.p8)',
|
|
1996
|
+
'new.apns.step2': '2. Firebase Console → Cloud Messaging → app iOS → subir la APNs Key',
|
|
1934
1997
|
'new.firebase.create.estimatedTime': '(generalmente 3-5 min — no cierres la terminal)',
|
|
1935
1998
|
'new.internet.warning': '📶 Asegurate de tener una conexion a internet estable — este paso requiere red.',
|
|
1936
1999
|
|
|
@@ -117,11 +117,12 @@ async function ensureLicenseKey(options = {}) {
|
|
|
117
117
|
|
|
118
118
|
// Key not found or deactivated
|
|
119
119
|
if (!result.valid) {
|
|
120
|
-
setStoredLicenseKey('');
|
|
121
|
-
setCachedValidation({ valid: false });
|
|
122
120
|
if (result.reason === 'inactive') {
|
|
121
|
+
// Admin deactivated this key (fraud/chargeback) — clear it so user can enter a new one
|
|
122
|
+
setStoredLicenseKey('');
|
|
123
123
|
throw new Error(t('license.inactive'));
|
|
124
124
|
}
|
|
125
|
+
// Not found: keep the stored key (might not be in DB yet), never cache failures
|
|
125
126
|
throw new Error(t('license.invalid'));
|
|
126
127
|
}
|
|
127
128
|
|
package/lib/utils/updates.js
CHANGED
|
@@ -73,7 +73,7 @@ async function checkForUpdates() {
|
|
|
73
73
|
kleur.bold(`v${cache.latestVersion} disponível`) +
|
|
74
74
|
kleur.dim(` (você tem v${pkg.version})`) +
|
|
75
75
|
'\n' +
|
|
76
|
-
kleur.dim(' ') + kleur.cyan('
|
|
76
|
+
kleur.dim(' ') + kleur.cyan('kasy upgrade') +
|
|
77
77
|
'\n'
|
|
78
78
|
);
|
|
79
79
|
}
|