Skip to content

Instantly share code, notes, and snippets.

@andersonbosa
Last active May 31, 2024 11:32
Show Gist options
  • Save andersonbosa/d45d0acfc31a8f3bcf6a5272f1d57e28 to your computer and use it in GitHub Desktop.
Save andersonbosa/d45d0acfc31a8f3bcf6a5272f1d57e28 to your computer and use it in GitHub Desktop.
import fs from 'node:fs'
import path from 'node:path'
import os from 'node:os'
import archiver from 'archiver'
interface FileNode {
name: string
content?: Buffer
children?: FileNode[]
}
class FileStructureEngine {
private baseFolder: string
constructor(baseFolder: string) {
this.baseFolder = baseFolder
fs.mkdirSync(this.baseFolder, { recursive: true })
}
private async createFileOrFolder (node: FileNode, currentPath: string): Promise<void> {
const newPath = path.join(currentPath, node.name)
if (node.content) {
await fs.promises.writeFile(newPath, node.content)
} else {
await fs.promises.mkdir(newPath, { recursive: true })
if (node.children) {
for (const child of node.children) {
await this.createFileOrFolder(child, newPath)
}
}
}
}
public async createStructure (structure: FileNode): Promise<void> {
await this.createFileOrFolder(structure, this.baseFolder)
}
public async zipStructure (): Promise<Buffer> {
const zipPath = path.join(os.tmpdir(), `${path.basename(this.baseFolder)}.zip`)
const output = fs.createWriteStream(zipPath)
const archive = archiver('zip', { zlib: { level: 9 } })
return new Promise((resolve, reject) => {
output.on('close', async () => {
const buffer = await fs.promises.readFile(zipPath)
await fs.promises.unlink(zipPath)
resolve(buffer)
})
archive.on('error', (err: any) => reject(err))
archive.pipe(output)
archive.directory(this.baseFolder, false)
archive.finalize()
})
}
public async saveZipBuffer (buffer: Buffer, outputPath: string): Promise<void> {
await fs.promises.writeFile(outputPath, buffer)
}
public cleanup (): void {
fs.rmSync(this.baseFolder, { recursive: true, force: true })
}
}
const main = async () => {
const fileStructure: FileNode = {
name: 'root',
children: [
{
name: 'folder1',
children: [
{
name: 'file1.txt',
content: Buffer.from('hello, world!')
},
{
name: 'file2.txt',
content: Buffer.from('goodbye, world!')
}
]
},
{
name: 'folder2',
children: [
{
name: 'file3.txt',
content: Buffer.from('hello, universe!')
},
{
name: 'file4.txt',
content: Buffer.from('goodbye, universe!')
}
]
}
]
}
const baseFolder = fs.mkdtempSync(path.join(os.tmpdir(), 'pasta_principal-'))
const engine = new FileStructureEngine(baseFolder)
try {
await engine.createStructure(fileStructure)
const zipBuffer = await engine.zipStructure()
const outputPath = path.join(os.tmpdir(), 'pasta_principal.zip')
await engine.saveZipBuffer(zipBuffer, outputPath)
console.log(`output: ${outputPath}`)
} finally {
engine.cleanup()
}
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment