@budibase/backend-core 2.32.11 → 2.32.13
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 +504 -172
- package/dist/index.js.map +4 -4
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +4 -4
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/db/couch/DatabaseImpl.js +10 -2
- package/dist/src/db/couch/DatabaseImpl.js.map +1 -1
- package/dist/src/features/features.d.ts +47 -0
- package/dist/src/features/features.js +269 -0
- package/dist/src/features/features.js.map +1 -0
- package/dist/src/features/index.d.ts +2 -39
- package/dist/src/features/index.js +6 -235
- package/dist/src/features/index.js.map +1 -1
- package/dist/src/features/tests/utils.d.ts +3 -0
- package/dist/src/features/tests/utils.js +56 -0
- package/dist/src/features/tests/utils.js.map +1 -0
- package/dist/src/middleware/passport/sso/sso.js +0 -25
- package/dist/src/middleware/passport/sso/sso.js.map +1 -1
- package/dist/src/sql/sql.js +93 -35
- package/dist/src/sql/sql.js.map +1 -1
- package/dist/src/users/users.js +8 -1
- package/dist/src/users/users.js.map +1 -1
- package/dist/tests/core/utilities/structures/accounts.d.ts +1 -6
- package/dist/tests/core/utilities/structures/accounts.js +4 -58
- package/dist/tests/core/utilities/structures/accounts.js.map +1 -1
- package/dist/tests/core/utilities/structures/users.js +2 -5
- package/dist/tests/core/utilities/structures/users.js.map +1 -1
- package/package.json +4 -4
- package/src/db/couch/DatabaseImpl.ts +12 -2
- package/src/features/features.ts +300 -0
- package/src/features/index.ts +2 -281
- package/src/features/tests/utils.ts +64 -0
- package/src/middleware/passport/sso/sso.ts +0 -24
- package/src/sql/sql.ts +107 -36
- package/src/users/users.ts +10 -2
- package/tests/core/utilities/structures/accounts.ts +1 -66
- package/tests/core/utilities/structures/users.ts +0 -5
package/dist/index.js
CHANGED
|
@@ -61260,7 +61260,7 @@ __export(src_exports, {
|
|
|
61260
61260
|
sql: () => sql_exports,
|
|
61261
61261
|
tenancy: () => tenancy,
|
|
61262
61262
|
timers: () => timers_exports,
|
|
61263
|
-
userUtils: () =>
|
|
61263
|
+
userUtils: () => utils_exports6,
|
|
61264
61264
|
users: () => users_exports3,
|
|
61265
61265
|
utils: () => utils_exports4,
|
|
61266
61266
|
withEnv: () => withEnv
|
|
@@ -61911,6 +61911,7 @@ __export(filters_exports, {
|
|
|
61911
61911
|
ColumnSplitter: () => ColumnSplitter,
|
|
61912
61912
|
NoEmptyFilterStrings: () => NoEmptyFilterStrings,
|
|
61913
61913
|
buildQuery: () => buildQuery,
|
|
61914
|
+
buildQueryLegacy: () => buildQueryLegacy,
|
|
61914
61915
|
cleanupQuery: () => cleanupQuery,
|
|
61915
61916
|
fixupFilterArrays: () => fixupFilterArrays,
|
|
61916
61917
|
getKeyNumbering: () => getKeyNumbering,
|
|
@@ -61926,6 +61927,164 @@ __export(filters_exports, {
|
|
|
61926
61927
|
});
|
|
61927
61928
|
var import_dayjs = __toESM(require_dayjs_min());
|
|
61928
61929
|
|
|
61930
|
+
// ../shared-core/src/utils.ts
|
|
61931
|
+
var utils_exports = {};
|
|
61932
|
+
__export(utils_exports, {
|
|
61933
|
+
filterValueToLabel: () => filterValueToLabel,
|
|
61934
|
+
hasSchema: () => hasSchema,
|
|
61935
|
+
isSupportedUserSearch: () => isSupportedUserSearch,
|
|
61936
|
+
parallelForeach: () => parallelForeach,
|
|
61937
|
+
processSearchFilters: () => processSearchFilters,
|
|
61938
|
+
trimOtherProps: () => trimOtherProps,
|
|
61939
|
+
unreachable: () => unreachable
|
|
61940
|
+
});
|
|
61941
|
+
function unreachable(value, message = `No such case in exhaustive switch: ${value}`) {
|
|
61942
|
+
throw new Error(message);
|
|
61943
|
+
}
|
|
61944
|
+
async function parallelForeach(items, task, maxConcurrency) {
|
|
61945
|
+
const promises = [];
|
|
61946
|
+
let index2 = 0;
|
|
61947
|
+
const processItem = async (item) => {
|
|
61948
|
+
try {
|
|
61949
|
+
await task(item);
|
|
61950
|
+
} finally {
|
|
61951
|
+
processNext();
|
|
61952
|
+
}
|
|
61953
|
+
};
|
|
61954
|
+
const processNext = () => {
|
|
61955
|
+
if (index2 >= items.length) {
|
|
61956
|
+
return;
|
|
61957
|
+
}
|
|
61958
|
+
const item = items[index2];
|
|
61959
|
+
index2++;
|
|
61960
|
+
const promise = processItem(item);
|
|
61961
|
+
promises.push(promise);
|
|
61962
|
+
if (promises.length >= maxConcurrency) {
|
|
61963
|
+
Promise.race(promises).then(processNext);
|
|
61964
|
+
} else {
|
|
61965
|
+
processNext();
|
|
61966
|
+
}
|
|
61967
|
+
};
|
|
61968
|
+
processNext();
|
|
61969
|
+
await Promise.all(promises);
|
|
61970
|
+
}
|
|
61971
|
+
function filterValueToLabel() {
|
|
61972
|
+
return Object.keys(OperatorOptions).reduce(
|
|
61973
|
+
(acc, key) => {
|
|
61974
|
+
const ops = OperatorOptions;
|
|
61975
|
+
const op = ops[key];
|
|
61976
|
+
acc[op["value"]] = op.label;
|
|
61977
|
+
return acc;
|
|
61978
|
+
},
|
|
61979
|
+
{}
|
|
61980
|
+
);
|
|
61981
|
+
}
|
|
61982
|
+
function hasSchema(test) {
|
|
61983
|
+
return typeof test === "object" && !Array.isArray(test) && test !== null && !(test instanceof Date) && Object.keys(test).length > 0;
|
|
61984
|
+
}
|
|
61985
|
+
function trimOtherProps(object, allowedProps) {
|
|
61986
|
+
const result = Object.keys(object).filter((key) => allowedProps.includes(key)).reduce(
|
|
61987
|
+
(acc, key) => ({ ...acc, [key]: object[key] }),
|
|
61988
|
+
{}
|
|
61989
|
+
);
|
|
61990
|
+
return result;
|
|
61991
|
+
}
|
|
61992
|
+
function isSupportedUserSearch(query) {
|
|
61993
|
+
const allowed = [
|
|
61994
|
+
{ op: "string" /* STRING */, key: "email" },
|
|
61995
|
+
{ op: "equal" /* EQUAL */, key: "_id" },
|
|
61996
|
+
{ op: "oneOf" /* ONE_OF */, key: "_id" }
|
|
61997
|
+
];
|
|
61998
|
+
for (const [key, operation] of Object.entries(query)) {
|
|
61999
|
+
if (typeof operation !== "object") {
|
|
62000
|
+
return false;
|
|
62001
|
+
}
|
|
62002
|
+
if (isLogicalSearchOperator(key)) {
|
|
62003
|
+
for (const condition of query[key].conditions) {
|
|
62004
|
+
if (!isSupportedUserSearch(condition)) {
|
|
62005
|
+
return false;
|
|
62006
|
+
}
|
|
62007
|
+
}
|
|
62008
|
+
return true;
|
|
62009
|
+
}
|
|
62010
|
+
const fields = Object.keys(operation || {});
|
|
62011
|
+
if (fields.length === 0) {
|
|
62012
|
+
continue;
|
|
62013
|
+
}
|
|
62014
|
+
const allowedOperation = allowed.find(
|
|
62015
|
+
(allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
|
|
62016
|
+
);
|
|
62017
|
+
if (!allowedOperation) {
|
|
62018
|
+
return false;
|
|
62019
|
+
}
|
|
62020
|
+
}
|
|
62021
|
+
return true;
|
|
62022
|
+
}
|
|
62023
|
+
var processSearchFilters = (filters) => {
|
|
62024
|
+
if (!filters) {
|
|
62025
|
+
return;
|
|
62026
|
+
}
|
|
62027
|
+
const defaultCfg = {
|
|
62028
|
+
logicalOperator: "all" /* ALL */,
|
|
62029
|
+
groups: []
|
|
62030
|
+
};
|
|
62031
|
+
const filterAllowedKeys = [
|
|
62032
|
+
"field",
|
|
62033
|
+
"operator",
|
|
62034
|
+
"value",
|
|
62035
|
+
"type",
|
|
62036
|
+
"externalType",
|
|
62037
|
+
"valueType",
|
|
62038
|
+
"noValue",
|
|
62039
|
+
"formulaType"
|
|
62040
|
+
];
|
|
62041
|
+
if (Array.isArray(filters)) {
|
|
62042
|
+
let baseGroup = {
|
|
62043
|
+
filters: [],
|
|
62044
|
+
logicalOperator: "all" /* ALL */
|
|
62045
|
+
};
|
|
62046
|
+
return filters.reduce((acc, filter) => {
|
|
62047
|
+
const filterPropertyKeys = Object.keys(filter).sort((a, b) => {
|
|
62048
|
+
return a.localeCompare(b);
|
|
62049
|
+
}).filter((key) => key in filter);
|
|
62050
|
+
if (filterPropertyKeys.length == 1) {
|
|
62051
|
+
const key = filterPropertyKeys[0], value = filter[key];
|
|
62052
|
+
if (key === "onEmptyFilter") {
|
|
62053
|
+
acc.onEmptyFilter = value;
|
|
62054
|
+
} else if (key === "operator" && value === "allOr") {
|
|
62055
|
+
baseGroup.logicalOperator = "any" /* ANY */;
|
|
62056
|
+
}
|
|
62057
|
+
return acc;
|
|
62058
|
+
}
|
|
62059
|
+
const allowedFilterSettings = filterPropertyKeys.reduce(
|
|
62060
|
+
(acc2, key) => {
|
|
62061
|
+
const value = filter[key];
|
|
62062
|
+
if (filterAllowedKeys.includes(key)) {
|
|
62063
|
+
if (key === "field") {
|
|
62064
|
+
acc2.push([key, removeKeyNumbering(value)]);
|
|
62065
|
+
} else {
|
|
62066
|
+
acc2.push([key, value]);
|
|
62067
|
+
}
|
|
62068
|
+
}
|
|
62069
|
+
return acc2;
|
|
62070
|
+
},
|
|
62071
|
+
[]
|
|
62072
|
+
);
|
|
62073
|
+
const migratedFilter = Object.fromEntries(
|
|
62074
|
+
allowedFilterSettings
|
|
62075
|
+
);
|
|
62076
|
+
baseGroup.filters.push(migratedFilter);
|
|
62077
|
+
if (!acc.groups || !acc.groups.length) {
|
|
62078
|
+
acc.groups = [baseGroup];
|
|
62079
|
+
}
|
|
62080
|
+
return acc;
|
|
62081
|
+
}, defaultCfg);
|
|
62082
|
+
} else if (!filters?.groups) {
|
|
62083
|
+
return;
|
|
62084
|
+
}
|
|
62085
|
+
return filters;
|
|
62086
|
+
};
|
|
62087
|
+
|
|
61929
62088
|
// ../shared-core/src/helpers/index.ts
|
|
61930
62089
|
var helpers_exports = {};
|
|
61931
62090
|
__export(helpers_exports, {
|
|
@@ -62130,6 +62289,7 @@ var views_exports = {};
|
|
|
62130
62289
|
__export(views_exports, {
|
|
62131
62290
|
basicFields: () => basicFields,
|
|
62132
62291
|
calculationFields: () => calculationFields,
|
|
62292
|
+
hasCalculationFields: () => hasCalculationFields,
|
|
62133
62293
|
isBasicViewField: () => isBasicViewField,
|
|
62134
62294
|
isCalculationField: () => isCalculationField,
|
|
62135
62295
|
isCalculationView: () => isCalculationView
|
|
@@ -62142,6 +62302,9 @@ function isBasicViewField(field) {
|
|
|
62142
62302
|
return !isCalculationField(field);
|
|
62143
62303
|
}
|
|
62144
62304
|
function isCalculationView(view) {
|
|
62305
|
+
return view.type === "calculation" /* CALCULATION */;
|
|
62306
|
+
}
|
|
62307
|
+
function hasCalculationFields(view) {
|
|
62145
62308
|
return Object.values(view.schema || {}).some(isCalculationField);
|
|
62146
62309
|
}
|
|
62147
62310
|
function calculationFields(view) {
|
|
@@ -62221,7 +62384,7 @@ var NoEmptyFilterStrings = [
|
|
|
62221
62384
|
];
|
|
62222
62385
|
function recurseLogicalOperators(filters, fn) {
|
|
62223
62386
|
for (const logical of LOGICAL_OPERATORS) {
|
|
62224
|
-
if (filters
|
|
62387
|
+
if (filters[logical]) {
|
|
62225
62388
|
filters[logical].conditions = filters[logical].conditions.map(
|
|
62226
62389
|
(condition) => fn(condition)
|
|
62227
62390
|
);
|
|
@@ -62241,9 +62404,6 @@ function recurseSearchFilters(filters, processFn) {
|
|
|
62241
62404
|
return filters;
|
|
62242
62405
|
}
|
|
62243
62406
|
var cleanupQuery = (query) => {
|
|
62244
|
-
if (!query) {
|
|
62245
|
-
return query;
|
|
62246
|
-
}
|
|
62247
62407
|
for (let filterField of NoEmptyFilterStrings) {
|
|
62248
62408
|
if (!query[filterField]) {
|
|
62249
62409
|
continue;
|
|
@@ -62334,7 +62494,106 @@ var ColumnSplitter = class {
|
|
|
62334
62494
|
};
|
|
62335
62495
|
}
|
|
62336
62496
|
};
|
|
62337
|
-
var
|
|
62497
|
+
var buildCondition = (expression) => {
|
|
62498
|
+
let query = {
|
|
62499
|
+
string: {},
|
|
62500
|
+
fuzzy: {},
|
|
62501
|
+
range: {},
|
|
62502
|
+
equal: {},
|
|
62503
|
+
notEqual: {},
|
|
62504
|
+
empty: {},
|
|
62505
|
+
notEmpty: {},
|
|
62506
|
+
contains: {},
|
|
62507
|
+
notContains: {},
|
|
62508
|
+
oneOf: {},
|
|
62509
|
+
containsAny: {}
|
|
62510
|
+
};
|
|
62511
|
+
let { operator, field, type, value, externalType, onEmptyFilter } = expression;
|
|
62512
|
+
if (!operator || !field) {
|
|
62513
|
+
return;
|
|
62514
|
+
}
|
|
62515
|
+
const queryOperator = operator;
|
|
62516
|
+
const isHbs = typeof value === "string" && (value.match(HBS_REGEX) || []).length > 0;
|
|
62517
|
+
if (operator === "allOr") {
|
|
62518
|
+
query.allOr = true;
|
|
62519
|
+
return;
|
|
62520
|
+
}
|
|
62521
|
+
if (onEmptyFilter) {
|
|
62522
|
+
query.onEmptyFilter = onEmptyFilter;
|
|
62523
|
+
return;
|
|
62524
|
+
}
|
|
62525
|
+
if (queryOperator === "empty" || queryOperator === "notEmpty") {
|
|
62526
|
+
value = null;
|
|
62527
|
+
}
|
|
62528
|
+
if (type === "datetime" && !isHbs && queryOperator !== "empty" && queryOperator !== "notEmpty") {
|
|
62529
|
+
if (!value) {
|
|
62530
|
+
return;
|
|
62531
|
+
}
|
|
62532
|
+
try {
|
|
62533
|
+
value = new Date(value).toISOString();
|
|
62534
|
+
} catch (error) {
|
|
62535
|
+
return;
|
|
62536
|
+
}
|
|
62537
|
+
}
|
|
62538
|
+
if (type === "number" && typeof value === "string" && !isHbs) {
|
|
62539
|
+
if (queryOperator === "oneOf") {
|
|
62540
|
+
value = value.split(",").map((item) => parseFloat(item));
|
|
62541
|
+
} else {
|
|
62542
|
+
value = parseFloat(value);
|
|
62543
|
+
}
|
|
62544
|
+
}
|
|
62545
|
+
if (type === "boolean") {
|
|
62546
|
+
value = `${value}`?.toLowerCase() === "true";
|
|
62547
|
+
}
|
|
62548
|
+
if (["contains", "notContains", "containsAny"].includes(
|
|
62549
|
+
operator.toLocaleString()
|
|
62550
|
+
) && type === "array" && typeof value === "string") {
|
|
62551
|
+
value = value.split(",");
|
|
62552
|
+
}
|
|
62553
|
+
if (operator.toLocaleString().startsWith("range") && query.range) {
|
|
62554
|
+
const minint = SqlNumberTypeRangeMap[externalType]?.min || Number.MIN_SAFE_INTEGER;
|
|
62555
|
+
const maxint = SqlNumberTypeRangeMap[externalType]?.max || Number.MAX_SAFE_INTEGER;
|
|
62556
|
+
if (!query.range[field]) {
|
|
62557
|
+
query.range[field] = {
|
|
62558
|
+
low: type === "number" ? minint : "0000-00-00T00:00:00.000Z",
|
|
62559
|
+
high: type === "number" ? maxint : "9999-00-00T00:00:00.000Z"
|
|
62560
|
+
};
|
|
62561
|
+
}
|
|
62562
|
+
if (operator === "rangeLow" && value != null && value !== "") {
|
|
62563
|
+
query.range[field] = {
|
|
62564
|
+
...query.range[field],
|
|
62565
|
+
low: value
|
|
62566
|
+
};
|
|
62567
|
+
} else if (operator === "rangeHigh" && value != null && value !== "") {
|
|
62568
|
+
query.range[field] = {
|
|
62569
|
+
...query.range[field],
|
|
62570
|
+
high: value
|
|
62571
|
+
};
|
|
62572
|
+
}
|
|
62573
|
+
} else if (isLogicalSearchOperator(queryOperator)) {
|
|
62574
|
+
} else if (query[queryOperator] && operator !== "onEmptyFilter") {
|
|
62575
|
+
if (type === "boolean") {
|
|
62576
|
+
if (queryOperator === "equal" && value === false) {
|
|
62577
|
+
query.notEqual = query.notEqual || {};
|
|
62578
|
+
query.notEqual[field] = true;
|
|
62579
|
+
} else if (queryOperator === "notEqual" && value === false) {
|
|
62580
|
+
query.equal = query.equal || {};
|
|
62581
|
+
query.equal[field] = true;
|
|
62582
|
+
} else {
|
|
62583
|
+
query[queryOperator] ??= {};
|
|
62584
|
+
query[queryOperator][field] = value;
|
|
62585
|
+
}
|
|
62586
|
+
} else {
|
|
62587
|
+
query[queryOperator] ??= {};
|
|
62588
|
+
query[queryOperator][field] = value;
|
|
62589
|
+
}
|
|
62590
|
+
}
|
|
62591
|
+
return query;
|
|
62592
|
+
};
|
|
62593
|
+
var buildQueryLegacy = (filter) => {
|
|
62594
|
+
if (!Array.isArray(filter)) {
|
|
62595
|
+
return filter;
|
|
62596
|
+
}
|
|
62338
62597
|
let query = {
|
|
62339
62598
|
string: {},
|
|
62340
62599
|
fuzzy: {},
|
|
@@ -62383,10 +62642,12 @@ var buildQuery = (filter) => {
|
|
|
62383
62642
|
if (type === "boolean") {
|
|
62384
62643
|
value = `${value}`?.toLowerCase() === "true";
|
|
62385
62644
|
}
|
|
62386
|
-
if (["contains", "notContains", "containsAny"].includes(
|
|
62645
|
+
if (["contains", "notContains", "containsAny"].includes(
|
|
62646
|
+
operator.toLocaleString()
|
|
62647
|
+
) && type === "array" && typeof value === "string") {
|
|
62387
62648
|
value = value.split(",");
|
|
62388
62649
|
}
|
|
62389
|
-
if (operator.startsWith("range") && query.range) {
|
|
62650
|
+
if (operator.toLocaleString().startsWith("range") && query.range) {
|
|
62390
62651
|
const minint = SqlNumberTypeRangeMap[externalType]?.min || Number.MIN_SAFE_INTEGER;
|
|
62391
62652
|
const maxint = SqlNumberTypeRangeMap[externalType]?.max || Number.MAX_SAFE_INTEGER;
|
|
62392
62653
|
if (!query.range[field]) {
|
|
@@ -62427,6 +62688,30 @@ var buildQuery = (filter) => {
|
|
|
62427
62688
|
});
|
|
62428
62689
|
return query;
|
|
62429
62690
|
};
|
|
62691
|
+
var buildQuery = (filter) => {
|
|
62692
|
+
const parsedFilter = processSearchFilters(filter);
|
|
62693
|
+
if (!parsedFilter) {
|
|
62694
|
+
return;
|
|
62695
|
+
}
|
|
62696
|
+
const operatorMap = {
|
|
62697
|
+
["all" /* ALL */]: "$and" /* AND */,
|
|
62698
|
+
["any" /* ANY */]: "$or" /* OR */
|
|
62699
|
+
};
|
|
62700
|
+
const globalOnEmpty = parsedFilter.onEmptyFilter ? parsedFilter.onEmptyFilter : null;
|
|
62701
|
+
const globalOperator = operatorMap[parsedFilter.logicalOperator];
|
|
62702
|
+
return {
|
|
62703
|
+
...globalOnEmpty ? { onEmptyFilter: globalOnEmpty } : {},
|
|
62704
|
+
[globalOperator]: {
|
|
62705
|
+
conditions: parsedFilter.groups?.map((group) => {
|
|
62706
|
+
return {
|
|
62707
|
+
[operatorMap[group.logicalOperator]]: {
|
|
62708
|
+
conditions: group.filters?.map((x) => buildCondition(x)).filter((filter2) => filter2)
|
|
62709
|
+
}
|
|
62710
|
+
};
|
|
62711
|
+
})
|
|
62712
|
+
}
|
|
62713
|
+
};
|
|
62714
|
+
};
|
|
62430
62715
|
function fixupFilterArrays(filters) {
|
|
62431
62716
|
for (const searchField of Object.values(ArrayOperator)) {
|
|
62432
62717
|
const field = filters[searchField];
|
|
@@ -62453,7 +62738,7 @@ function search(docs, query) {
|
|
|
62453
62738
|
if (query.sort) {
|
|
62454
62739
|
result = sort(result, query.sort, query.sortOrder || "ascending" /* ASCENDING */);
|
|
62455
62740
|
}
|
|
62456
|
-
|
|
62741
|
+
const totalRows = result.length;
|
|
62457
62742
|
if (query.limit) {
|
|
62458
62743
|
result = limit(result, query.limit.toString());
|
|
62459
62744
|
}
|
|
@@ -62767,91 +63052,6 @@ var hasFilters = (query) => {
|
|
|
62767
63052
|
return check(query);
|
|
62768
63053
|
};
|
|
62769
63054
|
|
|
62770
|
-
// ../shared-core/src/utils.ts
|
|
62771
|
-
var utils_exports = {};
|
|
62772
|
-
__export(utils_exports, {
|
|
62773
|
-
filterValueToLabel: () => filterValueToLabel,
|
|
62774
|
-
hasSchema: () => hasSchema,
|
|
62775
|
-
isSupportedUserSearch: () => isSupportedUserSearch,
|
|
62776
|
-
parallelForeach: () => parallelForeach,
|
|
62777
|
-
trimOtherProps: () => trimOtherProps,
|
|
62778
|
-
unreachable: () => unreachable
|
|
62779
|
-
});
|
|
62780
|
-
function unreachable(value, message = `No such case in exhaustive switch: ${value}`) {
|
|
62781
|
-
throw new Error(message);
|
|
62782
|
-
}
|
|
62783
|
-
async function parallelForeach(items, task, maxConcurrency) {
|
|
62784
|
-
const promises = [];
|
|
62785
|
-
let index2 = 0;
|
|
62786
|
-
const processItem = async (item) => {
|
|
62787
|
-
try {
|
|
62788
|
-
await task(item);
|
|
62789
|
-
} finally {
|
|
62790
|
-
processNext();
|
|
62791
|
-
}
|
|
62792
|
-
};
|
|
62793
|
-
const processNext = () => {
|
|
62794
|
-
if (index2 >= items.length) {
|
|
62795
|
-
return;
|
|
62796
|
-
}
|
|
62797
|
-
const item = items[index2];
|
|
62798
|
-
index2++;
|
|
62799
|
-
const promise = processItem(item);
|
|
62800
|
-
promises.push(promise);
|
|
62801
|
-
if (promises.length >= maxConcurrency) {
|
|
62802
|
-
Promise.race(promises).then(processNext);
|
|
62803
|
-
} else {
|
|
62804
|
-
processNext();
|
|
62805
|
-
}
|
|
62806
|
-
};
|
|
62807
|
-
processNext();
|
|
62808
|
-
await Promise.all(promises);
|
|
62809
|
-
}
|
|
62810
|
-
function filterValueToLabel() {
|
|
62811
|
-
return Object.keys(OperatorOptions).reduce(
|
|
62812
|
-
(acc, key) => {
|
|
62813
|
-
const ops = OperatorOptions;
|
|
62814
|
-
const op = ops[key];
|
|
62815
|
-
acc[op["value"]] = op.label;
|
|
62816
|
-
return acc;
|
|
62817
|
-
},
|
|
62818
|
-
{}
|
|
62819
|
-
);
|
|
62820
|
-
}
|
|
62821
|
-
function hasSchema(test) {
|
|
62822
|
-
return typeof test === "object" && !Array.isArray(test) && test !== null && !(test instanceof Date) && Object.keys(test).length > 0;
|
|
62823
|
-
}
|
|
62824
|
-
function trimOtherProps(object, allowedProps) {
|
|
62825
|
-
const result = Object.keys(object).filter((key) => allowedProps.includes(key)).reduce(
|
|
62826
|
-
(acc, key) => ({ ...acc, [key]: object[key] }),
|
|
62827
|
-
{}
|
|
62828
|
-
);
|
|
62829
|
-
return result;
|
|
62830
|
-
}
|
|
62831
|
-
function isSupportedUserSearch(query) {
|
|
62832
|
-
const allowed = [
|
|
62833
|
-
{ op: "string" /* STRING */, key: "email" },
|
|
62834
|
-
{ op: "equal" /* EQUAL */, key: "_id" },
|
|
62835
|
-
{ op: "oneOf" /* ONE_OF */, key: "_id" }
|
|
62836
|
-
];
|
|
62837
|
-
for (let [key, operation] of Object.entries(query)) {
|
|
62838
|
-
if (typeof operation !== "object") {
|
|
62839
|
-
return false;
|
|
62840
|
-
}
|
|
62841
|
-
const fields = Object.keys(operation || {});
|
|
62842
|
-
if (fields.length === 0) {
|
|
62843
|
-
continue;
|
|
62844
|
-
}
|
|
62845
|
-
const allowedOperation = allowed.find(
|
|
62846
|
-
(allow) => allow.op === key && fields.length === 1 && fields[0] === allow.key
|
|
62847
|
-
);
|
|
62848
|
-
if (!allowedOperation) {
|
|
62849
|
-
return false;
|
|
62850
|
-
}
|
|
62851
|
-
}
|
|
62852
|
-
return true;
|
|
62853
|
-
}
|
|
62854
|
-
|
|
62855
63055
|
// ../shared-core/src/sdk/index.ts
|
|
62856
63056
|
var sdk_exports = {};
|
|
62857
63057
|
__export(sdk_exports, {
|
|
@@ -66928,8 +67128,12 @@ __export(features_exports, {
|
|
|
66928
67128
|
FlagSet: () => FlagSet,
|
|
66929
67129
|
flags: () => flags,
|
|
66930
67130
|
init: () => init4,
|
|
66931
|
-
|
|
67131
|
+
parseEnvFlags: () => parseEnvFlags,
|
|
67132
|
+
shutdown: () => shutdown2,
|
|
67133
|
+
testutils: () => utils_exports5
|
|
66932
67134
|
});
|
|
67135
|
+
|
|
67136
|
+
// src/features/features.ts
|
|
66933
67137
|
var import_posthog_node = require("posthog-node");
|
|
66934
67138
|
var import_dd_trace3 = __toESM(require("dd-trace"));
|
|
66935
67139
|
|
|
@@ -67310,7 +67514,7 @@ var Duration = class _Duration {
|
|
|
67310
67514
|
}
|
|
67311
67515
|
};
|
|
67312
67516
|
|
|
67313
|
-
// src/features/
|
|
67517
|
+
// src/features/features.ts
|
|
67314
67518
|
var posthog;
|
|
67315
67519
|
function init4(opts) {
|
|
67316
67520
|
if (environment_default.POSTHOG_TOKEN && environment_default.POSTHOG_API_HOST && !environment_default.SELF_HOSTED && environment_default.POSTHOG_FEATURE_FLAGS_ENABLED) {
|
|
@@ -67375,6 +67579,21 @@ var NumberFlag = class extends Flag {
|
|
|
67375
67579
|
throw new Error(`could not parse value "${value}" as number`);
|
|
67376
67580
|
}
|
|
67377
67581
|
};
|
|
67582
|
+
function parseEnvFlags(flags2) {
|
|
67583
|
+
const split = flags2.split(",").map((x) => x.split(":"));
|
|
67584
|
+
const result = [];
|
|
67585
|
+
for (const [tenantId, ...features] of split) {
|
|
67586
|
+
for (let feature of features) {
|
|
67587
|
+
let value = true;
|
|
67588
|
+
if (feature.startsWith("!")) {
|
|
67589
|
+
feature = feature.slice(1);
|
|
67590
|
+
value = false;
|
|
67591
|
+
}
|
|
67592
|
+
result.push({ tenantId, key: feature, value });
|
|
67593
|
+
}
|
|
67594
|
+
}
|
|
67595
|
+
return result;
|
|
67596
|
+
}
|
|
67378
67597
|
var FlagSet = class {
|
|
67379
67598
|
constructor(flagSchema) {
|
|
67380
67599
|
this.flagSchema = flagSchema;
|
|
@@ -67409,28 +67628,24 @@ var FlagSet = class {
|
|
|
67409
67628
|
const flagValues = this.defaults();
|
|
67410
67629
|
const currentTenantId = getTenantId();
|
|
67411
67630
|
const specificallySetFalse = /* @__PURE__ */ new Set();
|
|
67412
|
-
const
|
|
67413
|
-
|
|
67631
|
+
for (const { tenantId, key, value } of parseEnvFlags(
|
|
67632
|
+
environment_default.TENANT_FEATURE_FLAGS || ""
|
|
67633
|
+
)) {
|
|
67414
67634
|
if (!tenantId || tenantId !== "*" && tenantId !== currentTenantId) {
|
|
67415
67635
|
continue;
|
|
67416
67636
|
}
|
|
67417
67637
|
tags[`readFromEnvironmentVars`] = true;
|
|
67418
|
-
|
|
67419
|
-
|
|
67420
|
-
|
|
67421
|
-
|
|
67422
|
-
|
|
67423
|
-
specificallySetFalse.add(feature);
|
|
67424
|
-
}
|
|
67425
|
-
if (!this.isFlagName(feature)) {
|
|
67426
|
-
continue;
|
|
67427
|
-
}
|
|
67428
|
-
if (typeof flagValues[feature] !== "boolean") {
|
|
67429
|
-
throw new Error(`Feature: ${feature} is not a boolean`);
|
|
67430
|
-
}
|
|
67431
|
-
flagValues[feature] = value;
|
|
67432
|
-
tags[`flags.${feature}.source`] = "environment";
|
|
67638
|
+
if (value === false) {
|
|
67639
|
+
specificallySetFalse.add(key);
|
|
67640
|
+
}
|
|
67641
|
+
if (!this.isFlagName(key)) {
|
|
67642
|
+
continue;
|
|
67433
67643
|
}
|
|
67644
|
+
if (typeof flagValues[key] !== "boolean") {
|
|
67645
|
+
throw new Error(`Feature: ${key} is not a boolean`);
|
|
67646
|
+
}
|
|
67647
|
+
flagValues[key] = value;
|
|
67648
|
+
tags[`flags.${key}.source`] = "environment";
|
|
67434
67649
|
}
|
|
67435
67650
|
const license = ctx?.user?.license;
|
|
67436
67651
|
if (license) {
|
|
@@ -67497,6 +67712,60 @@ var flags = new FlagSet({
|
|
|
67497
67712
|
["ENRICHED_RELATIONSHIPS" /* ENRICHED_RELATIONSHIPS */]: Flag.boolean(environment_default.isDev())
|
|
67498
67713
|
});
|
|
67499
67714
|
|
|
67715
|
+
// src/features/tests/utils.ts
|
|
67716
|
+
var utils_exports5 = {};
|
|
67717
|
+
__export(utils_exports5, {
|
|
67718
|
+
setFeatureFlags: () => setFeatureFlags2,
|
|
67719
|
+
withFeatureFlags: () => withFeatureFlags
|
|
67720
|
+
});
|
|
67721
|
+
function getCurrentFlags() {
|
|
67722
|
+
const result = {};
|
|
67723
|
+
for (const { tenantId, key, value } of parseEnvFlags(
|
|
67724
|
+
process.env.TENANT_FEATURE_FLAGS || ""
|
|
67725
|
+
)) {
|
|
67726
|
+
const tenantFlags = result[tenantId] || {};
|
|
67727
|
+
if (tenantFlags[key] === false) {
|
|
67728
|
+
continue;
|
|
67729
|
+
}
|
|
67730
|
+
tenantFlags[key] = value;
|
|
67731
|
+
result[tenantId] = tenantFlags;
|
|
67732
|
+
}
|
|
67733
|
+
return result;
|
|
67734
|
+
}
|
|
67735
|
+
function buildFlagString(flags2) {
|
|
67736
|
+
const parts = [];
|
|
67737
|
+
for (const [tenantId, tenantFlags] of Object.entries(flags2)) {
|
|
67738
|
+
for (const [key, value] of Object.entries(tenantFlags)) {
|
|
67739
|
+
if (value === false) {
|
|
67740
|
+
parts.push(`${tenantId}:!${key}`);
|
|
67741
|
+
} else {
|
|
67742
|
+
parts.push(`${tenantId}:${key}`);
|
|
67743
|
+
}
|
|
67744
|
+
}
|
|
67745
|
+
}
|
|
67746
|
+
return parts.join(",");
|
|
67747
|
+
}
|
|
67748
|
+
function setFeatureFlags2(tenantId, flags2) {
|
|
67749
|
+
const current = getCurrentFlags();
|
|
67750
|
+
for (const [key, value] of Object.entries(flags2)) {
|
|
67751
|
+
const tenantFlags = current[tenantId] || {};
|
|
67752
|
+
tenantFlags[key] = value;
|
|
67753
|
+
current[tenantId] = tenantFlags;
|
|
67754
|
+
}
|
|
67755
|
+
const flagString = buildFlagString(current);
|
|
67756
|
+
return setEnv({ TENANT_FEATURE_FLAGS: flagString });
|
|
67757
|
+
}
|
|
67758
|
+
function withFeatureFlags(tenantId, flags2, f) {
|
|
67759
|
+
const cleanup3 = setFeatureFlags2(tenantId, flags2);
|
|
67760
|
+
const result = f();
|
|
67761
|
+
if (result instanceof Promise) {
|
|
67762
|
+
return result.finally(cleanup3);
|
|
67763
|
+
} else {
|
|
67764
|
+
cleanup3();
|
|
67765
|
+
return result;
|
|
67766
|
+
}
|
|
67767
|
+
}
|
|
67768
|
+
|
|
67500
67769
|
// src/db/couch/DatabaseImpl.ts
|
|
67501
67770
|
var DATABASE_NOT_FOUND = "Database does not exist.";
|
|
67502
67771
|
function buildNano(couchInfo) {
|
|
@@ -67760,11 +68029,21 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
67760
68029
|
return this.performCall(() => {
|
|
67761
68030
|
return async () => {
|
|
67762
68031
|
const response = await directCouchUrlCall(args);
|
|
67763
|
-
const
|
|
68032
|
+
const text = await response.text();
|
|
67764
68033
|
if (response.status > 300) {
|
|
68034
|
+
let json;
|
|
68035
|
+
try {
|
|
68036
|
+
json = JSON.parse(text);
|
|
68037
|
+
} catch (err) {
|
|
68038
|
+
console.error(`SQS error: ${text}`);
|
|
68039
|
+
throw new CouchDBError(
|
|
68040
|
+
"error while running SQS query, please try again later",
|
|
68041
|
+
{ name: "sqs_error", status: response.status }
|
|
68042
|
+
);
|
|
68043
|
+
}
|
|
67765
68044
|
throw json;
|
|
67766
68045
|
}
|
|
67767
|
-
return
|
|
68046
|
+
return JSON.parse(text);
|
|
67768
68047
|
};
|
|
67769
68048
|
});
|
|
67770
68049
|
}
|
|
@@ -68777,8 +69056,8 @@ __export(users_exports3, {
|
|
|
68777
69056
|
});
|
|
68778
69057
|
|
|
68779
69058
|
// src/users/utils.ts
|
|
68780
|
-
var
|
|
68781
|
-
__export(
|
|
69059
|
+
var utils_exports6 = {};
|
|
69060
|
+
__export(utils_exports6, {
|
|
68782
69061
|
getAccountHolderFromUserIds: () => getAccountHolderFromUserIds,
|
|
68783
69062
|
hasAdminPermissions: () => hasAdminPermissions2,
|
|
68784
69063
|
hasAppBuilderPermissions: () => hasAppBuilderPermissions2,
|
|
@@ -72803,6 +73082,12 @@ async function paginatedUsers({
|
|
|
72803
73082
|
userList = await bulkGetGlobalUsersById(query?.oneOf?._id, {
|
|
72804
73083
|
cleanup: true
|
|
72805
73084
|
});
|
|
73085
|
+
} else if (query) {
|
|
73086
|
+
const response = await db.allDocs(
|
|
73087
|
+
getGlobalUserParams(null, { ...opts, limit: void 0 })
|
|
73088
|
+
);
|
|
73089
|
+
userList = response.rows.map((row) => row.doc);
|
|
73090
|
+
userList = filters_exports.search(userList, { query, limit: opts.limit }).rows;
|
|
72806
73091
|
} else {
|
|
72807
73092
|
const response = await db.allDocs(getGlobalUserParams(null, opts));
|
|
72808
73093
|
userList = response.rows.map((row) => row.doc);
|
|
@@ -73620,7 +73905,6 @@ __export(google_exports, {
|
|
|
73620
73905
|
});
|
|
73621
73906
|
|
|
73622
73907
|
// src/middleware/passport/sso/sso.ts
|
|
73623
|
-
var import_node_fetch5 = __toESM(require("node-fetch"));
|
|
73624
73908
|
var ssoSaveUserNoOp = (user) => Promise.resolve(user);
|
|
73625
73909
|
async function authenticate2(details, requireLocalAccount = true, done, saveUserFn) {
|
|
73626
73910
|
if (!saveUserFn) {
|
|
@@ -73675,24 +73959,10 @@ async function authenticate2(details, requireLocalAccount = true, done, saveUser
|
|
|
73675
73959
|
}
|
|
73676
73960
|
return done(null, ssoUser);
|
|
73677
73961
|
}
|
|
73678
|
-
async function getProfilePictureUrl(user, details) {
|
|
73679
|
-
const pictureUrl = details.profile?._json.picture;
|
|
73680
|
-
if (pictureUrl) {
|
|
73681
|
-
const response = await (0, import_node_fetch5.default)(pictureUrl);
|
|
73682
|
-
if (response.status === 200) {
|
|
73683
|
-
const type = response.headers.get("content-type");
|
|
73684
|
-
if (type.startsWith("image/")) {
|
|
73685
|
-
return pictureUrl;
|
|
73686
|
-
}
|
|
73687
|
-
}
|
|
73688
|
-
}
|
|
73689
|
-
}
|
|
73690
73962
|
async function syncUser(user, details) {
|
|
73691
73963
|
let firstName;
|
|
73692
73964
|
let lastName;
|
|
73693
|
-
let pictureUrl;
|
|
73694
73965
|
let oauth2;
|
|
73695
|
-
let thirdPartyProfile;
|
|
73696
73966
|
if (details.profile) {
|
|
73697
73967
|
const profile = details.profile;
|
|
73698
73968
|
if (profile.name) {
|
|
@@ -73704,10 +73974,6 @@ async function syncUser(user, details) {
|
|
|
73704
73974
|
lastName = name.familyName;
|
|
73705
73975
|
}
|
|
73706
73976
|
}
|
|
73707
|
-
pictureUrl = await getProfilePictureUrl(user, details);
|
|
73708
|
-
thirdPartyProfile = {
|
|
73709
|
-
...profile._json
|
|
73710
|
-
};
|
|
73711
73977
|
}
|
|
73712
73978
|
if (details.oauth2) {
|
|
73713
73979
|
oauth2 = {
|
|
@@ -73720,8 +73986,6 @@ async function syncUser(user, details) {
|
|
|
73720
73986
|
providerType: details.providerType,
|
|
73721
73987
|
firstName,
|
|
73722
73988
|
lastName,
|
|
73723
|
-
thirdPartyProfile,
|
|
73724
|
-
pictureUrl,
|
|
73725
73989
|
oauth2
|
|
73726
73990
|
};
|
|
73727
73991
|
}
|
|
@@ -73783,7 +74047,7 @@ __export(oidc_exports, {
|
|
|
73783
74047
|
getCallbackUrl: () => getCallbackUrl2,
|
|
73784
74048
|
strategyFactory: () => strategyFactory2
|
|
73785
74049
|
});
|
|
73786
|
-
var
|
|
74050
|
+
var import_node_fetch5 = __toESM(require("node-fetch"));
|
|
73787
74051
|
var OIDCStrategy = require_lib9().Strategy;
|
|
73788
74052
|
function buildVerifyFn2(saveUserFn) {
|
|
73789
74053
|
return async (issuer, sub, profile, jwtClaims, accessToken, refreshToken, idToken, params2, done) => {
|
|
@@ -73843,7 +74107,7 @@ async function fetchStrategyConfig(oidcConfig, callbackUrl) {
|
|
|
73843
74107
|
"Configuration invalid. Must contain clientID, clientSecret, callbackUrl and configUrl"
|
|
73844
74108
|
);
|
|
73845
74109
|
}
|
|
73846
|
-
const response = await (0,
|
|
74110
|
+
const response = await (0, import_node_fetch5.default)(configUrl);
|
|
73847
74111
|
if (!response.ok) {
|
|
73848
74112
|
throw new Error(
|
|
73849
74113
|
`Unexpected response when fetching openid-configuration: ${response.statusText}`
|
|
@@ -75270,25 +75534,56 @@ var InternalBuilder = class {
|
|
|
75270
75534
|
const { column } = this.splitter.run(key);
|
|
75271
75535
|
return this.table.schema[column];
|
|
75272
75536
|
}
|
|
75273
|
-
|
|
75274
|
-
// and "foo" for Postgres.
|
|
75275
|
-
quote(str) {
|
|
75537
|
+
quoteChars() {
|
|
75276
75538
|
switch (this.client) {
|
|
75277
|
-
case "sqlite3" /* SQL_LITE */:
|
|
75278
75539
|
case "oracledb" /* ORACLE */:
|
|
75279
75540
|
case "pg" /* POSTGRES */:
|
|
75280
|
-
return
|
|
75541
|
+
return ['"', '"'];
|
|
75281
75542
|
case "mssql" /* MS_SQL */:
|
|
75282
|
-
return
|
|
75543
|
+
return ["[", "]"];
|
|
75283
75544
|
case "mariadb" /* MARIADB */:
|
|
75284
75545
|
case "mysql2" /* MY_SQL */:
|
|
75285
|
-
|
|
75546
|
+
case "sqlite3" /* SQL_LITE */:
|
|
75547
|
+
return ["`", "`"];
|
|
75286
75548
|
}
|
|
75287
75549
|
}
|
|
75288
|
-
// Takes a string like
|
|
75289
|
-
//
|
|
75550
|
+
// Takes a string like foo and returns a quoted string like [foo] for SQL Server
|
|
75551
|
+
// and "foo" for Postgres.
|
|
75552
|
+
quote(str) {
|
|
75553
|
+
const [start2, end2] = this.quoteChars();
|
|
75554
|
+
return `${start2}${str}${end2}`;
|
|
75555
|
+
}
|
|
75556
|
+
isQuoted(key) {
|
|
75557
|
+
const [start2, end2] = this.quoteChars();
|
|
75558
|
+
return key.startsWith(start2) && key.endsWith(end2);
|
|
75559
|
+
}
|
|
75560
|
+
// Takes a string like a.b.c or an array like ["a", "b", "c"] and returns a
|
|
75561
|
+
// quoted identifier like [a].[b].[c] for SQL Server and `a`.`b`.`c` for
|
|
75562
|
+
// MySQL.
|
|
75290
75563
|
quotedIdentifier(key) {
|
|
75291
|
-
|
|
75564
|
+
if (!Array.isArray(key)) {
|
|
75565
|
+
key = this.splitIdentifier(key);
|
|
75566
|
+
}
|
|
75567
|
+
return key.map((part) => this.quote(part)).join(".");
|
|
75568
|
+
}
|
|
75569
|
+
// Turns an identifier like a.b.c or `a`.`b`.`c` into ["a", "b", "c"]
|
|
75570
|
+
splitIdentifier(key) {
|
|
75571
|
+
const [start2, end2] = this.quoteChars();
|
|
75572
|
+
if (this.isQuoted(key)) {
|
|
75573
|
+
return key.slice(1, -1).split(`${end2}.${start2}`);
|
|
75574
|
+
}
|
|
75575
|
+
return key.split(".");
|
|
75576
|
+
}
|
|
75577
|
+
qualifyIdentifier(key) {
|
|
75578
|
+
const tableName = this.getTableName();
|
|
75579
|
+
const parts = this.splitIdentifier(key);
|
|
75580
|
+
if (parts[0] !== tableName) {
|
|
75581
|
+
parts.unshift(tableName);
|
|
75582
|
+
}
|
|
75583
|
+
if (this.isQuoted(key)) {
|
|
75584
|
+
return this.quotedIdentifier(parts);
|
|
75585
|
+
}
|
|
75586
|
+
return parts.join(".");
|
|
75292
75587
|
}
|
|
75293
75588
|
isFullSelectStatementRequired() {
|
|
75294
75589
|
const { meta } = this.query;
|
|
@@ -75339,13 +75634,22 @@ var InternalBuilder = class {
|
|
|
75339
75634
|
// OracleDB can't use character-large-objects (CLOBs) in WHERE clauses,
|
|
75340
75635
|
// so when we use them we need to wrap them in to_char(). This function
|
|
75341
75636
|
// converts a field name to the appropriate identifier.
|
|
75342
|
-
convertClobs(field) {
|
|
75343
|
-
|
|
75637
|
+
convertClobs(field, opts) {
|
|
75638
|
+
if (this.client !== "oracledb" /* ORACLE */) {
|
|
75639
|
+
throw new Error(
|
|
75640
|
+
"you've called convertClobs on a DB that's not Oracle, this is a mistake"
|
|
75641
|
+
);
|
|
75642
|
+
}
|
|
75643
|
+
const parts = this.splitIdentifier(field);
|
|
75344
75644
|
const col = parts.pop();
|
|
75345
75645
|
const schema = this.table.schema[col];
|
|
75346
75646
|
let identifier = this.quotedIdentifier(field);
|
|
75347
75647
|
if (schema.type === "string" /* STRING */ || schema.type === "longform" /* LONGFORM */ || schema.type === "bb_reference_single" /* BB_REFERENCE_SINGLE */ || schema.type === "bb_reference" /* BB_REFERENCE */ || schema.type === "options" /* OPTIONS */ || schema.type === "barcodeqr" /* BARCODEQR */) {
|
|
75348
|
-
|
|
75648
|
+
if (opts?.forSelect) {
|
|
75649
|
+
identifier = `to_char(${identifier}) as ${this.quotedIdentifier(col)}`;
|
|
75650
|
+
} else {
|
|
75651
|
+
identifier = `to_char(${identifier})`;
|
|
75652
|
+
}
|
|
75349
75653
|
}
|
|
75350
75654
|
return identifier;
|
|
75351
75655
|
}
|
|
@@ -75842,28 +76146,56 @@ var InternalBuilder = class {
|
|
|
75842
76146
|
const fields = this.query.resource?.fields || [];
|
|
75843
76147
|
const tableName = this.getTableName();
|
|
75844
76148
|
if (fields.length > 0) {
|
|
75845
|
-
|
|
75846
|
-
|
|
76149
|
+
const qualifiedFields = fields.map((field) => this.qualifyIdentifier(field));
|
|
76150
|
+
if (this.client === "oracledb" /* ORACLE */) {
|
|
76151
|
+
const groupByFields = qualifiedFields.map(
|
|
76152
|
+
(field) => this.convertClobs(field)
|
|
76153
|
+
);
|
|
76154
|
+
const selectFields = qualifiedFields.map(
|
|
76155
|
+
(field) => this.convertClobs(field, { forSelect: true })
|
|
76156
|
+
);
|
|
76157
|
+
query = query.groupByRaw(groupByFields.join(", ")).select(this.knex.raw(selectFields.join(", ")));
|
|
76158
|
+
} else {
|
|
76159
|
+
query = query.groupBy(qualifiedFields).select(qualifiedFields);
|
|
76160
|
+
}
|
|
75847
76161
|
}
|
|
75848
76162
|
for (const aggregation of aggregations) {
|
|
75849
76163
|
const op = aggregation.calculationType;
|
|
75850
|
-
|
|
75851
|
-
|
|
75852
|
-
|
|
75853
|
-
|
|
75854
|
-
|
|
75855
|
-
|
|
75856
|
-
|
|
75857
|
-
|
|
75858
|
-
|
|
75859
|
-
|
|
75860
|
-
|
|
75861
|
-
|
|
75862
|
-
|
|
75863
|
-
|
|
75864
|
-
|
|
75865
|
-
|
|
75866
|
-
|
|
76164
|
+
if (op === "count" /* COUNT */) {
|
|
76165
|
+
if ("distinct" in aggregation && aggregation.distinct) {
|
|
76166
|
+
if (this.client === "oracledb" /* ORACLE */) {
|
|
76167
|
+
const field = this.convertClobs(`${tableName}.${aggregation.field}`);
|
|
76168
|
+
query = query.select(
|
|
76169
|
+
this.knex.raw(
|
|
76170
|
+
`COUNT(DISTINCT ${field}) as ${this.quotedIdentifier(
|
|
76171
|
+
aggregation.name
|
|
76172
|
+
)}`
|
|
76173
|
+
)
|
|
76174
|
+
);
|
|
76175
|
+
} else {
|
|
76176
|
+
query = query.countDistinct(
|
|
76177
|
+
`${tableName}.${aggregation.field} as ${aggregation.name}`
|
|
76178
|
+
);
|
|
76179
|
+
}
|
|
76180
|
+
} else {
|
|
76181
|
+
query = query.count(`* as ${aggregation.name}`);
|
|
76182
|
+
}
|
|
76183
|
+
} else {
|
|
76184
|
+
const field = `${tableName}.${aggregation.field} as ${aggregation.name}`;
|
|
76185
|
+
switch (op) {
|
|
76186
|
+
case "sum" /* SUM */:
|
|
76187
|
+
query = query.sum(field);
|
|
76188
|
+
break;
|
|
76189
|
+
case "avg" /* AVG */:
|
|
76190
|
+
query = query.avg(field);
|
|
76191
|
+
break;
|
|
76192
|
+
case "min" /* MIN */:
|
|
76193
|
+
query = query.min(field);
|
|
76194
|
+
break;
|
|
76195
|
+
case "max" /* MAX */:
|
|
76196
|
+
query = query.max(field);
|
|
76197
|
+
break;
|
|
76198
|
+
}
|
|
75867
76199
|
}
|
|
75868
76200
|
}
|
|
75869
76201
|
return query;
|