From de3968ffe3dadb17629f6b44e265324930508220 Mon Sep 17 00:00:00 2001 From: Michael Drury Date: Thu, 29 Feb 2024 12:32:15 +0000 Subject: [PATCH] Revert "SQL Query aliasing" --- .../scripts/integrations/postgres/reset.sh | 2 +- .../api/controllers/row/ExternalRequest.ts | 160 ++------ .../server/src/api/controllers/row/alias.ts | 166 -------- packages/server/src/environment.ts | 5 +- .../server/src/integrations/base/query.ts | 8 +- packages/server/src/integrations/base/sql.ts | 155 +++---- .../server/src/integrations/googlesheets.ts | 7 +- .../src/integrations/microsoftSqlServer.ts | 4 +- packages/server/src/integrations/mysql.ts | 4 +- packages/server/src/integrations/oracle.ts | 9 +- packages/server/src/integrations/postgres.ts | 7 +- .../server/src/integrations/tests/sql.spec.ts | 15 +- .../src/integrations/tests/sqlAlias.spec.ts | 204 ---------- .../basicFetchWithRelationships.json | 183 --------- .../sqlQueryJson/createWithRelationships.json | 173 -------- .../tests/sqlQueryJson/deleteSimple.json | 75 ---- .../sqlQueryJson/enrichRelationship.json | 123 ------ .../tests/sqlQueryJson/fetchManyToMany.json | 109 ----- .../sqlQueryJson/filterByRelationship.json | 94 ----- .../sqlQueryJson/manyRelationshipFilters.json | 202 --------- .../sqlQueryJson/updateRelationship.json | 181 --------- .../tests/sqlQueryJson/updateSimple.json | 181 --------- .../server/src/sdk/app/datasources/plus.ts | 36 +- packages/server/src/sdk/app/rows/utils.ts | 13 +- packages/types/src/sdk/datasources.ts | 16 +- packages/types/src/sdk/search.ts | 1 - yarn.lock | 384 ++++++++---------- 27 files changed, 284 insertions(+), 2233 deletions(-) delete mode 100644 packages/server/src/api/controllers/row/alias.ts delete mode 100644 packages/server/src/integrations/tests/sqlAlias.spec.ts delete mode 100644 packages/server/src/integrations/tests/sqlQueryJson/basicFetchWithRelationships.json delete mode 100644 packages/server/src/integrations/tests/sqlQueryJson/createWithRelationships.json delete mode 100644 packages/server/src/integrations/tests/sqlQueryJson/deleteSimple.json delete mode 100644 packages/server/src/integrations/tests/sqlQueryJson/enrichRelationship.json delete mode 100644 packages/server/src/integrations/tests/sqlQueryJson/fetchManyToMany.json delete mode 100644 packages/server/src/integrations/tests/sqlQueryJson/filterByRelationship.json delete mode 100644 packages/server/src/integrations/tests/sqlQueryJson/manyRelationshipFilters.json delete mode 100644 packages/server/src/integrations/tests/sqlQueryJson/updateRelationship.json delete mode 100644 packages/server/src/integrations/tests/sqlQueryJson/updateSimple.json diff --git a/packages/server/scripts/integrations/postgres/reset.sh b/packages/server/scripts/integrations/postgres/reset.sh index 8deb01cdf8..32778bd11f 100755 --- a/packages/server/scripts/integrations/postgres/reset.sh +++ b/packages/server/scripts/integrations/postgres/reset.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker-compose down -v +docker-compose down docker volume prune -f diff --git a/packages/server/src/api/controllers/row/ExternalRequest.ts b/packages/server/src/api/controllers/row/ExternalRequest.ts index 685af4e98e..b7dc02c0db 100644 --- a/packages/server/src/api/controllers/row/ExternalRequest.ts +++ b/packages/server/src/api/controllers/row/ExternalRequest.ts @@ -7,7 +7,6 @@ import { FilterType, IncludeRelationship, ManyToManyRelationshipFieldMetadata, - ManyToOneRelationshipFieldMetadata, OneToManyRelationshipFieldMetadata, Operation, PaginationJson, @@ -19,7 +18,6 @@ import { SortJson, SortType, Table, - isManyToOne, } from "@budibase/types" import { breakExternalTableId, @@ -34,9 +32,7 @@ import { processObjectSync } from "@budibase/string-templates" import { cloneDeep } from "lodash/fp" import { processDates, processFormulas } from "../../../utilities/rowProcessor" import { db as dbCore } from "@budibase/backend-core" -import AliasTables from "./alias" import sdk from "../../../sdk" -import env from "../../../environment" export interface ManyRelationship { tableId?: string @@ -105,39 +101,6 @@ function buildFilters( } } -async function removeManyToManyRelationships( - rowId: string, - table: Table, - colName: string -) { - const tableId = table._id! - const filters = buildFilters(rowId, {}, table) - // safety check, if there are no filters on deletion bad things happen - if (Object.keys(filters).length !== 0) { - return getDatasourceAndQuery({ - endpoint: getEndpoint(tableId, Operation.DELETE), - body: { [colName]: null }, - filters, - }) - } else { - return [] - } -} - -async function removeOneToManyRelationships(rowId: string, table: Table) { - const tableId = table._id! - const filters = buildFilters(rowId, {}, table) - // safety check, if there are no filters on deletion bad things happen - if (Object.keys(filters).length !== 0) { - return getDatasourceAndQuery({ - endpoint: getEndpoint(tableId, Operation.UPDATE), - filters, - }) - } else { - return [] - } -} - /** * This function checks the incoming parameters to make sure all the inputs are * valid based on on the table schema. The main thing this is looking for is when a @@ -215,13 +178,13 @@ function generateIdForRow( function getEndpoint(tableId: string | undefined, operation: string) { if (!tableId) { - throw new Error("Cannot get endpoint information - no table ID specified") + return {} } const { datasourceId, tableName } = breakExternalTableId(tableId) return { - datasourceId: datasourceId!, - entityId: tableName!, - operation: operation as Operation, + datasourceId, + entityId: tableName, + operation, } } @@ -341,18 +304,6 @@ export class ExternalRequest { } } - async getRow(table: Table, rowId: string): Promise { - const response = await getDatasourceAndQuery({ - endpoint: getEndpoint(table._id!, Operation.READ), - filters: buildFilters(rowId, {}, table), - }) - if (Array.isArray(response) && response.length > 0) { - return response[0] - } else { - throw new Error(`Cannot fetch row by ID "${rowId}"`) - } - } - inputProcessing(row: Row | undefined, table: Table) { if (!row) { return { row, manyRelationships: [] } @@ -620,9 +571,7 @@ export class ExternalRequest { * information. */ async lookupRelations(tableId: string, row: Row) { - const related: { - [key: string]: { rows: Row[]; isMany: boolean; tableId: string } - } = {} + const related: { [key: string]: any } = {} const { tableName } = breakExternalTableId(tableId) if (!tableName) { return related @@ -640,26 +589,14 @@ export class ExternalRequest { ) { continue } - let tableId: string | undefined, - lookupField: string | undefined, - fieldName: string | undefined - if (isManyToMany(field)) { - tableId = field.through - lookupField = primaryKey - fieldName = field.throughTo || primaryKey - } else if (isManyToOne(field)) { - tableId = field.tableId - lookupField = field.foreignKey - fieldName = field.fieldName - } - if (!tableId || !lookupField || !fieldName) { - throw new Error( - "Unable to lookup relationships - undefined column properties." - ) - } + const isMany = field.relationshipType === RelationshipType.MANY_TO_MANY + const tableId = isMany ? field.through : field.tableId const { tableName: relatedTableName } = breakExternalTableId(tableId) // @ts-ignore const linkPrimaryKey = this.tables[relatedTableName].primary[0] + + const lookupField = isMany ? primaryKey : field.foreignKey + const fieldName = isMany ? field.throughTo || primaryKey : field.fieldName if (!lookupField || !row[lookupField]) { continue } @@ -672,12 +609,9 @@ export class ExternalRequest { }, }) // this is the response from knex if no rows found - const rows: Row[] = - !Array.isArray(response) || response?.[0].read ? [] : response - const storeTo = isManyToMany(field) - ? field.throughFrom || linkPrimaryKey - : fieldName - related[storeTo] = { rows, isMany: isManyToMany(field), tableId } + const rows = !response[0].read ? response : [] + const storeTo = isMany ? field.throughFrom || linkPrimaryKey : fieldName + related[storeTo] = { rows, isMany, tableId } } return related } @@ -763,43 +697,24 @@ export class ExternalRequest { continue } for (let row of rows) { - const rowId = generateIdForRow(row, table) - const promise: Promise = isMany - ? removeManyToManyRelationships(rowId, table, colName) - : removeOneToManyRelationships(rowId, table) - if (promise) { - promises.push(promise) + const filters = buildFilters(generateIdForRow(row, table), {}, table) + // safety check, if there are no filters on deletion bad things happen + if (Object.keys(filters).length !== 0) { + const op = isMany ? Operation.DELETE : Operation.UPDATE + const body = isMany ? null : { [colName]: null } + promises.push( + getDatasourceAndQuery({ + endpoint: getEndpoint(tableId, op), + body, + filters, + }) + ) } } } await Promise.all(promises) } - async removeRelationshipsToRow(table: Table, rowId: string) { - const row = await this.getRow(table, rowId) - const related = await this.lookupRelations(table._id!, row) - for (let column of Object.values(table.schema)) { - const relationshipColumn = column as RelationshipFieldMetadata - if (!isManyToOne(relationshipColumn)) { - continue - } - const { rows, isMany, tableId } = related[relationshipColumn.fieldName] - const table = this.getTable(tableId)! - await Promise.all( - rows.map(row => { - const rowId = generateIdForRow(row, table) - return isMany - ? removeManyToManyRelationships( - rowId, - table, - relationshipColumn.fieldName - ) - : removeOneToManyRelationships(rowId, table) - }) - ) - } - } - /** * This function is a bit crazy, but the exact purpose of it is to protect against the scenario in which * you have column overlap in relationships, e.g. we join a few different tables and they all have the @@ -889,7 +804,7 @@ export class ExternalRequest { } let json = { endpoint: { - datasourceId: datasourceId!, + datasourceId, entityId: tableName, operation, }, @@ -911,30 +826,17 @@ export class ExternalRequest { }, } - // remove any relationships that could block deletion - if (operation === Operation.DELETE && id) { - await this.removeRelationshipsToRow(table, generateRowIdField(id)) - } - - // aliasing can be disabled fully if desired - let response - if (env.SQL_ALIASING_DISABLE) { - response = await getDatasourceAndQuery(json) - } else { - const aliasing = new AliasTables(Object.keys(this.tables)) - response = await aliasing.queryWithAliasing(json) - } - - const responseRows = Array.isArray(response) ? response : [] - // handle many-to-many relationships now if we know the ID (could be auto increment) + // can't really use response right now + const response = await getDatasourceAndQuery(json) + // handle many to many relationships now if we know the ID (could be auto increment) if (operation !== Operation.READ) { await this.handleManyRelationships( table._id || "", - responseRows[0], + response[0], processed.manyRelationships ) } - const output = this.outputProcessing(responseRows, table, relationships) + const output = this.outputProcessing(response, table, relationships) // if reading it'll just be an array of rows, return whole thing if (operation === Operation.READ) { return ( diff --git a/packages/server/src/api/controllers/row/alias.ts b/packages/server/src/api/controllers/row/alias.ts deleted file mode 100644 index 9658a0d638..0000000000 --- a/packages/server/src/api/controllers/row/alias.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { - QueryJson, - SearchFilters, - Table, - Row, - DatasourcePlusQueryResponse, -} from "@budibase/types" -import { getDatasourceAndQuery } from "../../../sdk/app/rows/utils" -import { cloneDeep } from "lodash" - -class CharSequence { - static alphabet = "abcdefghijklmnopqrstuvwxyz" - counters: number[] - - constructor() { - this.counters = [0] - } - - getCharacter(): string { - const char = this.counters.map(i => CharSequence.alphabet[i]).join("") - for (let i = this.counters.length - 1; i >= 0; i--) { - if (this.counters[i] < CharSequence.alphabet.length - 1) { - this.counters[i]++ - return char - } - this.counters[i] = 0 - } - this.counters.unshift(0) - return char - } -} - -export default class AliasTables { - aliases: Record - tableAliases: Record - tableNames: string[] - charSeq: CharSequence - - constructor(tableNames: string[]) { - this.tableNames = tableNames - this.aliases = {} - this.tableAliases = {} - this.charSeq = new CharSequence() - } - - getAlias(tableName: string) { - if (this.aliases[tableName]) { - return this.aliases[tableName] - } - const char = this.charSeq.getCharacter() - this.aliases[tableName] = char - this.tableAliases[char] = tableName - return char - } - - aliasField(field: string) { - const tableNames = this.tableNames - if (field.includes(".")) { - const [tableName, column] = field.split(".") - const foundTableName = tableNames.find(name => { - const idx = tableName.indexOf(name) - if (idx === -1 || idx > 1) { - return - } - return Math.abs(tableName.length - name.length) <= 2 - }) - if (foundTableName) { - const aliasedTableName = tableName.replace( - foundTableName, - this.getAlias(foundTableName) - ) - field = `${aliasedTableName}.${column}` - } - } - return field - } - - reverse(rows: T): T { - const process = (row: Row) => { - const final: Row = {} - for (let [key, value] of Object.entries(row)) { - if (!key.includes(".")) { - final[key] = value - } else { - const [alias, column] = key.split(".") - const tableName = this.tableAliases[alias] || alias - final[`${tableName}.${column}`] = value - } - } - return final - } - if (Array.isArray(rows)) { - return rows.map(row => process(row)) as T - } else { - return process(rows) as T - } - } - - aliasMap(tableNames: (string | undefined)[]) { - const map: Record = {} - for (let tableName of tableNames) { - if (tableName) { - map[tableName] = this.getAlias(tableName) - } - } - return map - } - - async queryWithAliasing(json: QueryJson): DatasourcePlusQueryResponse { - json = cloneDeep(json) - const aliasTable = (table: Table) => ({ - ...table, - name: this.getAlias(table.name), - }) - // run through the query json to update anywhere a table may be used - if (json.resource?.fields) { - json.resource.fields = json.resource.fields.map(field => - this.aliasField(field) - ) - } - if (json.filters) { - for (let [filterKey, filter] of Object.entries(json.filters)) { - if (typeof filter !== "object") { - continue - } - const aliasedFilters: typeof filter = {} - for (let key of Object.keys(filter)) { - aliasedFilters[this.aliasField(key)] = filter[key] - } - json.filters[filterKey as keyof SearchFilters] = aliasedFilters - } - } - if (json.relationships) { - json.relationships = json.relationships.map(relationship => ({ - ...relationship, - aliases: this.aliasMap([ - relationship.through, - relationship.tableName, - json.endpoint.entityId, - ]), - })) - } - if (json.meta?.table) { - json.meta.table = aliasTable(json.meta.table) - } - if (json.meta?.tables) { - const aliasedTables: Record = {} - for (let [tableName, table] of Object.entries(json.meta.tables)) { - aliasedTables[this.getAlias(tableName)] = aliasTable(table) - } - json.meta.tables = aliasedTables - } - // invert and return - const invertedTableAliases: Record = {} - for (let [key, value] of Object.entries(this.tableAliases)) { - invertedTableAliases[value] = key - } - json.tableAliases = invertedTableAliases - const response = await getDatasourceAndQuery(json) - if (Array.isArray(response)) { - return this.reverse(response) - } else { - return response - } - } -} diff --git a/packages/server/src/environment.ts b/packages/server/src/environment.ts index a7c6df29ea..d0b7e91401 100644 --- a/packages/server/src/environment.ts +++ b/packages/server/src/environment.ts @@ -76,16 +76,13 @@ const environment = { DEFAULTS.AUTOMATION_THREAD_TIMEOUT > QUERY_THREAD_TIMEOUT ? DEFAULTS.AUTOMATION_THREAD_TIMEOUT : QUERY_THREAD_TIMEOUT, + SQL_MAX_ROWS: process.env.SQL_MAX_ROWS, BB_ADMIN_USER_EMAIL: process.env.BB_ADMIN_USER_EMAIL, BB_ADMIN_USER_PASSWORD: process.env.BB_ADMIN_USER_PASSWORD, PLUGINS_DIR: process.env.PLUGINS_DIR || DEFAULTS.PLUGINS_DIR, OPENAI_API_KEY: process.env.OPENAI_API_KEY, MAX_IMPORT_SIZE_MB: process.env.MAX_IMPORT_SIZE_MB, SESSION_EXPIRY_SECONDS: process.env.SESSION_EXPIRY_SECONDS, - // SQL - SQL_MAX_ROWS: process.env.SQL_MAX_ROWS, - SQL_LOGGING_ENABLE: process.env.SQL_LOGGING_ENABLE, - SQL_ALIASING_DISABLE: process.env.SQL_ALIASING_DISABLE, // flags ALLOW_DEV_AUTOMATIONS: process.env.ALLOW_DEV_AUTOMATIONS, DISABLE_THREADING: process.env.DISABLE_THREADING, diff --git a/packages/server/src/integrations/base/query.ts b/packages/server/src/integrations/base/query.ts index b906ecbb1b..4f31e37744 100644 --- a/packages/server/src/integrations/base/query.ts +++ b/packages/server/src/integrations/base/query.ts @@ -1,15 +1,11 @@ -import { - QueryJson, - Datasource, - DatasourcePlusQueryResponse, -} from "@budibase/types" +import { QueryJson, Datasource } from "@budibase/types" import { getIntegration } from "../index" import sdk from "../../sdk" export async function makeExternalQuery( datasource: Datasource, json: QueryJson -): DatasourcePlusQueryResponse { +) { datasource = await sdk.datasources.enrich(datasource) const Integration = await getIntegration(datasource.source) // query is the opinionated function diff --git a/packages/server/src/integrations/base/sql.ts b/packages/server/src/integrations/base/sql.ts index 6605052598..e52e9dd2ae 100644 --- a/packages/server/src/integrations/base/sql.ts +++ b/packages/server/src/integrations/base/sql.ts @@ -17,6 +17,7 @@ const envLimit = environment.SQL_MAX_ROWS : null const BASE_LIMIT = envLimit || 5000 +type KnexQuery = Knex.QueryBuilder | Knex // these are invalid dates sent by the client, need to convert them to a real max date const MIN_ISO_DATE = "0000-00-00T00:00:00.000Z" const MAX_ISO_DATE = "9999-00-00T00:00:00.000Z" @@ -126,15 +127,10 @@ class InternalBuilder { // right now we only do filters on the specific table being queried addFilters( - query: Knex.QueryBuilder, + query: KnexQuery, filters: SearchFilters | undefined, - tableName: string, - opts: { aliases?: Record; relationship?: boolean } - ): Knex.QueryBuilder { - function getTableName(name: string) { - const alias = opts.aliases?.[name] - return alias || name - } + opts: { relationship?: boolean; tableName?: string } + ): KnexQuery { function iterate( structure: { [key: string]: any }, fn: (key: string, value: any) => void @@ -143,11 +139,10 @@ class InternalBuilder { const updatedKey = dbCore.removeKeyNumbering(key) const isRelationshipField = updatedKey.includes(".") if (!opts.relationship && !isRelationshipField) { - fn(`${getTableName(tableName)}.${updatedKey}`, value) + fn(`${opts.tableName}.${updatedKey}`, value) } if (opts.relationship && isRelationshipField) { - const [filterTableName, property] = updatedKey.split(".") - fn(`${getTableName(filterTableName)}.${property}`, value) + fn(updatedKey, value) } } } @@ -319,7 +314,7 @@ class InternalBuilder { return query } - addSorting(query: Knex.QueryBuilder, json: QueryJson): Knex.QueryBuilder { + addSorting(query: KnexQuery, json: QueryJson): KnexQuery { let { sort, paginate } = json const table = json.meta?.table if (sort && Object.keys(sort || {}).length > 0) { @@ -335,28 +330,16 @@ class InternalBuilder { return query } - tableNameWithSchema( - tableName: string, - opts?: { alias?: string; schema?: string } - ) { - let withSchema = opts?.schema ? `${opts.schema}.${tableName}` : tableName - if (opts?.alias) { - withSchema += ` as ${opts.alias}` - } - return withSchema - } - addRelationships( - query: Knex.QueryBuilder, + query: KnexQuery, fromTable: string, relationships: RelationshipsJson[] | undefined, - schema: string | undefined, - aliases?: Record - ): Knex.QueryBuilder { + schema: string | undefined + ): KnexQuery { if (!relationships) { return query } - const tableSets: Record = {} + const tableSets: Record = {} // aggregate into table sets (all the same to tables) for (let relationship of relationships) { const keyObj: { toTable: string; throughTable: string | undefined } = { @@ -375,17 +358,10 @@ class InternalBuilder { } for (let [key, relationships] of Object.entries(tableSets)) { const { toTable, throughTable } = JSON.parse(key) - const toAlias = aliases?.[toTable] || toTable, - throughAlias = aliases?.[throughTable] || throughTable, - fromAlias = aliases?.[fromTable] || fromTable - let toTableWithSchema = this.tableNameWithSchema(toTable, { - alias: toAlias, - schema, - }) - let throughTableWithSchema = this.tableNameWithSchema(throughTable, { - alias: throughAlias, - schema, - }) + const toTableWithSchema = schema ? `${schema}.${toTable}` : toTable + const throughTableWithSchema = schema + ? `${schema}.${throughTable}` + : throughTable if (!throughTable) { // @ts-ignore query = query.leftJoin(toTableWithSchema, function () { @@ -393,7 +369,7 @@ class InternalBuilder { const from = relationship.from, to = relationship.to // @ts-ignore - this.orOn(`${fromAlias}.${from}`, "=", `${toAlias}.${to}`) + this.orOn(`${fromTable}.${from}`, "=", `${toTable}.${to}`) } }) } else { @@ -405,9 +381,9 @@ class InternalBuilder { const from = relationship.from // @ts-ignore this.orOn( - `${fromAlias}.${fromPrimary}`, + `${fromTable}.${fromPrimary}`, "=", - `${throughAlias}.${from}` + `${throughTable}.${from}` ) } }) @@ -416,7 +392,7 @@ class InternalBuilder { const toPrimary = relationship.toPrimary const to = relationship.to // @ts-ignore - this.orOn(`${toAlias}.${toPrimary}`, `${throughAlias}.${to}`) + this.orOn(`${toTable}.${toPrimary}`, `${throughTable}.${to}`) } }) } @@ -424,25 +400,12 @@ class InternalBuilder { return query.limit(BASE_LIMIT) } - knexWithAlias( - knex: Knex, - endpoint: QueryJson["endpoint"], - aliases?: QueryJson["tableAliases"] - ): Knex.QueryBuilder { - const tableName = endpoint.entityId - const tableAliased = aliases?.[tableName] - ? `${tableName} as ${aliases?.[tableName]}` - : tableName - let query = knex(tableAliased) + create(knex: Knex, json: QueryJson, opts: QueryOptions): Knex.QueryBuilder { + const { endpoint, body } = json + let query: KnexQuery = knex(endpoint.entityId) if (endpoint.schema) { query = query.withSchema(endpoint.schema) } - return query - } - - create(knex: Knex, json: QueryJson, opts: QueryOptions): Knex.QueryBuilder { - const { endpoint, body } = json - let query = this.knexWithAlias(knex, endpoint) const parsedBody = parseBody(body) // make sure no null values in body for creation for (let [key, value] of Object.entries(parsedBody)) { @@ -461,7 +424,10 @@ class InternalBuilder { bulkCreate(knex: Knex, json: QueryJson): Knex.QueryBuilder { const { endpoint, body } = json - let query = this.knexWithAlias(knex, endpoint) + let query: KnexQuery = knex(endpoint.entityId) + if (endpoint.schema) { + query = query.withSchema(endpoint.schema) + } if (!Array.isArray(body)) { return query } @@ -469,10 +435,8 @@ class InternalBuilder { return query.insert(parsedBody) } - read(knex: Knex, json: QueryJson, limit: number): Knex.QueryBuilder { - let { endpoint, resource, filters, paginate, relationships, tableAliases } = - json - + read(knex: Knex, json: QueryJson, limit: number): KnexQuery { + let { endpoint, resource, filters, paginate, relationships } = json const tableName = endpoint.entityId // select all if not specified if (!resource) { @@ -498,20 +462,21 @@ class InternalBuilder { foundLimit = paginate.limit } // start building the query - let query = this.knexWithAlias(knex, endpoint, tableAliases) - query = query.limit(foundLimit) + let query: KnexQuery = knex(tableName).limit(foundLimit) + if (endpoint.schema) { + query = query.withSchema(endpoint.schema) + } if (foundOffset) { query = query.offset(foundOffset) } - query = this.addFilters(query, filters, tableName, { - aliases: tableAliases, - }) + query = this.addFilters(query, filters, { tableName }) // add sorting to pre-query query = this.addSorting(query, json) - const alias = tableAliases?.[tableName] || tableName - let preQuery = knex({ - [alias]: query, - } as any).select(selectStatement) as any + // @ts-ignore + let preQuery: KnexQuery = knex({ + // @ts-ignore + [tableName]: query, + }).select(selectStatement) // have to add after as well (this breaks MS-SQL) if (this.client !== SqlClient.MS_SQL) { preQuery = this.addSorting(preQuery, json) @@ -521,22 +486,19 @@ class InternalBuilder { preQuery, tableName, relationships, - endpoint.schema, - tableAliases + endpoint.schema ) - return this.addFilters(query, filters, tableName, { - relationship: true, - aliases: tableAliases, - }) + return this.addFilters(query, filters, { relationship: true }) } update(knex: Knex, json: QueryJson, opts: QueryOptions): Knex.QueryBuilder { - const { endpoint, body, filters, tableAliases } = json - let query = this.knexWithAlias(knex, endpoint, tableAliases) + const { endpoint, body, filters } = json + let query: KnexQuery = knex(endpoint.entityId) + if (endpoint.schema) { + query = query.withSchema(endpoint.schema) + } const parsedBody = parseBody(body) - query = this.addFilters(query, filters, endpoint.entityId, { - aliases: tableAliases, - }) + query = this.addFilters(query, filters, { tableName: endpoint.entityId }) // mysql can't use returning if (opts.disableReturning) { return query.update(parsedBody) @@ -546,11 +508,12 @@ class InternalBuilder { } delete(knex: Knex, json: QueryJson, opts: QueryOptions): Knex.QueryBuilder { - const { endpoint, filters, tableAliases } = json - let query = this.knexWithAlias(knex, endpoint, tableAliases) - query = this.addFilters(query, filters, endpoint.entityId, { - aliases: tableAliases, - }) + const { endpoint, filters } = json + let query: KnexQuery = knex(endpoint.entityId) + if (endpoint.schema) { + query = query.withSchema(endpoint.schema) + } + query = this.addFilters(query, filters, { tableName: endpoint.entityId }) // mysql can't use returning if (opts.disableReturning) { return query.delete() @@ -584,7 +547,7 @@ class SqlQueryBuilder extends SqlTableQueryBuilder { query = builder.create(client, json, opts) break case Operation.READ: - query = builder.read(client, json, this.limit) + query = builder.read(client, json, this.limit) as Knex.QueryBuilder break case Operation.UPDATE: query = builder.update(client, json, opts) @@ -683,18 +646,6 @@ class SqlQueryBuilder extends SqlTableQueryBuilder { } return results.length ? results : [{ [operation.toLowerCase()]: true }] } - - log(query: string, values?: any[]) { - if (!environment.SQL_LOGGING_ENABLE) { - return - } - const sqlClient = this.getSqlClient() - let string = `[SQL] [${sqlClient.toUpperCase()}] query="${query}"` - if (values) { - string += ` values="${values.join(", ")}"` - } - console.log(string) - } } export default SqlQueryBuilder diff --git a/packages/server/src/integrations/googlesheets.ts b/packages/server/src/integrations/googlesheets.ts index 32398bde41..58c867ea0b 100644 --- a/packages/server/src/integrations/googlesheets.ts +++ b/packages/server/src/integrations/googlesheets.ts @@ -16,7 +16,6 @@ import { Table, TableRequest, TableSourceType, - DatasourcePlusQueryResponse, } from "@budibase/types" import { OAuth2Client } from "google-auth-library" import { @@ -335,7 +334,7 @@ class GoogleSheetsIntegration implements DatasourcePlus { return { tables: externalTables, errors } } - async query(json: QueryJson): DatasourcePlusQueryResponse { + async query(json: QueryJson) { const sheet = json.endpoint.entityId switch (json.endpoint.operation) { case Operation.CREATE: @@ -385,7 +384,7 @@ class GoogleSheetsIntegration implements DatasourcePlus { } try { await this.connect() - await this.client.addSheet({ title: name, headerValues: [name] }) + return await this.client.addSheet({ title: name, headerValues: [name] }) } catch (err) { console.error("Error creating new table in google sheets", err) throw err @@ -451,7 +450,7 @@ class GoogleSheetsIntegration implements DatasourcePlus { try { await this.connect() const sheetToDelete = this.client.sheetsByTitle[sheet] - await sheetToDelete.delete() + return await sheetToDelete.delete() } catch (err) { console.error("Error deleting table in google sheets", err) throw err diff --git a/packages/server/src/integrations/microsoftSqlServer.ts b/packages/server/src/integrations/microsoftSqlServer.ts index f87e248ac0..d0a06d4476 100644 --- a/packages/server/src/integrations/microsoftSqlServer.ts +++ b/packages/server/src/integrations/microsoftSqlServer.ts @@ -13,7 +13,6 @@ import { SourceName, Schema, TableSourceType, - DatasourcePlusQueryResponse, } from "@budibase/types" import { getSqlQuery, @@ -330,7 +329,6 @@ class SqlServerIntegration extends Sql implements DatasourcePlus { operation === Operation.CREATE ? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;` : query.sql - this.log(sql, query.bindings) return await request.query(sql) } catch (err: any) { let readableMessage = getReadableErrorMessage( @@ -494,7 +492,7 @@ class SqlServerIntegration extends Sql implements DatasourcePlus { return response.recordset || [{ deleted: true }] } - async query(json: QueryJson): DatasourcePlusQueryResponse { + async query(json: QueryJson) { const schema = this.config.schema await this.connect() if (schema && schema !== DEFAULT_SCHEMA && json?.endpoint) { diff --git a/packages/server/src/integrations/mysql.ts b/packages/server/src/integrations/mysql.ts index f629381807..5a206e1a7f 100644 --- a/packages/server/src/integrations/mysql.ts +++ b/packages/server/src/integrations/mysql.ts @@ -12,7 +12,6 @@ import { SourceName, Schema, TableSourceType, - DatasourcePlusQueryResponse, } from "@budibase/types" import { getSqlQuery, @@ -261,7 +260,6 @@ class MySQLIntegration extends Sql implements DatasourcePlus { const bindings = opts?.disableCoercion ? baseBindings : bindingTypeCoerce(baseBindings) - this.log(query.sql, bindings) // Node MySQL is callback based, so we must wrap our call in a promise const response = await this.client!.query(query.sql, bindings) return response[0] @@ -381,7 +379,7 @@ class MySQLIntegration extends Sql implements DatasourcePlus { return results.length ? results : [{ deleted: true }] } - async query(json: QueryJson): DatasourcePlusQueryResponse { + async query(json: QueryJson) { await this.connect() try { const queryFn = (query: any) => diff --git a/packages/server/src/integrations/oracle.ts b/packages/server/src/integrations/oracle.ts index 08f3058d63..b3aefc578c 100644 --- a/packages/server/src/integrations/oracle.ts +++ b/packages/server/src/integrations/oracle.ts @@ -12,8 +12,6 @@ import { ConnectionInfo, Schema, TableSourceType, - Row, - DatasourcePlusQueryResponse, } from "@budibase/types" import { buildExternalTableId, @@ -370,7 +368,6 @@ class OracleIntegration extends Sql implements DatasourcePlus { const options: ExecuteOptions = { autoCommit: true } const bindings: BindParameters = query.bindings || [] - this.log(query.sql, bindings) return await connection.execute(query.sql, bindings, options) } finally { if (connection) { @@ -422,7 +419,7 @@ class OracleIntegration extends Sql implements DatasourcePlus { : [{ deleted: true }] } - async query(json: QueryJson): DatasourcePlusQueryResponse { + async query(json: QueryJson) { const operation = this._operation(json) const input = this._query(json, { disableReturning: true }) as SqlQuery if (Array.isArray(input)) { @@ -446,7 +443,7 @@ class OracleIntegration extends Sql implements DatasourcePlus { if (deletedRows?.rows?.length) { return deletedRows.rows } else if (response.rows?.length) { - return response.rows as Row[] + return response.rows } else { // get the last row that was updated if ( @@ -457,7 +454,7 @@ class OracleIntegration extends Sql implements DatasourcePlus { const lastRow = await this.internalQuery({ sql: `SELECT * FROM \"${json.endpoint.entityId}\" WHERE ROWID = '${response.lastRowid}'`, }) - return lastRow.rows as Row[] + return lastRow.rows } else { return [{ [operation.toLowerCase()]: true }] } diff --git a/packages/server/src/integrations/postgres.ts b/packages/server/src/integrations/postgres.ts index 635d834761..bea31d4031 100644 --- a/packages/server/src/integrations/postgres.ts +++ b/packages/server/src/integrations/postgres.ts @@ -12,7 +12,6 @@ import { SourceName, Schema, TableSourceType, - DatasourcePlusQueryResponse, } from "@budibase/types" import { getSqlQuery, @@ -269,9 +268,7 @@ class PostgresIntegration extends Sql implements DatasourcePlus { } } try { - const bindings = query.bindings || [] - this.log(query.sql, bindings) - return await client.query(query.sql, bindings) + return await client.query(query.sql, query.bindings || []) } catch (err: any) { await this.closeConnection() let readableMessage = getReadableErrorMessage( @@ -420,7 +417,7 @@ class PostgresIntegration extends Sql implements DatasourcePlus { return response.rows.length ? response.rows : [{ deleted: true }] } - async query(json: QueryJson): DatasourcePlusQueryResponse { + async query(json: QueryJson) { const operation = this._operation(json).toLowerCase() const input = this._query(json) as SqlQuery if (Array.isArray(input)) { diff --git a/packages/server/src/integrations/tests/sql.spec.ts b/packages/server/src/integrations/tests/sql.spec.ts index f4eaf2859c..fd705fc27c 100644 --- a/packages/server/src/integrations/tests/sql.spec.ts +++ b/packages/server/src/integrations/tests/sql.spec.ts @@ -1,5 +1,3 @@ -import { SqlClient } from "../utils" -import Sql from "../base/sql" import { Operation, QueryJson, @@ -8,6 +6,9 @@ import { FieldType, } from "@budibase/types" +const Sql = require("../base/sql").default +const { SqlClient } = require("../utils") + const TABLE_NAME = "test" function endpoint(table: any, operation: any) { @@ -41,7 +42,7 @@ function generateReadJson({ schema: {}, name: table || TABLE_NAME, primary: ["id"], - } as any, + }, }, } } @@ -518,7 +519,7 @@ describe("SQL query builder", () => { const query = sql._query(generateRelationshipJson({ schema: "production" })) expect(query).toEqual({ bindings: [500, 5000], - sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "production"."brands" limit $1) as "brands" left join "production"."products" as "products" on "brands"."brand_id" = "products"."brand_id" limit $2`, + sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "production"."brands" limit $1) as "brands" left join "production"."products" on "brands"."brand_id" = "products"."brand_id" limit $2`, }) }) @@ -526,7 +527,7 @@ describe("SQL query builder", () => { const query = sql._query(generateRelationshipJson()) expect(query).toEqual({ bindings: [500, 5000], - sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "brands" limit $1) as "brands" left join "products" as "products" on "brands"."brand_id" = "products"."brand_id" limit $2`, + sql: `select "brands"."brand_id" as "brands.brand_id", "brands"."brand_name" as "brands.brand_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name", "products"."brand_id" as "products.brand_id" from (select * from "brands" limit $1) as "brands" left join "products" on "brands"."brand_id" = "products"."brand_id" limit $2`, }) }) @@ -536,7 +537,7 @@ describe("SQL query builder", () => { ) expect(query).toEqual({ bindings: [500, 5000], - sql: `select "stores"."store_id" as "stores.store_id", "stores"."store_name" as "stores.store_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name" from (select * from "production"."stores" limit $1) as "stores" left join "production"."stocks" as "stocks" on "stores"."store_id" = "stocks"."store_id" left join "production"."products" as "products" on "products"."product_id" = "stocks"."product_id" limit $2`, + sql: `select "stores"."store_id" as "stores.store_id", "stores"."store_name" as "stores.store_name", "products"."product_id" as "products.product_id", "products"."product_name" as "products.product_name" from (select * from "production"."stores" limit $1) as "stores" left join "production"."stocks" on "stores"."store_id" = "stocks"."store_id" left join "production"."products" on "products"."product_id" = "stocks"."product_id" limit $2`, }) }) @@ -732,7 +733,7 @@ describe("SQL query builder", () => { }, meta: { table: oldTable, - tables: { [oldTable.name]: oldTable }, + tables: [oldTable], renamed: { old: "name", updated: "first_name", diff --git a/packages/server/src/integrations/tests/sqlAlias.spec.ts b/packages/server/src/integrations/tests/sqlAlias.spec.ts deleted file mode 100644 index 9b3f6a1b38..0000000000 --- a/packages/server/src/integrations/tests/sqlAlias.spec.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { QueryJson } from "@budibase/types" -import { join } from "path" -import Sql from "../base/sql" -import { SqlClient } from "../utils" -import AliasTables from "../../api/controllers/row/alias" -import { generator } from "@budibase/backend-core/tests" - -function multiline(sql: string) { - return sql.replace(/\n/g, "").replace(/ +/g, " ") -} - -describe("Captures of real examples", () => { - const limit = 5000 - const relationshipLimit = 100 - - function getJson(name: string): QueryJson { - return require(join(__dirname, "sqlQueryJson", name)) as QueryJson - } - - describe("create", () => { - it("should create a row with relationships", () => { - const queryJson = getJson("createWithRelationships.json") - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: ["A Street", 34, "London", "A", "B", "designer", 1990], - sql: multiline(`insert into "persons" ("address", "age", "city", "firstname", "lastname", "type", "year") - values ($1, $2, $3, $4, $5, $6, $7) returning *`), - }) - }) - }) - - describe("read", () => { - it("should handle basic retrieval with relationships", () => { - const queryJson = getJson("basicFetchWithRelationships.json") - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: [relationshipLimit, limit], - sql: multiline(`select "a"."year" as "a.year", "a"."firstname" as "a.firstname", "a"."personid" as "a.personid", - "a"."address" as "a.address", "a"."age" as "a.age", "a"."type" as "a.type", "a"."city" as "a.city", - "a"."lastname" as "a.lastname", "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", - "b"."taskid" as "b.taskid", "b"."completed" as "b.completed", "b"."qaid" as "b.qaid", - "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", - "b"."completed" as "b.completed", "b"."qaid" as "b.qaid" - from (select * from "persons" as "a" order by "a"."firstname" asc limit $1) as "a" - left join "tasks" as "b" on "a"."personid" = "b"."qaid" or "a"."personid" = "b"."executorid" - order by "a"."firstname" asc limit $2`), - }) - }) - - it("should handle filtering by relationship", () => { - const queryJson = getJson("filterByRelationship.json") - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: [relationshipLimit, "assembling", limit], - sql: multiline(`select "a"."productname" as "a.productname", "a"."productid" as "a.productid", - "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", - "b"."completed" as "b.completed", "b"."qaid" as "b.qaid" - from (select * from "products" as "a" order by "a"."productname" asc limit $1) as "a" - left join "products_tasks" as "c" on "a"."productid" = "c"."productid" - left join "tasks" as "b" on "b"."taskid" = "c"."taskid" where "b"."taskname" = $2 - order by "a"."productname" asc limit $3`), - }) - }) - - it("should handle fetching many to many relationships", () => { - const queryJson = getJson("fetchManyToMany.json") - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: [relationshipLimit, limit], - sql: multiline(`select "a"."productname" as "a.productname", "a"."productid" as "a.productid", - "b"."executorid" as "b.executorid", "b"."taskname" as "b.taskname", "b"."taskid" as "b.taskid", - "b"."completed" as "b.completed", "b"."qaid" as "b.qaid" - from (select * from "products" as "a" order by "a"."productname" asc limit $1) as "a" - left join "products_tasks" as "c" on "a"."productid" = "c"."productid" - left join "tasks" as "b" on "b"."taskid" = "c"."taskid" - order by "a"."productname" asc limit $2`), - }) - }) - - it("should handle enrichment of rows", () => { - const queryJson = getJson("enrichRelationship.json") - const filters = queryJson.filters?.oneOf?.taskid as number[] - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: [...filters, limit, limit], - sql: multiline(`select "a"."executorid" as "a.executorid", "a"."taskname" as "a.taskname", - "a"."taskid" as "a.taskid", "a"."completed" as "a.completed", "a"."qaid" as "a.qaid", - "b"."productname" as "b.productname", "b"."productid" as "b.productid" - from (select * from "tasks" as "a" where "a"."taskid" in ($1, $2) limit $3) as "a" - left join "products_tasks" as "c" on "a"."taskid" = "c"."taskid" - left join "products" as "b" on "b"."productid" = "c"."productid" limit $4`), - }) - }) - - it("should manage query with many relationship filters", () => { - const queryJson = getJson("manyRelationshipFilters.json") - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - const filters = queryJson.filters - const notEqualsValue = Object.values(filters?.notEqual!)[0] - const rangeValue = Object.values(filters?.range!)[0] - const equalValue = Object.values(filters?.equal!)[0] - - expect(query).toEqual({ - bindings: [ - notEqualsValue, - relationshipLimit, - rangeValue.low, - rangeValue.high, - equalValue, - limit, - ], - sql: multiline(`select "a"."executorid" as "a.executorid", "a"."taskname" as "a.taskname", "a"."taskid" as "a.taskid", - "a"."completed" as "a.completed", "a"."qaid" as "a.qaid", "b"."productname" as "b.productname", - "b"."productid" as "b.productid", "c"."year" as "c.year", "c"."firstname" as "c.firstname", - "c"."personid" as "c.personid", "c"."address" as "c.address", "c"."age" as "c.age", "c"."type" as "c.type", - "c"."city" as "c.city", "c"."lastname" as "c.lastname", "c"."year" as "c.year", "c"."firstname" as "c.firstname", - "c"."personid" as "c.personid", "c"."address" as "c.address", "c"."age" as "c.age", "c"."type" as "c.type", - "c"."city" as "c.city", "c"."lastname" as "c.lastname" - from (select * from "tasks" as "a" where not "a"."completed" = $1 - order by "a"."taskname" asc limit $2) as "a" - left join "products_tasks" as "d" on "a"."taskid" = "d"."taskid" - left join "products" as "b" on "b"."productid" = "d"."productid" - left join "persons" as "c" on "a"."executorid" = "c"."personid" or "a"."qaid" = "c"."personid" - where "c"."year" between $3 and $4 and "b"."productname" = $5 order by "a"."taskname" asc limit $6`), - }) - }) - }) - - describe("update", () => { - it("should handle performing a simple update", () => { - const queryJson = getJson("updateSimple.json") - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: [1990, "C", "A Street", 34, "designer", "London", "B", 5], - sql: multiline(`update "persons" as "a" set "year" = $1, "firstname" = $2, "address" = $3, "age" = $4, - "type" = $5, "city" = $6, "lastname" = $7 where "a"."personid" = $8 returning *`), - }) - }) - - it("should handle performing an update of relationships", () => { - const queryJson = getJson("updateRelationship.json") - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: [1990, "C", "A Street", 34, "designer", "London", "B", 5], - sql: multiline(`update "persons" as "a" set "year" = $1, "firstname" = $2, "address" = $3, "age" = $4, - "type" = $5, "city" = $6, "lastname" = $7 where "a"."personid" = $8 returning *`), - }) - }) - }) - - describe("delete", () => { - it("should handle deleting with relationships", () => { - const queryJson = getJson("deleteSimple.json") - let query = new Sql(SqlClient.POSTGRES, limit)._query(queryJson) - expect(query).toEqual({ - bindings: ["ddd", ""], - sql: multiline(`delete from "compositetable" as "a" where "a"."keypartone" = $1 and "a"."keyparttwo" = $2 - returning "a"."keyparttwo" as "a.keyparttwo", "a"."keypartone" as "a.keypartone", "a"."name" as "a.name"`), - }) - }) - }) - - describe("check max character aliasing", () => { - it("should handle over 'z' max character alias", () => { - const tableNames = [] - for (let i = 0; i < 100; i++) { - tableNames.push(generator.guid()) - } - const aliasing = new AliasTables(tableNames) - let alias: string = "" - for (let table of tableNames) { - alias = aliasing.getAlias(table) - } - expect(alias).toEqual("cv") - }) - }) - - describe("check some edge cases", () => { - const tableNames = ["hello", "world"] - - it("should handle quoted table names", () => { - const aliasing = new AliasTables(tableNames) - const aliased = aliasing.aliasField(`"hello"."field"`) - expect(aliased).toEqual(`"a"."field"`) - }) - - it("should handle quoted table names with graves", () => { - const aliasing = new AliasTables(tableNames) - const aliased = aliasing.aliasField("`hello`.`world`") - expect(aliased).toEqual("`a`.`world`") - }) - - it("should handle table names in table names correctly", () => { - const tableNames = ["he", "hell", "hello"] - const aliasing = new AliasTables(tableNames) - const aliased1 = aliasing.aliasField("`he`.`world`") - const aliased2 = aliasing.aliasField("`hell`.`world`") - const aliased3 = aliasing.aliasField("`hello`.`world`") - expect(aliased1).toEqual("`a`.`world`") - expect(aliased2).toEqual("`b`.`world`") - expect(aliased3).toEqual("`c`.`world`") - }) - }) -}) diff --git a/packages/server/src/integrations/tests/sqlQueryJson/basicFetchWithRelationships.json b/packages/server/src/integrations/tests/sqlQueryJson/basicFetchWithRelationships.json deleted file mode 100644 index 3445f5fe67..0000000000 --- a/packages/server/src/integrations/tests/sqlQueryJson/basicFetchWithRelationships.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "endpoint": { - "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "entityId": "persons", - "operation": "READ" - }, - "resource": { - "fields": [ - "a.year", - "a.firstname", - "a.personid", - "a.address", - "a.age", - "a.type", - "a.city", - "a.lastname", - "b.executorid", - "b.taskname", - "b.taskid", - "b.completed", - "b.qaid", - "b.executorid", - "b.taskname", - "b.taskid", - "b.completed", - "b.qaid" - ] - }, - "filters": {}, - "sort": { - "firstname": { - "direction": "ASCENDING" - } - }, - "paginate": { - "limit": 100, - "page": 1 - }, - "relationships": [ - { - "tableName": "tasks", - "column": "QA", - "from": "personid", - "to": "qaid", - "aliases": { - "tasks": "b", - "persons": "a" - } - }, - { - "tableName": "tasks", - "column": "executor", - "from": "personid", - "to": "executorid", - "aliases": { - "tasks": "b", - "persons": "a" - } - } - ], - "extra": { - "idFilter": {} - }, - "meta": { - "table": { - "type": "table", - "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__persons", - "primary": [ - "personid" - ], - "name": "a", - "schema": { - "year": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "year", - "constraints": { - "presence": false - } - }, - "firstname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "firstname", - "constraints": { - "presence": false - } - }, - "personid": { - "type": "number", - "externalType": "integer", - "autocolumn": true, - "name": "personid", - "constraints": { - "presence": false - } - }, - "address": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "address", - "constraints": { - "presence": false - } - }, - "age": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "age", - "constraints": { - "presence": false - } - }, - "type": { - "type": "options", - "externalType": "USER-DEFINED", - "autocolumn": false, - "name": "type", - "constraints": { - "presence": false, - "inclusion": [ - "support", - "designer", - "programmer", - "qa" - ] - } - }, - "city": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "city", - "constraints": { - "presence": false - } - }, - "lastname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "lastname", - "constraints": { - "presence": false - } - }, - "QA": { - "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - "name": "QA", - "relationshipType": "many-to-one", - "fieldName": "qaid", - "type": "link", - "main": true, - "_id": "ccb68481c80c34217a4540a2c6c27fe46", - "foreignKey": "personid" - }, - "executor": { - "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - "name": "executor", - "relationshipType": "many-to-one", - "fieldName": "executorid", - "type": "link", - "main": true, - "_id": "c89530b9770d94bec851e062b5cff3001", - "foreignKey": "personid", - "tableName": "persons" - } - }, - "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "sourceType": "external", - "primaryDisplay": "firstname", - "views": {} - } - }, - "tableAliases": { - "persons": "a", - "tasks": "b" - } -} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/createWithRelationships.json b/packages/server/src/integrations/tests/sqlQueryJson/createWithRelationships.json deleted file mode 100644 index 20331b949a..0000000000 --- a/packages/server/src/integrations/tests/sqlQueryJson/createWithRelationships.json +++ /dev/null @@ -1,173 +0,0 @@ -{ - "endpoint": { - "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "entityId": "persons", - "operation": "CREATE" - }, - "resource": { - "fields": [ - "a.year", - "a.firstname", - "a.personid", - "a.address", - "a.age", - "a.type", - "a.city", - "a.lastname" - ] - }, - "filters": {}, - "relationships": [ - { - "tableName": "tasks", - "column": "QA", - "from": "personid", - "to": "qaid", - "aliases": { - "tasks": "b", - "persons": "a" - } - }, - { - "tableName": "tasks", - "column": "executor", - "from": "personid", - "to": "executorid", - "aliases": { - "tasks": "b", - "persons": "a" - } - } - ], - "body": { - "year": 1990, - "firstname": "A", - "address": "A Street", - "age": 34, - "type": "designer", - "city": "London", - "lastname": "B" - }, - "extra": { - "idFilter": {} - }, - "meta": { - "table": { - "type": "table", - "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__persons", - "primary": [ - "personid" - ], - "name": "a", - "schema": { - "year": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "year", - "constraints": { - "presence": false - } - }, - "firstname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "firstname", - "constraints": { - "presence": false - } - }, - "personid": { - "type": "number", - "externalType": "integer", - "autocolumn": true, - "name": "personid", - "constraints": { - "presence": false - } - }, - "address": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "address", - "constraints": { - "presence": false - } - }, - "age": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "age", - "constraints": { - "presence": false - } - }, - "type": { - "type": "options", - "externalType": "USER-DEFINED", - "autocolumn": false, - "name": "type", - "constraints": { - "presence": false, - "inclusion": [ - "support", - "designer", - "programmer", - "qa" - ] - } - }, - "city": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "city", - "constraints": { - "presence": false - } - }, - "lastname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "lastname", - "constraints": { - "presence": false - } - }, - "QA": { - "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - "name": "QA", - "relationshipType": "many-to-one", - "fieldName": "qaid", - "type": "link", - "main": true, - "_id": "ccb68481c80c34217a4540a2c6c27fe46", - "foreignKey": "personid" - }, - "executor": { - "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - "name": "executor", - "relationshipType": "many-to-one", - "fieldName": "executorid", - "type": "link", - "main": true, - "_id": "c89530b9770d94bec851e062b5cff3001", - "foreignKey": "personid", - "tableName": "persons" - } - }, - "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "sourceType": "external", - "primaryDisplay": "firstname", - "views": {} - } - }, - "tableAliases": { - "persons": "a", - "tasks": "b" - } -} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/deleteSimple.json b/packages/server/src/integrations/tests/sqlQueryJson/deleteSimple.json deleted file mode 100644 index 2266b8c8be..0000000000 --- a/packages/server/src/integrations/tests/sqlQueryJson/deleteSimple.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "endpoint": { - "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "entityId": "compositetable", - "operation": "DELETE" - }, - "resource": { - "fields": [ - "a.keyparttwo", - "a.keypartone", - "a.name" - ] - }, - "filters": { - "equal": { - "keypartone": "ddd", - "keyparttwo": "" - } - }, - "relationships": [], - "extra": { - "idFilter": { - "equal": { - "keypartone": "ddd", - "keyparttwo": "" - } - } - }, - "meta": { - "table": { - "type": "table", - "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__compositetable", - "primary": [ - "keypartone", - "keyparttwo" - ], - "name": "a", - "schema": { - "keyparttwo": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "keyparttwo", - "constraints": { - "presence": true - } - }, - "keypartone": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "keypartone", - "constraints": { - "presence": true - } - }, - "name": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "name", - "constraints": { - "presence": false - } - } - }, - "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "sourceType": "external", - "primaryDisplay": "keypartone" - } - }, - "tableAliases": { - "compositetable": "a" - } -} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/enrichRelationship.json b/packages/server/src/integrations/tests/sqlQueryJson/enrichRelationship.json deleted file mode 100644 index ee658aed18..0000000000 --- a/packages/server/src/integrations/tests/sqlQueryJson/enrichRelationship.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "endpoint": { - "datasourceId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81", - "entityId": "tasks", - "operation": "READ" - }, - "resource": { - "fields": [ - "a.executorid", - "a.taskname", - "a.taskid", - "a.completed", - "a.qaid", - "b.productname", - "b.productid" - ] - }, - "filters": { - "oneOf": { - "taskid": [ - 1, - 2 - ] - } - }, - "relationships": [ - { - "tableName": "products", - "column": "products", - "through": "products_tasks", - "from": "taskid", - "to": "productid", - "fromPrimary": "taskid", - "toPrimary": "productid", - "aliases": { - "products_tasks": "c", - "products": "b", - "tasks": "a" - } - } - ], - "extra": { - "idFilter": {} - }, - "meta": { - "table": { - "type": "table", - "_id": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__tasks", - "primary": [ - "taskid" - ], - "name": "a", - "schema": { - "executorid": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "executorid", - "constraints": { - "presence": false - } - }, - "taskname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "taskname", - "constraints": { - "presence": false - } - }, - "taskid": { - "type": "number", - "externalType": "integer", - "autocolumn": true, - "name": "taskid", - "constraints": { - "presence": false - } - }, - "completed": { - "type": "boolean", - "externalType": "boolean", - "autocolumn": false, - "name": "completed", - "constraints": { - "presence": false - } - }, - "qaid": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "qaid", - "constraints": { - "presence": false - } - }, - "products": { - "tableId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__products", - "name": "products", - "relationshipType": "many-to-many", - "through": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__products_tasks", - "type": "link", - "_id": "c3b91d00cd36c4cc1a347794725b9adbd", - "fieldName": "productid", - "throughFrom": "productid", - "throughTo": "taskid" - } - }, - "sourceId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81", - "sourceType": "external", - "primaryDisplay": "taskname", - "sql": true, - "views": {} - } - }, - "tableAliases": { - "tasks": "a", - "products": "b", - "products_tasks": "c" - } -} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/fetchManyToMany.json b/packages/server/src/integrations/tests/sqlQueryJson/fetchManyToMany.json deleted file mode 100644 index 682ebaab2d..0000000000 --- a/packages/server/src/integrations/tests/sqlQueryJson/fetchManyToMany.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "endpoint": { - "datasourceId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81", - "entityId": "products", - "operation": "READ" - }, - "resource": { - "fields": [ - "a.productname", - "a.productid", - "b.executorid", - "b.taskname", - "b.taskid", - "b.completed", - "b.qaid" - ] - }, - "filters": { - "string": {}, - "fuzzy": {}, - "range": {}, - "equal": {}, - "notEqual": {}, - "empty": {}, - "notEmpty": {}, - "contains": {}, - "notContains": {}, - "oneOf": {}, - "containsAny": {} - }, - "sort": { - "productname": { - "direction": "ASCENDING" - } - }, - "paginate": { - "limit": 100, - "page": 1 - }, - "relationships": [ - { - "tableName": "tasks", - "column": "tasks", - "through": "products_tasks", - "from": "productid", - "to": "taskid", - "fromPrimary": "productid", - "toPrimary": "taskid", - "aliases": { - "products_tasks": "c", - "tasks": "b", - "products": "a" - } - } - ], - "extra": { - "idFilter": {} - }, - "meta": { - "table": { - "type": "table", - "_id": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__products", - "primary": [ - "productid" - ], - "name": "a", - "schema": { - "productname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "productname", - "constraints": { - "presence": false - } - }, - "productid": { - "type": "number", - "externalType": "integer", - "autocolumn": true, - "name": "productid", - "constraints": { - "presence": false - } - }, - "tasks": { - "tableId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__tasks", - "name": "tasks", - "relationshipType": "many-to-many", - "fieldName": "taskid", - "through": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__products_tasks", - "throughFrom": "taskid", - "throughTo": "productid", - "type": "link", - "main": true, - "_id": "c3b91d00cd36c4cc1a347794725b9adbd" - } - }, - "sourceId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81", - "sourceType": "external", - "primaryDisplay": "productname" - } - }, - "tableAliases": { - "products": "a", - "tasks": "b", - "products_tasks": "c" - } -} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/filterByRelationship.json b/packages/server/src/integrations/tests/sqlQueryJson/filterByRelationship.json deleted file mode 100644 index eb1025f382..0000000000 --- a/packages/server/src/integrations/tests/sqlQueryJson/filterByRelationship.json +++ /dev/null @@ -1,94 +0,0 @@ -{ - "endpoint": { - "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "entityId": "products", - "operation": "READ" - }, - "resource": { - "fields": [ - "a.productname", - "a.productid", - "b.executorid", - "b.taskname", - "b.taskid", - "b.completed", - "b.qaid" - ] - }, - "filters": { - "equal": { - "1:tasks.taskname": "assembling" - }, - "onEmptyFilter": "all" - }, - "sort": { - "productname": { - "direction": "ASCENDING" - } - }, - "paginate": { - "limit": 100, - "page": 1 - }, - "relationships": [ - { - "tableName": "tasks", - "column": "tasks", - "through": "products_tasks", - "from": "productid", - "to": "taskid", - "fromPrimary": "productid", - "toPrimary": "taskid" - } - ], - "tableAliases": { - "products_tasks": "c", - "tasks": "b", - "products": "a" - }, - "meta": { - "table": { - "type": "table", - "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__products", - "primary": [ - "productid" - ], - "name": "a", - "schema": { - "productname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "productname", - "constraints": { - "presence": false - } - }, - "productid": { - "type": "number", - "externalType": "integer", - "autocolumn": true, - "name": "productid", - "constraints": { - "presence": false - } - }, - "tasks": { - "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - "name": "tasks", - "relationshipType": "many-to-many", - "fieldName": "taskid", - "through": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__products_tasks", - "throughFrom": "taskid", - "throughTo": "productid", - "type": "link", - "main": true, - "_id": "ca6862d9ba09146dd8a68e3b5b7055a09" - } - }, - "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "sourceType": "external", - "primaryDisplay": "productname" - } - } -} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/manyRelationshipFilters.json b/packages/server/src/integrations/tests/sqlQueryJson/manyRelationshipFilters.json deleted file mode 100644 index afa0889450..0000000000 --- a/packages/server/src/integrations/tests/sqlQueryJson/manyRelationshipFilters.json +++ /dev/null @@ -1,202 +0,0 @@ -{ - "endpoint": { - "datasourceId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81", - "entityId": "tasks", - "operation": "READ" - }, - "resource": { - "fields": [ - "a.executorid", - "a.taskname", - "a.taskid", - "a.completed", - "a.qaid", - "b.productname", - "b.productid", - "c.year", - "c.firstname", - "c.personid", - "c.address", - "c.age", - "c.type", - "c.city", - "c.lastname", - "c.year", - "c.firstname", - "c.personid", - "c.address", - "c.age", - "c.type", - "c.city", - "c.lastname" - ] - }, - "filters": { - "string": {}, - "fuzzy": {}, - "range": { - "1:persons.year": { - "low": 1990, - "high": 2147483647 - } - }, - "equal": { - "2:products.productname": "Computers" - }, - "notEqual": { - "3:completed": true - }, - "empty": {}, - "notEmpty": {}, - "contains": {}, - "notContains": {}, - "oneOf": {}, - "containsAny": {}, - "onEmptyFilter": "all" - }, - "sort": { - "taskname": { - "direction": "ASCENDING" - } - }, - "paginate": { - "limit": 100, - "page": 1 - }, - "relationships": [ - { - "tableName": "products", - "column": "products", - "through": "products_tasks", - "from": "taskid", - "to": "productid", - "fromPrimary": "taskid", - "toPrimary": "productid", - "aliases": { - "products_tasks": "d", - "products": "b", - "tasks": "a" - } - }, - { - "tableName": "persons", - "column": "tasksToExecute", - "from": "executorid", - "to": "personid", - "aliases": { - "persons": "c", - "tasks": "a" - } - }, - { - "tableName": "persons", - "column": "tasksToQA", - "from": "qaid", - "to": "personid", - "aliases": { - "persons": "c", - "tasks": "a" - } - } - ], - "extra": { - "idFilter": {} - }, - "meta": { - "table": { - "type": "table", - "_id": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__tasks", - "primary": [ - "taskid" - ], - "name": "a", - "schema": { - "executorid": { - "type": "number", - "externalType": "integer", - "name": "executorid", - "constraints": { - "presence": false - }, - "autocolumn": true, - "autoReason": "foreign_key" - }, - "taskname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "taskname", - "constraints": { - "presence": false - } - }, - "taskid": { - "type": "number", - "externalType": "integer", - "autocolumn": true, - "name": "taskid", - "constraints": { - "presence": false - } - }, - "completed": { - "type": "boolean", - "externalType": "boolean", - "autocolumn": false, - "name": "completed", - "constraints": { - "presence": false - } - }, - "qaid": { - "type": "number", - "externalType": "integer", - "name": "qaid", - "constraints": { - "presence": false - } - }, - "products": { - "tableId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__products", - "name": "products", - "relationshipType": "many-to-many", - "through": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__products_tasks", - "type": "link", - "_id": "c3b91d00cd36c4cc1a347794725b9adbd", - "fieldName": "productid", - "throughFrom": "productid", - "throughTo": "taskid" - }, - "tasksToExecute": { - "tableId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__persons", - "name": "tasksToExecute", - "relationshipType": "one-to-many", - "type": "link", - "_id": "c0f440590bda04f28846242156c1dd60b", - "foreignKey": "executorid", - "fieldName": "personid" - }, - "tasksToQA": { - "tableId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81__persons", - "name": "tasksToQA", - "relationshipType": "one-to-many", - "type": "link", - "_id": "c5fdf453a0ba743d58e29491d174c974b", - "foreignKey": "qaid", - "fieldName": "personid" - } - }, - "sourceId": "datasource_plus_44a967caf37a435f84fe01cd6dfe8f81", - "sourceType": "external", - "primaryDisplay": "taskname", - "sql": true, - "views": {} - } - }, - "tableAliases": { - "tasks": "a", - "products": "b", - "persons": "c", - "products_tasks": "d" - } -} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/updateRelationship.json b/packages/server/src/integrations/tests/sqlQueryJson/updateRelationship.json deleted file mode 100644 index 01e795bd6c..0000000000 --- a/packages/server/src/integrations/tests/sqlQueryJson/updateRelationship.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "endpoint": { - "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "entityId": "persons", - "operation": "UPDATE" - }, - "resource": { - "fields": [ - "a.year", - "a.firstname", - "a.personid", - "a.address", - "a.age", - "a.type", - "a.city", - "a.lastname" - ] - }, - "filters": { - "equal": { - "personid": 5 - } - }, - "relationships": [ - { - "tableName": "tasks", - "column": "QA", - "from": "personid", - "to": "qaid", - "aliases": { - "tasks": "b", - "persons": "a" - } - }, - { - "tableName": "tasks", - "column": "executor", - "from": "personid", - "to": "executorid", - "aliases": { - "tasks": "b", - "persons": "a" - } - } - ], - "body": { - "year": 1990, - "firstname": "C", - "address": "A Street", - "age": 34, - "type": "designer", - "city": "London", - "lastname": "B" - }, - "extra": { - "idFilter": { - "equal": { - "personid": 5 - } - } - }, - "meta": { - "table": { - "type": "table", - "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__persons", - "primary": [ - "personid" - ], - "name": "a", - "schema": { - "year": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "year", - "constraints": { - "presence": false - } - }, - "firstname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "firstname", - "constraints": { - "presence": false - } - }, - "personid": { - "type": "number", - "externalType": "integer", - "autocolumn": true, - "name": "personid", - "constraints": { - "presence": false - } - }, - "address": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "address", - "constraints": { - "presence": false - } - }, - "age": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "age", - "constraints": { - "presence": false - } - }, - "type": { - "type": "options", - "externalType": "USER-DEFINED", - "autocolumn": false, - "name": "type", - "constraints": { - "presence": false, - "inclusion": [ - "support", - "designer", - "programmer", - "qa" - ] - } - }, - "city": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "city", - "constraints": { - "presence": false - } - }, - "lastname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "lastname", - "constraints": { - "presence": false - } - }, - "QA": { - "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - "name": "QA", - "relationshipType": "many-to-one", - "fieldName": "qaid", - "type": "link", - "main": true, - "_id": "ccb68481c80c34217a4540a2c6c27fe46", - "foreignKey": "personid" - }, - "executor": { - "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - "name": "executor", - "relationshipType": "many-to-one", - "fieldName": "executorid", - "type": "link", - "main": true, - "_id": "c89530b9770d94bec851e062b5cff3001", - "foreignKey": "personid", - "tableName": "persons" - } - }, - "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "sourceType": "external", - "primaryDisplay": "firstname", - "views": {} - } - }, - "tableAliases": { - "persons": "a", - "tasks": "b" - } -} \ No newline at end of file diff --git a/packages/server/src/integrations/tests/sqlQueryJson/updateSimple.json b/packages/server/src/integrations/tests/sqlQueryJson/updateSimple.json deleted file mode 100644 index 01e795bd6c..0000000000 --- a/packages/server/src/integrations/tests/sqlQueryJson/updateSimple.json +++ /dev/null @@ -1,181 +0,0 @@ -{ - "endpoint": { - "datasourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "entityId": "persons", - "operation": "UPDATE" - }, - "resource": { - "fields": [ - "a.year", - "a.firstname", - "a.personid", - "a.address", - "a.age", - "a.type", - "a.city", - "a.lastname" - ] - }, - "filters": { - "equal": { - "personid": 5 - } - }, - "relationships": [ - { - "tableName": "tasks", - "column": "QA", - "from": "personid", - "to": "qaid", - "aliases": { - "tasks": "b", - "persons": "a" - } - }, - { - "tableName": "tasks", - "column": "executor", - "from": "personid", - "to": "executorid", - "aliases": { - "tasks": "b", - "persons": "a" - } - } - ], - "body": { - "year": 1990, - "firstname": "C", - "address": "A Street", - "age": 34, - "type": "designer", - "city": "London", - "lastname": "B" - }, - "extra": { - "idFilter": { - "equal": { - "personid": 5 - } - } - }, - "meta": { - "table": { - "type": "table", - "_id": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__persons", - "primary": [ - "personid" - ], - "name": "a", - "schema": { - "year": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "year", - "constraints": { - "presence": false - } - }, - "firstname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "firstname", - "constraints": { - "presence": false - } - }, - "personid": { - "type": "number", - "externalType": "integer", - "autocolumn": true, - "name": "personid", - "constraints": { - "presence": false - } - }, - "address": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "address", - "constraints": { - "presence": false - } - }, - "age": { - "type": "number", - "externalType": "integer", - "autocolumn": false, - "name": "age", - "constraints": { - "presence": false - } - }, - "type": { - "type": "options", - "externalType": "USER-DEFINED", - "autocolumn": false, - "name": "type", - "constraints": { - "presence": false, - "inclusion": [ - "support", - "designer", - "programmer", - "qa" - ] - } - }, - "city": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "city", - "constraints": { - "presence": false - } - }, - "lastname": { - "type": "string", - "externalType": "character varying", - "autocolumn": false, - "name": "lastname", - "constraints": { - "presence": false - } - }, - "QA": { - "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - "name": "QA", - "relationshipType": "many-to-one", - "fieldName": "qaid", - "type": "link", - "main": true, - "_id": "ccb68481c80c34217a4540a2c6c27fe46", - "foreignKey": "personid" - }, - "executor": { - "tableId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7__tasks", - "name": "executor", - "relationshipType": "many-to-one", - "fieldName": "executorid", - "type": "link", - "main": true, - "_id": "c89530b9770d94bec851e062b5cff3001", - "foreignKey": "personid", - "tableName": "persons" - } - }, - "sourceId": "datasource_plus_8066e56456784eb2a00129d31be5c3e7", - "sourceType": "external", - "primaryDisplay": "firstname", - "views": {} - } - }, - "tableAliases": { - "persons": "a", - "tasks": "b" - } -} \ No newline at end of file diff --git a/packages/server/src/sdk/app/datasources/plus.ts b/packages/server/src/sdk/app/datasources/plus.ts index 31ec51c728..04cd508863 100644 --- a/packages/server/src/sdk/app/datasources/plus.ts +++ b/packages/server/src/sdk/app/datasources/plus.ts @@ -3,33 +3,12 @@ import { DatasourcePlus, IntegrationBase, Schema, - Table, } from "@budibase/types" import * as datasources from "./datasources" import tableSdk from "../tables" import { getIntegration } from "../../../integrations" import { context } from "@budibase/backend-core" -function checkForSchemaErrors(schema: Record) { - const errors: Record = {} - for (let [tableName, table] of Object.entries(schema)) { - if (tableName.includes(".")) { - errors[tableName] = "Table names containing dots are not supported." - } else { - const columnNames = Object.keys(table.schema) - const invalidColumnName = columnNames.find(columnName => - columnName.includes(".") - ) - if (invalidColumnName) { - errors[ - tableName - ] = `Column '${invalidColumnName}' is not supported as it contains a dot.` - } - } - } - return errors -} - export async function buildFilteredSchema( datasource: Datasource, filter?: string[] @@ -51,19 +30,16 @@ export async function buildFilteredSchema( filteredSchema.errors[key] = schema.errors[key] } } - - return { - ...filteredSchema, - errors: { - ...filteredSchema.errors, - ...checkForSchemaErrors(filteredSchema.tables), - }, - } + return filteredSchema } async function buildSchemaHelper(datasource: Datasource): Promise { const connector = (await getConnector(datasource)) as DatasourcePlus - return await connector.buildSchema(datasource._id!, datasource.entities!) + const externalSchema = await connector.buildSchema( + datasource._id!, + datasource.entities! + ) + return externalSchema } export async function getConnector( diff --git a/packages/server/src/sdk/app/rows/utils.ts b/packages/server/src/sdk/app/rows/utils.ts index a8052462a9..0ff85f40ac 100644 --- a/packages/server/src/sdk/app/rows/utils.ts +++ b/packages/server/src/sdk/app/rows/utils.ts @@ -1,21 +1,12 @@ import cloneDeep from "lodash/cloneDeep" import validateJs from "validate.js" -import { - FieldType, - QueryJson, - Row, - Table, - TableSchema, - DatasourcePlusQueryResponse, -} from "@budibase/types" +import { FieldType, Row, Table, TableSchema } from "@budibase/types" import { makeExternalQuery } from "../../../integrations/base/query" import { Format } from "../../../api/controllers/view/exporters" import sdk from "../.." import { isRelationshipColumn } from "../../../db/utils" -export async function getDatasourceAndQuery( - json: QueryJson -): DatasourcePlusQueryResponse { +export async function getDatasourceAndQuery(json: any) { const datasourceId = json.endpoint.datasourceId const datasource = await sdk.datasources.get(datasourceId) return makeExternalQuery(datasource, json) diff --git a/packages/types/src/sdk/datasources.ts b/packages/types/src/sdk/datasources.ts index 4cddb0c09e..7a335eb3b9 100644 --- a/packages/types/src/sdk/datasources.ts +++ b/packages/types/src/sdk/datasources.ts @@ -1,5 +1,4 @@ -import { Table, Row } from "../documents" -import { QueryJson } from "./search" +import { Table } from "../documents" export const PASSWORD_REPLACEMENT = "--secret-value--" @@ -181,24 +180,11 @@ export interface Schema { errors: Record } -// return these when an operation occurred but we got no response -enum DSPlusOperation { - CREATE = "create", - READ = "read", - UPDATE = "update", - DELETE = "delete", -} - -export type DatasourcePlusQueryResponse = Promise< - Row[] | Record[] | void -> - export interface DatasourcePlus extends IntegrationBase { // if the datasource supports the use of bindings directly (to protect against SQL injection) // this returns the format of the identifier getBindingIdentifier(): string getStringConcat(parts: string[]): string - query(json: QueryJson): DatasourcePlusQueryResponse buildSchema( datasourceId: string, entities: Record diff --git a/packages/types/src/sdk/search.ts b/packages/types/src/sdk/search.ts index 67c344d845..35fd148c05 100644 --- a/packages/types/src/sdk/search.ts +++ b/packages/types/src/sdk/search.ts @@ -94,7 +94,6 @@ export interface QueryJson { idFilter?: SearchFilters } relationships?: RelationshipsJson[] - tableAliases?: Record } export interface SqlQuery { diff --git a/yarn.lock b/yarn.lock index 260ae3870a..2c367e469b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1097,7 +1097,7 @@ "@babel/highlight@^7.23.4": version "7.23.4" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" - integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + integrity "sha1-7arfTYIy4alhQy23hQkSB+rQYhs= sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==" dependencies: "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" @@ -1988,14 +1988,14 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.10.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.21.0": +"@babel/runtime@^7.10.5": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== dependencies: regenerator-runtime "^0.14.0" -"@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.15.4", "@babel/runtime@^7.21.0", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.23.8" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.8.tgz#8ee6fe1ac47add7122902f257b8ddf55c898f650" integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== @@ -3419,9 +3419,9 @@ tar "^6.1.11" "@mongodb-js/saslprep@^1.1.0": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.4.tgz#24ec1c4915a65f5c506bb88c081731450d91bb1c" - integrity sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw== + version "1.1.1" + resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz#9a6c2516bc9188672c4d953ec99760ba49970da7" + integrity sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ== dependencies: sparse-bitfield "^3.0.3" @@ -4012,70 +4012,70 @@ estree-walker "^2.0.2" picomatch "^2.3.1" -"@rollup/rollup-android-arm-eabi@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz#38c3abd1955a3c21d492af6b1a1dca4bb1d894d6" - integrity sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w== +"@rollup/rollup-android-arm-eabi@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.10.0.tgz#786eaf6372be2fc209cc957c14aa9d3ff8fefe6a" + integrity sha512-/MeDQmcD96nVoRumKUljsYOLqfv1YFJps+0pTrb2Z9Nl/w5qNUysMaWQsrd1mvAlNT4yza1iVyIu4Q4AgF6V3A== -"@rollup/rollup-android-arm64@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz#3822e929f415627609e53b11cec9a4be806de0e2" - integrity sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ== +"@rollup/rollup-android-arm64@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.10.0.tgz#0114a042fd6396f4f3233e6171fd5b61a36ed539" + integrity sha512-lvu0jK97mZDJdpZKDnZI93I0Om8lSDaiPx3OiCk0RXn3E8CMPJNS/wxjAvSJJzhhZpfjXsjLWL8LnS6qET4VNQ== -"@rollup/rollup-darwin-arm64@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz#6c082de71f481f57df6cfa3701ab2a7afde96f69" - integrity sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ== +"@rollup/rollup-darwin-arm64@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.10.0.tgz#944d007c1dc71a8c9174d11671c0c34bd74a2c81" + integrity sha512-uFpayx8I8tyOvDkD7X6n0PriDRWxcqEjqgtlxnUA/G9oS93ur9aZ8c8BEpzFmsed1TH5WZNG5IONB8IiW90TQg== -"@rollup/rollup-darwin-x64@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz#c34ca0d31f3c46a22c9afa0e944403eea0edcfd8" - integrity sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg== +"@rollup/rollup-darwin-x64@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.10.0.tgz#1d08cb4521a058d7736ab1c7fe988daf034a2598" + integrity sha512-nIdCX03qFKoR/MwQegQBK+qZoSpO3LESurVAC6s6jazLA1Mpmgzo3Nj3H1vydXp/JM29bkCiuF7tDuToj4+U9Q== -"@rollup/rollup-linux-arm-gnueabihf@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz#48e899c1e438629c072889b824a98787a7c2362d" - integrity sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA== +"@rollup/rollup-linux-arm-gnueabihf@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.10.0.tgz#4763eec1591bf0e99a54ad3d1ef39cb268ed7b19" + integrity sha512-Fz7a+y5sYhYZMQFRkOyCs4PLhICAnxRX/GnWYReaAoruUzuRtcf+Qnw+T0CoAWbHCuz2gBUwmWnUgQ67fb3FYw== -"@rollup/rollup-linux-arm64-gnu@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz#788c2698a119dc229062d40da6ada8a090a73a68" - integrity sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA== +"@rollup/rollup-linux-arm64-gnu@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.10.0.tgz#e6dae70c53ace836973526c41803b877cffc6f7b" + integrity sha512-yPtF9jIix88orwfTi0lJiqINnlWo6p93MtZEoaehZnmCzEmLL0eqjA3eGVeyQhMtxdV+Mlsgfwhh0+M/k1/V7Q== -"@rollup/rollup-linux-arm64-musl@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz#3882a4e3a564af9e55804beeb67076857b035ab7" - integrity sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ== +"@rollup/rollup-linux-arm64-musl@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.10.0.tgz#5692e1a0feba0cc4a933864961afc3211177d242" + integrity sha512-9GW9yA30ib+vfFiwjX+N7PnjTnCMiUffhWj4vkG4ukYv1kJ4T9gHNg8zw+ChsOccM27G9yXrEtMScf1LaCuoWQ== -"@rollup/rollup-linux-riscv64-gnu@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz#0c6ad792e1195c12bfae634425a3d2aa0fe93ab7" - integrity sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw== +"@rollup/rollup-linux-riscv64-gnu@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.10.0.tgz#fbe3d80f7a7ac54a8847f5bddd1bc6f7b9ccb65f" + integrity sha512-X1ES+V4bMq2ws5fF4zHornxebNxMXye0ZZjUrzOrf7UMx1d6wMQtfcchZ8SqUnQPPHdOyOLW6fTcUiFgHFadRA== -"@rollup/rollup-linux-x64-gnu@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz#9d62485ea0f18d8674033b57aa14fb758f6ec6e3" - integrity sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA== +"@rollup/rollup-linux-x64-gnu@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.10.0.tgz#3f06b55ccf173446d390d0306643dff62ec99807" + integrity sha512-w/5OpT2EnI/Xvypw4FIhV34jmNqU5PZjZue2l2Y3ty1Ootm3SqhI+AmfhlUYGBTd9JnpneZCDnt3uNOiOBkMyw== -"@rollup/rollup-linux-x64-musl@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz#50e8167e28b33c977c1f813def2b2074d1435e05" - integrity sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw== +"@rollup/rollup-linux-x64-musl@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.10.0.tgz#e4ac9b27041c83d7faab6205f62763103eb317ba" + integrity sha512-q/meftEe3QlwQiGYxD9rWwB21DoKQ9Q8wA40of/of6yGHhZuGfZO0c3WYkN9dNlopHlNT3mf5BPsUSxoPuVQaw== -"@rollup/rollup-win32-arm64-msvc@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz#68d233272a2004429124494121a42c4aebdc5b8e" - integrity sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw== +"@rollup/rollup-win32-arm64-msvc@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.10.0.tgz#6ad0d4fb0066f240778ee3f61eecf7aa0357f883" + integrity sha512-NrR6667wlUfP0BHaEIKgYM/2va+Oj+RjZSASbBMnszM9k+1AmliRjHc3lJIiOehtSSjqYiO7R6KLNrWOX+YNSQ== -"@rollup/rollup-win32-ia32-msvc@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz#366ca62221d1689e3b55a03f4ae12ae9ba595d40" - integrity sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA== +"@rollup/rollup-win32-ia32-msvc@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.10.0.tgz#29d50292381311cc8d3623e73b427b7e2e40a653" + integrity sha512-FV0Tpt84LPYDduIDcXvEC7HKtyXxdvhdAOvOeWMWbQNulxViH2O07QXkT/FffX4FqEI02jEbCJbr+YcuKdyyMg== -"@rollup/rollup-win32-x64-msvc@4.12.0": - version "4.12.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz#9ffdf9ed133a7464f4ae187eb9e1294413fab235" - integrity sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg== +"@rollup/rollup-win32-x64-msvc@4.10.0": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.10.0.tgz#4eedd01af3a82c1acb0fe6d837ebf339c4cbf839" + integrity sha512-OZoJd+o5TaTSQeFFQ6WjFCiltiYVjIdsXxwu/XZ8qRpsvMQr4UsVrE5UyT9RIvsnuF47DqkJKhhVZ2Q9YW9IpQ== "@roxi/routify@2.18.0": version "2.18.0" @@ -5219,16 +5219,16 @@ integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== "@types/chai-subset@^1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@types/chai-subset/-/chai-subset-1.3.3.tgz#97893814e92abd2c534de422cb377e0e0bdaac94" - integrity sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw== + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/chai-subset/-/chai-subset-1.3.5.tgz#3fc044451f26985f45625230a7f22284808b0a9a" + integrity sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A== dependencies: "@types/chai" "*" "@types/chai@*", "@types/chai@^4.3.4": - version "4.3.9" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.9.tgz#144d762491967db8c6dea38e03d2206c2623feec" - integrity sha512-69TtiDzu0bcmKQv3yg1Zx409/Kd7r0b5F1PfpYJfSHzLGtB53547V4u+9iqKYsTu/O2ai6KTb0TInNpvuQ3qmg== + version "4.3.11" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.11.tgz#e95050bf79a932cb7305dd130254ccdf9bde671c" + integrity sha512-qQR1dr2rGIHYlJulmr8Ioq3De0Le9E4MJ5AiaeAETJJpndT1uUNHsGFK3L/UIu+rbkQSdj8J/w2bCsBZc/Y5fQ== "@types/chance@1.1.3": version "1.1.3" @@ -5623,10 +5623,10 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*", "@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.13.4", "@types/node@>=13.7.0": - version "20.10.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.7.tgz#40fe8faf25418a75de9fe68a8775546732a3a901" - integrity sha512-fRbIKb8C/Y2lXxB5eVMj4IU7xpdox0Lh8bUPEdtLysaylsml1hOOx1+STloRs/B9nf7C6kPRmmg/V7aQW7usNg== +"@types/node@*", "@types/node@>=10.0.0", "@types/node@>=12.12.47", "@types/node@>=13.13.4", "@types/node@>=13.7.0", "@types/node@>=8.1.0": + version "20.11.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.2.tgz#39cea3fe02fbbc2f80ed283e94e1d24f2d3856fb" + integrity sha512-cZShBaVa+UO1LjWWBPmWRR4+/eY/JR/UIEcDlVsw3okjWEu+rB7/mH6X3B/L+qJVHDLjk9QW/y2upp9wp1yDXA== dependencies: undici-types "~5.26.4" @@ -5652,17 +5652,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.37.tgz#0bfcd173e8e1e328337473a8317e37b3b14fd30d" integrity sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg== -"@types/node@>=8.1.0": - version "20.11.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.10.tgz#6c3de8974d65c362f82ee29db6b5adf4205462f9" - integrity sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg== - dependencies: - undici-types "~5.26.4" - "@types/node@^18.11.18": - version "18.19.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.10.tgz#4de314ab66faf6bc8ba691021a091ddcdf13a158" - integrity sha512-IZD8kAM02AW1HRDTPOlz3npFava678pr8Ie9Vp8uRhBROXAv8MXT2pCnGZZAKYdromsNQLHQcfWQ6EOatVLtqA== + version "18.19.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.13.tgz#c3e989ca967b862a1f6c8c4148fe31865eedaf1a" + integrity sha512-kgnbRDj8ioDyGxoiaXsiu1Ybm/K14ajCgMOkwiqpHrnF7d7QiYRoRqHIpglMMs3DwXinlK4qJ8TZGlj4hfleJg== dependencies: undici-types "~5.26.4" @@ -6082,9 +6075,9 @@ integrity sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog== "@types/whatwg-url@^11.0.2": - version "11.0.4" - resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-11.0.4.tgz#ffed0dc8d89d91f62e3f368fcbda222a487c4f63" - integrity sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw== + version "11.0.3" + resolved "https://registry.yarnpkg.com/@types/whatwg-url/-/whatwg-url-11.0.3.tgz#9f584c9a9421f0971029ee504dd62a831cb8f3aa" + integrity sha512-z1ELvMijRL1QmU7QuzDkeYXSF2+dXI0ITKoQsIoVKcNBOiK5RMmWy+pYYxJTHFt8vkpZe7UsvRErQwcxZkjoUw== dependencies: "@types/webidl-conversions" "*" @@ -6534,11 +6527,16 @@ acorn-walk@^7.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn-walk@^8.0.2, acorn-walk@^8.1.1, acorn-walk@^8.2.0: +acorn-walk@^8.0.2, acorn-walk@^8.1.1: version "8.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== +acorn-walk@^8.2.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" + integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== + acorn@^5.2.1, acorn@^5.7.3: version "5.7.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e" @@ -6549,10 +6547,10 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.1.0, acorn@^8.10.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: - version "8.11.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" - integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== +acorn@^8.1.0, acorn@^8.10.0, acorn@^8.11.3, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== add-stream@^1.0.0: version "1.0.0" @@ -6994,7 +6992,7 @@ asn1.js@^5.0.0, asn1.js@^5.2.0, asn1.js@^5.4.1: minimalistic-assert "^1.0.0" safer-buffer "^2.1.0" -asn1@^0.2.4, asn1@^0.2.6, asn1@~0.2.3: +asn1@^0.2.6, asn1@~0.2.3: version "0.2.6" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== @@ -7045,12 +7043,7 @@ async@^2.6.3: dependencies: lodash "^4.17.14" -async@^3.2.1, async@^3.2.3: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - -async@^3.2.4: +async@^3.2.1, async@^3.2.3, async@^3.2.4: version "3.2.5" resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== @@ -7653,11 +7646,6 @@ bufferutil@^4.0.1: dependencies: node-gyp-build "^4.3.0" -buildcheck@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.3.tgz#70451897a95d80f7807e68fc412eb2e7e35ff4d5" - integrity sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA== - buildcheck@~0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238" @@ -7922,9 +7910,9 @@ catharsis@^0.9.0: lodash "^4.17.15" chai@^4.3.7: - version "4.3.10" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" - integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g== + version "4.4.1" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" + integrity sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g== dependencies: assertion-error "^1.1.0" check-error "^1.0.3" @@ -8666,14 +8654,6 @@ cosmiconfig@^8.2.0: parse-json "^5.0.0" path-type "^4.0.0" -cpu-features@~0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.4.tgz#0023475bb4f4c525869c162e4108099e35bf19d8" - integrity sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A== - dependencies: - buildcheck "0.0.3" - nan "^2.15.0" - cpu-features@~0.0.9: version "0.0.9" resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.9.tgz#5226b92f0f1c63122b0a3eb84cb8335a4de499fc" @@ -9573,9 +9553,9 @@ diff@^4.0.1: integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== diff@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" - integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + version "5.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== diffie-hellman@^5.0.0: version "5.0.3" @@ -9631,16 +9611,7 @@ docker-modem@^3.0.0: split-ca "^1.0.1" ssh2 "^1.11.0" -dockerode@^3.2.1: - version "3.3.4" - resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-3.3.4.tgz#875de614a1be797279caa9fe27e5637cf0e40548" - integrity sha512-3EUwuXnCU+RUlQEheDjmBE0B7q66PV9Rw5NiH1sXwINq0M9c5ERP9fxgkw36ZHOtzf4AGEEYySnkx/sACC9EgQ== - dependencies: - "@balena/dockerignore" "^1.0.2" - docker-modem "^3.0.0" - tar-fs "~2.0.1" - -dockerode@^3.3.5: +dockerode@^3.2.1, dockerode@^3.3.5: version "3.3.5" resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-3.3.5.tgz#7ae3f40f2bec53ae5e9a741ce655fff459745629" integrity sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA== @@ -9770,9 +9741,9 @@ dotenv@8.6.0, dotenv@^8.2.0: integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== dotenv@^16.3.1: - version "16.4.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.1.tgz#1d9931f1d3e5d2959350d1250efab299561f7f11" - integrity sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ== + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== dotenv@~10.0.0: version "10.0.0" @@ -10820,20 +10791,13 @@ fast-xml-parser@4.2.5: dependencies: strnum "^1.0.5" -fast-xml-parser@^4.1.3: +fast-xml-parser@^4.1.3, fast-xml-parser@^4.2.2, fast-xml-parser@^4.2.5: version "4.3.3" resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.3.3.tgz#aeaf5778392329f17168c40c51bcbfec8ff965be" integrity sha512-coV/D1MhrShMvU6D0I+VAK3umz6hUaxxhL0yp/9RjfiYUfAv14rDhGQL+PLForhMdr0wq3PiV07WtkkNjJjNHg== dependencies: strnum "^1.0.5" -fast-xml-parser@^4.2.2, fast-xml-parser@^4.2.5: - version "4.3.2" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.3.2.tgz#761e641260706d6e13251c4ef8e3f5694d4b0d79" - integrity "sha1-dh5kEmBwbW4TJRxO+OP1aU1LDXk= sha512-rmrXUXwbJedoXkStenj1kkljNF7ugn5ZjR9FJcwmCfcCbtOMDghPajbc+Tck6vE6F5XsDmx+Pr2le9fw8+pXBg==" - dependencies: - strnum "^1.0.5" - fastest-levenshtein@^1.0.12: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" @@ -10893,7 +10857,7 @@ fetch-cookie@0.11.0: dependencies: tough-cookie "^2.3.3 || ^3.0.1 || ^4.0.0" -fflate@^0.4.1, fflate@^0.4.8: +fflate@^0.4.1: version "0.4.8" resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.4.8.tgz#f90b82aefbd8ac174213abb338bd7ef848f0f5ae" integrity sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA== @@ -15642,7 +15606,17 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mlly@^1.1.0, mlly@^1.2.0: +mlly@^1.1.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.6.0.tgz#0ecfbddc706857f5e170ccd28c6b0b9c81d3f548" + integrity sha512-YOvg9hfYQmnaB56Yb+KrJE2u0Yzz5zR+sLejEvF4fzwzV1Al6hkf2vyHTwqCRyv0hCi9rVCqVoXpyYevQIRwLQ== + dependencies: + acorn "^8.11.3" + pathe "^1.1.2" + pkg-types "^1.0.3" + ufo "^1.3.2" + +mlly@^1.2.0: version "1.4.2" resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.4.2.tgz#7cf406aa319ff6563d25da6b36610a93f2a8007e" integrity sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg== @@ -15835,11 +15809,6 @@ named-placeholders@^1.1.3: dependencies: lru-cache "^7.14.1" -nan@^2.15.0, nan@^2.16.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - nan@^2.17.0, nan@^2.18.0: version "2.18.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" @@ -17202,6 +17171,11 @@ pathe@^1.1.0, pathe@^1.1.1: resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== +pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== + pathval@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" @@ -17826,18 +17800,10 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" -posthog-js@^1.13.4: - version "1.103.1" - resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.103.1.tgz#f846c413c28aca204dc1527f49d39f651348f3c4" - integrity sha512-cFXFU4Z4kl/+RUUV4ju1DlfM7dwCGi6H9xWsfhljIhGcBbT8UfS4JGgZGXl9ABQDdgDPb9xciqnysFSsUQshTA== - dependencies: - fflate "^0.4.8" - preact "^10.19.3" - -posthog-js@^1.36.0: - version "1.96.1" - resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.96.1.tgz#4f9719a24e4e14037b0e72d430194d7cdb576447" - integrity sha512-kv1vQqYMt2BV3YHS+wxsbGuP+tz+M3y1AzNhz8TfkpY1HT8W/ONT0i0eQpeRr9Y+d4x/fZ6M4cXG5GMvi9lRCA== +posthog-js@^1.13.4, posthog-js@^1.36.0: + version "1.100.0" + resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.100.0.tgz#687b9a6e4ed226aa6572f4040b418ea0c8b3d353" + integrity sha512-r2XZEiHQ9mBK7D1G9k57I8uYZ2kZTAJ0OCX6K/OOdCWN8jKPhw3h5F9No5weilP6eVAn+hrsy7NvPV7SCX7gMg== dependencies: fflate "^0.4.1" @@ -18078,11 +18044,6 @@ pprof-format@^2.0.7: resolved "https://registry.yarnpkg.com/pprof-format/-/pprof-format-2.0.7.tgz#526e4361f8b37d16b2ec4bb0696b5292de5046a4" integrity sha512-1qWaGAzwMpaXJP9opRa23nPnt2Egi7RMNoNBptEE/XwHbcn4fC2b/4U4bKc5arkGkIh2ZabpF2bEb+c5GNHEKA== -preact@^10.19.3: - version "10.19.3" - resolved "https://registry.yarnpkg.com/preact/-/preact-10.19.3.tgz#7a7107ed2598a60676c943709ea3efb8aaafa899" - integrity sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ== - prebuild-install@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" @@ -19298,25 +19259,25 @@ rollup@^3.27.1: fsevents "~2.3.2" rollup@^4.9.6: - version "4.12.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.12.0.tgz#0b6d1e5f3d46bbcf244deec41a7421dc54cc45b5" - integrity sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q== + version "4.10.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.10.0.tgz#244c2cb54a8de004a949fe6036a0801be9060456" + integrity sha512-t2v9G2AKxcQ8yrG+WGxctBes1AomT0M4ND7jTFBCVPXQ/WFTvNSefIrNSmLKhIKBrvN8SG+CZslimJcT3W2u2g== dependencies: "@types/estree" "1.0.5" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.12.0" - "@rollup/rollup-android-arm64" "4.12.0" - "@rollup/rollup-darwin-arm64" "4.12.0" - "@rollup/rollup-darwin-x64" "4.12.0" - "@rollup/rollup-linux-arm-gnueabihf" "4.12.0" - "@rollup/rollup-linux-arm64-gnu" "4.12.0" - "@rollup/rollup-linux-arm64-musl" "4.12.0" - "@rollup/rollup-linux-riscv64-gnu" "4.12.0" - "@rollup/rollup-linux-x64-gnu" "4.12.0" - "@rollup/rollup-linux-x64-musl" "4.12.0" - "@rollup/rollup-win32-arm64-msvc" "4.12.0" - "@rollup/rollup-win32-ia32-msvc" "4.12.0" - "@rollup/rollup-win32-x64-msvc" "4.12.0" + "@rollup/rollup-android-arm-eabi" "4.10.0" + "@rollup/rollup-android-arm64" "4.10.0" + "@rollup/rollup-darwin-arm64" "4.10.0" + "@rollup/rollup-darwin-x64" "4.10.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.10.0" + "@rollup/rollup-linux-arm64-gnu" "4.10.0" + "@rollup/rollup-linux-arm64-musl" "4.10.0" + "@rollup/rollup-linux-riscv64-gnu" "4.10.0" + "@rollup/rollup-linux-x64-gnu" "4.10.0" + "@rollup/rollup-linux-x64-musl" "4.10.0" + "@rollup/rollup-win32-arm64-msvc" "4.10.0" + "@rollup/rollup-win32-ia32-msvc" "4.10.0" + "@rollup/rollup-win32-x64-msvc" "4.10.0" fsevents "~2.3.2" rotating-file-stream@3.1.0: @@ -19348,14 +19309,7 @@ rxjs@^6.6.6: dependencies: tslib "^1.9.0" -rxjs@^7.5.5: - version "7.8.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" - integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== - dependencies: - tslib "^2.1.0" - -rxjs@^7.8.1: +rxjs@^7.5.5, rxjs@^7.8.1: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== @@ -20049,18 +20003,7 @@ ssh-remote-port-forward@^1.0.4: "@types/ssh2" "^0.5.48" ssh2 "^1.4.0" -ssh2@^1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.11.0.tgz#ce60186216971e12f6deb553dcf82322498fe2e4" - integrity sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw== - dependencies: - asn1 "^0.2.4" - bcrypt-pbkdf "^1.0.2" - optionalDependencies: - cpu-features "~0.0.4" - nan "^2.16.0" - -ssh2@^1.4.0: +ssh2@^1.11.0, ssh2@^1.4.0: version "1.15.0" resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.15.0.tgz#2f998455036a7f89e0df5847efb5421748d9871b" integrity sha512-C0PHgX4h6lBxYx7hcXwu3QWdh4tg6tZZsTfXcdvc5caW/EMxaB4H9dWsl7qk+F7LAW762hp8VbXOX7x4xUYvEw== @@ -20138,9 +20081,9 @@ statuses@2.0.1, statuses@^2.0.0: integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== std-env@^3.3.1: - version "3.4.3" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.4.3.tgz#326f11db518db751c83fd58574f449b7c3060910" - integrity sha512-f9aPhy8fYBuMN+sNfakZV18U39PbalgjXG3lLB9WkaYTxijru61wb57V9wxxNthXM5Sd88ETBWi29qLAsHO52Q== + version "3.7.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" + integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== step@0.0.x: version "0.0.6" @@ -20603,9 +20546,9 @@ svelte-spa-router@^4.0.1: regexparam "2.0.2" svelte@^4.2.10: - version "4.2.12" - resolved "https://registry.yarnpkg.com/svelte/-/svelte-4.2.12.tgz#13d98d2274d24d3ad216c8fdc801511171c70bb1" - integrity sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug== + version "4.2.10" + resolved "https://registry.yarnpkg.com/svelte/-/svelte-4.2.10.tgz#3bef8d79ca75eb53cc4d03f9fac1546e60393f77" + integrity sha512-Ep06yCaCdgG1Mafb/Rx8sJ1QS3RW2I2BxGp2Ui9LBHSZ2/tO/aGLc5WqPjgiAP6KAnLJGaIr/zzwQlOo1b8MxA== dependencies: "@ampproject/remapping" "^2.2.1" "@jridgewell/sourcemap-codec" "^1.4.15" @@ -21015,9 +20958,9 @@ tiny-queue@^0.2.0: integrity sha512-EijGsv7kzd9I9g0ByCl6h42BWNGUZrlCSejfrb3AKeHC33SGbASu1VDf5O3rRiiUOhAC9CHdZxFPbZu0HmR70A== tinybench@^2.3.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.5.1.tgz#3408f6552125e53a5a48adee31261686fd71587e" - integrity sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg== + version "2.6.0" + resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.6.0.tgz#1423284ee22de07c91b3752c048d2764714b341b" + integrity sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA== tinycolor2@^1.6.0: version "1.6.0" @@ -21457,6 +21400,11 @@ ufo@^1.3.0: resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.1.tgz#e085842f4627c41d4c1b60ebea1f75cdab4ce86b" integrity sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw== +ufo@^1.3.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.4.0.tgz#39845b31be81b4f319ab1d99fd20c56cac528d32" + integrity sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ== + uglify-js@^3.1.4, uglify-js@^3.7.7: version "3.17.4" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" @@ -21501,9 +21449,9 @@ underscore@~1.13.2: integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== undici-types@^6.0.1: - version "6.6.2" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.6.2.tgz#48c65d30bfcae492c3c89b1d147fed9d43a16b79" - integrity sha512-acoBcoBobgsg3YUEO/Oht8JJCuFYpzWLFKbqEbcEZcXdkQrTzkF/yWj9JoLaFDa6ArI31dFEmNZkCjQZ7mlf7w== + version "6.0.1" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.0.1.tgz#62e2af9fcd3ce359634175658de39df8d0f37197" + integrity sha512-i9dNdkCziyqGpFxhatR9LITcInbFWh+ExlWkrZQpZHje8FfCcJKgps0IbmMd7D1o8c8syG4pIOV+aKIoC9JEyA== undici-types@~5.26.4: version "5.26.5" @@ -21516,9 +21464,9 @@ undici@^4.14.1: integrity sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw== undici@^6.0.1: - version "6.6.2" - resolved "https://registry.yarnpkg.com/undici/-/undici-6.6.2.tgz#8dce5ae54e8a3bc7140c2b2a0972b5fde9a88efb" - integrity sha512-vSqvUE5skSxQJ5sztTZ/CdeJb1Wq0Hf44hlYMciqHghvz+K88U0l7D6u1VsndoFgskDcnU+nG3gYmMzJVzd9Qg== + version "6.0.1" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.0.1.tgz#385572addca36d1c2b280629cb694b726170027e" + integrity sha512-eZFYQLeS9BiXpsU0cuFhCwfeda2MnC48EVmmOz/eCjsTgmyTdaHdVsPSC/kwC2GtW2e0uH0HIPbadf3/bRWSxw== dependencies: "@fastify/busboy" "^2.0.0" @@ -21842,7 +21790,18 @@ vite-plugin-static-copy@^0.17.0: fs-extra "^11.1.0" picocolors "^1.0.0" -"vite@^3.0.0 || ^4.0.0", vite@^4.5.0: +"vite@^3.0.0 || ^4.0.0": + version "4.5.2" + resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.2.tgz#d6ea8610e099851dad8c7371599969e0f8b97e82" + integrity sha512-tBCZBNSBbHQkaGyhGCDUGqeo2ph8Fstyp6FMSvTtsXeZSPpSMGlviAOav2hxVTqFcx8Hj/twtWKsMJXNY0xI8w== + dependencies: + esbuild "^0.18.10" + postcss "^8.4.27" + rollup "^3.27.1" + optionalDependencies: + fsevents "~2.3.2" + +vite@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/vite/-/vite-4.5.0.tgz#ec406295b4167ac3bc23e26f9c8ff559287cff26" integrity sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw== @@ -22476,12 +22435,7 @@ yaml@^1.10.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yaml@^2.1.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.2.tgz#f522db4313c671a0ca963a75670f1c12ea909144" - integrity sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg== - -yaml@^2.2.2: +yaml@^2.1.1, yaml@^2.2.2: version "2.3.4" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==