+ {#each meta as { placeholder }, i}
+ {#each propertyChoices as [displayName, [cssPropValue, icon]]}
+
+ {/each}
+ {/each}
+
+
+
diff --git a/packages/builder/src/userInterface/UserInterfaceRoot.svelte b/packages/builder/src/userInterface/UserInterfaceRoot.svelte
index bfe8ee4a99..18ad131923 100644
--- a/packages/builder/src/userInterface/UserInterfaceRoot.svelte
+++ b/packages/builder/src/userInterface/UserInterfaceRoot.svelte
@@ -128,7 +128,7 @@
.preview-pane {
grid-column: 2;
- margin: 80px 60px;
+ margin: 40px;
background: #fff;
border-radius: 5px;
box-shadow: 0 0px 6px rgba(0, 0, 0, 0.05);
diff --git a/packages/materialdesign-components/src/Templates/indexDatatable.js b/packages/materialdesign-components/src/Templates/indexDatatable.js
index 3ae9da003a..8c0ba95b47 100644
--- a/packages/materialdesign-components/src/Templates/indexDatatable.js
+++ b/packages/materialdesign-components/src/Templates/indexDatatable.js
@@ -37,7 +37,7 @@ const tableProps = (index, indexSchema) => ({
{
"##eventHandlerType": "List Records",
parameters: {
- indexKey:index.nodeKey(),
+ indexKey: index.nodeKey(),
statePath: index.name,
},
},
@@ -53,6 +53,7 @@ const columnHeaders = indexSchema =>
_component: "@budibase/standard-components/text",
type: "none",
text: col.name,
+ formattingTag: " - bold",
},
],
}))
diff --git a/packages/server/appPackages/testApp/yarn.lock b/packages/server/appPackages/testApp/yarn.lock
index 6471f44f81..5e94af9630 100644
--- a/packages/server/appPackages/testApp/yarn.lock
+++ b/packages/server/appPackages/testApp/yarn.lock
@@ -3,17 +3,19 @@
"@budibase/client@file:../../../client":
- version "0.0.16"
+ version "0.0.27"
dependencies:
"@nx-js/compiler-util" "^2.0.0"
bcryptjs "^2.4.3"
+ deep-equal "^2.0.1"
lodash "^4.17.15"
lunr "^2.3.5"
+ regexparam "^1.3.0"
shortid "^2.2.8"
svelte "^3.9.2"
"@budibase/standard-components@file:../../../standard-components":
- version "0.0.16"
+ version "0.0.27"
"@nx-js/compiler-util@^2.0.0":
version "2.0.0"
@@ -25,6 +27,161 @@ bcryptjs@^2.4.3:
resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
+deep-equal@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.1.tgz#fc12bbd6850e93212f21344748682ccc5a8813cf"
+ integrity sha512-7Et6r6XfNW61CPPCIYfm1YPGSmh6+CliYeL4km7GWJcpX5LTAflGF8drLLR+MZX+2P3NZfAfSduutBbSWqER4g==
+ dependencies:
+ es-abstract "^1.16.3"
+ es-get-iterator "^1.0.1"
+ is-arguments "^1.0.4"
+ is-date-object "^1.0.1"
+ is-regex "^1.0.4"
+ isarray "^2.0.5"
+ object-is "^1.0.1"
+ object-keys "^1.1.1"
+ regexp.prototype.flags "^1.2.0"
+ side-channel "^1.0.1"
+ which-boxed-primitive "^1.0.1"
+ which-collection "^1.0.0"
+
+define-properties@^1.1.2, define-properties@^1.1.3:
+ version "1.1.3"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
+ integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
+ dependencies:
+ object-keys "^1.0.12"
+
+es-abstract@^1.16.3, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4:
+ version "1.17.4"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184"
+ integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==
+ dependencies:
+ es-to-primitive "^1.2.1"
+ function-bind "^1.1.1"
+ has "^1.0.3"
+ has-symbols "^1.0.1"
+ is-callable "^1.1.5"
+ is-regex "^1.0.5"
+ object-inspect "^1.7.0"
+ object-keys "^1.1.1"
+ object.assign "^4.1.0"
+ string.prototype.trimleft "^2.1.1"
+ string.prototype.trimright "^2.1.1"
+
+es-get-iterator@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8"
+ integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==
+ dependencies:
+ es-abstract "^1.17.4"
+ has-symbols "^1.0.1"
+ is-arguments "^1.0.4"
+ is-map "^2.0.1"
+ is-set "^2.0.1"
+ is-string "^1.0.5"
+ isarray "^2.0.5"
+
+es-to-primitive@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
+ integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
+ dependencies:
+ is-callable "^1.1.4"
+ is-date-object "^1.0.1"
+ is-symbol "^1.0.2"
+
+function-bind@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
+ integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
+
+has-symbols@^1.0.0, has-symbols@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
+ integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
+
+has@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
+ integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
+ dependencies:
+ function-bind "^1.1.1"
+
+is-arguments@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3"
+ integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==
+
+is-bigint@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.0.tgz#73da8c33208d00f130e9b5e15d23eac9215601c4"
+ integrity sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g==
+
+is-boolean-object@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e"
+ integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==
+
+is-callable@^1.1.4, is-callable@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
+ integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
+
+is-date-object@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
+ integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
+
+is-map@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1"
+ integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==
+
+is-number-object@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197"
+ integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==
+
+is-regex@^1.0.4, is-regex@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
+ integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
+ dependencies:
+ has "^1.0.3"
+
+is-set@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43"
+ integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==
+
+is-string@^1.0.4, is-string@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
+ integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==
+
+is-symbol@^1.0.2:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
+ integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==
+ dependencies:
+ has-symbols "^1.0.1"
+
+is-weakmap@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2"
+ integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==
+
+is-weakset@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83"
+ integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw==
+
+isarray@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
+ integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
+
lodash@^4.17.15:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
@@ -40,6 +197,44 @@ nanoid@^2.1.0:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.0.tgz#3de3dbd68cfb2f3bd52550e2bfd439cf75040eb2"
integrity sha512-g5WwS+p6Cm+zQhO2YOpRbQThZVnNb7DDq74h8YDCLfAGynrEOrbx2E16dc8ciENiP1va5sqaAruqn2sN+xpkWg==
+object-inspect@^1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
+ integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==
+
+object-is@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4"
+ integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==
+
+object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
+ integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
+
+object.assign@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
+ integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
+ dependencies:
+ define-properties "^1.1.2"
+ function-bind "^1.1.1"
+ has-symbols "^1.0.0"
+ object-keys "^1.0.11"
+
+regexp.prototype.flags@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75"
+ integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==
+ dependencies:
+ define-properties "^1.1.3"
+ es-abstract "^1.17.0-next.1"
+
+regexparam@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
+ integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
+
shortid@^2.2.8:
version "2.2.15"
resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
@@ -47,7 +242,52 @@ shortid@^2.2.8:
dependencies:
nanoid "^2.1.0"
+side-channel@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947"
+ integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==
+ dependencies:
+ es-abstract "^1.17.0-next.1"
+ object-inspect "^1.7.0"
+
+string.prototype.trimleft@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74"
+ integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==
+ dependencies:
+ define-properties "^1.1.3"
+ function-bind "^1.1.1"
+
+string.prototype.trimright@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9"
+ integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==
+ dependencies:
+ define-properties "^1.1.3"
+ function-bind "^1.1.1"
+
svelte@^3.9.2:
version "3.12.1"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.12.1.tgz#ddfacd43272ac3255907c682b74ee7d3d8b06b0c"
integrity sha512-t29WJNjHIqfrdMcVXqIyRfgLEaNz7MihKXTpb8qHlbzvf0WyOOIhIlwIGvl6ahJ9+9CLJwz0sjhFNAmPgo8BHg==
+
+which-boxed-primitive@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz#cbe8f838ebe91ba2471bb69e9edbda67ab5a5ec1"
+ integrity sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==
+ dependencies:
+ is-bigint "^1.0.0"
+ is-boolean-object "^1.0.0"
+ is-number-object "^1.0.3"
+ is-string "^1.0.4"
+ is-symbol "^1.0.2"
+
+which-collection@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906"
+ integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==
+ dependencies:
+ is-map "^2.0.1"
+ is-set "^2.0.1"
+ is-weakmap "^2.0.1"
+ is-weakset "^2.0.1"
diff --git a/packages/server/builder/assets/budibase-emblem-white.svg b/packages/server/builder/assets/budibase-emblem-white.svg
new file mode 100644
index 0000000000..728e859260
--- /dev/null
+++ b/packages/server/builder/assets/budibase-emblem-white.svg
@@ -0,0 +1,29 @@
+
+
+
diff --git a/packages/server/middleware/routeHandlers/aggregatesPost.js b/packages/server/middleware/routeHandlers/aggregatesPost.js
new file mode 100644
index 0000000000..8b2af0c84f
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/aggregatesPost.js
@@ -0,0 +1,12 @@
+const StatusCodes = require("../../utilities/statusCodes")
+const { getRecordKey } = require("./helpers")
+
+module.exports = async ctx => {
+ const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
+ ctx.body = await ctx.instance.indexApi.aggregates(indexkey, {
+ rangeStartParams: ctx.request.body.rangeStartParams,
+ rangeEndParams: ctx.request.body.rangeEndParams,
+ searchPhrase: ctx.request.body.searchPhrase,
+ })
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/appDefault.js b/packages/server/middleware/routeHandlers/appDefault.js
new file mode 100644
index 0000000000..61dd9520de
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/appDefault.js
@@ -0,0 +1,19 @@
+const send = require("koa-send")
+
+module.exports = async (ctx, next) => {
+ const path = ctx.path.replace(`/${ctx.params.appname}`, "")
+
+ if (path.startsWith("/api/")) {
+ await next()
+ } else if (path.startsWith("/_shared/")) {
+ await send(ctx, path.replace(`/_shared/`, ""), { root: ctx.sharedPath })
+ } else if (
+ path.endsWith(".js") ||
+ path.endsWith(".map") ||
+ path.endsWith(".css")
+ ) {
+ await send(ctx, path, { root: ctx.publicPath })
+ } else {
+ await send(ctx, "/index.html", { root: ctx.publicPath })
+ }
+}
diff --git a/packages/server/middleware/routeHandlers/authenticate.js b/packages/server/middleware/routeHandlers/authenticate.js
new file mode 100644
index 0000000000..263c545907
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/authenticate.js
@@ -0,0 +1,15 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ const user = await ctx.master.authenticate(
+ ctx.sessionId,
+ ctx.params.appname,
+ ctx.request.body.username,
+ ctx.request.body.password
+ )
+ if (!user) {
+ ctx.throw(StatusCodes.UNAUTHORIZED, "invalid username or password")
+ }
+ ctx.body = user.user_json
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/changeMyPassword.js b/packages/server/middleware/routeHandlers/changeMyPassword.js
new file mode 100644
index 0000000000..5f7d63979c
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/changeMyPassword.js
@@ -0,0 +1,9 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ await ctx.instance.authApi.changeMyPassword(
+ ctx.request.body.currentPassword,
+ ctx.request.body.newPassword
+ )
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/createTemporaryAccess.js b/packages/server/middleware/routeHandlers/createTemporaryAccess.js
new file mode 100644
index 0000000000..8189e3027a
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/createTemporaryAccess.js
@@ -0,0 +1,17 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
+ ctx.params.appname,
+ ctx.request.body.username
+ )
+
+ if (!instanceApi) {
+ ctx.request.status = StatusCodes.OK
+ return
+ }
+
+ await instanceApi.authApi.createTemporaryAccess(ctx.request.body.username)
+
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/createUser.js b/packages/server/middleware/routeHandlers/createUser.js
new file mode 100644
index 0000000000..9e630ff6d4
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/createUser.js
@@ -0,0 +1,10 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ await ctx.instance.authApi.createUser(
+ ctx.request.body.user,
+ ctx.request.body.password
+ )
+
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/deleteRecord.js b/packages/server/middleware/routeHandlers/deleteRecord.js
new file mode 100644
index 0000000000..fb08046096
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/deleteRecord.js
@@ -0,0 +1,9 @@
+const StatusCodes = require("../../utilities/statusCodes")
+const { getRecordKey } = require("./helpers")
+
+module.exports = async ctx => {
+ await ctx.instance.recordApi.delete(
+ getRecordKey(ctx.params.appname, ctx.request.path)
+ )
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/disableUser.js b/packages/server/middleware/routeHandlers/disableUser.js
new file mode 100644
index 0000000000..b1be4d587e
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/disableUser.js
@@ -0,0 +1,11 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ await ctx.instance.authApi.disableUser(ctx.request.body.username)
+
+ await ctx.master.removeSessionsForUser(
+ ctx.params.appname,
+ ctx.request.body.username
+ )
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/enableUser.js b/packages/server/middleware/routeHandlers/enableUser.js
new file mode 100644
index 0000000000..fd86c24c4b
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/enableUser.js
@@ -0,0 +1,6 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ await ctx.instance.authApi.enableUser(ctx.request.body.username)
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/executeAction.js b/packages/server/middleware/routeHandlers/executeAction.js
new file mode 100644
index 0000000000..a6b3b3a310
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/executeAction.js
@@ -0,0 +1,9 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ ctx.body = await ctx.instance.actionApi.execute(
+ ctx.request.body.actionname,
+ ctx.request.body.parameters
+ )
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/getAccessLevels.js b/packages/server/middleware/routeHandlers/getAccessLevels.js
new file mode 100644
index 0000000000..75dd865982
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/getAccessLevels.js
@@ -0,0 +1,6 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ ctx.body = await ctx.instance.authApi.getAccessLevels()
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/getRecord.js b/packages/server/middleware/routeHandlers/getRecord.js
new file mode 100644
index 0000000000..177e56ffee
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/getRecord.js
@@ -0,0 +1,15 @@
+const StatusCodes = require("../../utilities/statusCodes")
+const { getRecordKey } = require("./helpers")
+
+module.exports = async ctx => {
+ try {
+ ctx.body = await ctx.instance.recordApi.load(
+ getRecordKey(ctx.params.appname, ctx.request.path)
+ )
+ ctx.response.status = StatusCodes.OK
+ } catch (e) {
+ // need to be catching for 404s here
+ ctx.response.status = StatusCodes.INTERAL_ERROR
+ ctx.response.body = e.message
+ }
+}
diff --git a/packages/server/middleware/routeHandlers/getUsers.js b/packages/server/middleware/routeHandlers/getUsers.js
new file mode 100644
index 0000000000..cd661b95df
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/getUsers.js
@@ -0,0 +1,6 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ ctx.body = await ctx.instance.authApi.getUsers()
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/helpers.js b/packages/server/middleware/routeHandlers/helpers.js
new file mode 100644
index 0000000000..22a29d3d84
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/helpers.js
@@ -0,0 +1,7 @@
+exports.getRecordKey = (appname, wholePath) =>
+ wholePath
+ .replace(`/${appname}/api/files/`, "")
+ .replace(`/${appname}/api/lookup_field/`, "")
+ .replace(`/${appname}/api/record/`, "")
+ .replace(`/${appname}/api/listRecords/`, "")
+ .replace(`/${appname}/api/aggregates/`, "")
diff --git a/packages/server/middleware/routeHandlers/index.js b/packages/server/middleware/routeHandlers/index.js
new file mode 100644
index 0000000000..af4ff60605
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/index.js
@@ -0,0 +1,43 @@
+const authenticate = require("./authenticate")
+const setPasswordFromTemporaryCode = require("./setPasswordFromTemporaryCode")
+const createTemporaryAccess = require("./createTemporaryAccess")
+const appDefault = require("./appDefault")
+const changeMyPassword = require("./changeMyPassword")
+const executeAction = require("./executeAction")
+const createUser = require("./createUser")
+const enableUser = require("./enableUser")
+const disableUser = require("./disableUser")
+const getUsers = require("./getUsers")
+const getAccessLevels = require("./getAccessLevels")
+const listRecordsGet = require("./listRecordsGet")
+const listRecordsPost = require("./listRecordsPost")
+const aggregatesPost = require("./aggregatesPost")
+const postFiles = require("./postFiles")
+const saveRecord = require("./saveRecord")
+const lookupField = require("./lookupField")
+const getRecord = require("./getRecord")
+const deleteRecord = require("./deleteRecord")
+const saveAppHierarchy = require("./saveAppHierarchy")
+
+module.exports = {
+ authenticate,
+ setPasswordFromTemporaryCode,
+ createTemporaryAccess,
+ appDefault,
+ changeMyPassword,
+ executeAction,
+ createUser,
+ enableUser,
+ disableUser,
+ getUsers,
+ getAccessLevels,
+ listRecordsGet,
+ listRecordsPost,
+ aggregatesPost,
+ postFiles,
+ saveRecord,
+ lookupField,
+ getRecord,
+ deleteRecord,
+ saveAppHierarchy,
+}
diff --git a/packages/server/middleware/routeHandlers/listRecordsGet.js b/packages/server/middleware/routeHandlers/listRecordsGet.js
new file mode 100644
index 0000000000..b456016451
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/listRecordsGet.js
@@ -0,0 +1,8 @@
+const StatusCodes = require("../../utilities/statusCodes")
+const { getRecordKey } = require("./helpers")
+
+module.exports = async ctx => {
+ const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
+ ctx.body = await ctx.instance.indexApi.listItems(indexkey)
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/listRecordsPost.js b/packages/server/middleware/routeHandlers/listRecordsPost.js
new file mode 100644
index 0000000000..c1856ba925
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/listRecordsPost.js
@@ -0,0 +1,12 @@
+const StatusCodes = require("../../utilities/statusCodes")
+const { getRecordKey } = require("./helpers")
+
+module.exports = async ctx => {
+ const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
+ ctx.body = await ctx.instance.indexApi.listItems(indexkey, {
+ rangeStartParams: ctx.request.body.rangeStartParams,
+ rangeEndParams: ctx.request.body.rangeEndParams,
+ searchPhrase: ctx.request.body.searchPhrase,
+ })
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/lookupField.js b/packages/server/middleware/routeHandlers/lookupField.js
new file mode 100644
index 0000000000..fec2d4e39e
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/lookupField.js
@@ -0,0 +1,14 @@
+const StatusCodes = require("../../utilities/statusCodes")
+const { getRecordKey } = require("./helpers")
+
+module.exports = async ctx => {
+ const recordKey = getRecordKey(ctx.params.appname, ctx.request.path)
+ const fields = ctx.query.fields.split(",")
+ const recordContext = await ctx.instance.recordApi.getContext(recordKey)
+ const allContext = []
+ for (let field of fields) {
+ allContext.push(await recordContext.referenceOptions(field))
+ }
+ ctx.body = allContext
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/postFiles.js b/packages/server/middleware/routeHandlers/postFiles.js
new file mode 100644
index 0000000000..7b63e8eccd
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/postFiles.js
@@ -0,0 +1,13 @@
+const StatusCodes = require("../../utilities/statusCodes")
+const { getRecordKey } = require("./helpers")
+const fs = require("fs")
+
+module.exports = async ctx => {
+ const file = ctx.request.files.file
+ ctx.body = await ctx.instance.recordApi.uploadFile(
+ getRecordKey(ctx.params.appname, ctx.request.path),
+ fs.createReadStream(file.path),
+ file.name
+ )
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/saveAppHierarchy.js b/packages/server/middleware/routeHandlers/saveAppHierarchy.js
new file mode 100644
index 0000000000..3537fa35f6
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/saveAppHierarchy.js
@@ -0,0 +1,6 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ ctx.body = await ctx.instance.templateApi.saveApplicationHierarchy(ctx.body)
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/saveRecord.js b/packages/server/middleware/routeHandlers/saveRecord.js
new file mode 100644
index 0000000000..53ec9d94ff
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/saveRecord.js
@@ -0,0 +1,6 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ ctx.body = await ctx.instance.recordApi.save(ctx.request.body)
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routeHandlers/setPasswordFromTemporaryCode.js b/packages/server/middleware/routeHandlers/setPasswordFromTemporaryCode.js
new file mode 100644
index 0000000000..69d0652450
--- /dev/null
+++ b/packages/server/middleware/routeHandlers/setPasswordFromTemporaryCode.js
@@ -0,0 +1,20 @@
+const StatusCodes = require("../../utilities/statusCodes")
+
+module.exports = async ctx => {
+ const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
+ ctx.params.appname,
+ ctx.request.body.username
+ )
+
+ if (!instanceApi) {
+ ctx.request.status = StatusCodes.OK
+ return
+ }
+
+ await instanceApi.authApi.setPasswordFromTemporaryCode(
+ ctx.request.body.tempCode,
+ ctx.request.body.newPassword
+ )
+
+ ctx.response.status = StatusCodes.OK
+}
diff --git a/packages/server/middleware/routers.js b/packages/server/middleware/routers.js
index 3d07ac29d9..2933ca0a55 100644
--- a/packages/server/middleware/routers.js
+++ b/packages/server/middleware/routers.js
@@ -1,9 +1,10 @@
const Router = require("@koa/router")
const session = require("./session")
const StatusCodes = require("../utilities/statusCodes")
-const fs = require("fs")
const { resolve } = require("path")
const send = require("koa-send")
+const routeHandlers = require("./routeHandlers")
+
const {
getPackageForBuilder,
getComponentDefinitions,
@@ -38,6 +39,25 @@ module.exports = (config, app) => {
ctx.set("x-bbappname", appname)
if (appname === "_builder") {
+ if (!config.dev) {
+ ctx.response.status = StatusCodes.FORBIDDEN
+ ctx.body = "run in dev mode to access builder"
+ return
+ }
+
+ if (ctx.path.startsWith("/_builder/instance/_master")) {
+ ctx.instance = ctx.master.getFullAccessApiForMaster()
+ ctx.isAuthenticated = !!ctx.instance
+ } else if (ctx.path.startsWith("/_builder/instance")) {
+ const builderAppName = pathParts[3]
+ const instanceId = pathParts[4]
+ ctx.instance = ctx.master.getFullAccessApiForInstanceId(
+ builderAppName,
+ instanceId
+ ).bbInstance
+ ctx.isAuthenticated = !!ctx.instance
+ }
+
await next()
} else {
const instance = await ctx.master.getInstanceApiForSession(
@@ -54,12 +74,6 @@ module.exports = (config, app) => {
}
})
.get("/_builder", async ctx => {
- if (!config.dev) {
- ctx.response.status = StatusCodes.FORBIDDEN
- ctx.body = "run in dev mode to access builder"
- return
- }
-
await send(ctx, "/index.html", { root: builderPath })
})
.get("/_builder/:appname/componentlibrary", async ctx => {
@@ -71,12 +85,6 @@ module.exports = (config, app) => {
await send(ctx, info.components._lib || "index.js", { root: info.libDir })
})
.get("/_builder/*", async (ctx, next) => {
- if (!config.dev) {
- ctx.response.status = StatusCodes.FORBIDDEN
- ctx.body = "run in dev mode to access builder"
- return
- }
-
const path = ctx.path.replace("/_builder", "")
if (path.startsWith("/api/")) {
@@ -85,58 +93,36 @@ module.exports = (config, app) => {
await send(ctx, path, { root: builderPath })
}
})
- .post("/:appname/api/authenticate", async ctx => {
- const user = await ctx.master.authenticate(
- ctx.sessionId,
- ctx.params.appname,
- ctx.request.body.username,
- ctx.request.body.password
- )
- if (!user) {
- ctx.throw(StatusCodes.UNAUTHORIZED, "invalid username or password")
- }
- ctx.body = user.user_json
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/setPasswordFromTemporaryCode", async ctx => {
- const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
- ctx.params.appname,
- ctx.request.body.username
- )
-
- if (!instanceApi) {
- ctx.request.status = StatusCodes.OK
- return
- }
-
- await instanceApi.authApi.setPasswordFromTemporaryCode(
- ctx.request.body.tempCode,
- ctx.request.body.newPassword
- )
-
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/createTemporaryAccess", async ctx => {
- const instanceApi = await ctx.master.getFullAccessInstanceApiForUsername(
- ctx.params.appname,
- ctx.request.body.username
- )
-
- if (!instanceApi) {
- ctx.request.status = StatusCodes.OK
- return
- }
-
- await instanceApi.authApi.createTemporaryAccess(ctx.request.body.username)
-
- ctx.response.status = StatusCodes.OK
- })
+ .post("/:appname/api/authenticate", routeHandlers.authenticate)
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/authenticate",
+ routeHandlers.authenticate
+ )
+ .post(
+ "/:appname/api/setPasswordFromTemporaryCode",
+ routeHandlers.setPasswordFromTemporaryCode
+ )
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/setPasswordFromTemporaryCode",
+ routeHandlers.setPasswordFromTemporaryCode
+ )
+ .post(
+ "/:appname/api/createTemporaryAccess",
+ routeHandlers.createTemporaryAccess
+ )
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/createTemporaryAccess",
+ routeHandlers.createTemporaryAccess
+ )
.get("/_builder/api/apps", async ctx => {
ctx.body = await getApps(config, ctx.master)
ctx.response.status = StatusCodes.OK
})
.get("/_builder/api/:appname/appPackage", async ctx => {
- ctx.body = await getPackageForBuilder(config, ctx.params.appname)
+ const application = await ctx.master.getApplicationWithInstances(
+ ctx.params.appname
+ )
+ ctx.body = await getPackageForBuilder(config, application)
ctx.response.status = StatusCodes.OK
})
.get("/_builder/api/:appname/components", async ctx => {
@@ -228,23 +214,9 @@ module.exports = (config, app) => {
.get("/:appname", async ctx => {
await send(ctx, "/index.html", { root: ctx.publicPath })
})
- .get("/:appname/*", async (ctx, next) => {
- const path = ctx.path.replace(`/${ctx.params.appname}`, "")
-
- if (path.startsWith("/api/")) {
- await next()
- } else if (path.startsWith("/_shared/")) {
- await send(ctx, path.replace(`/_shared/`, ""), { root: ctx.sharedPath })
- } else if (
- path.endsWith(".js") ||
- path.endsWith(".map") ||
- path.endsWith(".css")
- ) {
- await send(ctx, path, { root: ctx.publicPath })
- } else {
- await send(ctx, "/index.html", { root: ctx.publicPath })
- }
- })
+ .get("/:appname/*", routeHandlers.appDefault)
+ .get("/_builder/instance/:appname/:instanceid/*", routeHandlers.appDefault)
+ // EVERYTHING BELOW HERE REQUIRES AUTHENTICATION
.use(async (ctx, next) => {
if (ctx.isAuthenticated) {
await next()
@@ -252,147 +224,85 @@ module.exports = (config, app) => {
ctx.response.status = StatusCodes.UNAUTHORIZED
}
})
- .post("/:appname/api/changeMyPassword", async ctx => {
- await ctx.instance.authApi.changeMyPassword(
- ctx.request.body.currentPassword,
- ctx.request.body.newPassword
- )
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/changeMyPassword", async ctx => {
- await ctx.instance.authApi.changeMyPassword(
- ctx.request.body.currentPassword,
- ctx.request.body.newPassword
- )
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/executeAction/:actionname", async ctx => {
- ctx.body = await ctx.instance.actionApi.execute(
- ctx.request.body.actionname,
- ctx.request.body.parameters
- )
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/createUser", async ctx => {
- await ctx.instance.authApi.createUser(
- ctx.request.body.user,
- ctx.request.body.password
- )
-
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/enableUser", async ctx => {
- await ctx.instance.authApi.enableUser(ctx.request.body.username)
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/disableUser", async ctx => {
- await ctx.instance.authApi.disableUser(ctx.request.body.username)
-
- await ctx.master.removeSessionsForUser(
- ctx.params.appname,
- ctx.request.body.username
- )
- ctx.response.status = StatusCodes.OK
- })
- .get("/:appname/api/users", async ctx => {
- ctx.body = await ctx.instance.authApi.getUsers()
- ctx.response.status = StatusCodes.OK
- })
- .get("/:appname/api/accessLevels", async ctx => {
- ctx.body = await ctx.instance.authApi.getAccessLevels()
- ctx.response.status = StatusCodes.OK
- })
- .get("/:appname/api/listRecords/*", async ctx => {
- const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
- ctx.body = await ctx.instance.indexApi.listItems(indexkey)
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/listRecords/*", async ctx => {
- const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
- ctx.body = await ctx.instance.indexApi.listItems(indexkey, {
- rangeStartParams: ctx.request.body.rangeStartParams,
- rangeEndParams: ctx.request.body.rangeEndParams,
- searchPhrase: ctx.request.body.searchPhrase,
- })
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/aggregates/*", async ctx => {
- const indexkey = getRecordKey(ctx.params.appname, ctx.request.path)
- ctx.body = await ctx.instance.indexApi.aggregates(indexkey, {
- rangeStartParams: ctx.request.body.rangeStartParams,
- rangeEndParams: ctx.request.body.rangeEndParams,
- searchPhrase: ctx.request.body.searchPhrase,
- })
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/files/*", async ctx => {
- const file = ctx.request.files.file
- ctx.body = await ctx.instance.recordApi.uploadFile(
- getRecordKey(ctx.params.appname, ctx.request.path),
- fs.createReadStream(file.path),
- file.name
- )
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/record/*", async ctx => {
- ctx.body = await ctx.instance.recordApi.save(ctx.request.body)
- ctx.response.status = StatusCodes.OK
- })
- .get("/:appname/api/lookup_field/*", async ctx => {
- const recordKey = getRecordKey(ctx.params.appname, ctx.request.path)
- const fields = ctx.query.fields.split(",")
- const recordContext = await ctx.instance.recordApi.getContext(recordKey)
- const allContext = []
- for (let field of fields) {
- allContext.push(await recordContext.referenceOptions(field))
- }
- ctx.body = allContext
- ctx.response.status = StatusCodes.OK
- })
- .get("/:appname/api/record/*", async ctx => {
- try {
- ctx.body = await ctx.instance.recordApi.load(
- getRecordKey(ctx.params.appname, ctx.request.path)
- )
- ctx.response.status = StatusCodes.OK
- } catch (e) {
- // need to be catching for 404s here
- ctx.response.status = StatusCodes.INTERAL_ERROR
- ctx.response.body = e.message
- }
- })
- .del("/:appname/api/record/*", async ctx => {
- await ctx.instance.recordApi.delete(
- getRecordKey(ctx.params.appname, ctx.request.path)
- )
- ctx.response.status = StatusCodes.OK
- })
- .post("/:appname/api/apphierarchy", async ctx => {
- ctx.body = await ctx.instance.templateApi.saveApplicationHierarchy(
- ctx.body
- )
- ctx.response.status = StatusCodes.OK
- })
- /*.post("/:appname/api/actionsAndTriggers", async (ctx) => {
- ctx.body = await ctx.instance.templateApi.saveApplicationHierarchy(
- ctx.body
- );
- ctx.response.status = StatusCodes.OK;
- })
- .get("/:appname/api/appDefinition", async (ctx) => {
- ctx.body = await ctx.instance.templateApi.saveActionsAndTriggers(
- ctx.body
- );
- ctx.response.status = StatusCodes.OK;
- })*/
-
- const getRecordKey = (appname, wholePath) =>
- wholePath
- .replace(`/${appname}/api/files/`, "")
- .replace(`/${appname}/api/lookup_field/`, "")
- .replace(`/${appname}/api/record/`, "")
- .replace(`/${appname}/api/listRecords/`, "")
- .replace(`/${appname}/api/aggregates/`, "")
+ .post("/:appname/api/changeMyPassword", routeHandlers.changeMyPassword)
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/changeMyPassword",
+ routeHandlers.changeMyPassword
+ )
+ .post(
+ "/:appname/api/executeAction/:actionname",
+ routeHandlers.executeAction
+ )
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/executeAction/:actionname",
+ routeHandlers.executeAction
+ )
+ .post("/:appname/api/createUser", routeHandlers.createUser)
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/createUser",
+ routeHandlers.createUser
+ )
+ .post("/:appname/api/enableUser", routeHandlers.enableUser)
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/enableUser",
+ routeHandlers.enableUser
+ )
+ .post("/:appname/api/disableUser", routeHandlers.disableUser)
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/disableUser",
+ routeHandlers.disableUser
+ )
+ .get("/:appname/api/users", routeHandlers.getUsers)
+ .get(
+ "/_builder/instance/:appname/:instanceid/api/users",
+ routeHandlers.getUsers
+ )
+ .get("/:appname/api/accessLevels", routeHandlers.getAccessLevels)
+ .get(
+ "/_builder/instance/:appname/:instanceid/api/accessLevels",
+ routeHandlers.getAccessLevels
+ )
+ .get("/:appname/api/listRecords/*", routeHandlers.listRecordsGet)
+ .get(
+ "/_builder/instance/:appname/:instanceid/api/listRecords/*",
+ routeHandlers.listRecordsGet
+ )
+ .post("/:appname/api/listRecords/*", routeHandlers.listRecordsPost)
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/listRecords/*",
+ routeHandlers.listRecordsPost
+ )
+ .post("/:appname/api/aggregates/*", routeHandlers.aggregatesPost)
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/aggregates/*",
+ routeHandlers.aggregatesPost
+ )
+ .post("/:appname/api/files/*", routeHandlers.postFiles)
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/files/*",
+ routeHandlers.postFiles
+ )
+ .post("/:appname/api/record/*", routeHandlers.saveRecord)
+ .post(
+ "/_builder/instance/:appname/:instanceid/api/record/*",
+ routeHandlers.saveRecord
+ )
+ .get("/:appname/api/lookup_field/*", routeHandlers.lookupField)
+ .get(
+ "/_builder/instance/:appname/:instanceid/api/lookup_field/*",
+ routeHandlers.lookupField
+ )
+ .get("/:appname/api/record/*", routeHandlers.getRecord)
+ .get(
+ "/_builder/instance/:appname/:instanceid/api/record/*",
+ routeHandlers.getRecord
+ )
+ .del("/:appname/api/record/*", routeHandlers.deleteRecord)
+ .del(
+ "/_builder/instance/:appname/:instanceid/api/record/*",
+ routeHandlers.deleteRecord
+ )
+ .post("/:appname/api/apphierarchy", routeHandlers.saveAppHierarchy)
return router
}
diff --git a/packages/server/utilities/builder/index.js b/packages/server/utilities/builder/index.js
index 24215083bd..4dcdefa32b 100644
--- a/packages/server/utilities/builder/index.js
+++ b/packages/server/utilities/builder/index.js
@@ -27,8 +27,8 @@ module.exports.saveBackend = saveBackend
const getAppDefinition = async appPath =>
await readJSON(`${appPath}/appDefinition.json`)
-module.exports.getPackageForBuilder = async (config, appname) => {
- const appPath = appPackageFolder(config, appname)
+module.exports.getPackageForBuilder = async (config, application) => {
+ const appPath = appPackageFolder(config, application.name)
const pages = await getPages(appPath)
@@ -40,6 +40,8 @@ module.exports.getPackageForBuilder = async (config, appname) => {
pages,
components: await getComponentDefinitions(appPath, pages),
+
+ application,
}
}
diff --git a/packages/server/utilities/masterAppInternal.js b/packages/server/utilities/masterAppInternal.js
index 8da8da609f..462e628d59 100644
--- a/packages/server/utilities/masterAppInternal.js
+++ b/packages/server/utilities/masterAppInternal.js
@@ -6,7 +6,7 @@ const {
const getDatastore = require("./datastore")
const getDatabaseManager = require("./databaseManager")
const { $ } = require("@budibase/core").common
-const { keyBy, values } = require("lodash/fp")
+const { keyBy, values, cloneDeep } = require("lodash/fp")
const {
masterAppPackage,
applictionVersionPackage,
@@ -128,20 +128,10 @@ module.exports = async context => {
const userInMaster = await getUser(app.id, username)
if (!userInMaster) return null
- const instance = await bb.recordApi.load(userInMaster.instance.key)
-
- const versionId = determineVersionId(instance.version)
-
- const dsConfig = JSON.parse(instance.datastoreconfig)
- const appPackage = await applictionVersionPackage(
- context,
+ const { instance, bbInstance } = await getFullAccessApiForInstanceId(
appname,
- versionId,
- instance.key
- )
- const bbInstance = await getApisWithFullAccess(
- datastoreModule.getDatastore(dsConfig),
- appPackage
+ userInMaster.instance.id,
+ app.id
)
const authUser = await bbInstance.authApi.authenticate(username, password)
@@ -164,6 +154,34 @@ module.exports = async context => {
return session
}
+ const getFullAccessApiForInstanceId = async (appname, instanceId, appId) => {
+ if (!appId) {
+ appId = (await getApplication(appname)).id
+ }
+ const instanceKey = `/applications/${appId}/instances/${instanceId}`
+ const instance = await bb.recordApi.load(instanceKey)
+
+ const versionId = determineVersionId(instance.version)
+
+ const dsConfig = JSON.parse(instance.datastoreconfig)
+ const appPackage = await applictionVersionPackage(
+ context,
+ appname,
+ versionId,
+ instance.key
+ )
+ return {
+ bbInstance: await getApisWithFullAccess(
+ datastoreModule.getDatastore(dsConfig),
+ appPackage
+ ),
+ instance,
+ }
+ }
+
+ const getFullAccessApiForMaster = async () =>
+ await getApisWithFullAccess(masterDatastore, masterAppPackage(context))
+
const getInstanceApiForSession = async (appname, sessionId) => {
if (isMaster(appname)) {
const customId = bb.recordApi.customId("mastersession", sessionId)
@@ -295,6 +313,14 @@ module.exports = async context => {
}
}
+ const getApplicationWithInstances = async appname => {
+ const app = cloneDeep(await getApplication(appname))
+ app.instances = await bb.indexApi.listItems(
+ `/applications/${app.id}/allinstances`
+ )
+ return app
+ }
+
const disableUser = async (app, username) => {
await removeSessionsForUser(app.name, username)
const userInMaster = await getUser(app.id, username)
@@ -324,5 +350,8 @@ module.exports = async context => {
createAppUser,
bbMaster: bb,
listApplications,
+ getFullAccessApiForInstanceId,
+ getFullAccessApiForMaster,
+ getApplicationWithInstances,
}
}
diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock
index f4ad571cdd..5475d85d62 100644
--- a/packages/server/yarn.lock
+++ b/packages/server/yarn.lock
@@ -131,6 +131,33 @@
lodash "^4.17.13"
to-fast-properties "^2.0.0"
+"@budibase/client@^0.0.27":
+ version "0.0.27"
+ resolved "https://registry.yarnpkg.com/@budibase/client/-/client-0.0.27.tgz#d43a66202a23103ae5ac89d9fa69c3cd36b2a090"
+ integrity sha512-emS6L66fzfr/CdnpazlqveVKqcSQA9+sQRcbzLZ+sJLFk6FNIezRQcMjGHz+ooeYS91OVgOfleqXDCnvHO+MNg==
+ dependencies:
+ "@nx-js/compiler-util" "^2.0.0"
+ bcryptjs "^2.4.3"
+ deep-equal "^2.0.1"
+ lodash "^4.17.15"
+ lunr "^2.3.5"
+ regexparam "^1.3.0"
+ shortid "^2.2.8"
+ svelte "^3.9.2"
+
+"@budibase/core@^0.0.27":
+ version "0.0.27"
+ resolved "https://registry.yarnpkg.com/@budibase/core/-/core-0.0.27.tgz#05bbacce692222089a1ae85b7ea4bb322e327f64"
+ integrity sha512-V8qGB9Lcwz8CFGzYct6i1oI+WiYgEOCsBBQ6DPPRLLVg07i2DHI9Ynwa35QXWTO3WeyWIxy//WSmVwSlYPAtOw==
+ dependencies:
+ "@nx-js/compiler-util" "^2.0.0"
+ bcryptjs "^2.4.3"
+ date-fns "^1.29.0"
+ lodash "^4.17.13"
+ lunr "^2.3.5"
+ safe-buffer "^5.1.2"
+ shortid "^2.2.8"
+
"@cnakazawa/watch@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
@@ -299,6 +326,11 @@
path-to-regexp "^1.1.1"
urijs "^1.19.0"
+"@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"
+ integrity sha512-AxSQbwj9zqt8DYPZ6LwZdytqnwfiOEdcFdq4l8sdjkZmU2clTht7RDLCI8xvkp7KqgcNaOGlTeCM55TULWruyQ==
+
"@types/babel__core@^7.1.0":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.2.tgz#608c74f55928033fce18b99b213c16be4b3d114f"
@@ -646,6 +678,11 @@ bcrypt-pbkdf@^1.0.0:
dependencies:
tweetnacl "^0.14.3"
+bcryptjs@^2.4.3:
+ version "2.4.3"
+ resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb"
+ integrity sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=
+
binary-extensions@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c"
@@ -1045,6 +1082,11 @@ data-urls@^1.0.0:
whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0"
+date-fns@^1.29.0:
+ version "1.30.1"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c"
+ integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==
+
debug@^2.2.0, debug@^2.3.3:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -1083,6 +1125,24 @@ decode-uri-component@^0.2.0:
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=
+deep-equal@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.0.1.tgz#fc12bbd6850e93212f21344748682ccc5a8813cf"
+ integrity sha512-7Et6r6XfNW61CPPCIYfm1YPGSmh6+CliYeL4km7GWJcpX5LTAflGF8drLLR+MZX+2P3NZfAfSduutBbSWqER4g==
+ dependencies:
+ es-abstract "^1.16.3"
+ es-get-iterator "^1.0.1"
+ is-arguments "^1.0.4"
+ is-date-object "^1.0.1"
+ is-regex "^1.0.4"
+ isarray "^2.0.5"
+ object-is "^1.0.1"
+ object-keys "^1.1.1"
+ regexp.prototype.flags "^1.2.0"
+ side-channel "^1.0.1"
+ which-boxed-primitive "^1.0.1"
+ which-collection "^1.0.0"
+
deep-equal@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
@@ -1098,7 +1158,7 @@ deep-is@~0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
-define-properties@^1.1.2:
+define-properties@^1.1.2, define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
@@ -1218,6 +1278,23 @@ error-inject@^1.0.0:
resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37"
integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc=
+es-abstract@^1.16.3, es-abstract@^1.17.0-next.1, es-abstract@^1.17.4:
+ version "1.17.4"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184"
+ integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==
+ dependencies:
+ es-to-primitive "^1.2.1"
+ function-bind "^1.1.1"
+ has "^1.0.3"
+ has-symbols "^1.0.1"
+ is-callable "^1.1.5"
+ is-regex "^1.0.5"
+ object-inspect "^1.7.0"
+ object-keys "^1.1.1"
+ object.assign "^4.1.0"
+ string.prototype.trimleft "^2.1.1"
+ string.prototype.trimright "^2.1.1"
+
es-abstract@^1.5.1:
version "1.13.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9"
@@ -1230,6 +1307,19 @@ es-abstract@^1.5.1:
is-regex "^1.0.4"
object-keys "^1.0.12"
+es-get-iterator@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.0.tgz#bb98ad9d6d63b31aacdc8f89d5d0ee57bcb5b4c8"
+ integrity sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==
+ dependencies:
+ es-abstract "^1.17.4"
+ has-symbols "^1.0.1"
+ is-arguments "^1.0.4"
+ is-map "^2.0.1"
+ is-set "^2.0.1"
+ is-string "^1.0.5"
+ isarray "^2.0.5"
+
es-to-primitive@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377"
@@ -1239,6 +1329,15 @@ es-to-primitive@^1.2.0:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
+es-to-primitive@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
+ integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==
+ dependencies:
+ is-callable "^1.1.4"
+ is-date-object "^1.0.1"
+ is-symbol "^1.0.2"
+
escape-html@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@@ -1651,6 +1750,11 @@ has-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
+has-symbols@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8"
+ integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==
+
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -1835,11 +1939,21 @@ is-accessor-descriptor@^1.0.0:
dependencies:
kind-of "^6.0.0"
+is-arguments@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3"
+ integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==
+
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
+is-bigint@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.0.tgz#73da8c33208d00f130e9b5e15d23eac9215601c4"
+ integrity sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g==
+
is-binary-path@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
@@ -1847,6 +1961,11 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
+is-boolean-object@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e"
+ integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==
+
is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
@@ -1857,6 +1976,11 @@ is-callable@^1.1.4:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75"
integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==
+is-callable@^1.1.5:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
+ integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
+
is-ci@^1.0.10:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c"
@@ -1967,11 +2091,21 @@ is-installed-globally@^0.1.0:
global-dirs "^0.1.0"
is-path-inside "^1.0.0"
+is-map@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1"
+ integrity sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==
+
is-npm@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ=
+is-number-object@^1.0.3:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197"
+ integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==
+
is-number@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195"
@@ -2015,16 +2149,33 @@ is-regex@^1.0.4:
dependencies:
has "^1.0.1"
+is-regex@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
+ integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
+ dependencies:
+ has "^1.0.3"
+
is-retry-allowed@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
+is-set@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.1.tgz#d1604afdab1724986d30091575f54945da7e5f43"
+ integrity sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==
+
is-stream@^1.0.0, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
+is-string@^1.0.4, is-string@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6"
+ integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==
+
is-symbol@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38"
@@ -2046,6 +2197,16 @@ is-typedarray@~1.0.0:
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
+is-weakmap@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2"
+ integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==
+
+is-weakset@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.1.tgz#e9a0af88dbd751589f5e50d80f4c98b780884f83"
+ integrity sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw==
+
is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@@ -2066,6 +2227,11 @@ isarray@1.0.0, isarray@~1.0.0:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
+isarray@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
+ integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
+
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -2752,7 +2918,7 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
-lodash@^4.17.11, lodash@^4.17.13:
+lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.15:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@@ -2777,6 +2943,11 @@ lru-cache@^4.0.1:
pseudomap "^1.0.2"
yallist "^2.1.2"
+lunr@^2.3.5:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.8.tgz#a8b89c31f30b5a044b97d2d28e2da191b6ba2072"
+ integrity sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==
+
make-dir@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
@@ -2938,6 +3109,11 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
+nanoid@^2.1.0:
+ version "2.1.11"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.1.11.tgz#ec24b8a758d591561531b4176a01e3ab4f0f0280"
+ integrity sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==
+
nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
@@ -3133,7 +3309,17 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
-object-keys@^1.0.12:
+object-inspect@^1.7.0:
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
+ integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==
+
+object-is@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4"
+ integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==
+
+object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
@@ -3145,6 +3331,16 @@ object-visit@^1.0.0:
dependencies:
isobject "^3.0.0"
+object.assign@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da"
+ integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==
+ dependencies:
+ define-properties "^1.1.2"
+ function-bind "^1.1.1"
+ has-symbols "^1.0.0"
+ object-keys "^1.0.11"
+
object.getownpropertydescriptors@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16"
@@ -3531,6 +3727,19 @@ regex-not@^1.0.0, regex-not@^1.0.2:
extend-shallow "^3.0.2"
safe-regex "^1.1.0"
+regexp.prototype.flags@^1.2.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75"
+ integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==
+ dependencies:
+ define-properties "^1.1.3"
+ es-abstract "^1.17.0-next.1"
+
+regexparam@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f"
+ integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g==
+
registry-auth-token@^3.0.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e"
@@ -3773,6 +3982,21 @@ shellwords@^0.1.1:
resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b"
integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==
+shortid@^2.2.8:
+ version "2.2.15"
+ resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.15.tgz#2b902eaa93a69b11120373cd42a1f1fe4437c122"
+ integrity sha512-5EaCy2mx2Jgc/Fdn9uuDuNIIfWBpzY4XIlhoqtXF6qsf+/+SGZ+FxDdX/ZsMZiWupIWNqAEmiNY4RC+LSmCeOw==
+ dependencies:
+ nanoid "^2.1.0"
+
+side-channel@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947"
+ integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==
+ dependencies:
+ es-abstract "^1.17.0-next.1"
+ object-inspect "^1.7.0"
+
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
@@ -3962,6 +4186,22 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
+string.prototype.trimleft@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74"
+ integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==
+ dependencies:
+ define-properties "^1.1.3"
+ function-bind "^1.1.1"
+
+string.prototype.trimright@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9"
+ integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==
+ dependencies:
+ define-properties "^1.1.3"
+ function-bind "^1.1.1"
+
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
@@ -4050,6 +4290,11 @@ supports-color@^6.1.0:
dependencies:
has-flag "^3.0.0"
+svelte@^3.9.2:
+ version "3.19.2"
+ resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.19.2.tgz#4b0169ee33b37399f08eb92163593a0a46c242c7"
+ integrity sha512-Jswg065u8R9QYcN0rdpTQSFIr0hFq7YUzcPpEY6ZpFSAWkJKZG9AJvHE1d8+NJDTfr7SzKrO6EYssYYkUmszpA==
+
symbol-tree@^3.2.2:
version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
@@ -4428,6 +4673,27 @@ whatwg-url@^7.0.0:
tr46 "^1.0.1"
webidl-conversions "^4.0.2"
+which-boxed-primitive@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz#cbe8f838ebe91ba2471bb69e9edbda67ab5a5ec1"
+ integrity sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==
+ dependencies:
+ is-bigint "^1.0.0"
+ is-boolean-object "^1.0.0"
+ is-number-object "^1.0.3"
+ is-string "^1.0.4"
+ is-symbol "^1.0.2"
+
+which-collection@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906"
+ integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==
+ dependencies:
+ is-map "^2.0.1"
+ is-set "^2.0.1"
+ is-weakmap "^2.0.1"
+ is-weakset "^2.0.1"
+
which-module@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
diff --git a/readme.md b/readme.md
index 5b179c855d..159cd4a63c 100644
--- a/readme.md
+++ b/readme.md
@@ -70,19 +70,17 @@ yarn run budi new your-app-name
now build and publish the latest budibase libs, to your new app
```
-# from root of repo
+cd ../..
+# now back in the root of the repository
yarn run publishdev
```
then
-`yarn run budi` and to run the budibase server
+run the budibase server and builder in dev mode (i.e. with hot reloading):
-if you then want to run the builder in dev mode (i.e. with hot reloading):
-
-... keep the server running, and..
1. Open a new console
-2. `yarn dev`
+2. `yarn dev` (from root)
3. Access the builder on http://localhost:3000
This will enable watch mode for both the client AND the server.