@budibase/backend-core 2.33.2 → 2.33.3
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 +531 -265
- 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.map +1 -1
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/context/identity.js +1 -1
- package/dist/src/context/identity.js.map +1 -1
- package/dist/src/db/couch/DatabaseImpl.js +1 -1
- package/dist/src/db/couch/DatabaseImpl.js.map +1 -1
- package/dist/src/environment.js +28 -14
- package/dist/src/environment.js.map +1 -1
- package/dist/src/features/features.d.ts +1 -0
- package/dist/src/features/features.js +4 -3
- package/dist/src/features/features.js.map +1 -1
- package/dist/src/middleware/authenticated.js +16 -8
- package/dist/src/middleware/authenticated.js.map +1 -1
- package/dist/src/security/roles.d.ts +24 -3
- package/dist/src/security/roles.js +210 -51
- package/dist/src/security/roles.js.map +1 -1
- package/dist/src/sql/sql.js +243 -160
- package/dist/src/sql/sql.js.map +1 -1
- package/dist/src/sql/sqlTable.js +4 -1
- package/dist/src/sql/sqlTable.js.map +1 -1
- package/package.json +4 -4
- package/src/context/identity.ts +1 -1
- package/src/db/couch/DatabaseImpl.ts +2 -1
- package/src/environment.ts +33 -17
- package/src/features/features.ts +4 -3
- package/src/middleware/authenticated.ts +33 -17
- package/src/security/roles.ts +238 -56
- package/src/sql/sql.ts +290 -206
- package/src/sql/sqlTable.ts +4 -1
package/dist/index.js
CHANGED
|
@@ -33554,14 +33554,14 @@ var require_putty = __commonJS({
|
|
|
33554
33554
|
var buf = rfc4253.write(key);
|
|
33555
33555
|
var comment = key.comment || "";
|
|
33556
33556
|
var b64 = buf.toString("base64");
|
|
33557
|
-
var lines =
|
|
33557
|
+
var lines = wrap2(b64, 64);
|
|
33558
33558
|
lines.unshift("Public-Lines: " + lines.length);
|
|
33559
33559
|
lines.unshift("Comment: " + comment);
|
|
33560
33560
|
lines.unshift("Encryption: none");
|
|
33561
33561
|
lines.unshift("PuTTY-User-Key-File-2: " + alg);
|
|
33562
33562
|
return Buffer2.from(lines.join("\n") + "\n");
|
|
33563
33563
|
}
|
|
33564
|
-
function
|
|
33564
|
+
function wrap2(txt, len) {
|
|
33565
33565
|
var lines = [];
|
|
33566
33566
|
var pos = 0;
|
|
33567
33567
|
while (pos < txt.length) {
|
|
@@ -49489,7 +49489,7 @@ var require_util2 = __commonJS({
|
|
|
49489
49489
|
coerceToTypes,
|
|
49490
49490
|
toHash,
|
|
49491
49491
|
getProperty,
|
|
49492
|
-
escapeQuotes,
|
|
49492
|
+
escapeQuotes: escapeQuotes2,
|
|
49493
49493
|
equal: require_fast_deep_equal(),
|
|
49494
49494
|
ucs2length: require_ucs2length(),
|
|
49495
49495
|
varOccurences,
|
|
@@ -49578,9 +49578,9 @@ var require_util2 = __commonJS({
|
|
|
49578
49578
|
var IDENTIFIER = /^[a-z$_][a-z$_0-9]*$/i;
|
|
49579
49579
|
var SINGLE_QUOTE = /'|\\/g;
|
|
49580
49580
|
function getProperty(key) {
|
|
49581
|
-
return typeof key == "number" ? "[" + key + "]" : IDENTIFIER.test(key) ? "." + key : "['" +
|
|
49581
|
+
return typeof key == "number" ? "[" + key + "]" : IDENTIFIER.test(key) ? "." + key : "['" + escapeQuotes2(key) + "']";
|
|
49582
49582
|
}
|
|
49583
|
-
function
|
|
49583
|
+
function escapeQuotes2(str) {
|
|
49584
49584
|
return str.replace(SINGLE_QUOTE, "\\$&").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\f/g, "\\f").replace(/\t/g, "\\t");
|
|
49585
49585
|
}
|
|
49586
49586
|
function varOccurences(str, dataVar) {
|
|
@@ -49615,7 +49615,7 @@ var require_util2 = __commonJS({
|
|
|
49615
49615
|
return key;
|
|
49616
49616
|
}
|
|
49617
49617
|
function toQuotedString(str) {
|
|
49618
|
-
return "'" +
|
|
49618
|
+
return "'" + escapeQuotes2(str) + "'";
|
|
49619
49619
|
}
|
|
49620
49620
|
function getPathExpr(currentPath, expr, jsonPointers, isNumber) {
|
|
49621
49621
|
var path3 = jsonPointers ? "'/' + " + expr + (isNumber ? "" : ".replace(/~/g, '~0').replace(/\\//g, '~1')") : isNumber ? "'[' + " + expr + " + ']'" : "'[\\'' + " + expr + " + '\\']'";
|
|
@@ -56189,8 +56189,8 @@ var require_oauth4 = __commonJS({
|
|
|
56189
56189
|
var sha1 = shasum.digest("hex");
|
|
56190
56190
|
return Buffer2.from(sha1, "hex").toString("base64");
|
|
56191
56191
|
};
|
|
56192
|
-
OAuth.prototype.concatParams = function(oa, sep,
|
|
56193
|
-
|
|
56192
|
+
OAuth.prototype.concatParams = function(oa, sep, wrap2) {
|
|
56193
|
+
wrap2 = wrap2 || "";
|
|
56194
56194
|
var params2 = Object.keys(oa).filter(function(i) {
|
|
56195
56195
|
return i !== "realm" && i !== "oauth_signature";
|
|
56196
56196
|
}).sort();
|
|
@@ -56199,7 +56199,7 @@ var require_oauth4 = __commonJS({
|
|
|
56199
56199
|
}
|
|
56200
56200
|
params2.push("oauth_signature");
|
|
56201
56201
|
return params2.map(function(i) {
|
|
56202
|
-
return i + "=" +
|
|
56202
|
+
return i + "=" + wrap2 + oauth.rfc3986(oa[i]) + wrap2;
|
|
56203
56203
|
}).join(sep);
|
|
56204
56204
|
};
|
|
56205
56205
|
OAuth.prototype.onRequest = function(_oauth) {
|
|
@@ -61253,7 +61253,7 @@ __export(src_exports, {
|
|
|
61253
61253
|
plugins: () => plugin_exports,
|
|
61254
61254
|
queue: () => queue_exports,
|
|
61255
61255
|
redis: () => redis_exports,
|
|
61256
|
-
roles: () =>
|
|
61256
|
+
roles: () => roles_exports2,
|
|
61257
61257
|
security: () => security_exports,
|
|
61258
61258
|
sessions: () => sessions_exports,
|
|
61259
61259
|
setEnv: () => setEnv,
|
|
@@ -62109,6 +62109,7 @@ __export(helpers_exports, {
|
|
|
62109
62109
|
getUserLabel: () => getUserLabel,
|
|
62110
62110
|
isGoogleSheets: () => isGoogleSheets,
|
|
62111
62111
|
isSQL: () => isSQL,
|
|
62112
|
+
roles: () => roles_exports,
|
|
62112
62113
|
schema: () => schema_exports,
|
|
62113
62114
|
views: () => views_exports,
|
|
62114
62115
|
withTimeout: () => withTimeout
|
|
@@ -62334,6 +62335,48 @@ function basicFields(view, opts) {
|
|
|
62334
62335
|
});
|
|
62335
62336
|
}
|
|
62336
62337
|
|
|
62338
|
+
// ../shared-core/src/helpers/roles.ts
|
|
62339
|
+
var roles_exports = {};
|
|
62340
|
+
__export(roles_exports, {
|
|
62341
|
+
checkForRoleInheritanceLoops: () => checkForRoleInheritanceLoops
|
|
62342
|
+
});
|
|
62343
|
+
function prefixForCheck(id) {
|
|
62344
|
+
return `${"role" /* ROLE */}${SEPARATOR}${id}`;
|
|
62345
|
+
}
|
|
62346
|
+
function checkForRoleInheritanceLoops(roles) {
|
|
62347
|
+
const roleMap = /* @__PURE__ */ new Map();
|
|
62348
|
+
roles.forEach((role) => {
|
|
62349
|
+
roleMap.set(role._id, role);
|
|
62350
|
+
});
|
|
62351
|
+
const checked = /* @__PURE__ */ new Set();
|
|
62352
|
+
const checking = /* @__PURE__ */ new Set();
|
|
62353
|
+
function hasLoop(roleId) {
|
|
62354
|
+
const prefixed2 = prefixForCheck(roleId);
|
|
62355
|
+
if (checking.has(roleId) || checking.has(prefixed2)) {
|
|
62356
|
+
return true;
|
|
62357
|
+
}
|
|
62358
|
+
if (checked.has(roleId) || checked.has(prefixed2)) {
|
|
62359
|
+
return false;
|
|
62360
|
+
}
|
|
62361
|
+
checking.add(roleId);
|
|
62362
|
+
const role = roleMap.get(prefixed2) || roleMap.get(roleId);
|
|
62363
|
+
if (!role) {
|
|
62364
|
+
checking.delete(roleId);
|
|
62365
|
+
return false;
|
|
62366
|
+
}
|
|
62367
|
+
const inherits = Array.isArray(role.inherits) ? role.inherits : [role.inherits];
|
|
62368
|
+
for (const inheritedId of inherits) {
|
|
62369
|
+
if (inheritedId && hasLoop(inheritedId)) {
|
|
62370
|
+
return true;
|
|
62371
|
+
}
|
|
62372
|
+
}
|
|
62373
|
+
checking.delete(roleId);
|
|
62374
|
+
checked.add(roleId);
|
|
62375
|
+
return false;
|
|
62376
|
+
}
|
|
62377
|
+
return !!roles.find((role) => hasLoop(role._id));
|
|
62378
|
+
}
|
|
62379
|
+
|
|
62337
62380
|
// ../shared-core/src/filters.ts
|
|
62338
62381
|
var import_lodash2 = require("lodash");
|
|
62339
62382
|
var HBS_REGEX = /{{([^{].*?)}}/g;
|
|
@@ -63244,6 +63287,7 @@ var allowDisplayColumnByType = {
|
|
|
63244
63287
|
["number" /* NUMBER */]: true,
|
|
63245
63288
|
["datetime" /* DATETIME */]: true,
|
|
63246
63289
|
["formula" /* FORMULA */]: true,
|
|
63290
|
+
["ai" /* AI */]: true,
|
|
63247
63291
|
["auto" /* AUTO */]: true,
|
|
63248
63292
|
["internal" /* INTERNAL */]: true,
|
|
63249
63293
|
["barcodeqr" /* BARCODEQR */]: true,
|
|
@@ -63271,6 +63315,7 @@ var allowSortColumnByType = {
|
|
|
63271
63315
|
["boolean" /* BOOLEAN */]: true,
|
|
63272
63316
|
["json" /* JSON */]: true,
|
|
63273
63317
|
["formula" /* FORMULA */]: false,
|
|
63318
|
+
["ai" /* AI */]: false,
|
|
63274
63319
|
["attachment" /* ATTACHMENTS */]: false,
|
|
63275
63320
|
["attachment_single" /* ATTACHMENT_SINGLE */]: false,
|
|
63276
63321
|
["signature_single" /* SIGNATURE_SINGLE */]: false,
|
|
@@ -63293,6 +63338,7 @@ var allowDefaultColumnByType = {
|
|
|
63293
63338
|
["bigint" /* BIGINT */]: false,
|
|
63294
63339
|
["boolean" /* BOOLEAN */]: false,
|
|
63295
63340
|
["formula" /* FORMULA */]: false,
|
|
63341
|
+
["ai" /* AI */]: false,
|
|
63296
63342
|
["attachment" /* ATTACHMENTS */]: false,
|
|
63297
63343
|
["attachment_single" /* ATTACHMENT_SINGLE */]: false,
|
|
63298
63344
|
["signature_single" /* SIGNATURE_SINGLE */]: false,
|
|
@@ -63498,7 +63544,7 @@ function doInUserContext(user, ctx, task) {
|
|
|
63498
63544
|
hostInfo: {
|
|
63499
63545
|
ipAddress: ctx.request.ip,
|
|
63500
63546
|
// filled in by koa-useragent package
|
|
63501
|
-
userAgent: ctx.userAgent.
|
|
63547
|
+
userAgent: ctx.userAgent.source
|
|
63502
63548
|
}
|
|
63503
63549
|
};
|
|
63504
63550
|
return doInIdentityContext2(userContext, task);
|
|
@@ -63560,23 +63606,35 @@ function httpLogging() {
|
|
|
63560
63606
|
return process.env.HTTP_LOGGING;
|
|
63561
63607
|
}
|
|
63562
63608
|
function getPackageJsonFields() {
|
|
63563
|
-
function
|
|
63564
|
-
|
|
63565
|
-
|
|
63566
|
-
|
|
63609
|
+
function getParentFile(file) {
|
|
63610
|
+
function findFileInAncestors(fileName, currentDir) {
|
|
63611
|
+
const filePath = `${currentDir}/${fileName}`;
|
|
63612
|
+
if ((0, import_fs.existsSync)(filePath)) {
|
|
63613
|
+
return filePath;
|
|
63614
|
+
}
|
|
63615
|
+
const parentDir = `${currentDir}/..`;
|
|
63616
|
+
if (parentDir === currentDir) {
|
|
63617
|
+
return null;
|
|
63618
|
+
}
|
|
63619
|
+
return findFileInAncestors(fileName, parentDir);
|
|
63567
63620
|
}
|
|
63568
|
-
const
|
|
63569
|
-
|
|
63570
|
-
|
|
63621
|
+
const packageJsonFile = findFileInAncestors(file, process.cwd());
|
|
63622
|
+
const content = (0, import_fs.readFileSync)(packageJsonFile, "utf-8");
|
|
63623
|
+
const parsedContent = JSON.parse(content);
|
|
63624
|
+
return parsedContent;
|
|
63625
|
+
}
|
|
63626
|
+
let localVersion;
|
|
63627
|
+
if (isDev() && !isTest()) {
|
|
63628
|
+
try {
|
|
63629
|
+
const lerna = getParentFile("lerna.json");
|
|
63630
|
+
localVersion = `${lerna.version}+local`;
|
|
63631
|
+
} catch {
|
|
63571
63632
|
}
|
|
63572
|
-
return findFileInAncestors(fileName, parentDir);
|
|
63573
63633
|
}
|
|
63574
63634
|
try {
|
|
63575
|
-
const
|
|
63576
|
-
const content = (0, import_fs.readFileSync)(packageJsonFile, "utf-8");
|
|
63577
|
-
const parsedContent = JSON.parse(content);
|
|
63635
|
+
const parsedContent = getParentFile("package.json");
|
|
63578
63636
|
return {
|
|
63579
|
-
VERSION: process.env.BUDIBASE_VERSION || parsedContent.version,
|
|
63637
|
+
VERSION: localVersion || process.env.BUDIBASE_VERSION || parsedContent.version,
|
|
63580
63638
|
SERVICE_NAME: parsedContent.name
|
|
63581
63639
|
};
|
|
63582
63640
|
} catch {
|
|
@@ -66555,7 +66613,7 @@ var QueryBuilder = class _QueryBuilder {
|
|
|
66555
66613
|
preprocess(value, {
|
|
66556
66614
|
escape,
|
|
66557
66615
|
lowercase,
|
|
66558
|
-
wrap,
|
|
66616
|
+
wrap: wrap2,
|
|
66559
66617
|
type
|
|
66560
66618
|
} = {}) {
|
|
66561
66619
|
const hasVersion = !!this.#version;
|
|
@@ -66568,7 +66626,7 @@ var QueryBuilder = class _QueryBuilder {
|
|
|
66568
66626
|
}
|
|
66569
66627
|
if (originalType === "string" && !isNaN(value) && !type) {
|
|
66570
66628
|
value = `"${value}"`;
|
|
66571
|
-
} else if (hasVersion &&
|
|
66629
|
+
} else if (hasVersion && wrap2) {
|
|
66572
66630
|
value = originalType === "number" ? value : `"${value}"`;
|
|
66573
66631
|
}
|
|
66574
66632
|
return value;
|
|
@@ -67726,12 +67784,13 @@ var FlagSet = class {
|
|
|
67726
67784
|
}
|
|
67727
67785
|
};
|
|
67728
67786
|
var flags = new FlagSet({
|
|
67729
|
-
DEFAULT_VALUES: Flag.boolean(environment_default.isDev()),
|
|
67730
|
-
AUTOMATION_BRANCHING: Flag.boolean(environment_default.isDev()),
|
|
67731
|
-
SQS: Flag.boolean(true),
|
|
67787
|
+
["DEFAULT_VALUES" /* DEFAULT_VALUES */]: Flag.boolean(environment_default.isDev()),
|
|
67788
|
+
["AUTOMATION_BRANCHING" /* AUTOMATION_BRANCHING */]: Flag.boolean(environment_default.isDev()),
|
|
67789
|
+
["SQS" /* SQS */]: Flag.boolean(true),
|
|
67732
67790
|
["AI_CUSTOM_CONFIGS" /* AI_CUSTOM_CONFIGS */]: Flag.boolean(environment_default.isDev()),
|
|
67733
67791
|
["ENRICHED_RELATIONSHIPS" /* ENRICHED_RELATIONSHIPS */]: Flag.boolean(environment_default.isDev()),
|
|
67734
|
-
["TABLES_DEFAULT_ADMIN" /* TABLES_DEFAULT_ADMIN */]: Flag.boolean(environment_default.isDev())
|
|
67792
|
+
["TABLES_DEFAULT_ADMIN" /* TABLES_DEFAULT_ADMIN */]: Flag.boolean(environment_default.isDev()),
|
|
67793
|
+
["BUDIBASE_AI" /* BUDIBASE_AI */]: Flag.boolean(environment_default.isDev())
|
|
67735
67794
|
});
|
|
67736
67795
|
|
|
67737
67796
|
// src/features/tests/utils.ts
|
|
@@ -68119,7 +68178,7 @@ var DatabaseImpl = class _DatabaseImpl {
|
|
|
68119
68178
|
});
|
|
68120
68179
|
}
|
|
68121
68180
|
async destroy() {
|
|
68122
|
-
if (await flags.isEnabled("SQS") && await this.exists(SQLITE_DESIGN_DOC_ID)) {
|
|
68181
|
+
if (await flags.isEnabled("SQS" /* SQS */) && await this.exists(SQLITE_DESIGN_DOC_ID)) {
|
|
68123
68182
|
const definition = await this.get(SQLITE_DESIGN_DOC_ID);
|
|
68124
68183
|
definition.sql.tables = {};
|
|
68125
68184
|
await this.put(definition);
|
|
@@ -69321,27 +69380,35 @@ var EmailUnavailableError = class extends Error {
|
|
|
69321
69380
|
};
|
|
69322
69381
|
|
|
69323
69382
|
// src/security/roles.ts
|
|
69324
|
-
var
|
|
69325
|
-
__export(
|
|
69383
|
+
var roles_exports2 = {};
|
|
69384
|
+
__export(roles_exports2, {
|
|
69326
69385
|
AccessController: () => AccessController,
|
|
69327
69386
|
BUILTIN_ROLE_IDS: () => BUILTIN_ROLE_IDS,
|
|
69328
|
-
Role: () =>
|
|
69387
|
+
Role: () => Role2,
|
|
69388
|
+
RoleHierarchyTraversal: () => RoleHierarchyTraversal,
|
|
69329
69389
|
RoleIDVersion: () => RoleIDVersion,
|
|
69330
69390
|
builtinRoleToNumber: () => builtinRoleToNumber,
|
|
69331
69391
|
checkForRoleResourceArray: () => checkForRoleResourceArray,
|
|
69392
|
+
compareRoleIds: () => compareRoleIds,
|
|
69393
|
+
externalRole: () => externalRole,
|
|
69394
|
+
findRole: () => findRole,
|
|
69332
69395
|
getAllRoleIds: () => getAllRoleIds,
|
|
69333
69396
|
getAllRoles: () => getAllRoles,
|
|
69334
69397
|
getBuiltinRole: () => getBuiltinRole,
|
|
69335
69398
|
getBuiltinRoles: () => getBuiltinRoles,
|
|
69336
69399
|
getDBRoleID: () => getDBRoleID,
|
|
69337
69400
|
getExternalRoleID: () => getExternalRoleID,
|
|
69401
|
+
getExternalRoleIDs: () => getExternalRoleIDs,
|
|
69338
69402
|
getRole: () => getRole,
|
|
69339
69403
|
getUserRoleHierarchy: () => getUserRoleHierarchy,
|
|
69340
69404
|
getUserRoleIdHierarchy: () => getUserRoleIdHierarchy,
|
|
69341
69405
|
isBuiltin: () => isBuiltin,
|
|
69342
69406
|
lowerBuiltinRoleID: () => lowerBuiltinRoleID,
|
|
69343
|
-
|
|
69407
|
+
prefixRoleIDNoBuiltin: () => prefixRoleIDNoBuiltin,
|
|
69408
|
+
roleToNumber: () => roleToNumber,
|
|
69409
|
+
saveRoles: () => saveRoles
|
|
69344
69410
|
});
|
|
69411
|
+
var import_semver = __toESM(require("semver"));
|
|
69345
69412
|
|
|
69346
69413
|
// src/security/permissions.ts
|
|
69347
69414
|
var permissions_exports = {};
|
|
@@ -69493,6 +69560,7 @@ var GLOBAL_BUILDER = "globalBuilder" /* GLOBAL_BUILDER */;
|
|
|
69493
69560
|
|
|
69494
69561
|
// src/security/roles.ts
|
|
69495
69562
|
var import_cloneDeep2 = __toESM(require("lodash/fp/cloneDeep"));
|
|
69563
|
+
var import_lodash4 = require("lodash");
|
|
69496
69564
|
var BUILTIN_ROLE_IDS = {
|
|
69497
69565
|
ADMIN: "ADMIN",
|
|
69498
69566
|
POWER: "POWER",
|
|
@@ -69503,19 +69571,20 @@ var BUILTIN_IDS = {
|
|
|
69503
69571
|
...BUILTIN_ROLE_IDS,
|
|
69504
69572
|
BUILDER: "BUILDER"
|
|
69505
69573
|
};
|
|
69506
|
-
var EXTERNAL_BUILTIN_ROLE_IDS = [
|
|
69507
|
-
BUILTIN_IDS.ADMIN,
|
|
69508
|
-
BUILTIN_IDS.POWER,
|
|
69509
|
-
BUILTIN_IDS.BASIC,
|
|
69510
|
-
BUILTIN_IDS.PUBLIC
|
|
69511
|
-
];
|
|
69512
69574
|
var RoleIDVersion = {
|
|
69513
69575
|
// original version, with a UUID based ID
|
|
69514
69576
|
UUID: void 0,
|
|
69515
69577
|
// new version - with name based ID
|
|
69516
69578
|
NAME: "name"
|
|
69517
69579
|
};
|
|
69518
|
-
|
|
69580
|
+
function rolesInList(roleIds, ids) {
|
|
69581
|
+
if (Array.isArray(ids)) {
|
|
69582
|
+
return ids.filter((id) => roleIds.includes(id)).length === ids.length;
|
|
69583
|
+
} else {
|
|
69584
|
+
return roleIds.includes(ids);
|
|
69585
|
+
}
|
|
69586
|
+
}
|
|
69587
|
+
var Role2 = class {
|
|
69519
69588
|
constructor(id, name, permissionId, uiMetadata) {
|
|
69520
69589
|
this.permissions = {};
|
|
69521
69590
|
this._id = id;
|
|
@@ -69525,12 +69594,57 @@ var Role = class {
|
|
|
69525
69594
|
this.version = RoleIDVersion.NAME;
|
|
69526
69595
|
}
|
|
69527
69596
|
addInheritance(inherits) {
|
|
69597
|
+
if (inherits && typeof inherits === "string") {
|
|
69598
|
+
inherits = prefixRoleIDNoBuiltin(inherits);
|
|
69599
|
+
} else if (inherits && Array.isArray(inherits)) {
|
|
69600
|
+
inherits = inherits.map(prefixRoleIDNoBuiltin);
|
|
69601
|
+
}
|
|
69528
69602
|
this.inherits = inherits;
|
|
69529
69603
|
return this;
|
|
69530
69604
|
}
|
|
69531
69605
|
};
|
|
69606
|
+
var RoleHierarchyTraversal = class {
|
|
69607
|
+
constructor(allRoles, opts) {
|
|
69608
|
+
this.allRoles = allRoles;
|
|
69609
|
+
this.opts = opts;
|
|
69610
|
+
}
|
|
69611
|
+
walk(role) {
|
|
69612
|
+
const opts = this.opts, allRoles = this.allRoles;
|
|
69613
|
+
let roleList = [];
|
|
69614
|
+
if (!role || !role._id) {
|
|
69615
|
+
return roleList;
|
|
69616
|
+
}
|
|
69617
|
+
roleList.push(role);
|
|
69618
|
+
if (Array.isArray(role.inherits)) {
|
|
69619
|
+
for (let roleId of role.inherits) {
|
|
69620
|
+
const foundRole = findRole(roleId, allRoles, opts);
|
|
69621
|
+
if (foundRole) {
|
|
69622
|
+
roleList = roleList.concat(this.walk(foundRole));
|
|
69623
|
+
}
|
|
69624
|
+
}
|
|
69625
|
+
} else {
|
|
69626
|
+
const foundRoleIds = [];
|
|
69627
|
+
let currentRole = role;
|
|
69628
|
+
while (currentRole && currentRole.inherits && !rolesInList(foundRoleIds, currentRole.inherits)) {
|
|
69629
|
+
if (Array.isArray(currentRole.inherits)) {
|
|
69630
|
+
return roleList.concat(this.walk(currentRole));
|
|
69631
|
+
} else {
|
|
69632
|
+
foundRoleIds.push(currentRole.inherits);
|
|
69633
|
+
currentRole = findRole(currentRole.inherits, allRoles, opts);
|
|
69634
|
+
if (currentRole) {
|
|
69635
|
+
roleList.push(currentRole);
|
|
69636
|
+
}
|
|
69637
|
+
}
|
|
69638
|
+
if (helpers_exports.roles.checkForRoleInheritanceLoops(roleList)) {
|
|
69639
|
+
break;
|
|
69640
|
+
}
|
|
69641
|
+
}
|
|
69642
|
+
}
|
|
69643
|
+
return (0, import_lodash4.uniqBy)(roleList, (role2) => role2._id);
|
|
69644
|
+
}
|
|
69645
|
+
};
|
|
69532
69646
|
var BUILTIN_ROLES = {
|
|
69533
|
-
ADMIN: new
|
|
69647
|
+
ADMIN: new Role2(
|
|
69534
69648
|
BUILTIN_IDS.ADMIN,
|
|
69535
69649
|
BUILTIN_IDS.ADMIN,
|
|
69536
69650
|
"admin" /* ADMIN */,
|
|
@@ -69540,7 +69654,7 @@ var BUILTIN_ROLES = {
|
|
|
69540
69654
|
color: "var(--spectrum-global-color-static-red-400)" /* ADMIN */
|
|
69541
69655
|
}
|
|
69542
69656
|
).addInheritance(BUILTIN_IDS.POWER),
|
|
69543
|
-
POWER: new
|
|
69657
|
+
POWER: new Role2(
|
|
69544
69658
|
BUILTIN_IDS.POWER,
|
|
69545
69659
|
BUILTIN_IDS.POWER,
|
|
69546
69660
|
"power" /* POWER */,
|
|
@@ -69550,7 +69664,7 @@ var BUILTIN_ROLES = {
|
|
|
69550
69664
|
color: "var(--spectrum-global-color-static-orange-400)" /* POWER */
|
|
69551
69665
|
}
|
|
69552
69666
|
).addInheritance(BUILTIN_IDS.BASIC),
|
|
69553
|
-
BASIC: new
|
|
69667
|
+
BASIC: new Role2(
|
|
69554
69668
|
BUILTIN_IDS.BASIC,
|
|
69555
69669
|
BUILTIN_IDS.BASIC,
|
|
69556
69670
|
"write" /* WRITE */,
|
|
@@ -69560,7 +69674,7 @@ var BUILTIN_ROLES = {
|
|
|
69560
69674
|
color: "var(--spectrum-global-color-static-green-400)" /* BASIC */
|
|
69561
69675
|
}
|
|
69562
69676
|
).addInheritance(BUILTIN_IDS.PUBLIC),
|
|
69563
|
-
PUBLIC: new
|
|
69677
|
+
PUBLIC: new Role2(
|
|
69564
69678
|
BUILTIN_IDS.PUBLIC,
|
|
69565
69679
|
BUILTIN_IDS.PUBLIC,
|
|
69566
69680
|
"public" /* PUBLIC */,
|
|
@@ -69570,7 +69684,7 @@ var BUILTIN_ROLES = {
|
|
|
69570
69684
|
color: "var(--spectrum-global-color-static-blue-400)" /* PUBLIC */
|
|
69571
69685
|
}
|
|
69572
69686
|
),
|
|
69573
|
-
BUILDER: new
|
|
69687
|
+
BUILDER: new Role2(
|
|
69574
69688
|
BUILTIN_IDS.BUILDER,
|
|
69575
69689
|
BUILTIN_IDS.BUILDER,
|
|
69576
69690
|
"admin" /* ADMIN */,
|
|
@@ -69585,7 +69699,14 @@ function getBuiltinRoles() {
|
|
|
69585
69699
|
return (0, import_cloneDeep2.default)(BUILTIN_ROLES);
|
|
69586
69700
|
}
|
|
69587
69701
|
function isBuiltin(role) {
|
|
69588
|
-
return
|
|
69702
|
+
return Object.values(BUILTIN_ROLE_IDS).includes(role);
|
|
69703
|
+
}
|
|
69704
|
+
function prefixRoleIDNoBuiltin(roleId) {
|
|
69705
|
+
if (isBuiltin(roleId)) {
|
|
69706
|
+
return roleId;
|
|
69707
|
+
} else {
|
|
69708
|
+
return prefixRoleID(roleId);
|
|
69709
|
+
}
|
|
69589
69710
|
}
|
|
69590
69711
|
function getBuiltinRole(roleId) {
|
|
69591
69712
|
const role = Object.values(BUILTIN_ROLES).find(
|
|
@@ -69607,7 +69728,11 @@ function builtinRoleToNumber(id) {
|
|
|
69607
69728
|
if (!role) {
|
|
69608
69729
|
break;
|
|
69609
69730
|
}
|
|
69610
|
-
|
|
69731
|
+
if (Array.isArray(role.inherits)) {
|
|
69732
|
+
throw new Error("Built-in roles don't support multi-inheritance");
|
|
69733
|
+
} else {
|
|
69734
|
+
role = builtins[role.inherits];
|
|
69735
|
+
}
|
|
69611
69736
|
count++;
|
|
69612
69737
|
} while (role !== null);
|
|
69613
69738
|
return count;
|
|
@@ -69619,12 +69744,26 @@ async function roleToNumber(id) {
|
|
|
69619
69744
|
const hierarchy = await getUserRoleHierarchy(id, {
|
|
69620
69745
|
defaultPublic: true
|
|
69621
69746
|
});
|
|
69622
|
-
|
|
69623
|
-
if (role
|
|
69747
|
+
const findNumber = (role) => {
|
|
69748
|
+
if (!role.inherits) {
|
|
69749
|
+
return 0;
|
|
69750
|
+
}
|
|
69751
|
+
if (Array.isArray(role.inherits)) {
|
|
69752
|
+
const highestBuiltin = role.inherits.map((roleId) => {
|
|
69753
|
+
const foundRole = hierarchy.find((role2) => role2._id === roleId);
|
|
69754
|
+
if (foundRole) {
|
|
69755
|
+
return findNumber(foundRole) + 1;
|
|
69756
|
+
}
|
|
69757
|
+
}).filter((number) => number).sort().pop();
|
|
69758
|
+
if (highestBuiltin != void 0) {
|
|
69759
|
+
return highestBuiltin;
|
|
69760
|
+
}
|
|
69761
|
+
} else if (isBuiltin(role.inherits)) {
|
|
69624
69762
|
return builtinRoleToNumber(role.inherits) + 1;
|
|
69625
69763
|
}
|
|
69626
|
-
|
|
69627
|
-
|
|
69764
|
+
return 0;
|
|
69765
|
+
};
|
|
69766
|
+
return Math.max(...hierarchy.map(findNumber));
|
|
69628
69767
|
}
|
|
69629
69768
|
function lowerBuiltinRoleID(roleId1, roleId2) {
|
|
69630
69769
|
if (!roleId1) {
|
|
@@ -69635,39 +69774,67 @@ function lowerBuiltinRoleID(roleId1, roleId2) {
|
|
|
69635
69774
|
}
|
|
69636
69775
|
return builtinRoleToNumber(roleId1) > builtinRoleToNumber(roleId2) ? roleId2 : roleId1;
|
|
69637
69776
|
}
|
|
69638
|
-
|
|
69777
|
+
function compareRoleIds(roleId1, roleId2) {
|
|
69778
|
+
return prefixRoleID(roleId1) === prefixRoleID(roleId2);
|
|
69779
|
+
}
|
|
69780
|
+
function externalRole(role) {
|
|
69781
|
+
let _id;
|
|
69782
|
+
if (role._id) {
|
|
69783
|
+
_id = getExternalRoleID(role._id);
|
|
69784
|
+
}
|
|
69785
|
+
return {
|
|
69786
|
+
...role,
|
|
69787
|
+
_id,
|
|
69788
|
+
inherits: getExternalRoleIDs(role.inherits, role.version)
|
|
69789
|
+
};
|
|
69790
|
+
}
|
|
69791
|
+
function findRole(roleId, roles, opts) {
|
|
69639
69792
|
let role = getBuiltinRole(roleId);
|
|
69640
69793
|
if (!role) {
|
|
69641
69794
|
roleId = prefixRoleID(roleId);
|
|
69642
69795
|
}
|
|
69643
|
-
|
|
69644
|
-
|
|
69645
|
-
|
|
69646
|
-
|
|
69796
|
+
const dbRole = roles.find(
|
|
69797
|
+
(role2) => role2._id && compareRoleIds(role2._id, roleId)
|
|
69798
|
+
);
|
|
69799
|
+
if (!dbRole && !isBuiltin(roleId) && opts?.defaultPublic) {
|
|
69800
|
+
return (0, import_cloneDeep2.default)(BUILTIN_ROLES.PUBLIC);
|
|
69801
|
+
}
|
|
69802
|
+
role = Object.assign(role || {}, dbRole);
|
|
69803
|
+
if (role?._id) {
|
|
69647
69804
|
role._id = getExternalRoleID(role._id, role.version);
|
|
69648
|
-
}
|
|
69649
|
-
|
|
69650
|
-
|
|
69651
|
-
|
|
69652
|
-
|
|
69653
|
-
|
|
69805
|
+
}
|
|
69806
|
+
return Object.keys(role).length === 0 ? void 0 : role;
|
|
69807
|
+
}
|
|
69808
|
+
async function getRole(roleId, opts) {
|
|
69809
|
+
const db = getAppDB();
|
|
69810
|
+
const roleList = [];
|
|
69811
|
+
if (!isBuiltin(roleId)) {
|
|
69812
|
+
const role = await db.tryGet(getDBRoleID(roleId));
|
|
69813
|
+
if (role) {
|
|
69814
|
+
roleList.push(role);
|
|
69654
69815
|
}
|
|
69655
69816
|
}
|
|
69656
|
-
return
|
|
69817
|
+
return findRole(roleId, roleList, opts);
|
|
69818
|
+
}
|
|
69819
|
+
async function saveRoles(roles) {
|
|
69820
|
+
const db = getAppDB();
|
|
69821
|
+
await db.bulkDocs(
|
|
69822
|
+
roles.filter((role) => role._id).map((role) => ({
|
|
69823
|
+
...role,
|
|
69824
|
+
_id: prefixRoleID(role._id)
|
|
69825
|
+
}))
|
|
69826
|
+
);
|
|
69657
69827
|
}
|
|
69658
69828
|
async function getAllUserRoles(userRoleId, opts) {
|
|
69829
|
+
const allRoles = await getAllRoles();
|
|
69659
69830
|
if (userRoleId === BUILTIN_IDS.ADMIN) {
|
|
69660
|
-
return
|
|
69831
|
+
return allRoles;
|
|
69661
69832
|
}
|
|
69662
|
-
|
|
69663
|
-
let roles =
|
|
69664
|
-
|
|
69665
|
-
|
|
69666
|
-
|
|
69667
|
-
currentRole = await getRole(currentRole.inherits);
|
|
69668
|
-
if (currentRole) {
|
|
69669
|
-
roles.push(currentRole);
|
|
69670
|
-
}
|
|
69833
|
+
const foundRole = findRole(userRoleId, allRoles, opts);
|
|
69834
|
+
let roles = [];
|
|
69835
|
+
if (foundRole) {
|
|
69836
|
+
const traversal = new RoleHierarchyTraversal(allRoles, opts);
|
|
69837
|
+
roles = traversal.walk(foundRole);
|
|
69671
69838
|
}
|
|
69672
69839
|
return roles;
|
|
69673
69840
|
}
|
|
@@ -69717,7 +69884,22 @@ async function getAllRoles(appId) {
|
|
|
69717
69884
|
);
|
|
69718
69885
|
}
|
|
69719
69886
|
const builtinRoles = getBuiltinRoles();
|
|
69720
|
-
|
|
69887
|
+
let externalBuiltinRoles = [];
|
|
69888
|
+
if (!db || await shouldIncludePowerRole(db)) {
|
|
69889
|
+
externalBuiltinRoles = [
|
|
69890
|
+
BUILTIN_IDS.ADMIN,
|
|
69891
|
+
BUILTIN_IDS.POWER,
|
|
69892
|
+
BUILTIN_IDS.BASIC,
|
|
69893
|
+
BUILTIN_IDS.PUBLIC
|
|
69894
|
+
];
|
|
69895
|
+
} else {
|
|
69896
|
+
externalBuiltinRoles = [
|
|
69897
|
+
BUILTIN_IDS.ADMIN,
|
|
69898
|
+
BUILTIN_IDS.BASIC,
|
|
69899
|
+
BUILTIN_IDS.PUBLIC
|
|
69900
|
+
];
|
|
69901
|
+
}
|
|
69902
|
+
for (let builtinRoleId of externalBuiltinRoles) {
|
|
69721
69903
|
const builtinRole = builtinRoles[builtinRoleId];
|
|
69722
69904
|
const dbBuiltin = roles.filter(
|
|
69723
69905
|
(dbRole) => getExternalRoleID(dbRole._id, dbRole.version) === builtinRoleId
|
|
@@ -69744,6 +69926,15 @@ async function getAllRoles(appId) {
|
|
|
69744
69926
|
return roles;
|
|
69745
69927
|
}
|
|
69746
69928
|
}
|
|
69929
|
+
async function shouldIncludePowerRole(db) {
|
|
69930
|
+
const app = await db.tryGet("app_metadata" /* APP_METADATA */);
|
|
69931
|
+
const creationVersion = app?.creationVersion;
|
|
69932
|
+
if (!creationVersion || !import_semver.default.valid(creationVersion)) {
|
|
69933
|
+
return true;
|
|
69934
|
+
}
|
|
69935
|
+
const isGreaterThan3x = import_semver.default.gte(creationVersion, "3.0.0");
|
|
69936
|
+
return !isGreaterThan3x;
|
|
69937
|
+
}
|
|
69747
69938
|
var AccessController = class {
|
|
69748
69939
|
constructor() {
|
|
69749
69940
|
this.userHierarchies = {};
|
|
@@ -69757,7 +69948,7 @@ var AccessController = class {
|
|
|
69757
69948
|
roleIds = await getUserRoleIdHierarchy(userRoleId);
|
|
69758
69949
|
this.userHierarchies[userRoleId] = roleIds;
|
|
69759
69950
|
}
|
|
69760
|
-
return roleIds?.
|
|
69951
|
+
return roleIds?.find((roleId) => compareRoleIds(roleId, tryingRoleId)) !== void 0;
|
|
69761
69952
|
}
|
|
69762
69953
|
async checkScreensAccess(screens, userRoleId) {
|
|
69763
69954
|
let accessibleScreens = [];
|
|
@@ -69784,13 +69975,22 @@ function getDBRoleID(roleName) {
|
|
|
69784
69975
|
return prefixRoleID(roleName);
|
|
69785
69976
|
}
|
|
69786
69977
|
function getExternalRoleID(roleId, version) {
|
|
69787
|
-
if (roleId.startsWith("role" /* ROLE */) && (isBuiltin(roleId) || version === RoleIDVersion.NAME)) {
|
|
69978
|
+
if (roleId.startsWith(`${"role" /* ROLE */}${SEPARATOR}`) && (isBuiltin(roleId) || version === RoleIDVersion.NAME)) {
|
|
69788
69979
|
const parts = roleId.split(SEPARATOR);
|
|
69789
69980
|
parts.shift();
|
|
69790
69981
|
return parts.join(SEPARATOR);
|
|
69791
69982
|
}
|
|
69792
69983
|
return roleId;
|
|
69793
69984
|
}
|
|
69985
|
+
function getExternalRoleIDs(roleIds, version) {
|
|
69986
|
+
if (!roleIds) {
|
|
69987
|
+
return roleIds;
|
|
69988
|
+
} else if (typeof roleIds === "string") {
|
|
69989
|
+
return getExternalRoleID(roleIds, version);
|
|
69990
|
+
} else {
|
|
69991
|
+
return roleIds.map((roleId) => getExternalRoleID(roleId, version));
|
|
69992
|
+
}
|
|
69993
|
+
}
|
|
69794
69994
|
|
|
69795
69995
|
// src/users/utils.ts
|
|
69796
69996
|
var isBuilder2 = sdk_exports.users.isBuilder;
|
|
@@ -70590,7 +70790,7 @@ __export(installation_exports, {
|
|
|
70590
70790
|
getInstall: () => getInstall,
|
|
70591
70791
|
getInstallFromDB: () => getInstallFromDB
|
|
70592
70792
|
});
|
|
70593
|
-
var
|
|
70793
|
+
var import_semver2 = __toESM(require("semver"));
|
|
70594
70794
|
var getInstall = async () => {
|
|
70595
70795
|
return withCache("installation" /* INSTALLATION */, 86400 /* ONE_DAY */, getInstallFromDB, {
|
|
70596
70796
|
useTenancy: false
|
|
@@ -70659,8 +70859,8 @@ var checkInstallVersion = async () => {
|
|
|
70659
70859
|
const newVersion = environment_default.VERSION;
|
|
70660
70860
|
try {
|
|
70661
70861
|
if (currentVersion !== newVersion) {
|
|
70662
|
-
const isUpgrade =
|
|
70663
|
-
const isDowngrade =
|
|
70862
|
+
const isUpgrade = import_semver2.default.gt(newVersion, currentVersion);
|
|
70863
|
+
const isDowngrade = import_semver2.default.lt(newVersion, currentVersion);
|
|
70664
70864
|
const success = await updateVersion(newVersion);
|
|
70665
70865
|
if (success) {
|
|
70666
70866
|
await doInIdentityContext(
|
|
@@ -74435,6 +74635,7 @@ function timeMinusOneMinute() {
|
|
|
74435
74635
|
function finalise(ctx, opts = {}) {
|
|
74436
74636
|
ctx.publicEndpoint = opts.publicEndpoint || false;
|
|
74437
74637
|
ctx.isAuthenticated = opts.authenticated || false;
|
|
74638
|
+
ctx.loginMethod = opts.loginMethod;
|
|
74438
74639
|
ctx.user = opts.user;
|
|
74439
74640
|
ctx.internal = opts.internal || false;
|
|
74440
74641
|
ctx.version = opts.version;
|
|
@@ -74492,7 +74693,7 @@ function authenticated_default(noAuthPatterns = [], opts = {
|
|
|
74492
74693
|
apiKey = ctx.request.headers["authorization" /* AUTHORIZATION */].split(" ")[1];
|
|
74493
74694
|
}
|
|
74494
74695
|
const tenantId = ctx.request.headers["x-budibase-tenant-id" /* TENANT_ID */];
|
|
74495
|
-
let authenticated = false, user =
|
|
74696
|
+
let authenticated = false, user = void 0, internal = false, loginMethod = void 0;
|
|
74496
74697
|
if (authCookie && !apiKey) {
|
|
74497
74698
|
const sessionId = authCookie.sessionId;
|
|
74498
74699
|
const userId = authCookie.userId;
|
|
@@ -74514,6 +74715,7 @@ function authenticated_default(noAuthPatterns = [], opts = {
|
|
|
74514
74715
|
});
|
|
74515
74716
|
}
|
|
74516
74717
|
user.csrfToken = session.csrfToken;
|
|
74718
|
+
loginMethod = "cookie" /* COOKIE */;
|
|
74517
74719
|
if (session?.lastAccessedAt < timeMinusOneMinute()) {
|
|
74518
74720
|
await updateSessionTTL(session);
|
|
74519
74721
|
}
|
|
@@ -74530,17 +74732,16 @@ function authenticated_default(noAuthPatterns = [], opts = {
|
|
|
74530
74732
|
apiKey,
|
|
74531
74733
|
populateUser
|
|
74532
74734
|
);
|
|
74533
|
-
if (valid
|
|
74735
|
+
if (valid) {
|
|
74534
74736
|
authenticated = true;
|
|
74737
|
+
loginMethod = "api_key" /* API_KEY */;
|
|
74535
74738
|
user = foundUser;
|
|
74536
|
-
|
|
74537
|
-
authenticated = true;
|
|
74538
|
-
internal = true;
|
|
74739
|
+
internal = !foundUser;
|
|
74539
74740
|
}
|
|
74540
74741
|
}
|
|
74541
74742
|
if (!user && tenantId) {
|
|
74542
74743
|
user = { tenantId };
|
|
74543
|
-
} else if (user) {
|
|
74744
|
+
} else if (user && "password" in user) {
|
|
74544
74745
|
delete user.password;
|
|
74545
74746
|
}
|
|
74546
74747
|
if (!authenticated) {
|
|
@@ -74557,7 +74758,14 @@ function authenticated_default(noAuthPatterns = [], opts = {
|
|
|
74557
74758
|
status: user.status
|
|
74558
74759
|
});
|
|
74559
74760
|
}
|
|
74560
|
-
finalise(ctx, {
|
|
74761
|
+
finalise(ctx, {
|
|
74762
|
+
authenticated,
|
|
74763
|
+
user,
|
|
74764
|
+
internal,
|
|
74765
|
+
version,
|
|
74766
|
+
publicEndpoint,
|
|
74767
|
+
loginMethod
|
|
74768
|
+
});
|
|
74561
74769
|
if (isUser(user)) {
|
|
74562
74770
|
return doInUserContext(user, ctx, next);
|
|
74563
74771
|
} else {
|
|
@@ -75294,7 +75502,7 @@ var import_knex2 = require("knex");
|
|
|
75294
75502
|
// src/sql/sqlTable.ts
|
|
75295
75503
|
var import_knex = require("knex");
|
|
75296
75504
|
function isIgnoredType(type) {
|
|
75297
|
-
const ignored = ["link" /* LINK */, "formula" /* FORMULA */];
|
|
75505
|
+
const ignored = ["link" /* LINK */, "formula" /* FORMULA */, "ai" /* AI */];
|
|
75298
75506
|
return ignored.indexOf(type) !== -1;
|
|
75299
75507
|
}
|
|
75300
75508
|
function generateSchema(schema, table, tables, oldTable = null, renamed) {
|
|
@@ -75390,6 +75598,8 @@ function generateSchema(schema, table, tables, oldTable = null, renamed) {
|
|
|
75390
75598
|
break;
|
|
75391
75599
|
case "formula" /* FORMULA */:
|
|
75392
75600
|
break;
|
|
75601
|
+
case "ai" /* AI */:
|
|
75602
|
+
break;
|
|
75393
75603
|
case "attachment" /* ATTACHMENTS */:
|
|
75394
75604
|
case "attachment_single" /* ATTACHMENT_SINGLE */:
|
|
75395
75605
|
case "signature_single" /* SIGNATURE_SINGLE */:
|
|
@@ -75521,7 +75731,7 @@ var SqlTableQueryBuilder = class {
|
|
|
75521
75731
|
var sqlTable_default = SqlTableQueryBuilder;
|
|
75522
75732
|
|
|
75523
75733
|
// src/sql/sql.ts
|
|
75524
|
-
var
|
|
75734
|
+
var import_lodash5 = require("lodash");
|
|
75525
75735
|
var COUNT_FIELD_NAME = "__bb_total";
|
|
75526
75736
|
function getBaseLimit() {
|
|
75527
75737
|
const envLimit = environment_default.SQL_MAX_ROWS ? parseInt(environment_default.SQL_MAX_ROWS) : null;
|
|
@@ -75562,6 +75772,20 @@ function convertBooleans(query) {
|
|
|
75562
75772
|
function isSqs(table) {
|
|
75563
75773
|
return table.sourceType === "internal" /* INTERNAL */ || table.sourceId === INTERNAL_TABLE_SOURCE_ID;
|
|
75564
75774
|
}
|
|
75775
|
+
function escapeQuotes(value, quoteChar = '"') {
|
|
75776
|
+
return value.replace(new RegExp(quoteChar, "g"), `${quoteChar}${quoteChar}`);
|
|
75777
|
+
}
|
|
75778
|
+
function wrap(value, quoteChar = '"') {
|
|
75779
|
+
return `${quoteChar}${escapeQuotes(value, quoteChar)}${quoteChar}`;
|
|
75780
|
+
}
|
|
75781
|
+
function stringifyArray(value, quoteStyle = '"') {
|
|
75782
|
+
for (let i in value) {
|
|
75783
|
+
if (typeof value[i] === "string") {
|
|
75784
|
+
value[i] = wrap(value[i], quoteStyle);
|
|
75785
|
+
}
|
|
75786
|
+
}
|
|
75787
|
+
return `[${value.join(",")}]`;
|
|
75788
|
+
}
|
|
75565
75789
|
var allowEmptyRelationships = {
|
|
75566
75790
|
["equal" /* EQUAL */]: false,
|
|
75567
75791
|
["notEqual" /* NOT_EQUAL */]: true,
|
|
@@ -75599,28 +75823,24 @@ var InternalBuilder = class {
|
|
|
75599
75823
|
get table() {
|
|
75600
75824
|
return this.query.meta.table;
|
|
75601
75825
|
}
|
|
75826
|
+
get knexClient() {
|
|
75827
|
+
return this.knex.client;
|
|
75828
|
+
}
|
|
75602
75829
|
getFieldSchema(key) {
|
|
75603
75830
|
const { column } = this.splitter.run(key);
|
|
75604
75831
|
return this.table.schema[column];
|
|
75605
75832
|
}
|
|
75833
|
+
supportsILike() {
|
|
75834
|
+
return !(this.client === "oracledb" /* ORACLE */ || this.client === "sqlite3" /* SQL_LITE */);
|
|
75835
|
+
}
|
|
75606
75836
|
quoteChars() {
|
|
75607
|
-
|
|
75608
|
-
|
|
75609
|
-
case "pg" /* POSTGRES */:
|
|
75610
|
-
return ['"', '"'];
|
|
75611
|
-
case "mssql" /* MS_SQL */:
|
|
75612
|
-
return ["[", "]"];
|
|
75613
|
-
case "mariadb" /* MARIADB */:
|
|
75614
|
-
case "mysql2" /* MY_SQL */:
|
|
75615
|
-
case "sqlite3" /* SQL_LITE */:
|
|
75616
|
-
return ["`", "`"];
|
|
75617
|
-
}
|
|
75837
|
+
const wrapped = this.knexClient.wrapIdentifier("foo", {});
|
|
75838
|
+
return [wrapped[0], wrapped[wrapped.length - 1]];
|
|
75618
75839
|
}
|
|
75619
|
-
// Takes a string like foo and returns a quoted string like [foo] for SQL
|
|
75620
|
-
// and "foo" for Postgres.
|
|
75840
|
+
// Takes a string like foo and returns a quoted string like [foo] for SQL
|
|
75841
|
+
// Server and "foo" for Postgres.
|
|
75621
75842
|
quote(str) {
|
|
75622
|
-
|
|
75623
|
-
return `${start2}${str}${end2}`;
|
|
75843
|
+
return this.knexClient.wrapIdentifier(str, {});
|
|
75624
75844
|
}
|
|
75625
75845
|
isQuoted(key) {
|
|
75626
75846
|
const [start2, end2] = this.quoteChars();
|
|
@@ -75635,6 +75855,27 @@ var InternalBuilder = class {
|
|
|
75635
75855
|
}
|
|
75636
75856
|
return key.map((part) => this.quote(part)).join(".");
|
|
75637
75857
|
}
|
|
75858
|
+
quotedValue(value) {
|
|
75859
|
+
const formatter = this.knexClient.formatter(this.knexClient.queryBuilder());
|
|
75860
|
+
return formatter.wrap(value, false);
|
|
75861
|
+
}
|
|
75862
|
+
rawQuotedValue(value) {
|
|
75863
|
+
return this.knex.raw(this.quotedValue(value));
|
|
75864
|
+
}
|
|
75865
|
+
// Unfortuantely we cannot rely on knex's identifier escaping because it trims
|
|
75866
|
+
// the identifier string before escaping it, which breaks cases for us where
|
|
75867
|
+
// columns that start or end with a space aren't referenced correctly anymore.
|
|
75868
|
+
//
|
|
75869
|
+
// So whenever you're using an identifier binding in knex, e.g. knex.raw("??
|
|
75870
|
+
// as ?", ["foo", "bar"]), you need to make sure you call this:
|
|
75871
|
+
//
|
|
75872
|
+
// knex.raw("?? as ?", [this.quotedIdentifier("foo"), "bar"])
|
|
75873
|
+
//
|
|
75874
|
+
// Issue we filed against knex about this:
|
|
75875
|
+
// https://github.com/knex/knex/issues/6143
|
|
75876
|
+
rawQuotedIdentifier(key) {
|
|
75877
|
+
return this.knex.raw(this.quotedIdentifier(key));
|
|
75878
|
+
}
|
|
75638
75879
|
// Turns an identifier like a.b.c or `a`.`b`.`c` into ["a", "b", "c"]
|
|
75639
75880
|
splitIdentifier(key) {
|
|
75640
75881
|
const [start2, end2] = this.quoteChars();
|
|
@@ -75673,7 +75914,7 @@ var InternalBuilder = class {
|
|
|
75673
75914
|
const alias = this.getTableName(endpoint.entityId);
|
|
75674
75915
|
const schema = meta.table.schema;
|
|
75675
75916
|
if (!this.isFullSelectStatementRequired()) {
|
|
75676
|
-
return [this.knex.raw(`${
|
|
75917
|
+
return [this.knex.raw("??", [`${alias}.*`])];
|
|
75677
75918
|
}
|
|
75678
75919
|
return resource.fields.map((field) => {
|
|
75679
75920
|
const parts = field.split(/\./g);
|
|
@@ -75687,17 +75928,21 @@ var InternalBuilder = class {
|
|
|
75687
75928
|
}).filter(({ table }) => !table || table === alias).map(({ table, column, field }) => {
|
|
75688
75929
|
const columnSchema = schema[column];
|
|
75689
75930
|
if (this.SPECIAL_SELECT_CASES.POSTGRES_MONEY(columnSchema)) {
|
|
75690
|
-
return this.knex.raw(
|
|
75691
|
-
|
|
75692
|
-
|
|
75693
|
-
|
|
75694
|
-
);
|
|
75931
|
+
return this.knex.raw(`??::money::numeric as "${field}"`, [
|
|
75932
|
+
this.rawQuotedIdentifier([table, column].join(".")),
|
|
75933
|
+
field
|
|
75934
|
+
]);
|
|
75695
75935
|
}
|
|
75696
75936
|
if (this.SPECIAL_SELECT_CASES.MSSQL_DATES(columnSchema)) {
|
|
75697
|
-
return this.knex.raw(`CONVERT(varchar,
|
|
75937
|
+
return this.knex.raw(`CONVERT(varchar, ??, 108) as "${field}"`, [
|
|
75938
|
+
this.rawQuotedIdentifier(field)
|
|
75939
|
+
]);
|
|
75940
|
+
}
|
|
75941
|
+
if (table) {
|
|
75942
|
+
return this.rawQuotedIdentifier(`${table}.${column}`);
|
|
75943
|
+
} else {
|
|
75944
|
+
return this.rawQuotedIdentifier(field);
|
|
75698
75945
|
}
|
|
75699
|
-
const quoted = table ? `${this.quote(table)}.${this.quote(column)}` : this.quote(field);
|
|
75700
|
-
return this.knex.raw(quoted);
|
|
75701
75946
|
});
|
|
75702
75947
|
}
|
|
75703
75948
|
// OracleDB can't use character-large-objects (CLOBs) in WHERE clauses,
|
|
@@ -75712,12 +75957,15 @@ var InternalBuilder = class {
|
|
|
75712
75957
|
const parts = this.splitIdentifier(field);
|
|
75713
75958
|
const col = parts.pop();
|
|
75714
75959
|
const schema = this.table.schema[col];
|
|
75715
|
-
let identifier = this.
|
|
75960
|
+
let identifier = this.rawQuotedIdentifier(field);
|
|
75716
75961
|
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 */) {
|
|
75717
75962
|
if (opts?.forSelect) {
|
|
75718
|
-
identifier =
|
|
75963
|
+
identifier = this.knex.raw("to_char(??) as ??", [
|
|
75964
|
+
identifier,
|
|
75965
|
+
this.rawQuotedIdentifier(col)
|
|
75966
|
+
]);
|
|
75719
75967
|
} else {
|
|
75720
|
-
identifier =
|
|
75968
|
+
identifier = this.knex.raw("to_char(??)", [identifier]);
|
|
75721
75969
|
}
|
|
75722
75970
|
}
|
|
75723
75971
|
return identifier;
|
|
@@ -75762,7 +76010,7 @@ var InternalBuilder = class {
|
|
|
75762
76010
|
return body2;
|
|
75763
76011
|
}
|
|
75764
76012
|
parseFilters(filters) {
|
|
75765
|
-
filters = (0,
|
|
76013
|
+
filters = (0, import_lodash5.cloneDeep)(filters);
|
|
75766
76014
|
for (const op of Object.values(BasicOperator)) {
|
|
75767
76015
|
const filter = filters[op];
|
|
75768
76016
|
if (!filter) {
|
|
@@ -75822,7 +76070,6 @@ var InternalBuilder = class {
|
|
|
75822
76070
|
return query.andWhere(`${document}.fieldName`, "=", relationship.column);
|
|
75823
76071
|
}
|
|
75824
76072
|
addRelationshipForFilter(query, allowEmptyRelationships2, filterKey, whereCb) {
|
|
75825
|
-
const mainKnex = this.knex;
|
|
75826
76073
|
const { relationships, endpoint, tableAliases: aliases } = this.query;
|
|
75827
76074
|
const tableName = endpoint.entityId;
|
|
75828
76075
|
const fromAlias = aliases?.[tableName] || tableName;
|
|
@@ -75836,7 +76083,7 @@ var InternalBuilder = class {
|
|
|
75836
76083
|
const matchesTableName = matches2(relatedTableName) || matches2(toAlias);
|
|
75837
76084
|
const matchesRelationName = matches2(relationship.column);
|
|
75838
76085
|
if ((matchesTableName || matchesRelationName) && relationship.to && relationship.tableName) {
|
|
75839
|
-
const joinTable =
|
|
76086
|
+
const joinTable = this.knex.select(this.knex.raw(1)).from({ [toAlias]: relatedTableName });
|
|
75840
76087
|
let subQuery = joinTable.clone();
|
|
75841
76088
|
const manyToMany = validateManyToMany(relationship);
|
|
75842
76089
|
let updatedKey;
|
|
@@ -75863,9 +76110,7 @@ var InternalBuilder = class {
|
|
|
75863
76110
|
}).where(
|
|
75864
76111
|
`${throughAlias}.${manyToMany.from}`,
|
|
75865
76112
|
"=",
|
|
75866
|
-
|
|
75867
|
-
this.quotedIdentifier(`${fromAlias}.${manyToMany.fromPrimary}`)
|
|
75868
|
-
)
|
|
76113
|
+
this.rawQuotedIdentifier(`${fromAlias}.${manyToMany.fromPrimary}`)
|
|
75869
76114
|
);
|
|
75870
76115
|
if (this.client === "sqlite3" /* SQL_LITE */) {
|
|
75871
76116
|
subQuery = this.addJoinFieldCheck(subQuery, manyToMany);
|
|
@@ -75890,7 +76135,7 @@ var InternalBuilder = class {
|
|
|
75890
76135
|
subQuery = subQuery.where(
|
|
75891
76136
|
toKey,
|
|
75892
76137
|
"=",
|
|
75893
|
-
|
|
76138
|
+
this.rawQuotedIdentifier(foreignKey)
|
|
75894
76139
|
);
|
|
75895
76140
|
query = query.where((q2) => {
|
|
75896
76141
|
q2.whereExists(whereCb(updatedKey, subQuery.clone()));
|
|
@@ -75911,7 +76156,7 @@ var InternalBuilder = class {
|
|
|
75911
76156
|
const builder = this;
|
|
75912
76157
|
filters = this.parseFilters({ ...filters });
|
|
75913
76158
|
const aliases = this.query.tableAliases;
|
|
75914
|
-
const
|
|
76159
|
+
const shouldOr = filters.allOr;
|
|
75915
76160
|
const isSqlite = this.client === "sqlite3" /* SQL_LITE */;
|
|
75916
76161
|
const tableName = isSqlite ? this.table._id : this.table.name;
|
|
75917
76162
|
function getTableAlias(name) {
|
|
@@ -75950,7 +76195,7 @@ var InternalBuilder = class {
|
|
|
75950
76195
|
value
|
|
75951
76196
|
);
|
|
75952
76197
|
} else if (shouldProcessRelationship) {
|
|
75953
|
-
if (
|
|
76198
|
+
if (shouldOr) {
|
|
75954
76199
|
query = query.or;
|
|
75955
76200
|
}
|
|
75956
76201
|
query = builder.addRelationshipForFilter(
|
|
@@ -75965,75 +76210,89 @@ var InternalBuilder = class {
|
|
|
75965
76210
|
}
|
|
75966
76211
|
}
|
|
75967
76212
|
const like = (q2, key, value) => {
|
|
75968
|
-
|
|
75969
|
-
|
|
75970
|
-
|
|
75971
|
-
|
|
75972
|
-
|
|
75973
|
-
|
|
75974
|
-
return q2[rawFnc](`LOWER(${this.quotedIdentifier(key)}) LIKE ?`, [
|
|
76213
|
+
if (filters?.fuzzyOr || shouldOr) {
|
|
76214
|
+
q2 = q2.or;
|
|
76215
|
+
}
|
|
76216
|
+
if (this.client === "oracledb" /* ORACLE */ || this.client === "sqlite3" /* SQL_LITE */) {
|
|
76217
|
+
return q2.whereRaw(`LOWER(??) LIKE ?`, [
|
|
76218
|
+
this.rawQuotedIdentifier(key),
|
|
75975
76219
|
`%${value.toLowerCase()}%`
|
|
75976
76220
|
]);
|
|
75977
76221
|
}
|
|
76222
|
+
return q2.whereILike(
|
|
76223
|
+
// @ts-expect-error knex types are wrong, raw is fine here
|
|
76224
|
+
this.rawQuotedIdentifier(key),
|
|
76225
|
+
this.knex.raw("?", [`%${value}%`])
|
|
76226
|
+
);
|
|
75978
76227
|
};
|
|
75979
76228
|
const contains = (mode, any = false) => {
|
|
75980
|
-
|
|
75981
|
-
|
|
75982
|
-
|
|
75983
|
-
|
|
75984
|
-
|
|
75985
|
-
|
|
75986
|
-
}
|
|
76229
|
+
function addModifiers(q2) {
|
|
76230
|
+
if (shouldOr || mode === filters?.containsAny) {
|
|
76231
|
+
q2 = q2.or;
|
|
76232
|
+
}
|
|
76233
|
+
if (mode === filters?.notContains) {
|
|
76234
|
+
q2 = q2.not;
|
|
75987
76235
|
}
|
|
75988
|
-
return
|
|
76236
|
+
return q2;
|
|
75989
76237
|
}
|
|
75990
76238
|
if (this.client === "pg" /* POSTGRES */) {
|
|
75991
76239
|
iterate(mode, "contains" /* CONTAINS */, (q2, key, value) => {
|
|
75992
|
-
|
|
75993
|
-
|
|
75994
|
-
|
|
75995
|
-
|
|
75996
|
-
|
|
75997
|
-
|
|
75998
|
-
|
|
75999
|
-
|
|
76000
|
-
|
|
76001
|
-
|
|
76002
|
-
|
|
76240
|
+
q2 = addModifiers(q2);
|
|
76241
|
+
if (any) {
|
|
76242
|
+
return q2.whereRaw(`COALESCE(??::jsonb \\?| array??, FALSE)`, [
|
|
76243
|
+
this.rawQuotedIdentifier(key),
|
|
76244
|
+
this.knex.raw(stringifyArray(value, "'"))
|
|
76245
|
+
]);
|
|
76246
|
+
} else {
|
|
76247
|
+
return q2.whereRaw(`COALESCE(??::jsonb @> '??', FALSE)`, [
|
|
76248
|
+
this.rawQuotedIdentifier(key),
|
|
76249
|
+
this.knex.raw(stringifyArray(value))
|
|
76250
|
+
]);
|
|
76251
|
+
}
|
|
76003
76252
|
});
|
|
76004
76253
|
} else if (this.client === "mysql2" /* MY_SQL */ || this.client === "mariadb" /* MARIADB */) {
|
|
76005
|
-
const jsonFnc = any ? "JSON_OVERLAPS" : "JSON_CONTAINS";
|
|
76006
76254
|
iterate(mode, "contains" /* CONTAINS */, (q2, key, value) => {
|
|
76007
|
-
return q2[
|
|
76008
|
-
|
|
76009
|
-
|
|
76010
|
-
)
|
|
76011
|
-
);
|
|
76255
|
+
return addModifiers(q2).whereRaw(`COALESCE(?(??, ?), FALSE)`, [
|
|
76256
|
+
this.knex.raw(any ? "JSON_OVERLAPS" : "JSON_CONTAINS"),
|
|
76257
|
+
this.rawQuotedIdentifier(key),
|
|
76258
|
+
this.knex.raw(wrap(stringifyArray(value)))
|
|
76259
|
+
]);
|
|
76012
76260
|
});
|
|
76013
76261
|
} else {
|
|
76014
|
-
const andOr = mode === filters?.containsAny ? " OR " : " AND ";
|
|
76015
76262
|
iterate(mode, "contains" /* CONTAINS */, (q2, key, value) => {
|
|
76016
|
-
|
|
76017
|
-
const identifier = this.quotedIdentifier(key);
|
|
76018
|
-
for (let i in value) {
|
|
76019
|
-
if (typeof value[i] === "string") {
|
|
76020
|
-
value[i] = `%"${value[i].toLowerCase()}"%`;
|
|
76021
|
-
} else {
|
|
76022
|
-
value[i] = `%${value[i]}%`;
|
|
76023
|
-
}
|
|
76024
|
-
statement += `${statement ? andOr : ""}COALESCE(LOWER(${identifier}), '') LIKE ?`;
|
|
76025
|
-
}
|
|
76026
|
-
if (statement === "") {
|
|
76263
|
+
if (value.length === 0) {
|
|
76027
76264
|
return q2;
|
|
76028
76265
|
}
|
|
76029
|
-
|
|
76030
|
-
|
|
76031
|
-
|
|
76032
|
-
|
|
76033
|
-
)
|
|
76034
|
-
|
|
76035
|
-
|
|
76036
|
-
|
|
76266
|
+
q2 = q2.where((subQuery) => {
|
|
76267
|
+
if (mode === filters?.notContains) {
|
|
76268
|
+
subQuery = subQuery.not;
|
|
76269
|
+
}
|
|
76270
|
+
subQuery = subQuery.where((subSubQuery) => {
|
|
76271
|
+
for (const elem of value) {
|
|
76272
|
+
if (mode === filters?.containsAny) {
|
|
76273
|
+
subSubQuery = subSubQuery.or;
|
|
76274
|
+
} else {
|
|
76275
|
+
subSubQuery = subSubQuery.and;
|
|
76276
|
+
}
|
|
76277
|
+
const lower = typeof elem === "string" ? `"${elem.toLowerCase()}"` : elem;
|
|
76278
|
+
subSubQuery = subSubQuery.whereLike(
|
|
76279
|
+
// @ts-expect-error knex types are wrong, raw is fine here
|
|
76280
|
+
this.knex.raw(`COALESCE(LOWER(??), '')`, [
|
|
76281
|
+
this.rawQuotedIdentifier(key)
|
|
76282
|
+
]),
|
|
76283
|
+
`%${lower}%`
|
|
76284
|
+
);
|
|
76285
|
+
}
|
|
76286
|
+
});
|
|
76287
|
+
if (mode === filters?.notContains) {
|
|
76288
|
+
subQuery = subQuery.or.whereNull(
|
|
76289
|
+
// @ts-expect-error knex types are wrong, raw is fine here
|
|
76290
|
+
this.rawQuotedIdentifier(key)
|
|
76291
|
+
);
|
|
76292
|
+
}
|
|
76293
|
+
return subQuery;
|
|
76294
|
+
});
|
|
76295
|
+
return q2;
|
|
76037
76296
|
});
|
|
76038
76297
|
}
|
|
76039
76298
|
};
|
|
@@ -76056,41 +76315,41 @@ var InternalBuilder = class {
|
|
|
76056
76315
|
});
|
|
76057
76316
|
}
|
|
76058
76317
|
if (filters.oneOf) {
|
|
76059
|
-
const fnc = allOr ? "orWhereIn" : "whereIn";
|
|
76060
76318
|
iterate(
|
|
76061
76319
|
filters.oneOf,
|
|
76062
76320
|
"oneOf" /* ONE_OF */,
|
|
76063
76321
|
(q2, key, array) => {
|
|
76322
|
+
if (shouldOr) {
|
|
76323
|
+
q2 = q2.or;
|
|
76324
|
+
}
|
|
76064
76325
|
if (this.client === "oracledb" /* ORACLE */) {
|
|
76065
76326
|
key = this.convertClobs(key);
|
|
76066
|
-
array = Array.isArray(array) ? array : [array];
|
|
76067
|
-
const binding = new Array(array.length).fill("?").join(",");
|
|
76068
|
-
return q2.whereRaw(`${key} IN (${binding})`, array);
|
|
76069
|
-
} else {
|
|
76070
|
-
return q2[fnc](key, Array.isArray(array) ? array : [array]);
|
|
76071
76327
|
}
|
|
76328
|
+
return q2.whereIn(key, Array.isArray(array) ? array : [array]);
|
|
76072
76329
|
},
|
|
76073
76330
|
(q2, key, array) => {
|
|
76331
|
+
if (shouldOr) {
|
|
76332
|
+
q2 = q2.or;
|
|
76333
|
+
}
|
|
76074
76334
|
if (this.client === "oracledb" /* ORACLE */) {
|
|
76075
|
-
|
|
76076
|
-
const binding = `(${array.map((a) => `(${new Array(a.length).fill("?").join(",")})`).join(",")})`;
|
|
76077
|
-
return q2.whereRaw(`${keyStr} IN ${binding}`, array.flat());
|
|
76078
|
-
} else {
|
|
76079
|
-
return q2[fnc](key, Array.isArray(array) ? array : [array]);
|
|
76335
|
+
key = key.map((k) => this.convertClobs(k));
|
|
76080
76336
|
}
|
|
76337
|
+
return q2.whereIn(key, Array.isArray(array) ? array : [array]);
|
|
76081
76338
|
}
|
|
76082
76339
|
);
|
|
76083
76340
|
}
|
|
76084
76341
|
if (filters.string) {
|
|
76085
76342
|
iterate(filters.string, "string" /* STRING */, (q2, key, value) => {
|
|
76086
|
-
|
|
76087
|
-
|
|
76088
|
-
|
|
76089
|
-
|
|
76090
|
-
|
|
76091
|
-
|
|
76343
|
+
if (shouldOr) {
|
|
76344
|
+
q2 = q2.or;
|
|
76345
|
+
}
|
|
76346
|
+
if (this.client === "oracledb" /* ORACLE */ || this.client === "sqlite3" /* SQL_LITE */) {
|
|
76347
|
+
return q2.whereRaw(`LOWER(??) LIKE ?`, [
|
|
76348
|
+
this.rawQuotedIdentifier(key),
|
|
76092
76349
|
`${value.toLowerCase()}%`
|
|
76093
76350
|
]);
|
|
76351
|
+
} else {
|
|
76352
|
+
return q2.whereILike(key, `${value}%`);
|
|
76094
76353
|
}
|
|
76095
76354
|
});
|
|
76096
76355
|
}
|
|
@@ -76110,56 +76369,52 @@ var InternalBuilder = class {
|
|
|
76110
76369
|
}
|
|
76111
76370
|
const lowValid = isValidFilter(value.low), highValid = isValidFilter(value.high);
|
|
76112
76371
|
const schema = this.getFieldSchema(key);
|
|
76372
|
+
let rawKey = key;
|
|
76373
|
+
let high = value.high;
|
|
76374
|
+
let low = value.low;
|
|
76113
76375
|
if (this.client === "oracledb" /* ORACLE */) {
|
|
76114
|
-
|
|
76376
|
+
rawKey = this.convertClobs(key);
|
|
76377
|
+
} else if (this.client === "sqlite3" /* SQL_LITE */ && schema?.type === "bigint" /* BIGINT */) {
|
|
76378
|
+
rawKey = this.knex.raw("CAST(?? AS INTEGER)", [
|
|
76379
|
+
this.rawQuotedIdentifier(key)
|
|
76380
|
+
]);
|
|
76381
|
+
high = this.knex.raw("CAST(? AS INTEGER)", [value.high]);
|
|
76382
|
+
low = this.knex.raw("CAST(? AS INTEGER)", [value.low]);
|
|
76383
|
+
}
|
|
76384
|
+
if (shouldOr) {
|
|
76385
|
+
q2 = q2.or;
|
|
76115
76386
|
}
|
|
76116
76387
|
if (lowValid && highValid) {
|
|
76117
|
-
|
|
76118
|
-
return q2.whereRaw(
|
|
76119
|
-
`CAST(${key} AS INTEGER) BETWEEN CAST(? AS INTEGER) AND CAST(? AS INTEGER)`,
|
|
76120
|
-
[value.low, value.high]
|
|
76121
|
-
);
|
|
76122
|
-
} else {
|
|
76123
|
-
const fnc = allOr ? "orWhereBetween" : "whereBetween";
|
|
76124
|
-
return q2[fnc](key, [value.low, value.high]);
|
|
76125
|
-
}
|
|
76388
|
+
return q2.whereBetween(rawKey, [low, high]);
|
|
76126
76389
|
} else if (lowValid) {
|
|
76127
|
-
|
|
76128
|
-
return q2.whereRaw(`CAST(${key} AS INTEGER) >= CAST(? AS INTEGER)`, [
|
|
76129
|
-
value.low
|
|
76130
|
-
]);
|
|
76131
|
-
} else {
|
|
76132
|
-
const fnc = allOr ? "orWhere" : "where";
|
|
76133
|
-
return q2[fnc](key, ">=", value.low);
|
|
76134
|
-
}
|
|
76390
|
+
return q2.where(rawKey, ">=", low);
|
|
76135
76391
|
} else if (highValid) {
|
|
76136
|
-
|
|
76137
|
-
return q2.whereRaw(`CAST(${key} AS INTEGER) <= CAST(? AS INTEGER)`, [
|
|
76138
|
-
value.high
|
|
76139
|
-
]);
|
|
76140
|
-
} else {
|
|
76141
|
-
const fnc = allOr ? "orWhere" : "where";
|
|
76142
|
-
return q2[fnc](key, "<=", value.high);
|
|
76143
|
-
}
|
|
76392
|
+
return q2.where(rawKey, "<=", high);
|
|
76144
76393
|
}
|
|
76145
76394
|
return q2;
|
|
76146
76395
|
});
|
|
76147
76396
|
}
|
|
76148
76397
|
if (filters.equal) {
|
|
76149
76398
|
iterate(filters.equal, "equal" /* EQUAL */, (q2, key, value) => {
|
|
76150
|
-
|
|
76399
|
+
if (shouldOr) {
|
|
76400
|
+
q2 = q2.or;
|
|
76401
|
+
}
|
|
76151
76402
|
if (this.client === "mssql" /* MS_SQL */) {
|
|
76152
|
-
return q2[
|
|
76153
|
-
|
|
76154
|
-
[value]
|
|
76155
|
-
);
|
|
76156
|
-
} else if (this.client === "oracledb" /* ORACLE */) {
|
|
76157
|
-
const identifier = this.convertClobs(key);
|
|
76158
|
-
return q2[fnc](`(${identifier} IS NOT NULL AND ${identifier} = ?)`, [
|
|
76403
|
+
return q2.whereRaw(`CASE WHEN ?? = ? THEN 1 ELSE 0 END = 1`, [
|
|
76404
|
+
this.rawQuotedIdentifier(key),
|
|
76159
76405
|
value
|
|
76160
76406
|
]);
|
|
76407
|
+
} else if (this.client === "oracledb" /* ORACLE */) {
|
|
76408
|
+
const identifier = this.convertClobs(key);
|
|
76409
|
+
return q2.where(
|
|
76410
|
+
(subq) => (
|
|
76411
|
+
// @ts-expect-error knex types are wrong, raw is fine here
|
|
76412
|
+
subq.whereNotNull(identifier).andWhere(identifier, value)
|
|
76413
|
+
)
|
|
76414
|
+
);
|
|
76161
76415
|
} else {
|
|
76162
|
-
return q2
|
|
76416
|
+
return q2.whereRaw(`COALESCE(?? = ?, FALSE)`, [
|
|
76417
|
+
this.rawQuotedIdentifier(key),
|
|
76163
76418
|
value
|
|
76164
76419
|
]);
|
|
76165
76420
|
}
|
|
@@ -76167,20 +76422,22 @@ var InternalBuilder = class {
|
|
|
76167
76422
|
}
|
|
76168
76423
|
if (filters.notEqual) {
|
|
76169
76424
|
iterate(filters.notEqual, "notEqual" /* NOT_EQUAL */, (q2, key, value) => {
|
|
76170
|
-
|
|
76425
|
+
if (shouldOr) {
|
|
76426
|
+
q2 = q2.or;
|
|
76427
|
+
}
|
|
76171
76428
|
if (this.client === "mssql" /* MS_SQL */) {
|
|
76172
|
-
return q2[
|
|
76173
|
-
|
|
76174
|
-
|
|
76175
|
-
);
|
|
76429
|
+
return q2.whereRaw(`CASE WHEN ?? = ? THEN 1 ELSE 0 END = 0`, [
|
|
76430
|
+
this.rawQuotedIdentifier(key),
|
|
76431
|
+
value
|
|
76432
|
+
]);
|
|
76176
76433
|
} else if (this.client === "oracledb" /* ORACLE */) {
|
|
76177
76434
|
const identifier = this.convertClobs(key);
|
|
76178
|
-
return q2
|
|
76179
|
-
|
|
76180
|
-
|
|
76181
|
-
);
|
|
76435
|
+
return q2.where(
|
|
76436
|
+
(subq) => subq.not.whereNull(identifier).and.where(identifier, "!=", value)
|
|
76437
|
+
).or.whereNull(identifier);
|
|
76182
76438
|
} else {
|
|
76183
|
-
return q2
|
|
76439
|
+
return q2.whereRaw(`COALESCE(?? != ?, TRUE)`, [
|
|
76440
|
+
this.rawQuotedIdentifier(key),
|
|
76184
76441
|
value
|
|
76185
76442
|
]);
|
|
76186
76443
|
}
|
|
@@ -76188,14 +76445,18 @@ var InternalBuilder = class {
|
|
|
76188
76445
|
}
|
|
76189
76446
|
if (filters.empty) {
|
|
76190
76447
|
iterate(filters.empty, "empty" /* EMPTY */, (q2, key) => {
|
|
76191
|
-
|
|
76192
|
-
|
|
76448
|
+
if (shouldOr) {
|
|
76449
|
+
q2 = q2.or;
|
|
76450
|
+
}
|
|
76451
|
+
return q2.whereNull(key);
|
|
76193
76452
|
});
|
|
76194
76453
|
}
|
|
76195
76454
|
if (filters.notEmpty) {
|
|
76196
76455
|
iterate(filters.notEmpty, "notEmpty" /* NOT_EMPTY */, (q2, key) => {
|
|
76197
|
-
|
|
76198
|
-
|
|
76456
|
+
if (shouldOr) {
|
|
76457
|
+
q2 = q2.or;
|
|
76458
|
+
}
|
|
76459
|
+
return q2.whereNotNull(key);
|
|
76199
76460
|
});
|
|
76200
76461
|
}
|
|
76201
76462
|
if (filters.contains) {
|
|
@@ -76264,7 +76525,7 @@ var InternalBuilder = class {
|
|
|
76264
76525
|
const selectFields = qualifiedFields.map(
|
|
76265
76526
|
(field) => this.convertClobs(field, { forSelect: true })
|
|
76266
76527
|
);
|
|
76267
|
-
query = query.
|
|
76528
|
+
query = query.groupBy(groupByFields).select(selectFields);
|
|
76268
76529
|
} else {
|
|
76269
76530
|
query = query.groupBy(qualifiedFields).select(qualifiedFields);
|
|
76270
76531
|
}
|
|
@@ -76276,11 +76537,10 @@ var InternalBuilder = class {
|
|
|
76276
76537
|
if (this.client === "oracledb" /* ORACLE */) {
|
|
76277
76538
|
const field = this.convertClobs(`${tableName}.${aggregation.field}`);
|
|
76278
76539
|
query = query.select(
|
|
76279
|
-
this.knex.raw(
|
|
76280
|
-
|
|
76281
|
-
|
|
76282
|
-
|
|
76283
|
-
)
|
|
76540
|
+
this.knex.raw(`COUNT(DISTINCT ??) as ??`, [
|
|
76541
|
+
field,
|
|
76542
|
+
aggregation.name
|
|
76543
|
+
])
|
|
76284
76544
|
);
|
|
76285
76545
|
} else {
|
|
76286
76546
|
query = query.countDistinct(
|
|
@@ -76335,9 +76595,11 @@ var InternalBuilder = class {
|
|
|
76335
76595
|
} else {
|
|
76336
76596
|
let composite = `${aliased}.${key}`;
|
|
76337
76597
|
if (this.client === "oracledb" /* ORACLE */) {
|
|
76338
|
-
query = query.orderByRaw(
|
|
76339
|
-
|
|
76340
|
-
|
|
76598
|
+
query = query.orderByRaw(`?? ?? nulls ??`, [
|
|
76599
|
+
this.convertClobs(composite),
|
|
76600
|
+
this.knex.raw(direction),
|
|
76601
|
+
this.knex.raw(nulls)
|
|
76602
|
+
]);
|
|
76341
76603
|
} else {
|
|
76342
76604
|
query = query.orderBy(composite, direction, nulls);
|
|
76343
76605
|
}
|
|
@@ -76359,17 +76621,18 @@ var InternalBuilder = class {
|
|
|
76359
76621
|
}
|
|
76360
76622
|
buildJsonField(field) {
|
|
76361
76623
|
const parts = field.split(".");
|
|
76362
|
-
let
|
|
76624
|
+
let unaliased;
|
|
76625
|
+
let tableField;
|
|
76363
76626
|
if (parts.length > 1) {
|
|
76364
76627
|
const alias = parts.shift();
|
|
76365
76628
|
unaliased = parts.join(".");
|
|
76366
|
-
tableField = `${
|
|
76629
|
+
tableField = `${alias}.${unaliased}`;
|
|
76367
76630
|
} else {
|
|
76368
76631
|
unaliased = parts.join(".");
|
|
76369
|
-
tableField =
|
|
76632
|
+
tableField = unaliased;
|
|
76370
76633
|
}
|
|
76371
76634
|
const separator = this.client === "oracledb" /* ORACLE */ ? " VALUE " : ",";
|
|
76372
|
-
return
|
|
76635
|
+
return this.knex.raw(`?${separator}??`, [unaliased, this.rawQuotedIdentifier(tableField)]).toString();
|
|
76373
76636
|
}
|
|
76374
76637
|
maxFunctionParameters() {
|
|
76375
76638
|
switch (this.client) {
|
|
@@ -76433,11 +76696,11 @@ var InternalBuilder = class {
|
|
|
76433
76696
|
subQuery = subQuery.where(
|
|
76434
76697
|
correlatedTo,
|
|
76435
76698
|
"=",
|
|
76436
|
-
|
|
76699
|
+
this.rawQuotedIdentifier(correlatedFrom)
|
|
76437
76700
|
);
|
|
76438
76701
|
const standardWrap = (select) => {
|
|
76439
76702
|
subQuery = subQuery.select(`${toAlias}.*`).limit(getRelationshipLimit());
|
|
76440
|
-
return knex3.select(
|
|
76703
|
+
return knex3.select(select).from({
|
|
76441
76704
|
[toAlias]: subQuery
|
|
76442
76705
|
});
|
|
76443
76706
|
};
|
|
@@ -76446,12 +76709,12 @@ var InternalBuilder = class {
|
|
|
76446
76709
|
case "sqlite3" /* SQL_LITE */:
|
|
76447
76710
|
subQuery = this.addJoinFieldCheck(subQuery, relationship);
|
|
76448
76711
|
wrapperQuery = standardWrap(
|
|
76449
|
-
`json_group_array(json_object(${fieldList}))`
|
|
76712
|
+
this.knex.raw(`json_group_array(json_object(${fieldList}))`)
|
|
76450
76713
|
);
|
|
76451
76714
|
break;
|
|
76452
76715
|
case "pg" /* POSTGRES */:
|
|
76453
76716
|
wrapperQuery = standardWrap(
|
|
76454
|
-
`json_agg(json_build_object(${fieldList}))`
|
|
76717
|
+
this.knex.raw(`json_agg(json_build_object(${fieldList}))`)
|
|
76455
76718
|
);
|
|
76456
76719
|
break;
|
|
76457
76720
|
case "mariadb" /* MARIADB */:
|
|
@@ -76464,16 +76727,19 @@ var InternalBuilder = class {
|
|
|
76464
76727
|
case "mysql2" /* MY_SQL */:
|
|
76465
76728
|
case "oracledb" /* ORACLE */:
|
|
76466
76729
|
wrapperQuery = standardWrap(
|
|
76467
|
-
`json_arrayagg(json_object(${fieldList}))`
|
|
76730
|
+
this.knex.raw(`json_arrayagg(json_object(${fieldList}))`)
|
|
76468
76731
|
);
|
|
76469
76732
|
break;
|
|
76470
|
-
case "mssql" /* MS_SQL */:
|
|
76733
|
+
case "mssql" /* MS_SQL */: {
|
|
76734
|
+
const comparatorQuery = knex3.select(`${fromAlias}.*`).from({
|
|
76735
|
+
[fromAlias]: subQuery.select(`${toAlias}.*`).limit(getRelationshipLimit())
|
|
76736
|
+
});
|
|
76471
76737
|
wrapperQuery = knex3.raw(
|
|
76472
|
-
`(SELECT
|
|
76473
|
-
|
|
76474
|
-
})} FOR JSON PATH))`
|
|
76738
|
+
`(SELECT ?? = (${comparatorQuery} FOR JSON PATH))`,
|
|
76739
|
+
[this.rawQuotedIdentifier(toAlias)]
|
|
76475
76740
|
);
|
|
76476
76741
|
break;
|
|
76742
|
+
}
|
|
76477
76743
|
default:
|
|
76478
76744
|
throw new Error(`JSON relationships not implement for ${sqlClient}`);
|
|
76479
76745
|
}
|