@budibase/backend-core 2.31.8 → 2.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +420 -186
- 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 +2 -2
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/cache/user.d.ts +7 -1
- package/dist/src/cache/user.js +4 -3
- package/dist/src/cache/user.js.map +1 -1
- package/dist/src/environment.d.ts +1 -0
- package/dist/src/environment.js +1 -1
- package/dist/src/environment.js.map +1 -1
- package/dist/src/events/index.d.ts +1 -0
- package/dist/src/events/index.js +3 -1
- package/dist/src/events/index.js.map +1 -1
- package/dist/src/events/publishers/ai.d.ts +7 -0
- package/dist/src/events/publishers/ai.js +30 -0
- package/dist/src/events/publishers/ai.js.map +1 -0
- package/dist/src/events/publishers/index.d.ts +1 -0
- package/dist/src/events/publishers/index.js +3 -1
- package/dist/src/events/publishers/index.js.map +1 -1
- package/dist/src/features/index.d.ts +2 -0
- package/dist/src/features/index.js +2 -0
- package/dist/src/features/index.js.map +1 -1
- package/dist/src/middleware/authenticated.js +16 -3
- package/dist/src/middleware/authenticated.js.map +1 -1
- package/dist/src/sql/sql.js +333 -161
- package/dist/src/sql/sql.js.map +1 -1
- package/dist/src/sql/utils.d.ts +2 -1
- package/dist/src/sql/utils.js +14 -0
- package/dist/src/sql/utils.js.map +1 -1
- package/dist/tests/core/utilities/structures/licenses.js +10 -0
- package/dist/tests/core/utilities/structures/licenses.js.map +1 -1
- package/dist/tests/core/utilities/structures/quotas.js +4 -0
- package/dist/tests/core/utilities/structures/quotas.js.map +1 -1
- package/package.json +4 -4
- package/src/cache/user.ts +17 -6
- package/src/environment.ts +1 -0
- package/src/events/index.ts +1 -0
- package/src/events/publishers/ai.ts +21 -0
- package/src/events/publishers/index.ts +1 -0
- package/src/features/index.ts +2 -0
- package/src/middleware/authenticated.ts +25 -8
- package/src/sql/sql.ts +460 -224
- package/src/sql/utils.ts +29 -1
- package/tests/core/utilities/structures/licenses.ts +10 -0
- package/tests/core/utilities/structures/quotas.ts +4 -0
package/dist/index.js
CHANGED
|
@@ -54288,6 +54288,9 @@ var AuditedEventFriendlyName = {
|
|
|
54288
54288
|
// EMAIL
|
|
54289
54289
|
["email:smtp:created" /* EMAIL_SMTP_CREATED */]: `Email configuration created`,
|
|
54290
54290
|
["email:smtp:updated" /* EMAIL_SMTP_UPDATED */]: `Email configuration updated`,
|
|
54291
|
+
// AI
|
|
54292
|
+
["ai:config:created" /* AI_CONFIG_CREATED */]: `AI configuration created`,
|
|
54293
|
+
["ai:config:updated" /* AI_CONFIG_UPDATED */]: `AI configuration updated`,
|
|
54291
54294
|
// AUTH
|
|
54292
54295
|
["auth:sso:created" /* AUTH_SSO_CREATED */]: `SSO configuration created`,
|
|
54293
54296
|
["auth:sso:updated" /* AUTH_SSO_UPDATED */]: `SSO configuration updated`,
|
|
@@ -55065,6 +55068,12 @@ function decodeNonAscii(str) {
|
|
|
55065
55068
|
// ../shared-core/src/filters.ts
|
|
55066
55069
|
var import_lodash = require("lodash");
|
|
55067
55070
|
var HBS_REGEX = /{{([^{].*?)}}/g;
|
|
55071
|
+
var LOGICAL_OPERATORS = Object.values(LogicalOperator);
|
|
55072
|
+
var SEARCH_OPERATORS = [
|
|
55073
|
+
...Object.values(BasicOperator),
|
|
55074
|
+
...Object.values(ArrayOperator),
|
|
55075
|
+
...Object.values(RangeOperator)
|
|
55076
|
+
];
|
|
55068
55077
|
var getValidOperatorsForType = (fieldType, field, datasource2) => {
|
|
55069
55078
|
const Op = OperatorOptions;
|
|
55070
55079
|
const stringOps = [
|
|
@@ -55125,7 +55134,7 @@ var NoEmptyFilterStrings = [
|
|
|
55125
55134
|
OperatorOptions.In.value
|
|
55126
55135
|
];
|
|
55127
55136
|
function recurseLogicalOperators(filters, fn) {
|
|
55128
|
-
for (const logical of
|
|
55137
|
+
for (const logical of LOGICAL_OPERATORS) {
|
|
55129
55138
|
if (filters[logical]) {
|
|
55130
55139
|
filters[logical].conditions = filters[logical].conditions.map(
|
|
55131
55140
|
(condition) => fn(condition)
|
|
@@ -55136,7 +55145,7 @@ function recurseLogicalOperators(filters, fn) {
|
|
|
55136
55145
|
}
|
|
55137
55146
|
function recurseSearchFilters(filters, processFn) {
|
|
55138
55147
|
filters = processFn(filters);
|
|
55139
|
-
for (const logical of
|
|
55148
|
+
for (const logical of LOGICAL_OPERATORS) {
|
|
55140
55149
|
if (filters[logical]) {
|
|
55141
55150
|
filters[logical].conditions = filters[logical].conditions.map(
|
|
55142
55151
|
(condition) => recurseSearchFilters(condition, processFn)
|
|
@@ -55353,7 +55362,7 @@ function fixupFilterArrays(filters) {
|
|
|
55353
55362
|
recurseLogicalOperators(filters, fixupFilterArrays);
|
|
55354
55363
|
return filters;
|
|
55355
55364
|
}
|
|
55356
|
-
|
|
55365
|
+
function search(docs, query) {
|
|
55357
55366
|
let result = runQuery(docs, query.query);
|
|
55358
55367
|
if (query.sort) {
|
|
55359
55368
|
result = sort(result, query.sort, query.sortOrder || "ascending" /* ASCENDING */);
|
|
@@ -55367,8 +55376,8 @@ var search = (docs, query) => {
|
|
|
55367
55376
|
response.totalRows = totalRows;
|
|
55368
55377
|
}
|
|
55369
55378
|
return response;
|
|
55370
|
-
}
|
|
55371
|
-
|
|
55379
|
+
}
|
|
55380
|
+
function runQuery(docs, query) {
|
|
55372
55381
|
if (!docs || !Array.isArray(docs)) {
|
|
55373
55382
|
return [];
|
|
55374
55383
|
}
|
|
@@ -55382,7 +55391,7 @@ var runQuery = (docs, query, findInDoc = deepGet) => {
|
|
|
55382
55391
|
}
|
|
55383
55392
|
const match = (type, test) => (doc) => {
|
|
55384
55393
|
for (const [key, testValue] of Object.entries(query[type] || {})) {
|
|
55385
|
-
const valueToCheck = isLogicalSearchOperator(type) ? doc :
|
|
55394
|
+
const valueToCheck = isLogicalSearchOperator(type) ? doc : deepGet(doc, removeKeyNumbering(key));
|
|
55386
55395
|
const result = test(valueToCheck, testValue);
|
|
55387
55396
|
if (query.allOr && result) {
|
|
55388
55397
|
return true;
|
|
@@ -55599,15 +55608,17 @@ var runQuery = (docs, query, findInDoc = deepGet) => {
|
|
|
55599
55608
|
).map(([key]) => {
|
|
55600
55609
|
return filterFunctions[key]?.(doc) ?? false;
|
|
55601
55610
|
});
|
|
55602
|
-
if (query
|
|
55611
|
+
if (!hasFilters(query)) {
|
|
55612
|
+
return true;
|
|
55613
|
+
} else if (query.allOr) {
|
|
55603
55614
|
return results.some((result) => result === true);
|
|
55604
55615
|
} else {
|
|
55605
55616
|
return results.every((result) => result === true);
|
|
55606
55617
|
}
|
|
55607
55618
|
};
|
|
55608
55619
|
return docs.filter(docMatch);
|
|
55609
|
-
}
|
|
55610
|
-
|
|
55620
|
+
}
|
|
55621
|
+
function sort(docs, sort2, sortOrder, sortType = "string" /* STRING */) {
|
|
55611
55622
|
if (!sort2 || !sortOrder || !sortType) {
|
|
55612
55623
|
return docs;
|
|
55613
55624
|
}
|
|
@@ -55629,28 +55640,45 @@ var sort = (docs, sort2, sortOrder, sortType = "string" /* STRING */) => {
|
|
|
55629
55640
|
}
|
|
55630
55641
|
return result;
|
|
55631
55642
|
});
|
|
55632
|
-
}
|
|
55633
|
-
|
|
55643
|
+
}
|
|
55644
|
+
function limit(docs, limit2) {
|
|
55634
55645
|
const numLimit = parseFloat(limit2);
|
|
55635
55646
|
if (isNaN(numLimit)) {
|
|
55636
55647
|
return docs;
|
|
55637
55648
|
}
|
|
55638
55649
|
return docs.slice(0, numLimit);
|
|
55639
|
-
}
|
|
55650
|
+
}
|
|
55640
55651
|
var hasFilters = (query) => {
|
|
55641
55652
|
if (!query) {
|
|
55642
55653
|
return false;
|
|
55643
55654
|
}
|
|
55644
|
-
const
|
|
55645
|
-
|
|
55646
|
-
|
|
55647
|
-
|
|
55655
|
+
const check = (filters) => {
|
|
55656
|
+
for (const logical of LOGICAL_OPERATORS) {
|
|
55657
|
+
if (filters[logical]) {
|
|
55658
|
+
for (const condition of filters[logical]?.conditions || []) {
|
|
55659
|
+
const result = check(condition);
|
|
55660
|
+
if (result) {
|
|
55661
|
+
return result;
|
|
55662
|
+
}
|
|
55663
|
+
}
|
|
55664
|
+
}
|
|
55648
55665
|
}
|
|
55649
|
-
|
|
55650
|
-
|
|
55666
|
+
for (const search2 of SEARCH_OPERATORS) {
|
|
55667
|
+
const searchValue = filters[search2];
|
|
55668
|
+
if (!searchValue || typeof searchValue !== "object") {
|
|
55669
|
+
continue;
|
|
55670
|
+
}
|
|
55671
|
+
const filtered2 = Object.entries(searchValue).filter((entry2) => {
|
|
55672
|
+
const valueDefined = entry2[1] !== void 0 || entry2[1] !== null || entry2[1] !== "";
|
|
55673
|
+
return search2 === "notEmpty" /* NOT_EMPTY */ || valueDefined;
|
|
55674
|
+
});
|
|
55675
|
+
if (filtered2.length !== 0) {
|
|
55676
|
+
return true;
|
|
55677
|
+
}
|
|
55651
55678
|
}
|
|
55652
|
-
|
|
55653
|
-
|
|
55679
|
+
return false;
|
|
55680
|
+
};
|
|
55681
|
+
return check(query);
|
|
55654
55682
|
};
|
|
55655
55683
|
|
|
55656
55684
|
// ../shared-core/src/utils.ts
|
|
@@ -56297,6 +56325,7 @@ var environment = {
|
|
|
56297
56325
|
// Couch/search
|
|
56298
56326
|
SQL_LOGGING_ENABLE: process.env.SQL_LOGGING_ENABLE,
|
|
56299
56327
|
SQL_MAX_ROWS: process.env.SQL_MAX_ROWS,
|
|
56328
|
+
SQL_MAX_RELATED_ROWS: process.env.MAX_RELATED_ROWS,
|
|
56300
56329
|
// smtp
|
|
56301
56330
|
SMTP_FALLBACK_ENABLED: process.env.SMTP_FALLBACK_ENABLED,
|
|
56302
56331
|
SMTP_USER: process.env.SMTP_USER,
|
|
@@ -56788,7 +56817,8 @@ __export(utils_exports3, {
|
|
|
56788
56817
|
isValidFilter: () => isValidFilter,
|
|
56789
56818
|
isValidISODateString: () => isValidISODateString,
|
|
56790
56819
|
isValidTime: () => isValidTime,
|
|
56791
|
-
sqlLog: () => sqlLog
|
|
56820
|
+
sqlLog: () => sqlLog,
|
|
56821
|
+
validateManyToMany: () => validateManyToMany
|
|
56792
56822
|
});
|
|
56793
56823
|
|
|
56794
56824
|
// src/db/index.ts
|
|
@@ -59762,6 +59792,15 @@ function sqlLog(client, query, values2) {
|
|
|
59762
59792
|
}
|
|
59763
59793
|
console.log(string);
|
|
59764
59794
|
}
|
|
59795
|
+
function isValidManyToManyRelationship(relationship) {
|
|
59796
|
+
return !!relationship.through && !!relationship.fromPrimary && !!relationship.from && !!relationship.toPrimary && !!relationship.to;
|
|
59797
|
+
}
|
|
59798
|
+
function validateManyToMany(relationship) {
|
|
59799
|
+
if (isValidManyToManyRelationship(relationship)) {
|
|
59800
|
+
return relationship;
|
|
59801
|
+
}
|
|
59802
|
+
return void 0;
|
|
59803
|
+
}
|
|
59765
59804
|
|
|
59766
59805
|
// src/features/index.ts
|
|
59767
59806
|
var features_exports = {};
|
|
@@ -59953,7 +59992,9 @@ var FlagSet = class {
|
|
|
59953
59992
|
};
|
|
59954
59993
|
var flags = new FlagSet({
|
|
59955
59994
|
DEFAULT_VALUES: Flag.boolean(environment_default.isDev()),
|
|
59995
|
+
AUTOMATION_BRANCHING: Flag.boolean(environment_default.isDev()),
|
|
59956
59996
|
SQS: Flag.boolean(environment_default.isDev()),
|
|
59997
|
+
["AI_CUSTOM_CONFIGS" /* AI_CUSTOM_CONFIGS */]: Flag.boolean(environment_default.isDev()),
|
|
59957
59998
|
["ENRICHED_RELATIONSHIPS" /* ENRICHED_RELATIONSHIPS */]: Flag.boolean(false)
|
|
59958
59999
|
});
|
|
59959
60000
|
|
|
@@ -62307,6 +62348,7 @@ async function getAccountHolderFromUserIds(userIds) {
|
|
|
62307
62348
|
var events_exports = {};
|
|
62308
62349
|
__export(events_exports, {
|
|
62309
62350
|
account: () => account_default,
|
|
62351
|
+
ai: () => ai_default,
|
|
62310
62352
|
analytics: () => analytics_exports,
|
|
62311
62353
|
app: () => app_default,
|
|
62312
62354
|
auditLog: () => auditLog_default,
|
|
@@ -62327,6 +62369,7 @@ __export(events_exports, {
|
|
|
62327
62369
|
org: () => org_default,
|
|
62328
62370
|
plugin: () => plugin_default,
|
|
62329
62371
|
processors: () => processors_exports,
|
|
62372
|
+
publishEvent: () => publishEvent,
|
|
62330
62373
|
query: () => query_default,
|
|
62331
62374
|
role: () => role_default,
|
|
62332
62375
|
rows: () => rows_default,
|
|
@@ -63891,6 +63934,20 @@ var email_default = {
|
|
|
63891
63934
|
SMTPUpdated
|
|
63892
63935
|
};
|
|
63893
63936
|
|
|
63937
|
+
// src/events/publishers/ai.ts
|
|
63938
|
+
async function AIConfigCreated(timestamp) {
|
|
63939
|
+
const properties = {};
|
|
63940
|
+
await publishEvent("ai:config:created" /* AI_CONFIG_CREATED */, properties, timestamp);
|
|
63941
|
+
}
|
|
63942
|
+
async function AIConfigUpdated() {
|
|
63943
|
+
const properties = {};
|
|
63944
|
+
await publishEvent("ai:config:updated" /* AI_CONFIG_UPDATED */, properties);
|
|
63945
|
+
}
|
|
63946
|
+
var ai_default = {
|
|
63947
|
+
AIConfigCreated,
|
|
63948
|
+
AIConfigUpdated
|
|
63949
|
+
};
|
|
63950
|
+
|
|
63894
63951
|
// src/events/publishers/license.ts
|
|
63895
63952
|
async function planChanged(account, opts) {
|
|
63896
63953
|
const properties = {
|
|
@@ -65677,7 +65734,12 @@ async function populateUsersFromDB(userIds) {
|
|
|
65677
65734
|
}
|
|
65678
65735
|
return { users };
|
|
65679
65736
|
}
|
|
65680
|
-
async function getUser(
|
|
65737
|
+
async function getUser({
|
|
65738
|
+
userId,
|
|
65739
|
+
tenantId,
|
|
65740
|
+
email,
|
|
65741
|
+
populateUser
|
|
65742
|
+
}) {
|
|
65681
65743
|
if (!populateUser) {
|
|
65682
65744
|
populateUser = populateFromDB2;
|
|
65683
65745
|
}
|
|
@@ -65691,7 +65753,7 @@ async function getUser(userId, tenantId, populateUser) {
|
|
|
65691
65753
|
const client = await getUserClient();
|
|
65692
65754
|
let user = await client.get(userId);
|
|
65693
65755
|
if (!user) {
|
|
65694
|
-
user = await populateUser(userId, tenantId);
|
|
65756
|
+
user = await populateUser(userId, tenantId, email);
|
|
65695
65757
|
await client.store(userId, user, EXPIRY_SECONDS3);
|
|
65696
65758
|
}
|
|
65697
65759
|
if (user && !user.tenantId && tenantId) {
|
|
@@ -66922,7 +66984,11 @@ async function checkApiKey(apiKey, populateUser) {
|
|
|
66922
66984
|
if (userId) {
|
|
66923
66985
|
return {
|
|
66924
66986
|
valid: true,
|
|
66925
|
-
user: await getUser(
|
|
66987
|
+
user: await getUser({
|
|
66988
|
+
userId,
|
|
66989
|
+
tenantId,
|
|
66990
|
+
populateUser
|
|
66991
|
+
})
|
|
66926
66992
|
};
|
|
66927
66993
|
} else {
|
|
66928
66994
|
throw new InvalidAPIKeyError();
|
|
@@ -66956,13 +67022,18 @@ function authenticated_default(noAuthPatterns = [], opts = {
|
|
|
66956
67022
|
try {
|
|
66957
67023
|
session = await getSession(userId, sessionId);
|
|
66958
67024
|
if (opts && opts.populateUser) {
|
|
66959
|
-
user = await getUser(
|
|
67025
|
+
user = await getUser({
|
|
66960
67026
|
userId,
|
|
66961
|
-
session.tenantId,
|
|
66962
|
-
|
|
66963
|
-
|
|
67027
|
+
tenantId: session.tenantId,
|
|
67028
|
+
email: session.email,
|
|
67029
|
+
populateUser: opts.populateUser(ctx)
|
|
67030
|
+
});
|
|
66964
67031
|
} else {
|
|
66965
|
-
user = await getUser(
|
|
67032
|
+
user = await getUser({
|
|
67033
|
+
userId,
|
|
67034
|
+
tenantId: session.tenantId,
|
|
67035
|
+
email: session.email
|
|
67036
|
+
});
|
|
66966
67037
|
}
|
|
66967
67038
|
user.csrfToken = session.csrfToken;
|
|
66968
67039
|
if (session?.lastAccessedAt < timeMinusOneMinute()) {
|
|
@@ -67953,10 +68024,15 @@ var sqlTable_default = SqlTableQueryBuilder;
|
|
|
67953
68024
|
|
|
67954
68025
|
// src/sql/sql.ts
|
|
67955
68026
|
var import_lodash3 = require("lodash");
|
|
68027
|
+
var MAX_SQS_RELATIONSHIP_FIELDS = 63;
|
|
67956
68028
|
function getBaseLimit() {
|
|
67957
68029
|
const envLimit = environment_default.SQL_MAX_ROWS ? parseInt(environment_default.SQL_MAX_ROWS) : null;
|
|
67958
68030
|
return envLimit || 5e3;
|
|
67959
68031
|
}
|
|
68032
|
+
function getRelationshipLimit() {
|
|
68033
|
+
const envLimit = environment_default.SQL_MAX_RELATED_ROWS ? parseInt(environment_default.SQL_MAX_RELATED_ROWS) : null;
|
|
68034
|
+
return envLimit || 500;
|
|
68035
|
+
}
|
|
67960
68036
|
function getTableName(table) {
|
|
67961
68037
|
if (table?.sourceType === "internal" /* INTERNAL */ || table?.sourceId === INTERNAL_TABLE_SOURCE_ID) {
|
|
67962
68038
|
return table?._id;
|
|
@@ -67981,6 +68057,15 @@ function convertBooleans(query) {
|
|
|
67981
68057
|
}
|
|
67982
68058
|
var InternalBuilder = class {
|
|
67983
68059
|
constructor(client, knex3, query) {
|
|
68060
|
+
// states the various situations in which we need a full mapped select statement
|
|
68061
|
+
this.SPECIAL_SELECT_CASES = {
|
|
68062
|
+
POSTGRES_MONEY: (field) => {
|
|
68063
|
+
return this.client === "pg" /* POSTGRES */ && field?.externalType?.includes("money");
|
|
68064
|
+
},
|
|
68065
|
+
MSSQL_DATES: (field) => {
|
|
68066
|
+
return this.client === "mssql" /* MS_SQL */ && field?.type === "datetime" /* DATETIME */ && field.timeOnly;
|
|
68067
|
+
}
|
|
68068
|
+
};
|
|
67984
68069
|
this.client = client;
|
|
67985
68070
|
this.query = query;
|
|
67986
68071
|
this.knex = knex3;
|
|
@@ -68015,48 +68100,50 @@ var InternalBuilder = class {
|
|
|
68015
68100
|
quotedIdentifier(key) {
|
|
68016
68101
|
return key.split(".").map((part) => this.quote(part)).join(".");
|
|
68017
68102
|
}
|
|
68103
|
+
isFullSelectStatementRequired() {
|
|
68104
|
+
const { meta } = this.query;
|
|
68105
|
+
for (let column of Object.values(meta.table.schema)) {
|
|
68106
|
+
if (this.SPECIAL_SELECT_CASES.POSTGRES_MONEY(column)) {
|
|
68107
|
+
return true;
|
|
68108
|
+
} else if (this.SPECIAL_SELECT_CASES.MSSQL_DATES(column)) {
|
|
68109
|
+
return true;
|
|
68110
|
+
}
|
|
68111
|
+
}
|
|
68112
|
+
return false;
|
|
68113
|
+
}
|
|
68018
68114
|
generateSelectStatement() {
|
|
68019
|
-
const { resource,
|
|
68115
|
+
const { meta, endpoint, resource, tableAliases } = this.query;
|
|
68020
68116
|
if (!resource || !resource.fields || resource.fields.length === 0) {
|
|
68021
68117
|
return "*";
|
|
68022
68118
|
}
|
|
68119
|
+
const alias = tableAliases?.[endpoint.entityId] ? tableAliases?.[endpoint.entityId] : endpoint.entityId;
|
|
68023
68120
|
const schema = meta.table.schema;
|
|
68121
|
+
if (!this.isFullSelectStatementRequired()) {
|
|
68122
|
+
return [this.knex.raw(`${this.quote(alias)}.*`)];
|
|
68123
|
+
}
|
|
68024
68124
|
return resource.fields.map((field) => {
|
|
68025
68125
|
const parts = field.split(/\./g);
|
|
68026
68126
|
let table = void 0;
|
|
68027
|
-
let column =
|
|
68028
|
-
if (parts.length
|
|
68029
|
-
column = parts[0];
|
|
68030
|
-
}
|
|
68031
|
-
if (parts.length === 2) {
|
|
68032
|
-
table = parts[0];
|
|
68033
|
-
column = parts[1];
|
|
68034
|
-
}
|
|
68035
|
-
if (parts.length > 2) {
|
|
68127
|
+
let column = parts[0];
|
|
68128
|
+
if (parts.length > 1) {
|
|
68036
68129
|
table = parts[0];
|
|
68037
68130
|
column = parts.slice(1).join(".");
|
|
68038
68131
|
}
|
|
68039
|
-
|
|
68040
|
-
|
|
68041
|
-
}
|
|
68132
|
+
return { table, column, field };
|
|
68133
|
+
}).filter(({ table }) => !table || table === alias).map(({ table, column, field }) => {
|
|
68042
68134
|
const columnSchema = schema[column];
|
|
68043
|
-
if (this.
|
|
68135
|
+
if (this.SPECIAL_SELECT_CASES.POSTGRES_MONEY(columnSchema)) {
|
|
68044
68136
|
return this.knex.raw(
|
|
68045
68137
|
`${this.quotedIdentifier(
|
|
68046
68138
|
[table, column].join(".")
|
|
68047
68139
|
)}::money::numeric as ${this.quote(field)}`
|
|
68048
68140
|
);
|
|
68049
68141
|
}
|
|
68050
|
-
if (this.
|
|
68142
|
+
if (this.SPECIAL_SELECT_CASES.MSSQL_DATES(columnSchema)) {
|
|
68051
68143
|
return this.knex.raw(`CONVERT(varchar, ${field}, 108) as "${field}"`);
|
|
68052
68144
|
}
|
|
68053
|
-
|
|
68054
|
-
|
|
68055
|
-
`${this.quote(table)}.${this.quote(column)} as ${this.quote(field)}`
|
|
68056
|
-
);
|
|
68057
|
-
} else {
|
|
68058
|
-
return this.knex.raw(`${this.quote(field)} as ${this.quote(field)}`);
|
|
68059
|
-
}
|
|
68145
|
+
const quoted = table ? `${this.quote(table)}.${this.quote(column)}` : this.quote(field);
|
|
68146
|
+
return this.knex.raw(quoted);
|
|
68060
68147
|
});
|
|
68061
68148
|
}
|
|
68062
68149
|
// OracleDB can't use character-large-objects (CLOBs) in WHERE clauses,
|
|
@@ -68167,28 +68254,94 @@ var InternalBuilder = class {
|
|
|
68167
68254
|
}
|
|
68168
68255
|
return filters;
|
|
68169
68256
|
}
|
|
68257
|
+
addJoinFieldCheck(query, relationship) {
|
|
68258
|
+
const document = relationship.from?.split(".")[0] || "";
|
|
68259
|
+
return query.andWhere(`${document}.fieldName`, "=", relationship.column);
|
|
68260
|
+
}
|
|
68261
|
+
addRelationshipForFilter(query, filterKey, whereCb) {
|
|
68262
|
+
const mainKnex = this.knex;
|
|
68263
|
+
const { relationships, endpoint, tableAliases: aliases } = this.query;
|
|
68264
|
+
const tableName = endpoint.entityId;
|
|
68265
|
+
const fromAlias = aliases?.[tableName] || tableName;
|
|
68266
|
+
const matches2 = (possibleTable) => filterKey.startsWith(`${possibleTable}`);
|
|
68267
|
+
if (!relationships) {
|
|
68268
|
+
return query;
|
|
68269
|
+
}
|
|
68270
|
+
for (const relationship of relationships) {
|
|
68271
|
+
const relatedTableName = relationship.tableName;
|
|
68272
|
+
const toAlias = aliases?.[relatedTableName] || relatedTableName;
|
|
68273
|
+
if ((matches2(relatedTableName) || matches2(toAlias)) && relationship.to && relationship.tableName) {
|
|
68274
|
+
let subQuery = mainKnex.select(mainKnex.raw(1)).from({ [toAlias]: relatedTableName });
|
|
68275
|
+
const manyToMany = validateManyToMany(relationship);
|
|
68276
|
+
if (manyToMany) {
|
|
68277
|
+
const throughAlias = aliases?.[manyToMany.through] || relationship.through;
|
|
68278
|
+
let throughTable = this.tableNameWithSchema(manyToMany.through, {
|
|
68279
|
+
alias: throughAlias,
|
|
68280
|
+
schema: endpoint.schema
|
|
68281
|
+
});
|
|
68282
|
+
subQuery = subQuery.innerJoin(throughTable, function() {
|
|
68283
|
+
this.on(
|
|
68284
|
+
`${toAlias}.${manyToMany.toPrimary}`,
|
|
68285
|
+
"=",
|
|
68286
|
+
`${throughAlias}.${manyToMany.to}`
|
|
68287
|
+
);
|
|
68288
|
+
}).where(
|
|
68289
|
+
`${throughAlias}.${manyToMany.from}`,
|
|
68290
|
+
"=",
|
|
68291
|
+
mainKnex.raw(
|
|
68292
|
+
this.quotedIdentifier(`${fromAlias}.${manyToMany.fromPrimary}`)
|
|
68293
|
+
)
|
|
68294
|
+
);
|
|
68295
|
+
if (this.client === "sqlite3" /* SQL_LITE */) {
|
|
68296
|
+
subQuery = this.addJoinFieldCheck(subQuery, manyToMany);
|
|
68297
|
+
}
|
|
68298
|
+
} else {
|
|
68299
|
+
subQuery = subQuery.where(
|
|
68300
|
+
`${toAlias}.${relationship.to}`,
|
|
68301
|
+
"=",
|
|
68302
|
+
mainKnex.raw(
|
|
68303
|
+
this.quotedIdentifier(`${fromAlias}.${relationship.from}`)
|
|
68304
|
+
)
|
|
68305
|
+
);
|
|
68306
|
+
}
|
|
68307
|
+
query = query.whereExists(whereCb(subQuery));
|
|
68308
|
+
break;
|
|
68309
|
+
}
|
|
68310
|
+
}
|
|
68311
|
+
return query;
|
|
68312
|
+
}
|
|
68170
68313
|
// right now we only do filters on the specific table being queried
|
|
68171
68314
|
addFilters(query, filters, opts) {
|
|
68172
68315
|
if (!filters) {
|
|
68173
68316
|
return query;
|
|
68174
68317
|
}
|
|
68318
|
+
const builder = this;
|
|
68175
68319
|
filters = this.parseFilters({ ...filters });
|
|
68176
68320
|
const aliases = this.query.tableAliases;
|
|
68177
68321
|
const allOr = filters.allOr;
|
|
68178
|
-
const
|
|
68322
|
+
const isSqlite = this.client === "sqlite3" /* SQL_LITE */;
|
|
68323
|
+
const tableName = isSqlite ? this.table._id : this.table.name;
|
|
68179
68324
|
function getTableAlias(name) {
|
|
68180
68325
|
const alias = aliases?.[name];
|
|
68181
68326
|
return alias || name;
|
|
68182
68327
|
}
|
|
68183
68328
|
function iterate(structure, fn, complexKeyFn) {
|
|
68329
|
+
const handleRelationship = (q2, key, value) => {
|
|
68330
|
+
const [filterTableName, ...otherProperties] = key.split(".");
|
|
68331
|
+
const property = otherProperties.join(".");
|
|
68332
|
+
const alias = getTableAlias(filterTableName);
|
|
68333
|
+
return fn(q2, alias ? `${alias}.${property}` : property, value);
|
|
68334
|
+
};
|
|
68184
68335
|
for (const key in structure) {
|
|
68185
68336
|
const value = structure[key];
|
|
68186
68337
|
const updatedKey = removeKeyNumbering2(key);
|
|
68187
68338
|
const isRelationshipField = updatedKey.includes(".");
|
|
68339
|
+
const shouldProcessRelationship = opts?.relationship && isRelationshipField;
|
|
68188
68340
|
let castedTypeValue;
|
|
68189
68341
|
if (key === "_complexIdOperator" /* COMPLEX_ID_OPERATOR */ && (castedTypeValue = structure[key]) && complexKeyFn) {
|
|
68190
68342
|
const alias = getTableAlias(tableName);
|
|
68191
|
-
complexKeyFn(
|
|
68343
|
+
query = complexKeyFn(
|
|
68344
|
+
query,
|
|
68192
68345
|
castedTypeValue.id.map(
|
|
68193
68346
|
(x) => alias ? `${alias}.${x}` : x
|
|
68194
68347
|
),
|
|
@@ -68196,23 +68349,26 @@ var InternalBuilder = class {
|
|
|
68196
68349
|
);
|
|
68197
68350
|
} else if (!isRelationshipField) {
|
|
68198
68351
|
const alias = getTableAlias(tableName);
|
|
68199
|
-
fn(
|
|
68200
|
-
|
|
68201
|
-
|
|
68202
|
-
|
|
68203
|
-
|
|
68204
|
-
|
|
68352
|
+
query = fn(
|
|
68353
|
+
query,
|
|
68354
|
+
alias ? `${alias}.${updatedKey}` : updatedKey,
|
|
68355
|
+
value
|
|
68356
|
+
);
|
|
68357
|
+
} else if (shouldProcessRelationship) {
|
|
68358
|
+
query = builder.addRelationshipForFilter(query, updatedKey, (q2) => {
|
|
68359
|
+
return handleRelationship(q2, updatedKey, value);
|
|
68360
|
+
});
|
|
68205
68361
|
}
|
|
68206
68362
|
}
|
|
68207
68363
|
}
|
|
68208
|
-
const like = (key, value) => {
|
|
68364
|
+
const like = (q2, key, value) => {
|
|
68209
68365
|
const fuzzyOr = filters?.fuzzyOr;
|
|
68210
68366
|
const fnc = fuzzyOr || allOr ? "orWhere" : "where";
|
|
68211
68367
|
if (this.client === "pg" /* POSTGRES */) {
|
|
68212
|
-
|
|
68368
|
+
return q2[fnc](key, "ilike", `%${value}%`);
|
|
68213
68369
|
} else {
|
|
68214
68370
|
const rawFnc = `${fnc}Raw`;
|
|
68215
|
-
|
|
68371
|
+
return q2[rawFnc](`LOWER(${this.quotedIdentifier(key)}) LIKE ?`, [
|
|
68216
68372
|
`%${value.toLowerCase()}%`
|
|
68217
68373
|
]);
|
|
68218
68374
|
}
|
|
@@ -68229,13 +68385,13 @@ var InternalBuilder = class {
|
|
|
68229
68385
|
return `[${value.join(",")}]`;
|
|
68230
68386
|
}
|
|
68231
68387
|
if (this.client === "pg" /* POSTGRES */) {
|
|
68232
|
-
iterate(mode, (key, value) => {
|
|
68388
|
+
iterate(mode, (q2, key, value) => {
|
|
68233
68389
|
const wrap = any ? "" : "'";
|
|
68234
68390
|
const op = any ? "\\?| array" : "@>";
|
|
68235
68391
|
const fieldNames = key.split(/\./g);
|
|
68236
68392
|
const table = fieldNames[0];
|
|
68237
68393
|
const col = fieldNames[1];
|
|
68238
|
-
|
|
68394
|
+
return q2[rawFnc](
|
|
68239
68395
|
`${not}COALESCE("${table}"."${col}"::jsonb ${op} ${wrap}${stringifyArray(
|
|
68240
68396
|
value,
|
|
68241
68397
|
any ? "'" : '"'
|
|
@@ -68244,8 +68400,8 @@ var InternalBuilder = class {
|
|
|
68244
68400
|
});
|
|
68245
68401
|
} else if (this.client === "mysql2" /* MY_SQL */) {
|
|
68246
68402
|
const jsonFnc = any ? "JSON_OVERLAPS" : "JSON_CONTAINS";
|
|
68247
|
-
iterate(mode, (key, value) => {
|
|
68248
|
-
|
|
68403
|
+
iterate(mode, (q2, key, value) => {
|
|
68404
|
+
return q2[rawFnc](
|
|
68249
68405
|
`${not}COALESCE(${jsonFnc}(${key}, '${stringifyArray(
|
|
68250
68406
|
value
|
|
68251
68407
|
)}'), FALSE)`
|
|
@@ -68253,7 +68409,7 @@ var InternalBuilder = class {
|
|
|
68253
68409
|
});
|
|
68254
68410
|
} else {
|
|
68255
68411
|
const andOr = mode === filters?.containsAny ? " OR " : " AND ";
|
|
68256
|
-
iterate(mode, (key, value) => {
|
|
68412
|
+
iterate(mode, (q2, key, value) => {
|
|
68257
68413
|
let statement = "";
|
|
68258
68414
|
const identifier = this.quotedIdentifier(key);
|
|
68259
68415
|
for (let i in value) {
|
|
@@ -68265,15 +68421,15 @@ var InternalBuilder = class {
|
|
|
68265
68421
|
statement += `${statement ? andOr : ""}COALESCE(LOWER(${identifier}), '') LIKE ?`;
|
|
68266
68422
|
}
|
|
68267
68423
|
if (statement === "") {
|
|
68268
|
-
return;
|
|
68424
|
+
return q2;
|
|
68269
68425
|
}
|
|
68270
68426
|
if (not) {
|
|
68271
|
-
|
|
68427
|
+
return q2[rawFnc](
|
|
68272
68428
|
`(NOT (${statement}) OR ${identifier} IS NULL)`,
|
|
68273
68429
|
value
|
|
68274
68430
|
);
|
|
68275
68431
|
} else {
|
|
68276
|
-
|
|
68432
|
+
return q2[rawFnc](statement, value);
|
|
68277
68433
|
}
|
|
68278
68434
|
});
|
|
68279
68435
|
}
|
|
@@ -68300,35 +68456,35 @@ var InternalBuilder = class {
|
|
|
68300
68456
|
const fnc = allOr ? "orWhereIn" : "whereIn";
|
|
68301
68457
|
iterate(
|
|
68302
68458
|
filters.oneOf,
|
|
68303
|
-
(key, array) => {
|
|
68459
|
+
(q2, key, array) => {
|
|
68304
68460
|
if (this.client === "oracledb" /* ORACLE */) {
|
|
68305
68461
|
key = this.convertClobs(key);
|
|
68306
68462
|
array = Array.isArray(array) ? array : [array];
|
|
68307
68463
|
const binding = new Array(array.length).fill("?").join(",");
|
|
68308
|
-
|
|
68464
|
+
return q2.whereRaw(`${key} IN (${binding})`, array);
|
|
68309
68465
|
} else {
|
|
68310
|
-
|
|
68466
|
+
return q2[fnc](key, Array.isArray(array) ? array : [array]);
|
|
68311
68467
|
}
|
|
68312
68468
|
},
|
|
68313
|
-
(key, array) => {
|
|
68469
|
+
(q2, key, array) => {
|
|
68314
68470
|
if (this.client === "oracledb" /* ORACLE */) {
|
|
68315
68471
|
const keyStr = `(${key.map((k) => this.convertClobs(k)).join(",")})`;
|
|
68316
68472
|
const binding = `(${array.map((a) => `(${new Array(a.length).fill("?").join(",")})`).join(",")})`;
|
|
68317
|
-
|
|
68473
|
+
return q2.whereRaw(`${keyStr} IN ${binding}`, array.flat());
|
|
68318
68474
|
} else {
|
|
68319
|
-
|
|
68475
|
+
return q2[fnc](key, Array.isArray(array) ? array : [array]);
|
|
68320
68476
|
}
|
|
68321
68477
|
}
|
|
68322
68478
|
);
|
|
68323
68479
|
}
|
|
68324
68480
|
if (filters.string) {
|
|
68325
|
-
iterate(filters.string, (key, value) => {
|
|
68481
|
+
iterate(filters.string, (q2, key, value) => {
|
|
68326
68482
|
const fnc = allOr ? "orWhere" : "where";
|
|
68327
68483
|
if (this.client === "pg" /* POSTGRES */) {
|
|
68328
|
-
|
|
68484
|
+
return q2[fnc](key, "ilike", `${value}%`);
|
|
68329
68485
|
} else {
|
|
68330
68486
|
const rawFnc = `${fnc}Raw`;
|
|
68331
|
-
|
|
68487
|
+
return q2[rawFnc](`LOWER(${this.quotedIdentifier(key)}) LIKE ?`, [
|
|
68332
68488
|
`${value.toLowerCase()}%`
|
|
68333
68489
|
]);
|
|
68334
68490
|
}
|
|
@@ -68338,7 +68494,7 @@ var InternalBuilder = class {
|
|
|
68338
68494
|
iterate(filters.fuzzy, like);
|
|
68339
68495
|
}
|
|
68340
68496
|
if (filters.range) {
|
|
68341
|
-
iterate(filters.range, (key, value) => {
|
|
68497
|
+
iterate(filters.range, (q2, key, value) => {
|
|
68342
68498
|
const isEmptyObject = (val) => {
|
|
68343
68499
|
return val && Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
|
|
68344
68500
|
};
|
|
@@ -68355,91 +68511,87 @@ var InternalBuilder = class {
|
|
|
68355
68511
|
}
|
|
68356
68512
|
if (lowValid && highValid) {
|
|
68357
68513
|
if (schema?.type === "bigint" /* BIGINT */ && this.client === "sqlite3" /* SQL_LITE */) {
|
|
68358
|
-
|
|
68514
|
+
return q2.whereRaw(
|
|
68359
68515
|
`CAST(${key} AS INTEGER) BETWEEN CAST(? AS INTEGER) AND CAST(? AS INTEGER)`,
|
|
68360
68516
|
[value.low, value.high]
|
|
68361
68517
|
);
|
|
68362
68518
|
} else {
|
|
68363
68519
|
const fnc = allOr ? "orWhereBetween" : "whereBetween";
|
|
68364
|
-
|
|
68520
|
+
return q2[fnc](key, [value.low, value.high]);
|
|
68365
68521
|
}
|
|
68366
68522
|
} else if (lowValid) {
|
|
68367
68523
|
if (schema?.type === "bigint" /* BIGINT */ && this.client === "sqlite3" /* SQL_LITE */) {
|
|
68368
|
-
|
|
68369
|
-
|
|
68370
|
-
|
|
68371
|
-
);
|
|
68524
|
+
return q2.whereRaw(`CAST(${key} AS INTEGER) >= CAST(? AS INTEGER)`, [
|
|
68525
|
+
value.low
|
|
68526
|
+
]);
|
|
68372
68527
|
} else {
|
|
68373
68528
|
const fnc = allOr ? "orWhere" : "where";
|
|
68374
|
-
|
|
68529
|
+
return q2[fnc](key, ">=", value.low);
|
|
68375
68530
|
}
|
|
68376
68531
|
} else if (highValid) {
|
|
68377
68532
|
if (schema?.type === "bigint" /* BIGINT */ && this.client === "sqlite3" /* SQL_LITE */) {
|
|
68378
|
-
|
|
68379
|
-
|
|
68380
|
-
|
|
68381
|
-
);
|
|
68533
|
+
return q2.whereRaw(`CAST(${key} AS INTEGER) <= CAST(? AS INTEGER)`, [
|
|
68534
|
+
value.high
|
|
68535
|
+
]);
|
|
68382
68536
|
} else {
|
|
68383
68537
|
const fnc = allOr ? "orWhere" : "where";
|
|
68384
|
-
|
|
68538
|
+
return q2[fnc](key, "<=", value.high);
|
|
68385
68539
|
}
|
|
68386
68540
|
}
|
|
68541
|
+
return q2;
|
|
68387
68542
|
});
|
|
68388
68543
|
}
|
|
68389
68544
|
if (filters.equal) {
|
|
68390
|
-
iterate(filters.equal, (key, value) => {
|
|
68545
|
+
iterate(filters.equal, (q2, key, value) => {
|
|
68391
68546
|
const fnc = allOr ? "orWhereRaw" : "whereRaw";
|
|
68392
68547
|
if (this.client === "mssql" /* MS_SQL */) {
|
|
68393
|
-
|
|
68548
|
+
return q2[fnc](
|
|
68394
68549
|
`CASE WHEN ${this.quotedIdentifier(key)} = ? THEN 1 ELSE 0 END = 1`,
|
|
68395
68550
|
[value]
|
|
68396
68551
|
);
|
|
68397
68552
|
} else if (this.client === "oracledb" /* ORACLE */) {
|
|
68398
68553
|
const identifier = this.convertClobs(key);
|
|
68399
|
-
|
|
68400
|
-
|
|
68401
|
-
|
|
68402
|
-
);
|
|
68554
|
+
return q2[fnc](`(${identifier} IS NOT NULL AND ${identifier} = ?)`, [
|
|
68555
|
+
value
|
|
68556
|
+
]);
|
|
68403
68557
|
} else {
|
|
68404
|
-
|
|
68405
|
-
|
|
68406
|
-
|
|
68407
|
-
);
|
|
68558
|
+
return q2[fnc](`COALESCE(${this.quotedIdentifier(key)} = ?, FALSE)`, [
|
|
68559
|
+
value
|
|
68560
|
+
]);
|
|
68408
68561
|
}
|
|
68409
68562
|
});
|
|
68410
68563
|
}
|
|
68411
68564
|
if (filters.notEqual) {
|
|
68412
|
-
iterate(filters.notEqual, (key, value) => {
|
|
68565
|
+
iterate(filters.notEqual, (q2, key, value) => {
|
|
68413
68566
|
const fnc = allOr ? "orWhereRaw" : "whereRaw";
|
|
68414
68567
|
if (this.client === "mssql" /* MS_SQL */) {
|
|
68415
|
-
|
|
68568
|
+
return q2[fnc](
|
|
68416
68569
|
`CASE WHEN ${this.quotedIdentifier(key)} = ? THEN 1 ELSE 0 END = 0`,
|
|
68417
68570
|
[value]
|
|
68418
68571
|
);
|
|
68419
68572
|
} else if (this.client === "oracledb" /* ORACLE */) {
|
|
68420
68573
|
const identifier = this.convertClobs(key);
|
|
68421
|
-
|
|
68574
|
+
return q2[fnc](
|
|
68422
68575
|
`(${identifier} IS NOT NULL AND ${identifier} != ?) OR ${identifier} IS NULL`,
|
|
68423
68576
|
[value]
|
|
68424
68577
|
);
|
|
68425
68578
|
} else {
|
|
68426
|
-
|
|
68427
|
-
|
|
68428
|
-
|
|
68429
|
-
);
|
|
68579
|
+
return q2[fnc](`COALESCE(${this.quotedIdentifier(key)} != ?, TRUE)`, [
|
|
68580
|
+
value
|
|
68581
|
+
]);
|
|
68430
68582
|
}
|
|
68431
68583
|
});
|
|
68432
68584
|
}
|
|
68433
68585
|
if (filters.empty) {
|
|
68434
|
-
iterate(filters.empty, (key) => {
|
|
68586
|
+
iterate(filters.empty, (q2, key) => {
|
|
68435
68587
|
const fnc = allOr ? "orWhereNull" : "whereNull";
|
|
68436
|
-
|
|
68588
|
+
return q2[fnc](key);
|
|
68437
68589
|
});
|
|
68438
68590
|
}
|
|
68439
68591
|
if (filters.notEmpty) {
|
|
68440
|
-
iterate(filters.notEmpty, (key) => {
|
|
68592
|
+
iterate(filters.notEmpty, (q2, key) => {
|
|
68441
68593
|
const fnc = allOr ? "orWhereNotNull" : "whereNotNull";
|
|
68442
|
-
|
|
68594
|
+
return q2[fnc](key);
|
|
68443
68595
|
});
|
|
68444
68596
|
}
|
|
68445
68597
|
if (filters.contains) {
|
|
@@ -68507,63 +68659,155 @@ var InternalBuilder = class {
|
|
|
68507
68659
|
}
|
|
68508
68660
|
return withSchema;
|
|
68509
68661
|
}
|
|
68510
|
-
|
|
68511
|
-
|
|
68512
|
-
|
|
68662
|
+
buildJsonField(field) {
|
|
68663
|
+
const parts = field.split(".");
|
|
68664
|
+
let tableField, unaliased;
|
|
68665
|
+
if (parts.length > 1) {
|
|
68666
|
+
const alias = parts.shift();
|
|
68667
|
+
unaliased = parts.join(".");
|
|
68668
|
+
tableField = `${this.quote(alias)}.${this.quote(unaliased)}`;
|
|
68669
|
+
} else {
|
|
68670
|
+
unaliased = parts.join(".");
|
|
68671
|
+
tableField = this.quote(unaliased);
|
|
68513
68672
|
}
|
|
68514
|
-
const
|
|
68673
|
+
const separator = this.client === "oracledb" /* ORACLE */ ? " VALUE " : ",";
|
|
68674
|
+
return `'${unaliased}'${separator}${tableField}`;
|
|
68675
|
+
}
|
|
68676
|
+
addJsonRelationships(query, fromTable, relationships) {
|
|
68677
|
+
const sqlClient = this.client;
|
|
68678
|
+
const knex3 = this.knex;
|
|
68679
|
+
const { resource, tableAliases: aliases, endpoint } = this.query;
|
|
68680
|
+
const fields = resource?.fields || [];
|
|
68515
68681
|
for (let relationship of relationships) {
|
|
68516
|
-
const
|
|
68517
|
-
|
|
68518
|
-
|
|
68519
|
-
|
|
68520
|
-
|
|
68521
|
-
|
|
68522
|
-
|
|
68523
|
-
|
|
68524
|
-
if (
|
|
68525
|
-
|
|
68526
|
-
} else {
|
|
68527
|
-
tableSets[key] = [relationship];
|
|
68682
|
+
const {
|
|
68683
|
+
tableName: toTable,
|
|
68684
|
+
through: throughTable,
|
|
68685
|
+
to: toKey,
|
|
68686
|
+
from: fromKey,
|
|
68687
|
+
fromPrimary,
|
|
68688
|
+
toPrimary
|
|
68689
|
+
} = relationship;
|
|
68690
|
+
if (!toTable || !fromTable) {
|
|
68691
|
+
continue;
|
|
68528
68692
|
}
|
|
68529
|
-
|
|
68530
|
-
for (let [key, relationships2] of Object.entries(tableSets)) {
|
|
68531
|
-
const { toTable, throughTable } = JSON.parse(key);
|
|
68532
|
-
const toAlias = aliases?.[toTable] || toTable, throughAlias = aliases?.[throughTable] || throughTable, fromAlias = aliases?.[fromTable] || fromTable;
|
|
68693
|
+
const toAlias = aliases?.[toTable] || toTable, fromAlias = aliases?.[fromTable] || fromTable;
|
|
68533
68694
|
let toTableWithSchema = this.tableNameWithSchema(toTable, {
|
|
68534
68695
|
alias: toAlias,
|
|
68535
|
-
schema
|
|
68536
|
-
});
|
|
68537
|
-
let throughTableWithSchema = this.tableNameWithSchema(throughTable, {
|
|
68538
|
-
alias: throughAlias,
|
|
68539
|
-
schema
|
|
68696
|
+
schema: endpoint.schema
|
|
68540
68697
|
});
|
|
68541
|
-
|
|
68542
|
-
|
|
68543
|
-
|
|
68544
|
-
|
|
68545
|
-
|
|
68546
|
-
|
|
68698
|
+
let relationshipFields = fields.filter(
|
|
68699
|
+
(field) => field.split(".")[0] === toAlias
|
|
68700
|
+
);
|
|
68701
|
+
if (this.client === "sqlite3" /* SQL_LITE */) {
|
|
68702
|
+
relationshipFields = relationshipFields.slice(
|
|
68703
|
+
0,
|
|
68704
|
+
MAX_SQS_RELATIONSHIP_FIELDS
|
|
68705
|
+
);
|
|
68706
|
+
}
|
|
68707
|
+
const fieldList = relationshipFields.map((field) => this.buildJsonField(field)).join(",");
|
|
68708
|
+
const primaryKey = `${toAlias}.${toPrimary || toKey}`;
|
|
68709
|
+
let subQuery = knex3.from(toTableWithSchema).limit(getRelationshipLimit()).orderBy(primaryKey);
|
|
68710
|
+
if (throughTable && toPrimary && fromPrimary) {
|
|
68711
|
+
const throughAlias = aliases?.[throughTable] || throughTable;
|
|
68712
|
+
let throughTableWithSchema = this.tableNameWithSchema(throughTable, {
|
|
68713
|
+
alias: throughAlias,
|
|
68714
|
+
schema: endpoint.schema
|
|
68547
68715
|
});
|
|
68716
|
+
subQuery = subQuery.join(throughTableWithSchema, function() {
|
|
68717
|
+
this.on(`${toAlias}.${toPrimary}`, "=", `${throughAlias}.${toKey}`);
|
|
68718
|
+
}).where(
|
|
68719
|
+
`${throughAlias}.${fromKey}`,
|
|
68720
|
+
"=",
|
|
68721
|
+
knex3.raw(this.quotedIdentifier(`${fromAlias}.${fromPrimary}`))
|
|
68722
|
+
);
|
|
68548
68723
|
} else {
|
|
68549
|
-
|
|
68550
|
-
|
|
68551
|
-
|
|
68552
|
-
|
|
68553
|
-
|
|
68554
|
-
|
|
68555
|
-
|
|
68556
|
-
|
|
68557
|
-
|
|
68558
|
-
|
|
68559
|
-
}).leftJoin(toTableWithSchema, function() {
|
|
68560
|
-
for (let relationship of relationships2) {
|
|
68561
|
-
const toPrimary = relationship.toPrimary;
|
|
68562
|
-
const to = relationship.to;
|
|
68563
|
-
this.orOn(`${toAlias}.${toPrimary}`, `${throughAlias}.${to}`);
|
|
68564
|
-
}
|
|
68724
|
+
subQuery = subQuery.where(
|
|
68725
|
+
`${toAlias}.${toKey}`,
|
|
68726
|
+
"=",
|
|
68727
|
+
knex3.raw(this.quotedIdentifier(`${fromAlias}.${fromKey}`))
|
|
68728
|
+
);
|
|
68729
|
+
}
|
|
68730
|
+
const standardWrap = (select) => {
|
|
68731
|
+
subQuery = subQuery.select(`${toAlias}.*`);
|
|
68732
|
+
return knex3.select(knex3.raw(select)).from({
|
|
68733
|
+
[toAlias]: subQuery
|
|
68565
68734
|
});
|
|
68735
|
+
};
|
|
68736
|
+
let wrapperQuery;
|
|
68737
|
+
switch (sqlClient) {
|
|
68738
|
+
case "sqlite3" /* SQL_LITE */:
|
|
68739
|
+
subQuery = this.addJoinFieldCheck(subQuery, relationship);
|
|
68740
|
+
wrapperQuery = standardWrap(
|
|
68741
|
+
`json_group_array(json_object(${fieldList}))`
|
|
68742
|
+
);
|
|
68743
|
+
break;
|
|
68744
|
+
case "pg" /* POSTGRES */:
|
|
68745
|
+
wrapperQuery = standardWrap(
|
|
68746
|
+
`json_agg(json_build_object(${fieldList}))`
|
|
68747
|
+
);
|
|
68748
|
+
break;
|
|
68749
|
+
case "mysql2" /* MY_SQL */:
|
|
68750
|
+
wrapperQuery = subQuery.select(
|
|
68751
|
+
knex3.raw(`json_arrayagg(json_object(${fieldList}))`)
|
|
68752
|
+
);
|
|
68753
|
+
break;
|
|
68754
|
+
case "oracledb" /* ORACLE */:
|
|
68755
|
+
wrapperQuery = standardWrap(
|
|
68756
|
+
`json_arrayagg(json_object(${fieldList}))`
|
|
68757
|
+
);
|
|
68758
|
+
break;
|
|
68759
|
+
case "mssql" /* MS_SQL */:
|
|
68760
|
+
wrapperQuery = knex3.raw(
|
|
68761
|
+
`(SELECT ${this.quote(toAlias)} = (${knex3.select(`${fromAlias}.*`).from({
|
|
68762
|
+
[fromAlias]: subQuery.select(`${toAlias}.*`)
|
|
68763
|
+
})} FOR JSON PATH))`
|
|
68764
|
+
);
|
|
68765
|
+
break;
|
|
68766
|
+
default:
|
|
68767
|
+
throw new Error(`JSON relationships not implement for ${sqlClient}`);
|
|
68566
68768
|
}
|
|
68769
|
+
query = query.select({ [relationship.column]: wrapperQuery });
|
|
68770
|
+
}
|
|
68771
|
+
return query;
|
|
68772
|
+
}
|
|
68773
|
+
addJoin(query, tables, columns) {
|
|
68774
|
+
const { tableAliases: aliases, endpoint } = this.query;
|
|
68775
|
+
const schema = endpoint.schema;
|
|
68776
|
+
const toTable = tables.to, fromTable = tables.from, throughTable = tables.through;
|
|
68777
|
+
const toAlias = aliases?.[toTable] || toTable, throughAlias = throughTable && aliases?.[throughTable] || throughTable, fromAlias = aliases?.[fromTable] || fromTable;
|
|
68778
|
+
let toTableWithSchema = this.tableNameWithSchema(toTable, {
|
|
68779
|
+
alias: toAlias,
|
|
68780
|
+
schema
|
|
68781
|
+
});
|
|
68782
|
+
let throughTableWithSchema = throughTable ? this.tableNameWithSchema(throughTable, {
|
|
68783
|
+
alias: throughAlias,
|
|
68784
|
+
schema
|
|
68785
|
+
}) : void 0;
|
|
68786
|
+
if (!throughTable) {
|
|
68787
|
+
query = query.leftJoin(toTableWithSchema, function() {
|
|
68788
|
+
for (let relationship of columns) {
|
|
68789
|
+
const from = relationship.from, to = relationship.to;
|
|
68790
|
+
this.orOn(`${fromAlias}.${from}`, "=", `${toAlias}.${to}`);
|
|
68791
|
+
}
|
|
68792
|
+
});
|
|
68793
|
+
} else {
|
|
68794
|
+
query = query.leftJoin(throughTableWithSchema, function() {
|
|
68795
|
+
for (let relationship of columns) {
|
|
68796
|
+
const fromPrimary = relationship.fromPrimary;
|
|
68797
|
+
const from = relationship.from;
|
|
68798
|
+
this.orOn(
|
|
68799
|
+
`${fromAlias}.${fromPrimary}`,
|
|
68800
|
+
"=",
|
|
68801
|
+
`${throughAlias}.${from}`
|
|
68802
|
+
);
|
|
68803
|
+
}
|
|
68804
|
+
}).leftJoin(toTableWithSchema, function() {
|
|
68805
|
+
for (let relationship of columns) {
|
|
68806
|
+
const toPrimary = relationship.toPrimary;
|
|
68807
|
+
const to = relationship.to;
|
|
68808
|
+
this.orOn(`${toAlias}.${toPrimary}`, `${throughAlias}.${to}`);
|
|
68809
|
+
}
|
|
68810
|
+
});
|
|
68567
68811
|
}
|
|
68568
68812
|
return query;
|
|
68569
68813
|
}
|
|
@@ -68631,15 +68875,14 @@ var InternalBuilder = class {
|
|
|
68631
68875
|
if (!primary) {
|
|
68632
68876
|
throw new Error("Primary key is required for upsert");
|
|
68633
68877
|
}
|
|
68634
|
-
|
|
68635
|
-
return ret;
|
|
68878
|
+
return query.insert(parsedBody).onConflict(primary).merge();
|
|
68636
68879
|
} else if (this.client === "mssql" /* MS_SQL */ || this.client === "oracledb" /* ORACLE */) {
|
|
68637
68880
|
return query.insert(parsedBody);
|
|
68638
68881
|
}
|
|
68639
68882
|
return query.upsert(parsedBody);
|
|
68640
68883
|
}
|
|
68641
68884
|
read(opts = {}) {
|
|
68642
|
-
let { endpoint, filters, paginate, relationships
|
|
68885
|
+
let { endpoint, filters, paginate, relationships } = this.query;
|
|
68643
68886
|
const { limits } = opts;
|
|
68644
68887
|
const counting = endpoint.operation === "COUNT" /* COUNT */;
|
|
68645
68888
|
const tableName = endpoint.entityId;
|
|
@@ -68664,32 +68907,23 @@ var InternalBuilder = class {
|
|
|
68664
68907
|
if (foundOffset != null) {
|
|
68665
68908
|
query = query.offset(foundOffset);
|
|
68666
68909
|
}
|
|
68667
|
-
query = this.addSorting(query);
|
|
68668
68910
|
}
|
|
68669
|
-
query = this.
|
|
68670
|
-
|
|
68671
|
-
|
|
68672
|
-
// the typescript definition for the knex constructor doesn't support this
|
|
68673
|
-
// syntax, but it is the only way to alias a pre-query result as part of
|
|
68674
|
-
// a query - there is an alias dictionary type, but it assumes it can only
|
|
68675
|
-
// be a table name, not a pre-query
|
|
68676
|
-
[alias]: query
|
|
68677
|
-
});
|
|
68678
|
-
preQuery = !counting ? preQuery.select(this.generateSelectStatement()) : this.addDistinctCount(preQuery);
|
|
68679
|
-
if (this.client !== "mssql" /* MS_SQL */ && !counting) {
|
|
68680
|
-
preQuery = this.addSorting(preQuery);
|
|
68911
|
+
query = !counting ? query.select(this.generateSelectStatement()) : this.addDistinctCount(query);
|
|
68912
|
+
if (!counting) {
|
|
68913
|
+
query = this.addSorting(query);
|
|
68681
68914
|
}
|
|
68682
|
-
query = this.
|
|
68683
|
-
|
|
68684
|
-
|
|
68685
|
-
|
|
68686
|
-
|
|
68687
|
-
|
|
68688
|
-
|
|
68689
|
-
|
|
68690
|
-
|
|
68915
|
+
query = this.addFilters(query, filters, { relationship: true });
|
|
68916
|
+
if (relationships?.length) {
|
|
68917
|
+
const mainTable = this.query.tableAliases?.[this.query.endpoint.entityId] || this.query.endpoint.entityId;
|
|
68918
|
+
const cte = this.addSorting(
|
|
68919
|
+
this.knex.with("paginated", query).select(this.generateSelectStatement()).from({
|
|
68920
|
+
[mainTable]: "paginated"
|
|
68921
|
+
})
|
|
68922
|
+
);
|
|
68923
|
+
return this.addJsonRelationships(cte, tableName, relationships);
|
|
68924
|
+
} else {
|
|
68925
|
+
return query;
|
|
68691
68926
|
}
|
|
68692
|
-
return this.addFilters(query, filters, { relationship: true });
|
|
68693
68927
|
}
|
|
68694
68928
|
update(opts) {
|
|
68695
68929
|
const { body: body2, filters } = this.query;
|