@budibase/backend-core 2.33.14 → 3.0.1

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
@@ -61,7 +61,7 @@ var require_dayjs_min = __commonJS({
61
61
  } }, g = "en", D = {};
62
62
  D[g] = M;
63
63
  var p = "$isDayjsObject", S = function(t2) {
64
- return t2 instanceof _2 || !(!t2 || !t2[p]);
64
+ return t2 instanceof _3 || !(!t2 || !t2[p]);
65
65
  }, w = function t2(e2, n2, r2) {
66
66
  var i2;
67
67
  if (!e2)
@@ -81,12 +81,12 @@ var require_dayjs_min = __commonJS({
81
81
  if (S(t2))
82
82
  return t2.clone();
83
83
  var n2 = "object" == typeof e2 ? e2 : {};
84
- return n2.date = t2, n2.args = arguments, new _2(n2);
84
+ return n2.date = t2, n2.args = arguments, new _3(n2);
85
85
  }, b = v;
86
86
  b.l = w, b.i = S, b.w = function(t2, e2) {
87
87
  return O(t2, { locale: e2.$L, utc: e2.$u, x: e2.$x, $offset: e2.$offset });
88
88
  };
89
- var _2 = function() {
89
+ var _3 = function() {
90
90
  function M2(t2) {
91
91
  this.$L = w(t2.locale, null, true), this.parse(t2), this.$x = this.$x || t2.x || {}, this[p] = true;
92
92
  }
@@ -311,13 +311,13 @@ var require_dayjs_min = __commonJS({
311
311
  }, m2.toString = function() {
312
312
  return this.$d.toUTCString();
313
313
  }, M2;
314
- }(), k = _2.prototype;
314
+ }(), k = _3.prototype;
315
315
  return O.prototype = k, [["$ms", r], ["$s", i], ["$m", s], ["$H", u], ["$W", a], ["$M", c], ["$y", h], ["$D", d]].forEach(function(t2) {
316
316
  k[t2[1]] = function(e2) {
317
317
  return this.$g(e2, t2[0], t2[1]);
318
318
  };
319
319
  }), O.extend = function(t2, e2) {
320
- return t2.$i || (t2(e2, _2, O), t2.$i = true), O;
320
+ return t2.$i || (t2(e2, _3, O), t2.$i = true), O;
321
321
  }, O.locale = w, O.isDayjs = S, O.unix = function(t2) {
322
322
  return O(1e3 * t2);
323
323
  }, O.en = D[g], O.Ls = D, O.p = {}, O;
@@ -797,12 +797,12 @@ var require_nanoclone = __commonJS({
797
797
  var map;
798
798
  try {
799
799
  map = Map;
800
- } catch (_2) {
800
+ } catch (_3) {
801
801
  }
802
802
  var set2;
803
803
  try {
804
804
  set2 = Set;
805
- } catch (_2) {
805
+ } catch (_3) {
806
806
  }
807
807
  function baseClone(src, circulars, clones) {
808
808
  if (!src || typeof src !== "object" || typeof src === "function") {
@@ -1110,7 +1110,7 @@ var require_ValidationError = __commonJS({
1110
1110
  path: path3
1111
1111
  });
1112
1112
  if (typeof message === "string")
1113
- return message.replace(strReg, (_2, key) => (0, _printValue.default)(params2[key]));
1113
+ return message.replace(strReg, (_3, key) => (0, _printValue.default)(params2[key]));
1114
1114
  if (typeof message === "function")
1115
1115
  return message(params2);
1116
1116
  return message;
@@ -2989,7 +2989,7 @@ var require_object = __commonJS({
2989
2989
  return;
2990
2990
  }
2991
2991
  originalValue = originalValue || value;
2992
- let tests = this._nodes.map((key) => (_2, cb) => {
2992
+ let tests = this._nodes.map((key) => (_3, cb) => {
2993
2993
  let path3 = key.indexOf(".") === -1 ? (opts.path ? `${opts.path}.` : "") + key : `${opts.path || ""}["${key}"]`;
2994
2994
  let field = this.fields[key];
2995
2995
  if (field && "validate" in field) {
@@ -3133,7 +3133,7 @@ var require_object = __commonJS({
3133
3133
  return this.noUnknown(!allow, message);
3134
3134
  }
3135
3135
  transformKeys(fn) {
3136
- return this.transform((obj) => obj && (0, _mapKeys.default)(obj, (_2, key) => fn(key)));
3136
+ return this.transform((obj) => obj && (0, _mapKeys.default)(obj, (_3, key) => fn(key)));
3137
3137
  }
3138
3138
  camelCase() {
3139
3139
  return this.transformKeys(_camelCase.default);
@@ -3266,7 +3266,7 @@ var require_array = __commonJS({
3266
3266
  index: idx,
3267
3267
  originalValue: originalValue[idx]
3268
3268
  });
3269
- tests[idx] = (_2, cb) => innerType.validate(item, innerOptions, cb);
3269
+ tests[idx] = (_3, cb) => innerType.validate(item, innerOptions, cb);
3270
3270
  }
3271
3271
  (0, _runTests.default)({
3272
3272
  sync,
@@ -10474,7 +10474,7 @@ var require_field_stringify = __commonJS({
10474
10474
  var multiplier = range.start == 0 ? range.count - 1 : range.count;
10475
10475
  if (range.step * multiplier > range.end) {
10476
10476
  result = result.concat(
10477
- Array.from({ length: range.end - range.start + 1 }).map(function(_2, index2) {
10477
+ Array.from({ length: range.end - range.start + 1 }).map(function(_3, index2) {
10478
10478
  var value = range.start + index2;
10479
10479
  if ((value - range.start) % range.step === 0) {
10480
10480
  return value;
@@ -48989,7 +48989,7 @@ var require_uri_all = __commonJS({
48989
48989
  uriTokens.push("@");
48990
48990
  }
48991
48991
  if (components.host !== void 0) {
48992
- uriTokens.push(_normalizeIPv6(_normalizeIPv4(String(components.host), protocol), protocol).replace(protocol.IPV6ADDRESS, function(_2, $1, $2) {
48992
+ uriTokens.push(_normalizeIPv6(_normalizeIPv4(String(components.host), protocol), protocol).replace(protocol.IPV6ADDRESS, function(_3, $1, $2) {
48993
48993
  return "[" + $1 + ($2 ? "%25" + $2 : "") + "]";
48994
48994
  }));
48995
48995
  }
@@ -61537,7 +61537,16 @@ var LogicalOperator = /* @__PURE__ */ ((LogicalOperator2) => {
61537
61537
  return LogicalOperator2;
61538
61538
  })(LogicalOperator || {});
61539
61539
  function isLogicalSearchOperator(value) {
61540
- return value === "$and" /* AND */ || value === "$or" /* OR */;
61540
+ return Object.values(LogicalOperator).includes(value);
61541
+ }
61542
+ function isBasicSearchOperator(value) {
61543
+ return Object.values(BasicOperator).includes(value);
61544
+ }
61545
+ function isArraySearchOperator(value) {
61546
+ return Object.values(ArrayOperator).includes(value);
61547
+ }
61548
+ function isRangeSearchOperator(value) {
61549
+ return Object.values(RangeOperator).includes(value);
61541
61550
  }
61542
61551
 
61543
61552
  // ../types/src/sdk/db.ts
@@ -61795,6 +61804,33 @@ __export(constants_exports2, {
61795
61804
  ViewName: () => ViewName
61796
61805
  });
61797
61806
 
61807
+ // ../shared-core/src/constants/ai.ts
61808
+ var OperationFields = {
61809
+ ["SUMMARISE_TEXT" /* SUMMARISE_TEXT */]: {
61810
+ columns: "columns" /* MULTI_COLUMN */
61811
+ },
61812
+ ["CLEAN_DATA" /* CLEAN_DATA */]: {
61813
+ column: "column" /* COLUMN */
61814
+ },
61815
+ ["TRANSLATE" /* TRANSLATE */]: {
61816
+ column: "column" /* COLUMN */,
61817
+ language: "prompt" /* BINDABLE_TEXT */
61818
+ },
61819
+ ["CATEGORISE_TEXT" /* CATEGORISE_TEXT */]: {
61820
+ columns: "columns" /* MULTI_COLUMN */,
61821
+ categories: "prompt" /* BINDABLE_TEXT */
61822
+ },
61823
+ ["SENTIMENT_ANALYSIS" /* SENTIMENT_ANALYSIS */]: {
61824
+ column: "column" /* COLUMN */
61825
+ },
61826
+ ["PROMPT" /* PROMPT */]: {
61827
+ prompt: "prompt" /* BINDABLE_TEXT */
61828
+ },
61829
+ ["SEARCH_WEB" /* SEARCH_WEB */]: {
61830
+ columns: "columns" /* MULTI_COLUMN */
61831
+ }
61832
+ };
61833
+
61798
61834
  // ../shared-core/src/constants/api.ts
61799
61835
  var Header = /* @__PURE__ */ ((Header2) => {
61800
61836
  Header2["API_KEY"] = "x-budibase-api-key";
@@ -61847,6 +61883,31 @@ var SWITCHABLE_TYPES = {
61847
61883
  ["number" /* NUMBER */]: ["number" /* NUMBER */, "boolean" /* BOOLEAN */]
61848
61884
  };
61849
61885
 
61886
+ // ../shared-core/src/constants/themes.ts
61887
+ var DefaultBuilderTheme = "darkest" /* DARKEST */;
61888
+ var DefaultAppTheme = "light" /* LIGHT */;
61889
+ var ThemeOptions = [
61890
+ {
61891
+ id: "light" /* LIGHT */,
61892
+ name: "Light"
61893
+ },
61894
+ {
61895
+ // We call this dark for simplicity, but we want to use the spectrum darkest style
61896
+ id: "darkest" /* DARKEST */,
61897
+ name: "Dark"
61898
+ },
61899
+ {
61900
+ id: "nord" /* NORD */,
61901
+ name: "Nord",
61902
+ base: "darkest" /* DARKEST */
61903
+ },
61904
+ {
61905
+ id: "midnight" /* MIDNIGHT */,
61906
+ name: "Midnight",
61907
+ base: "darkest" /* DARKEST */
61908
+ }
61909
+ ];
61910
+
61850
61911
  // ../shared-core/src/constants/index.ts
61851
61912
  var OperatorOptions = {
61852
61913
  Equals: {
@@ -61924,7 +61985,6 @@ __export(filters_exports, {
61924
61985
  ColumnSplitter: () => ColumnSplitter,
61925
61986
  NoEmptyFilterStrings: () => NoEmptyFilterStrings,
61926
61987
  buildQuery: () => buildQuery,
61927
- buildQueryLegacy: () => buildQueryLegacy,
61928
61988
  cleanupQuery: () => cleanupQuery,
61929
61989
  fixupFilterArrays: () => fixupFilterArrays,
61930
61990
  getKeyNumbering: () => getKeyNumbering,
@@ -61936,7 +61996,8 @@ __export(filters_exports, {
61936
61996
  removeKeyNumbering: () => removeKeyNumbering,
61937
61997
  runQuery: () => runQuery,
61938
61998
  search: () => search,
61939
- sort: () => sort
61999
+ sort: () => sort,
62000
+ splitFiltersArray: () => splitFiltersArray
61940
62001
  });
61941
62002
  var import_dayjs = __toESM(require_dayjs_min());
61942
62003
 
@@ -61951,6 +62012,17 @@ __export(utils_exports, {
61951
62012
  trimOtherProps: () => trimOtherProps,
61952
62013
  unreachable: () => unreachable
61953
62014
  });
62015
+ var import_lodash = __toESM(require("lodash"));
62016
+ var FILTER_ALLOWED_KEYS = [
62017
+ "field",
62018
+ "operator",
62019
+ "value",
62020
+ "type",
62021
+ "externalType",
62022
+ "valueType",
62023
+ "noValue",
62024
+ "formulaType"
62025
+ ];
61954
62026
  function unreachable(value, message = `No such case in exhaustive switch: ${value}`) {
61955
62027
  throw new Error(message);
61956
62028
  }
@@ -62033,70 +62105,29 @@ function isSupportedUserSearch(query) {
62033
62105
  }
62034
62106
  return true;
62035
62107
  }
62036
- var processSearchFilters = (filters) => {
62037
- if (!filters) {
62038
- return;
62108
+ function processSearchFilters(filterArray) {
62109
+ if (!filterArray || filterArray.length === 0) {
62110
+ return void 0;
62039
62111
  }
62040
- const defaultCfg = {
62112
+ const { allOr, onEmptyFilter, filters } = splitFiltersArray(filterArray);
62113
+ return {
62041
62114
  logicalOperator: "all" /* ALL */,
62042
- groups: []
62043
- };
62044
- const filterAllowedKeys = [
62045
- "field",
62046
- "operator",
62047
- "value",
62048
- "type",
62049
- "externalType",
62050
- "valueType",
62051
- "noValue",
62052
- "formulaType"
62053
- ];
62054
- if (Array.isArray(filters)) {
62055
- let baseGroup = {
62056
- filters: [],
62057
- logicalOperator: "all" /* ALL */
62058
- };
62059
- return filters.reduce((acc, filter) => {
62060
- const filterPropertyKeys = Object.keys(filter).sort((a, b) => {
62061
- return a.localeCompare(b);
62062
- }).filter((key) => filter[key]);
62063
- if (filterPropertyKeys.length == 1) {
62064
- const key = filterPropertyKeys[0], value = filter[key];
62065
- if (key === "onEmptyFilter") {
62066
- acc.onEmptyFilter = value;
62067
- } else if (key === "operator" && value === "allOr") {
62068
- baseGroup.logicalOperator = "any" /* ANY */;
62069
- }
62070
- return acc;
62071
- }
62072
- const allowedFilterSettings = filterPropertyKeys.reduce(
62073
- (acc2, key) => {
62074
- const value = filter[key];
62075
- if (filterAllowedKeys.includes(key)) {
62076
- if (key === "field") {
62077
- acc2.push([key, removeKeyNumbering(value)]);
62078
- } else {
62079
- acc2.push([key, value]);
62080
- }
62081
- }
62082
- return acc2;
62083
- },
62084
- []
62085
- );
62086
- const migratedFilter = Object.fromEntries(
62087
- allowedFilterSettings
62088
- );
62089
- baseGroup.filters.push(migratedFilter);
62090
- if (!acc.groups || !acc.groups.length) {
62091
- acc.groups = [baseGroup];
62115
+ onEmptyFilter: onEmptyFilter || "all" /* RETURN_ALL */,
62116
+ groups: [
62117
+ {
62118
+ logicalOperator: allOr ? "any" /* ANY */ : "all" /* ALL */,
62119
+ filters: filters.map((filter) => {
62120
+ const trimmedFilter = import_lodash.default.pick(
62121
+ filter,
62122
+ FILTER_ALLOWED_KEYS
62123
+ );
62124
+ trimmedFilter.field = removeKeyNumbering(trimmedFilter.field);
62125
+ return trimmedFilter;
62126
+ })
62092
62127
  }
62093
- return acc;
62094
- }, defaultCfg);
62095
- } else if (!filters?.groups) {
62096
- return;
62097
- }
62098
- return filters;
62099
- };
62128
+ ]
62129
+ };
62130
+ }
62100
62131
 
62101
62132
  // ../shared-core/src/helpers/index.ts
62102
62133
  var helpers_exports = {};
@@ -62309,7 +62340,7 @@ __export(views_exports, {
62309
62340
  isCalculationView: () => isCalculationView,
62310
62341
  isVisible: () => isVisible
62311
62342
  });
62312
- var import_lodash = require("lodash");
62343
+ var import_lodash2 = require("lodash");
62313
62344
  function isCalculationField(field) {
62314
62345
  return "calculationType" in field;
62315
62346
  }
@@ -62323,14 +62354,14 @@ function hasCalculationFields(view) {
62323
62354
  return Object.values(view.schema || {}).some(isCalculationField);
62324
62355
  }
62325
62356
  function calculationFields(view) {
62326
- return (0, import_lodash.pickBy)(view.schema || {}, isCalculationField);
62357
+ return (0, import_lodash2.pickBy)(view.schema || {}, isCalculationField);
62327
62358
  }
62328
62359
  function isVisible(field) {
62329
62360
  return field.visible !== false;
62330
62361
  }
62331
62362
  function basicFields(view, opts) {
62332
62363
  const { visible = true } = opts || {};
62333
- return (0, import_lodash.pickBy)(view.schema || {}, (field) => {
62364
+ return (0, import_lodash2.pickBy)(view.schema || {}, (field) => {
62334
62365
  return !isCalculationField(field) && (!visible || isVisible(field));
62335
62366
  });
62336
62367
  }
@@ -62378,7 +62409,7 @@ function checkForRoleInheritanceLoops(roles) {
62378
62409
  }
62379
62410
 
62380
62411
  // ../shared-core/src/filters.ts
62381
- var import_lodash2 = require("lodash");
62412
+ var import_lodash3 = require("lodash");
62382
62413
  var HBS_REGEX = /{{([^{].*?)}}/g;
62383
62414
  var LOGICAL_OPERATORS = Object.values(LogicalOperator);
62384
62415
  var SEARCH_OPERATORS = [
@@ -62424,6 +62455,8 @@ var getValidOperatorsForType = (fieldType, field, datasource2) => {
62424
62455
  ops = numOps;
62425
62456
  } else if (type === "formula" /* FORMULA */ && formulaType === "static" /* STATIC */) {
62426
62457
  ops = stringOps.concat([Op.MoreThan, Op.LessThan]);
62458
+ } else if (type === "ai" /* AI */) {
62459
+ ops = stringOps.concat([Op.MoreThan, Op.LessThan]);
62427
62460
  } else if (type === "bb_reference_single" /* BB_REFERENCE_SINGLE */ || schema_exports.isDeprecatedSingleUserColumn(fieldType)) {
62428
62461
  ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty, Op.In];
62429
62462
  } else if (type === "bb_reference" /* BB_REFERENCE */) {
@@ -62557,228 +62590,153 @@ var ColumnSplitter = class {
62557
62590
  };
62558
62591
  }
62559
62592
  };
62560
- var buildCondition = (expression) => {
62561
- let query = {
62562
- string: {},
62563
- fuzzy: {},
62564
- range: {},
62565
- equal: {},
62566
- notEqual: {},
62567
- empty: {},
62568
- notEmpty: {},
62569
- contains: {},
62570
- notContains: {},
62571
- oneOf: {},
62572
- containsAny: {}
62573
- };
62574
- let { operator, field, type, value, externalType, onEmptyFilter } = expression;
62575
- if (!operator || !field) {
62593
+ function buildCondition(filter) {
62594
+ if (!filter) {
62576
62595
  return;
62577
62596
  }
62578
- const queryOperator = operator;
62579
- const isHbs = typeof value === "string" && (value.match(HBS_REGEX) || []).length > 0;
62580
- if (operator === "allOr") {
62581
- query.allOr = true;
62582
- return;
62583
- }
62584
- if (onEmptyFilter) {
62585
- query.onEmptyFilter = onEmptyFilter;
62586
- return;
62587
- }
62588
- if (queryOperator === "empty" || queryOperator === "notEmpty") {
62597
+ const query = {};
62598
+ const { operator, field, type, externalType } = filter;
62599
+ let { value } = filter;
62600
+ if (operator === "empty" || operator === "notEmpty") {
62589
62601
  value = null;
62590
62602
  }
62591
- if (type === "datetime" && !isHbs && queryOperator !== "empty" && queryOperator !== "notEmpty") {
62592
- if (!value) {
62593
- return;
62594
- }
62595
- try {
62596
- value = new Date(value).toISOString();
62597
- } catch (error) {
62598
- return;
62599
- }
62600
- }
62601
- if (type === "number" && typeof value === "string" && !isHbs) {
62602
- if (queryOperator === "oneOf") {
62603
- value = value.split(",").map((item) => parseFloat(item));
62604
- } else {
62605
- value = parseFloat(value);
62606
- }
62607
- }
62608
- if (type === "boolean") {
62609
- value = `${value}`?.toLowerCase() === "true";
62610
- }
62611
- if (["contains", "notContains", "containsAny"].includes(
62612
- operator.toLocaleString()
62613
- ) && type === "array" && typeof value === "string") {
62614
- value = value.split(",");
62603
+ const isHbs = typeof value === "string" && (value.match(HBS_REGEX) || []).length > 0;
62604
+ switch (type) {
62605
+ case "datetime" /* DATETIME */:
62606
+ if (!isHbs && operator !== "empty" && operator !== "notEmpty") {
62607
+ if (!value) {
62608
+ return;
62609
+ }
62610
+ value = new Date(value).toISOString();
62611
+ }
62612
+ break;
62613
+ case "number" /* NUMBER */:
62614
+ if (typeof value === "string" && !isHbs) {
62615
+ if (operator === "oneOf") {
62616
+ value = value.split(",").map(parseFloat);
62617
+ } else {
62618
+ value = parseFloat(value);
62619
+ }
62620
+ }
62621
+ break;
62622
+ case "boolean" /* BOOLEAN */:
62623
+ value = `${value}`.toLowerCase() === "true";
62624
+ break;
62625
+ case "array" /* ARRAY */:
62626
+ if (["contains", "notContains", "containsAny"].includes(
62627
+ operator.toLocaleString()
62628
+ ) && typeof value === "string") {
62629
+ value = value.split(",");
62630
+ }
62631
+ break;
62615
62632
  }
62616
- if (operator.toLocaleString().startsWith("range") && query.range) {
62617
- const minint = SqlNumberTypeRangeMap[externalType]?.min || Number.MIN_SAFE_INTEGER;
62618
- const maxint = SqlNumberTypeRangeMap[externalType]?.max || Number.MAX_SAFE_INTEGER;
62619
- if (!query.range[field]) {
62620
- query.range[field] = {
62621
- low: type === "number" ? minint : "0000-00-00T00:00:00.000Z",
62622
- high: type === "number" ? maxint : "9999-00-00T00:00:00.000Z"
62623
- };
62624
- }
62625
- if (operator === "rangeLow" && value != null && value !== "") {
62626
- query.range[field] = {
62627
- ...query.range[field],
62628
- low: value
62629
- };
62630
- } else if (operator === "rangeHigh" && value != null && value !== "") {
62631
- query.range[field] = {
62632
- ...query.range[field],
62633
- high: value
62634
- };
62635
- }
62636
- } else if (isLogicalSearchOperator(queryOperator)) {
62637
- } else if (query[queryOperator] && operator !== "onEmptyFilter") {
62633
+ if (isRangeSearchOperator(operator)) {
62634
+ const key = externalType;
62635
+ const limits = SqlNumberTypeRangeMap[key] || {
62636
+ min: Number.MIN_SAFE_INTEGER,
62637
+ max: Number.MAX_SAFE_INTEGER
62638
+ };
62639
+ query[operator] ??= {};
62640
+ query[operator][field] = {
62641
+ low: type === "number" ? limits.min : "0000-00-00T00:00:00.000Z",
62642
+ high: type === "number" ? limits.max : "9999-00-00T00:00:00.000Z"
62643
+ };
62644
+ } else if (operator === "rangeHigh" && value != null && value !== "") {
62645
+ query.range ??= {};
62646
+ query.range[field] = {
62647
+ ...query.range[field],
62648
+ high: value
62649
+ };
62650
+ } else if (operator === "rangeLow" && value != null && value !== "") {
62651
+ query.range ??= {};
62652
+ query.range[field] = {
62653
+ ...query.range[field],
62654
+ low: value
62655
+ };
62656
+ } else if (isBasicSearchOperator(operator) || isArraySearchOperator(operator) || isRangeSearchOperator(operator)) {
62638
62657
  if (type === "boolean") {
62639
- if (queryOperator === "equal" && value === false) {
62658
+ if (operator === "equal" && value === false) {
62640
62659
  query.notEqual = query.notEqual || {};
62641
62660
  query.notEqual[field] = true;
62642
- } else if (queryOperator === "notEqual" && value === false) {
62661
+ } else if (operator === "notEqual" && value === false) {
62643
62662
  query.equal = query.equal || {};
62644
62663
  query.equal[field] = true;
62645
62664
  } else {
62646
- query[queryOperator] ??= {};
62647
- query[queryOperator][field] = value;
62665
+ query[operator] ??= {};
62666
+ query[operator][field] = value;
62648
62667
  }
62649
62668
  } else {
62650
- query[queryOperator] ??= {};
62651
- query[queryOperator][field] = value;
62669
+ query[operator] ??= {};
62670
+ query[operator][field] = value;
62652
62671
  }
62672
+ } else {
62673
+ throw new Error(`Unsupported operator: ${operator}`);
62653
62674
  }
62654
62675
  return query;
62655
- };
62656
- var buildQueryLegacy = (filter) => {
62657
- if (!Array.isArray(filter)) {
62658
- return filter;
62659
- }
62660
- let query = {
62661
- string: {},
62662
- fuzzy: {},
62663
- range: {},
62664
- equal: {},
62665
- notEqual: {},
62666
- empty: {},
62667
- notEmpty: {},
62668
- contains: {},
62669
- notContains: {},
62670
- oneOf: {},
62671
- containsAny: {}
62676
+ }
62677
+ function splitFiltersArray(filters) {
62678
+ const split = {
62679
+ filters: []
62672
62680
  };
62673
- if (!Array.isArray(filter)) {
62674
- return query;
62675
- }
62676
- filter.forEach((expression) => {
62677
- let { operator, field, type, value, externalType, onEmptyFilter } = expression;
62678
- const queryOperator = operator;
62679
- const isHbs = typeof value === "string" && (value.match(HBS_REGEX) || []).length > 0;
62680
- if (operator === "allOr") {
62681
- query.allOr = true;
62682
- return;
62683
- }
62684
- if (onEmptyFilter) {
62685
- query.onEmptyFilter = onEmptyFilter;
62686
- return;
62687
- }
62688
- if (type === "datetime" && !isHbs && queryOperator !== "empty" && queryOperator !== "notEmpty") {
62689
- if (!value) {
62690
- return;
62691
- }
62692
- try {
62693
- value = new Date(value).toISOString();
62694
- } catch (error) {
62695
- return;
62696
- }
62681
+ for (const filter of filters) {
62682
+ if ("operator" in filter && filter.operator === "allOr") {
62683
+ split.allOr = true;
62684
+ } else if ("onEmptyFilter" in filter) {
62685
+ split.onEmptyFilter = filter.onEmptyFilter;
62686
+ } else {
62687
+ split.filters.push(filter);
62697
62688
  }
62698
- if (type === "number" && typeof value === "string" && !isHbs) {
62699
- if (queryOperator === "oneOf") {
62700
- value = value.split(",").map((item) => parseFloat(item));
62701
- } else {
62702
- value = parseFloat(value);
62703
- }
62689
+ }
62690
+ return split;
62691
+ }
62692
+ function buildQuery(filter) {
62693
+ if (!filter) {
62694
+ return {};
62695
+ }
62696
+ if (Array.isArray(filter)) {
62697
+ filter = processSearchFilters(filter);
62698
+ if (!filter) {
62699
+ return {};
62704
62700
  }
62705
- if (type === "boolean") {
62706
- value = `${value}`?.toLowerCase() === "true";
62707
- }
62708
- if (["contains", "notContains", "containsAny"].includes(
62709
- operator.toLocaleString()
62710
- ) && type === "array" && typeof value === "string") {
62711
- value = value.split(",");
62712
- }
62713
- if (operator.toLocaleString().startsWith("range") && query.range) {
62714
- const minint = SqlNumberTypeRangeMap[externalType]?.min || Number.MIN_SAFE_INTEGER;
62715
- const maxint = SqlNumberTypeRangeMap[externalType]?.max || Number.MAX_SAFE_INTEGER;
62716
- if (!query.range[field]) {
62717
- query.range[field] = {
62718
- low: type === "number" ? minint : "0000-00-00T00:00:00.000Z",
62719
- high: type === "number" ? maxint : "9999-00-00T00:00:00.000Z"
62720
- };
62721
- }
62722
- if (operator === "rangeLow" && value != null && value !== "") {
62723
- query.range[field] = {
62724
- ...query.range[field],
62725
- low: value
62726
- };
62727
- } else if (operator === "rangeHigh" && value != null && value !== "") {
62728
- query.range[field] = {
62729
- ...query.range[field],
62730
- high: value
62731
- };
62701
+ }
62702
+ const operator = logicalOperatorFromUI(
62703
+ filter.logicalOperator || "all" /* ALL */
62704
+ );
62705
+ const query = {};
62706
+ if (filter.onEmptyFilter) {
62707
+ query.onEmptyFilter = filter.onEmptyFilter;
62708
+ } else {
62709
+ query.onEmptyFilter = "all" /* RETURN_ALL */;
62710
+ }
62711
+ query[operator] = {
62712
+ conditions: (filter.groups || []).map((group) => {
62713
+ const { allOr, onEmptyFilter, filters } = splitFiltersArray(
62714
+ group.filters || []
62715
+ );
62716
+ if (onEmptyFilter) {
62717
+ query.onEmptyFilter = onEmptyFilter;
62732
62718
  }
62733
- } else if (isLogicalSearchOperator(queryOperator)) {
62734
- } else if (query[queryOperator] && operator !== "onEmptyFilter") {
62735
- if (type === "boolean") {
62736
- if (queryOperator === "equal" && value === false) {
62737
- query.notEqual = query.notEqual || {};
62738
- query.notEqual[field] = true;
62739
- } else if (queryOperator === "notEqual" && value === false) {
62740
- query.equal = query.equal || {};
62741
- query.equal[field] = true;
62742
- } else {
62743
- query[queryOperator] ??= {};
62744
- query[queryOperator][field] = value;
62745
- }
62746
- } else {
62747
- query[queryOperator] ??= {};
62748
- query[queryOperator][field] = value;
62719
+ let operator2 = allOr ? "$or" /* OR */ : "$and" /* AND */;
62720
+ if (group.logicalOperator) {
62721
+ operator2 = logicalOperatorFromUI(group.logicalOperator);
62749
62722
  }
62750
- }
62751
- });
62752
- return query;
62753
- };
62754
- var buildQuery = (filter) => {
62755
- const parsedFilter = processSearchFilters(filter);
62756
- if (!parsedFilter) {
62757
- return;
62758
- }
62759
- const operatorMap = {
62760
- ["all" /* ALL */]: "$and" /* AND */,
62761
- ["any" /* ANY */]: "$or" /* OR */
62762
- };
62763
- const globalOnEmpty = parsedFilter.onEmptyFilter ? parsedFilter.onEmptyFilter : null;
62764
- const globalOperator = operatorMap[parsedFilter.logicalOperator];
62765
- return {
62766
- ...globalOnEmpty ? { onEmptyFilter: globalOnEmpty } : {},
62767
- [globalOperator]: {
62768
- conditions: parsedFilter.groups?.map((group) => {
62769
- return {
62770
- [operatorMap[group.logicalOperator]]: {
62771
- conditions: group.filters?.map((x) => buildCondition(x)).filter((filter2) => filter2)
62772
- }
62773
- };
62774
- })
62775
- }
62723
+ return {
62724
+ [operator2]: { conditions: filters.map(buildCondition).filter((f) => f) }
62725
+ };
62726
+ })
62776
62727
  };
62777
- };
62728
+ return query;
62729
+ }
62730
+ function logicalOperatorFromUI(operator) {
62731
+ return operator === "all" /* ALL */ ? "$and" /* AND */ : "$or" /* OR */;
62732
+ }
62778
62733
  function fixupFilterArrays(filters) {
62734
+ if (!filters) {
62735
+ return filters;
62736
+ }
62779
62737
  for (const searchField of Object.values(ArrayOperator)) {
62780
62738
  const field = filters[searchField];
62781
- if (field == null || !(0, import_lodash2.isPlainObject)(field)) {
62739
+ if (field == null || !(0, import_lodash3.isPlainObject)(field)) {
62782
62740
  continue;
62783
62741
  }
62784
62742
  for (const key of Object.keys(field)) {
@@ -62865,10 +62823,10 @@ function runQuery(docs, query) {
62865
62823
  if (docValue == null || docValue === "") {
62866
62824
  return false;
62867
62825
  }
62868
- if ((0, import_lodash2.isPlainObject)(testValue.low) && (0, import_lodash2.isEmpty)(testValue.low)) {
62826
+ if ((0, import_lodash3.isPlainObject)(testValue.low) && (0, import_lodash3.isEmpty)(testValue.low)) {
62869
62827
  testValue.low = void 0;
62870
62828
  }
62871
- if ((0, import_lodash2.isPlainObject)(testValue.high) && (0, import_lodash2.isEmpty)(testValue.high)) {
62829
+ if ((0, import_lodash3.isPlainObject)(testValue.high) && (0, import_lodash3.isEmpty)(testValue.high)) {
62872
62830
  testValue.high = void 0;
62873
62831
  }
62874
62832
  if (testValue.low == null && testValue.high == null) {
@@ -63189,7 +63147,7 @@ __export(users_exports, {
63189
63147
  isCreator: () => isCreator,
63190
63148
  isGlobalBuilder: () => isGlobalBuilder
63191
63149
  });
63192
- var _ = __toESM(require("lodash/fp"));
63150
+ var _2 = __toESM(require("lodash/fp"));
63193
63151
  function isBuilder(user, appId) {
63194
63152
  if (!user) {
63195
63153
  return false;
@@ -63231,10 +63189,10 @@ function hasAppCreatorPermissions(user) {
63231
63189
  if (!user) {
63232
63190
  return false;
63233
63191
  }
63234
- return _.flow(
63235
- _.get("roles"),
63236
- _.values,
63237
- _.find((x) => ["CREATOR", "ADMIN"].includes(x)),
63192
+ return _2.flow(
63193
+ _2.get("roles"),
63194
+ _2.values,
63195
+ _2.find((x) => ["CREATOR", "ADMIN"].includes(x)),
63238
63196
  (x) => !!x
63239
63197
  )(user);
63240
63198
  }
@@ -63332,11 +63290,11 @@ var allowDefaultColumnByType = {
63332
63290
  ["string" /* STRING */]: true,
63333
63291
  ["options" /* OPTIONS */]: true,
63334
63292
  ["array" /* ARRAY */]: true,
63293
+ ["bigint" /* BIGINT */]: true,
63294
+ ["boolean" /* BOOLEAN */]: true,
63335
63295
  ["auto" /* AUTO */]: false,
63336
63296
  ["internal" /* INTERNAL */]: false,
63337
63297
  ["barcodeqr" /* BARCODEQR */]: false,
63338
- ["bigint" /* BIGINT */]: false,
63339
- ["boolean" /* BOOLEAN */]: false,
63340
63298
  ["formula" /* FORMULA */]: false,
63341
63299
  ["ai" /* AI */]: false,
63342
63300
  ["attachment" /* ATTACHMENTS */]: false,
@@ -63438,6 +63396,7 @@ var Config = /* @__PURE__ */ ((Config3) => {
63438
63396
  Config3["OIDC"] = "oidc";
63439
63397
  Config3["OIDC_LOGOS"] = "logos_oidc";
63440
63398
  Config3["SCIM"] = "scim";
63399
+ Config3["AI"] = "AI";
63441
63400
  return Config3;
63442
63401
  })(Config || {});
63443
63402
  var MIN_VALID_DATE = /* @__PURE__ */ new Date(-2147483647e3);
@@ -63572,7 +63531,7 @@ function getAccountUserId(account) {
63572
63531
 
63573
63532
  // src/environment.ts
63574
63533
  var import_fs = require("fs");
63575
- var import_lodash3 = require("lodash");
63534
+ var import_lodash4 = require("lodash");
63576
63535
  function isTest() {
63577
63536
  return isJest();
63578
63537
  }
@@ -63749,10 +63708,11 @@ var environment = {
63749
63708
  DISABLE_SCIM_CALLS: process.env.DISABLE_SCIM_CALLS,
63750
63709
  BB_ADMIN_USER_EMAIL: process.env.BB_ADMIN_USER_EMAIL,
63751
63710
  BB_ADMIN_USER_PASSWORD: process.env.BB_ADMIN_USER_PASSWORD,
63752
- OPENAI_API_KEY: process.env.OPENAI_API_KEY
63711
+ OPENAI_API_KEY: process.env.OPENAI_API_KEY,
63712
+ MIN_VERSION_WITHOUT_POWER_ROLE: process.env.MIN_VERSION_WITHOUT_POWER_ROLE || "3.0.0"
63753
63713
  };
63754
63714
  function setEnv(newEnvVars) {
63755
- const oldEnv = (0, import_lodash3.cloneDeep)(environment);
63715
+ const oldEnv = (0, import_lodash4.cloneDeep)(environment);
63756
63716
  let key;
63757
63717
  for (key in newEnvVars) {
63758
63718
  environment._set(key, newEnvVars[key]);
@@ -69371,7 +69331,6 @@ __export(roles_exports2, {
69371
69331
  RoleIDVersion: () => RoleIDVersion,
69372
69332
  builtinRoleToNumber: () => builtinRoleToNumber,
69373
69333
  checkForRoleResourceArray: () => checkForRoleResourceArray,
69374
- compareRoleIds: () => compareRoleIds,
69375
69334
  externalRole: () => externalRole,
69376
69335
  findRole: () => findRole,
69377
69336
  getAllRoleIds: () => getAllRoleIds,
@@ -69387,162 +69346,14 @@ __export(roles_exports2, {
69387
69346
  isBuiltin: () => isBuiltin,
69388
69347
  lowerBuiltinRoleID: () => lowerBuiltinRoleID,
69389
69348
  prefixRoleIDNoBuiltin: () => prefixRoleIDNoBuiltin,
69349
+ roleIDsAreEqual: () => roleIDsAreEqual,
69390
69350
  roleToNumber: () => roleToNumber,
69391
- saveRoles: () => saveRoles
69351
+ saveRoles: () => saveRoles,
69352
+ validInherits: () => validInherits
69392
69353
  });
69393
69354
  var import_semver = __toESM(require("semver"));
69394
-
69395
- // src/security/permissions.ts
69396
- var permissions_exports = {};
69397
- __export(permissions_exports, {
69398
- BUILDER: () => BUILDER,
69399
- BUILTIN_PERMISSIONS: () => BUILTIN_PERMISSIONS,
69400
- BuiltinPermissionID: () => BuiltinPermissionID,
69401
- CREATOR: () => CREATOR,
69402
- GLOBAL_BUILDER: () => GLOBAL_BUILDER,
69403
- Permission: () => Permission,
69404
- PermissionLevel: () => PermissionLevel,
69405
- PermissionType: () => PermissionType,
69406
- doesHaveBasePermission: () => doesHaveBasePermission,
69407
- getAllowedLevels: () => getAllowedLevels,
69408
- getBuiltinPermissionByID: () => getBuiltinPermissionByID,
69409
- getBuiltinPermissions: () => getBuiltinPermissions,
69410
- isPermissionLevelHigherThanRead: () => isPermissionLevelHigherThanRead,
69411
- levelToNumber: () => levelToNumber
69412
- });
69413
- var import_flatten = __toESM(require("lodash/flatten"));
69414
69355
  var import_cloneDeep = __toESM(require("lodash/fp/cloneDeep"));
69415
- var Permission = class {
69416
- constructor(type, level) {
69417
- this.type = type;
69418
- this.level = level;
69419
- }
69420
- };
69421
- function levelToNumber(perm) {
69422
- switch (perm) {
69423
- case "execute" /* EXECUTE */:
69424
- return 0;
69425
- case "read" /* READ */:
69426
- return 1;
69427
- case "write" /* WRITE */:
69428
- return 2;
69429
- case "admin" /* ADMIN */:
69430
- return 3;
69431
- default:
69432
- return -1;
69433
- }
69434
- }
69435
- function getAllowedLevels(userPermLevel) {
69436
- switch (userPermLevel) {
69437
- case "execute" /* EXECUTE */:
69438
- return ["execute" /* EXECUTE */];
69439
- case "read" /* READ */:
69440
- return ["execute" /* EXECUTE */, "read" /* READ */];
69441
- case "write" /* WRITE */:
69442
- case "admin" /* ADMIN */:
69443
- return [
69444
- "execute" /* EXECUTE */,
69445
- "read" /* READ */,
69446
- "write" /* WRITE */
69447
- ];
69448
- default:
69449
- return [];
69450
- }
69451
- }
69452
- var BuiltinPermissionID = /* @__PURE__ */ ((BuiltinPermissionID2) => {
69453
- BuiltinPermissionID2["PUBLIC"] = "public";
69454
- BuiltinPermissionID2["READ_ONLY"] = "read_only";
69455
- BuiltinPermissionID2["WRITE"] = "write";
69456
- BuiltinPermissionID2["ADMIN"] = "admin";
69457
- BuiltinPermissionID2["POWER"] = "power";
69458
- return BuiltinPermissionID2;
69459
- })(BuiltinPermissionID || {});
69460
- var BUILTIN_PERMISSIONS = {
69461
- PUBLIC: {
69462
- _id: "public" /* PUBLIC */,
69463
- name: "Public",
69464
- permissions: [
69465
- new Permission("webhook" /* WEBHOOK */, "execute" /* EXECUTE */)
69466
- ]
69467
- },
69468
- READ_ONLY: {
69469
- _id: "read_only" /* READ_ONLY */,
69470
- name: "Read only",
69471
- permissions: [
69472
- new Permission("query" /* QUERY */, "read" /* READ */),
69473
- new Permission("table" /* TABLE */, "read" /* READ */),
69474
- new Permission("app" /* APP */, "read" /* READ */)
69475
- ]
69476
- },
69477
- WRITE: {
69478
- _id: "write" /* WRITE */,
69479
- name: "Read/Write",
69480
- permissions: [
69481
- new Permission("query" /* QUERY */, "write" /* WRITE */),
69482
- new Permission("table" /* TABLE */, "write" /* WRITE */),
69483
- new Permission("automation" /* AUTOMATION */, "execute" /* EXECUTE */),
69484
- new Permission("legacy_view" /* LEGACY_VIEW */, "read" /* READ */),
69485
- new Permission("app" /* APP */, "read" /* READ */)
69486
- ]
69487
- },
69488
- POWER: {
69489
- _id: "power" /* POWER */,
69490
- name: "Power",
69491
- permissions: [
69492
- new Permission("table" /* TABLE */, "write" /* WRITE */),
69493
- new Permission("user" /* USER */, "read" /* READ */),
69494
- new Permission("automation" /* AUTOMATION */, "execute" /* EXECUTE */),
69495
- new Permission("webhook" /* WEBHOOK */, "read" /* READ */),
69496
- new Permission("legacy_view" /* LEGACY_VIEW */, "read" /* READ */),
69497
- new Permission("app" /* APP */, "read" /* READ */)
69498
- ]
69499
- },
69500
- ADMIN: {
69501
- _id: "admin" /* ADMIN */,
69502
- name: "Admin",
69503
- permissions: [
69504
- new Permission("table" /* TABLE */, "admin" /* ADMIN */),
69505
- new Permission("user" /* USER */, "admin" /* ADMIN */),
69506
- new Permission("automation" /* AUTOMATION */, "admin" /* ADMIN */),
69507
- new Permission("webhook" /* WEBHOOK */, "read" /* READ */),
69508
- new Permission("query" /* QUERY */, "admin" /* ADMIN */),
69509
- new Permission("legacy_view" /* LEGACY_VIEW */, "read" /* READ */),
69510
- new Permission("app" /* APP */, "read" /* READ */)
69511
- ]
69512
- }
69513
- };
69514
- function getBuiltinPermissions() {
69515
- return (0, import_cloneDeep.default)(BUILTIN_PERMISSIONS);
69516
- }
69517
- function getBuiltinPermissionByID(id) {
69518
- const perms = Object.values(BUILTIN_PERMISSIONS);
69519
- return perms.find((perm) => perm._id === id);
69520
- }
69521
- function doesHaveBasePermission(permType, permLevel, rolesHierarchy) {
69522
- const basePermissions = [
69523
- ...new Set(rolesHierarchy.map((role) => role.permissionId))
69524
- ];
69525
- const builtins = Object.values(BUILTIN_PERMISSIONS);
69526
- let permissions = (0, import_flatten.default)(
69527
- builtins.filter((builtin) => basePermissions.indexOf(builtin._id) !== -1).map((builtin) => builtin.permissions)
69528
- );
69529
- for (let permission of permissions) {
69530
- if (permission.type === permType && getAllowedLevels(permission.level).indexOf(permLevel) !== -1) {
69531
- return true;
69532
- }
69533
- }
69534
- return false;
69535
- }
69536
- function isPermissionLevelHigherThanRead(level) {
69537
- return levelToNumber(level) > 1;
69538
- }
69539
- var BUILDER = "builder" /* BUILDER */;
69540
- var CREATOR = "creator" /* CREATOR */;
69541
- var GLOBAL_BUILDER = "globalBuilder" /* GLOBAL_BUILDER */;
69542
-
69543
- // src/security/roles.ts
69544
- var import_cloneDeep2 = __toESM(require("lodash/fp/cloneDeep"));
69545
- var import_lodash4 = require("lodash");
69356
+ var import_lodash5 = require("lodash");
69546
69357
  var BUILTIN_ROLE_IDS = {
69547
69358
  ADMIN: "ADMIN",
69548
69359
  POWER: "POWER",
@@ -69622,7 +69433,7 @@ var RoleHierarchyTraversal = class {
69622
69433
  }
69623
69434
  }
69624
69435
  }
69625
- return (0, import_lodash4.uniqBy)(roleList, (role2) => role2._id);
69436
+ return (0, import_lodash5.uniqBy)(roleList, (role2) => role2._id);
69626
69437
  }
69627
69438
  };
69628
69439
  var BUILTIN_ROLES = {
@@ -69678,7 +69489,7 @@ var BUILTIN_ROLES = {
69678
69489
  )
69679
69490
  };
69680
69491
  function getBuiltinRoles() {
69681
- return (0, import_cloneDeep2.default)(BUILTIN_ROLES);
69492
+ return (0, import_cloneDeep.default)(BUILTIN_ROLES);
69682
69493
  }
69683
69494
  function isBuiltin(role) {
69684
69495
  return Object.values(BUILTIN_ROLE_IDS).includes(role);
@@ -69697,12 +69508,24 @@ function getBuiltinRole(roleId) {
69697
69508
  if (!role) {
69698
69509
  return void 0;
69699
69510
  }
69700
- return (0, import_cloneDeep2.default)(role);
69511
+ return (0, import_cloneDeep.default)(role);
69512
+ }
69513
+ function validInherits(allRoles, inherits) {
69514
+ if (!inherits) {
69515
+ return false;
69516
+ }
69517
+ const find2 = (id) => allRoles.find((r) => roleIDsAreEqual(r._id, id));
69518
+ if (Array.isArray(inherits)) {
69519
+ const filtered2 = inherits.filter((roleId) => find2(roleId));
69520
+ return inherits.length !== 0 && filtered2.length === inherits.length;
69521
+ } else {
69522
+ return !!find2(inherits);
69523
+ }
69701
69524
  }
69702
69525
  function builtinRoleToNumber(id) {
69703
69526
  const builtins = getBuiltinRoles();
69704
69527
  const MAX = Object.values(builtins).length + 1;
69705
- if (compareRoleIds(id, BUILTIN_IDS.ADMIN) || compareRoleIds(id, BUILTIN_IDS.BUILDER)) {
69528
+ if (roleIDsAreEqual(id, BUILTIN_IDS.ADMIN) || roleIDsAreEqual(id, BUILTIN_IDS.BUILDER)) {
69706
69529
  return MAX;
69707
69530
  }
69708
69531
  let role = builtins[id], count = 0;
@@ -69733,7 +69556,7 @@ async function roleToNumber(id) {
69733
69556
  if (Array.isArray(role.inherits)) {
69734
69557
  const highestBuiltin = role.inherits.map((roleId) => {
69735
69558
  const foundRole = hierarchy.find(
69736
- (role2) => compareRoleIds(role2._id, roleId)
69559
+ (role2) => roleIDsAreEqual(role2._id, roleId)
69737
69560
  );
69738
69561
  if (foundRole) {
69739
69562
  return findNumber(foundRole) + 1;
@@ -69758,7 +69581,7 @@ function lowerBuiltinRoleID(roleId1, roleId2) {
69758
69581
  }
69759
69582
  return builtinRoleToNumber(roleId1) > builtinRoleToNumber(roleId2) ? roleId2 : roleId1;
69760
69583
  }
69761
- function compareRoleIds(roleId1, roleId2) {
69584
+ function roleIDsAreEqual(roleId1, roleId2) {
69762
69585
  return prefixRoleID(roleId1) === prefixRoleID(roleId2);
69763
69586
  }
69764
69587
  function externalRole(role) {
@@ -69778,10 +69601,10 @@ function findRole(roleId, roles, opts) {
69778
69601
  roleId = prefixRoleID(roleId);
69779
69602
  }
69780
69603
  const dbRole = roles.find(
69781
- (role2) => role2._id && compareRoleIds(role2._id, roleId)
69604
+ (role2) => role2._id && roleIDsAreEqual(role2._id, roleId)
69782
69605
  );
69783
69606
  if (!dbRole && !isBuiltin(roleId) && opts?.defaultPublic) {
69784
- return (0, import_cloneDeep2.default)(BUILTIN_ROLES.PUBLIC);
69607
+ return (0, import_cloneDeep.default)(BUILTIN_ROLES.PUBLIC);
69785
69608
  }
69786
69609
  role = Object.assign(role || {}, dbRole);
69787
69610
  if (role?._id) {
@@ -69811,7 +69634,7 @@ async function saveRoles(roles) {
69811
69634
  }
69812
69635
  async function getAllUserRoles(userRoleId, opts) {
69813
69636
  const allRoles = await getAllRoles();
69814
- if (compareRoleIds(userRoleId, BUILTIN_IDS.ADMIN)) {
69637
+ if (roleIDsAreEqual(userRoleId, BUILTIN_IDS.ADMIN)) {
69815
69638
  return allRoles;
69816
69639
  }
69817
69640
  const foundRole = findRole(userRoleId, allRoles, opts);
@@ -69886,7 +69709,7 @@ async function getAllRoles(appId) {
69886
69709
  for (let builtinRoleId of externalBuiltinRoles) {
69887
69710
  const builtinRole = builtinRoles[builtinRoleId];
69888
69711
  const dbBuiltin = roles.filter(
69889
- (dbRole) => compareRoleIds(dbRole._id, builtinRoleId)
69712
+ (dbRole) => roleIDsAreEqual(dbRole._id, builtinRoleId)
69890
69713
  )[0];
69891
69714
  if (dbBuiltin == null) {
69892
69715
  roles.push(builtinRole || builtinRoles.BASIC);
@@ -69921,7 +69744,10 @@ async function shouldIncludePowerRole(db) {
69921
69744
  if (!creationVersion || !import_semver.default.valid(creationVersion)) {
69922
69745
  return true;
69923
69746
  }
69924
- const isGreaterThan3x = import_semver.default.gte(creationVersion, "3.0.0");
69747
+ const isGreaterThan3x = import_semver.default.gte(
69748
+ creationVersion,
69749
+ environment_default.MIN_VERSION_WITHOUT_POWER_ROLE
69750
+ );
69925
69751
  return !isGreaterThan3x;
69926
69752
  }
69927
69753
  var AccessController = class {
@@ -69929,7 +69755,7 @@ var AccessController = class {
69929
69755
  this.userHierarchies = {};
69930
69756
  }
69931
69757
  async hasAccess(tryingRoleId, userRoleId) {
69932
- if (tryingRoleId == null || tryingRoleId === "" || compareRoleIds(tryingRoleId, BUILTIN_IDS.BUILDER) || compareRoleIds(userRoleId, tryingRoleId) || compareRoleIds(userRoleId, BUILTIN_IDS.BUILDER)) {
69758
+ if (tryingRoleId == null || tryingRoleId === "" || roleIDsAreEqual(tryingRoleId, BUILTIN_IDS.BUILDER) || roleIDsAreEqual(userRoleId, tryingRoleId) || roleIDsAreEqual(userRoleId, BUILTIN_IDS.BUILDER)) {
69933
69759
  return true;
69934
69760
  }
69935
69761
  let roleIds = userRoleId ? this.userHierarchies[userRoleId] : null;
@@ -69937,7 +69763,7 @@ var AccessController = class {
69937
69763
  roleIds = await getUserRoleIdHierarchy(userRoleId);
69938
69764
  this.userHierarchies[userRoleId] = roleIds;
69939
69765
  }
69940
- return roleIds?.find((roleId) => compareRoleIds(roleId, tryingRoleId)) !== void 0;
69766
+ return roleIds?.find((roleId) => roleIDsAreEqual(roleId, tryingRoleId)) !== void 0;
69941
69767
  }
69942
69768
  async checkScreensAccess(screens, userRoleId) {
69943
69769
  let accessibleScreens = [];
@@ -74030,6 +73856,145 @@ var DEFINITIONS = [
74030
73856
  }
74031
73857
  ];
74032
73858
 
73859
+ // src/security/permissions.ts
73860
+ var permissions_exports = {};
73861
+ __export(permissions_exports, {
73862
+ BUILDER: () => BUILDER,
73863
+ BUILTIN_PERMISSIONS: () => BUILTIN_PERMISSIONS,
73864
+ CREATOR: () => CREATOR,
73865
+ GLOBAL_BUILDER: () => GLOBAL_BUILDER,
73866
+ Permission: () => Permission,
73867
+ PermissionLevel: () => PermissionLevel,
73868
+ PermissionType: () => PermissionType,
73869
+ doesHaveBasePermission: () => doesHaveBasePermission,
73870
+ getAllowedLevels: () => getAllowedLevels,
73871
+ getBuiltinPermissionByID: () => getBuiltinPermissionByID,
73872
+ getBuiltinPermissions: () => getBuiltinPermissions,
73873
+ isPermissionLevelHigherThanRead: () => isPermissionLevelHigherThanRead,
73874
+ levelToNumber: () => levelToNumber
73875
+ });
73876
+ var import_flatten = __toESM(require("lodash/flatten"));
73877
+ var import_cloneDeep2 = __toESM(require("lodash/fp/cloneDeep"));
73878
+ var Permission = class {
73879
+ constructor(type, level) {
73880
+ this.type = type;
73881
+ this.level = level;
73882
+ }
73883
+ };
73884
+ function levelToNumber(perm) {
73885
+ switch (perm) {
73886
+ case "execute" /* EXECUTE */:
73887
+ return 0;
73888
+ case "read" /* READ */:
73889
+ return 1;
73890
+ case "write" /* WRITE */:
73891
+ return 2;
73892
+ case "admin" /* ADMIN */:
73893
+ return 3;
73894
+ default:
73895
+ return -1;
73896
+ }
73897
+ }
73898
+ function getAllowedLevels(userPermLevel) {
73899
+ switch (userPermLevel) {
73900
+ case "execute" /* EXECUTE */:
73901
+ return ["execute" /* EXECUTE */];
73902
+ case "read" /* READ */:
73903
+ return ["execute" /* EXECUTE */, "read" /* READ */];
73904
+ case "write" /* WRITE */:
73905
+ case "admin" /* ADMIN */:
73906
+ return [
73907
+ "execute" /* EXECUTE */,
73908
+ "read" /* READ */,
73909
+ "write" /* WRITE */
73910
+ ];
73911
+ default:
73912
+ return [];
73913
+ }
73914
+ }
73915
+ var BUILTIN_PERMISSIONS = {
73916
+ PUBLIC: {
73917
+ _id: "public" /* PUBLIC */,
73918
+ name: "Public",
73919
+ permissions: [
73920
+ new Permission("webhook" /* WEBHOOK */, "execute" /* EXECUTE */)
73921
+ ]
73922
+ },
73923
+ READ_ONLY: {
73924
+ _id: "read_only" /* READ_ONLY */,
73925
+ name: "Read only",
73926
+ permissions: [
73927
+ new Permission("query" /* QUERY */, "read" /* READ */),
73928
+ new Permission("table" /* TABLE */, "read" /* READ */),
73929
+ new Permission("app" /* APP */, "read" /* READ */)
73930
+ ]
73931
+ },
73932
+ WRITE: {
73933
+ _id: "write" /* WRITE */,
73934
+ name: "Read/Write",
73935
+ permissions: [
73936
+ new Permission("query" /* QUERY */, "write" /* WRITE */),
73937
+ new Permission("table" /* TABLE */, "write" /* WRITE */),
73938
+ new Permission("automation" /* AUTOMATION */, "execute" /* EXECUTE */),
73939
+ new Permission("legacy_view" /* LEGACY_VIEW */, "read" /* READ */),
73940
+ new Permission("app" /* APP */, "read" /* READ */)
73941
+ ]
73942
+ },
73943
+ POWER: {
73944
+ _id: "power" /* POWER */,
73945
+ name: "Power",
73946
+ permissions: [
73947
+ new Permission("table" /* TABLE */, "write" /* WRITE */),
73948
+ new Permission("user" /* USER */, "read" /* READ */),
73949
+ new Permission("automation" /* AUTOMATION */, "execute" /* EXECUTE */),
73950
+ new Permission("webhook" /* WEBHOOK */, "read" /* READ */),
73951
+ new Permission("legacy_view" /* LEGACY_VIEW */, "read" /* READ */),
73952
+ new Permission("app" /* APP */, "read" /* READ */)
73953
+ ]
73954
+ },
73955
+ ADMIN: {
73956
+ _id: "admin" /* ADMIN */,
73957
+ name: "Admin",
73958
+ permissions: [
73959
+ new Permission("table" /* TABLE */, "admin" /* ADMIN */),
73960
+ new Permission("user" /* USER */, "admin" /* ADMIN */),
73961
+ new Permission("automation" /* AUTOMATION */, "admin" /* ADMIN */),
73962
+ new Permission("webhook" /* WEBHOOK */, "read" /* READ */),
73963
+ new Permission("query" /* QUERY */, "admin" /* ADMIN */),
73964
+ new Permission("legacy_view" /* LEGACY_VIEW */, "read" /* READ */),
73965
+ new Permission("app" /* APP */, "read" /* READ */)
73966
+ ]
73967
+ }
73968
+ };
73969
+ function getBuiltinPermissions() {
73970
+ return (0, import_cloneDeep2.default)(BUILTIN_PERMISSIONS);
73971
+ }
73972
+ function getBuiltinPermissionByID(id) {
73973
+ const perms = Object.values(BUILTIN_PERMISSIONS);
73974
+ return perms.find((perm) => perm._id === id);
73975
+ }
73976
+ function doesHaveBasePermission(permType, permLevel, rolesHierarchy) {
73977
+ const basePermissions = [
73978
+ ...new Set(rolesHierarchy.map((role) => role.permissionId))
73979
+ ];
73980
+ const builtins = Object.values(BUILTIN_PERMISSIONS);
73981
+ let permissions = (0, import_flatten.default)(
73982
+ builtins.filter((builtin) => basePermissions.indexOf(builtin._id) !== -1).map((builtin) => builtin.permissions)
73983
+ );
73984
+ for (let permission of permissions) {
73985
+ if (permission.type === permType && getAllowedLevels(permission.level).indexOf(permLevel) !== -1) {
73986
+ return true;
73987
+ }
73988
+ }
73989
+ return false;
73990
+ }
73991
+ function isPermissionLevelHigherThanRead(level) {
73992
+ return levelToNumber(level) > 1;
73993
+ }
73994
+ var BUILDER = "builder" /* BUILDER */;
73995
+ var CREATOR = "creator" /* CREATOR */;
73996
+ var GLOBAL_BUILDER = "globalBuilder" /* GLOBAL_BUILDER */;
73997
+
74033
73998
  // src/auth/index.ts
74034
73999
  var auth_exports = {};
74035
74000
  __export(auth_exports, {
@@ -75729,7 +75694,7 @@ var SqlTableQueryBuilder = class {
75729
75694
  var sqlTable_default = SqlTableQueryBuilder;
75730
75695
 
75731
75696
  // src/sql/sql.ts
75732
- var import_lodash5 = require("lodash");
75697
+ var import_lodash6 = require("lodash");
75733
75698
  var COUNT_FIELD_NAME = "__bb_total";
75734
75699
  function getBaseLimit() {
75735
75700
  const envLimit = environment_default.SQL_MAX_ROWS ? parseInt(environment_default.SQL_MAX_ROWS) : null;
@@ -75828,9 +75793,6 @@ var InternalBuilder = class {
75828
75793
  const { column } = this.splitter.run(key);
75829
75794
  return this.table.schema[column];
75830
75795
  }
75831
- supportsILike() {
75832
- return !(this.client === "oracledb" /* ORACLE */ || this.client === "sqlite3" /* SQL_LITE */);
75833
- }
75834
75796
  quoteChars() {
75835
75797
  const wrapped = this.knexClient.wrapIdentifier("foo", {});
75836
75798
  return [wrapped[0], wrapped[wrapped.length - 1]];
@@ -75857,8 +75819,25 @@ var InternalBuilder = class {
75857
75819
  const formatter = this.knexClient.formatter(this.knexClient.queryBuilder());
75858
75820
  return formatter.wrap(value, false);
75859
75821
  }
75860
- rawQuotedValue(value) {
75861
- return this.knex.raw(this.quotedValue(value));
75822
+ castIntToString(identifier) {
75823
+ switch (this.client) {
75824
+ case "oracledb" /* ORACLE */: {
75825
+ return this.knex.raw("to_char(??)", [identifier]);
75826
+ }
75827
+ case "pg" /* POSTGRES */: {
75828
+ return this.knex.raw("??::TEXT", [identifier]);
75829
+ }
75830
+ case "mysql2" /* MY_SQL */:
75831
+ case "mariadb" /* MARIADB */: {
75832
+ return this.knex.raw("CAST(?? AS CHAR)", [identifier]);
75833
+ }
75834
+ case "sqlite3" /* SQL_LITE */: {
75835
+ return this.knex.raw("printf('%d', ??)", [identifier]);
75836
+ }
75837
+ case "mssql" /* MS_SQL */: {
75838
+ return this.knex.raw("CONVERT(NVARCHAR, ??)", [identifier]);
75839
+ }
75840
+ }
75862
75841
  }
75863
75842
  // Unfortuantely we cannot rely on knex's identifier escaping because it trims
75864
75843
  // the identifier string before escaping it, which breaks cases for us where
@@ -76009,7 +75988,7 @@ var InternalBuilder = class {
76009
75988
  return body2;
76010
75989
  }
76011
75990
  parseFilters(filters) {
76012
- filters = (0, import_lodash5.cloneDeep)(filters);
75991
+ filters = (0, import_lodash6.cloneDeep)(filters);
76013
75992
  for (const op of Object.values(BasicOperator)) {
76014
75993
  const filter = filters[op];
76015
75994
  if (!filter) {
@@ -76089,7 +76068,7 @@ var InternalBuilder = class {
76089
76068
  if (!matchesTableName) {
76090
76069
  updatedKey = filterKey.replace(
76091
76070
  new RegExp(`^${relationship.column}.`),
76092
- `${aliases[relationship.tableName]}.`
76071
+ `${aliases?.[relationship.tableName] || relationship.tableName}.`
76093
76072
  );
76094
76073
  } else {
76095
76074
  updatedKey = filterKey;
@@ -76547,24 +76526,32 @@ var InternalBuilder = class {
76547
76526
  );
76548
76527
  }
76549
76528
  } else {
76550
- query = query.count(`* as ${aggregation.name}`);
76529
+ if (this.client === "oracledb" /* ORACLE */) {
76530
+ const field = this.convertClobs(`${tableName}.${aggregation.field}`);
76531
+ query = query.select(
76532
+ this.knex.raw(`COUNT(??) as ??`, [field, aggregation.name])
76533
+ );
76534
+ } else {
76535
+ query = query.count(`${aggregation.field} as ${aggregation.name}`);
76536
+ }
76551
76537
  }
76552
76538
  } else {
76553
- const field = `${tableName}.${aggregation.field} as ${aggregation.name}`;
76554
- switch (op) {
76555
- case "sum" /* SUM */:
76556
- query = query.sum(field);
76557
- break;
76558
- case "avg" /* AVG */:
76559
- query = query.avg(field);
76560
- break;
76561
- case "min" /* MIN */:
76562
- query = query.min(field);
76563
- break;
76564
- case "max" /* MAX */:
76565
- query = query.max(field);
76566
- break;
76539
+ const fieldSchema = this.getFieldSchema(aggregation.field);
76540
+ if (!fieldSchema) {
76541
+ throw new Error(
76542
+ `field schema missing for aggregation target: ${aggregation.field}`
76543
+ );
76544
+ }
76545
+ let aggregate = this.knex.raw("??(??)", [
76546
+ this.knex.raw(op),
76547
+ this.rawQuotedIdentifier(`${tableName}.${aggregation.field}`)
76548
+ ]);
76549
+ if (fieldSchema.type === "bigint" /* BIGINT */) {
76550
+ aggregate = this.castIntToString(aggregate);
76567
76551
  }
76552
+ query = query.select(
76553
+ this.knex.raw("?? as ??", [aggregate, aggregation.name])
76554
+ );
76568
76555
  }
76569
76556
  }
76570
76557
  return query;
@@ -76812,7 +76799,7 @@ var InternalBuilder = class {
76812
76799
  for (const [column, schema] of Object.entries(
76813
76800
  this.query.meta.table.schema
76814
76801
  )) {
76815
- if (schema.constraints?.presence === true || schema.type === "formula" /* FORMULA */ || schema.type === "auto" /* AUTO */ || schema.type === "link" /* LINK */) {
76802
+ if (schema.constraints?.presence === true || schema.type === "formula" /* FORMULA */ || schema.type === "auto" /* AUTO */ || schema.type === "link" /* LINK */ || schema.type === "ai" /* AI */) {
76816
76803
  continue;
76817
76804
  }
76818
76805
  const value = parsedBody[column];
@@ -76899,7 +76886,7 @@ var InternalBuilder = class {
76899
76886
  query = this.addSorting(query);
76900
76887
  }
76901
76888
  query = this.addFilters(query, filters, { relationship: true });
76902
- if (relationships?.length) {
76889
+ if (relationships?.length && aggregations.length === 0) {
76903
76890
  const mainTable = this.query.tableAliases?.[this.query.endpoint.entityId] || this.query.endpoint.entityId;
76904
76891
  const cte = this.addSorting(
76905
76892
  this.knex.with("paginated", query).select(this.generateSelectStatement()).from({
@@ -76907,9 +76894,8 @@ var InternalBuilder = class {
76907
76894
  })
76908
76895
  );
76909
76896
  return this.addJsonRelationships(cte, tableName, relationships);
76910
- } else {
76911
- return query;
76912
76897
  }
76898
+ return query;
76913
76899
  }
76914
76900
  update(opts) {
76915
76901
  const { body: body2, filters } = this.query;