budibase/packages/core/test/memory.js

135 lines
5.0 KiB
JavaScript
Raw Normal View History

2019-07-15 08:12:52 +02:00
import {isUndefined, has} from "lodash";
import {take} from "lodash/fp";
import {Readable, Writable} from "readable-stream";
import { Buffer } from "safe-buffer";
import {splitKey, joinKey, $} from "../src/common";
import {getLastPartInKey} from "../src/templateApi/hierarchy";
const folderMarker = "OH-YES-ITSA-FOLDER-";
const isFolder = val => val.includes(folderMarker);
const getParentFolderKey = key =>
$(key, [
splitKey,
take((splitKey(key).length - 1)),
joinKey,
]);
const getParentFolder = (data,key) => {
const parentKey = getParentFolderKey(key);
if(data[parentKey] === undefined)
throw new Error("Parent folder for " + key + " does not exist (" + parentKey + ")");
return JSON.parse(data[parentKey]);
}
const addItemToParentFolder = (data, path) => {
if(getParentFolderKey(path) === "/") return;
const parentFolder = getParentFolder(data, path);
parentFolder.items.push(
getLastPartInKey(path));
data[getParentFolderKey(path)] = JSON.stringify(parentFolder);
}
export const createFile = data => async (path, content) => {
if(await exists(data)(path)) {
throw new Error(path + " already exists");
}
addItemToParentFolder(data, path);
data[path] = content;
};
export const updateFile = data => async (path, content) => {
// putting this check in to force use of create
if(!await exists(data)(path)) throw new Error("cannot update " + path + " - does not exist");
data[path] = content;
}
export const writableFileStream = data => async (path) => {
//if(!await exists(data)(path)) throw new Error("cannot write stream to " + path + " - does not exist");
const stream = Writable();
stream._write = (chunk, encoding, done) => {
data[path] = data[path] === undefined
? [] : data[path];
data[path] = [...data[path], ...chunk];
done();
};
return stream;
};
export const readableFileStream = data => async (path) => {
if(!await exists(data)(path))
throw new Error("cannot read stream from " + path + " - does not exist");
const s = new Readable();
s._read = () => {
s.push(Buffer.from(data[path]));
s.push(null);
};
return s;
};
export const getFileSize = data => async (path) => {
if(!await exists(data)(path))
throw new Error("cannot get size of " + path + " - does not exist");
return data[path].length;
}
export const renameFile = data => async (oldKey, newKey) => {
if(!await exists(data)(oldKey)) throw new Error("cannot rename path: " + oldKey + " ... does not exist");
if(await exists(data)(newKey)) throw new Error("cannot rename path: " + newKey + " ... already exists");
data[newKey] = data[oldKey];
delete data[oldKey];
};
export const loadFile = data => async (path) => {
const result = data[path];
if(isUndefined(result)) throw new Error("Load failed - path " + path + " does not exist");
return result;
};
export const exists = data => async (path) => has(data, path);
export const deleteFile = data => async (path) => {
if(!await exists(data)(path))
throw new Error("Cannot delete file, path " + path + " does not exist");
if(isFolder(data[path])) throw new Error("DeleteFile: Path " + path + " is a folder, not a file");
const parentFolder = getParentFolder(data, path);
parentFolder.items = parentFolder.items.filter(i => i !== getLastPartInKey(path));
data[getParentFolderKey(path)] = JSON.stringify(parentFolder);
delete data[path];
}
export const createFolder = data => async (path) => {
if(await exists(data)(path)) throw new Error("Cannot create folder, path " + path + " already exists");
addItemToParentFolder(data, path);
data[path] = JSON.stringify({folderMarker, items:[]});
}
export const deleteFolder = data => async (path) => {
if(!await exists(data)(path)) throw new Error("Cannot delete folder, path " + path + " does not exist");
if(!isFolder(data[path]))
throw new Error("DeleteFolder: Path " + path + " is not a folder");
delete data[path];
}
export const getFolderContents = data => async (folderPath) => {
if(!isFolder(data[folderPath]))
throw new Error("Not a folder: " + folderPath);
if(!await exists(data)(folderPath))
throw new Error("Folder does not exist: " + folderPath);
return JSON.parse(data[folderPath]).items;
};
export default data => {
return {
createFile : createFile(data),
updateFile : updateFile(data),
loadFile : loadFile(data),
exists : exists(data),
deleteFile : deleteFile(data),
createFolder: createFolder(data),
deleteFolder: deleteFolder(data),
readableFileStream: readableFileStream(data),
writableFileStream: writableFileStream(data),
renameFile: renameFile(data),
getFolderContents: getFolderContents(data),
getFileSize: getFileSize(data),
datastoreType : "memory",
datastoreDescription: "",
data
};
};