diff --git a/packages/server/appPackages/master/appDefinition.json b/packages/server/appPackages/master/appDefinition.json index 5cb778ac4..29f29fa89 100644 --- a/packages/server/appPackages/master/appDefinition.json +++ b/packages/server/appPackages/master/appDefinition.json @@ -1 +1,437 @@ -{"hierarchy":{"name":"root","type":"root","children":[{"name":"application","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":500,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"domain","type":"string","typeOptions":{"maxLength":500,"values":null,"allowDeclaredValuesOnly":false},"label":"domain","getInitialValue":"default","getUndefinedValue":"default"},{"name":"application_resolve_strategy","type":"string","typeOptions":{"maxLength":100,"values":["domain","path"],"allowDeclaredValuesOnly":true},"label":"Resolve Application By","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"user","type":"record","fields":[{"name":"unique_name","type":"string","typeOptions":{"maxLength":200,"values":null,"allowDeclaredValuesOnly":false},"label":"Name (unique)","getInitialValue":"default","getUndefinedValue":"default"},{"name":"active","type":"bool","typeOptions":{"allowNulls":false},"label":"Is Active","getInitialValue":"default","getUndefinedValue":"default"},{"name":"instance","type":"reference","typeOptions":{"indexNodeKey":"/applications/1-{id}/allinstances","reverseIndexNodeKeys":["/applications/1-{id}/instances/2-{id}/users_on_this_instance"],"displayValue":"name"},"label":"Instance","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":8,"indexes":[],"allidsShardFactor":"64","collectionName":"users","isSingle":false},{"name":"instance","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"active","type":"bool","typeOptions":{"allowNulls":false},"label":"Is Active","getInitialValue":"default","getUndefinedValue":"default"},{"name":"version","type":"reference","typeOptions":{"indexNodeKey":"/applications/1-{id}/all_versions","reverseIndexNodeKeys":["/applications/1-{id}/versions/3-{id}/instances_on_this_version"],"displayValue":"name"},"label":"Version","getInitialValue":"default","getUndefinedValue":"default"},{"name":"datastoreconfig","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"Datastore Config","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[{"name":"users_on_this_instance","type":"index","map":"return {...record};","filter":"","indexType":"reference","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":15}],"allidsShardFactor":1,"collectionName":"instances","isSingle":false},{"name":"version","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":200,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":3,"indexes":[{"name":"instances_for_this_version","type":"index","map":"return {name:record.name};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":9},{"name":"instances_on_this_version","type":"index","map":"return {...record};","filter":"","indexType":"reference","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":10}],"allidsShardFactor":1,"collectionName":"versions","isSingle":false},{"name":"session","type":"record","fields":[{"name":"created","type":"number","typeOptions":{"minValue":0,"maxValue":99999999999999,"decimalPlaces":0},"label":"Created","getInitialValue":"default","getUndefinedValue":"default"},{"name":"user_json","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User Json","getInitialValue":"default","getUndefinedValue":"default"},{"name":"instanceDatastoreConfig","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"Instance Datastore Config","getInitialValue":"default","getUndefinedValue":"default"},{"name":"username","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":16,"indexes":[],"allidsShardFactor":1,"collectionName":"sessions","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[{"name":"allinstances","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":23},{"name":"sessions_by_user","type":"index","map":"return {username:record.username};","filter":"","indexType":"ancestor","getShardName":"return record.username.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[16],"nodeId":24},{"name":"user_name_lookup","type":"index","map":"return {name:record.name, instanceDatastoreConfig:instance.datastoreconfig};","filter":"","indexType":"ancestor","getShardName":"return record.name.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[8],"nodeId":25},{"name":"all_versions","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[3],"nodeId":26}],"allidsShardFactor":64,"collectionName":"applications","isSingle":false},{"name":"mastersession","type":"record","fields":[{"name":"user_json","type":"string","typeOptions":{"maxLength":10000,"values":null,"allowDeclaredValuesOnly":false},"label":"User Json","getInitialValue":"default","getUndefinedValue":"default"},{"name":"username","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":17,"indexes":[],"allidsShardFactor":64,"collectionName":"sessions","isSingle":false}],"pathMaps":[],"indexes":[{"name":"all_applications","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":22},{"name":"mastersessions_by_user","type":"index","map":"return {username:record.username};","filter":"","indexType":"ancestor","getShardName":"return record.username.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[17],"nodeId":27}],"nodeId":0},"actions":{},"triggers":[]} \ No newline at end of file +{ + "hierarchy": { + "name": "root", + "type": "root", + "children": [ + { + "name": "application", + "type": "record", + "fields": [ + { + "name": "name", + "type": "string", + "typeOptions": { + "maxLength": 500, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Name", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "domain", + "type": "string", + "typeOptions": { + "maxLength": 500, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "domain", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "application_resolve_strategy", + "type": "string", + "typeOptions": { + "maxLength": 100, + "values": [ + "domain", + "path" + ], + "allowDeclaredValuesOnly": true + }, + "label": "Resolve Application By", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [ + { + "name": "user", + "type": "record", + "fields": [ + { + "name": "unique_name", + "type": "string", + "typeOptions": { + "maxLength": 200, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Name (unique)", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "active", + "type": "bool", + "typeOptions": { + "allowNulls": false + }, + "label": "Is Active", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "instance", + "type": "reference", + "typeOptions": { + "indexNodeKey": "/applications/1-{id}/allinstances", + "reverseIndexNodeKeys": [ + "/applications/1-{id}/instances/2-{id}/users_on_this_instance" + ], + "displayValue": "name" + }, + "label": "Instance", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 8, + "indexes": [], + "allidsShardFactor": "64", + "collectionName": "users", + "isSingle": false + }, + { + "name": "instance", + "type": "record", + "fields": [ + { + "name": "name", + "type": "string", + "typeOptions": { + "maxLength": 1000, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Name", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "active", + "type": "bool", + "typeOptions": { + "allowNulls": false + }, + "label": "Is Active", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "version", + "type": "reference", + "typeOptions": { + "indexNodeKey": "/applications/1-{id}/all_versions", + "reverseIndexNodeKeys": [ + "/applications/1-{id}/versions/3-{id}/instances_on_this_version" + ], + "displayValue": "name" + }, + "label": "Version", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "datastoreconfig", + "type": "string", + "typeOptions": { + "maxLength": 1000, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Datastore Config", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 2, + "indexes": [ + { + "name": "users_on_this_instance", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "reference", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [], + "nodeId": 15 + } + ], + "allidsShardFactor": 1, + "collectionName": "instances", + "isSingle": false + }, + { + "name": "version", + "type": "record", + "fields": [ + { + "name": "name", + "type": "string", + "typeOptions": { + "maxLength": 200, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Name", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 3, + "indexes": [ + { + "name": "instances_for_this_version", + "type": "index", + "map": "return {name:record.name};", + "filter": "", + "indexType": "ancestor", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [], + "nodeId": 9 + }, + { + "name": "instances_on_this_version", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "reference", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [], + "nodeId": 10 + } + ], + "allidsShardFactor": 1, + "collectionName": "versions", + "isSingle": false + }, + { + "name": "session", + "type": "record", + "fields": [ + { + "name": "created", + "type": "number", + "typeOptions": { + "minValue": 0, + "maxValue": 99999999999999, + "decimalPlaces": 0 + }, + "label": "Created", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "user_json", + "type": "string", + "typeOptions": { + "maxLength": null, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "User Json", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "instanceDatastoreConfig", + "type": "string", + "typeOptions": { + "maxLength": null, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "Instance Datastore Config", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "username", + "type": "string", + "typeOptions": { + "maxLength": null, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "User", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 16, + "indexes": [], + "allidsShardFactor": 1, + "collectionName": "sessions", + "isSingle": false + } + ], + "validationRules": [], + "nodeId": 1, + "indexes": [ + { + "name": "allinstances", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "ancestor", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 2 + ], + "nodeId": 23 + }, + { + "name": "sessions_by_user", + "type": "index", + "map": "return {username:record.username};", + "filter": "", + "indexType": "ancestor", + "getShardName": "return record.username.substring(0,2)", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 16 + ], + "nodeId": 24 + }, + { + "name": "user_name_lookup", + "type": "index", + "map": "return {name:record.name, instanceDatastoreConfig:instance.datastoreconfig};", + "filter": "", + "indexType": "ancestor", + "getShardName": "return record.name.substring(0,2)", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 8 + ], + "nodeId": 25 + }, + { + "name": "all_versions", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "ancestor", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 3 + ], + "nodeId": 26 + } + ], + "allidsShardFactor": 64, + "collectionName": "applications", + "isSingle": false + }, + { + "name": "mastersession", + "type": "record", + "fields": [ + { + "name": "user_json", + "type": "string", + "typeOptions": { + "maxLength": 10000, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "User Json", + "getInitialValue": "default", + "getUndefinedValue": "default" + }, + { + "name": "username", + "type": "string", + "typeOptions": { + "maxLength": null, + "values": null, + "allowDeclaredValuesOnly": false + }, + "label": "User", + "getInitialValue": "default", + "getUndefinedValue": "default" + } + ], + "children": [], + "validationRules": [], + "nodeId": 17, + "indexes": [], + "allidsShardFactor": 64, + "collectionName": "sessions", + "isSingle": false + } + ], + "pathMaps": [], + "indexes": [ + { + "name": "all_applications", + "type": "index", + "map": "return {...record};", + "filter": "", + "indexType": "ancestor", + "getShardName": "", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 1 + ], + "nodeId": 22 + }, + { + "name": "mastersessions_by_user", + "type": "index", + "map": "return {username:record.username};", + "filter": "", + "indexType": "ancestor", + "getShardName": "return record.username.substring(0,2)", + "getSortKey": "record.id", + "aggregateGroups": [], + "allowedRecordNodeIds": [ + 17 + ], + "nodeId": 27 + } + ], + "nodeId": 0 + }, + "actions": { + "initialise_instance": { + "name": "initialise_instance", + "behaviourSource": "main", + "behaviourName": "initialiseInstance", + "initialOptions": {} + } + }, + "triggers": [ + { + "actionName": "initialise_instance", + "eventName": "recordApi:save:onRecordCreated", + "optionsCreator": "return { instance:context.record, apis };", + "condition": "context.record.type === \"instance\"" + } + ] +} \ No newline at end of file diff --git a/packages/server/appPackages/master/main.js b/packages/server/appPackages/master/main.js index a5f106176..2ac149734 100644 --- a/packages/server/appPackages/master/main.js +++ b/packages/server/appPackages/master/main.js @@ -2,24 +2,26 @@ const { tmpdir } = require("os"); const { join } = require("path"); const uuid = require("uuid/v1"); const { take, takeRight } = require("lodash/fp"); -const { splitKey, $ } = require("budibase-core").common; +const { splitKey, $, joinKey } = require("budibase-core").common; const { unzipTarGzPackageToRuntime } = require("../../utilities/targzAppPackage"); const { getRuntimePackageDirectory } = require("../../utilities/runtimePackages"); const { exists } = require("../../utilities/fsawait"); const createInstanceDb = require("../../initialise/createInstanceDb"); +const { createWriteStream } = require("fs"); module.exports = (config) => ({ initialiseInstance : async ({ instance, apis }) => { - const appKey = $(instance.key, [ splitKey, - take(2) + take(2), + joinKey ]); const application = await apis.recordApi.load(appKey); + const datastoreModule = require(`../../../datastores/datastores/${config.datastore}`); const dbConfig = await createInstanceDb( - require(config.datastore), + datastoreModule, config.datastoreConfig, application.id, instance.id @@ -27,7 +29,8 @@ module.exports = (config) => ({ const versionId = $(instance.version.key, [ splitKey, - takeRight(1) + takeRight(1), + joinKey ]); const runtimeDir = getRuntimePackageDirectory( @@ -35,7 +38,7 @@ module.exports = (config) => ({ versionId); if(!await exists(runtimeDir)) - await downloadAppPackage(instance, application.name, versionId); + await downloadAppPackage(apis, instance, application.name, versionId); instance.datastoreconfig = JSON.stringify(dbConfig); instance.isNew = false; @@ -43,12 +46,11 @@ module.exports = (config) => ({ } }); -const downloadAppPackage = async (instance, appName, versionId) => { - const inputStream = apis.recordApi.downloadFile(instance.key, "package.tar.gz"); +const downloadAppPackage = async (apis, instance, appName, versionId) => { + const inputStream = await apis.recordApi.downloadFile(instance.version.key, "package.tar.gz"); const tempFilePath = join(tmpdir(), `bbpackage_${uuid()}.tar.gz`); - const outputStream = await app.datastore.writableFileStream( - tempFilePath); + const outputStream = createWriteStream(tempFilePath); await new Promise((resolve,reject) => { inputStream.pipe(outputStream); diff --git a/packages/server/appPackages/testApp/dist/package.tar.gz b/packages/server/appPackages/testApp/dist/package.tar.gz index 3d913d83a..35f3f0edf 100644 Binary files a/packages/server/appPackages/testApp/dist/package.tar.gz and b/packages/server/appPackages/testApp/dist/package.tar.gz differ diff --git a/packages/server/initialise/createInstanceDb.js b/packages/server/initialise/createInstanceDb.js index a5486abe1..d0996c0a7 100644 --- a/packages/server/initialise/createInstanceDb.js +++ b/packages/server/initialise/createInstanceDb.js @@ -3,14 +3,8 @@ const { setupDatastore } = require("budibase-core"); const constructHierarchy = require("../utilities/constructHierarchy"); -const getDatabaseManager = require("../utilities/databaseManager"); -const { - getApisForUser, - getApisWithFullAccess -} = require("../utilities/budibaseApi"); +const getDatabaseManager = require("../utilities/databaseManager"); const masterDbAppDefinition = require("../appPackages/master/appDefinition.json"); -const masterDbAccessLevels = require("../appPackages/master/access_levels.json"); -const { masterAppPackage } = require("../utilities/createAppPackage"); module.exports = async (datastoreModule, rootDatastoreConfig, appId, instanceId) => { try { diff --git a/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/access_levels.json b/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/access_levels.json new file mode 100644 index 000000000..ebb7ca11a --- /dev/null +++ b/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/access_levels.json @@ -0,0 +1 @@ +{"levels":[{"name":"owner","permissions":[{"type":"create record","nodeKey":"/applications/1-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}"},{"type":"create record","nodeKey":"/applications/1-{id}/users/8-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}/users/8-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}/users/8-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}/users/8-{id}"},{"type":"create record","nodeKey":"/applications/1-{id}/instances/2-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}/instances/2-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}/instances/2-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}/instances/2-{id}"},{"type":"create record","nodeKey":"/applications/1-{id}/versions/3-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}/versions/3-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}/versions/3-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}/versions/3-{id}"},{"type":"create record","nodeKey":"/applications/1-{id}/sessions/16-{id}"},{"type":"update record","nodeKey":"/applications/1-{id}/sessions/16-{id}"},{"type":"delete record","nodeKey":"/applications/1-{id}/sessions/16-{id}"},{"type":"read record","nodeKey":"/applications/1-{id}/sessions/16-{id}"},{"type":"create record","nodeKey":"/sessions/17-{id}"},{"type":"update record","nodeKey":"/sessions/17-{id}"},{"type":"delete record","nodeKey":"/sessions/17-{id}"},{"type":"read record","nodeKey":"/sessions/17-{id}"},{"type":"read index","nodeKey":"/mastersessions_by_user"},{"type":"read index","nodeKey":"/all_applications"},{"type":"read index","nodeKey":"/applications/1-{id}/allinstances"},{"type":"read index","nodeKey":"/applications/1-{id}/sessions_by_user"},{"type":"read index","nodeKey":"/applications/1-{id}/user_name_lookup"},{"type":"read index","nodeKey":"/applications/1-{id}/all_versions"},{"type":"read index","nodeKey":"/applications/1-{id}/instances/2-{id}/users_on_this_instance"},{"type":"read index","nodeKey":"/applications/1-{id}/versions/3-{id}/instances_for_this_version"},{"type":"read index","nodeKey":"/applications/1-{id}/versions/3-{id}/instances_on_this_version"},{"type":"write templates"},{"type":"create user"},{"type":"set password"},{"type":"create temporary access"},{"type":"enable or disable user"},{"type":"write access levels"},{"type":"list users"},{"type":"list access levels"},{"type":"manage index"},{"type":"manage collection"},{"type":"set user access levels"}]}],"version":0} \ No newline at end of file diff --git a/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/appDefinition.json b/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/appDefinition.json new file mode 100644 index 000000000..61f0510f5 --- /dev/null +++ b/packages/server/runtime_apps/testApp/3-dYHF49T8Oyo/appDefinition.json @@ -0,0 +1 @@ +{"hierarchy":{"name":"root","type":"root","children":[{"name":"application","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":500,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"domain","type":"string","typeOptions":{"maxLength":500,"values":null,"allowDeclaredValuesOnly":false},"label":"domain","getInitialValue":"default","getUndefinedValue":"default"},{"name":"application_resolve_strategy","type":"string","typeOptions":{"maxLength":100,"values":["domain","path"],"allowDeclaredValuesOnly":true},"label":"Resolve Application By","getInitialValue":"default","getUndefinedValue":"default"}],"children":[{"name":"user","type":"record","fields":[{"name":"unique_name","type":"string","typeOptions":{"maxLength":200,"values":null,"allowDeclaredValuesOnly":false},"label":"Name (unique)","getInitialValue":"default","getUndefinedValue":"default"},{"name":"active","type":"bool","typeOptions":{"allowNulls":false},"label":"Is Active","getInitialValue":"default","getUndefinedValue":"default"},{"name":"instance","type":"reference","typeOptions":{"indexNodeKey":"/applications/1-{id}/allinstances","reverseIndexNodeKeys":["/applications/1-{id}/instances/2-{id}/users_on_this_instance"],"displayValue":"name"},"label":"Instance","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":8,"indexes":[],"allidsShardFactor":"64","collectionName":"users","isSingle":false},{"name":"instance","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"active","type":"bool","typeOptions":{"allowNulls":false},"label":"Is Active","getInitialValue":"default","getUndefinedValue":"default"},{"name":"version","type":"reference","typeOptions":{"indexNodeKey":"/applications/1-{id}/all_versions","reverseIndexNodeKeys":["/applications/1-{id}/versions/3-{id}/instances_on_this_version"],"displayValue":"name"},"label":"Version","getInitialValue":"default","getUndefinedValue":"default"},{"name":"datastoreconfig","type":"string","typeOptions":{"maxLength":1000,"values":null,"allowDeclaredValuesOnly":false},"label":"Datastore Config","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":2,"indexes":[{"name":"users_on_this_instance","type":"index","map":"return {...record};","filter":"","indexType":"reference","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":15}],"allidsShardFactor":1,"collectionName":"instances","isSingle":false},{"name":"version","type":"record","fields":[{"name":"name","type":"string","typeOptions":{"maxLength":200,"values":null,"allowDeclaredValuesOnly":false},"label":"Name","getInitialValue":"default","getUndefinedValue":"default"},{"name":"package","type":"file","typeOptions":{},"label":"Package","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":3,"indexes":[{"name":"instances_for_this_version","type":"index","map":"return {name:record.name};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":9},{"name":"instances_on_this_version","type":"index","map":"return {...record};","filter":"","indexType":"reference","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[],"nodeId":10}],"allidsShardFactor":1,"collectionName":"versions","isSingle":false},{"name":"session","type":"record","fields":[{"name":"created","type":"number","typeOptions":{"minValue":0,"maxValue":99999999999999,"decimalPlaces":0},"label":"Created","getInitialValue":"default","getUndefinedValue":"default"},{"name":"user_json","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User Json","getInitialValue":"default","getUndefinedValue":"default"},{"name":"instanceDatastoreConfig","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"Instance Datastore Config","getInitialValue":"default","getUndefinedValue":"default"},{"name":"username","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":16,"indexes":[],"allidsShardFactor":1,"collectionName":"sessions","isSingle":false}],"validationRules":[],"nodeId":1,"indexes":[{"name":"allinstances","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[2],"nodeId":23},{"name":"sessions_by_user","type":"index","map":"return {username:record.username};","filter":"","indexType":"ancestor","getShardName":"return record.username.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[16],"nodeId":24},{"name":"user_name_lookup","type":"index","map":"return {name:record.name, instanceDatastoreConfig:instance.datastoreconfig};","filter":"","indexType":"ancestor","getShardName":"return record.name.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[8],"nodeId":25},{"name":"all_versions","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[3],"nodeId":26}],"allidsShardFactor":64,"collectionName":"applications","isSingle":false},{"name":"mastersession","type":"record","fields":[{"name":"user_json","type":"string","typeOptions":{"maxLength":10000,"values":null,"allowDeclaredValuesOnly":false},"label":"User Json","getInitialValue":"default","getUndefinedValue":"default"},{"name":"username","type":"string","typeOptions":{"maxLength":null,"values":null,"allowDeclaredValuesOnly":false},"label":"User","getInitialValue":"default","getUndefinedValue":"default"}],"children":[],"validationRules":[],"nodeId":17,"indexes":[],"allidsShardFactor":64,"collectionName":"sessions","isSingle":false}],"pathMaps":[],"indexes":[{"name":"all_applications","type":"index","map":"return {...record};","filter":"","indexType":"ancestor","getShardName":"","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[1],"nodeId":22},{"name":"mastersessions_by_user","type":"index","map":"return {username:record.username};","filter":"","indexType":"ancestor","getShardName":"return record.username.substring(0,2)","getSortKey":"record.id","aggregateGroups":[],"allowedRecordNodeIds":[17],"nodeId":27}],"nodeId":0},"actions":{},"triggers":[]} \ No newline at end of file diff --git a/packages/server/tests/createNewApp.js b/packages/server/tests/createNewApp.js index 8d216e3b5..07449fe8b 100644 --- a/packages/server/tests/createNewApp.js +++ b/packages/server/tests/createNewApp.js @@ -57,6 +57,7 @@ module.exports = (app) => { }); + let instance1Key; it("should be able to create new instance of app", async () => { const master = await getmaster(); const instance1 = master.recordApi @@ -64,7 +65,11 @@ module.exports = (app) => { instance1.name = "instance 1"; instance1.active = true; instance1.version = {key:version1Key, name:"v1"}; - instance1.datastoreconfig; + instance1Key = instance1.key; + + await app.post(`/_master/api/record/${instance1.key}`, instance1) + .set("cookie", app.masterAuth.cookie) + .expect(statusCodes.OK); }); diff --git a/packages/server/tests/testApp.js b/packages/server/tests/testApp.js index 93c37a281..8fffaba32 100644 --- a/packages/server/tests/testApp.js +++ b/packages/server/tests/testApp.js @@ -11,7 +11,7 @@ const masterOwnerName = "test_master"; const masterOwnerPassword = "test_master_pass"; const extraMasterPlugins = { - main: { + test_plugins: { outputToFile : ({filename, content}) => { fs.writeFile(`./tests/.data/${filename}`, content, {encoding:"utf8"}); } @@ -22,7 +22,7 @@ const customizeMaster = appDefinition => { appDefinition.actions.outputToFile = { name: 'outputToFile', - behaviourSource: 'main', + behaviourSource: 'test_plugins', behaviourName: 'outputToFile', initialOptions: {} }; diff --git a/packages/server/utilities/runtimePackages.js b/packages/server/utilities/runtimePackages.js index d7859d489..4b21e6592 100644 --- a/packages/server/utilities/runtimePackages.js +++ b/packages/server/utilities/runtimePackages.js @@ -2,7 +2,14 @@ const { join } = require("path"); const runtimePackagesDirectory = "./runtime_apps"; +const getRuntimeAppsDirectory = (appName) => + join(runtimePackagesDirectory, appName); + module.exports.runtimePackagesDirectory = runtimePackagesDirectory; module.exports.getRuntimePackageDirectory = (appName, versionId) => - join(runtimePackagesDirectory, appName, versionId); + join( + getRuntimeAppsDirectory(appName), + versionId); + +module.exports.getRuntimeAppsDirectory = getRuntimeAppsDirectory; diff --git a/packages/server/utilities/targzAppPackage.js b/packages/server/utilities/targzAppPackage.js index 684457fa3..b35f3f08a 100644 --- a/packages/server/utilities/targzAppPackage.js +++ b/packages/server/utilities/targzAppPackage.js @@ -6,7 +6,7 @@ const tar = require('tar-fs'); const zlib = require("zlib"); const { join, dirname, sep } = require("path"); const { exists, mkdir, unlink, stat } = require("../utilities/fsawait"); -const { getRuntimePackageDirectory } = require("./runtimePackages"); +const { getRuntimePackageDirectory, getRuntimeAppsDirectory } = require("./runtimePackages"); module.exports.createTarGzPackage = async (config, appName) => { @@ -29,14 +29,19 @@ module.exports.createTarGzPackage = async (config, appName) => { module.exports.unzipTarGzPackageToRuntime = async (src, appName, versionId) => { const versionDir = getRuntimePackageDirectory(appName, versionId); - - if(await exists(versionDir)) { - await rimraf(versionDir); + const appDir = getRuntimeAppsDirectory(appName); + + if(await exists(appDir)) { + if(await exists(versionDir)) { + await rimraf(versionDir); + } + } else { + await mkdir(appDir); } await mkdir(versionDir); - decompress(src, versionDir); + await decompress(src, versionDir); } const compress = (src, dest) => new Promise((resolve, reject) => {