forked from tsai/budibase
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