@neetru/cli 2.4.0 → 2.6.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.
@@ -0,0 +1,328 @@
1
+ /**
2
+ * `neetru bootstrap` — checa o ambiente de dev e instala/sugere TUDO que
3
+ * um dev Neetru precisa pra rodar o ecossistema do zero.
4
+ *
5
+ * Diferente de `neetru doctor` (só diagnóstico, 5 checks rapidíssimos) e de
6
+ * `neetru init`/`neetru new` (só scaffold do projeto), o `bootstrap`:
7
+ *
8
+ * 1. Verifica binários do sistema (Node, npm, git, gcloud, docker, firebase).
9
+ * 2. Pra deps Node críticas — auto-install no `cwd` se há `package.json`.
10
+ * 3. Pra binários do SO — NÃO auto-install (risco em máquinas variadas);
11
+ * mostra a linha exata pra instalar em macOS/Linux/Windows.
12
+ * 4. Faz login GCP (`gcloud auth application-default login`) se ausente.
13
+ * 5. Roda `neetru doctor` no final pra confirmar estado.
14
+ *
15
+ * Filosofia: o comando NUNCA faz mudança não-autorizada. Pra cada coisa
16
+ * que precisa instalar, mostra o comando e pede `y/N` (a menos que `--yes`).
17
+ * Em CI roda só os auto-installs seguros (`npm ci`).
18
+ *
19
+ * Uso:
20
+ * neetru bootstrap # interativo
21
+ * neetru bootstrap --yes # aceita todos os auto-installs
22
+ * neetru bootstrap --check # só lista o que falta, sem instalar nada
23
+ * neetru bootstrap --json # output JSON pra automação
24
+ */
25
+ import { spawn, spawnSync } from 'node:child_process';
26
+ import * as fsSync from 'node:fs';
27
+ import * as path from 'node:path';
28
+ import { createInterface } from 'node:readline';
29
+ import chalk from 'chalk';
30
+ import { log } from '../utils/logger.js';
31
+ function detectVersion(bin, args = ['--version']) {
32
+ try {
33
+ const r = spawnSync(bin, args, { encoding: 'utf8', timeout: 5000 });
34
+ if (r.status !== 0)
35
+ return null;
36
+ const out = (r.stdout || r.stderr || '').trim();
37
+ // Pega a primeira string que parece versão semver (X.Y.Z)
38
+ const m = out.match(/\d+\.\d+(\.\d+)?/);
39
+ return m ? m[0] : out.split('\n')[0]?.trim() || null;
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ function meetsMinor(version, min) {
46
+ if (!version)
47
+ return false;
48
+ const [a, b] = version.split('.').map((n) => parseInt(n, 10));
49
+ const [ma, mb] = min.split('.').map((n) => parseInt(n, 10));
50
+ if (Number.isNaN(a) || Number.isNaN(ma))
51
+ return false;
52
+ if (a > ma)
53
+ return true;
54
+ if (a < ma)
55
+ return false;
56
+ return (b ?? 0) >= (mb ?? 0);
57
+ }
58
+ function platformCmd(installCmd) {
59
+ if (!installCmd)
60
+ return null;
61
+ const p = process.platform;
62
+ return installCmd[p] ?? installCmd.linux ?? null;
63
+ }
64
+ function promptYesNo(question) {
65
+ if (!process.stdin.isTTY)
66
+ return Promise.resolve(false);
67
+ return new Promise((resolve) => {
68
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
69
+ rl.question(` ${question} [y/N] `, (answer) => {
70
+ rl.close();
71
+ const a = answer.trim().toLowerCase();
72
+ resolve(a === 'y' || a === 'yes');
73
+ });
74
+ });
75
+ }
76
+ function runSpawn(cmd, args, opts = {}) {
77
+ return new Promise((resolve) => {
78
+ const p = spawn(cmd, args, {
79
+ cwd: opts.cwd,
80
+ stdio: opts.quiet ? 'pipe' : 'inherit',
81
+ shell: process.platform === 'win32',
82
+ });
83
+ p.on('close', (code) => resolve(code ?? 1));
84
+ p.on('error', () => resolve(1));
85
+ });
86
+ }
87
+ /* ─── Checks individuais ─────────────────────────────────────────────── */
88
+ function checkNode() {
89
+ const v = detectVersion('node', ['--version']);
90
+ const min = '22.0';
91
+ const ok = meetsMinor(v, min);
92
+ return {
93
+ name: 'Node.js',
94
+ status: !v ? 'missing' : ok ? 'ok' : 'outdated',
95
+ detected: v ?? undefined,
96
+ required: `>=${min} LTS`,
97
+ required_hard: true,
98
+ installCmd: {
99
+ darwin: 'brew install node@22',
100
+ linux: 'curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - && sudo apt-get install -y nodejs',
101
+ win32: 'choco install nodejs-lts # ou: winget install OpenJS.NodeJS.LTS',
102
+ },
103
+ detail: !v ? 'binário ausente' : ok ? undefined : `versão ${v} é antiga`,
104
+ };
105
+ }
106
+ function checkNpm() {
107
+ const v = detectVersion('npm', ['--version']);
108
+ return {
109
+ name: 'npm',
110
+ status: v ? 'ok' : 'missing',
111
+ detected: v ?? undefined,
112
+ required: '>=10.0',
113
+ required_hard: true,
114
+ detail: !v ? 'vem junto com Node — reinstale Node' : undefined,
115
+ };
116
+ }
117
+ function checkGit() {
118
+ const v = detectVersion('git', ['--version']);
119
+ return {
120
+ name: 'git',
121
+ status: v ? 'ok' : 'missing',
122
+ detected: v ?? undefined,
123
+ required: '>=2.0',
124
+ required_hard: true,
125
+ installCmd: {
126
+ darwin: 'brew install git # ou já vem com Xcode Command Line Tools',
127
+ linux: 'sudo apt-get install -y git',
128
+ win32: 'winget install Git.Git # ou: choco install git',
129
+ },
130
+ };
131
+ }
132
+ function checkGcloud() {
133
+ const v = detectVersion('gcloud', ['--version']);
134
+ return {
135
+ name: 'gcloud (Google Cloud CLI)',
136
+ status: v ? 'ok' : 'missing',
137
+ detected: v ?? undefined,
138
+ required: 'qualquer recente',
139
+ required_hard: false,
140
+ installCmd: {
141
+ darwin: 'brew install --cask google-cloud-sdk',
142
+ linux: 'curl https://sdk.cloud.google.com | bash && exec -l $SHELL',
143
+ win32: 'winget install Google.CloudSDK # ou baixe de https://cloud.google.com/sdk/docs/install',
144
+ },
145
+ detail: !v
146
+ ? 'opcional pra dev local — obrigatório se for fazer deploy/admin GCP'
147
+ : undefined,
148
+ };
149
+ }
150
+ function checkDocker() {
151
+ const v = detectVersion('docker', ['--version']);
152
+ return {
153
+ name: 'Docker',
154
+ status: v ? 'ok' : 'missing',
155
+ detected: v ?? undefined,
156
+ required: 'qualquer recente',
157
+ required_hard: false,
158
+ installCmd: {
159
+ darwin: 'brew install --cask docker # ou Docker Desktop manual',
160
+ linux: 'curl -fsSL https://get.docker.com | sh',
161
+ win32: 'winget install Docker.DockerDesktop',
162
+ },
163
+ detail: !v
164
+ ? 'opcional — usado pra build local de imagens antes de push pra Artifact Registry'
165
+ : undefined,
166
+ };
167
+ }
168
+ function checkFirebase() {
169
+ const v = detectVersion('firebase', ['--version']);
170
+ return {
171
+ name: 'Firebase CLI',
172
+ status: v ? 'ok' : 'missing',
173
+ detected: v ?? undefined,
174
+ required: '>=13',
175
+ required_hard: false,
176
+ installCmd: {
177
+ npm: 'npm install -g firebase-tools',
178
+ },
179
+ detail: !v
180
+ ? 'opcional — usado pra deploy de Cloud Functions + Firestore rules/indexes'
181
+ : undefined,
182
+ };
183
+ }
184
+ function checkProjectDeps(cwd) {
185
+ const pkgPath = path.join(cwd, 'package.json');
186
+ if (!fsSync.existsSync(pkgPath)) {
187
+ return {
188
+ name: 'deps NPM do projeto',
189
+ status: 'unknown',
190
+ detail: 'sem package.json no cwd — fora de um projeto Neetru',
191
+ };
192
+ }
193
+ const nodeModulesPath = path.join(cwd, 'node_modules');
194
+ const installed = fsSync.existsSync(nodeModulesPath);
195
+ return {
196
+ name: 'deps NPM do projeto',
197
+ status: installed ? 'ok' : 'missing',
198
+ required_hard: true,
199
+ detail: installed
200
+ ? `${path.basename(cwd)}/node_modules presente`
201
+ : `${path.basename(cwd)}/node_modules ausente — rodar npm ci`,
202
+ };
203
+ }
204
+ function checkGcloudAdc() {
205
+ const home = process.env.HOME || process.env.USERPROFILE || '';
206
+ const adcPath = path.join(home, process.platform === 'win32'
207
+ ? 'AppData\\Roaming\\gcloud\\application_default_credentials.json'
208
+ : '.config/gcloud/application_default_credentials.json');
209
+ const present = fsSync.existsSync(adcPath);
210
+ return {
211
+ name: 'GCP Application Default Credentials',
212
+ status: present ? 'ok' : 'missing',
213
+ required_hard: false,
214
+ detail: present
215
+ ? 'ADC configurado'
216
+ : 'pra acessar GCP APIs localmente: gcloud auth application-default login',
217
+ };
218
+ }
219
+ /* ─── Render ─────────────────────────────────────────────────────────── */
220
+ function statusIcon(s) {
221
+ if (s === 'ok')
222
+ return chalk.green('✓');
223
+ if (s === 'missing')
224
+ return chalk.red('✗');
225
+ if (s === 'outdated')
226
+ return chalk.yellow('!');
227
+ return chalk.dim('—');
228
+ }
229
+ function renderTable(report) {
230
+ log.info(chalk.bold('\n Estado do ambiente Neetru'));
231
+ log.info(` ${chalk.dim('OS:')} ${report.os} ${chalk.dim('cwd:')} ${report.cwd}\n`);
232
+ for (const t of report.tools) {
233
+ const icon = statusIcon(t.status);
234
+ const required = t.required_hard ? chalk.red('[obrigatório]') : chalk.dim('[opcional]');
235
+ const detected = t.detected ? chalk.dim(`(${t.detected})`) : '';
236
+ log.info(` ${icon} ${t.name.padEnd(40)} ${required} ${detected}`);
237
+ if (t.detail)
238
+ log.info(` ${chalk.dim(t.detail)}`);
239
+ if (t.status !== 'ok' && t.installCmd) {
240
+ const cmd = platformCmd(t.installCmd) ?? t.installCmd.npm;
241
+ if (cmd)
242
+ log.info(` ${chalk.cyan('→ ' + cmd)}`);
243
+ }
244
+ }
245
+ }
246
+ /* ─── Run ────────────────────────────────────────────────────────────── */
247
+ export async function runBootstrap(opts = {}) {
248
+ const cwd = opts.cwd ?? process.cwd();
249
+ const tools = [
250
+ checkNode(),
251
+ checkNpm(),
252
+ checkGit(),
253
+ checkGcloud(),
254
+ checkDocker(),
255
+ checkFirebase(),
256
+ checkProjectDeps(cwd),
257
+ checkGcloudAdc(),
258
+ ];
259
+ const report = {
260
+ ok: tools.every((t) => !t.required_hard || t.status === 'ok'),
261
+ cwd,
262
+ os: process.platform,
263
+ tools,
264
+ actionsTaken: [],
265
+ pendingActions: tools
266
+ .filter((t) => t.status !== 'ok' && (t.installCmd?.npm || platformCmd(t.installCmd)))
267
+ .map((t) => ({
268
+ tool: t.name,
269
+ cmd: (platformCmd(t.installCmd) ?? t.installCmd?.npm) || '(sem comando sugerido)',
270
+ })),
271
+ };
272
+ if (opts.json) {
273
+ console.log(JSON.stringify(report, null, 2));
274
+ return;
275
+ }
276
+ renderTable(report);
277
+ // ─── Auto-actions (só com confirmação OU --yes) ────────────────────
278
+ if (opts.check) {
279
+ log.info('\n Modo --check — nenhuma ação tomada.');
280
+ process.exit(report.ok ? 0 : 1);
281
+ }
282
+ // Ação 1: npm ci se cwd tem package.json mas falta node_modules
283
+ const projectDepsCheck = tools.find((t) => t.name === 'deps NPM do projeto');
284
+ if (projectDepsCheck?.status === 'missing') {
285
+ const should = opts.yes || (await promptYesNo('Rodar `npm ci` no diretório atual?'));
286
+ if (should) {
287
+ log.info(chalk.cyan('\n → Instalando deps NPM (npm ci)…\n'));
288
+ const code = await runSpawn('npm', ['ci', '--legacy-peer-deps'], { cwd });
289
+ if (code === 0) {
290
+ report.actionsTaken.push('npm ci');
291
+ log.success(' deps NPM instaladas');
292
+ }
293
+ else {
294
+ log.error(` npm ci falhou (exit ${code}). Tente manualmente.`);
295
+ }
296
+ }
297
+ }
298
+ // Ação 2: ADC login
299
+ const adcCheck = tools.find((t) => t.name === 'GCP Application Default Credentials');
300
+ if (adcCheck?.status === 'missing') {
301
+ const gcloudOk = tools.find((t) => t.name === 'gcloud (Google Cloud CLI)')?.status === 'ok';
302
+ if (gcloudOk) {
303
+ const should = opts.yes ||
304
+ (await promptYesNo('Rodar `gcloud auth application-default login` (abre browser)?'));
305
+ if (should) {
306
+ log.info(chalk.cyan('\n → Login ADC GCP (abrindo browser)…\n'));
307
+ const code = await runSpawn('gcloud', ['auth', 'application-default', 'login']);
308
+ if (code === 0)
309
+ report.actionsTaken.push('gcloud ADC login');
310
+ }
311
+ }
312
+ }
313
+ // ─── Sumário final ────────────────────────────────────────────────
314
+ if (report.actionsTaken.length > 0) {
315
+ log.success(`\n ${report.actionsTaken.length} ação(ões) executadas: ${report.actionsTaken.join(', ')}`);
316
+ }
317
+ if (report.pendingActions.length > 0) {
318
+ log.warn(`\n ${report.pendingActions.length} pendência(s) — rode os comandos sugeridos acima.`);
319
+ }
320
+ if (report.ok && report.pendingActions.length === 0) {
321
+ log.success(`\n Ambiente pronto. Próximos passos:`);
322
+ log.info(` ${chalk.cyan('neetru login')} — autenticar CLI no Core`);
323
+ log.info(` ${chalk.cyan('neetru new <slug>')} — criar novo produto SaaS`);
324
+ log.info(` ${chalk.cyan('neetru deploy')} — fazer deploy de produto existente`);
325
+ log.info(` ${chalk.cyan('neetru doctor')} — re-validar estado depois\n`);
326
+ }
327
+ }
328
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/commands/bootstrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAmCzC,SAAS,aAAa,CAAC,GAAW,EAAE,OAAiB,CAAC,WAAW,CAAC;IAChE,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAChC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,0DAA0D;QAC1D,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACxC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,OAAsB,EAAE,GAAW;IACrD,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5D,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IACtD,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IACzB,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,WAAW,CAAC,UAAmC;IACtD,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,MAAM,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC3B,OAAO,UAAU,CAAC,CAAiC,CAAC,IAAI,UAAU,CAAC,KAAK,IAAI,IAAI,CAAC;AACnF,CAAC;AAED,SAAS,WAAW,CAAC,QAAgB;IACnC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACxD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,EAAE,CAAC,QAAQ,CAAC,KAAK,QAAQ,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE;YAC7C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACtC,OAAO,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CACf,GAAW,EACX,IAAc,EACd,OAA0C,EAAE;IAE5C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;YACzB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;YACtC,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;SACpC,CAAC,CAAC;QACH,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,4EAA4E;AAE5E,SAAS,SAAS;IAChB,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAG,MAAM,CAAC;IACnB,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9B,OAAO;QACL,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU;QAC/C,QAAQ,EAAE,CAAC,IAAI,SAAS;QACxB,QAAQ,EAAE,KAAK,GAAG,MAAM;QACxB,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE;YACV,MAAM,EAAE,sBAAsB;YAC9B,KAAK,EAAE,qGAAqG;YAC5G,KAAK,EAAE,kEAAkE;SAC1E;QACD,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW;KACzE,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ;IACf,MAAM,CAAC,GAAG,aAAa,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9C,OAAO;QACL,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QAC5B,QAAQ,EAAE,CAAC,IAAI,SAAS;QACxB,QAAQ,EAAE,QAAQ;QAClB,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,SAAS;KAC/D,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ;IACf,MAAM,CAAC,GAAG,aAAa,CAAC,KAAK,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAC9C,OAAO;QACL,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QAC5B,QAAQ,EAAE,CAAC,IAAI,SAAS;QACxB,QAAQ,EAAE,OAAO;QACjB,aAAa,EAAE,IAAI;QACnB,UAAU,EAAE;YACV,MAAM,EAAE,4DAA4D;YACpE,KAAK,EAAE,6BAA6B;YACpC,KAAK,EAAE,iDAAiD;SACzD;KACF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,CAAC,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IACjD,OAAO;QACL,IAAI,EAAE,2BAA2B;QACjC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QAC5B,QAAQ,EAAE,CAAC,IAAI,SAAS;QACxB,QAAQ,EAAE,kBAAkB;QAC5B,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE;YACV,MAAM,EAAE,sCAAsC;YAC9C,KAAK,EAAE,4DAA4D;YACnE,KAAK,EAAE,yFAAyF;SACjG;QACD,MAAM,EAAE,CAAC,CAAC;YACR,CAAC,CAAC,oEAAoE;YACtE,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,CAAC,GAAG,aAAa,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IACjD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QAC5B,QAAQ,EAAE,CAAC,IAAI,SAAS;QACxB,QAAQ,EAAE,kBAAkB;QAC5B,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE;YACV,MAAM,EAAE,wDAAwD;YAChE,KAAK,EAAE,wCAAwC;YAC/C,KAAK,EAAE,qCAAqC;SAC7C;QACD,MAAM,EAAE,CAAC,CAAC;YACR,CAAC,CAAC,iFAAiF;YACnF,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC;AAED,SAAS,aAAa;IACpB,MAAM,CAAC,GAAG,aAAa,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IACnD,OAAO;QACL,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QAC5B,QAAQ,EAAE,CAAC,IAAI,SAAS;QACxB,QAAQ,EAAE,MAAM;QAChB,aAAa,EAAE,KAAK;QACpB,UAAU,EAAE;YACV,GAAG,EAAE,+BAA+B;SACrC;QACD,MAAM,EAAE,CAAC,CAAC;YACR,CAAC,CAAC,0EAA0E;YAC5E,CAAC,CAAC,SAAS;KACd,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,GAAW;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,IAAI,EAAE,qBAAqB;YAC3B,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,qDAAqD;SAC9D,CAAC;IACJ,CAAC;IACD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IACrD,OAAO;QACL,IAAI,EAAE,qBAAqB;QAC3B,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QACpC,aAAa,EAAE,IAAI;QACnB,MAAM,EAAE,SAAS;YACf,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,wBAAwB;YAC/C,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,sCAAsC;KAChE,CAAC;AACJ,CAAC;AAED,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;IAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CACvB,IAAI,EACJ,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC1B,CAAC,CAAC,gEAAgE;QAClE,CAAC,CAAC,qDAAqD,CAC1D,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC3C,OAAO;QACL,IAAI,EAAE,qCAAqC;QAC3C,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QAClC,aAAa,EAAE,KAAK;QACpB,MAAM,EAAE,OAAO;YACb,CAAC,CAAC,iBAAiB;YACnB,CAAC,CAAC,wEAAwE;KAC7E,CAAC;AACJ,CAAC;AAED,4EAA4E;AAE5E,SAAS,UAAU,CAAC,CAAc;IAChC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,WAAW,CAAC,MAAuB;IAC1C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC,CAAC;IACtD,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;IACtF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACxF,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC;QACnE,IAAI,CAAC,CAAC,MAAM;YAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YACtC,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAC1D,IAAI,GAAG;gBAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;AACH,CAAC;AAED,4EAA4E;AAE5E,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAyB,EAAE;IAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACtC,MAAM,KAAK,GAAgB;QACzB,SAAS,EAAE;QACX,QAAQ,EAAE;QACV,QAAQ,EAAE;QACV,WAAW,EAAE;QACb,WAAW,EAAE;QACb,aAAa,EAAE;QACf,gBAAgB,CAAC,GAAG,CAAC;QACrB,cAAc,EAAE;KACjB,CAAC;IAEF,MAAM,MAAM,GAAoB;QAC9B,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC;QAC7D,GAAG;QACH,EAAE,EAAE,OAAO,CAAC,QAAQ;QACpB,KAAK;QACL,YAAY,EAAE,EAAE;QAChB,cAAc,EAAE,KAAK;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;aACpF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,wBAAwB;SAClF,CAAC,CAAC;KACN,CAAC;IAEF,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,WAAW,CAAC,MAAM,CAAC,CAAC;IAEpB,sEAAsE;IACtE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IAED,gEAAgE;IAChE,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAC;IAC7E,IAAI,gBAAgB,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,WAAW,CAAC,oCAAoC,CAAC,CAAC,CAAC;QACrF,IAAI,MAAM,EAAE,CAAC;YACX,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;YAC9D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,oBAAoB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YAC1E,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACnC,GAAG,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,yBAAyB,IAAI,uBAAuB,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qCAAqC,CAAC,CAAC;IACrF,IAAI,QAAQ,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,2BAA2B,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;QAC5F,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,MAAM,GACV,IAAI,CAAC,GAAG;gBACR,CAAC,MAAM,WAAW,CAAC,+DAA+D,CAAC,CAAC,CAAC;YACvF,IAAI,MAAM,EAAE,CAAC;gBACX,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC,CAAC;gBACjE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,OAAO,CAAC,CAAC,CAAC;gBAChF,IAAI,IAAI,KAAK,CAAC;oBAAE,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,GAAG,CAAC,OAAO,CAAC,OAAO,MAAM,CAAC,YAAY,CAAC,MAAM,0BAA0B,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC3G,CAAC;IACD,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,GAAG,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,cAAc,CAAC,MAAM,mDAAmD,CAAC,CAAC;IACnG,CAAC;IACD,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,GAAG,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC;QACrD,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,kCAAkC,CAAC,CAAC;QAC9E,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,8BAA8B,CAAC,CAAC;QAC/E,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,4CAA4C,CAAC,CAAC;QACzF,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,qCAAqC,CAAC,CAAC;IACpF,CAAC;AACH,CAAC"}
@@ -12,4 +12,15 @@ export interface EnvSwitchOptions {
12
12
  */
13
13
  export declare function applyEnvSwitch(content: string, value: EnvTarget): string;
14
14
  export declare function runEnvSwitch(opts: EnvSwitchOptions): Promise<void>;
15
+ import { type StepUpOptions } from '../lib/cli-write.js';
16
+ export interface EnvSetOptions extends StepUpOptions {
17
+ service: string;
18
+ /** Repetível: --set KEY=VALUE */
19
+ set?: string[];
20
+ /** Repetível: --secret KEY=secretName[:version] */
21
+ secret?: string[];
22
+ /** Repetível: --unset KEY */
23
+ unset?: string[];
24
+ }
25
+ export declare function runEnvSet(opts: EnvSetOptions): Promise<void>;
15
26
  export {};
@@ -53,4 +53,95 @@ export async function runEnvSwitch(opts) {
53
53
  await fs.writeFile(filePath, updated, 'utf-8');
54
54
  log.success(`NEETRU_ENV=${target} (${file}).`);
55
55
  }
56
+ // ─── neetru env set --service=X --key=Y --value=Z ──────────────────────────
57
+ //
58
+ // Mutação REMOTA: env vars de um serviço Cloud Run via control plane Core.
59
+ // Distinto do `env switch` (local .env.local). Operação merge — preserva vars
60
+ // existentes não-listadas em --unset. Suporta secretRefs apontando pra
61
+ // Secret Manager.
62
+ //
63
+ // Step-up MFA obrigatório (env vars contêm credenciais efetivas).
64
+ import ora from 'ora';
65
+ import { apiRequest } from '../lib/api-client.js';
66
+ import { requireToken, handleApiError, printWriteResult, resolveStepUp, } from '../lib/cli-write.js';
67
+ function parseKeyValue(pair) {
68
+ const idx = pair.indexOf('=');
69
+ if (idx < 1) {
70
+ throw new Error(`Formato inválido (esperado KEY=VALUE): ${pair}`);
71
+ }
72
+ const k = pair.slice(0, idx);
73
+ const v = pair.slice(idx + 1);
74
+ if (!k)
75
+ throw new Error(`KEY vazia em: ${pair}`);
76
+ return [k, v];
77
+ }
78
+ function parseSecretRef(pair) {
79
+ const [k, ref] = parseKeyValue(pair);
80
+ // ref pode ser "secretName" ou "secretName:version"
81
+ const colonIdx = ref.lastIndexOf(':');
82
+ if (colonIdx > 0) {
83
+ return [k, { secret: ref.slice(0, colonIdx), version: ref.slice(colonIdx + 1) }];
84
+ }
85
+ return [k, { secret: ref, version: 'latest' }];
86
+ }
87
+ export async function runEnvSet(opts) {
88
+ if (!opts.service) {
89
+ log.error('Uso: neetru env set --service=X [--set KEY=VAL] [--secret KEY=secretName[:version]] [--unset KEY]');
90
+ process.exit(1);
91
+ }
92
+ const envVars = {};
93
+ const secretRefs = {};
94
+ const unset = opts.unset ?? [];
95
+ try {
96
+ for (const pair of opts.set ?? []) {
97
+ const [k, v] = parseKeyValue(pair);
98
+ envVars[k] = v;
99
+ }
100
+ for (const pair of opts.secret ?? []) {
101
+ const [k, ref] = parseSecretRef(pair);
102
+ secretRefs[k] = ref;
103
+ }
104
+ }
105
+ catch (err) {
106
+ log.error(err instanceof Error ? err.message : String(err));
107
+ process.exit(1);
108
+ }
109
+ if (Object.keys(envVars).length === 0 &&
110
+ Object.keys(secretRefs).length === 0 &&
111
+ unset.length === 0) {
112
+ log.error('Nada para alterar — passe --set, --secret ou --unset.');
113
+ process.exit(1);
114
+ }
115
+ const token = await requireToken(opts.json);
116
+ const { headers } = await resolveStepUp(opts);
117
+ const spinner = opts.json
118
+ ? null
119
+ : ora({
120
+ text: `Atualizando env vars em ${opts.service}…`,
121
+ color: 'blue',
122
+ }).start();
123
+ const path = `/api/cli/v1/cloud-run/${encodeURIComponent(opts.service)}/env${opts.dryRun ? '?dryRun=true' : ''}`;
124
+ let res;
125
+ try {
126
+ res = await apiRequest(path, {
127
+ method: 'POST',
128
+ token,
129
+ headers,
130
+ body: { envVars, secretRefs, unset },
131
+ });
132
+ spinner?.stop();
133
+ }
134
+ catch (error) {
135
+ spinner?.fail('Falha ao atualizar env vars.');
136
+ handleApiError(error, opts.json);
137
+ }
138
+ const setSummary = [
139
+ Object.keys(envVars).length ? `${Object.keys(envVars).length} var(s)` : null,
140
+ Object.keys(secretRefs).length ? `${Object.keys(secretRefs).length} secret(s)` : null,
141
+ unset.length ? `${unset.length} removida(s)` : null,
142
+ ]
143
+ .filter(Boolean)
144
+ .join(' · ');
145
+ printWriteResult(res.dryRun ? res : { service: res.service, totalEnvVars: res.totalEnvVars }, `Env vars atualizadas em ${res.service} (${setSummary}; total agora: ${res.totalEnvVars}).`, opts.json);
146
+ }
56
147
  //# sourceMappingURL=env.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAEzC,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,CAAU,CAAC;AAU9D,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAQ,SAA+B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe,EAAE,KAAgB;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,EAAE,CAAC;YACN,KAAK,GAAG,IAAI,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,KAAK,EAAE,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/D,GAAG,CAAC,IAAI,CAAC,cAAc,KAAK,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAsB;IACvD,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,GAAG,YAAY,EAAE,GAAG,IAAI,CAAC;IAClE,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,KAAK,CAAC,WAAW,MAAM,oBAAoB,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChC,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,GAAG,CAAC,OAAO,CAAC,cAAc,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/commands/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type StepUpOptions } from '../lib/cli-write.js';
2
+ export interface HostingCreateMappingOptions extends StepUpOptions {
3
+ service: string;
4
+ domain: string;
5
+ }
6
+ export declare function runHostingCreateMapping(opts: HostingCreateMappingOptions): Promise<void>;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * `neetru hosting create-mapping` — cria domain mapping pra Cloud Run.
3
+ *
4
+ * Endpoint: POST /api/cli/v1/hosting/mappings
5
+ * body: { service: string, domain: string }
6
+ *
7
+ * Step-up MFA: SIM (pode redirecionar tráfego público).
8
+ * Owner ainda precisa criar o CNAME no DNS provider externo.
9
+ */
10
+ import ora from 'ora';
11
+ import { apiRequest } from '../lib/api-client.js';
12
+ import { requireToken, handleApiError, printWriteResult, resolveStepUp, } from '../lib/cli-write.js';
13
+ import { log } from '../utils/logger.js';
14
+ export async function runHostingCreateMapping(opts) {
15
+ if (!opts.service || !opts.domain) {
16
+ log.error('Uso: neetru hosting create-mapping --service=<service> --domain=<domain>');
17
+ process.exit(1);
18
+ }
19
+ const token = await requireToken(opts.json);
20
+ const { headers } = await resolveStepUp(opts);
21
+ const spinner = opts.json
22
+ ? null
23
+ : ora({
24
+ text: `Criando mapping ${opts.domain} → ${opts.service}…`,
25
+ color: 'blue',
26
+ }).start();
27
+ const path = `/api/cli/v1/hosting/mappings${opts.dryRun ? '?dryRun=true' : ''}`;
28
+ let res;
29
+ try {
30
+ res = await apiRequest(path, {
31
+ method: 'POST',
32
+ token,
33
+ headers,
34
+ body: { service: opts.service, domain: opts.domain },
35
+ });
36
+ spinner?.stop();
37
+ }
38
+ catch (error) {
39
+ spinner?.fail('Falha ao criar domain mapping.');
40
+ handleApiError(error, opts.json);
41
+ }
42
+ const verb = res.alreadyExisted ? 'já existia' : 'criado';
43
+ printWriteResult(res.dryRun
44
+ ? res
45
+ : {
46
+ service: res.service,
47
+ domain: res.domain,
48
+ alreadyExisted: res.alreadyExisted,
49
+ hint: res.hint,
50
+ }, `Domain mapping ${verb}: ${res.domain} → ${res.service}. ${res.hint ?? ''}`.trim(), opts.json);
51
+ }
52
+ //# sourceMappingURL=hosting-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosting-write.js","sourceRoot":"","sources":["../../src/commands/hosting-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EACL,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,aAAa,GAEd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAOzC,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAiC;IAEjC,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,GAAG,CAAC,KAAK,CAAC,0EAA0E,CAAC,CAAC;QACtF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC;IAE9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI;QACvB,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,GAAG,CAAC;YACF,IAAI,EAAE,mBAAmB,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,OAAO,GAAG;YACzD,KAAK,EAAE,MAAM;SACd,CAAC,CAAC,KAAK,EAAE,CAAC;IAEf,MAAM,IAAI,GAAG,+BAA+B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAEhF,IAAI,GAQH,CAAC;IACF,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE;YAC3B,MAAM,EAAE,MAAM;YACd,KAAK;YACL,OAAO;YACP,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;SACrD,CAAC,CAAC;QACH,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAChD,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1D,gBAAgB,CACd,GAAG,CAAC,MAAM;QACR,CAAC,CAAC,GAAG;QACL,CAAC,CAAC;YACE,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,cAAc,EAAE,GAAG,CAAC,cAAc;YAClC,IAAI,EAAE,GAAG,CAAC,IAAI;SACf,EACL,kBAAkB,IAAI,KAAK,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAClF,IAAI,CAAC,IAAI,CACV,CAAC;AACJ,CAAC"}
@@ -10,5 +10,7 @@ export interface LogsOptions {
10
10
  channel?: string;
11
11
  /** v1.3 — buscar logs com `correlationId == <uuid>`. */
12
12
  correlationId?: string;
13
+ /** C2 2026-05-18 — saída NDJSON linha a linha (útil para pipes). */
14
+ json?: boolean;
13
15
  }
14
16
  export declare function runLogs(opts: LogsOptions): Promise<void>;