API/api.medcify.app/node_modules/js-git/lib/git-fs.js
2022-09-26 11:41:44 +05:30

126 lines
3.1 KiB
JavaScript

"use strict";
var modes = require('./modes');
var defer = require('./defer');
// options.encrypt(plain) -> encrypted
// options.decrypt(encrypted) -> plain
// options.shouldEncrypt(path) -> boolean
// options.getRootTree() => hash
// options.setRootTree(hash) =>
module.exports = function (repo, options) {
var toWrite = {};
var callbacks = [];
var writing = false;
return {
readFile: readFile,
writeFile: writeFile,
readDir: readDir
};
function readFile(path, callback) {
if (!callback) return readFile.bind(null, path);
// If there is a pending write for this path, pull from the cache.
if (toWrite[path]) return callback(null, toWrite[path]);
// Otherwise read from the persistent storage
options.getRootTree(onRootTree);
function onRootTree(err, hash) {
if (!hash) return callback(err);
repo.pathToEntry(hash, path, onEntry);
}
function onEntry(err, entry) {
if (!entry || !modes.isBlob(entry.mode)) return callback(err);
repo.loadAs("blob", entry.hash, function (err, content) {
if (!content) return callback(err);
if (entry.mode === modes.sym) {
content = options.decrypt(content);
}
callback(null, content);
});
}
}
function writeFile(path, binary, callback) {
if (!callback) return writeFile.bind(null, path, binary);
toWrite[path] = binary;
callbacks.push(callback);
defer(check);
}
function readDir(path, callback) {
if (!callback) return readDir.bind(null, path);
options.getRootTree(onRootTree);
function onRootTree(err, hash) {
if (!hash) return callback(err);
repo.pathToEntry(hash, path, onEntry);
}
function onEntry(err, entry) {
if (!entry || entry.mode !== modes.tree) return callback(err);
repo.loadAs("tree", entry.hash, onTree);
}
function onTree(err, tree) {
if (!tree) return callback(err);
callback(null, Object.keys(tree));
}
}
function check() {
if (writing || !callbacks.length) return;
writing = true;
options.getRootTree(onRootTree);
function onRootTree(err, hash) {
if (err) return callall(err);
var files = pullFiles();
if (hash) files.base = hash;
repo.createTree(files, onNewTree);
}
function onNewTree(err, hash) {
if (err) return callall(err);
options.setRootTree(hash, onSaveRoot);
}
function onSaveRoot(err) {
if (err) return callall(err);
writing = false;
callall();
defer(check);
}
}
function pullFiles() {
var files = Object.keys(toWrite).map(function (path) {
var content = toWrite[path];
delete toWrite[path];
var mode = modes.blob;
if (options.shouldEncrypt && options.shouldEncrypt(path)) {
mode = modes.sym;
content = options.encrypt(content);
}
return {
path: path,
mode: mode,
content: content
};
});
return files;
}
function callall(err) {
callbacks.splice(0, callbacks.length).forEach(function (callback) {
callback(err);
});
}
};