ForgeTotal.js 5
fr

Total.js 5

Sauvegarder un dossier avec BACKUP() et RESTORE(), et exécuter des commandes avec SHELL()

Total.js 5 · total5@0.0.19 backupshellfiles Exécutée avec Total.js 5
  • BACKUP(filename, directory, [callback], [filter]) regroupe un répertoire (avec ses sous-répertoires) dans un seul fichier et se résout avec { filename, files, size }. Un fichier existant portant ce nom est remplacé. Sans callback, la fonction renvoie une promesse.
  • RESTORE(filename, directory, [callback], [filter]) dépaquette un fichier créé avec BACKUP() dans un répertoire, en créant les dossiers nécessaires, et se résout avec { files, size, path }.
  • SHELL(command, [callback], [cwd]) exécute une commande du shell et se résout avec sa sortie (stdout). Le dossier est celui du projet, ou le texte que vous passez en dernier argument. Quand la commande échoue, la promesse est rejetée avec une erreur dont le code est le code de sortie. Avec un callback, il est appelé sous la forme callback(err, stdout, stderr).

SHELL() exécute exactement le texte que vous lui donnez : ne construisez jamais la commande à partir de ce qu'un utilisateur a envoyé.

controllers/backups.js
const Fs = require('fs');
const Path = require('path');

exports.install = function() {
	ROUTE('GET /backup/', backup);
	ROUTE('GET /shell/', shell);
};

async function backup($) {

	// a folder with a file and a subfolder
	const source = PATH.tmp('source');
	Fs.rmSync(source, { recursive: true, force: true });
	Fs.mkdirSync(Path.join(source, 'sub'), { recursive: true });
	Fs.writeFileSync(Path.join(source, 'a.txt'), 'hello');
	Fs.writeFileSync(Path.join(source, 'sub', 'b.txt'), 'world');

	const file = PATH.tmp('folder.backup');
	const packed = await BACKUP(file, source);

	const target = PATH.tmp('restored');
	Fs.rmSync(target, { recursive: true, force: true });
	const unpacked = await RESTORE(file, target);

	$.json({
		packed: [packed.files, packed.filename === file, Fs.existsSync(file)],
		unpacked: [unpacked.files, unpacked.size, unpacked.path === target],
		content: [Fs.readFileSync(Path.join(target, 'a.txt'), 'utf8'), Fs.readFileSync(Path.join(target, 'sub', 'b.txt'), 'utf8')]
	});
}

async function shell($) {

	const output = await SHELL('echo hello');
	const where = await SHELL('pwd', PATH.tmp());

	let code = null;
	try {
		await SHELL('exit 3');
	} catch (e) {
		code = e.code;
	}

	SHELL('echo from callback', (err, stdout) => $.json({ output: output, where: where.trim() === PATH.tmp() || where.trim().endsWith('/tmp'), code: code, callback: stdout }));
}