Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 6,925 Bytes
0e4f3a0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
#!/usr/bin/env node
/**
* Export bundle: TXT + DOCX + screenshots β ZIP archive
*
* Runs the three export steps in sequence, gathers all outputs
* into a single folder, and creates a .zip archive.
*
* Usage:
* node scripts/export-bundle.mjs
* npm run export:bundle
*
* Output: dist/{slug}-bundle.zip
*/
import { spawn } from 'node:child_process';
import { resolve, join, basename } from 'node:path';
import { promises as fs } from 'node:fs';
import { createWriteStream } from 'node:fs';
import { pipeline } from 'node:stream/promises';
import { Readable } from 'node:stream';
import process from 'node:process';
import { execSync } from 'node:child_process';
const cwd = process.cwd();
// βββ Helpers ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
function run(command, args = [], options = {}) {
return new Promise((resolvePromise, reject) => {
console.log(` $ ${command} ${args.join(' ')}`);
const child = spawn(command, args, { stdio: 'inherit', shell: false, ...options });
child.on('error', reject);
child.on('close', (code) => {
if (code === 0) resolvePromise();
else reject(new Error(`"${command} ${args.join(' ')}" exited with code ${code}`));
});
});
}
async function exists(p) {
try { await fs.access(p); return true; } catch { return false; }
}
async function copyDir(src, dest) {
await fs.mkdir(dest, { recursive: true });
const entries = await fs.readdir(src, { withFileTypes: true });
for (const entry of entries) {
const srcPath = join(src, entry.name);
const destPath = join(dest, entry.name);
if (entry.isDirectory()) {
await copyDir(srcPath, destPath);
} else {
await fs.copyFile(srcPath, destPath);
}
}
}
async function findFiles(dir, pattern) {
const results = [];
try {
const entries = await fs.readdir(dir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isFile() && pattern.test(entry.name)) {
results.push(join(dir, entry.name));
}
}
} catch { /* dir may not exist */ }
return results;
}
// βββ Main βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
async function main() {
const distDir = resolve(cwd, 'dist');
const screenshotsDir = resolve(cwd, 'screenshots');
console.log('π¦ Export Bundle: TXT + DOCX + Images β ZIP\n');
// ββ Step 1: Export TXT ββββββββββββββββββββββββββββββββββββββββββββββββββββ
console.log('β'.repeat(60));
console.log('1/3 Exporting TXTβ¦');
console.log('β'.repeat(60));
await run('node', ['scripts/export-txt.mjs']);
console.log();
// Find the generated TXT file
const txtFiles = await findFiles(distDir, /\.txt$/);
if (txtFiles.length === 0) {
console.error('β No TXT file found in dist/ after export:txt');
process.exit(1);
}
const txtPath = txtFiles[0];
const slug = basename(txtPath, '.txt');
console.log(` β Found: ${basename(txtPath)}`);
// ββ Step 2: Export DOCX βββββββββββββββββββββββββββββββββββββββββββββββββββ
console.log('\n' + 'β'.repeat(60));
console.log('2/3 Exporting DOCXβ¦');
console.log('β'.repeat(60));
await run('node', ['scripts/export-docx.mjs', `--input=${txtPath}`]);
console.log();
const docxPath = txtPath.replace('.txt', '.docx');
if (!(await exists(docxPath))) {
console.error('β DOCX file not found after export:docx');
process.exit(1);
}
console.log(` β Found: ${basename(docxPath)}`);
// ββ Step 3: Export Images βββββββββββββββββββββββββββββββββββββββββββββββββ
console.log('\n' + 'β'.repeat(60));
console.log('3/3 Exporting screenshotsβ¦');
console.log('β'.repeat(60));
await run('node', ['scripts/screenshot-elements.mjs']);
console.log();
if (!(await exists(screenshotsDir))) {
console.error('β screenshots/ folder not found after export:images');
process.exit(1);
}
// Count screenshots
const pngFiles = await findFiles(screenshotsDir, /\.png$/);
console.log(` β Found: ${pngFiles.length} screenshots`);
// ββ Step 4: Assemble bundle folder ββββββββββββββββββββββββββββββββββββββββ
console.log('\n' + 'β'.repeat(60));
console.log('4/4 Creating archiveβ¦');
console.log('β'.repeat(60));
const bundleDir = resolve(distDir, `${slug}-bundle`);
const imagesDir = join(bundleDir, 'images');
// Clean previous bundle
await fs.rm(bundleDir, { recursive: true, force: true });
await fs.mkdir(imagesDir, { recursive: true });
// Copy TXT
await fs.copyFile(txtPath, join(bundleDir, basename(txtPath)));
console.log(` β
${basename(txtPath)}`);
// Copy DOCX
await fs.copyFile(docxPath, join(bundleDir, basename(docxPath)));
console.log(` β
${basename(docxPath)}`);
// Copy screenshots
for (const png of pngFiles) {
await fs.copyFile(png, join(imagesDir, basename(png)));
}
console.log(` β
images/ (${pngFiles.length} files)`);
// ββ Step 5: Create ZIP ββββββββββββββββββββββββββββββββββββββββββββββββββββ
const zipPath = resolve(distDir, `${slug}-bundle.zip`);
// Remove old zip
try { await fs.unlink(zipPath); } catch { /* ok */ }
// Use system zip command (available on macOS/Linux)
execSync(
`cd "${distDir}" && zip -r "${basename(zipPath)}" "${basename(bundleDir)}"`,
{ stdio: 'inherit' },
);
const zipStat = await fs.stat(zipPath);
const sizeMB = (zipStat.size / 1024 / 1024).toFixed(1);
// Clean up bundle folder (keep only the zip)
await fs.rm(bundleDir, { recursive: true, force: true });
console.log(`\n${'β'.repeat(60)}`);
console.log(`π Bundle created: dist/${basename(zipPath)} (${sizeMB} MB)`);
console.log(` Contents: ${basename(txtPath)}, ${basename(docxPath)}, ${pngFiles.length} images`);
console.log('β'.repeat(60));
// Also copy to public/
const publicZip = resolve(cwd, 'public', basename(zipPath));
await fs.mkdir(resolve(cwd, 'public'), { recursive: true });
await fs.copyFile(zipPath, publicZip);
console.log(` β Copied to public/${basename(zipPath)}`);
}
main().catch((err) => {
console.error('β Bundle failed:', err.message);
process.exit(1);
});
|