initial commit
This commit is contained in:
commit
a8aa18d01d
|
@ -0,0 +1,73 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"presets": ["@babel/env"],
|
||||||
|
"sourceMaps": "inline",
|
||||||
|
"retainLines": true
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "node",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "debug memory",
|
||||||
|
"program": "${workspaceFolder}/index.js",
|
||||||
|
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/babel-node",
|
||||||
|
"runtimeArgs": ["--nolazy"],
|
||||||
|
"args":["memory"],
|
||||||
|
"skipFiles": [
|
||||||
|
"<node_internals>/**/*.js"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
import fs from "fs";
|
||||||
|
import {join} from "path";
|
||||||
|
import {promisify} from 'es6-promisify';
|
||||||
|
import _rimraf from "rimraf";
|
||||||
|
|
||||||
|
const mkdir = promisify(fs.mkdir);
|
||||||
|
const rmdir = promisify(fs.rmdir);
|
||||||
|
const rimraf = promisify(_rimraf);
|
||||||
|
|
||||||
|
const getConfig = async () => {
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
local: {
|
||||||
|
root: "./output/local/files"
|
||||||
|
},
|
||||||
|
memory: {
|
||||||
|
root:"./output/memory"
|
||||||
|
},
|
||||||
|
azure: {
|
||||||
|
root:"./output/azure"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
await rimraf("./output");
|
||||||
|
await mkdir("./output");
|
||||||
|
|
||||||
|
for(let type in config) {
|
||||||
|
await mkdir(join("output", type));
|
||||||
|
}
|
||||||
|
|
||||||
|
await mkdir("./output/local/files");
|
||||||
|
|
||||||
|
return config;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default getConfig;
|
|
@ -0,0 +1,32 @@
|
||||||
|
import fs from "fs";
|
||||||
|
import {mkdir} from "fs";
|
||||||
|
import {join} from "path";
|
||||||
|
import {promisify} from 'es6-promisify';
|
||||||
|
|
||||||
|
mkdirp = promisify(mkdir);
|
||||||
|
|
||||||
|
|
||||||
|
const getConfig = async () => {
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
local: {
|
||||||
|
root: "./output/local/files"
|
||||||
|
},
|
||||||
|
memory: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
await mkdir("./output");
|
||||||
|
} catch(e){}
|
||||||
|
|
||||||
|
for(let type in config) {
|
||||||
|
await mkdir(join("output", type));
|
||||||
|
}
|
||||||
|
|
||||||
|
await mkdir("./output/local/files");
|
||||||
|
|
||||||
|
return config;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default getConfig;
|
|
@ -0,0 +1,86 @@
|
||||||
|
import {SharedKeyCredential, BlockBlobURL,
|
||||||
|
BlobURL, ContainerURL, ServiceURL,
|
||||||
|
StorageURL, Aborter} from "@azure/storage-blob";
|
||||||
|
|
||||||
|
export const createFile = ({containerUrl}) => async (key, content) => {
|
||||||
|
const blobURL = BlobURL.fromContainerURL(containerURL, key);
|
||||||
|
const blockBlobURL = BlockBlobURL.fromBlobURL(blobURL);
|
||||||
|
await blockBlobURL.upload(
|
||||||
|
Aborter.none,
|
||||||
|
content,
|
||||||
|
content.length
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateFile = opts => async (path, content) =>
|
||||||
|
createFile(opts)(path,content);
|
||||||
|
|
||||||
|
export const loadFile = ({containerUrl}) => async key => {
|
||||||
|
const blobURL = BlobURL.fromContainerURL(
|
||||||
|
containerUrl, key);
|
||||||
|
|
||||||
|
const downloadBlockBlobResponse =
|
||||||
|
await blobURL.download(Aborter.none, 0);
|
||||||
|
|
||||||
|
return downloadBlockBlobResponse
|
||||||
|
.readableStreamBody
|
||||||
|
.read(content.length)
|
||||||
|
.toString();
|
||||||
|
};
|
||||||
|
|
||||||
|
export const exists = ({containerURL}) => async (key) => {
|
||||||
|
const blobURL = BlobURL.fromContainerURL(containerURL, key);
|
||||||
|
const getPropsResponse = await blobURL.getProperties();
|
||||||
|
return getPropsResponse._response.StatusCode === 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const deleteFile = ({containerURL}) => async key => {
|
||||||
|
const blobURL = BlobURL.fromContainerURL(
|
||||||
|
containerURL, key);
|
||||||
|
await blobURL.delete(Aborter.none);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createContainer = ({containerUrl}) => async () =>
|
||||||
|
await containerUrl.create(Aborter.none);
|
||||||
|
|
||||||
|
export const deleteContainer = ({containerUrl}) => async () =>
|
||||||
|
await containerUrl.delete(Aborter.none);
|
||||||
|
|
||||||
|
const initialise = opts => {
|
||||||
|
|
||||||
|
const sharedKeyCredential = new SharedKeyCredential(
|
||||||
|
opts.account,
|
||||||
|
opts.accountKey
|
||||||
|
);
|
||||||
|
|
||||||
|
const pipeline = StorageURL.newPipeline(sharedKeyCredential);
|
||||||
|
|
||||||
|
const serviceURL = new ServiceURL(
|
||||||
|
`https://${account}.blob.core.windows.net`,
|
||||||
|
pipeline
|
||||||
|
);
|
||||||
|
|
||||||
|
const containerURL = ContainerURL.fromServiceURL(
|
||||||
|
serviceURL,
|
||||||
|
opts.containerName
|
||||||
|
);
|
||||||
|
|
||||||
|
return ({
|
||||||
|
containerURL
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default opts => {
|
||||||
|
const access = initialise(opts);
|
||||||
|
return ({
|
||||||
|
createFile : createFile(access),
|
||||||
|
updateFile : updateFile(access),
|
||||||
|
loadFile : loadFile(access),
|
||||||
|
exists : exists(access),
|
||||||
|
|
||||||
|
datastoreType : "azure-blob-storage",
|
||||||
|
datastoreDescription: "",
|
||||||
|
data
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,100 @@
|
||||||
|
import {promisify} from 'es6-promisify';
|
||||||
|
|
||||||
|
import fs from "fs";
|
||||||
|
import {join} from "path";
|
||||||
|
|
||||||
|
const readFile = promisify(fs.readFile);
|
||||||
|
const writeFile = (path, content) =>
|
||||||
|
promisify(fs.writeFile)(path, content, "utf8");
|
||||||
|
const access = promisify(fs.access);
|
||||||
|
const mkdir = promisify(fs.mkdir);
|
||||||
|
const rmdir = promisify(fs.rmdir);
|
||||||
|
const unlink = promisify(fs.unlink);
|
||||||
|
const readdir = promisify(fs.readdir);
|
||||||
|
const rename = promisify(fs.rename);
|
||||||
|
|
||||||
|
const updateFile = root => async (path, file) =>
|
||||||
|
await writeFile(
|
||||||
|
join(root,path),
|
||||||
|
file
|
||||||
|
);
|
||||||
|
|
||||||
|
const createFile = updateFile;
|
||||||
|
|
||||||
|
const loadFile = root => async (path) =>
|
||||||
|
await readFile(
|
||||||
|
join(root,path)
|
||||||
|
, "utf8");
|
||||||
|
|
||||||
|
const exists = root => async (path) => {
|
||||||
|
try {
|
||||||
|
await access(
|
||||||
|
join(root,path)
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const createFolder = root => async (path) =>
|
||||||
|
await mkdir(
|
||||||
|
join(root, path));
|
||||||
|
|
||||||
|
export const deleteFile = root => async (path) =>
|
||||||
|
await unlink(
|
||||||
|
join(root, path)
|
||||||
|
);
|
||||||
|
|
||||||
|
const deleteFolder = root => async (path) =>
|
||||||
|
await rmdir(
|
||||||
|
join(root, path));
|
||||||
|
|
||||||
|
const readableFileStream = root => async path =>
|
||||||
|
fs.createReadStream(
|
||||||
|
join(root, path), "utf8"
|
||||||
|
);
|
||||||
|
|
||||||
|
const writableFileStream = root => async path =>
|
||||||
|
fs.createWriteStream(
|
||||||
|
join(root, path), "utf8"
|
||||||
|
);
|
||||||
|
|
||||||
|
const getFolderContents = root => async path => {
|
||||||
|
await readdir(
|
||||||
|
join(root, path)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renameFile = root => async (oldPath, newPath) =>
|
||||||
|
await rename(
|
||||||
|
join(root, oldPath),
|
||||||
|
join(root, newPath)
|
||||||
|
);
|
||||||
|
|
||||||
|
const createEmptyDb = root = async (type, productSetId, productId, productInstanceId) => {
|
||||||
|
const folder = !productSetId ? type
|
||||||
|
: !productInstanceId ? `${type}.${productSetId}`
|
||||||
|
: `${type}.${productSetId}.${productId}.${productInstanceId}`;
|
||||||
|
|
||||||
|
await createFolder(root)(folder);
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default rootFolderPath => ({
|
||||||
|
createFile : createFile(rootFolderPath),
|
||||||
|
updateFile : updateFile(rootFolderPath),
|
||||||
|
loadFile : loadFile(rootFolderPath),
|
||||||
|
exists : exists(rootFolderPath),
|
||||||
|
deleteFile : deleteFile(rootFolderPath),
|
||||||
|
createFolder: createFolder(rootFolderPath),
|
||||||
|
deleteFolder: deleteFolder(rootFolderPath),
|
||||||
|
readableFileStream: readableFileStream(rootFolderPath),
|
||||||
|
writableFileStream: writableFileStream(rootFolderPath),
|
||||||
|
renameFile: renameFile(rootFolderPath),
|
||||||
|
getFolderContents: getFolderContents(rootFolderPath),
|
||||||
|
createEmptyDb: createEmptyDb(rootFolderPath),
|
||||||
|
datastoreType : "local",
|
||||||
|
datastoreDescription: rootFolderPath
|
||||||
|
});
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
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/heirarchy";
|
||||||
|
|
||||||
|
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 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),
|
||||||
|
datastoreType : "memory",
|
||||||
|
datastoreDescription: "",
|
||||||
|
data
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
import local from "./datastores/local";
|
||||||
|
import azureBlob from "./datastores/azure-blob";
|
||||||
|
import memory from "./datastores/memory";
|
||||||
|
import getConfig from "./config";
|
||||||
|
import tests from "./tests";
|
||||||
|
|
||||||
|
const initialise = async () => {
|
||||||
|
|
||||||
|
const type = process.argv[2];
|
||||||
|
const config = (await getConfig())[type];
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case "local":
|
||||||
|
return {datastore:local(config.root), config};
|
||||||
|
case "memory":
|
||||||
|
return {datastore:memory(config), config};
|
||||||
|
case "azure":
|
||||||
|
return {datastore:azureBlob(config), config};
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initialise()
|
||||||
|
.then(init => {
|
||||||
|
return tests(init.datastore, init.config);
|
||||||
|
})
|
||||||
|
.then(_ => console.log("done"))
|
||||||
|
.catch(e => console.log(e));
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
"name": "budibase-datastores",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "implementations of all the datastores... azureblob, local etc",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"memory": "npx babel-node index.js memory",
|
||||||
|
"local": "npx babel-node index.js local",
|
||||||
|
"azure": "npx babel-node index.js azure"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+ssh://git@gitlab.com/budibase-source/budibase-datastores.git"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"budibase"
|
||||||
|
],
|
||||||
|
"author": "Michael Shanks",
|
||||||
|
"license": "AGPL-3.0",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://gitlab.com/budibase-source/budibase-datastores/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://gitlab.com/budibase-source/budibase-datastores#README",
|
||||||
|
"dependencies": {
|
||||||
|
"@azure/storage-blob": "^10.1.0-preview",
|
||||||
|
"@babel/cli": "^7.1.2",
|
||||||
|
"@babel/core": "^7.1.2",
|
||||||
|
"@babel/node": "^7.0.0",
|
||||||
|
"@babel/preset-env": "^7.1.0",
|
||||||
|
"budibase-core": "git+ssh://git@gitlab.com/budibase-dist/budibase-core.git",
|
||||||
|
"es6-promisify": "^6.0.1",
|
||||||
|
"lodash": "^4.17.11",
|
||||||
|
"p-limit": "^2.0.0",
|
||||||
|
"papaparse": "^4.6.1",
|
||||||
|
"rimraf": "^2.6.2"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
import {eventsList} from "budibase-core";
|
||||||
|
import {filter,union,has,map} from "lodash/fp";
|
||||||
|
import records from "./records";
|
||||||
|
|
||||||
|
const allEventsOfType = type =>
|
||||||
|
filter(
|
||||||
|
e => e.endsWith(`:${type}`)
|
||||||
|
)(eventsList);
|
||||||
|
|
||||||
|
const getEventNamespace = ev => {
|
||||||
|
const parts = ev.split(":");
|
||||||
|
return `${parts[0]}:${parts[1]}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasRecord = has("record");
|
||||||
|
|
||||||
|
export const register = (app, logTimeElapsed, eventNamespaces = []) => {
|
||||||
|
const onCompleteEvents =
|
||||||
|
eventNamespaces.length === 0
|
||||||
|
? allEventsOfType("onComplete")
|
||||||
|
: map(e => `${e}:onComplete`)(eventNamespaces)
|
||||||
|
|
||||||
|
const onErrorEvents =
|
||||||
|
eventNamespaces.length === 0
|
||||||
|
? allEventsOfType("onError")
|
||||||
|
: map(e => `${e}:onError`)(eventNamespaces)
|
||||||
|
|
||||||
|
for(let ev of union(onCompleteEvents)(onErrorEvents)) {
|
||||||
|
app.subscribe(ev, (_, ctx) => {
|
||||||
|
const info =
|
||||||
|
hasRecord(ctx)
|
||||||
|
? ctx.record.type()
|
||||||
|
: "";
|
||||||
|
|
||||||
|
logTimeElapsed(
|
||||||
|
ev, ctx.elapsed, info);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,9 @@
|
||||||
|
import {map} from "lodash";
|
||||||
|
|
||||||
|
export const action = (name, run, iterator=iterateActionTimes(1)) => ({name, run, iterator});
|
||||||
|
|
||||||
|
export const iterateActionTimes = times => run =>
|
||||||
|
map([...Array(times).keys()], run);
|
||||||
|
|
||||||
|
export const iterateCollection = getCollection => run =>
|
||||||
|
map(getCollection(), run);
|
|
@ -0,0 +1,57 @@
|
||||||
|
import setup from "./setup";
|
||||||
|
import records from "./records";
|
||||||
|
import {register} from "./diagnosticPlugin";
|
||||||
|
import pLimit from "p-limit";
|
||||||
|
import papa from "papaparse";
|
||||||
|
import {writeFileSync} from "fs";
|
||||||
|
|
||||||
|
const limit = pLimit(1);
|
||||||
|
|
||||||
|
const iterateActions = async (apis,getIterator) => {
|
||||||
|
const iterator = getIterator(apis);
|
||||||
|
let result = iterator();
|
||||||
|
while(!result.done) {
|
||||||
|
try {
|
||||||
|
const runPromises = result.action.iterator(i =>
|
||||||
|
limit(() => result.action.run(i))
|
||||||
|
);
|
||||||
|
|
||||||
|
let n = 1;
|
||||||
|
await Promise.all(runPromises);
|
||||||
|
result = iterator();
|
||||||
|
} catch(e) {
|
||||||
|
e.message = `FAILED: ${result.action.name}: ${e.message}`;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async (datastore,config) => {
|
||||||
|
|
||||||
|
const apis = await setup(datastore);
|
||||||
|
|
||||||
|
const diagnostics = [];
|
||||||
|
let currentRecordCount = 0;
|
||||||
|
|
||||||
|
register(apis, (ev, elapsed, info) => {
|
||||||
|
if(ev === "recordApi:save:onComplete") {
|
||||||
|
currentRecordCount++;
|
||||||
|
} else if(ev === "recordApi:delete:onComplete") {
|
||||||
|
currentRecordCount--;
|
||||||
|
}
|
||||||
|
diagnostics.push(
|
||||||
|
{method:ev, elapsed, info, count:currentRecordCount}
|
||||||
|
);
|
||||||
|
console.log(`${ev} ${info} ${elapsed/1000} s`);
|
||||||
|
}, [
|
||||||
|
"recordApi:save",
|
||||||
|
"recordApi:load",
|
||||||
|
"viewApi:listItems",
|
||||||
|
"recordApi:delete"]);
|
||||||
|
|
||||||
|
await iterateActions(apis, records);
|
||||||
|
|
||||||
|
const diagnosticscsv = papa.unparse(diagnostics);
|
||||||
|
|
||||||
|
writeFileSync(config.root + "\\results.csv", diagnosticscsv, {encoding:"utf8"});
|
||||||
|
};
|
|
@ -0,0 +1,96 @@
|
||||||
|
import {action, iterateActionTimes, iterateCollection} from "./helpers";
|
||||||
|
import {isUndefined, union, takeRight} from "lodash";
|
||||||
|
|
||||||
|
const createClient = (apis, getState) => async (i) => {
|
||||||
|
const client = apis.recordApi.getNew("/clients", "client");
|
||||||
|
client.FamilyName = "Humperdink";
|
||||||
|
client.Address1 = `${i} Mainitucetts Avenue`;
|
||||||
|
client.Address2 = "Longerton Road South";
|
||||||
|
client.Address3 = "Chalico City";
|
||||||
|
client.Address4 = "Northern Humranistan";
|
||||||
|
client.Postcode = "BY71 5FR";
|
||||||
|
client.CreatedDate = new Date();
|
||||||
|
|
||||||
|
const state = getState();
|
||||||
|
if(isUndefined(state.clientKeys)) state.clientKeys = [];
|
||||||
|
state.clientKeys.push(client.key());
|
||||||
|
|
||||||
|
await apis.recordApi.save(client);
|
||||||
|
|
||||||
|
return client.key();
|
||||||
|
}
|
||||||
|
|
||||||
|
const getClient = (apis, getState) => async (k) => {
|
||||||
|
const state = getState();
|
||||||
|
if(isUndefined(state.clients)) state.clients = [];
|
||||||
|
|
||||||
|
const client = await apis.recordApi.load(k);
|
||||||
|
state.clients.push(client);
|
||||||
|
|
||||||
|
return `key: ${k} , add1: ${client.Address1} , count: ${state.clients.length}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const listClients = (apis, getState) => async () => {
|
||||||
|
const clients = await apis.viewApi.listItems("/clients/default");
|
||||||
|
const state = getState();
|
||||||
|
if(state.clientKeys.length !== clients.length) {
|
||||||
|
throw new Error(
|
||||||
|
"list CLients, expected "
|
||||||
|
+ state.clientKeys.length.toString()
|
||||||
|
+ " clients, actual "
|
||||||
|
+ clients.length.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteClient = (apis, getState) => async k => {
|
||||||
|
await apis.recordApi.delete(k);
|
||||||
|
const state = getState();
|
||||||
|
state.clientKeys = state.clientKeys.filter(key => key !== k);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default (apis) => {
|
||||||
|
|
||||||
|
const state = {};
|
||||||
|
const getState = () => state;
|
||||||
|
|
||||||
|
const noOfRecords = 10000;
|
||||||
|
const recordsPerIteration = 10;
|
||||||
|
const noOfIterations = noOfRecords / recordsPerIteration;
|
||||||
|
|
||||||
|
const actionsInOneIteration = () => ([
|
||||||
|
|
||||||
|
action("Create client", createClient(apis, getState),
|
||||||
|
iterateActionTimes(recordsPerIteration)),
|
||||||
|
|
||||||
|
/*action("Get client", getClient(apis, getState),
|
||||||
|
iterateCollection(() => takeRight(getState().clientKeys, recordsPerIteration))),*/
|
||||||
|
|
||||||
|
action("List Clients", listClients(apis, getState))
|
||||||
|
]);
|
||||||
|
|
||||||
|
let actions = [];
|
||||||
|
for (let index = 0; index < noOfIterations; index++) {
|
||||||
|
actions = union(actions, actionsInOneIteration());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
for (let index = 0; index < noOfIterations; index++) {
|
||||||
|
actions.push(
|
||||||
|
action("Delete Clients", deleteClient(apis, getState),
|
||||||
|
iterateCollection(() => takeRight(getState().clientKeys, recordsPerIteration))),
|
||||||
|
action("List Clients", listClients(apis, getState))
|
||||||
|
);
|
||||||
|
}*/
|
||||||
|
let actionIndex = 0;
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
if(actionIndex == actions.length) {
|
||||||
|
return {done:true};
|
||||||
|
}
|
||||||
|
const result = {action:actions[actionIndex], done:false};
|
||||||
|
actionIndex++;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,70 @@
|
||||||
|
import {getAppApis, getTemplateApi, setupDatastore} from "budibase-core";
|
||||||
|
import {action} from "./helpers";
|
||||||
|
|
||||||
|
const addField = templateApi => type => (record, name) => {
|
||||||
|
const field = templateApi.getNewField(type);
|
||||||
|
field.name = name;
|
||||||
|
field.type = type;
|
||||||
|
field.label = name;
|
||||||
|
templateApi.addField(
|
||||||
|
record,
|
||||||
|
field);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async (datastore) => {
|
||||||
|
|
||||||
|
datastore = setupDatastore(datastore);
|
||||||
|
const templateApi = await getTemplateApi(datastore);
|
||||||
|
const addStringField = addField(templateApi)("string");
|
||||||
|
const addDateField = addField(templateApi)("datetime");
|
||||||
|
const addBoolField = addField(templateApi)("bool");
|
||||||
|
|
||||||
|
const root = templateApi.getNewRootLevel();
|
||||||
|
|
||||||
|
const clients = templateApi.getNewCollectionTemplate(root);
|
||||||
|
clients.name = "clients";
|
||||||
|
|
||||||
|
const client = templateApi.getNewRecordTemplate(clients);
|
||||||
|
client.name = "client"
|
||||||
|
addStringField(client, "FamilyName");
|
||||||
|
addStringField(client, "Address1");
|
||||||
|
addStringField(client, "Address2");
|
||||||
|
addStringField(client, "Address3");
|
||||||
|
addStringField(client, "Address4");
|
||||||
|
addStringField(client, "Postcode");
|
||||||
|
addDateField(client, "CreatedDate");
|
||||||
|
|
||||||
|
const children = templateApi.getNewCollectionTemplate(client);
|
||||||
|
children.name = "children";
|
||||||
|
|
||||||
|
const child = templateApi.getNewRecordTemplate(children);
|
||||||
|
child.name = "child";
|
||||||
|
addStringField(child, "FirstName");
|
||||||
|
addStringField(child, "Surname");
|
||||||
|
addDateField(child, "DateOfBirth");
|
||||||
|
addBoolField(child, "Current");
|
||||||
|
|
||||||
|
const contacts = templateApi.getNewCollectionTemplate(client);
|
||||||
|
contacts.name = "contacts";
|
||||||
|
|
||||||
|
const contact = templateApi.getNewRecordTemplate(contacts);
|
||||||
|
contact.name = "contact";
|
||||||
|
addStringField(contact, "Name");
|
||||||
|
addStringField(contact, "relationship");
|
||||||
|
addStringField(contact, "phone1");
|
||||||
|
addStringField(contact, "phone2");
|
||||||
|
addBoolField(contact, "active");
|
||||||
|
|
||||||
|
await templateApi.saveApplicationHeirarchy(root);
|
||||||
|
|
||||||
|
const apis = await getAppApis(datastore);
|
||||||
|
|
||||||
|
await apis.collectionApi.initialiseAll();
|
||||||
|
|
||||||
|
return apis;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,76 @@
|
||||||
|
const {initialiseData, getTemplateApi,
|
||||||
|
getAppApis} = require("budibase-core");
|
||||||
|
const crypto = require("../server/nodeCrypto");
|
||||||
|
|
||||||
|
module.exports = async (datastoreFactory, dataRootOpts,
|
||||||
|
username, password) => {
|
||||||
|
const rootDatastore = datastoreFactory(dataRootOpts);
|
||||||
|
const masterDatastoreOpts = await rootDatastore.createEmptyMasterDb();
|
||||||
|
const datastore = datastoreFactory(masterDatastoreOpts);
|
||||||
|
|
||||||
|
/*const bb = getAppApis(
|
||||||
|
datastore, {},
|
||||||
|
null, null,
|
||||||
|
crypto
|
||||||
|
);*/
|
||||||
|
|
||||||
|
const templateApi = getTemplateApi();
|
||||||
|
|
||||||
|
const root = templateApi.getNewRootLevel();
|
||||||
|
const productSets = templateApi.getNewCollectionTemplate(root);
|
||||||
|
productSets.name = "ProductSets";
|
||||||
|
|
||||||
|
const productSet = templateApi.getNewRecordTemplate(productSets);
|
||||||
|
productSet.name = "ProductSet";
|
||||||
|
|
||||||
|
const newProductSetField = newField(templateApi, productSet);
|
||||||
|
newProductSetField("name", "string", true);
|
||||||
|
|
||||||
|
const products = templateApi.getNewCollectionTemplate(productSet);
|
||||||
|
products.name = "Products";
|
||||||
|
|
||||||
|
const product = templateApi.getNewRecordTemplate(products);
|
||||||
|
product.name = "product";
|
||||||
|
|
||||||
|
const newProductField = newField(templateApi, product);
|
||||||
|
newProductField("name", "string", true);
|
||||||
|
newProductField("domain", "string", true);
|
||||||
|
|
||||||
|
|
||||||
|
await initialiseData(datastore, {
|
||||||
|
heirarchy:root, actions:[], triggers:[]
|
||||||
|
});
|
||||||
|
|
||||||
|
const bb = await getAppApis(
|
||||||
|
datastore,
|
||||||
|
null, null, null,
|
||||||
|
crypto
|
||||||
|
);
|
||||||
|
|
||||||
|
bb.asFullAccess();
|
||||||
|
|
||||||
|
const fullAccess = bb.authApi.getNewAccessLevel();
|
||||||
|
fullAccess.permissions = bb.authApi.generateFullPermissions();
|
||||||
|
fullAccess.name = "Full Access";
|
||||||
|
await bb.authApi.saveAccessLevels([fullAccess]);
|
||||||
|
const seedUser = bb.authApi.getNewUser();
|
||||||
|
seedUser.name = username;
|
||||||
|
seedUser.accessLevels = ["Full Access"];
|
||||||
|
await bb.authApi.createUser(seedUser, password);
|
||||||
|
|
||||||
|
const initialProductSet = bb.recordApi.getNew("/ProductSets", "ProductSet");
|
||||||
|
initialProductSet.name = "Dev Products";
|
||||||
|
|
||||||
|
return await bb.recordApi.save(initialProductSet);
|
||||||
|
};
|
||||||
|
|
||||||
|
const newField = (templateApi, recordNode) => (name, type, mandatory=false) => {
|
||||||
|
const field = templateApi.getNewField(type);
|
||||||
|
field.name = name;
|
||||||
|
templateApi.addField(recordNode, field);
|
||||||
|
if(mandatory) {
|
||||||
|
templateApi.addRecordValidationRule(recordNode)
|
||||||
|
(templateApi.commonValidationRules.fieldNotEmpty)
|
||||||
|
}
|
||||||
|
return field;
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = async (datastoreFactory, productDbOpts) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,12 @@
|
||||||
|
const createMasterDb = require("./createMasterDb");
|
||||||
|
//datastore.createDb("productSet", "product", "instance");
|
||||||
|
|
||||||
|
module.exports = async (datastoreFactory, rootDataOpts, username, password) => {
|
||||||
|
await createMasterDb(
|
||||||
|
datastoreFactory, rootDataOpts,
|
||||||
|
username, password);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"name": "budibase",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "budibase wrapper repo for development",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"budibase"
|
||||||
|
],
|
||||||
|
"author": "Michael Shanks",
|
||||||
|
"license": "AGPL-3.0-or-later",
|
||||||
|
"dependencies": {
|
||||||
|
"budibase-core": "git+ssh://git@gitlab.com/budibase-dist/budibase-core.git"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# TypeScript v1 declaration files
|
||||||
|
typings/
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
|
||||||
|
# next.js build output
|
||||||
|
.next
|
||||||
|
|
||||||
|
# nuxt.js build output
|
||||||
|
.nuxt
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless
|
|
@ -0,0 +1,8 @@
|
||||||
|
const Koa = require('koa');
|
||||||
|
const app = new Koa();
|
||||||
|
|
||||||
|
app.use(async ctx => {
|
||||||
|
ctx.body = 'Hello World';
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(3000);
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
export const budibaseRouting = (options) => {
|
||||||
|
|
||||||
|
return async (ctx, next) => {
|
||||||
|
|
||||||
|
ctx.request.path
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/* api Routes (all /api/..)
|
||||||
|
|
||||||
|
POST executeAction/<name> {}
|
||||||
|
POST authenticate {}
|
||||||
|
POST authenticateTemporaryAccess {}
|
||||||
|
POST createUser {}
|
||||||
|
POST enabledUser {}
|
||||||
|
POST disableUser {}
|
||||||
|
GET users
|
||||||
|
GET accessLevels
|
||||||
|
POST accessLevels {}
|
||||||
|
POST changeMyPassword {}
|
||||||
|
POST setPasswordFromTemporaryCode {}
|
||||||
|
POST listItems/index/key {}
|
||||||
|
POST aggregates/index/key {}
|
||||||
|
POST record/key/to/rec {}
|
||||||
|
GET record/key/to/rec
|
||||||
|
DELETE record/key/to/rec
|
||||||
|
POST appHeirarchy {}
|
||||||
|
POST actionsAndTriggers {}
|
||||||
|
GET appDefinition
|
||||||
|
|
||||||
|
*/
|
|
@ -0,0 +1,5 @@
|
||||||
|
const {hash, verify} = require("argon2");
|
||||||
|
|
||||||
|
module.export = {
|
||||||
|
hash, verify
|
||||||
|
};
|
|
@ -0,0 +1,331 @@
|
||||||
|
{
|
||||||
|
"name": "budibase-server",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@nx-js/compiler-util": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nx-js/compiler-util/-/compiler-util-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-AxSQbwj9zqt8DYPZ6LwZdytqnwfiOEdcFdq4l8sdjkZmU2clTht7RDLCI8xvkp7KqgcNaOGlTeCM55TULWruyQ=="
|
||||||
|
},
|
||||||
|
"accepts": {
|
||||||
|
"version": "1.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
|
||||||
|
"integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
|
||||||
|
"requires": {
|
||||||
|
"mime-types": "~2.1.18",
|
||||||
|
"negotiator": "0.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"any-promise": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
|
||||||
|
"integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
|
||||||
|
},
|
||||||
|
"budibase-core": {
|
||||||
|
"version": "git+ssh://git@gitlab.com/budibase-dist/budibase-core.git#de68bcdf985183061d656d5f995cb4b8ea08d1a0",
|
||||||
|
"from": "git+ssh://git@gitlab.com/budibase-dist/budibase-core.git",
|
||||||
|
"requires": {
|
||||||
|
"@nx-js/compiler-util": "^2.0.0",
|
||||||
|
"date-fns": "^1.29.0",
|
||||||
|
"lodash": "^4.17.11",
|
||||||
|
"papaparse": "^4.3.7",
|
||||||
|
"shortid": "^2.2.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"cache-content-type": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==",
|
||||||
|
"requires": {
|
||||||
|
"mime-types": "^2.1.18",
|
||||||
|
"ylru": "^1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"co": {
|
||||||
|
"version": "4.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
|
||||||
|
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
|
||||||
|
},
|
||||||
|
"content-disposition": {
|
||||||
|
"version": "0.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||||
|
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"content-type": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||||
|
},
|
||||||
|
"cookies": {
|
||||||
|
"version": "0.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.3.tgz",
|
||||||
|
"integrity": "sha512-+gixgxYSgQLTaTIilDHAdlNPZDENDQernEMiIcZpYYP14zgHsCt4Ce1FEjFtcp6GefhozebB6orvhAAWx/IS0A==",
|
||||||
|
"requires": {
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"keygrip": "~1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"date-fns": {
|
||||||
|
"version": "1.30.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
|
||||||
|
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw=="
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deep-equal": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
|
||||||
|
},
|
||||||
|
"delegates": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
|
||||||
|
},
|
||||||
|
"depd": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||||
|
},
|
||||||
|
"destroy": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||||
|
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||||
|
},
|
||||||
|
"ee-first": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||||
|
},
|
||||||
|
"error-inject": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/error-inject/-/error-inject-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc="
|
||||||
|
},
|
||||||
|
"escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||||
|
},
|
||||||
|
"fresh": {
|
||||||
|
"version": "0.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
|
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||||
|
},
|
||||||
|
"http-assert": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-tPVv62a6l3BbQoM/N5qo969l0OFxqpnQzNUPeYfTP6Spo4zkgWeDBD1D5thI7sDLg7jCCihXTLB0X8UtdyAy8A==",
|
||||||
|
"requires": {
|
||||||
|
"deep-equal": "~1.0.1",
|
||||||
|
"http-errors": "~1.7.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"http-errors": {
|
||||||
|
"version": "1.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||||
|
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||||
|
"requires": {
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"setprototypeof": "1.1.1",
|
||||||
|
"statuses": ">= 1.5.0 < 2",
|
||||||
|
"toidentifier": "1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
|
},
|
||||||
|
"is-generator-function": {
|
||||||
|
"version": "1.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.7.tgz",
|
||||||
|
"integrity": "sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw=="
|
||||||
|
},
|
||||||
|
"keygrip": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-/PpesirAIfaklxUzp4Yb7xBper9MwP6hNRA6BGGUFCgbJ+BM5CKBtsoxinNXkLHAr+GXS1/lSlF2rP7cv5Fl+g=="
|
||||||
|
},
|
||||||
|
"koa": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/koa/-/koa-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-7ojD05s2Q+hFudF8tDLZ1CpCdVZw8JQELWSkcfG9bdtoTDzMmkRF6BQBU7JzIzCCOY3xd3tftiy/loHBUYaY2Q==",
|
||||||
|
"requires": {
|
||||||
|
"accepts": "^1.3.5",
|
||||||
|
"cache-content-type": "^1.0.0",
|
||||||
|
"content-disposition": "~0.5.2",
|
||||||
|
"content-type": "^1.0.4",
|
||||||
|
"cookies": "~0.7.1",
|
||||||
|
"debug": "~3.1.0",
|
||||||
|
"delegates": "^1.0.0",
|
||||||
|
"depd": "^1.1.2",
|
||||||
|
"destroy": "^1.0.4",
|
||||||
|
"error-inject": "^1.0.0",
|
||||||
|
"escape-html": "^1.0.3",
|
||||||
|
"fresh": "~0.5.2",
|
||||||
|
"http-assert": "^1.3.0",
|
||||||
|
"http-errors": "^1.6.3",
|
||||||
|
"is-generator-function": "^1.0.7",
|
||||||
|
"koa-compose": "^4.1.0",
|
||||||
|
"koa-convert": "^1.2.0",
|
||||||
|
"koa-is-json": "^1.0.0",
|
||||||
|
"on-finished": "^2.3.0",
|
||||||
|
"only": "~0.0.2",
|
||||||
|
"parseurl": "^1.3.2",
|
||||||
|
"statuses": "^1.5.0",
|
||||||
|
"type-is": "^1.6.16",
|
||||||
|
"vary": "^1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"koa-compose": {
|
||||||
|
"version": "4.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz",
|
||||||
|
"integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw=="
|
||||||
|
},
|
||||||
|
"koa-convert": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA=",
|
||||||
|
"requires": {
|
||||||
|
"co": "^4.6.0",
|
||||||
|
"koa-compose": "^3.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"koa-compose": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-3.2.1.tgz",
|
||||||
|
"integrity": "sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec=",
|
||||||
|
"requires": {
|
||||||
|
"any-promise": "^1.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"koa-is-json": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/koa-is-json/-/koa-is-json-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ="
|
||||||
|
},
|
||||||
|
"lodash": {
|
||||||
|
"version": "4.17.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
||||||
|
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
|
||||||
|
},
|
||||||
|
"media-typer": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||||
|
},
|
||||||
|
"mime-db": {
|
||||||
|
"version": "1.38.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
|
||||||
|
"integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg=="
|
||||||
|
},
|
||||||
|
"mime-types": {
|
||||||
|
"version": "2.1.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
|
||||||
|
"integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
|
||||||
|
"requires": {
|
||||||
|
"mime-db": "~1.38.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
|
},
|
||||||
|
"nanoid": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-k1u2uemjIGsn25zmujKnotgniC/gxQ9sdegdezeDiKdkDW56THUMqlz3urndKCXJxA6yPzSZbXx/QCMe/pxqsA=="
|
||||||
|
},
|
||||||
|
"negotiator": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
|
||||||
|
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
|
||||||
|
},
|
||||||
|
"on-finished": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||||
|
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||||
|
"requires": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"only": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz",
|
||||||
|
"integrity": "sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q="
|
||||||
|
},
|
||||||
|
"papaparse": {
|
||||||
|
"version": "4.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-4.6.3.tgz",
|
||||||
|
"integrity": "sha512-LRq7BrHC2kHPBYSD50aKuw/B/dGcg29omyJbKWY3KsYUZU69RKwaBHu13jGmCYBtOc4odsLCrFyk6imfyNubJQ=="
|
||||||
|
},
|
||||||
|
"parseurl": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
||||||
|
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||||
|
},
|
||||||
|
"setprototypeof": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||||
|
},
|
||||||
|
"shortid": {
|
||||||
|
"version": "2.2.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.14.tgz",
|
||||||
|
"integrity": "sha512-4UnZgr9gDdA1kaKj/38IiudfC3KHKhDc1zi/HSxd9FQDR0VLwH3/y79tZJLsVYPsJgIjeHjqIWaWVRJUj9qZOQ==",
|
||||||
|
"requires": {
|
||||||
|
"nanoid": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"statuses": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||||
|
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||||
|
},
|
||||||
|
"toidentifier": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
|
||||||
|
},
|
||||||
|
"type-is": {
|
||||||
|
"version": "1.6.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
|
||||||
|
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
|
||||||
|
"requires": {
|
||||||
|
"media-typer": "0.3.0",
|
||||||
|
"mime-types": "~2.1.18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||||
|
},
|
||||||
|
"ylru": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ylru/-/ylru-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"name": "budibase-server",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"description": "budibase http api",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"build-core": "cd ./node_modules/budibase-core && rollup --config rollup.config.js"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"budibase"
|
||||||
|
],
|
||||||
|
"author": "Michael Shanks",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"budibase-core": "git+ssh://git@gitlab.com/budibase-dist/budibase-core.git",
|
||||||
|
"koa": "^2.7.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@nx-js/compiler-util@^2.0.0":
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@nx-js/compiler-util/-/compiler-util-2.0.0.tgz#c74c12165fa2f017a292bb79af007e8fce0af297"
|
||||||
|
|
||||||
|
"budibase-core@git+ssh://git@gitlab.com/budibase-dist/budibase-core.git":
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "git+ssh://git@gitlab.com/budibase-dist/budibase-core.git#99f1604b1314a3687312820b783256440c3a57f1"
|
||||||
|
dependencies:
|
||||||
|
"@nx-js/compiler-util" "^2.0.0"
|
||||||
|
date-fns "^1.29.0"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
papaparse "^4.3.7"
|
||||||
|
shortid "^2.2.8"
|
||||||
|
|
||||||
|
date-fns@^1.29.0:
|
||||||
|
version "1.30.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
|
||||||
|
|
||||||
|
lodash@^4.17.11:
|
||||||
|
version "4.17.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
|
||||||
|
|
||||||
|
nanoid@^2.0.0:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.0.1.tgz#deb55cac196e3f138071911dabbc3726eb048864"
|
||||||
|
|
||||||
|
papaparse@^4.3.7:
|
||||||
|
version "4.6.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/papaparse/-/papaparse-4.6.3.tgz#742e5eaaa97fa6c7e1358d2934d8f18f44aee781"
|
||||||
|
|
||||||
|
shortid@^2.2.8:
|
||||||
|
version "2.2.14"
|
||||||
|
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.14.tgz#80db6aafcbc3e3a46850b3c88d39e051b84c8d18"
|
||||||
|
dependencies:
|
||||||
|
nanoid "^2.0.0"
|
Loading…
Reference in New Issue