@budibase/backend-core 3.2.14 → 3.2.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -25669,7 +25669,7 @@ function isIgnoredType(type) {
25669
25669
  const ignored = ["link" /* LINK */, "formula" /* FORMULA */, "ai" /* AI */];
25670
25670
  return ignored.indexOf(type) !== -1;
25671
25671
  }
25672
- function generateSchema(schema, table, tables, oldTable = null, renamed) {
25672
+ function generateSchema(schema, table, tables, oldTable, renamed) {
25673
25673
  let primaryKeys = table && table.primary ? table.primary : [];
25674
25674
  const columns = Object.values(table.schema);
25675
25675
  let metaCols = columns.filter((col) => col.meta);
@@ -25689,7 +25689,7 @@ function generateSchema(schema, table, tables, oldTable = null, renamed) {
25689
25689
  (col) => col.foreignKey
25690
25690
  );
25691
25691
  for (let [key, column] of Object.entries(table.schema)) {
25692
- const oldColumn = oldTable ? oldTable.schema[key] : null;
25692
+ const oldColumn = oldTable?.schema[key];
25693
25693
  if (oldColumn && oldColumn.type || columnTypeSet.includes(key) || renamed?.updated === key) {
25694
25694
  continue;
25695
25695
  }
@@ -25829,16 +25829,15 @@ var SqlTableQueryBuilder = class {
25829
25829
  * @return the operation that was found in the JSON.
25830
25830
  */
25831
25831
  _operation(json) {
25832
- return json.endpoint.operation;
25832
+ return json.operation;
25833
25833
  }
25834
25834
  _tableQuery(json) {
25835
25835
  let client = (0, import_knex.knex)({ client: this.sqlClient }).schema;
25836
- let schemaName = json?.endpoint?.schema;
25837
- if (schemaName) {
25838
- client = client.withSchema(schemaName);
25836
+ if (json?.schema) {
25837
+ client = client.withSchema(json.schema);
25839
25838
  }
25840
25839
  let query;
25841
- if (!json.table || !json.meta || !json.meta.tables) {
25840
+ if (!json.table || !json.tables) {
25842
25841
  throw new Error("Cannot execute without table being specified");
25843
25842
  }
25844
25843
  if (json.table.sourceType === "internal" /* INTERNAL */) {
@@ -25846,15 +25845,15 @@ var SqlTableQueryBuilder = class {
25846
25845
  }
25847
25846
  switch (this._operation(json)) {
25848
25847
  case "CREATE_TABLE" /* CREATE_TABLE */:
25849
- query = buildCreateTable(client, json.table, json.meta.tables);
25848
+ query = buildCreateTable(client, json.table, json.tables);
25850
25849
  break;
25851
25850
  case "UPDATE_TABLE" /* UPDATE_TABLE */:
25852
- if (!json.meta || !json.meta.table) {
25851
+ if (!json.table) {
25853
25852
  throw new Error("Must specify old table for update");
25854
25853
  }
25855
- if (this.sqlClient === "mysql2" /* MY_SQL */ && json.meta.renamed) {
25854
+ if (this.sqlClient === "mysql2" /* MY_SQL */ && json.meta?.renamed) {
25856
25855
  const updatedColumn = json.meta.renamed.updated;
25857
- const tableName = schemaName ? `\`${schemaName}\`.\`${json.table.name}\`` : `\`${json.table.name}\``;
25856
+ const tableName = json?.schema ? `\`${json.schema}\`.\`${json.table.name}\`` : `\`${json.table.name}\``;
25858
25857
  return {
25859
25858
  sql: `alter table ${tableName} rename column \`${json.meta.renamed.old}\` to \`${updatedColumn}\`;`,
25860
25859
  bindings: []
@@ -25863,14 +25862,14 @@ var SqlTableQueryBuilder = class {
25863
25862
  query = buildUpdateTable(
25864
25863
  client,
25865
25864
  json.table,
25866
- json.meta.tables,
25867
- json.meta.table,
25868
- json.meta.renamed
25865
+ json.tables,
25866
+ json.meta?.oldTable,
25867
+ json.meta?.renamed
25869
25868
  );
25870
- if (this.sqlClient === "mssql" /* MS_SQL */ && json.meta.renamed) {
25869
+ if (this.sqlClient === "mssql" /* MS_SQL */ && json.meta?.renamed) {
25871
25870
  const oldColumn = json.meta.renamed.old;
25872
25871
  const updatedColumn = json.meta.renamed.updated;
25873
- const tableName = schemaName ? `${schemaName}.${json.table.name}` : `${json.table.name}`;
25872
+ const tableName = json?.schema ? `${json.schema}.${json.table.name}` : `${json.table.name}`;
25874
25873
  const sql = getNativeSql(query);
25875
25874
  if (Array.isArray(sql)) {
25876
25875
  for (const query2 of sql) {
@@ -25981,11 +25980,11 @@ var InternalBuilder = class {
25981
25980
  this.knex = knex3;
25982
25981
  this.splitter = new filters_exports.ColumnSplitter([this.table], {
25983
25982
  aliases: this.query.tableAliases,
25984
- columnPrefix: this.query.meta.columnPrefix
25983
+ columnPrefix: this.query.meta?.columnPrefix
25985
25984
  });
25986
25985
  }
25987
25986
  get table() {
25988
- return this.query.meta.table;
25987
+ return this.query.table;
25989
25988
  }
25990
25989
  get knexClient() {
25991
25990
  return this.knex.client;
@@ -26074,8 +26073,7 @@ var InternalBuilder = class {
26074
26073
  return parts.join(".");
26075
26074
  }
26076
26075
  isFullSelectStatementRequired() {
26077
- const { meta } = this.query;
26078
- for (let column of Object.values(meta.table.schema)) {
26076
+ for (let column of Object.values(this.table.schema)) {
26079
26077
  if (this.SPECIAL_SELECT_CASES.POSTGRES_MONEY(column)) {
26080
26078
  return true;
26081
26079
  } else if (this.SPECIAL_SELECT_CASES.MSSQL_DATES(column)) {
@@ -26085,29 +26083,29 @@ var InternalBuilder = class {
26085
26083
  return false;
26086
26084
  }
26087
26085
  generateSelectStatement() {
26088
- const { meta, endpoint, resource } = this.query;
26086
+ const { table, resource } = this.query;
26089
26087
  if (!resource || !resource.fields || resource.fields.length === 0) {
26090
26088
  return "*";
26091
26089
  }
26092
- const alias = this.getTableName(endpoint.entityId);
26093
- const schema = meta.table.schema;
26090
+ const alias = this.getTableName(table);
26091
+ const schema = this.table.schema;
26094
26092
  if (!this.isFullSelectStatementRequired()) {
26095
26093
  return [this.knex.raw("??", [`${alias}.*`])];
26096
26094
  }
26097
26095
  return resource.fields.map((field) => {
26098
26096
  const parts = field.split(/\./g);
26099
- let table = void 0;
26097
+ let table2 = void 0;
26100
26098
  let column = parts[0];
26101
26099
  if (parts.length > 1) {
26102
- table = parts[0];
26100
+ table2 = parts[0];
26103
26101
  column = parts.slice(1).join(".");
26104
26102
  }
26105
- return { table, column, field };
26106
- }).filter(({ table }) => !table || table === alias).map(({ table, column, field }) => {
26103
+ return { table: table2, column, field };
26104
+ }).filter(({ table: table2 }) => !table2 || table2 === alias).map(({ table: table2, column, field }) => {
26107
26105
  const columnSchema = schema[column];
26108
26106
  if (this.SPECIAL_SELECT_CASES.POSTGRES_MONEY(columnSchema)) {
26109
26107
  return this.knex.raw(`??::money::numeric as ??`, [
26110
- this.rawQuotedIdentifier([table, column].join(".")),
26108
+ this.rawQuotedIdentifier([table2, column].join(".")),
26111
26109
  this.knex.raw(this.quote(field))
26112
26110
  ]);
26113
26111
  }
@@ -26117,8 +26115,8 @@ var InternalBuilder = class {
26117
26115
  this.knex.raw(this.quote(field))
26118
26116
  ]);
26119
26117
  }
26120
- if (table) {
26121
- return this.rawQuotedIdentifier(`${table}.${column}`);
26118
+ if (table2) {
26119
+ return this.rawQuotedIdentifier(`${table2}.${column}`);
26122
26120
  } else {
26123
26121
  return this.rawQuotedIdentifier(field);
26124
26122
  }
@@ -26249,9 +26247,8 @@ var InternalBuilder = class {
26249
26247
  return query.andWhere(`${document}.fieldName`, "=", relationship.column);
26250
26248
  }
26251
26249
  addRelationshipForFilter(query, allowEmptyRelationships2, filterKey, whereCb) {
26252
- const { relationships, endpoint, tableAliases: aliases } = this.query;
26253
- const tableName = endpoint.entityId;
26254
- const fromAlias = aliases?.[tableName] || tableName;
26250
+ const { relationships, schema, tableAliases: aliases, table } = this.query;
26251
+ const fromAlias = aliases?.[table.name] || table.name;
26255
26252
  const matches2 = (value) => filterKey.match(new RegExp(`^${value}\\.`));
26256
26253
  if (!relationships) {
26257
26254
  return query;
@@ -26278,7 +26275,7 @@ var InternalBuilder = class {
26278
26275
  const throughAlias = aliases?.[manyToMany.through] || relationship.through;
26279
26276
  let throughTable = this.tableNameWithSchema(manyToMany.through, {
26280
26277
  alias: throughAlias,
26281
- schema: endpoint.schema
26278
+ schema
26282
26279
  });
26283
26280
  subQuery = subQuery.innerJoin(throughTable, function() {
26284
26281
  this.on(
@@ -26659,22 +26656,8 @@ var InternalBuilder = class {
26659
26656
  isSqs() {
26660
26657
  return isSqs(this.table);
26661
26658
  }
26662
- getTableName(tableOrName) {
26663
- let table;
26664
- if (typeof tableOrName === "string") {
26665
- const name2 = tableOrName;
26666
- if (this.query.table?.name === name2) {
26667
- table = this.query.table;
26668
- } else if (this.query.meta.table?.name === name2) {
26669
- table = this.query.meta.table;
26670
- } else if (!this.query.meta.tables?.[name2]) {
26671
- return name2;
26672
- } else {
26673
- table = this.query.meta.tables[name2];
26674
- }
26675
- } else if (tableOrName) {
26676
- table = tableOrName;
26677
- } else {
26659
+ getTableName(table) {
26660
+ if (!table) {
26678
26661
  table = this.table;
26679
26662
  }
26680
26663
  let name = table.name;
@@ -26806,8 +26789,9 @@ var InternalBuilder = class {
26806
26789
  }
26807
26790
  return withSchema;
26808
26791
  }
26809
- buildJsonField(field) {
26792
+ buildJsonField(table, field) {
26810
26793
  const parts = field.split(".");
26794
+ let baseName = parts[parts.length - 1];
26811
26795
  let unaliased;
26812
26796
  let tableField;
26813
26797
  if (parts.length > 1) {
@@ -26818,8 +26802,15 @@ var InternalBuilder = class {
26818
26802
  unaliased = parts.join(".");
26819
26803
  tableField = unaliased;
26820
26804
  }
26821
- const separator = this.client === "oracledb" /* ORACLE */ ? " VALUE " : ",";
26822
- return this.knex.raw(`?${separator}??`, [unaliased, this.rawQuotedIdentifier(tableField)]).toString();
26805
+ if (this.query.meta?.columnPrefix) {
26806
+ baseName = baseName.replace(this.query.meta.columnPrefix, "");
26807
+ }
26808
+ let identifier = this.rawQuotedIdentifier(tableField);
26809
+ const schema = table.schema[baseName];
26810
+ if (schema && schema.type === "bigint" /* BIGINT */) {
26811
+ identifier = this.castIntToString(identifier);
26812
+ }
26813
+ return [unaliased, identifier];
26823
26814
  }
26824
26815
  maxFunctionParameters() {
26825
26816
  switch (this.client) {
@@ -26834,7 +26825,7 @@ var InternalBuilder = class {
26834
26825
  addJsonRelationships(query, fromTable, relationships) {
26835
26826
  const sqlClient = this.client;
26836
26827
  const knex3 = this.knex;
26837
- const { resource, tableAliases: aliases, endpoint, meta } = this.query;
26828
+ const { resource, tableAliases: aliases, schema, tables } = this.query;
26838
26829
  const fields = resource?.fields || [];
26839
26830
  for (let relationship of relationships) {
26840
26831
  const {
@@ -26848,11 +26839,14 @@ var InternalBuilder = class {
26848
26839
  if (!toTable || !fromTable) {
26849
26840
  continue;
26850
26841
  }
26851
- const relatedTable = meta.tables?.[toTable];
26842
+ const relatedTable = tables[toTable];
26843
+ if (!relatedTable) {
26844
+ throw new Error(`related table "${toTable}" not found in datasource`);
26845
+ }
26852
26846
  const toAlias = aliases?.[toTable] || toTable, fromAlias = aliases?.[fromTable] || fromTable, throughAlias = throughTable && aliases?.[throughTable] || throughTable;
26853
26847
  let toTableWithSchema = this.tableNameWithSchema(toTable, {
26854
26848
  alias: toAlias,
26855
- schema: endpoint.schema
26849
+ schema
26856
26850
  });
26857
26851
  const requiredFields = [
26858
26852
  ...relatedTable?.primary || [],
@@ -26866,7 +26860,13 @@ var InternalBuilder = class {
26866
26860
  0,
26867
26861
  Math.floor(this.maxFunctionParameters() / 2)
26868
26862
  );
26869
- const fieldList = relationshipFields.map((field) => this.buildJsonField(field)).join(",");
26863
+ const fieldList = relationshipFields.map(
26864
+ (field) => this.buildJsonField(relatedTable, field)
26865
+ );
26866
+ const fieldListFormatted = fieldList.map((f) => {
26867
+ const separator = this.client === "oracledb" /* ORACLE */ ? " VALUE " : ",";
26868
+ return this.knex.raw(`?${separator}??`, [f[0], f[1]]).toString();
26869
+ }).join(",");
26870
26870
  const primaryKey = `${toAlias}.${toPrimary || toKey}`;
26871
26871
  let subQuery = knex3.from(toTableWithSchema).orderBy(primaryKey);
26872
26872
  const isManyToMany = throughTable && toPrimary && fromPrimary;
@@ -26874,7 +26874,7 @@ var InternalBuilder = class {
26874
26874
  if (isManyToMany) {
26875
26875
  let throughTableWithSchema = this.tableNameWithSchema(throughTable, {
26876
26876
  alias: throughAlias,
26877
- schema: endpoint.schema
26877
+ schema
26878
26878
  });
26879
26879
  subQuery = subQuery.join(throughTableWithSchema, function() {
26880
26880
  this.on(`${toAlias}.${toPrimary}`, "=", `${throughAlias}.${toKey}`);
@@ -26896,30 +26896,36 @@ var InternalBuilder = class {
26896
26896
  case "sqlite3" /* SQL_LITE */:
26897
26897
  subQuery = this.addJoinFieldCheck(subQuery, relationship);
26898
26898
  wrapperQuery = standardWrap(
26899
- this.knex.raw(`json_group_array(json_object(${fieldList}))`)
26899
+ this.knex.raw(
26900
+ `json_group_array(json_object(${fieldListFormatted}))`
26901
+ )
26900
26902
  );
26901
26903
  break;
26902
26904
  case "pg" /* POSTGRES */:
26903
26905
  wrapperQuery = standardWrap(
26904
- this.knex.raw(`json_agg(json_build_object(${fieldList}))`)
26906
+ this.knex.raw(`json_agg(json_build_object(${fieldListFormatted}))`)
26905
26907
  );
26906
26908
  break;
26907
26909
  case "mariadb" /* MARIADB */:
26908
26910
  wrapperQuery = subQuery.select(
26909
26911
  knex3.raw(
26910
- `json_arrayagg(json_object(${fieldList}) LIMIT ${getRelationshipLimit()})`
26912
+ `json_arrayagg(json_object(${fieldListFormatted}) LIMIT ${getRelationshipLimit()})`
26911
26913
  )
26912
26914
  );
26913
26915
  break;
26914
26916
  case "mysql2" /* MY_SQL */:
26915
26917
  case "oracledb" /* ORACLE */:
26916
26918
  wrapperQuery = standardWrap(
26917
- this.knex.raw(`json_arrayagg(json_object(${fieldList}))`)
26919
+ this.knex.raw(`json_arrayagg(json_object(${fieldListFormatted}))`)
26918
26920
  );
26919
26921
  break;
26920
26922
  case "mssql" /* MS_SQL */: {
26921
- const comparatorQuery = knex3.select(`${fromAlias}.*`).from({
26922
- [fromAlias]: subQuery.select(`${toAlias}.*`).limit(getRelationshipLimit())
26923
+ const comparatorQuery = knex3.select(`*`).from({
26924
+ [fromAlias]: subQuery.select(
26925
+ fieldList.map((f) => {
26926
+ return knex3.ref(f[1]).as(f[0]);
26927
+ })
26928
+ ).limit(getRelationshipLimit())
26923
26929
  });
26924
26930
  wrapperQuery = knex3.raw(
26925
26931
  `(SELECT ?? = (${comparatorQuery} FOR JSON PATH))`,
@@ -26935,8 +26941,7 @@ var InternalBuilder = class {
26935
26941
  return query;
26936
26942
  }
26937
26943
  addJoin(query, tables, columns) {
26938
- const { tableAliases: aliases, endpoint } = this.query;
26939
- const schema = endpoint.schema;
26944
+ const { tableAliases: aliases, schema } = this.query;
26940
26945
  const toTable = tables.to, fromTable = tables.from, throughTable = tables.through;
26941
26946
  const toAlias = aliases?.[toTable] || toTable, throughAlias = throughTable && aliases?.[throughTable] || throughTable, fromAlias = aliases?.[fromTable] || fromTable;
26942
26947
  let toTableWithSchema = this.tableNameWithSchema(toTable, {
@@ -26976,16 +26981,16 @@ var InternalBuilder = class {
26976
26981
  return query;
26977
26982
  }
26978
26983
  qualifiedKnex(opts) {
26979
- let alias = this.query.tableAliases?.[this.query.endpoint.entityId];
26984
+ let alias = this.query.tableAliases?.[this.query.table.name];
26980
26985
  if (opts?.alias === false) {
26981
26986
  alias = void 0;
26982
26987
  } else if (typeof opts?.alias === "string") {
26983
26988
  alias = opts.alias;
26984
26989
  }
26985
26990
  return this.knex(
26986
- this.tableNameWithSchema(this.query.endpoint.entityId, {
26991
+ this.tableNameWithSchema(this.query.table.name, {
26987
26992
  alias,
26988
- schema: this.query.endpoint.schema
26993
+ schema: this.query.schema
26989
26994
  })
26990
26995
  );
26991
26996
  }
@@ -26997,9 +27002,7 @@ var InternalBuilder = class {
26997
27002
  let query = this.qualifiedKnex({ alias: false });
26998
27003
  const parsedBody = this.parseBody(body2);
26999
27004
  if (this.client === "oracledb" /* ORACLE */) {
27000
- for (const [column, schema] of Object.entries(
27001
- this.query.meta.table.schema
27002
- )) {
27005
+ for (const [column, schema] of Object.entries(this.query.table.schema)) {
27003
27006
  if (schema.constraints?.presence === true || schema.type === "formula" /* FORMULA */ || schema.type === "auto" /* AUTO */ || schema.type === "link" /* LINK */ || schema.type === "ai" /* AI */) {
27004
27007
  continue;
27005
27008
  }
@@ -27049,10 +27052,8 @@ var InternalBuilder = class {
27049
27052
  return query.upsert(parsedBody);
27050
27053
  }
27051
27054
  read(opts = {}) {
27052
- let { endpoint, filters, paginate, relationships } = this.query;
27055
+ let { operation, filters, paginate, relationships, table } = this.query;
27053
27056
  const { limits } = opts;
27054
- const counting = endpoint.operation === "COUNT" /* COUNT */;
27055
- const tableName = endpoint.entityId;
27056
27057
  let query = this.qualifiedKnex();
27057
27058
  let foundOffset = null;
27058
27059
  let foundLimit = limits?.query || limits?.base;
@@ -27067,7 +27068,7 @@ var InternalBuilder = class {
27067
27068
  } else if (paginate && paginate.limit) {
27068
27069
  foundLimit = paginate.limit;
27069
27070
  }
27070
- if (!counting) {
27071
+ if (operation !== "COUNT" /* COUNT */) {
27071
27072
  if (foundLimit != null) {
27072
27073
  query = query.limit(foundLimit);
27073
27074
  }
@@ -27076,25 +27077,25 @@ var InternalBuilder = class {
27076
27077
  }
27077
27078
  }
27078
27079
  const aggregations = this.query.resource?.aggregations || [];
27079
- if (counting) {
27080
+ if (operation === "COUNT" /* COUNT */) {
27080
27081
  query = this.addDistinctCount(query);
27081
27082
  } else if (aggregations.length > 0) {
27082
27083
  query = this.addAggregations(query, aggregations);
27083
27084
  } else {
27084
27085
  query = query.select(this.generateSelectStatement());
27085
27086
  }
27086
- if (!counting) {
27087
+ if (operation !== "COUNT" /* COUNT */) {
27087
27088
  query = this.addSorting(query);
27088
27089
  }
27089
27090
  query = this.addFilters(query, filters, { relationship: true });
27090
27091
  if (relationships?.length && aggregations.length === 0) {
27091
- const mainTable = this.query.tableAliases?.[this.query.endpoint.entityId] || this.query.endpoint.entityId;
27092
+ const mainTable = this.query.tableAliases?.[table.name] || table.name;
27092
27093
  const cte = this.addSorting(
27093
27094
  this.knex.with("paginated", query).select(this.generateSelectStatement()).from({
27094
27095
  [mainTable]: "paginated"
27095
27096
  })
27096
27097
  );
27097
- return this.addJsonRelationships(cte, tableName, relationships);
27098
+ return this.addJsonRelationships(cte, table.name, relationships);
27098
27099
  }
27099
27100
  return query;
27100
27101
  }
@@ -27199,28 +27200,24 @@ var SqlQueryBuilder = class extends sqlTable_default {
27199
27200
  return {};
27200
27201
  }
27201
27202
  const input = this._query({
27202
- endpoint: {
27203
- ...json.endpoint,
27204
- operation: "READ" /* READ */
27205
- },
27206
- resource: {
27207
- fields: []
27208
- },
27203
+ operation: "READ" /* READ */,
27204
+ datasource: json.datasource,
27205
+ schema: json.schema,
27206
+ table: json.table,
27207
+ tables: json.tables,
27208
+ resource: { fields: [] },
27209
27209
  filters: json.extra?.idFilter,
27210
- paginate: {
27211
- limit: 1
27212
- },
27213
- meta: json.meta
27210
+ paginate: { limit: 1 }
27214
27211
  });
27215
27212
  return queryFn(input, "READ" /* READ */);
27216
27213
  }
27217
27214
  // when creating if an ID has been inserted need to make sure
27218
27215
  // the id filter is enriched with it before trying to retrieve the row
27219
27216
  checkLookupKeys(id, json) {
27220
- if (!id || !json.meta.table || !json.meta.table.primary) {
27217
+ if (!id || !json.table.primary) {
27221
27218
  return json;
27222
27219
  }
27223
- const primaryKey = json.meta.table.primary?.[0];
27220
+ const primaryKey = json.table.primary[0];
27224
27221
  json.extra = {
27225
27222
  idFilter: {
27226
27223
  equal: {