kasy-cli 1.10.0 → 1.12.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.
- package/bin/kasy.js +4 -4
- package/lib/commands/check.js +40 -50
- package/lib/commands/deploy.js +25 -25
- package/lib/utils/i18n.js +214 -43
- package/package.json +1 -1
- package/templates/firebase/lib/core/initializer/onstart_widget.dart +7 -1
package/bin/kasy.js
CHANGED
|
@@ -242,14 +242,15 @@ function buildProgram(language) {
|
|
|
242
242
|
const langName = t('cli.command.setup.langName');
|
|
243
243
|
applyLocalizedHelp(
|
|
244
244
|
program
|
|
245
|
-
.command('setup')
|
|
245
|
+
.command('setup', { hidden: true })
|
|
246
246
|
.argument(`[${directoryName}]`, t('cli.command.setup.directoryArg'), '.')
|
|
247
247
|
.option(`-l, --lang <${langName}>`, t('cli.command.setup.langOption'))
|
|
248
248
|
.option('-b, --backend <backend>', t('cli.command.setup.backendOption'))
|
|
249
249
|
.option('--with <features>', t('cli.command.setup.featuresOption'))
|
|
250
250
|
.description(t('cli.command.setup.description'))
|
|
251
251
|
.action(async (directory, options) => {
|
|
252
|
-
// `setup` is an alias for `new` — unified flow
|
|
252
|
+
// `setup` is an alias for `new` — unified flow.
|
|
253
|
+
// Hidden from root help to reduce noise; still callable.
|
|
253
254
|
await runNew(directory, {
|
|
254
255
|
language: options.lang,
|
|
255
256
|
backend: options.backend,
|
|
@@ -516,7 +517,6 @@ function buildProgram(language) {
|
|
|
516
517
|
notificationsCmd
|
|
517
518
|
.command('text')
|
|
518
519
|
.argument('[directory]', 'Project folder (default: current directory)', '.')
|
|
519
|
-
.option('-d, --directory <path>', 'Project folder (default: current directory)')
|
|
520
520
|
.option('--locale <code>', 'i18n files to update: pt, en, es, or all (default: all)', 'all')
|
|
521
521
|
.option('--demo-title <text>', 'Home → Features demo notification title')
|
|
522
522
|
.option('--demo-body <text>', 'Home → Features demo card description / instant notification body')
|
|
@@ -524,7 +524,7 @@ function buildProgram(language) {
|
|
|
524
524
|
.option('--reminder-body <text>', 'Scheduled reminder notification body')
|
|
525
525
|
.description(t('cli.command.notifications.text.description'))
|
|
526
526
|
.action(async (directory, options) => {
|
|
527
|
-
const dir =
|
|
527
|
+
const dir = directory || '.';
|
|
528
528
|
await runNotificationsText(dir, {
|
|
529
529
|
language,
|
|
530
530
|
directory: dir,
|
package/lib/commands/check.js
CHANGED
|
@@ -110,67 +110,67 @@ async function runCheck(options = {}) {
|
|
|
110
110
|
const t = createTranslator(lang);
|
|
111
111
|
|
|
112
112
|
printCompactHeader(t);
|
|
113
|
-
ui.intro('
|
|
113
|
+
ui.intro(t('check.intro'));
|
|
114
114
|
|
|
115
115
|
// ── Detect backend ────────────────────────────────────────────────────────
|
|
116
116
|
const isFirebase = await fs.pathExists(path.join(projectDir, 'firebase.json'));
|
|
117
117
|
const isSupabase = await fs.pathExists(path.join(projectDir, 'supabase'));
|
|
118
118
|
|
|
119
119
|
if (isFirebase && !isSupabase) {
|
|
120
|
-
ok('
|
|
121
|
-
info('
|
|
120
|
+
ok(t('check.firebase.detected'));
|
|
121
|
+
info(t('check.firebase.adcInfo'));
|
|
122
122
|
const firebaseProjectId = await readFirebaseProjectId(projectDir);
|
|
123
123
|
const apnsLines = [
|
|
124
|
-
kleur.yellow(
|
|
125
|
-
kleur.dim('
|
|
124
|
+
kleur.yellow(t('check.apns.warn')),
|
|
125
|
+
kleur.dim(t('check.apns.where')),
|
|
126
126
|
];
|
|
127
127
|
if (firebaseProjectId) {
|
|
128
128
|
apnsLines.push(kleur.cyan(`https://console.firebase.google.com/project/${firebaseProjectId}/settings/cloudmessaging`));
|
|
129
129
|
}
|
|
130
130
|
ui.note(apnsLines.join('\n'));
|
|
131
|
-
ui.outro('
|
|
131
|
+
ui.outro(t('check.done'));
|
|
132
132
|
return;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
if (!isSupabase) {
|
|
136
|
-
ui.log.error('
|
|
137
|
-
ui.cancel('
|
|
136
|
+
ui.log.error(t('check.notKasy'));
|
|
137
|
+
ui.cancel(t('check.aborted'));
|
|
138
138
|
process.exit(1);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
// ── 1. Project linked? ────────────────────────────────────────────────────
|
|
142
142
|
const projectRef = await readProjectRef(projectDir);
|
|
143
143
|
if (!projectRef) {
|
|
144
|
-
fail('
|
|
145
|
-
ui.cancel('
|
|
144
|
+
fail(t('check.supabase.notLinked'), t('check.supabase.notLinkedHint'));
|
|
145
|
+
ui.cancel(t('check.aborted'));
|
|
146
146
|
process.exit(1);
|
|
147
147
|
}
|
|
148
|
-
ok('
|
|
148
|
+
ok(t('check.supabase.linked'), projectRef);
|
|
149
149
|
|
|
150
150
|
// ── Read secrets list ─────────────────────────────────────────────────────
|
|
151
151
|
const spinner = ui.spinner();
|
|
152
|
-
spinner.start('
|
|
152
|
+
spinner.start(t('check.spin.secrets'));
|
|
153
153
|
const secrets = await listSecretNames(projectDir);
|
|
154
|
-
spinner.stop('
|
|
154
|
+
spinner.stop(t('check.spin.secretsDone'));
|
|
155
155
|
|
|
156
156
|
if (!secrets) {
|
|
157
|
-
warn('
|
|
157
|
+
warn(t('check.secrets.listFailed'), t('check.secrets.checkLogin'));
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
// ── 2. FIREBASE_PROJECT_ID ────────────────────────────────────────────────
|
|
161
161
|
const firebaseProjectId = await readFirebaseProjectId(projectDir);
|
|
162
162
|
if (secrets) {
|
|
163
163
|
if (secrets.has('FIREBASE_PROJECT_ID')) {
|
|
164
|
-
ok('
|
|
164
|
+
ok(t('check.fbProjId.ok'));
|
|
165
165
|
} else {
|
|
166
|
-
fail('
|
|
166
|
+
fail(t('check.fbProjId.missing'));
|
|
167
167
|
if (firebaseProjectId) {
|
|
168
|
-
ui.log.message(kleur.gray(
|
|
168
|
+
ui.log.message(kleur.gray(t('check.fbProjId.fixHint', { id: firebaseProjectId })));
|
|
169
169
|
if (options.fix) {
|
|
170
170
|
const r = await runCmd(`supabase secrets set FIREBASE_PROJECT_ID="${firebaseProjectId}"`, projectDir);
|
|
171
171
|
r.ok
|
|
172
|
-
? ok('
|
|
173
|
-
: fail('
|
|
172
|
+
? ok(t('check.fbProjId.fixed'))
|
|
173
|
+
: fail(t('check.fbProjId.fixFailed'), r.error);
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
}
|
|
@@ -179,15 +179,15 @@ async function runCheck(options = {}) {
|
|
|
179
179
|
// ── 3. FIREBASE_SERVICE_ACCOUNT_JSON ─────────────────────────────────────
|
|
180
180
|
if (secrets) {
|
|
181
181
|
if (secrets.has('FIREBASE_SERVICE_ACCOUNT_JSON')) {
|
|
182
|
-
ok('
|
|
182
|
+
ok(t('check.fbSak.ok'));
|
|
183
183
|
} else {
|
|
184
|
-
fail('
|
|
184
|
+
fail(t('check.fbSak.missing'));
|
|
185
185
|
|
|
186
186
|
if (options.fix && firebaseProjectId) {
|
|
187
187
|
const fixSpinner = ui.spinner();
|
|
188
|
-
fixSpinner.start('
|
|
188
|
+
fixSpinner.start(t('check.fbSak.spin'));
|
|
189
189
|
const fcmResult = await createFcmServiceAccountKey(firebaseProjectId);
|
|
190
|
-
fixSpinner.stop('
|
|
190
|
+
fixSpinner.stop(t('check.fbSak.spinDone'));
|
|
191
191
|
|
|
192
192
|
if (fcmResult.ok) {
|
|
193
193
|
const secretSteps = await setSupabaseSecrets(projectDir, {
|
|
@@ -196,62 +196,52 @@ async function runCheck(options = {}) {
|
|
|
196
196
|
});
|
|
197
197
|
const setStep = secretSteps.find((s) => s.name === 'secret FIREBASE_SERVICE_ACCOUNT_JSON');
|
|
198
198
|
setStep?.ok
|
|
199
|
-
? ok('
|
|
200
|
-
: fail('
|
|
199
|
+
? ok(t('check.fbSak.fixed'))
|
|
200
|
+
: fail(t('check.fbSak.fixFailed'), setStep?.error);
|
|
201
201
|
} else {
|
|
202
|
-
fail('
|
|
203
|
-
ui.log.message(kleur.gray(
|
|
204
|
-
'Manual: Firebase Console → Configurações → Contas de serviço → Gerar chave\n' +
|
|
205
|
-
"Depois: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='$(cat chave.json)'"
|
|
206
|
-
));
|
|
202
|
+
fail(t('check.fbSak.genFailed'), fcmResult.error);
|
|
203
|
+
ui.log.message(kleur.gray(t('check.fbSak.manual')));
|
|
207
204
|
}
|
|
208
205
|
} else {
|
|
209
|
-
ui.log.message(kleur.gray(
|
|
210
|
-
'Corrija automaticamente: kasy check --fix\n' +
|
|
211
|
-
'Ou manualmente: Firebase Console → Configurações → Contas de serviço → Gerar chave\n' +
|
|
212
|
-
"Depois: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='$(cat chave.json)'"
|
|
213
|
-
));
|
|
206
|
+
ui.log.message(kleur.gray(t('check.fbSak.hint')));
|
|
214
207
|
}
|
|
215
208
|
}
|
|
216
209
|
}
|
|
217
210
|
|
|
218
211
|
// ── 4. Edge function send-push-notification ────────────────────────────────
|
|
219
212
|
const fnSpinner = ui.spinner();
|
|
220
|
-
fnSpinner.start('
|
|
213
|
+
fnSpinner.start(t('check.fn.spin'));
|
|
221
214
|
const functions = await listDeployedFunctions(projectDir);
|
|
222
|
-
fnSpinner.stop('
|
|
215
|
+
fnSpinner.stop(t('check.fn.spinDone'));
|
|
223
216
|
|
|
224
217
|
if (!functions) {
|
|
225
|
-
warn('
|
|
218
|
+
warn(t('check.fn.listFailed'), t('check.secrets.checkLogin'));
|
|
226
219
|
} else if (functions.has('send-push-notification')) {
|
|
227
|
-
ok('
|
|
220
|
+
ok(t('check.fn.deployed'));
|
|
228
221
|
} else {
|
|
229
|
-
fail('
|
|
222
|
+
fail(t('check.fn.missing'));
|
|
230
223
|
if (options.fix) {
|
|
231
224
|
const deploySpinner = ui.spinner();
|
|
232
|
-
deploySpinner.start('
|
|
225
|
+
deploySpinner.start(t('check.fn.deploySpin'));
|
|
233
226
|
const r = await runCmd('supabase functions deploy send-push-notification', projectDir);
|
|
234
227
|
r.ok
|
|
235
|
-
? deploySpinner.stop('
|
|
236
|
-
: deploySpinner.error(
|
|
228
|
+
? deploySpinner.stop(t('check.fn.deployDone'))
|
|
229
|
+
: deploySpinner.error(`${t('check.fn.deployFailed')}${r.error ? ` — ${r.error}` : ''}`);
|
|
237
230
|
} else {
|
|
238
|
-
ui.log.message(kleur.gray(
|
|
239
|
-
'Corrija automaticamente: kasy check --fix\n' +
|
|
240
|
-
'Ou manualmente: supabase functions deploy send-push-notification'
|
|
241
|
-
));
|
|
231
|
+
ui.log.message(kleur.gray(t('check.fn.hint')));
|
|
242
232
|
}
|
|
243
233
|
}
|
|
244
234
|
|
|
245
235
|
// ── 5. APNs reminder ─────────────────────────────────────────────────────
|
|
246
236
|
const apnsLines = [
|
|
247
|
-
kleur.yellow(
|
|
248
|
-
kleur.dim('
|
|
237
|
+
kleur.yellow(t('check.apns.warn')),
|
|
238
|
+
kleur.dim(t('check.apns.where')),
|
|
249
239
|
];
|
|
250
240
|
if (firebaseProjectId) {
|
|
251
241
|
apnsLines.push(kleur.cyan(`https://console.firebase.google.com/project/${firebaseProjectId}/settings/cloudmessaging`));
|
|
252
242
|
}
|
|
253
243
|
ui.note(apnsLines.join('\n'));
|
|
254
|
-
ui.outro('
|
|
244
|
+
ui.outro(t('check.done'));
|
|
255
245
|
}
|
|
256
246
|
|
|
257
247
|
module.exports = { runCheck };
|
package/lib/commands/deploy.js
CHANGED
|
@@ -123,14 +123,14 @@ async function deployFirebase(projectDir, options, tr) {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
const spinner = ui.spinner();
|
|
126
|
-
spinner.start('
|
|
126
|
+
spinner.start(tr('deploy.firebase.spin'));
|
|
127
127
|
let steps;
|
|
128
128
|
try {
|
|
129
129
|
steps = await runFirebaseDeploy(projectDir, null, firebaseProjectId, {
|
|
130
130
|
functionsRegion,
|
|
131
131
|
onProgress: (key) => { spinner.message(String(key)); },
|
|
132
132
|
});
|
|
133
|
-
spinner.stop('
|
|
133
|
+
spinner.stop(tr('deploy.firebase.spinDone'));
|
|
134
134
|
} catch (err) {
|
|
135
135
|
spinner.error(err.message);
|
|
136
136
|
throw err;
|
|
@@ -145,9 +145,9 @@ async function deployFirebase(projectDir, options, tr) {
|
|
|
145
145
|
// ── APNs reminder — required for iOS push notifications ──────────────────
|
|
146
146
|
// Cannot be automated: the .p8 key only exists in Apple Developer Portal.
|
|
147
147
|
const apnsBody = [
|
|
148
|
-
kleur.yellow('
|
|
149
|
-
kleur.dim('
|
|
150
|
-
kleur.dim('
|
|
148
|
+
kleur.yellow(tr('deploy.apns.title')),
|
|
149
|
+
kleur.dim(tr('deploy.apns.step1')),
|
|
150
|
+
kleur.dim(tr('deploy.apns.step2')),
|
|
151
151
|
kleur.cyan(`https://console.firebase.google.com/project/${firebaseProjectId}/settings/cloudmessaging`),
|
|
152
152
|
].join('\n');
|
|
153
153
|
ui.note(apnsBody);
|
|
@@ -155,28 +155,28 @@ async function deployFirebase(projectDir, options, tr) {
|
|
|
155
155
|
|
|
156
156
|
// ── Supabase deploy ───────────────────────────────────────────────────────────
|
|
157
157
|
|
|
158
|
-
async function deploySupabase(projectDir) {
|
|
158
|
+
async function deploySupabase(projectDir, tr) {
|
|
159
159
|
// ── 1. Get project ref ──────────────────────────────────────────────────
|
|
160
160
|
const projectRef = await readSupabaseProjectRef(projectDir);
|
|
161
161
|
if (!projectRef) {
|
|
162
|
-
ui.log.error('
|
|
163
|
-
ui.log.message(kleur.gray('
|
|
162
|
+
ui.log.error(tr('deploy.supabase.notLinked'));
|
|
163
|
+
ui.log.message(kleur.gray(tr('deploy.supabase.linkHint')));
|
|
164
164
|
process.exit(1);
|
|
165
165
|
}
|
|
166
|
-
ui.log.message(kleur.gray(
|
|
166
|
+
ui.log.message(kleur.gray(tr('deploy.supabase.projectRef', { ref: kleur.cyan(projectRef) })));
|
|
167
167
|
|
|
168
168
|
// ── 2. FCM Service Account JSON ─────────────────────────────────────────
|
|
169
169
|
const alreadySet = await isServiceAccountJsonSet(projectDir);
|
|
170
170
|
if (alreadySet) {
|
|
171
|
-
printStep(true, false, '
|
|
171
|
+
printStep(true, false, tr('deploy.supabase.sakAlready'));
|
|
172
172
|
} else {
|
|
173
173
|
const firebaseProjectId = await readFirebaseProjectId(projectDir);
|
|
174
174
|
|
|
175
175
|
if (firebaseProjectId) {
|
|
176
176
|
const fcmSpinner = ui.spinner();
|
|
177
|
-
fcmSpinner.start(
|
|
177
|
+
fcmSpinner.start(tr('deploy.supabase.sakSpin'));
|
|
178
178
|
const fcmResult = await createFcmServiceAccountKey(firebaseProjectId);
|
|
179
|
-
fcmSpinner.stop('
|
|
179
|
+
fcmSpinner.stop(tr('deploy.supabase.sakSpinDone'));
|
|
180
180
|
|
|
181
181
|
if (fcmResult.ok) {
|
|
182
182
|
const secretSteps = await setSupabaseSecrets(projectDir, {
|
|
@@ -186,23 +186,23 @@ async function deploySupabase(projectDir) {
|
|
|
186
186
|
for (const s of secretSteps) printStep(s.ok, false, s.name, s.error);
|
|
187
187
|
} else {
|
|
188
188
|
printStep(false, false, 'FIREBASE_SERVICE_ACCOUNT_JSON', fcmResult.error);
|
|
189
|
-
ui.log.warn(
|
|
189
|
+
ui.log.warn(tr('deploy.supabase.sakManual'));
|
|
190
190
|
}
|
|
191
191
|
} else {
|
|
192
|
-
printStep(false, false, 'FIREBASE_SERVICE_ACCOUNT_JSON', '
|
|
192
|
+
printStep(false, false, 'FIREBASE_SERVICE_ACCOUNT_JSON', tr('deploy.supabase.sakNoGS'));
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
|
|
196
196
|
// ── 3. Deploy edge functions ────────────────────────────────────────────
|
|
197
197
|
const fnSpinner = ui.spinner();
|
|
198
|
-
fnSpinner.start('
|
|
198
|
+
fnSpinner.start(tr('deploy.supabase.fnSpin'));
|
|
199
199
|
const fnResult = await deployFunctions(projectDir);
|
|
200
|
-
fnSpinner.stop('
|
|
200
|
+
fnSpinner.stop(tr('deploy.supabase.fnSpinDone'));
|
|
201
201
|
|
|
202
202
|
if (Array.isArray(fnResult)) {
|
|
203
203
|
fnResult.forEach((s) => printStep(s.ok, s.skipped, s.name, s.error));
|
|
204
204
|
} else if (fnResult.skipped) {
|
|
205
|
-
printStep(true, true,
|
|
205
|
+
printStep(true, true, tr('deploy.supabase.fnNone'));
|
|
206
206
|
} else {
|
|
207
207
|
printStep(fnResult.ok, false, 'supabase functions deploy', fnResult.error);
|
|
208
208
|
}
|
|
@@ -210,9 +210,9 @@ async function deploySupabase(projectDir) {
|
|
|
210
210
|
// ── 4. APNs reminder ────────────────────────────────────────────────────
|
|
211
211
|
const firebaseProjectId = await readFirebaseProjectId(projectDir);
|
|
212
212
|
const apnsLines = [
|
|
213
|
-
kleur.yellow('
|
|
214
|
-
kleur.dim('
|
|
215
|
-
kleur.dim('
|
|
213
|
+
kleur.yellow(tr('deploy.apns.title')),
|
|
214
|
+
kleur.dim(tr('deploy.apns.step1')),
|
|
215
|
+
kleur.dim(tr('deploy.apns.step2')),
|
|
216
216
|
];
|
|
217
217
|
if (firebaseProjectId) {
|
|
218
218
|
apnsLines.push(kleur.cyan(`https://console.firebase.google.com/project/${firebaseProjectId}/settings/cloudmessaging`));
|
|
@@ -240,17 +240,17 @@ async function runDeployCommand(directory, options = {}, { language: langHint }
|
|
|
240
240
|
|
|
241
241
|
if (isFirebase) {
|
|
242
242
|
printCompactHeader(tr);
|
|
243
|
-
ui.intro('
|
|
243
|
+
ui.intro(tr('deploy.firebase.intro'));
|
|
244
244
|
await deployFirebase(projectDir, options, tr);
|
|
245
|
-
ui.outro('
|
|
245
|
+
ui.outro(tr('deploy.outro'));
|
|
246
246
|
return;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
if (isSupabase) {
|
|
250
250
|
printCompactHeader(tr);
|
|
251
|
-
ui.intro('
|
|
252
|
-
await deploySupabase(projectDir);
|
|
253
|
-
ui.outro('
|
|
251
|
+
ui.intro(tr('deploy.supabase.intro'));
|
|
252
|
+
await deploySupabase(projectDir, tr);
|
|
253
|
+
ui.outro(tr('deploy.outro'));
|
|
254
254
|
return;
|
|
255
255
|
}
|
|
256
256
|
|
package/lib/utils/i18n.js
CHANGED
|
@@ -59,7 +59,7 @@ const MESSAGES = {
|
|
|
59
59
|
'new.checks.environment.done': 'Environment ready',
|
|
60
60
|
'setup.checks.backend.checking': 'Checking {backend} tools',
|
|
61
61
|
'setup.checks.backend.done': '{backend} tools ready',
|
|
62
|
-
'new.checks.firebaseForPush': 'Note: Firebase CLI is required for push notifications (FCM) on all backends.',
|
|
62
|
+
'new.checks.firebaseForPush': 'Note: Firebase CLI is required for push notifications (Firebase Cloud Messaging / FCM) on all backends.',
|
|
63
63
|
'new.checks.requiredBlock': 'Required tools are missing. Install them to continue.',
|
|
64
64
|
'new.checks.installFirebase': 'Firebase: npm i -g firebase-tools && firebase login. FlutterFire: dart pub global activate flutterfire_cli',
|
|
65
65
|
'new.checks.installSupabase': 'Supabase: npm i -g supabase (or brew install supabase/tap/supabase) && supabase login',
|
|
@@ -578,7 +578,7 @@ const MESSAGES = {
|
|
|
578
578
|
'new.success.step.run': 'Run your app (with your configured keys):',
|
|
579
579
|
'new.success.step.run.vscode': '(or F5 in VS Code)',
|
|
580
580
|
'new.success.step.console': 'Open your backend console:',
|
|
581
|
-
'new.fcm.generating': 'Generating
|
|
581
|
+
'new.fcm.generating': 'Generating push notifications key (Firebase Service Account)…',
|
|
582
582
|
'new.sha1.registering': 'Registering SHA-1 for Google Sign-In (Android)…',
|
|
583
583
|
'new.sha1.failed': 'SHA-1 not added automatically: {error}',
|
|
584
584
|
'new.sha1.manual': 'Add it manually so Google Sign-In works on Android:',
|
|
@@ -654,15 +654,15 @@ const MESSAGES = {
|
|
|
654
654
|
'add.error.unknownModule': 'Unknown feature: {module}\nAvailable: {list}',
|
|
655
655
|
'add.alreadyActive': 'Feature "{module}" is already active in this project.',
|
|
656
656
|
'add.applying': 'Adding feature: {module}',
|
|
657
|
-
'add.applyingPatch': 'Applying
|
|
657
|
+
'add.applyingPatch': 'Applying feature changes...',
|
|
658
658
|
'add.patchApplied': 'Patch applied',
|
|
659
659
|
'add.patchFailed': 'Patch failed — check the output above',
|
|
660
|
-
'add.pubGet': '
|
|
660
|
+
'add.pubGet': 'Installing Flutter packages (flutter pub get)...',
|
|
661
661
|
'add.pubGetDone': 'Dependencies updated',
|
|
662
|
-
'add.pubGetFailed': '
|
|
663
|
-
'add.buildRunner': '
|
|
662
|
+
'add.pubGetFailed': 'Failed to install Flutter packages — run `flutter pub get` manually',
|
|
663
|
+
'add.buildRunner': 'Generating code (Riverpod/Freezed)...',
|
|
664
664
|
'add.buildRunnerDone': 'Code generation complete',
|
|
665
|
-
'add.buildRunnerFailed': '
|
|
665
|
+
'add.buildRunnerFailed': 'Code generation failed — run `dart run build_runner build` manually',
|
|
666
666
|
'add.success': 'Feature "{module}" added successfully.',
|
|
667
667
|
'add.cancelled': 'Cancelled.',
|
|
668
668
|
'add.prompt.sentryDsn': 'Sentry DSN (leave blank to configure later):',
|
|
@@ -697,12 +697,12 @@ const MESSAGES = {
|
|
|
697
697
|
'remove.confirm': 'Remove feature "{module}"? This will delete files and dependencies.',
|
|
698
698
|
'remove.cancelled': 'Cancelled.',
|
|
699
699
|
'remove.removing': 'Removing feature: {module}',
|
|
700
|
-
'remove.pubGet': '
|
|
700
|
+
'remove.pubGet': 'Installing Flutter packages (flutter pub get)...',
|
|
701
701
|
'remove.pubGetDone': 'Dependencies updated',
|
|
702
|
-
'remove.pubGetFailed': '
|
|
703
|
-
'remove.buildRunner': '
|
|
702
|
+
'remove.pubGetFailed': 'Failed to install Flutter packages — run `flutter pub get` manually',
|
|
703
|
+
'remove.buildRunner': 'Generating code (Riverpod/Freezed)...',
|
|
704
704
|
'remove.buildRunnerDone': 'Code generation complete',
|
|
705
|
-
'remove.buildRunnerFailed': '
|
|
705
|
+
'remove.buildRunnerFailed': 'Code generation failed — run `dart run build_runner build` manually',
|
|
706
706
|
'remove.success': 'Feature "{module}" removed successfully.',
|
|
707
707
|
'remove.warn.ci': 'CI files removed. If you had custom workflow files, restore them from git.',
|
|
708
708
|
'remove.warn.sentry.shared': 'sentry_flutter kept — still required by active features (revenuecat/facebook).',
|
|
@@ -735,15 +735,72 @@ const MESSAGES = {
|
|
|
735
735
|
'update.applyComponentsFailed': 'Failed to apply update for base components',
|
|
736
736
|
'update.noPatch': 'Feature "{module}" has no files to update (configuration-only feature).',
|
|
737
737
|
'update.noComponentFiles': 'No base component files were found to update.',
|
|
738
|
-
'update.pubGet': '
|
|
738
|
+
'update.pubGet': 'Installing Flutter packages (flutter pub get)...',
|
|
739
739
|
'update.pubGetDone': 'Dependencies updated',
|
|
740
|
-
'update.pubGetFailed': '
|
|
741
|
-
'update.buildRunner': '
|
|
740
|
+
'update.pubGetFailed': 'Failed to install Flutter packages — run `flutter pub get` manually',
|
|
741
|
+
'update.buildRunner': 'Generating code (Riverpod/Freezed)...',
|
|
742
742
|
'update.buildRunnerDone': 'Code generation complete',
|
|
743
|
-
'update.buildRunnerFailed': '
|
|
743
|
+
'update.buildRunnerFailed': 'Code generation failed — run `dart run build_runner build` manually',
|
|
744
744
|
'update.success': 'Feature "{module}" updated successfully.',
|
|
745
745
|
'update.componentsSuccess': 'Base components updated successfully.',
|
|
746
746
|
'update.coreSuccess': 'Core files updated successfully.',
|
|
747
|
+
'check.intro': 'Kasy Check — Push Notifications',
|
|
748
|
+
'check.firebase.detected': 'Firebase backend',
|
|
749
|
+
'check.firebase.adcInfo': 'Firebase uses Application Default Credentials — no extra setup needed.',
|
|
750
|
+
'check.apns.warn': 'iOS push requires APNs Key (cannot be verified via CLI)',
|
|
751
|
+
'check.apns.where': 'Firebase Console → Cloud Messaging → iOS app → APNs Authentication Key',
|
|
752
|
+
'check.done': 'Done',
|
|
753
|
+
'check.notKasy': 'This directory does not look like a Kasy project.',
|
|
754
|
+
'check.aborted': 'Aborted',
|
|
755
|
+
'check.supabase.notLinked': 'Supabase project not linked',
|
|
756
|
+
'check.supabase.notLinkedHint': 'run: supabase link --project-ref YOUR_REF',
|
|
757
|
+
'check.supabase.linked': 'Project linked',
|
|
758
|
+
'check.spin.secrets': 'Checking secrets…',
|
|
759
|
+
'check.spin.secretsDone': 'Secrets checked',
|
|
760
|
+
'check.secrets.listFailed': 'Could not list secrets',
|
|
761
|
+
'check.secrets.checkLogin': 'verify: supabase login',
|
|
762
|
+
'check.fbProjId.ok': 'FIREBASE_PROJECT_ID configured',
|
|
763
|
+
'check.fbProjId.missing': 'FIREBASE_PROJECT_ID missing',
|
|
764
|
+
'check.fbProjId.fixHint': 'Fix: supabase secrets set FIREBASE_PROJECT_ID="{id}"',
|
|
765
|
+
'check.fbProjId.fixed': 'FIREBASE_PROJECT_ID → set automatically',
|
|
766
|
+
'check.fbProjId.fixFailed': 'FIREBASE_PROJECT_ID → failed to set',
|
|
767
|
+
'check.fbSak.ok': 'FIREBASE_SERVICE_ACCOUNT_JSON configured',
|
|
768
|
+
'check.fbSak.missing': 'FIREBASE_SERVICE_ACCOUNT_JSON missing',
|
|
769
|
+
'check.fbSak.spin': 'Generating and setting FCM key…',
|
|
770
|
+
'check.fbSak.spinDone': 'FCM key generated',
|
|
771
|
+
'check.fbSak.fixed': 'FIREBASE_SERVICE_ACCOUNT_JSON → set automatically',
|
|
772
|
+
'check.fbSak.fixFailed': 'FIREBASE_SERVICE_ACCOUNT_JSON → failed to set',
|
|
773
|
+
'check.fbSak.genFailed': 'FIREBASE_SERVICE_ACCOUNT_JSON → could not generate key',
|
|
774
|
+
'check.fbSak.manual': "Manual: Firebase Console → Settings → Service accounts → Generate key\nThen: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='$(cat key.json)'",
|
|
775
|
+
'check.fbSak.hint': "Auto-fix: kasy check --fix\nOr manually: Firebase Console → Settings → Service accounts → Generate key\nThen: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='$(cat key.json)'",
|
|
776
|
+
'check.fn.spin': 'Checking edge functions…',
|
|
777
|
+
'check.fn.spinDone': 'Edge functions checked',
|
|
778
|
+
'check.fn.listFailed': 'Could not list edge functions',
|
|
779
|
+
'check.fn.deployed': 'Edge function send-push-notification deployed',
|
|
780
|
+
'check.fn.missing': 'Edge function send-push-notification not deployed',
|
|
781
|
+
'check.fn.deploySpin': 'Deploying send-push-notification…',
|
|
782
|
+
'check.fn.deployDone': 'send-push-notification → deployed automatically',
|
|
783
|
+
'check.fn.deployFailed': 'send-push-notification → deploy failed',
|
|
784
|
+
'check.fn.hint': 'Auto-fix: kasy check --fix\nOr manually: supabase functions deploy send-push-notification',
|
|
785
|
+
'deploy.firebase.intro': 'Deploy — Firebase',
|
|
786
|
+
'deploy.firebase.spin': 'Deploying Firebase...',
|
|
787
|
+
'deploy.firebase.spinDone': 'Firebase deploy completed',
|
|
788
|
+
'deploy.apns.title': 'iOS push: configure the APNs Key in Firebase Console',
|
|
789
|
+
'deploy.apns.step1': '1. Apple Developer Portal → Keys → create APNs Key (.p8)',
|
|
790
|
+
'deploy.apns.step2': '2. Firebase Console → Cloud Messaging → iOS app → upload APNs Key',
|
|
791
|
+
'deploy.supabase.intro': 'Deploy — Supabase',
|
|
792
|
+
'deploy.supabase.notLinked': 'Supabase project not linked in this directory.',
|
|
793
|
+
'deploy.supabase.linkHint': 'Run: supabase link --project-ref YOUR_PROJECT_REF',
|
|
794
|
+
'deploy.supabase.projectRef': 'Project ref: {ref}',
|
|
795
|
+
'deploy.supabase.sakAlready': 'FIREBASE_SERVICE_ACCOUNT_JSON already configured',
|
|
796
|
+
'deploy.supabase.sakSpin': 'Generating FCM key (Service Account)…',
|
|
797
|
+
'deploy.supabase.sakSpinDone': 'FCM key generated',
|
|
798
|
+
'deploy.supabase.sakManual': "Configure manually: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='...'",
|
|
799
|
+
'deploy.supabase.sakNoGS': 'google-services.json not found — configure manually',
|
|
800
|
+
'deploy.supabase.fnSpin': 'Deploying edge functions…',
|
|
801
|
+
'deploy.supabase.fnSpinDone': 'Edge functions processed',
|
|
802
|
+
'deploy.supabase.fnNone': 'edge functions (none found)',
|
|
803
|
+
'deploy.outro': 'Deploy completed',
|
|
747
804
|
},
|
|
748
805
|
pt: {
|
|
749
806
|
'cli.tagline': 'Crie apps móveis sem dor de configuração',
|
|
@@ -799,7 +856,7 @@ const MESSAGES = {
|
|
|
799
856
|
'new.checks.environment.done': 'Ambiente pronto',
|
|
800
857
|
'setup.checks.backend.checking': 'Verificando ferramentas {backend}',
|
|
801
858
|
'setup.checks.backend.done': 'Ferramentas {backend} prontas',
|
|
802
|
-
'new.checks.firebaseForPush': 'Atenção: Firebase CLI é obrigatório para notificações push (FCM) em todos os backends.',
|
|
859
|
+
'new.checks.firebaseForPush': 'Atenção: Firebase CLI é obrigatório para notificações push (Firebase Cloud Messaging / FCM) em todos os backends.',
|
|
803
860
|
'new.checks.requiredBlock': 'Ferramentas obrigatórias não encontradas. Instale-as para continuar.',
|
|
804
861
|
'new.checks.installFirebase': 'Firebase: npm i -g firebase-tools && firebase login. FlutterFire: dart pub global activate flutterfire_cli',
|
|
805
862
|
'new.checks.installSupabase': 'Supabase: npm i -g supabase (ou brew install supabase/tap/supabase) && supabase login',
|
|
@@ -1394,15 +1451,15 @@ const MESSAGES = {
|
|
|
1394
1451
|
'add.error.unknownModule': 'Feature desconhecida: {module}\nDisponiveis: {list}',
|
|
1395
1452
|
'add.alreadyActive': 'A feature "{module}" já está ativa neste projeto.',
|
|
1396
1453
|
'add.applying': 'Adicionando feature: {module}',
|
|
1397
|
-
'add.applyingPatch': 'Aplicando
|
|
1454
|
+
'add.applyingPatch': 'Aplicando mudanças da feature...',
|
|
1398
1455
|
'add.patchApplied': 'Patch aplicado',
|
|
1399
1456
|
'add.patchFailed': 'Patch falhou — verifique a saída acima',
|
|
1400
|
-
'add.pubGet': '
|
|
1457
|
+
'add.pubGet': 'Instalando pacotes do Flutter (flutter pub get)...',
|
|
1401
1458
|
'add.pubGetDone': 'Dependencias atualizadas',
|
|
1402
|
-
'add.pubGetFailed': '
|
|
1403
|
-
'add.buildRunner': '
|
|
1459
|
+
'add.pubGetFailed': 'Falha ao instalar pacotes do Flutter — execute `flutter pub get` manualmente',
|
|
1460
|
+
'add.buildRunner': 'Gerando código (Riverpod/Freezed)...',
|
|
1404
1461
|
'add.buildRunnerDone': 'Geração de código concluída',
|
|
1405
|
-
'add.buildRunnerFailed': '
|
|
1462
|
+
'add.buildRunnerFailed': 'Geração de código falhou — execute `dart run build_runner build` manualmente',
|
|
1406
1463
|
'add.success': 'Feature "{module}" adicionada com sucesso.',
|
|
1407
1464
|
'add.cancelled': 'Cancelado.',
|
|
1408
1465
|
'add.prompt.sentryDsn': 'Sentry DSN (deixe em branco para configurar depois):',
|
|
@@ -1437,12 +1494,12 @@ const MESSAGES = {
|
|
|
1437
1494
|
'remove.confirm': 'Remover a feature "{module}"? Isso vai deletar arquivos e dependências.',
|
|
1438
1495
|
'remove.cancelled': 'Cancelado.',
|
|
1439
1496
|
'remove.removing': 'Removendo feature: {module}',
|
|
1440
|
-
'remove.pubGet': '
|
|
1497
|
+
'remove.pubGet': 'Instalando pacotes do Flutter (flutter pub get)...',
|
|
1441
1498
|
'remove.pubGetDone': 'Dependencias atualizadas',
|
|
1442
|
-
'remove.pubGetFailed': '
|
|
1443
|
-
'remove.buildRunner': '
|
|
1499
|
+
'remove.pubGetFailed': 'Falha ao instalar pacotes do Flutter — execute `flutter pub get` manualmente',
|
|
1500
|
+
'remove.buildRunner': 'Gerando código (Riverpod/Freezed)...',
|
|
1444
1501
|
'remove.buildRunnerDone': 'Geração de código concluída',
|
|
1445
|
-
'remove.buildRunnerFailed': '
|
|
1502
|
+
'remove.buildRunnerFailed': 'Geração de código falhou — execute `dart run build_runner build` manualmente',
|
|
1446
1503
|
'remove.success': 'Feature "{module}" removida com sucesso.',
|
|
1447
1504
|
'remove.warn.ci': 'Arquivos de CI removidos. Se tinha workflows customizados, restaure-os pelo git.',
|
|
1448
1505
|
'remove.warn.sentry.shared': 'sentry_flutter mantido — ainda necessário para features ativas (revenuecat/facebook).',
|
|
@@ -1475,15 +1532,72 @@ const MESSAGES = {
|
|
|
1475
1532
|
'update.applyComponentsFailed': 'Falha ao aplicar atualização dos componentes base',
|
|
1476
1533
|
'update.noPatch': 'Feature "{module}" não tem arquivos para atualizar (feature so de configuração).',
|
|
1477
1534
|
'update.noComponentFiles': 'Nenhum arquivo de componente base foi encontrado para atualizar.',
|
|
1478
|
-
'update.pubGet': '
|
|
1535
|
+
'update.pubGet': 'Instalando pacotes do Flutter (flutter pub get)...',
|
|
1479
1536
|
'update.pubGetDone': 'Dependencias atualizadas',
|
|
1480
|
-
'update.pubGetFailed': '
|
|
1481
|
-
'update.buildRunner': '
|
|
1537
|
+
'update.pubGetFailed': 'Falha ao instalar pacotes do Flutter — execute `flutter pub get` manualmente',
|
|
1538
|
+
'update.buildRunner': 'Gerando código (Riverpod/Freezed)...',
|
|
1482
1539
|
'update.buildRunnerDone': 'Geração de código concluída',
|
|
1483
|
-
'update.buildRunnerFailed': '
|
|
1540
|
+
'update.buildRunnerFailed': 'Geração de código falhou — execute `dart run build_runner build` manualmente',
|
|
1484
1541
|
'update.success': 'Feature "{module}" atualizada com sucesso.',
|
|
1485
1542
|
'update.componentsSuccess': 'Componentes base atualizados com sucesso.',
|
|
1486
1543
|
'update.coreSuccess': 'Arquivos de core atualizados com sucesso.',
|
|
1544
|
+
'check.intro': 'Kasy Check — Notificações Push',
|
|
1545
|
+
'check.firebase.detected': 'Backend Firebase',
|
|
1546
|
+
'check.firebase.adcInfo': 'Firebase usa Application Default Credentials — nenhuma configuração extra necessária.',
|
|
1547
|
+
'check.apns.warn': 'Push iOS requer APNs Key (não verificável via CLI)',
|
|
1548
|
+
'check.apns.where': 'Firebase Console → Cloud Messaging → app iOS → Chave de autenticação APNs',
|
|
1549
|
+
'check.done': 'Pronto',
|
|
1550
|
+
'check.notKasy': 'Esse diretório não parece ser um projeto Kasy.',
|
|
1551
|
+
'check.aborted': 'Cancelado',
|
|
1552
|
+
'check.supabase.notLinked': 'Projeto Supabase não vinculado',
|
|
1553
|
+
'check.supabase.notLinkedHint': 'execute: supabase link --project-ref SEU_REF',
|
|
1554
|
+
'check.supabase.linked': 'Projeto vinculado',
|
|
1555
|
+
'check.spin.secrets': 'Verificando secrets…',
|
|
1556
|
+
'check.spin.secretsDone': 'Secrets verificados',
|
|
1557
|
+
'check.secrets.listFailed': 'Não foi possível listar secrets',
|
|
1558
|
+
'check.secrets.checkLogin': 'verifique: supabase login',
|
|
1559
|
+
'check.fbProjId.ok': 'FIREBASE_PROJECT_ID configurado',
|
|
1560
|
+
'check.fbProjId.missing': 'FIREBASE_PROJECT_ID ausente',
|
|
1561
|
+
'check.fbProjId.fixHint': 'Corrija: supabase secrets set FIREBASE_PROJECT_ID="{id}"',
|
|
1562
|
+
'check.fbProjId.fixed': 'FIREBASE_PROJECT_ID → configurado automaticamente',
|
|
1563
|
+
'check.fbProjId.fixFailed': 'FIREBASE_PROJECT_ID → falhou ao configurar',
|
|
1564
|
+
'check.fbSak.ok': 'FIREBASE_SERVICE_ACCOUNT_JSON configurado',
|
|
1565
|
+
'check.fbSak.missing': 'FIREBASE_SERVICE_ACCOUNT_JSON ausente',
|
|
1566
|
+
'check.fbSak.spin': 'Gerando e configurando chave FCM…',
|
|
1567
|
+
'check.fbSak.spinDone': 'Chave FCM gerada',
|
|
1568
|
+
'check.fbSak.fixed': 'FIREBASE_SERVICE_ACCOUNT_JSON → configurado automaticamente',
|
|
1569
|
+
'check.fbSak.fixFailed': 'FIREBASE_SERVICE_ACCOUNT_JSON → falhou ao configurar',
|
|
1570
|
+
'check.fbSak.genFailed': 'FIREBASE_SERVICE_ACCOUNT_JSON → não foi possível gerar chave',
|
|
1571
|
+
'check.fbSak.manual': "Manual: Firebase Console → Configurações → Contas de serviço → Gerar chave\nDepois: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='$(cat chave.json)'",
|
|
1572
|
+
'check.fbSak.hint': "Corrija automaticamente: kasy check --fix\nOu manualmente: Firebase Console → Configurações → Contas de serviço → Gerar chave\nDepois: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='$(cat chave.json)'",
|
|
1573
|
+
'check.fn.spin': 'Verificando edge functions…',
|
|
1574
|
+
'check.fn.spinDone': 'Edge functions verificadas',
|
|
1575
|
+
'check.fn.listFailed': 'Não foi possível listar edge functions',
|
|
1576
|
+
'check.fn.deployed': 'Edge function send-push-notification deployada',
|
|
1577
|
+
'check.fn.missing': 'Edge function send-push-notification não deployada',
|
|
1578
|
+
'check.fn.deploySpin': 'Publicando send-push-notification…',
|
|
1579
|
+
'check.fn.deployDone': 'send-push-notification → deployada automaticamente',
|
|
1580
|
+
'check.fn.deployFailed': 'send-push-notification → falhou no deploy',
|
|
1581
|
+
'check.fn.hint': 'Corrija automaticamente: kasy check --fix\nOu manualmente: supabase functions deploy send-push-notification',
|
|
1582
|
+
'deploy.firebase.intro': 'Deploy — Firebase',
|
|
1583
|
+
'deploy.firebase.spin': 'Publicando no Firebase...',
|
|
1584
|
+
'deploy.firebase.spinDone': 'Deploy do Firebase concluído',
|
|
1585
|
+
'deploy.apns.title': 'Push iOS: configure a APNs Key no Firebase Console',
|
|
1586
|
+
'deploy.apns.step1': '1. Apple Developer Portal → Keys → criar APNs Key (.p8)',
|
|
1587
|
+
'deploy.apns.step2': '2. Firebase Console → Cloud Messaging → app iOS → upload da APNs Key',
|
|
1588
|
+
'deploy.supabase.intro': 'Deploy — Supabase',
|
|
1589
|
+
'deploy.supabase.notLinked': 'Projeto Supabase não está vinculado neste diretório.',
|
|
1590
|
+
'deploy.supabase.linkHint': 'Execute: supabase link --project-ref SEU_PROJECT_REF',
|
|
1591
|
+
'deploy.supabase.projectRef': 'Project ref: {ref}',
|
|
1592
|
+
'deploy.supabase.sakAlready': 'FIREBASE_SERVICE_ACCOUNT_JSON já configurado',
|
|
1593
|
+
'deploy.supabase.sakSpin': 'Gerando chave FCM (Service Account)…',
|
|
1594
|
+
'deploy.supabase.sakSpinDone': 'Chave FCM gerada',
|
|
1595
|
+
'deploy.supabase.sakManual': "Configure manualmente: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='...'",
|
|
1596
|
+
'deploy.supabase.sakNoGS': 'google-services.json não encontrado — configure manualmente',
|
|
1597
|
+
'deploy.supabase.fnSpin': 'Publicando edge functions…',
|
|
1598
|
+
'deploy.supabase.fnSpinDone': 'Edge functions processadas',
|
|
1599
|
+
'deploy.supabase.fnNone': 'edge functions (nenhuma encontrada)',
|
|
1600
|
+
'deploy.outro': 'Deploy concluído',
|
|
1487
1601
|
},
|
|
1488
1602
|
es: {
|
|
1489
1603
|
'cli.tagline': 'Crea apps móviles sin dolor de configuración',
|
|
@@ -1539,7 +1653,7 @@ const MESSAGES = {
|
|
|
1539
1653
|
'new.checks.environment.done': 'Entorno listo',
|
|
1540
1654
|
'setup.checks.backend.checking': 'Verificando herramientas {backend}',
|
|
1541
1655
|
'setup.checks.backend.done': 'Herramientas {backend} listas',
|
|
1542
|
-
'new.checks.firebaseForPush': 'Nota: Firebase CLI es obligatorio para notificaciones push (FCM) en todos los backends.',
|
|
1656
|
+
'new.checks.firebaseForPush': 'Nota: Firebase CLI es obligatorio para notificaciones push (Firebase Cloud Messaging / FCM) en todos los backends.',
|
|
1543
1657
|
'new.checks.requiredBlock': 'Faltan herramientas obligatorias. Instalalas para continuar.',
|
|
1544
1658
|
'new.checks.installFirebase': 'Firebase: npm i -g firebase-tools && firebase login. FlutterFire: dart pub global activate flutterfire_cli',
|
|
1545
1659
|
'new.checks.installSupabase': 'Supabase: npm i -g supabase (o brew install supabase/tap/supabase) && supabase login',
|
|
@@ -2134,15 +2248,15 @@ const MESSAGES = {
|
|
|
2134
2248
|
'add.error.unknownModule': 'Feature desconocida: {module}\nDisponibles: {list}',
|
|
2135
2249
|
'add.alreadyActive': 'La feature "{module}" ya está activa en este proyecto.',
|
|
2136
2250
|
'add.applying': 'Agregando feature: {module}',
|
|
2137
|
-
'add.applyingPatch': 'Aplicando
|
|
2251
|
+
'add.applyingPatch': 'Aplicando cambios de la feature...',
|
|
2138
2252
|
'add.patchApplied': 'Patch aplicado',
|
|
2139
2253
|
'add.patchFailed': 'Patch fallo — revisa la salida anterior',
|
|
2140
|
-
'add.pubGet': '
|
|
2254
|
+
'add.pubGet': 'Instalando paquetes de Flutter (flutter pub get)...',
|
|
2141
2255
|
'add.pubGetDone': 'Dependencias actualizadas',
|
|
2142
|
-
'add.pubGetFailed': '
|
|
2143
|
-
'add.buildRunner': '
|
|
2256
|
+
'add.pubGetFailed': 'Falló al instalar paquetes de Flutter — ejecuta `flutter pub get` manualmente',
|
|
2257
|
+
'add.buildRunner': 'Generando código (Riverpod/Freezed)...',
|
|
2144
2258
|
'add.buildRunnerDone': 'Generación de código completada',
|
|
2145
|
-
'add.buildRunnerFailed': '
|
|
2259
|
+
'add.buildRunnerFailed': 'Generación de código falló — ejecuta `dart run build_runner build` manualmente',
|
|
2146
2260
|
'add.success': 'Feature "{module}" agregada exitosamente.',
|
|
2147
2261
|
'add.cancelled': 'Cancelado.',
|
|
2148
2262
|
'add.prompt.sentryDsn': 'Sentry DSN (deja en blanco para configurar después):',
|
|
@@ -2177,12 +2291,12 @@ const MESSAGES = {
|
|
|
2177
2291
|
'remove.confirm': 'Eliminar la feature "{module}"? Esto borrara archivos y dependencias.',
|
|
2178
2292
|
'remove.cancelled': 'Cancelado.',
|
|
2179
2293
|
'remove.removing': 'Eliminando feature: {module}',
|
|
2180
|
-
'remove.pubGet': '
|
|
2294
|
+
'remove.pubGet': 'Instalando paquetes de Flutter (flutter pub get)...',
|
|
2181
2295
|
'remove.pubGetDone': 'Dependencias actualizadas',
|
|
2182
|
-
'remove.pubGetFailed': '
|
|
2183
|
-
'remove.buildRunner': '
|
|
2296
|
+
'remove.pubGetFailed': 'Falló al instalar paquetes de Flutter — ejecuta `flutter pub get` manualmente',
|
|
2297
|
+
'remove.buildRunner': 'Generando código (Riverpod/Freezed)...',
|
|
2184
2298
|
'remove.buildRunnerDone': 'Generación de código completada',
|
|
2185
|
-
'remove.buildRunnerFailed': '
|
|
2299
|
+
'remove.buildRunnerFailed': 'Generación de código falló — ejecuta `dart run build_runner build` manualmente',
|
|
2186
2300
|
'remove.success': 'Feature "{module}" eliminada exitosamente.',
|
|
2187
2301
|
'remove.warn.ci': 'Archivos de CI eliminados. Si tenias workflows personalizados, restauralos desde git.',
|
|
2188
2302
|
'remove.warn.sentry.shared': 'sentry_flutter conservado — todavia requerido por features activas (revenuecat/facebook).',
|
|
@@ -2215,15 +2329,72 @@ const MESSAGES = {
|
|
|
2215
2329
|
'update.applyComponentsFailed': 'Error al aplicar actualización de componentes base',
|
|
2216
2330
|
'update.noPatch': 'La feature "{module}" no tiene archivos para actualizar (feature solo de configuración).',
|
|
2217
2331
|
'update.noComponentFiles': 'No se encontraron archivos de componentes base para actualizar.',
|
|
2218
|
-
'update.pubGet': '
|
|
2332
|
+
'update.pubGet': 'Instalando paquetes de Flutter (flutter pub get)...',
|
|
2219
2333
|
'update.pubGetDone': 'Dependencias actualizadas',
|
|
2220
|
-
'update.pubGetFailed': '
|
|
2221
|
-
'update.buildRunner': '
|
|
2334
|
+
'update.pubGetFailed': 'Falló al instalar paquetes de Flutter — ejecuta `flutter pub get` manualmente',
|
|
2335
|
+
'update.buildRunner': 'Generando código (Riverpod/Freezed)...',
|
|
2222
2336
|
'update.buildRunnerDone': 'Generación de código completada',
|
|
2223
|
-
'update.buildRunnerFailed': '
|
|
2337
|
+
'update.buildRunnerFailed': 'Generación de código falló — ejecuta `dart run build_runner build` manualmente',
|
|
2224
2338
|
'update.success': 'Feature "{module}" actualizada exitosamente.',
|
|
2225
2339
|
'update.componentsSuccess': 'Componentes base actualizados exitosamente.',
|
|
2226
2340
|
'update.coreSuccess': 'Archivos de core actualizados exitosamente.',
|
|
2341
|
+
'check.intro': 'Kasy Check — Notificaciones Push',
|
|
2342
|
+
'check.firebase.detected': 'Backend Firebase',
|
|
2343
|
+
'check.firebase.adcInfo': 'Firebase usa Application Default Credentials — no requiere configuración extra.',
|
|
2344
|
+
'check.apns.warn': 'Push iOS requiere APNs Key (no verificable via CLI)',
|
|
2345
|
+
'check.apns.where': 'Firebase Console → Cloud Messaging → app iOS → Clave de autenticación APNs',
|
|
2346
|
+
'check.done': 'Listo',
|
|
2347
|
+
'check.notKasy': 'Este directorio no parece ser un proyecto Kasy.',
|
|
2348
|
+
'check.aborted': 'Cancelado',
|
|
2349
|
+
'check.supabase.notLinked': 'Proyecto Supabase no vinculado',
|
|
2350
|
+
'check.supabase.notLinkedHint': 'ejecuta: supabase link --project-ref TU_REF',
|
|
2351
|
+
'check.supabase.linked': 'Proyecto vinculado',
|
|
2352
|
+
'check.spin.secrets': 'Verificando secrets…',
|
|
2353
|
+
'check.spin.secretsDone': 'Secrets verificados',
|
|
2354
|
+
'check.secrets.listFailed': 'No se pudo listar los secrets',
|
|
2355
|
+
'check.secrets.checkLogin': 'verifica: supabase login',
|
|
2356
|
+
'check.fbProjId.ok': 'FIREBASE_PROJECT_ID configurado',
|
|
2357
|
+
'check.fbProjId.missing': 'FIREBASE_PROJECT_ID ausente',
|
|
2358
|
+
'check.fbProjId.fixHint': 'Corrige: supabase secrets set FIREBASE_PROJECT_ID="{id}"',
|
|
2359
|
+
'check.fbProjId.fixed': 'FIREBASE_PROJECT_ID → configurado automáticamente',
|
|
2360
|
+
'check.fbProjId.fixFailed': 'FIREBASE_PROJECT_ID → falló al configurar',
|
|
2361
|
+
'check.fbSak.ok': 'FIREBASE_SERVICE_ACCOUNT_JSON configurado',
|
|
2362
|
+
'check.fbSak.missing': 'FIREBASE_SERVICE_ACCOUNT_JSON ausente',
|
|
2363
|
+
'check.fbSak.spin': 'Generando y configurando clave FCM…',
|
|
2364
|
+
'check.fbSak.spinDone': 'Clave FCM generada',
|
|
2365
|
+
'check.fbSak.fixed': 'FIREBASE_SERVICE_ACCOUNT_JSON → configurado automáticamente',
|
|
2366
|
+
'check.fbSak.fixFailed': 'FIREBASE_SERVICE_ACCOUNT_JSON → falló al configurar',
|
|
2367
|
+
'check.fbSak.genFailed': 'FIREBASE_SERVICE_ACCOUNT_JSON → no se pudo generar la clave',
|
|
2368
|
+
'check.fbSak.manual': "Manual: Firebase Console → Configuración → Cuentas de servicio → Generar clave\nLuego: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='$(cat clave.json)'",
|
|
2369
|
+
'check.fbSak.hint': "Corrige automáticamente: kasy check --fix\nO manualmente: Firebase Console → Configuración → Cuentas de servicio → Generar clave\nLuego: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='$(cat clave.json)'",
|
|
2370
|
+
'check.fn.spin': 'Verificando edge functions…',
|
|
2371
|
+
'check.fn.spinDone': 'Edge functions verificadas',
|
|
2372
|
+
'check.fn.listFailed': 'No se pudo listar edge functions',
|
|
2373
|
+
'check.fn.deployed': 'Edge function send-push-notification publicada',
|
|
2374
|
+
'check.fn.missing': 'Edge function send-push-notification no publicada',
|
|
2375
|
+
'check.fn.deploySpin': 'Publicando send-push-notification…',
|
|
2376
|
+
'check.fn.deployDone': 'send-push-notification → publicada automáticamente',
|
|
2377
|
+
'check.fn.deployFailed': 'send-push-notification → falló el deploy',
|
|
2378
|
+
'check.fn.hint': 'Corrige automáticamente: kasy check --fix\nO manualmente: supabase functions deploy send-push-notification',
|
|
2379
|
+
'deploy.firebase.intro': 'Deploy — Firebase',
|
|
2380
|
+
'deploy.firebase.spin': 'Publicando en Firebase...',
|
|
2381
|
+
'deploy.firebase.spinDone': 'Deploy de Firebase completado',
|
|
2382
|
+
'deploy.apns.title': 'Push iOS: configura la APNs Key en Firebase Console',
|
|
2383
|
+
'deploy.apns.step1': '1. Apple Developer Portal → Keys → crear APNs Key (.p8)',
|
|
2384
|
+
'deploy.apns.step2': '2. Firebase Console → Cloud Messaging → app iOS → subir APNs Key',
|
|
2385
|
+
'deploy.supabase.intro': 'Deploy — Supabase',
|
|
2386
|
+
'deploy.supabase.notLinked': 'Proyecto Supabase no vinculado en este directorio.',
|
|
2387
|
+
'deploy.supabase.linkHint': 'Ejecuta: supabase link --project-ref TU_PROJECT_REF',
|
|
2388
|
+
'deploy.supabase.projectRef': 'Project ref: {ref}',
|
|
2389
|
+
'deploy.supabase.sakAlready': 'FIREBASE_SERVICE_ACCOUNT_JSON ya configurado',
|
|
2390
|
+
'deploy.supabase.sakSpin': 'Generando clave FCM (Service Account)…',
|
|
2391
|
+
'deploy.supabase.sakSpinDone': 'Clave FCM generada',
|
|
2392
|
+
'deploy.supabase.sakManual': "Configura manualmente: supabase secrets set FIREBASE_SERVICE_ACCOUNT_JSON='...'",
|
|
2393
|
+
'deploy.supabase.sakNoGS': 'google-services.json no encontrado — configura manualmente',
|
|
2394
|
+
'deploy.supabase.fnSpin': 'Publicando edge functions…',
|
|
2395
|
+
'deploy.supabase.fnSpinDone': 'Edge functions procesadas',
|
|
2396
|
+
'deploy.supabase.fnNone': 'edge functions (ninguna encontrada)',
|
|
2397
|
+
'deploy.outro': 'Deploy completado',
|
|
2227
2398
|
}
|
|
2228
2399
|
};
|
|
2229
2400
|
|
package/package.json
CHANGED
|
@@ -64,7 +64,13 @@ class _InitializerState extends ConsumerState<Initializer> {
|
|
|
64
64
|
Sentry.captureException(e, stackTrace: s);
|
|
65
65
|
ref.read(onStartProvider.notifier).notifyError(e.toString());
|
|
66
66
|
} finally {
|
|
67
|
-
|
|
67
|
+
// Defer splash removal until after the next frame is painted so the
|
|
68
|
+
// onReady widget renders under the splash before it disappears.
|
|
69
|
+
// Without this, the splash is removed before the new frame paints,
|
|
70
|
+
// briefly revealing the onLoading widget (visible flash).
|
|
71
|
+
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
72
|
+
FlutterNativeSplash.remove();
|
|
73
|
+
});
|
|
68
74
|
}
|
|
69
75
|
});
|
|
70
76
|
}
|