Merge branch 'master' of github.com:Budibase/budibase into views-openapi

This commit is contained in:
mike12345567 2024-10-28 14:19:29 +00:00
commit 6fe4f16845
8 changed files with 446 additions and 48 deletions

View File

@ -1,6 +1,6 @@
{ {
"$schema": "node_modules/lerna/schemas/lerna-schema.json", "$schema": "node_modules/lerna/schemas/lerna-schema.json",
"version": "2.33.2", "version": "2.33.3",
"npmClient": "yarn", "npmClient": "yarn",
"packages": [ "packages": [
"packages/*", "packages/*",

View File

@ -11,11 +11,13 @@ import {
IncludeRelationship, IncludeRelationship,
InternalSearchFilterOperator, InternalSearchFilterOperator,
isManyToOne, isManyToOne,
isOneToMany,
OneToManyRelationshipFieldMetadata, OneToManyRelationshipFieldMetadata,
Operation, Operation,
PaginationJson, PaginationJson,
QueryJson, QueryJson,
RelationshipFieldMetadata, RelationshipFieldMetadata,
RelationshipType,
Row, Row,
SearchFilters, SearchFilters,
SortJson, SortJson,
@ -50,13 +52,15 @@ import sdk from "../../../sdk"
import env from "../../../environment" import env from "../../../environment"
import { makeExternalQuery } from "../../../integrations/base/query" import { makeExternalQuery } from "../../../integrations/base/query"
import { dataFilters, helpers } from "@budibase/shared-core" import { dataFilters, helpers } from "@budibase/shared-core"
import { isRelationshipColumn } from "../../../db/utils"
export interface ManyRelationship { interface ManyRelationship {
tableId?: string tableId?: string
id?: string id?: string
isUpdate?: boolean isUpdate?: boolean
key: string key: string
[key: string]: any [key: string]: any
relationshipType: RelationshipType
} }
export interface RunConfig { export interface RunConfig {
@ -384,6 +388,7 @@ export class ExternalRequest<T extends Operation> {
[otherKey]: breakRowIdField(relationship)[0], [otherKey]: breakRowIdField(relationship)[0],
// leave the ID for enrichment later // leave the ID for enrichment later
[thisKey]: `{{ literal ${tablePrimary} }}`, [thisKey]: `{{ literal ${tablePrimary} }}`,
relationshipType: RelationshipType.MANY_TO_MANY,
}) })
} }
} }
@ -400,6 +405,7 @@ export class ExternalRequest<T extends Operation> {
[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} }}`,
relationshipType: RelationshipType.MANY_TO_ONE,
}) })
} }
} }
@ -420,14 +426,30 @@ export class ExternalRequest<T extends Operation> {
return { row: newRow as T, manyRelationships } return { row: newRow as T, manyRelationships }
} }
private getLookupRelationsKey(relationship: {
relationshipType: RelationshipType
fieldName: string
through?: string
}) {
if (relationship.relationshipType === RelationshipType.MANY_TO_MANY) {
return `${relationship.through}_${relationship.fieldName}`
}
return relationship.fieldName
}
/** /**
* 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 lookupRelations(tableId: string, row: Row) { private async lookupRelations(tableId: string, row: Row) {
const related: { const related: Record<
[key: string]: { rows: Row[]; isMany: boolean; tableId: string } string,
} = {} {
rows: Row[]
isMany: boolean
tableId: string
}
> = {}
const { tableName } = breakExternalTableId(tableId) const { tableName } = breakExternalTableId(tableId)
const table = this.tables[tableName] const table = this.tables[tableName]
// @ts-ignore // @ts-ignore
@ -459,11 +481,8 @@ export class ExternalRequest<T extends Operation> {
"Unable to lookup relationships - undefined column properties." "Unable to lookup relationships - undefined column properties."
) )
} }
const { tableName: relatedTableName } =
breakExternalTableId(relatedTableId) if (!lookupField || !row?.[lookupField]) {
// @ts-ignore
const linkPrimaryKey = this.tables[relatedTableName].primary[0]
if (!lookupField || !row?.[lookupField] == null) {
continue continue
} }
const endpoint = getEndpoint(relatedTableId, Operation.READ) const endpoint = getEndpoint(relatedTableId, Operation.READ)
@ -487,10 +506,8 @@ export class ExternalRequest<T extends Operation> {
!Array.isArray(response) || isKnexEmptyReadResponse(response) !Array.isArray(response) || isKnexEmptyReadResponse(response)
? [] ? []
: response : response
const storeTo = isManyToMany(field)
? field.throughFrom || linkPrimaryKey related[this.getLookupRelationsKey(field)] = {
: fieldName
related[storeTo] = {
rows, rows,
isMany: isManyToMany(field), isMany: isManyToMany(field),
tableId: relatedTableId, tableId: relatedTableId,
@ -518,7 +535,8 @@ export class ExternalRequest<T extends Operation> {
const promises = [] const promises = []
const related = await this.lookupRelations(mainTableId, row) const related = await this.lookupRelations(mainTableId, row)
for (let relationship of relationships) { for (let relationship of relationships) {
const { key, tableId, isUpdate, id, ...rest } = relationship const { key, tableId, isUpdate, id, relationshipType, ...rest } =
relationship
const body: { [key: string]: any } = processObjectSync(rest, row, {}) const body: { [key: string]: any } = processObjectSync(rest, row, {})
const linkTable = this.getTable(tableId) const linkTable = this.getTable(tableId)
const relationshipPrimary = linkTable?.primary || [] const relationshipPrimary = linkTable?.primary || []
@ -529,7 +547,14 @@ export class ExternalRequest<T extends Operation> {
const linkSecondary = relationshipPrimary[1] const linkSecondary = relationshipPrimary[1]
const rows = related[key]?.rows || [] const rows =
related[
this.getLookupRelationsKey({
relationshipType,
fieldName: key,
through: relationship.tableId,
})
]?.rows || []
const relationshipMatchPredicate = ({ const relationshipMatchPredicate = ({
row, row,
@ -574,12 +599,12 @@ export class ExternalRequest<T extends Operation> {
} }
} }
// finally cleanup anything that needs to be removed // finally cleanup anything that needs to be removed
for (let [colName, { isMany, rows, tableId }] of Object.entries(related)) { for (const [field, { isMany, rows, tableId }] of Object.entries(related)) {
const table: Table | undefined = this.getTable(tableId) const table: Table | undefined = this.getTable(tableId)
// if it's not the foreign key skip it, nothing to do // if it's not the foreign key skip it, nothing to do
if ( if (
!table || !table ||
(!isMany && table.primary && table.primary.indexOf(colName) !== -1) (!isMany && table.primary && table.primary.indexOf(field) !== -1)
) { ) {
continue continue
} }
@ -587,7 +612,7 @@ export class ExternalRequest<T extends Operation> {
const rowId = generateIdForRow(row, table) const rowId = generateIdForRow(row, table)
const promise: Promise<any> = isMany const promise: Promise<any> = isMany
? this.removeManyToManyRelationships(rowId, table) ? this.removeManyToManyRelationships(rowId, table)
: this.removeOneToManyRelationships(rowId, table, colName) : this.removeOneToManyRelationships(rowId, table, field)
if (promise) { if (promise) {
promises.push(promise) promises.push(promise)
} }
@ -599,23 +624,24 @@ export class ExternalRequest<T extends Operation> {
async removeRelationshipsToRow(table: Table, rowId: string) { async removeRelationshipsToRow(table: Table, rowId: string) {
const row = await this.getRow(table, rowId) const row = await this.getRow(table, rowId)
const related = await this.lookupRelations(table._id!, row) const related = await this.lookupRelations(table._id!, row)
for (let column of Object.values(table.schema)) { for (const column of Object.values(table.schema)) {
const relationshipColumn = column as RelationshipFieldMetadata if (!isRelationshipColumn(column) || isOneToMany(column)) {
if (!isManyToOne(relationshipColumn)) {
continue continue
} }
const { rows, isMany, tableId } = related[relationshipColumn.fieldName]
const relatedByTable = related[this.getLookupRelationsKey(column)]
if (!relatedByTable) {
continue
}
const { rows, isMany, tableId } = relatedByTable
const table = this.getTable(tableId)! const table = this.getTable(tableId)!
await Promise.all( await Promise.all(
rows.map(row => { rows.map(row => {
const rowId = generateIdForRow(row, table) const rowId = generateIdForRow(row, table)
return isMany return isMany
? this.removeManyToManyRelationships(rowId, table) ? this.removeManyToManyRelationships(rowId, table)
: this.removeOneToManyRelationships( : this.removeOneToManyRelationships(rowId, table, column.fieldName)
rowId,
table,
relationshipColumn.fieldName
)
}) })
) )
} }

View File

@ -9,9 +9,15 @@ import {
TRIGGER_DEFINITIONS, TRIGGER_DEFINITIONS,
BUILTIN_ACTION_DEFINITIONS, BUILTIN_ACTION_DEFINITIONS,
} from "../../../automations" } from "../../../automations"
import { events } from "@budibase/backend-core" import { configs, context, events } from "@budibase/backend-core"
import sdk from "../../../sdk" import sdk from "../../../sdk"
import { Automation, FieldType, Table } from "@budibase/types" import {
Automation,
ConfigType,
FieldType,
SettingsConfig,
Table,
} from "@budibase/types"
import { mocks } from "@budibase/backend-core/tests" import { mocks } from "@budibase/backend-core/tests"
import { FilterConditions } from "../../../automations/steps/filter" import { FilterConditions } from "../../../automations/steps/filter"
import { removeDeprecated } from "../../../automations/utils" import { removeDeprecated } from "../../../automations/utils"
@ -39,8 +45,7 @@ describe("/automations", () => {
}) })
beforeEach(() => { beforeEach(() => {
// @ts-ignore jest.clearAllMocks()
events.automation.deleted.mockClear()
}) })
describe("get definitions", () => { describe("get definitions", () => {
@ -244,6 +249,59 @@ describe("/automations", () => {
}) })
}) })
describe("run", () => {
let oldConfig: SettingsConfig
beforeAll(async () => {
await context.doInTenant(config.getTenantId(), async () => {
oldConfig = await configs.getSettingsConfigDoc()
const settings: SettingsConfig = {
_id: oldConfig._id,
_rev: oldConfig._rev,
type: ConfigType.SETTINGS,
config: {
platformUrl: "https://example.com",
logoUrl: "https://example.com/logo.png",
company: "Test Company",
},
}
const saved = await configs.save(settings)
oldConfig._rev = saved.rev
})
})
afterAll(async () => {
await context.doInTenant(config.getTenantId(), async () => {
await configs.save(oldConfig)
})
})
it("should be able to access platformUrl, logoUrl and company in the automation", async () => {
const result = await createAutomationBuilder({
name: "Test Automation",
appId: config.getAppId(),
config,
})
.appAction({ fields: {} })
.serverLog({
text: "{{ settings.url }}",
})
.serverLog({
text: "{{ settings.logo }}",
})
.serverLog({
text: "{{ settings.company }}",
})
.run()
expect(result.steps[0].outputs.message).toEndWith("https://example.com")
expect(result.steps[1].outputs.message).toEndWith(
"https://example.com/logo.png"
)
expect(result.steps[2].outputs.message).toEndWith("Test Company")
})
})
describe("test", () => { describe("test", () => {
it("tests the automation successfully", async () => { it("tests the automation successfully", async () => {
let table = await config.createTable() let table = await config.createTable()

View File

@ -952,6 +952,105 @@ describe.each([
}) })
}) })
}) })
!isLucene &&
describe("relations to same table", () => {
let relatedRows: Row[]
beforeAll(async () => {
const relatedTable = await config.api.table.save(
defaultTable({
schema: {
name: { name: "name", type: FieldType.STRING },
},
})
)
const relatedTableId = relatedTable._id!
table = await config.api.table.save(
defaultTable({
schema: {
name: { name: "name", type: FieldType.STRING },
related1: {
type: FieldType.LINK,
name: "related1",
fieldName: "main1",
tableId: relatedTableId,
relationshipType: RelationshipType.MANY_TO_MANY,
},
related2: {
type: FieldType.LINK,
name: "related2",
fieldName: "main2",
tableId: relatedTableId,
relationshipType: RelationshipType.MANY_TO_MANY,
},
},
})
)
relatedRows = await Promise.all([
config.api.row.save(relatedTableId, { name: "foo" }),
config.api.row.save(relatedTableId, { name: "bar" }),
config.api.row.save(relatedTableId, { name: "baz" }),
config.api.row.save(relatedTableId, { name: "boo" }),
])
})
it("can create rows with both relationships", async () => {
const row = await config.api.row.save(table._id!, {
name: "test",
related1: [relatedRows[0]._id!],
related2: [relatedRows[1]._id!],
})
expect(row).toEqual(
expect.objectContaining({
name: "test",
related1: [
{
_id: relatedRows[0]._id,
primaryDisplay: relatedRows[0].name,
},
],
related2: [
{
_id: relatedRows[1]._id,
primaryDisplay: relatedRows[1].name,
},
],
})
)
})
it("can create rows with no relationships", async () => {
const row = await config.api.row.save(table._id!, {
name: "test",
})
expect(row.related1).toBeUndefined()
expect(row.related2).toBeUndefined()
})
it("can create rows with only one relationships field", async () => {
const row = await config.api.row.save(table._id!, {
name: "test",
related1: [],
related2: [relatedRows[1]._id!],
})
expect(row).toEqual(
expect.objectContaining({
name: "test",
related2: [
{
_id: relatedRows[1]._id,
primaryDisplay: relatedRows[1].name,
},
],
})
)
expect(row.related1).toBeUndefined()
})
})
}) })
describe("get", () => { describe("get", () => {
@ -1054,6 +1153,134 @@ describe.each([
const rows = await config.api.row.fetch(table._id!) const rows = await config.api.row.fetch(table._id!)
expect(rows).toHaveLength(1) expect(rows).toHaveLength(1)
}) })
!isLucene &&
describe("relations to same table", () => {
let relatedRows: Row[]
beforeAll(async () => {
const relatedTable = await config.api.table.save(
defaultTable({
schema: {
name: { name: "name", type: FieldType.STRING },
},
})
)
const relatedTableId = relatedTable._id!
table = await config.api.table.save(
defaultTable({
schema: {
name: { name: "name", type: FieldType.STRING },
related1: {
type: FieldType.LINK,
name: "related1",
fieldName: "main1",
tableId: relatedTableId,
relationshipType: RelationshipType.MANY_TO_MANY,
},
related2: {
type: FieldType.LINK,
name: "related2",
fieldName: "main2",
tableId: relatedTableId,
relationshipType: RelationshipType.MANY_TO_MANY,
},
},
})
)
relatedRows = await Promise.all([
config.api.row.save(relatedTableId, { name: "foo" }),
config.api.row.save(relatedTableId, { name: "bar" }),
config.api.row.save(relatedTableId, { name: "baz" }),
config.api.row.save(relatedTableId, { name: "boo" }),
])
})
it("can edit rows with both relationships", async () => {
let row = await config.api.row.save(table._id!, {
name: "test",
related1: [relatedRows[0]._id!],
related2: [relatedRows[1]._id!],
})
row = await config.api.row.save(table._id!, {
...row,
related1: [relatedRows[0]._id!, relatedRows[1]._id!],
related2: [relatedRows[2]._id!],
})
expect(row).toEqual(
expect.objectContaining({
name: "test",
related1: expect.arrayContaining([
{
_id: relatedRows[0]._id,
primaryDisplay: relatedRows[0].name,
},
{
_id: relatedRows[1]._id,
primaryDisplay: relatedRows[1].name,
},
]),
related2: [
{
_id: relatedRows[2]._id,
primaryDisplay: relatedRows[2].name,
},
],
})
)
})
it("can drop existing relationship", async () => {
let row = await config.api.row.save(table._id!, {
name: "test",
related1: [relatedRows[0]._id!],
related2: [relatedRows[1]._id!],
})
row = await config.api.row.save(table._id!, {
...row,
related1: [],
related2: [relatedRows[2]._id!],
})
expect(row).toEqual(
expect.objectContaining({
name: "test",
related2: [
{
_id: relatedRows[2]._id,
primaryDisplay: relatedRows[2].name,
},
],
})
)
expect(row.related1).toBeUndefined()
})
it("can drop both relationships", async () => {
let row = await config.api.row.save(table._id!, {
name: "test",
related1: [relatedRows[0]._id!],
related2: [relatedRows[1]._id!],
})
row = await config.api.row.save(table._id!, {
...row,
related1: [],
related2: [],
})
expect(row).toEqual(
expect.objectContaining({
name: "test",
})
)
expect(row.related1).toBeUndefined()
expect(row.related2).toBeUndefined()
})
})
}) })
describe("patch", () => { describe("patch", () => {
@ -1330,6 +1557,73 @@ describe.each([
) )
expect(res.length).toEqual(2) expect(res.length).toEqual(2)
}) })
!isLucene &&
describe("relations to same table", () => {
let relatedRows: Row[]
beforeAll(async () => {
const relatedTable = await config.api.table.save(
defaultTable({
schema: {
name: { name: "name", type: FieldType.STRING },
},
})
)
const relatedTableId = relatedTable._id!
table = await config.api.table.save(
defaultTable({
schema: {
name: { name: "name", type: FieldType.STRING },
related1: {
type: FieldType.LINK,
name: "related1",
fieldName: "main1",
tableId: relatedTableId,
relationshipType: RelationshipType.MANY_TO_MANY,
},
related2: {
type: FieldType.LINK,
name: "related2",
fieldName: "main2",
tableId: relatedTableId,
relationshipType: RelationshipType.MANY_TO_MANY,
},
},
})
)
relatedRows = await Promise.all([
config.api.row.save(relatedTableId, { name: "foo" }),
config.api.row.save(relatedTableId, { name: "bar" }),
config.api.row.save(relatedTableId, { name: "baz" }),
config.api.row.save(relatedTableId, { name: "boo" }),
])
})
it("can delete rows with both relationships", async () => {
const row = await config.api.row.save(table._id!, {
name: "test",
related1: [relatedRows[0]._id!],
related2: [relatedRows[1]._id!],
})
await config.api.row.delete(table._id!, { _id: row._id! })
await config.api.row.get(table._id!, row._id!, { status: 404 })
})
it("can delete rows with empty relationships", async () => {
const row = await config.api.row.save(table._id!, {
name: "test",
related1: [],
related2: [],
})
await config.api.row.delete(table._id!, { _id: row._id! })
await config.api.row.get(table._id!, row._id!, { status: 404 })
})
})
}) })
describe("validate", () => { describe("validate", () => {
@ -2796,7 +3090,7 @@ describe.each([
}, },
], ],
["from original saved row", (row: Row) => row], ["from original saved row", (row: Row) => row],
["from updated row", (row: Row) => config.api.row.save(viewId, row)], ["from updated row", (row: Row) => config.api.row.save(viewId, row)],
] ]
it.each(testScenarios)( it.each(testScenarios)(

View File

@ -225,7 +225,9 @@ class AutomationBuilder extends BaseStepBuilder {
private triggerOutputs: any private triggerOutputs: any
private triggerSet: boolean = false private triggerSet: boolean = false
constructor(options: { name?: string; appId?: string } = {}) { constructor(
options: { name?: string; appId?: string; config?: TestConfiguration } = {}
) {
super() super()
this.automationConfig = { this.automationConfig = {
name: options.name || `Test Automation ${uuidv4()}`, name: options.name || `Test Automation ${uuidv4()}`,
@ -237,7 +239,7 @@ class AutomationBuilder extends BaseStepBuilder {
type: "automation", type: "automation",
appId: options.appId ?? setup.getConfig().getAppId(), appId: options.appId ?? setup.getConfig().getAppId(),
} }
this.config = setup.getConfig() this.config = options.config || setup.getConfig()
} }
// TRIGGERS // TRIGGERS
@ -347,6 +349,7 @@ class AutomationBuilder extends BaseStepBuilder {
export function createAutomationBuilder(options?: { export function createAutomationBuilder(options?: {
name?: string name?: string
appId?: string appId?: string
config?: TestConfiguration
}) { }) {
return new AutomationBuilder(options) return new AutomationBuilder(options)
} }

View File

@ -20,4 +20,9 @@ export interface AutomationContext extends AutomationResults {
env?: Record<string, string> env?: Record<string, string>
user?: UserBindings user?: UserBindings
trigger: any trigger: any
settings?: {
url?: string
logo?: string
company?: string
}
} }

View File

@ -30,7 +30,7 @@ import {
} from "@budibase/types" } from "@budibase/types"
import { AutomationContext, TriggerOutput } from "../definitions/automations" import { AutomationContext, TriggerOutput } from "../definitions/automations"
import { WorkerCallback } from "./definitions" import { WorkerCallback } from "./definitions"
import { context, logging } from "@budibase/backend-core" import { context, logging, configs } from "@budibase/backend-core"
import { processObject, processStringSync } from "@budibase/string-templates" import { processObject, processStringSync } from "@budibase/string-templates"
import { cloneDeep } from "lodash/fp" import { cloneDeep } from "lodash/fp"
import { performance } from "perf_hooks" import { performance } from "perf_hooks"
@ -263,6 +263,18 @@ class Orchestrator {
this.context.env = await sdkUtils.getEnvironmentVariables() this.context.env = await sdkUtils.getEnvironmentVariables()
this.context.user = this.currentUser this.context.user = this.currentUser
try {
const { config } = await configs.getSettingsConfigDoc()
this.context.settings = {
url: config.platformUrl,
logo: config.logoUrl,
company: config.company,
}
} catch (e) {
// if settings doc doesn't exist, make the settings blank
this.context.settings = {}
}
let metadata let metadata
// check if this is a recurring automation, // check if this is a recurring automation,

View File

@ -2051,7 +2051,7 @@
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
"@budibase/backend-core@2.32.11": "@budibase/backend-core@2.33.2":
version "0.0.0" version "0.0.0"
dependencies: dependencies:
"@budibase/nano" "10.1.5" "@budibase/nano" "10.1.5"
@ -2132,15 +2132,15 @@
through2 "^2.0.0" through2 "^2.0.0"
"@budibase/pro@npm:@budibase/pro@latest": "@budibase/pro@npm:@budibase/pro@latest":
version "2.32.11" version "2.33.2"
resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.32.11.tgz#c94d534f829ca0ef252677757e157a7e58b87b4d" resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.33.2.tgz#5c2012f7b2bf0fd871cda1ad37ad7a0442c84658"
integrity sha512-mOkqJpqHKWsfTWZwWcvBCYFUIluSUHltQNinc1ZRsg9rC3OKoHSDop6gzm744++H/GzGRN8V86kLhCgtNIlkpA== integrity sha512-lBB6Wfp6OIOHRlGq82WS9KxvEXRs/P2QlwJT0Aj9PhmkQFsnXm2r8d18f0xTGvcflD+iR7XGP/k56JlCanmhQg==
dependencies: dependencies:
"@anthropic-ai/sdk" "^0.27.3" "@anthropic-ai/sdk" "^0.27.3"
"@budibase/backend-core" "2.32.11" "@budibase/backend-core" "2.33.2"
"@budibase/shared-core" "2.32.11" "@budibase/shared-core" "2.33.2"
"@budibase/string-templates" "2.32.11" "@budibase/string-templates" "2.33.2"
"@budibase/types" "2.32.11" "@budibase/types" "2.33.2"
"@koa/router" "8.0.8" "@koa/router" "8.0.8"
bull "4.10.1" bull "4.10.1"
dd-trace "5.2.0" dd-trace "5.2.0"
@ -2153,13 +2153,13 @@
scim-patch "^0.8.1" scim-patch "^0.8.1"
scim2-parse-filter "^0.2.8" scim2-parse-filter "^0.2.8"
"@budibase/shared-core@2.32.11": "@budibase/shared-core@2.33.2":
version "0.0.0" version "0.0.0"
dependencies: dependencies:
"@budibase/types" "0.0.0" "@budibase/types" "0.0.0"
cron-validate "1.4.5" cron-validate "1.4.5"
"@budibase/string-templates@2.32.11": "@budibase/string-templates@2.33.2":
version "0.0.0" version "0.0.0"
dependencies: dependencies:
"@budibase/handlebars-helpers" "^0.13.2" "@budibase/handlebars-helpers" "^0.13.2"
@ -2167,7 +2167,7 @@
handlebars "^4.7.8" handlebars "^4.7.8"
lodash.clonedeep "^4.5.0" lodash.clonedeep "^4.5.0"
"@budibase/types@2.32.11": "@budibase/types@2.33.2":
version "0.0.0" version "0.0.0"
dependencies: dependencies:
scim-patch "^0.8.1" scim-patch "^0.8.1"