@budibase/backend-core 2.23.5 → 2.23.7

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
@@ -54720,6 +54720,35 @@ var Header = /* @__PURE__ */ ((Header2) => {
54720
54720
  return Header2;
54721
54721
  })(Header || {});
54722
54722
 
54723
+ // ../shared-core/src/constants/fields.ts
54724
+ var SWITCHABLE_TYPES = {
54725
+ ["string" /* STRING */]: [
54726
+ "string" /* STRING */,
54727
+ "options" /* OPTIONS */,
54728
+ "longform" /* LONGFORM */,
54729
+ "barcodeqr" /* BARCODEQR */
54730
+ ],
54731
+ ["options" /* OPTIONS */]: [
54732
+ "options" /* OPTIONS */,
54733
+ "string" /* STRING */,
54734
+ "longform" /* LONGFORM */,
54735
+ "barcodeqr" /* BARCODEQR */
54736
+ ],
54737
+ ["longform" /* LONGFORM */]: [
54738
+ "longform" /* LONGFORM */,
54739
+ "string" /* STRING */,
54740
+ "options" /* OPTIONS */,
54741
+ "barcodeqr" /* BARCODEQR */
54742
+ ],
54743
+ ["barcodeqr" /* BARCODEQR */]: [
54744
+ "barcodeqr" /* BARCODEQR */,
54745
+ "string" /* STRING */,
54746
+ "options" /* OPTIONS */,
54747
+ "longform" /* LONGFORM */
54748
+ ],
54749
+ ["number" /* NUMBER */]: ["number" /* NUMBER */, "boolean" /* BOOLEAN */]
54750
+ };
54751
+
54723
54752
  // ../shared-core/src/constants/index.ts
54724
54753
  var OperatorOptions = {
54725
54754
  Equals: {
@@ -54771,14 +54800,108 @@ var OperatorOptions = {
54771
54800
  label: "Has any"
54772
54801
  }
54773
54802
  };
54803
+ var SqlNumberTypeRangeMap = {
54804
+ integer: {
54805
+ max: 2147483647,
54806
+ min: -2147483648
54807
+ },
54808
+ int: {
54809
+ max: 2147483647,
54810
+ min: -2147483648
54811
+ },
54812
+ smallint: {
54813
+ max: 32767,
54814
+ min: -32768
54815
+ },
54816
+ mediumint: {
54817
+ max: 8388607,
54818
+ min: -8388608
54819
+ }
54820
+ };
54774
54821
 
54775
54822
  // ../shared-core/src/filters.ts
54823
+ var filters_exports = {};
54824
+ __export(filters_exports, {
54825
+ NoEmptyFilterStrings: () => NoEmptyFilterStrings,
54826
+ buildLuceneQuery: () => buildLuceneQuery,
54827
+ getValidOperatorsForType: () => getValidOperatorsForType,
54828
+ hasFilters: () => hasFilters,
54829
+ luceneLimit: () => luceneLimit,
54830
+ luceneSort: () => luceneSort,
54831
+ removeKeyNumbering: () => removeKeyNumbering,
54832
+ runLuceneQuery: () => runLuceneQuery
54833
+ });
54776
54834
  var import_dayjs = __toESM(require_dayjs_min());
54777
54835
 
54836
+ // ../shared-core/src/helpers/helpers.ts
54837
+ var deepGet = (obj, key) => {
54838
+ if (!obj || !key) {
54839
+ return null;
54840
+ }
54841
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
54842
+ return obj[key];
54843
+ }
54844
+ const split = key.split(".");
54845
+ for (let i = 0; i < split.length; i++) {
54846
+ obj = obj?.[split[i]];
54847
+ }
54848
+ return obj;
54849
+ };
54850
+
54778
54851
  // ../shared-core/src/helpers/cron.ts
54779
54852
  var import_cron_validate = __toESM(require_lib2());
54780
54853
 
54781
54854
  // ../shared-core/src/filters.ts
54855
+ var HBS_REGEX = /{{([^{].*?)}}/g;
54856
+ var getValidOperatorsForType = (fieldType, field, datasource2) => {
54857
+ const Op = OperatorOptions;
54858
+ const stringOps = [
54859
+ Op.Equals,
54860
+ Op.NotEquals,
54861
+ Op.StartsWith,
54862
+ Op.Like,
54863
+ Op.Empty,
54864
+ Op.NotEmpty,
54865
+ Op.In
54866
+ ];
54867
+ const numOps = [
54868
+ Op.Equals,
54869
+ Op.NotEquals,
54870
+ Op.MoreThan,
54871
+ Op.LessThan,
54872
+ Op.Empty,
54873
+ Op.NotEmpty,
54874
+ Op.In
54875
+ ];
54876
+ let ops = [];
54877
+ const { type, subtype, formulaType } = fieldType;
54878
+ if (type === "string" /* STRING */) {
54879
+ ops = stringOps;
54880
+ } else if (type === "number" /* NUMBER */ || type === "bigint" /* BIGINT */) {
54881
+ ops = numOps;
54882
+ } else if (type === "options" /* OPTIONS */) {
54883
+ ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty, Op.In];
54884
+ } else if (type === "array" /* ARRAY */) {
54885
+ ops = [Op.Contains, Op.NotContains, Op.Empty, Op.NotEmpty, Op.ContainsAny];
54886
+ } else if (type === "boolean" /* BOOLEAN */) {
54887
+ ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty];
54888
+ } else if (type === "longform" /* LONGFORM */) {
54889
+ ops = stringOps;
54890
+ } else if (type === "datetime" /* DATETIME */) {
54891
+ ops = numOps;
54892
+ } else if (type === "formula" /* FORMULA */ && formulaType === "static" /* STATIC */) {
54893
+ ops = stringOps.concat([Op.MoreThan, Op.LessThan]);
54894
+ } else if (type === "bb_reference" /* BB_REFERENCE */ && subtype == "user" /* USER */) {
54895
+ ops = [Op.Equals, Op.NotEquals, Op.Empty, Op.NotEmpty, Op.In];
54896
+ } else if (type === "bb_reference" /* BB_REFERENCE */ && subtype == "users" /* USERS */) {
54897
+ ops = [Op.Contains, Op.NotContains, Op.ContainsAny, Op.Empty, Op.NotEmpty];
54898
+ }
54899
+ const externalTable = datasource2?.tableId?.includes("datasource_plus");
54900
+ if (field === "_id" && externalTable) {
54901
+ ops = [Op.Equals, Op.NotEquals, Op.In];
54902
+ }
54903
+ return ops;
54904
+ };
54782
54905
  var NoEmptyFilterStrings = [
54783
54906
  OperatorOptions.StartsWith.value,
54784
54907
  OperatorOptions.Like.value,
@@ -54787,6 +54910,283 @@ var NoEmptyFilterStrings = [
54787
54910
  OperatorOptions.Contains.value,
54788
54911
  OperatorOptions.NotContains.value
54789
54912
  ];
54913
+ var cleanupQuery = (query) => {
54914
+ if (!query) {
54915
+ return query;
54916
+ }
54917
+ for (let filterField of NoEmptyFilterStrings) {
54918
+ const operator = filterField;
54919
+ if (!query[operator]) {
54920
+ continue;
54921
+ }
54922
+ for (let [key, value] of Object.entries(query[operator])) {
54923
+ if (value == null || value === "") {
54924
+ delete query[operator][key];
54925
+ }
54926
+ }
54927
+ }
54928
+ return query;
54929
+ };
54930
+ var removeKeyNumbering = (key) => {
54931
+ if (typeof key === "string" && key.match(/\d[0-9]*:/g) != null) {
54932
+ const parts = key.split(":");
54933
+ parts.shift();
54934
+ return parts.join(":");
54935
+ } else {
54936
+ return key;
54937
+ }
54938
+ };
54939
+ var buildLuceneQuery = (filter) => {
54940
+ let query = {
54941
+ string: {},
54942
+ fuzzy: {},
54943
+ range: {},
54944
+ equal: {},
54945
+ notEqual: {},
54946
+ empty: {},
54947
+ notEmpty: {},
54948
+ contains: {},
54949
+ notContains: {},
54950
+ oneOf: {},
54951
+ containsAny: {}
54952
+ };
54953
+ if (!Array.isArray(filter)) {
54954
+ return query;
54955
+ }
54956
+ filter.forEach((expression) => {
54957
+ let { operator, field, type, value, externalType, onEmptyFilter } = expression;
54958
+ const queryOperator = operator;
54959
+ const isHbs = typeof value === "string" && (value.match(HBS_REGEX) || []).length > 0;
54960
+ if (operator === "allOr") {
54961
+ query.allOr = true;
54962
+ return;
54963
+ }
54964
+ if (onEmptyFilter) {
54965
+ query.onEmptyFilter = onEmptyFilter;
54966
+ return;
54967
+ }
54968
+ if (type === "datetime" && !isHbs && queryOperator !== "empty" && queryOperator !== "notEmpty") {
54969
+ if (!value) {
54970
+ return;
54971
+ }
54972
+ try {
54973
+ value = new Date(value).toISOString();
54974
+ } catch (error) {
54975
+ return;
54976
+ }
54977
+ }
54978
+ if (type === "number" && typeof value === "string" && !isHbs) {
54979
+ if (queryOperator === "oneOf") {
54980
+ value = value.split(",").map((item) => parseFloat(item));
54981
+ } else {
54982
+ value = parseFloat(value);
54983
+ }
54984
+ }
54985
+ if (type === "boolean") {
54986
+ value = `${value}`?.toLowerCase() === "true";
54987
+ }
54988
+ if (["contains", "notContains", "containsAny"].includes(operator) && type === "array" && typeof value === "string") {
54989
+ value = value.split(",");
54990
+ }
54991
+ if (operator.startsWith("range") && query.range) {
54992
+ const minint = SqlNumberTypeRangeMap[externalType]?.min || Number.MIN_SAFE_INTEGER;
54993
+ const maxint = SqlNumberTypeRangeMap[externalType]?.max || Number.MAX_SAFE_INTEGER;
54994
+ if (!query.range[field]) {
54995
+ query.range[field] = {
54996
+ low: type === "number" ? minint : "0000-00-00T00:00:00.000Z",
54997
+ high: type === "number" ? maxint : "9999-00-00T00:00:00.000Z"
54998
+ };
54999
+ }
55000
+ if (operator === "rangeLow" && value != null && value !== "") {
55001
+ query.range[field].low = value;
55002
+ } else if (operator === "rangeHigh" && value != null && value !== "") {
55003
+ query.range[field].high = value;
55004
+ }
55005
+ } else if (query[queryOperator] && operator !== "onEmptyFilter") {
55006
+ if (type === "boolean") {
55007
+ if (queryOperator === "equal" && value === false) {
55008
+ query.notEqual = query.notEqual || {};
55009
+ query.notEqual[field] = true;
55010
+ } else if (queryOperator === "notEqual" && value === false) {
55011
+ query.equal = query.equal || {};
55012
+ query.equal[field] = true;
55013
+ } else {
55014
+ query[queryOperator] = query[queryOperator] || {};
55015
+ query[queryOperator][field] = value;
55016
+ }
55017
+ } else {
55018
+ query[queryOperator] = query[queryOperator] || {};
55019
+ query[queryOperator][field] = value;
55020
+ }
55021
+ }
55022
+ });
55023
+ return query;
55024
+ };
55025
+ var runLuceneQuery = (docs, query) => {
55026
+ if (!docs || !Array.isArray(docs)) {
55027
+ return [];
55028
+ }
55029
+ if (!query) {
55030
+ return docs;
55031
+ }
55032
+ query = cleanupQuery(query);
55033
+ const match = (type, failFn) => (doc) => {
55034
+ const filters = Object.entries(query[type] || {});
55035
+ for (let i = 0; i < filters.length; i++) {
55036
+ const [key, testValue] = filters[i];
55037
+ const docValue = deepGet(doc, removeKeyNumbering(key));
55038
+ if (failFn(docValue, testValue)) {
55039
+ return false;
55040
+ }
55041
+ }
55042
+ return true;
55043
+ };
55044
+ const stringMatch = match(
55045
+ "string" /* STRING */,
55046
+ (docValue, testValue) => {
55047
+ return !docValue || !docValue?.toLowerCase().startsWith(testValue?.toLowerCase());
55048
+ }
55049
+ );
55050
+ const fuzzyMatch = match(
55051
+ "fuzzy" /* FUZZY */,
55052
+ (docValue, testValue) => {
55053
+ return !docValue || !docValue?.toLowerCase().startsWith(testValue?.toLowerCase());
55054
+ }
55055
+ );
55056
+ const rangeMatch = match(
55057
+ "range" /* RANGE */,
55058
+ (docValue, testValue) => {
55059
+ if (docValue == null || docValue === "") {
55060
+ return true;
55061
+ }
55062
+ if (!isNaN(+docValue)) {
55063
+ return +docValue < testValue.low || +docValue > testValue.high;
55064
+ }
55065
+ if ((0, import_dayjs.default)(docValue).isValid()) {
55066
+ return new Date(docValue).getTime() < new Date(testValue.low).getTime() || new Date(docValue).getTime() > new Date(testValue.high).getTime();
55067
+ }
55068
+ return false;
55069
+ }
55070
+ );
55071
+ const equalMatch = match(
55072
+ "equal" /* EQUAL */,
55073
+ (docValue, testValue) => {
55074
+ return testValue != null && testValue !== "" && docValue !== testValue;
55075
+ }
55076
+ );
55077
+ const notEqualMatch = match(
55078
+ "notEqual" /* NOT_EQUAL */,
55079
+ (docValue, testValue) => {
55080
+ return testValue != null && testValue !== "" && docValue === testValue;
55081
+ }
55082
+ );
55083
+ const emptyMatch = match(
55084
+ "empty" /* EMPTY */,
55085
+ (docValue) => {
55086
+ return docValue != null && docValue !== "";
55087
+ }
55088
+ );
55089
+ const notEmptyMatch = match(
55090
+ "notEmpty" /* NOT_EMPTY */,
55091
+ (docValue) => {
55092
+ return docValue == null || docValue === "";
55093
+ }
55094
+ );
55095
+ const oneOf = match(
55096
+ "oneOf" /* ONE_OF */,
55097
+ (docValue, testValue) => {
55098
+ if (typeof testValue === "string") {
55099
+ testValue = testValue.split(",");
55100
+ if (typeof docValue === "number") {
55101
+ testValue = testValue.map((item) => parseFloat(item));
55102
+ }
55103
+ }
55104
+ return !testValue?.includes(docValue);
55105
+ }
55106
+ );
55107
+ const containsAny = match(
55108
+ "containsAny" /* CONTAINS_ANY */,
55109
+ (docValue, testValue) => {
55110
+ return !docValue?.includes(...testValue);
55111
+ }
55112
+ );
55113
+ const contains = match(
55114
+ "contains" /* CONTAINS */,
55115
+ (docValue, testValue) => {
55116
+ return !testValue?.every((item) => docValue?.includes(item));
55117
+ }
55118
+ );
55119
+ const notContains = match(
55120
+ "notContains" /* NOT_CONTAINS */,
55121
+ (docValue, testValue) => {
55122
+ return testValue?.every((item) => docValue?.includes(item));
55123
+ }
55124
+ );
55125
+ const docMatch = (doc) => {
55126
+ const filterFunctions = {
55127
+ string: stringMatch,
55128
+ fuzzy: fuzzyMatch,
55129
+ range: rangeMatch,
55130
+ equal: equalMatch,
55131
+ notEqual: notEqualMatch,
55132
+ empty: emptyMatch,
55133
+ notEmpty: notEmptyMatch,
55134
+ oneOf,
55135
+ contains,
55136
+ containsAny,
55137
+ notContains
55138
+ };
55139
+ const activeFilterKeys = Object.entries(query || {}).filter(
55140
+ ([key, value]) => !["allOr", "onEmptyFilter"].includes(key) && value && Object.keys(value).length > 0
55141
+ ).map(([key]) => key);
55142
+ const results = activeFilterKeys.map((filterKey) => {
55143
+ return filterFunctions[filterKey]?.(doc) ?? false;
55144
+ });
55145
+ if (query.allOr) {
55146
+ return results.some((result) => result === true);
55147
+ } else {
55148
+ return results.every((result) => result === true);
55149
+ }
55150
+ };
55151
+ return docs.filter(docMatch);
55152
+ };
55153
+ var luceneSort = (docs, sort, sortOrder, sortType = "string" /* STRING */) => {
55154
+ if (!sort || !sortOrder || !sortType) {
55155
+ return docs;
55156
+ }
55157
+ const parse = sortType === "string" ? (x) => `${x}` : (x) => parseFloat(x);
55158
+ return docs.slice().sort((a, b) => {
55159
+ const colA = parse(a[sort]);
55160
+ const colB = parse(b[sort]);
55161
+ if (sortOrder.toLowerCase() === "descending") {
55162
+ return colA > colB ? -1 : 1;
55163
+ } else {
55164
+ return colA > colB ? 1 : -1;
55165
+ }
55166
+ });
55167
+ };
55168
+ var luceneLimit = (docs, limit) => {
55169
+ const numLimit = parseFloat(limit);
55170
+ if (isNaN(numLimit)) {
55171
+ return docs;
55172
+ }
55173
+ return docs.slice(0, numLimit);
55174
+ };
55175
+ var hasFilters = (query) => {
55176
+ if (!query) {
55177
+ return false;
55178
+ }
55179
+ const skipped = ["allOr", "onEmptyFilter"];
55180
+ for (let [key, value] of Object.entries(query)) {
55181
+ if (skipped.includes(key) || typeof value !== "object") {
55182
+ continue;
55183
+ }
55184
+ if (Object.keys(value || {}).length !== 0) {
55185
+ return true;
55186
+ }
55187
+ }
55188
+ return false;
55189
+ };
54790
55190
 
54791
55191
  // ../shared-core/src/utils.ts
54792
55192
  var utils_exports = {};
@@ -55262,7 +55662,7 @@ var environment = {
55262
55662
  ENCRYPTION_KEY: process.env.ENCRYPTION_KEY,
55263
55663
  API_ENCRYPTION_KEY: getAPIEncryptionKey(),
55264
55664
  COUCH_DB_URL: process.env.COUCH_DB_URL || "http://localhost:4005",
55265
- COUCH_DB_SQL_URL: process.env.COUCH_DB_SQL_URL || "http://localhost:4984",
55665
+ COUCH_DB_SQL_URL: process.env.COUCH_DB_SQL_URL || "http://localhost:4006",
55266
55666
  COUCH_DB_USERNAME: process.env.COUCH_DB_USER,
55267
55667
  COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,
55268
55668
  GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,
@@ -56602,7 +57002,7 @@ __export(db_exports, {
56602
57002
  queryPlatformView: () => queryPlatformView,
56603
57003
  queryView: () => queryView,
56604
57004
  queryViewRaw: () => queryViewRaw,
56605
- removeKeyNumbering: () => removeKeyNumbering,
57005
+ removeKeyNumbering: () => removeKeyNumbering2,
56606
57006
  searchIndexes: () => searchIndexes_exports
56607
57007
  });
56608
57008
 
@@ -57191,16 +57591,7 @@ var Replication_default = Replication;
57191
57591
 
57192
57592
  // src/db/lucene.ts
57193
57593
  var import_node_fetch2 = __toESM(require("node-fetch"));
57194
- var QUERY_START_REGEX = /\d[0-9]*:/g;
57195
- function removeKeyNumbering(key) {
57196
- if (typeof key === "string" && key.match(QUERY_START_REGEX) != null) {
57197
- const parts = key.split(":");
57198
- parts.shift();
57199
- return parts.join(":");
57200
- } else {
57201
- return key;
57202
- }
57203
- }
57594
+ var removeKeyNumbering2 = filters_exports.removeKeyNumbering;
57204
57595
  var QueryBuilder = class _QueryBuilder {
57205
57596
  #dbName;
57206
57597
  #index;
@@ -57395,7 +57786,7 @@ var QueryBuilder = class _QueryBuilder {
57395
57786
  compressFilters(filters) {
57396
57787
  const compressed = {};
57397
57788
  for (let key of Object.keys(filters)) {
57398
- const finalKey = removeKeyNumbering(key);
57789
+ const finalKey = removeKeyNumbering2(key);
57399
57790
  if (compressed[finalKey]) {
57400
57791
  compressed[finalKey] = compressed[finalKey].concat(filters[key]);
57401
57792
  } else {
@@ -57483,7 +57874,7 @@ var QueryBuilder = class _QueryBuilder {
57483
57874
  function build(structure, queryFn, opts) {
57484
57875
  let built = "";
57485
57876
  for (let [key, value] of Object.entries(structure)) {
57486
- key = removeKeyNumbering(key);
57877
+ key = removeKeyNumbering2(key);
57487
57878
  key = builder.preprocess(builder.handleSpaces(key), {
57488
57879
  escape: true
57489
57880
  });
@@ -60998,7 +61389,6 @@ var InMemoryQueue = class {
60998
61389
  * a JSON message as this is required by Bull.
60999
61390
  * @param repeat serves no purpose for the import queue.
61000
61391
  */
61001
- // eslint-disable-next-line no-unused-vars
61002
61392
  async add(data, opts) {
61003
61393
  const jobId = opts?.jobId?.toString();
61004
61394
  if (jobId && this._queuedJobIds.has(jobId)) {
@@ -61042,8 +61432,7 @@ var InMemoryQueue = class {
61042
61432
  async getRepeatableJobs() {
61043
61433
  return [];
61044
61434
  }
61045
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
61046
- async removeJobs(pattern) {
61435
+ async removeJobs(_pattern) {
61047
61436
  }
61048
61437
  /**
61049
61438
  * Implemented for tests