mega-brain-ai 1.2.2 → 1.2.4
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/lib/installer.js +69 -60
- package/package.json +1 -1
package/bin/lib/installer.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* 6. Post-install summary
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import { existsSync, mkdirSync, cpSync, writeFileSync, readFileSync } from 'fs';
|
|
16
|
+
import { existsSync, mkdirSync, cpSync, writeFileSync, readFileSync, readdirSync } from 'fs';
|
|
17
17
|
import { resolve, dirname, join } from 'path';
|
|
18
18
|
import { fileURLToPath } from 'url';
|
|
19
19
|
import { execSync } from 'child_process';
|
|
@@ -261,64 +261,65 @@ async function selectEdition() {
|
|
|
261
261
|
* This installer runs on other people's machines — we never risk data loss.
|
|
262
262
|
*/
|
|
263
263
|
async function fetchPremiumContent(targetDir, token, spinner) {
|
|
264
|
-
const premiumRepo = 'https://github.com/thiagofinch/mega-brain-premium.git';
|
|
265
264
|
const tempDir = join(targetDir, '.layer-sync', 'premium-fetch');
|
|
266
265
|
|
|
267
|
-
// Safety: ensure tempDir is strictly INSIDE targetDir
|
|
266
|
+
// Safety: ensure tempDir is strictly INSIDE targetDir
|
|
268
267
|
const resolvedTemp = resolve(tempDir);
|
|
269
268
|
const resolvedTarget = resolve(targetDir);
|
|
270
269
|
if (!resolvedTemp.startsWith(resolvedTarget + '/') && !resolvedTemp.startsWith(resolvedTarget + '\\')) {
|
|
271
270
|
throw new Error('Erro interno: caminho de download fora do diretório de instalação.');
|
|
272
271
|
}
|
|
273
272
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
273
|
+
mkdirSync(dirname(tempDir), { recursive: true });
|
|
274
|
+
|
|
275
|
+
// Clone with token in URL — .layer-sync/ is in .gitignore so token stays local
|
|
276
|
+
const authUrl = `https://x-access-token:${token}@github.com/thiagofinch/mega-brain-premium.git`;
|
|
277
277
|
|
|
278
|
-
// If a previous clone exists, reuse it (no delete + re-clone)
|
|
279
278
|
if (!existsSync(join(tempDir, '.git'))) {
|
|
280
279
|
spinner.text = 'Clonando repositório premium...';
|
|
281
280
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const base64Auth = Buffer.from(`x-access-token:${token}`).toString('base64');
|
|
285
|
-
|
|
286
|
-
execSync(
|
|
287
|
-
`git -c "http.https://github.com/.extraheader=AUTHORIZATION: basic ${base64Auth}" clone --depth 1 "${premiumRepo}" "${tempDir}"`,
|
|
288
|
-
{
|
|
281
|
+
try {
|
|
282
|
+
execSync(`git clone --depth 1 "${authUrl}" "${tempDir}"`, {
|
|
289
283
|
stdio: 'pipe',
|
|
290
284
|
encoding: 'utf-8',
|
|
291
285
|
timeout: 120000,
|
|
292
|
-
}
|
|
293
|
-
)
|
|
286
|
+
});
|
|
287
|
+
} catch (cloneErr) {
|
|
288
|
+
throw new Error(`Git clone falhou: ${cloneErr.message.split('\n')[0]}`);
|
|
289
|
+
}
|
|
294
290
|
} else {
|
|
295
291
|
spinner.text = 'Download anterior encontrado, reutilizando...';
|
|
296
292
|
}
|
|
297
293
|
|
|
294
|
+
// Verify clone has content
|
|
295
|
+
if (!existsSync(tempDir) || readdirSync(tempDir).length <= 1) {
|
|
296
|
+
throw new Error('Repositório premium clonado mas vazio.');
|
|
297
|
+
}
|
|
298
|
+
|
|
298
299
|
spinner.text = 'Integrando conteúdo premium na estrutura...';
|
|
299
300
|
|
|
300
301
|
// Copy premium content over the shell (merge, not replace)
|
|
301
|
-
const
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
302
|
+
const premiumExclude = ['.git', 'node_modules', 'bin', '.layer-sync'];
|
|
303
|
+
const premiumEntries = readdirSync(tempDir, { withFileTypes: true });
|
|
304
|
+
let copied = 0;
|
|
305
|
+
|
|
306
|
+
for (const entry of premiumEntries) {
|
|
307
|
+
if (premiumExclude.includes(entry.name)) continue;
|
|
308
|
+
|
|
309
|
+
const srcPath = join(tempDir, entry.name);
|
|
310
|
+
const destPath = join(targetDir, entry.name);
|
|
311
|
+
|
|
312
|
+
if (entry.isDirectory()) {
|
|
313
|
+
cpSync(srcPath, destPath, { recursive: true, force: true });
|
|
314
|
+
} else {
|
|
315
|
+
cpSync(srcPath, destPath, { force: true });
|
|
316
|
+
}
|
|
317
|
+
copied++;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (copied === 0) {
|
|
321
|
+
throw new Error('Nenhum conteúdo premium copiado.');
|
|
322
|
+
}
|
|
322
323
|
}
|
|
323
324
|
|
|
324
325
|
/**
|
|
@@ -369,30 +370,38 @@ function showPostInstallCommunity() {
|
|
|
369
370
|
}
|
|
370
371
|
|
|
371
372
|
function copyTemplateFiles(source, target, excludeDirs) {
|
|
372
|
-
|
|
373
|
-
|
|
373
|
+
if (!existsSync(source)) {
|
|
374
|
+
throw new Error(`Template não encontrado: ${source}`);
|
|
375
|
+
}
|
|
374
376
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
377
|
+
const entries = readdirSync(source, { withFileTypes: true });
|
|
378
|
+
|
|
379
|
+
if (entries.length === 0) {
|
|
380
|
+
throw new Error(`Template vazio: ${source}`);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
let copied = 0;
|
|
384
|
+
for (const entry of entries) {
|
|
385
|
+
if (excludeDirs.includes(entry.name)) continue;
|
|
386
|
+
|
|
387
|
+
const srcPath = join(source, entry.name);
|
|
388
|
+
const destPath = join(target, entry.name);
|
|
389
|
+
|
|
390
|
+
try {
|
|
391
|
+
if (entry.isDirectory()) {
|
|
392
|
+
cpSync(srcPath, destPath, { recursive: true, force: true });
|
|
393
|
+
} else {
|
|
394
|
+
mkdirSync(dirname(destPath), { recursive: true });
|
|
395
|
+
cpSync(srcPath, destPath, { force: true });
|
|
396
|
+
}
|
|
397
|
+
copied++;
|
|
398
|
+
} catch (err) {
|
|
399
|
+
console.error(` Aviso: falha ao copiar ${entry.name}: ${err.message}`);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (copied === 0) {
|
|
404
|
+
throw new Error(`Nenhum arquivo copiado. Source: ${source} (${entries.length} entries, ${excludeDirs.length} excluded)`);
|
|
396
405
|
}
|
|
397
406
|
}
|
|
398
407
|
|