import { readFile, writeFile, mkdir, cp } from 'node:fs/promises'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { unzipSync } from 'fflate'; import { unpackProject, projectArchive, decodeData } from '../engine/archive.ts'; const [projectFile, outputDirectory] = process.argv.slice(2); if (!projectFile || !outputDirectory) throw Error('Usage: node --import tsx scripts/export-editor.ts PROJECT.forma[.json] OUTPUT_DIRECTORY'); const source = path.resolve(projectFile), out = path.resolve(outputDirectory); const engine = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const project = unpackProject(new Uint8Array(await readFile(source))); const archive = await projectArchive(project, async uri => uri.startsWith('data:') ? decodeData(uri) : new Uint8Array(await readFile(path.resolve(path.dirname(source), uri)))); await mkdir(out, { recursive: true }); for (const [name, bytes] of Object.entries(unzipSync(archive))) { if (name !== 'project.forma.json' && !name.startsWith('assets/')) continue; const target = path.join(out, name); await mkdir(path.dirname(target), { recursive: true }); await writeFile(target, bytes); } for (const [sourceDir, targetDir] of [['hosted-editor', 'studio'], ['engine', 'engine'], ['build-targets', 'build-targets']]) { await cp(path.join(engine, 'public', sourceDir), path.join(out, targetDir), { recursive: true }); } await cp(path.join(engine, 'public/favicon.svg'), path.join(out, 'favicon.svg')); const title = project.name.replace(/[<>&"']/g, ''); await writeFile(path.join(out, 'index.html'), `
Открываю проект Forma…