merge with master

This commit is contained in:
Martin McKeaveney 2021-09-06 16:13:17 +01:00
commit c39abe4081
32 changed files with 1568 additions and 1956 deletions

View File

@ -1,5 +1,5 @@
{ {
"version": "0.9.116", "version": "0.9.121",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/*" "packages/*"

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/auth", "name": "@budibase/auth",
"version": "0.9.116", "version": "0.9.121",
"description": "Authentication middlewares for budibase builder and apps", "description": "Authentication middlewares for budibase builder and apps",
"main": "src/index.js", "main": "src/index.js",
"author": "Budibase", "author": "Budibase",

View File

@ -18,6 +18,10 @@ exports.getUser = async (userId, tenantId = null) => {
user = await getGlobalDB(tenantId).get(userId) user = await getGlobalDB(tenantId).get(userId)
client.store(userId, user, EXPIRY_SECONDS) client.store(userId, user, EXPIRY_SECONDS)
} }
if (user && !user.tenantId && tenantId) {
// make sure the tenant ID is always correct/set
user.tenantId = tenantId
}
return user return user
} }

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/bbui", "name": "@budibase/bbui",
"description": "A UI solution used in the different Budibase projects.", "description": "A UI solution used in the different Budibase projects.",
"version": "0.9.116", "version": "0.9.121",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"svelte": "src/index.js", "svelte": "src/index.js",
"module": "dist/bbui.es.js", "module": "dist/bbui.es.js",

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/builder", "name": "@budibase/builder",
"version": "0.9.116", "version": "0.9.121",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"private": true, "private": true,
"scripts": { "scripts": {
@ -65,10 +65,10 @@
} }
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.116", "@budibase/bbui": "^0.9.121",
"@budibase/client": "^0.9.116", "@budibase/client": "^0.9.121",
"@budibase/colorpicker": "1.1.2", "@budibase/colorpicker": "1.1.2",
"@budibase/string-templates": "^0.9.116", "@budibase/string-templates": "^0.9.121",
"@sentry/browser": "5.19.1", "@sentry/browser": "5.19.1",
"@spectrum-css/page": "^3.0.1", "@spectrum-css/page": "^3.0.1",
"@spectrum-css/vars": "^3.0.1", "@spectrum-css/vars": "^3.0.1",

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/cli", "name": "@budibase/cli",
"version": "0.9.116", "version": "0.9.121",
"description": "Budibase CLI, for developers, self hosting and migrations.", "description": "Budibase CLI, for developers, self hosting and migrations.",
"main": "src/index.js", "main": "src/index.js",
"bin": { "bin": {

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/client", "name": "@budibase/client",
"version": "0.9.116", "version": "0.9.121",
"license": "MPL-2.0", "license": "MPL-2.0",
"module": "dist/budibase-client.js", "module": "dist/budibase-client.js",
"main": "dist/budibase-client.js", "main": "dist/budibase-client.js",
@ -18,9 +18,9 @@
"dev:builder": "rollup -cw" "dev:builder": "rollup -cw"
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.116", "@budibase/bbui": "^0.9.121",
"@budibase/standard-components": "^0.9.116", "@budibase/standard-components": "^0.9.121",
"@budibase/string-templates": "^0.9.116", "@budibase/string-templates": "^0.9.121",
"regexparam": "^1.3.0", "regexparam": "^1.3.0",
"shortid": "^2.2.15", "shortid": "^2.2.15",
"svelte-spa-router": "^3.0.5" "svelte-spa-router": "^3.0.5"

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/server", "name": "@budibase/server",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "0.9.116", "version": "0.9.121",
"description": "Budibase Web Server", "description": "Budibase Web Server",
"main": "src/index.js", "main": "src/index.js",
"repository": { "repository": {
@ -62,9 +62,9 @@
"author": "Budibase", "author": "Budibase",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@budibase/auth": "^0.9.116", "@budibase/auth": "^0.9.121",
"@budibase/client": "^0.9.116", "@budibase/client": "^0.9.121",
"@budibase/string-templates": "^0.9.116", "@budibase/string-templates": "^0.9.121",
"@elastic/elasticsearch": "7.10.0", "@elastic/elasticsearch": "7.10.0",
"@koa/router": "8.0.0", "@koa/router": "8.0.0",
"@sendgrid/mail": "7.1.1", "@sendgrid/mail": "7.1.1",
@ -117,7 +117,7 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.14.3", "@babel/core": "^7.14.3",
"@babel/preset-env": "^7.14.4", "@babel/preset-env": "^7.14.4",
"@budibase/standard-components": "^0.9.116", "@budibase/standard-components": "^0.9.121",
"@jest/test-sequencer": "^24.8.0", "@jest/test-sequencer": "^24.8.0",
"@types/bull": "^3.15.1", "@types/bull": "^3.15.1",
"@types/jest": "^26.0.23", "@types/jest": "^26.0.23",
@ -138,7 +138,7 @@
"supertest": "^4.0.2", "supertest": "^4.0.2",
"ts-jest": "^27.0.3", "ts-jest": "^27.0.3",
"ts-node": "^10.0.0", "ts-node": "^10.0.0",
"typescript": "^4.3.4", "typescript": "^4.3.5",
"update-dotenv": "^1.1.1" "update-dotenv": "^1.1.1"
}, },
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc" "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc"

View File

@ -106,6 +106,12 @@ async function createInstance(template) {
views: {}, views: {},
}) })
// NOTE: indexes need to be created before any tables/templates
// add view for linked rows
await createLinkView(appId)
await createRoutingView(appId)
await createAllSearchIndex(appId)
// replicate the template data to the instance DB // replicate the template data to the instance DB
// this is currently very hard to test, downloading and importing template files // this is currently very hard to test, downloading and importing template files
/* istanbul ignore next */ /* istanbul ignore next */
@ -119,11 +125,6 @@ async function createInstance(template) {
await db.put(USERS_TABLE_SCHEMA) await db.put(USERS_TABLE_SCHEMA)
} }
// add view for linked rows
await createLinkView(appId)
await createRoutingView(appId)
await createAllSearchIndex(appId)
return { _id: appId } return { _id: appId }
} }

View File

@ -1,34 +1,29 @@
import { import {
IncludeRelationships,
Operation, Operation,
SearchFilters,
SortJson,
PaginationJson, PaginationJson,
RelationshipsJson, RelationshipsJson,
SearchFilters,
SortJson,
} from "../../../definitions/datasource" } from "../../../definitions/datasource"
import { import {Datasource, FieldSchema, Row, Table} from "../../../definitions/common"
Row, import {breakRowIdField, generateRowIdField} from "../../../integrations/utils"
Table, import { RelationshipTypes } from "../../../constants"
FieldSchema,
Datasource,
} from "../../../definitions/common"
import {
breakRowIdField,
generateRowIdField,
} from "../../../integrations/utils"
interface ManyRelationship { interface ManyRelationship {
tableId?: string tableId?: string
id?: string id?: string
isUpdate?: boolean isUpdate?: boolean
key: string
[key: string]: any [key: string]: any
} }
interface RunConfig { interface RunConfig {
id: string id?: string
filters: SearchFilters filters?: SearchFilters
sort: SortJson sort?: SortJson
paginate: PaginationJson paginate?: PaginationJson
row: Row row?: Row
} }
module External { module External {
@ -37,7 +32,6 @@ module External {
const { breakExternalTableId, isSQL } = require("../../../integrations/utils") const { breakExternalTableId, isSQL } = require("../../../integrations/utils")
const { processObjectSync } = require("@budibase/string-templates") const { processObjectSync } = require("@budibase/string-templates")
const { cloneDeep } = require("lodash/fp") const { cloneDeep } = require("lodash/fp")
const { isEqual } = require("lodash")
const CouchDB = require("../../../db") const CouchDB = require("../../../db")
function buildFilters( function buildFilters(
@ -81,7 +75,7 @@ module External {
} }
} }
function generateIdForRow(row: Row, table: Table): string { function generateIdForRow(row: Row | undefined, table: Table): string {
const primary = table.primary const primary = table.primary
if (!row || !primary) { if (!row || !primary) {
return "" return ""
@ -89,7 +83,8 @@ module External {
// build id array // build id array
let idParts = [] let idParts = []
for (let field of primary) { for (let field of primary) {
const fieldValue = row[`${table.name}.${field}`] // need to handle table name + field or just field, depending on if relationships used
const fieldValue = row[`${table.name}.${field}`] || row[field]
if (fieldValue) { if (fieldValue) {
idParts.push(fieldValue) idParts.push(fieldValue)
} }
@ -116,7 +111,7 @@ module External {
const thisRow: { [key: string]: any } = {} const thisRow: { [key: string]: any } = {}
// filter the row down to what is actually the row (not joined) // filter the row down to what is actually the row (not joined)
for (let fieldName of Object.keys(table.schema)) { for (let fieldName of Object.keys(table.schema)) {
const value = row[`${table.name}.${fieldName}`] const value = row[`${table.name}.${fieldName}`] || row[fieldName]
// all responses include "select col as table.col" so that overlaps are handled // all responses include "select col as table.col" so that overlaps are handled
if (value) { if (value) {
thisRow[fieldName] = value thisRow[fieldName] = value
@ -156,7 +151,15 @@ module External {
} }
} }
inputProcessing(row: Row, table: Table) { getTable(tableId: string | undefined): Table {
if (!tableId) {
throw "Table ID is unknown, cannot find table"
}
const { tableName } = breakExternalTableId(tableId)
return this.tables[tableName]
}
inputProcessing(row: Row | undefined, table: Table) {
if (!row) { if (!row) {
return { row, manyRelationships: [] } return { row, manyRelationships: [] }
} }
@ -202,6 +205,7 @@ module External {
manyRelationships.push({ manyRelationships.push({
tableId: field.through || field.tableId, tableId: field.through || field.tableId,
isUpdate, isUpdate,
key: otherKey,
[thisKey]: breakRowIdField(relationship)[0], [thisKey]: breakRowIdField(relationship)[0],
// leave the ID for enrichment later // leave the ID for enrichment later
[otherKey]: `{{ literal ${tablePrimary} }}`, [otherKey]: `{{ literal ${tablePrimary} }}`,
@ -343,41 +347,34 @@ module External {
* This is a cached lookup, of relationship records, this is mainly for creating/deleting junction * This is a cached lookup, of relationship records, this is mainly for creating/deleting junction
* information. * information.
*/ */
async lookup( async lookupRelations(tableId: string, row: Row) {
row: Row, const related: {[key: string]: any} = {}
relationship: ManyRelationship,
cache: { [key: string]: Row[] } = {}
) {
const { tableId, isUpdate, id, ...rest } = relationship
const { tableName } = breakExternalTableId(tableId) const { tableName } = breakExternalTableId(tableId)
const table = this.tables[tableName] const table = this.tables[tableName]
if (isUpdate) { // @ts-ignore
return { rows: [], table } const primaryKey = table.primary[0]
// make a new request to get the row with all its relationships
// we need this to work out if any relationships need removed
for (let field of Object.values(table.schema)) {
if (field.type !== FieldTypes.LINK || !field.fieldName) {
continue
} }
// if not updating need to make sure we have a list of all possible options const isMany = field.relationshipType === RelationshipTypes.MANY_TO_MANY
let fullKey: string = tableId + "/", const tableId = isMany ? field.through : field.tableId
rowKey: string = "" const fieldName = isMany ? primaryKey : field.fieldName
for (let key of Object.keys(rest)) {
if (row[key]) {
fullKey += key
rowKey = key
}
}
if (cache[fullKey] == null) {
const response = await makeExternalQuery(this.appId, { const response = await makeExternalQuery(this.appId, {
endpoint: getEndpoint(tableId, DataSourceOperation.READ), endpoint: getEndpoint(tableId, DataSourceOperation.READ),
filters: { filters: {
equal: { equal: {
[rowKey]: row[rowKey], [fieldName]: row[primaryKey],
}, },
}, },
}) })
// this is the response from knex if no rows found // this is the response from knex if no rows found
if (!response[0].read) { const rows = !response[0].read ? response : []
cache[fullKey] = response related[fieldName] = { rows, isMany, tableId }
} }
} return related
return { rows: cache[fullKey] || [], table }
} }
/** /**
@ -390,19 +387,21 @@ module External {
* isn't supposed to exist anymore and delete those. This is better than the usual method of delete them * isn't supposed to exist anymore and delete those. This is better than the usual method of delete them
* all and then re-create, as theres no chance of losing data (e.g. delete succeed, but write fail). * all and then re-create, as theres no chance of losing data (e.g. delete succeed, but write fail).
*/ */
async handleManyRelationships(row: Row, relationships: ManyRelationship[]) { async handleManyRelationships(mainTableId: string, row: Row, relationships: ManyRelationship[]) {
const { appId } = this const { appId } = this
if (relationships.length === 0) {
return
}
// if we're creating (in a through table) need to wipe the existing ones first // if we're creating (in a through table) need to wipe the existing ones first
const promises = [] const promises = []
const cache: { [key: string]: Row[] } = {} const related = await this.lookupRelations(mainTableId, row)
for (let relationship of relationships) { for (let relationship of relationships) {
const { tableId, isUpdate, id, ...rest } = relationship const { key, tableId, isUpdate, id, ...rest } = relationship
const body = processObjectSync(rest, row) const body = processObjectSync(rest, row)
const { table, rows } = await this.lookup(row, relationship, cache) const linkTable = this.getTable(tableId)
const found = rows.find(row => isEqual(body, row)) // @ts-ignore
const linkPrimary = linkTable.primary[0]
const rows = related[key].rows || []
const found = rows.find((row: { [key: string]: any }) =>
row[linkPrimary] === relationship.id || row[linkPrimary] === body[linkPrimary]
)
const operation = isUpdate const operation = isUpdate
? DataSourceOperation.UPDATE ? DataSourceOperation.UPDATE
: DataSourceOperation.CREATE : DataSourceOperation.CREATE
@ -412,27 +411,27 @@ module External {
endpoint: getEndpoint(tableId, operation), endpoint: getEndpoint(tableId, operation),
// if we're doing many relationships then we're writing, only one response // if we're doing many relationships then we're writing, only one response
body, body,
filters: buildFilters(id, {}, table), filters: buildFilters(id, {}, linkTable),
}) })
) )
} else { } else {
// remove the relationship from the rows // remove the relationship from cache so it isn't adjusted again
rows.splice(rows.indexOf(found), 1) rows.splice(rows.indexOf(found), 1)
} }
} }
// finally if creating, cleanup any rows that aren't supposed to be here // finally cleanup anything that needs to be removed
for (let [key, rows] of Object.entries(cache)) { for (let [colName, {isMany, rows, tableId}] of Object.entries(related)) {
// @ts-ignore const table = this.getTable(tableId)
const tableId: string = key.split("/").shift()
const { tableName } = breakExternalTableId(tableId)
const table = this.tables[tableName]
for (let row of rows) { for (let row of rows) {
const filters = buildFilters(generateIdForRow(row, table), {}, table) const filters = buildFilters(generateIdForRow(row, table), {}, table)
// safety check, if there are no filters on deletion bad things happen // safety check, if there are no filters on deletion bad things happen
if (Object.keys(filters).length !== 0) { if (Object.keys(filters).length !== 0) {
const op = isMany ? DataSourceOperation.DELETE : DataSourceOperation.UPDATE
const body = isMany ? null : { [colName]: null }
promises.push( promises.push(
makeExternalQuery(this.appId, { makeExternalQuery(this.appId, {
endpoint: getEndpoint(tableId, DataSourceOperation.DELETE), endpoint: getEndpoint(tableId, op),
body,
filters, filters,
}) })
) )
@ -449,7 +448,7 @@ module External {
* Creating the specific list of fields that we desire, and excluding the ones that are no use to us * Creating the specific list of fields that we desire, and excluding the ones that are no use to us
* is more performant and has the added benefit of protecting against this scenario. * is more performant and has the added benefit of protecting against this scenario.
*/ */
buildFields(table: Table) { buildFields(table: Table, includeRelations: IncludeRelationships = IncludeRelationships.INCLUDE) {
function extractNonLinkFieldNames(table: Table, existing: string[] = []) { function extractNonLinkFieldNames(table: Table, existing: string[] = []) {
return Object.entries(table.schema) return Object.entries(table.schema)
.filter( .filter(
@ -461,7 +460,7 @@ module External {
} }
let fields = extractNonLinkFieldNames(table) let fields = extractNonLinkFieldNames(table)
for (let field of Object.values(table.schema)) { for (let field of Object.values(table.schema)) {
if (field.type !== FieldTypes.LINK) { if (field.type !== FieldTypes.LINK || !includeRelations) {
continue continue
} }
const { tableName: linkTableName } = breakExternalTableId(field.tableId) const { tableName: linkTableName } = breakExternalTableId(field.tableId)
@ -491,7 +490,7 @@ module External {
throw `Unable to process query, table "${tableName}" not defined.` throw `Unable to process query, table "${tableName}" not defined.`
} }
// clean up row on ingress using schema // clean up row on ingress using schema
filters = buildFilters(id, filters, table) filters = buildFilters(id, filters || {}, table)
const relationships = this.buildRelationships(table) const relationships = this.buildRelationships(table)
const processed = this.inputProcessing(row, table) const processed = this.inputProcessing(row, table)
row = processed.row row = processed.row
@ -524,8 +523,9 @@ module External {
// can't really use response right now // can't really use response right now
const response = await makeExternalQuery(appId, json) const response = await makeExternalQuery(appId, json)
// handle many to many relationships now if we know the ID (could be auto increment) // handle many to many relationships now if we know the ID (could be auto increment)
if (processed.manyRelationships && response) { if (operation !== DataSourceOperation.READ && processed.manyRelationships) {
await this.handleManyRelationships( await this.handleManyRelationships(
table._id || "",
response[0], response[0],
processed.manyRelationships processed.manyRelationships
) )

View File

@ -15,6 +15,7 @@ const { FieldTypes } = require("../../../constants")
const { isEqual } = require("lodash") const { isEqual } = require("lodash")
const { validate, findRow } = require("./utils") const { validate, findRow } = require("./utils")
const { fullSearch, paginatedSearch } = require("./internalSearch") const { fullSearch, paginatedSearch } = require("./internalSearch")
const { getGlobalUsersFromMetadata } = require("../../../utilities/global")
const CALCULATION_TYPES = { const CALCULATION_TYPES = {
SUM: "sum", SUM: "sum",
@ -132,7 +133,7 @@ exports.fetchView = async ctx => {
const viewName = ctx.params.viewName const viewName = ctx.params.viewName
// if this is a table view being looked for just transfer to that // if this is a table view being looked for just transfer to that
if (viewName.includes(DocumentTypes.TABLE)) { if (viewName.startsWith(DocumentTypes.TABLE)) {
ctx.params.tableId = viewName ctx.params.tableId = viewName
return exports.fetch(ctx) return exports.fetch(ctx)
} }
@ -290,6 +291,10 @@ exports.search = async ctx => {
// Enrich search results with relationships // Enrich search results with relationships
if (response.rows && response.rows.length) { if (response.rows && response.rows.length) {
// enrich with global users if from users table
if (tableId === InternalTables.USER_METADATA) {
response.rows = await getGlobalUsersFromMetadata(appId, response.rows)
}
const table = await db.get(tableId) const table = await db.get(tableId)
response.rows = await outputProcessing(ctx, table, response.rows) response.rows = await outputProcessing(ctx, table, response.rows)
} }

View File

@ -17,7 +17,7 @@ function removeGlobalProps(user) {
exports.fetchMetadata = async function (ctx) { exports.fetchMetadata = async function (ctx) {
const database = new CouchDB(ctx.appId) const database = new CouchDB(ctx.appId)
const global = await getGlobalUsers(ctx, ctx.appId) const global = await getGlobalUsers(ctx.appId)
const metadata = ( const metadata = (
await database.allDocs( await database.allDocs(
getUserMetadataParams(null, { getUserMetadataParams(null, {

View File

@ -15,6 +15,20 @@ const NO_TENANCY_ENDPOINTS = [
route: "/api/analytics", route: "/api/analytics",
method: "GET", method: "GET",
}, },
{
route: "/builder",
method: "GET",
},
// when using this locally there can be pass through, need
// to allow all pass through endpoints to go without tenancy
{
route: "/api/global",
method: "ALL",
},
{
route: "/api/system",
method: "ALL",
},
] ]
router router

View File

@ -13,8 +13,8 @@ const CouchDB = require("../../db")
const { FieldTypes } = require("../../constants") const { FieldTypes } = require("../../constants")
const { getMultiIDParams, USER_METDATA_PREFIX } = require("../../db/utils") const { getMultiIDParams, USER_METDATA_PREFIX } = require("../../db/utils")
const { partition } = require("lodash") const { partition } = require("lodash")
const { getGlobalUsers } = require("../../utilities/global") const { getGlobalUsersFromMetadata } = require("../../utilities/global")
const processor = require("../../utilities/rowProcessor") const { processFormulas } = require("../../utilities/rowProcessor/utils")
/** /**
* This functionality makes sure that when rows with links are created, updated or deleted they are processed * This functionality makes sure that when rows with links are created, updated or deleted they are processed
@ -71,17 +71,7 @@ async function getFullLinkedDocs(ctx, appId, links) {
let [users, other] = partition(linked, linkRow => let [users, other] = partition(linked, linkRow =>
linkRow._id.startsWith(USER_METDATA_PREFIX) linkRow._id.startsWith(USER_METDATA_PREFIX)
) )
const globalUsers = await getGlobalUsers(ctx, appId, users) users = await getGlobalUsersFromMetadata(appId, users)
users = users.map(user => {
const globalUser = globalUsers.find(
globalUser => globalUser && user._id.includes(globalUser._id)
)
return {
...globalUser,
// doing user second overwrites the id and rev (always metadata)
...user,
}
})
return [...other, ...users] return [...other, ...users]
} }
@ -197,9 +187,7 @@ exports.attachFullLinkedDocs = async (ctx, table, rows) => {
if (!linkedRow || !linkedTable) { if (!linkedRow || !linkedTable) {
continue continue
} }
row[link.fieldName].push( row[link.fieldName].push(processFormulas(linkedTable, linkedRow))
processor.processFormulas(linkedTable, linkedRow)
)
} }
} }
return rows return rows

View File

@ -100,11 +100,11 @@ exports.createAllSearchIndex = async appId => {
let idxKey = prev != null ? `${prev}.${key}` : key let idxKey = prev != null ? `${prev}.${key}` : key
idxKey = idxKey.replace(/ /, "_") idxKey = idxKey.replace(/ /, "_")
if (Array.isArray(input[key])) { if (Array.isArray(input[key])) {
for (let val in input[key]) { for (let val of input[key]) {
if (typeof val !== "object") {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
index(idxKey, input[key][val], { index(idxKey, val, { store: true })
store: true, }
})
} }
} else if (key === "_id" || key === "_rev" || input[key] == null) { } else if (key === "_id" || key === "_rev" || input[key] == null) {
continue continue

View File

@ -40,6 +40,11 @@ export enum SourceNames {
REST = "REST", REST = "REST",
} }
export enum IncludeRelationships {
INCLUDE = 1,
EXCLUDE = 0
}
export interface QueryDefinition { export interface QueryDefinition {
type: QueryTypes type: QueryTypes
displayName?: string displayName?: string

View File

@ -76,6 +76,7 @@ module ArangoModule {
const result = await this.client.query(query.sql) const result = await this.client.query(query.sql)
return result.all() return result.all()
} catch (err) { } catch (err) {
// @ts-ignore
console.error("Error querying arangodb", err.message) console.error("Error querying arangodb", err.message)
throw err throw err
} finally { } finally {
@ -91,6 +92,7 @@ module ArangoModule {
) )
return result.all() return result.all()
} catch (err) { } catch (err) {
// @ts-ignore
console.error("Error querying arangodb", err.message) console.error("Error querying arangodb", err.message)
throw err throw err
} finally { } finally {

View File

@ -1,5 +1,7 @@
import { Knex, knex } from "knex" import { Knex, knex } from "knex"
const BASE_LIMIT = 5000 const BASE_LIMIT = 5000
// if requesting a single row then need to up the limit for the sake of joins
const SINGLE_ROW_LIMIT = 100
import { import {
QueryJson, QueryJson,
SearchFilters, SearchFilters,
@ -168,17 +170,21 @@ function buildRead(knex: Knex, json: QueryJson, limit: number): KnexQuery {
query = query.orderBy(key, direction) query = query.orderBy(key, direction)
} }
} }
let foundLimit = limit || BASE_LIMIT
// handle pagination // handle pagination
if (paginate && paginate.page && paginate.limit) { if (paginate && paginate.page && paginate.limit) {
// @ts-ignore // @ts-ignore
const page = paginate.page <= 1 ? 0 : paginate.page - 1 const page = paginate.page <= 1 ? 0 : paginate.page - 1
const offset = page * paginate.limit const offset = page * paginate.limit
query = query.offset(offset).limit(paginate.limit) foundLimit = paginate.limit
query = query.offset(offset)
} else if (paginate && paginate.limit) { } else if (paginate && paginate.limit) {
query = query.limit(paginate.limit) foundLimit = paginate.limit
} else {
query.limit(limit)
} }
if (foundLimit === 1) {
foundLimit = SINGLE_ROW_LIMIT
}
query = query.limit(foundLimit)
return query return query
} }

View File

@ -73,6 +73,7 @@ module MSSQLModule {
try { try {
return await client.query(query.sql, query.bindings || {}) return await client.query(query.sql, query.bindings || {})
} catch (err) { } catch (err) {
// @ts-ignore
throw new Error(err) throw new Error(err)
} }
} }
@ -101,6 +102,7 @@ module MSSQLModule {
const client = await this.pool.connect() const client = await this.pool.connect()
this.client = client.request() this.client = client.request()
} catch (err) { } catch (err) {
// @ts-ignore
throw new Error(err) throw new Error(err)
} }
} }

View File

@ -94,6 +94,7 @@ module PostgresModule {
try { try {
return await client.query(query.sql, query.bindings || []) return await client.query(query.sql, query.bindings || [])
} catch (err) { } catch (err) {
// @ts-ignore
throw new Error(err) throw new Error(err)
} }
} }

View File

@ -33,13 +33,14 @@ export function generateRowIdField(keyProps: any[] = []) {
} }
// should always return an array // should always return an array
export function breakRowIdField(_id: string): any[] { export function breakRowIdField(_id: string | { _id: string }): any[] {
if (!_id) { if (!_id) {
return [] return []
} }
// have to replace on the way back as we swapped out the double quotes // have to replace on the way back as we swapped out the double quotes
// when encoding, but JSON can't handle the single quotes // when encoding, but JSON can't handle the single quotes
const decoded: string = decodeURIComponent(_id).replace(/'/g, '"') const id = typeof _id === "string" ? _id : _id._id
const decoded: string = decodeURIComponent(id).replace(/'/g, '"')
try { try {
const parsed = JSON.parse(decoded) const parsed = JSON.parse(decoded)
return Array.isArray(parsed) ? parsed : [parsed] return Array.isArray(parsed) ? parsed : [parsed]

View File

@ -39,13 +39,13 @@ exports.getCachedSelf = async (ctx, appId) => {
return processUser(appId, user) return processUser(appId, user)
} }
exports.getGlobalUser = async (ctx, appId, userId) => { exports.getGlobalUser = async (appId, userId) => {
const db = getGlobalDB() const db = getGlobalDB()
let user = await db.get(getGlobalIDFromUserMetadataID(userId)) let user = await db.get(getGlobalIDFromUserMetadataID(userId))
return processUser(appId, user) return processUser(appId, user)
} }
exports.getGlobalUsers = async (ctx, appId = null, users = null) => { exports.getGlobalUsers = async (appId = null, users = null) => {
const db = getGlobalDB() const db = getGlobalDB()
let globalUsers let globalUsers
if (users) { if (users) {
@ -73,3 +73,17 @@ exports.getGlobalUsers = async (ctx, appId = null, users = null) => {
} }
return globalUsers.map(user => exports.updateAppRole(appId, user)) return globalUsers.map(user => exports.updateAppRole(appId, user))
} }
exports.getGlobalUsersFromMetadata = async (appId, users) => {
const globalUsers = await exports.getGlobalUsers(appId, users)
return users.map(user => {
const globalUser = globalUsers.find(
globalUser => globalUser && user._id.includes(globalUser._id)
)
return {
...globalUser,
// doing user second overwrites the id and rev (always metadata)
...user,
}
})
}

View File

@ -1,8 +1,8 @@
const linkRows = require("../db/linkedRows") const linkRows = require("../../db/linkedRows")
const { cloneDeep } = require("lodash/fp") const { cloneDeep } = require("lodash/fp")
const { FieldTypes, AutoFieldSubTypes } = require("../constants") const { FieldTypes, AutoFieldSubTypes } = require("../../constants")
const { processStringSync } = require("@budibase/string-templates") const { attachmentsRelativeURL } = require("../index")
const { attachmentsRelativeURL } = require("./index") const { processFormulas } = require("./utils")
const BASE_AUTO_ID = 1 const BASE_AUTO_ID = 1
@ -128,28 +128,6 @@ function processAutoColumn(user, table, row) {
return { table, row } return { table, row }
} }
/**
* Looks through the rows provided and finds formulas - which it then processes.
*/
function processFormulas(table, rows) {
const single = !Array.isArray(rows)
if (single) {
rows = [rows]
}
for (let [column, schema] of Object.entries(table.schema)) {
if (schema.type !== FieldTypes.FORMULA) {
continue
}
// iterate through rows and process formula
rows = rows.map(row => ({
...row,
[column]: processStringSync(schema.formula, row),
}))
}
return single ? rows[0] : rows
}
exports.processFormulas = processFormulas
/** /**
* This will coerce a value to the correct types based on the type transform map * This will coerce a value to the correct types based on the type transform map
* @param {object} row The value to coerce * @param {object} row The value to coerce

View File

@ -0,0 +1,23 @@
const { FieldTypes } = require("../../constants")
const { processStringSync } = require("@budibase/string-templates")
/**
* Looks through the rows provided and finds formulas - which it then processes.
*/
exports.processFormulas = (table, rows) => {
const single = !Array.isArray(rows)
if (single) {
rows = [rows]
}
for (let [column, schema] of Object.entries(table.schema)) {
if (schema.type !== FieldTypes.FORMULA) {
continue
}
// iterate through rows and process formula
rows = rows.map(row => ({
...row,
[column]: processStringSync(schema.formula, row),
}))
}
return single ? rows[0] : rows
}

View File

@ -3,7 +3,7 @@ const { InternalTables } = require("../db/utils")
const { getGlobalUser } = require("../utilities/global") const { getGlobalUser } = require("../utilities/global")
exports.getFullUser = async (ctx, userId) => { exports.getFullUser = async (ctx, userId) => {
const global = await getGlobalUser(ctx, ctx.appId, userId) const global = await getGlobalUser(ctx.appId, userId)
let metadata let metadata
try { try {
// this will throw an error if the db doesn't exist, or there is no appId // this will throw an error if the db doesn't exist, or there is no appId

View File

@ -104,7 +104,7 @@ exports.addAppRoleToUser = async (ctx, appId, roleId, userId = null) => {
user = await exports.getGlobalSelf(ctx) user = await exports.getGlobalSelf(ctx)
endpoint = `/api/global/users/self` endpoint = `/api/global/users/self`
} else { } else {
user = await getGlobalUser(ctx, appId, userId) user = await getGlobalUser(appId, userId)
body._id = userId body._id = userId
endpoint = `/api/global/users` endpoint = `/api/global/users`
} }

File diff suppressed because it is too large Load Diff

View File

@ -29,11 +29,11 @@
"keywords": [ "keywords": [
"svelte" "svelte"
], ],
"version": "0.9.116", "version": "0.9.121",
"license": "MIT", "license": "MIT",
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc", "gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc",
"dependencies": { "dependencies": {
"@budibase/bbui": "^0.9.116", "@budibase/bbui": "^0.9.121",
"@spectrum-css/button": "^3.0.3", "@spectrum-css/button": "^3.0.3",
"@spectrum-css/card": "^3.0.3", "@spectrum-css/card": "^3.0.3",
"@spectrum-css/divider": "^1.0.3", "@spectrum-css/divider": "^1.0.3",

View File

@ -2,59 +2,6 @@
# yarn lockfile v1 # yarn lockfile v1
"@adobe/spectrum-css-workflow-icons@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@adobe/spectrum-css-workflow-icons/-/spectrum-css-workflow-icons-1.2.1.tgz#7e2cb3fcfb5c8b12d7275afafbb6ec44913551b4"
integrity sha512-uVgekyBXnOVkxp+CUssjN/gefARtudZC8duEn1vm0lBQFwGRZFlDEzU1QC+aIRWCrD1Z8OgRpmBYlSZ7QS003w==
"@budibase/bbui@^0.9.115":
version "0.9.115"
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.115.tgz#6aa0226908812052cd02628d6d604b95a3d55b92"
integrity sha512-HysxPp8POetLWj1pucrhn4Na+KllKvHRmBV7qU9XE1BVL9B2pLa6rPoZeLYrdMQmBW070bmXSdUuYDWZqEYYog==
dependencies:
"@adobe/spectrum-css-workflow-icons" "^1.2.1"
"@spectrum-css/actionbutton" "^1.0.1"
"@spectrum-css/actiongroup" "^1.0.1"
"@spectrum-css/avatar" "^3.0.2"
"@spectrum-css/button" "^3.0.1"
"@spectrum-css/buttongroup" "^3.0.2"
"@spectrum-css/checkbox" "^3.0.2"
"@spectrum-css/dialog" "^3.0.1"
"@spectrum-css/divider" "^1.0.1"
"@spectrum-css/dropzone" "^3.0.2"
"@spectrum-css/fieldgroup" "^3.0.2"
"@spectrum-css/fieldlabel" "^3.0.1"
"@spectrum-css/icon" "^3.0.1"
"@spectrum-css/illustratedmessage" "^3.0.2"
"@spectrum-css/inputgroup" "^3.0.2"
"@spectrum-css/label" "^2.0.10"
"@spectrum-css/link" "^3.1.1"
"@spectrum-css/menu" "^3.0.1"
"@spectrum-css/modal" "^3.0.1"
"@spectrum-css/pagination" "^3.0.3"
"@spectrum-css/picker" "^1.0.1"
"@spectrum-css/popover" "^3.0.1"
"@spectrum-css/progressbar" "^1.0.2"
"@spectrum-css/progresscircle" "^1.0.2"
"@spectrum-css/radio" "^3.0.2"
"@spectrum-css/search" "^3.0.2"
"@spectrum-css/sidenav" "^3.0.2"
"@spectrum-css/statuslight" "^3.0.2"
"@spectrum-css/switch" "^1.0.2"
"@spectrum-css/table" "^3.0.1"
"@spectrum-css/tabs" "^3.0.1"
"@spectrum-css/tags" "^3.0.2"
"@spectrum-css/textfield" "^3.0.1"
"@spectrum-css/toast" "^3.0.1"
"@spectrum-css/tooltip" "^3.0.3"
"@spectrum-css/treeview" "^3.0.2"
"@spectrum-css/typography" "^3.0.1"
"@spectrum-css/underlay" "^2.0.9"
"@spectrum-css/vars" "^3.0.1"
dayjs "^1.10.4"
svelte-flatpickr "^3.1.0"
svelte-portal "^1.0.0"
"@rollup/pluginutils@^4.1.1": "@rollup/pluginutils@^4.1.1":
version "4.1.1" version "4.1.1"
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.1.tgz#1d4da86dd4eded15656a57d933fda2b9a08d47ec" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.1.tgz#1d4da86dd4eded15656a57d933fda2b9a08d47ec"
@ -63,103 +10,28 @@
estree-walker "^2.0.1" estree-walker "^2.0.1"
picomatch "^2.2.2" picomatch "^2.2.2"
"@spectrum-css/actionbutton@^1.0.1": "@spectrum-css/button@^3.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/actionbutton/-/actionbutton-1.0.3.tgz#8f7342a69b303c5acdcfa0a59f5e9267b9f3cb30"
integrity sha512-P9qoCPSiZ1SB6ZYqK5hub0vGty00YYqonQE0KTjtb1i+T1nYR/87vWqVPERx9j63uhgZncjwFYaThTvRqye7eQ==
"@spectrum-css/actiongroup@^1.0.1":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/actiongroup/-/actiongroup-1.0.3.tgz#4713ce65e6f5c72c404a7b638fbc3b4fd7e3874f"
integrity sha512-NlB9Q4ZlWixXxymoPIYG6g2hkwAGKFodHWPFfxHD8ddkjXWRB9G2akUP7cfsJ4DcYn4VisUORCOYQwqDiSmboQ==
"@spectrum-css/avatar@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/avatar/-/avatar-3.0.2.tgz#4f1826223eae330e64b6d3cc899e9bc2e98dac95"
integrity sha512-wEczvSqxttTWSiL3cOvXV/RmGRwSkw2w6+slcHhnf0kb7ovymMM+9oz8vvEpEsSeo5u598bc+7ktrKFpAd6soQ==
"@spectrum-css/button@^3.0.1", "@spectrum-css/button@^3.0.3":
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/button/-/button-3.0.3.tgz#2df1efaab6c7e0b3b06cb4b59e1eae59c7f1fc84" resolved "https://registry.yarnpkg.com/@spectrum-css/button/-/button-3.0.3.tgz#2df1efaab6c7e0b3b06cb4b59e1eae59c7f1fc84"
integrity sha512-6CnLPqqtaU/PcSSIGeGRi0iFIIxIUByYLKFO6zn5NEUc12KQ28dJ4PLwB6WBa0L8vRoAGlnWWH2ZZweTijbXgg== integrity sha512-6CnLPqqtaU/PcSSIGeGRi0iFIIxIUByYLKFO6zn5NEUc12KQ28dJ4PLwB6WBa0L8vRoAGlnWWH2ZZweTijbXgg==
"@spectrum-css/buttongroup@^3.0.2":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/buttongroup/-/buttongroup-3.0.3.tgz#719d868845ac9d2c4f939c1b9f6044507902d5aa"
integrity sha512-eXl8U4QWMWXqyTu654FdQdEGnmczgOYlpIFSHyCMVjhtPqZp2xwnLFiGh6LKw+bLio6eeOZ0L+vpk1GcoYqgkw==
"@spectrum-css/card@^3.0.3": "@spectrum-css/card@^3.0.3":
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/card/-/card-3.0.3.tgz#56b2e2da6b80c1583228baa279de7407383bfb6b" resolved "https://registry.yarnpkg.com/@spectrum-css/card/-/card-3.0.3.tgz#56b2e2da6b80c1583228baa279de7407383bfb6b"
integrity sha512-+oKLUI2a0QmQP9EzySeq/G4FpUkkdaDNbuEbqCj2IkPMc/2v/nwzsPhh1fj2UIghGAiiUwXfPpzax1e8fyhQUg== integrity sha512-+oKLUI2a0QmQP9EzySeq/G4FpUkkdaDNbuEbqCj2IkPMc/2v/nwzsPhh1fj2UIghGAiiUwXfPpzax1e8fyhQUg==
"@spectrum-css/checkbox@^3.0.2": "@spectrum-css/divider@^1.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/checkbox/-/checkbox-3.0.3.tgz#8577067fc8b97e4609f92bd242364937a533a7bb"
integrity sha512-QVG9uMHq+lh70Dh6mDNnY+vEvNz2p7VC6xgLfDYfijp2qeiqYPq72fQK6p/SiyqPk96ZACzNRwgeROU6Xf6Wgg==
"@spectrum-css/dialog@^3.0.1":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/dialog/-/dialog-3.0.3.tgz#7715a4ea435e753afb623d99ca5917ed1bcd6f34"
integrity sha512-AhmKgfRIVyTe3ABiJ8lLUQL34VB/H6fN16na2LlbDRJvyRMzkdN1Xf2i6U3f4OMd3qQ8Gm5xat4BvMxIQPBAUQ==
"@spectrum-css/divider@^1.0.1", "@spectrum-css/divider@^1.0.3":
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/divider/-/divider-1.0.3.tgz#639e2ebaa0834efa40f42397668bbd5c153ea385" resolved "https://registry.yarnpkg.com/@spectrum-css/divider/-/divider-1.0.3.tgz#639e2ebaa0834efa40f42397668bbd5c153ea385"
integrity sha512-Zy4Rn40w8UtzMh3wx/U9+CepSCpm1aOCGftHgWDub0XZuVTzh0c1WwyzTuLCx2Hf21z5VRGNiDh8bGEEzSbtNA== integrity sha512-Zy4Rn40w8UtzMh3wx/U9+CepSCpm1aOCGftHgWDub0XZuVTzh0c1WwyzTuLCx2Hf21z5VRGNiDh8bGEEzSbtNA==
dependencies: dependencies:
"@spectrum-css/vars" "^3.0.2" "@spectrum-css/vars" "^3.0.2"
"@spectrum-css/dropzone@^3.0.2": "@spectrum-css/link@^3.1.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/dropzone/-/dropzone-3.0.3.tgz#aee71697a2c195947599d7541b858c3c198741dc"
integrity sha512-ujrswdtB6bHigklyHsm6zomFd6rUnKJ3xVVRjroVF4+ouK4DxK5tX0iVd0EW6AOfOjx4Cc28uyFot3fpxp+MQw==
"@spectrum-css/fieldgroup@^3.0.2":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/fieldgroup/-/fieldgroup-3.0.3.tgz#85d85da048d08200f25ceab378026dd2b11e0bb2"
integrity sha512-wXUXTXN1CPnR7M4Ltd+3uh7BfcNGUV1+Xe0/h0tCpq/j+S2Sd4xo7/pUMdU19sIDrAAtpEFp1tt+nouHcU5HGQ==
"@spectrum-css/fieldlabel@^3.0.1":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/fieldlabel/-/fieldlabel-3.0.3.tgz#f73c04d20734d4718ffb620dc46458904685b449"
integrity sha512-nEvIkEXCD5n4fW67Unq6Iu7VXoauEd/JGpfTY02VsC5p4FJLnwKfPDbJUuUsqClAxqw7nAsmXVKtn4zQFf5yPQ==
"@spectrum-css/icon@^3.0.1":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/icon/-/icon-3.0.3.tgz#5c612822380927087aebd526855d82ed2c3e2cba"
integrity sha512-hyloKOejPCXhP3MBNsm3SjR9j8xT1R1S19p32KW/0Qhj+VMUtfyEPmevyFptpn7wcovQccdl/vZVIVDuML/imw==
"@spectrum-css/illustratedmessage@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/illustratedmessage/-/illustratedmessage-3.0.2.tgz#6a480be98b027e050b086e7899e40d87adb0a8c0"
integrity sha512-dqnE8X27bGcO0HN8+dYx8O4o0dNNIAqeivOzDHhe2El+V4dTzMrNIerF6G0NLm3GjVf6XliwmitsZK+K6FmbtA==
"@spectrum-css/inputgroup@^3.0.2":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/inputgroup/-/inputgroup-3.0.3.tgz#00c9a370ddc2c55cf0f37dd6069faa9501fd7eb5"
integrity sha512-FqRJTiLL7jiGfzDVXWUGVLqHryJjCcqQIrqAi+Tq0oenapzsBe2qc/zIrKgh2wtMI+NTIBLXTECvij3L1HlqAg==
"@spectrum-css/label@^2.0.10":
version "2.0.10"
resolved "https://registry.yarnpkg.com/@spectrum-css/label/-/label-2.0.10.tgz#2368651d7636a19385b5d300cdf6272db1916001"
integrity sha512-xCbtEiQkZIlLdWFikuw7ifDCC21DOC/KMgVrrVJHXFc4KRQe9LTZSqmGF3tovm+CSq1adE59mYoTbojVQ9YuEQ==
"@spectrum-css/link@^3.1.1", "@spectrum-css/link@^3.1.3":
version "3.1.3" version "3.1.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/link/-/link-3.1.3.tgz#b0e560a7e0acdb4a2b329b6669696aa3438f5993" resolved "https://registry.yarnpkg.com/@spectrum-css/link/-/link-3.1.3.tgz#b0e560a7e0acdb4a2b329b6669696aa3438f5993"
integrity sha512-8Pmy5d73MwKcATTPaj+fSrZYnIw7GmfX40AvpC1xx5LauOxsbUb4AVNp1kn2H8rrOBmxF7czyhoBBhEiv66QUg== integrity sha512-8Pmy5d73MwKcATTPaj+fSrZYnIw7GmfX40AvpC1xx5LauOxsbUb4AVNp1kn2H8rrOBmxF7czyhoBBhEiv66QUg==
"@spectrum-css/menu@^3.0.1":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/menu/-/menu-3.0.3.tgz#46a9b221bb5f470a2f8a934bdfd512d84d2fdc4d"
integrity sha512-qKA9J/MrikNKIpCEHsAazG2vY3im5tjGCmo6p9Pdnu8/aQMsiuZDHZayukeCttJUZkrb9guDVL9OIHlK5RZvcQ==
"@spectrum-css/modal@^3.0.1":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/modal/-/modal-3.0.2.tgz#58b6621cab65f90788d310374f40df1f7090473f"
integrity sha512-YnIivJhoaao7Otu+HV7sgebPyFbO6sd/oMvTN/Rb2wwgnaMnIIuIRdGandSrcgotN2uNgs+P0knG6mv/xA1/dg==
"@spectrum-css/page@^3.0.1": "@spectrum-css/page@^3.0.1":
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/page/-/page-3.0.2.tgz#8f0c03d25f5565fb13115541a8fcaf0e1d3a8ee0" resolved "https://registry.yarnpkg.com/@spectrum-css/page/-/page-3.0.2.tgz#8f0c03d25f5565fb13115541a8fcaf0e1d3a8ee0"
@ -167,101 +39,11 @@
dependencies: dependencies:
"@spectrum-css/vars" "^3.0.2" "@spectrum-css/vars" "^3.0.2"
"@spectrum-css/pagination@^3.0.3": "@spectrum-css/typography@^3.0.2":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/pagination/-/pagination-3.0.3.tgz#b204c3ada384c4af751a354bc428346d82eeea65"
integrity sha512-OJ/v9GeNXJOZ9Yr9LDBYPrR2NCiLOWP9wANT/a5sqFuugRnQbn/HYMnRp9TBxwpDY6ihaPo0T/wi7kLiAJFdDw==
"@spectrum-css/picker@^1.0.1":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/picker/-/picker-1.0.3.tgz#21379bcf8ae94277deeb6ad65dcd9e2bbfacb487"
integrity sha512-oHLGxBx5BwVCSGo7/T1C9PTHX1+/5AmVjyLiTJ4UoIdSJmOERw9YcRZbcGZgBJNWbxcjr4TyGtwj1EcSjEy97w==
"@spectrum-css/popover@^3.0.1":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/popover/-/popover-3.0.3.tgz#6fb69873474fb968afb738eacb9e121f93e83a09"
integrity sha512-KvmXv4TV19FBx39KfmgVlDYtvtBqv/8RRK7RRLDDHGViTxZtShjVsVpwIgfkfgn4iJztCnXpWzFqRXWUu2XCpQ==
"@spectrum-css/progressbar@^1.0.2":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/progressbar/-/progressbar-1.0.3.tgz#f70bcc38a2a21cff2f422ec825724ebbb9455e67"
integrity sha512-vJHplefUuy8+NjCw1X7fLbqHVGNVBpvGFXNAeaIj4SFf4ygxiUq/5c9iRhhsCQixEsJlfD/b7BnGXU7BUDkr6Q==
"@spectrum-css/progresscircle@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/progresscircle/-/progresscircle-1.0.2.tgz#258ea9170fb70f795edda03e38a61d93bef4487c"
integrity sha512-JLULpyzjIY95lzlWR1yE1gv4l1K6p+scQ+edmuZZUHBzwM3pUtkvHJmUlA9TYdResUYW6Uka60VRdY6lZ8gnFQ==
"@spectrum-css/radio@^3.0.2":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/radio/-/radio-3.0.3.tgz#25c3bc5e9c30a8a8ae728717b7c7fb736cdae640"
integrity sha512-LaLGfz/eGNR2iyqouXYILIA+pKRqF769iPdwM0REm5RpWvMQDD7rPZ/kWlg18owjaFsyllEp25gEjmhRJIIVOw==
"@spectrum-css/search@^3.0.2":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/search/-/search-3.0.3.tgz#3415dc106aca0d5dd996e87084a1b47c2b95a882"
integrity sha512-kdLpKTt0obljuhS1q1tukujRlvSs8sBwij76D4Qp8KpMzwePfZyvv1kYzuWPNZfTeISxWsmyZ6Wxd1uvzjn+UA==
"@spectrum-css/sidenav@^3.0.2":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/sidenav/-/sidenav-3.0.3.tgz#132141fbd2500a927c312fa4e1d712c438b3d597"
integrity sha512-cQ+CgwjxGftrcc79i1XnGd66QTl7H7zopSU0UTV4Qq7hvqfrjjWxfZ6b+3tezrrhNlDope1ff9o8sm67PsPXtg==
"@spectrum-css/statuslight@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/statuslight/-/statuslight-3.0.2.tgz#dc54b6cd113413dcdb909c486b5d7bae60db65c5"
integrity sha512-xodB8g8vGJH20XmUj9ZsPlM1jHrGeRbvmVXkz0q7YvQrYAhim8pP3W+XKKZAletPFAuu8cmUOc6SWn6i4X4z6w==
"@spectrum-css/switch@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/switch/-/switch-1.0.2.tgz#f0b4c69271964573e02b08e90998096e49e1de44"
integrity sha512-zqmHpgWPNg1gEwdUNFYV3CBX5JaeALfIqcJIxE0FLZqr9d1C4+oLE0ItIFzt1bwr4bFAOmkEpvtiY+amluzGxQ==
"@spectrum-css/table@^3.0.1":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/table/-/table-3.0.3.tgz#7f7f19905ef3275cbf907ce3a5818e63c30b2caf"
integrity sha512-nxwzVjLPsXoY/v4sdxOVYLcC+cEbGgJyLcLclT5LT9MGSbngFeUMJzzVR4EvehzuN4dH7hrATG7Mbuq29Mf0Hg==
"@spectrum-css/tabs@^3.0.1":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/tabs/-/tabs-3.0.3.tgz#51dd6f168c897b0fdc3a7e9f901df7bd2288b4fc"
integrity sha512-iLP1I72bJWz9APdQB1jiw+pOv5a7N+hYOCJvRoc56Us/hJKVzowkyGRe3uH+8v36nCG9bHxiAQNLoU8eXisVrg==
"@spectrum-css/tags@^3.0.2":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/tags/-/tags-3.0.3.tgz#fc76d2735cdc442de91b7eb3bee49a928c0767ac"
integrity sha512-SL8vPxVDfWcY5VdIuyl0TImEXcOU1I7yCyXkk7MudMwfnYs81FaIyY32hFV9OHj0Tz/36UzRzc7AVMSuRQ53pw==
"@spectrum-css/textfield@^3.0.1":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/textfield/-/textfield-3.0.2.tgz#907f62d2dc82852dd6236a820be99e252b531631"
integrity sha512-nkFgAb0cP4jUodkUBErMNfyF78jJLtgL1Mrr9/rvGpGobo10IAbb8zZY4CkZ64o8XmMy/85+wZTKcx+KHatqpg==
"@spectrum-css/toast@^3.0.1":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/toast/-/toast-3.0.3.tgz#97c1527384707600832ecda35643ed304615250f"
integrity sha512-CjLeaMs+cjUXojCCRtbj0YkD2BoZW16kjj2o5omkEpUTjA34IJ8xJ1a+CCtDILWekhXvN0MBN4sbumcnwcnx8w==
"@spectrum-css/tooltip@^3.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/tooltip/-/tooltip-3.0.3.tgz#26b8ca3b3d30e29630244d85eb4fc11d0c841281"
integrity sha512-ztRF7WW1FzyNavXBRc+80z67UoOrY9wl3cMYsVD3MpDnyxdzP8cjza1pCcolKBaFqRTcQKkxKw3GWtGICRKR5A==
"@spectrum-css/treeview@^3.0.2":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@spectrum-css/treeview/-/treeview-3.0.3.tgz#aeda5175158b9f8d7529cb2b394428eb2a428046"
integrity sha512-D5gGzZC/KtRArdx86Mesc9+99W9nTbUOeyYGqoJoAfJSOttoT6Tk5CrDvlCmAqjKf5rajemAkGri1ChqvUIwkw==
"@spectrum-css/typography@^3.0.1", "@spectrum-css/typography@^3.0.2":
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/typography/-/typography-3.0.2.tgz#ea3ca0a60e18064527819d48c8c4364cab4fcd38" resolved "https://registry.yarnpkg.com/@spectrum-css/typography/-/typography-3.0.2.tgz#ea3ca0a60e18064527819d48c8c4364cab4fcd38"
integrity sha512-5ZOLmQe0edzsDMyhghUd4hBb5uxGsFrxzf+WasfcUw9klSfTsRZ09n1BsaaWbgrLjlMQ+EEHS46v5VNo0Ms2CA== integrity sha512-5ZOLmQe0edzsDMyhghUd4hBb5uxGsFrxzf+WasfcUw9klSfTsRZ09n1BsaaWbgrLjlMQ+EEHS46v5VNo0Ms2CA==
"@spectrum-css/underlay@^2.0.9":
version "2.0.10"
resolved "https://registry.yarnpkg.com/@spectrum-css/underlay/-/underlay-2.0.10.tgz#8b75b646605a311850f6620caa18d4996cd64ed7"
integrity sha512-PmsmkzeGD/rY4pp3ILXHt9w8BW7uaEqXe08hQRS7rGki7wqCpG4mE0/8N3yEcA3QxWQclmG9gdkg5uz6wMmYzA==
"@spectrum-css/vars@^3.0.1", "@spectrum-css/vars@^3.0.2": "@spectrum-css/vars@^3.0.1", "@spectrum-css/vars@^3.0.2":
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.2.tgz#ea9062c3c98dfc6ba59e5df14a03025ad8969999" resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.2.tgz#ea9062c3c98dfc6ba59e5df14a03025ad8969999"
@ -296,7 +78,7 @@ colorette@^1.2.2:
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
dayjs@^1.10.4, dayjs@^1.10.5: dayjs@^1.10.5:
version "1.10.6" version "1.10.6"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.6.tgz#288b2aa82f2d8418a6c9d4df5898c0737ad02a63" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.6.tgz#288b2aa82f2d8418a6c9d4df5898c0737ad02a63"
integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw== integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw==
@ -437,11 +219,6 @@ svelte-hmr@^0.14.7:
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.7.tgz#7fa8261c7b225d9409f0a86f3b9ea5c3ca6f6607" resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.7.tgz#7fa8261c7b225d9409f0a86f3b9ea5c3ca6f6607"
integrity sha512-pDrzgcWSoMaK6AJkBWkmgIsecW0GChxYZSZieIYfCP0v2oPyx2CYU/zm7TBIcjLVUPP714WxmViE9Thht4etog== integrity sha512-pDrzgcWSoMaK6AJkBWkmgIsecW0GChxYZSZieIYfCP0v2oPyx2CYU/zm7TBIcjLVUPP714WxmViE9Thht4etog==
svelte-portal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/svelte-portal/-/svelte-portal-1.0.0.tgz#36a47c5578b1a4d9b4dc60fa32a904640ec4cdd3"
integrity sha512-nHf+DS/jZ6jjnZSleBMSaZua9JlG5rZv9lOGKgJuaZStfevtjIlUJrkLc3vbV8QdBvPPVmvcjTlazAzfKu0v3Q==
svelte@^3.38.2: svelte@^3.38.2:
version "3.42.1" version "3.42.1"
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.42.1.tgz#d4b4d9068cce911835f7c6b8ff1d290e1a0b5657" resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.42.1.tgz#d4b4d9068cce911835f7c6b8ff1d290e1a0b5657"

View File

@ -1,6 +1,6 @@
{ {
"name": "@budibase/string-templates", "name": "@budibase/string-templates",
"version": "0.9.116", "version": "0.9.121",
"description": "Handlebars wrapper for Budibase templating.", "description": "Handlebars wrapper for Budibase templating.",
"main": "src/index.cjs", "main": "src/index.cjs",
"module": "dist/bundle.mjs", "module": "dist/bundle.mjs",

View File

@ -1,7 +1,7 @@
{ {
"name": "@budibase/worker", "name": "@budibase/worker",
"email": "hi@budibase.com", "email": "hi@budibase.com",
"version": "0.9.116", "version": "0.9.121",
"description": "Budibase background service", "description": "Budibase background service",
"main": "src/index.js", "main": "src/index.js",
"repository": { "repository": {
@ -23,8 +23,8 @@
"author": "Budibase", "author": "Budibase",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@budibase/auth": "^0.9.116", "@budibase/auth": "^0.9.121",
"@budibase/string-templates": "^0.9.116", "@budibase/string-templates": "^0.9.121",
"@koa/router": "^8.0.0", "@koa/router": "^8.0.0",
"@techpass/passport-openidconnect": "^0.3.0", "@techpass/passport-openidconnect": "^0.3.0",
"aws-sdk": "^2.811.0", "aws-sdk": "^2.811.0",

View File

@ -7,7 +7,6 @@ exports.getApps = async ctx => {
const apps = await getAllApps(CouchDB, { dev: true }) const apps = await getAllApps(CouchDB, { dev: true })
const body = {} const body = {}
for (let app of apps) { for (let app of apps) {
app = app.value
let url = app.url || encodeURI(`${app.name}`) let url = app.url || encodeURI(`${app.name}`)
url = `/${url.replace(URL_REGEX_SLASH, "")}` url = `/${url.replace(URL_REGEX_SLASH, "")}`
body[url] = { body[url] = {