mirror of https://github.com/Budibase/budibase.git
commit
a8aa18d01d
28 changed files with 6808 additions and 0 deletions
@ -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
@ -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
@ -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