prostgles-server 4.2.448 → 4.2.449
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/DboBuilder/DboBuilderTypes.d.ts +6 -2
- package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.js +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.d.ts +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.js +31 -31
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts +5 -5
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts +2 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.js +12 -10
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts +2 -2
- package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js +2 -2
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.js +6 -12
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.js.map +1 -1
- package/dist/DboBuilder/TableRules/getValidatedRules.js +3 -3
- package/dist/DboBuilder/TableRules/getValidatedRules.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.js +3 -3
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareSortItems.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/prepareSortItems.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareSortItems.js +6 -4
- package/dist/DboBuilder/ViewHandler/prepareSortItems.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts.map +1 -1
- package/dist/DboBuilder/getCondition.d.ts +2 -2
- package/dist/DboBuilder/getCondition.d.ts.map +1 -1
- package/dist/DboBuilder/getCondition.js +6 -6
- package/dist/DboBuilder/getCondition.js.map +1 -1
- package/dist/DboBuilder/getSubscribeRelatedTables.js +1 -1
- package/dist/DboBuilder/getSubscribeRelatedTables.js.map +1 -1
- package/dist/Filtering.d.ts +1 -1
- package/dist/Filtering.d.ts.map +1 -1
- package/dist/Filtering.js +3 -3
- package/dist/Filtering.js.map +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js.map +1 -1
- package/eslint.config.mjs +2 -2
- package/lib/DboBuilder/DboBuilderTypes.ts +7 -2
- package/lib/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.ts +1 -1
- package/lib/DboBuilder/QueryBuilder/Functions/Functions.ts +66 -62
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +6 -6
- package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +16 -12
- package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +5 -5
- package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +11 -17
- package/lib/DboBuilder/TableRules/getValidatedRules.ts +9 -9
- package/lib/DboBuilder/ViewHandler/parseComplexFilter.ts +4 -4
- package/lib/DboBuilder/ViewHandler/prepareSortItems.ts +14 -12
- package/lib/DboBuilder/ViewHandler/prepareWhere.ts +6 -6
- package/lib/DboBuilder/getCondition.ts +8 -12
- package/lib/DboBuilder/getSubscribeRelatedTables.ts +1 -1
- package/lib/Filtering.ts +11 -13
- package/lib/PublishParser/getSchemaFromPublish.ts +1 -1
- package/package.json +18 -18
|
@@ -18,7 +18,7 @@ export function getSelectQuery(
|
|
|
18
18
|
viewHandler: ViewHandler,
|
|
19
19
|
q: NewQuery,
|
|
20
20
|
depth = 0,
|
|
21
|
-
selectParamsGroupBy: boolean
|
|
21
|
+
selectParamsGroupBy: boolean,
|
|
22
22
|
): string {
|
|
23
23
|
const rootSelect = q.select
|
|
24
24
|
.filter((s) => s.selected)
|
|
@@ -27,7 +27,7 @@ export function getSelectQuery(
|
|
|
27
27
|
const parsedJoins =
|
|
28
28
|
q.joins?.flatMap((q2) => {
|
|
29
29
|
const parsed = getJoinQuery(viewHandler, {
|
|
30
|
-
q1: { ...q, tableAlias: ROOT_TABLE_ALIAS },
|
|
30
|
+
q1: { ...q, tableAlias: { raw: ROOT_TABLE_ALIAS, escaped: ROOT_TABLE_ALIAS } },
|
|
31
31
|
q2: { ...q2 },
|
|
32
32
|
selectParamsGroupBy,
|
|
33
33
|
});
|
|
@@ -40,8 +40,8 @@ export function getSelectQuery(
|
|
|
40
40
|
const selectItems = rootSelect.concat(
|
|
41
41
|
parsedJoins.map((join) => {
|
|
42
42
|
const { joinAlias } = join;
|
|
43
|
-
return `COALESCE(${
|
|
44
|
-
})
|
|
43
|
+
return `COALESCE(${joinAlias.escaped}.${join.resultAlias.escaped}, '[]') as ${joinAlias.escaped}`;
|
|
44
|
+
}),
|
|
45
45
|
);
|
|
46
46
|
|
|
47
47
|
/** OR joins cannot be easily aggregated to one-many with the root table. Must group by root table id */
|
|
@@ -62,9 +62,9 @@ export function getSelectQuery(
|
|
|
62
62
|
if (hasOrJoins) {
|
|
63
63
|
const pkey = viewHandler.columns.find((c) => c.is_pkey);
|
|
64
64
|
joinCtes = [
|
|
65
|
-
`${q.table} AS (`,
|
|
65
|
+
`${q.table.escaped} AS (`,
|
|
66
66
|
` SELECT *, ${pkey ? asName(pkey.name) : "ROW_NUMBER() OVER()"} as ${ROOT_TABLE_ROW_NUM_ID}`,
|
|
67
|
-
` FROM ${q.table}`,
|
|
67
|
+
` FROM ${q.table.escaped}`,
|
|
68
68
|
`)`,
|
|
69
69
|
joinCtes.length ? "," : "",
|
|
70
70
|
...joinCtes,
|
|
@@ -81,7 +81,7 @@ export function getSelectQuery(
|
|
|
81
81
|
...indentLines(selectItems, { appendCommas: true }),
|
|
82
82
|
`FROM ( `,
|
|
83
83
|
` SELECT *`,
|
|
84
|
-
` FROM ${q.table}`,
|
|
84
|
+
` FROM ${q.table.escaped}`,
|
|
85
85
|
...(q.where ? [` ${q.where}`] : []),
|
|
86
86
|
`) ${ROOT_TABLE_ALIAS}`,
|
|
87
87
|
...parsedJoins.flatMap((j) => j.joinLines),
|
|
@@ -104,7 +104,7 @@ type IndentLinesOpts = {
|
|
|
104
104
|
};
|
|
105
105
|
export const indentLines = (
|
|
106
106
|
strArr: (string | undefined | null)[],
|
|
107
|
-
{ numberOfSpaces = 2, indentStr = " ", appendCommas = false }: IndentLinesOpts = {}
|
|
107
|
+
{ numberOfSpaces = 2, indentStr = " ", appendCommas = false }: IndentLinesOpts = {},
|
|
108
108
|
): string[] => {
|
|
109
109
|
const nonEmptyLines = strArr.filter((v) => v);
|
|
110
110
|
|
|
@@ -120,11 +120,10 @@ const indentLinesToString = (
|
|
|
120
120
|
strArr: (string | undefined | null)[],
|
|
121
121
|
numberOfSpaces = 0,
|
|
122
122
|
separator = " \n ",
|
|
123
|
-
indentStr = " "
|
|
123
|
+
indentStr = " ",
|
|
124
124
|
) => indentLines(strArr, { numberOfSpaces, indentStr }).join(separator);
|
|
125
|
-
const
|
|
126
|
-
!q.tableAlias ? q.table : `${q.tableAlias || ""}_${q.table}
|
|
127
|
-
export const getTableAliasAsName = (q: NewQuery) => asName(getTableAlias(q));
|
|
125
|
+
export const getTableAliasAsName = (q: NewQuery) =>
|
|
126
|
+
!q.tableAlias ? q.table.escaped : asName(`${q.tableAlias.raw || ""}_${q.table.raw}`);
|
|
128
127
|
|
|
129
128
|
export const getRootGroupBy = (q: NewQuery, selectParamsGroupBy?: boolean) => {
|
|
130
129
|
const aggs = q.select.filter((s) => s.selected && s.type === "aggregation");
|
|
@@ -133,11 +132,6 @@ export const getRootGroupBy = (q: NewQuery, selectParamsGroupBy?: boolean) => {
|
|
|
133
132
|
if ((selectParamsGroupBy || aggs.length) && nonAggs.length) {
|
|
134
133
|
/** Add ORDER BY items not included in root select */
|
|
135
134
|
const orderByItems: string[] = [];
|
|
136
|
-
// q.orderByItems.forEach(sortItem => {
|
|
137
|
-
// if (!sortItem.nested && "fieldQuery" in sortItem && !orderByItems.includes(sortItem.fieldQuery)) {
|
|
138
|
-
// orderByItems.push(sortItem.fieldQuery);
|
|
139
|
-
// }
|
|
140
|
-
// });
|
|
141
135
|
|
|
142
136
|
return [
|
|
143
137
|
`GROUP BY ${q.select
|
|
@@ -9,7 +9,7 @@ import { asNameAlias } from "../../utils/asNameAlias";
|
|
|
9
9
|
export function getValidatedRules(
|
|
10
10
|
this: ViewHandler,
|
|
11
11
|
tableRules?: ParsedTableRule,
|
|
12
|
-
localParams?: LocalParams
|
|
12
|
+
localParams?: LocalParams,
|
|
13
13
|
): ValidatedTableRules {
|
|
14
14
|
if (localParams?.clientReq?.socket && !tableRules) {
|
|
15
15
|
throw "INTERNAL ERROR: Unexpected case -> localParams && !tableRules";
|
|
@@ -23,15 +23,15 @@ export function getValidatedRules(
|
|
|
23
23
|
({
|
|
24
24
|
type: "column",
|
|
25
25
|
name: fieldName,
|
|
26
|
-
getQuery: ({ tableAlias }) => asNameAlias(fieldName, tableAlias),
|
|
26
|
+
getQuery: ({ tableAliasRaw: tableAlias }) => asNameAlias(fieldName, tableAlias),
|
|
27
27
|
selected: false,
|
|
28
|
-
}) as FieldSpec
|
|
28
|
+
}) as FieldSpec,
|
|
29
29
|
)
|
|
30
30
|
.concat(
|
|
31
31
|
COMPUTED_FIELDS.map((c) => ({
|
|
32
32
|
type: c.type,
|
|
33
33
|
name: c.name,
|
|
34
|
-
getQuery: ({ tableAlias, allowedFields }) =>
|
|
34
|
+
getQuery: ({ tableAliasRaw: tableAlias, allowedFields }) =>
|
|
35
35
|
c.getQuery({
|
|
36
36
|
allowedFields,
|
|
37
37
|
ctidField: undefined,
|
|
@@ -39,10 +39,10 @@ export function getValidatedRules(
|
|
|
39
39
|
|
|
40
40
|
/* CTID not available in AFTER trigger */
|
|
41
41
|
// ctidField: this.is_view? undefined : "ctid",
|
|
42
|
-
tableAlias,
|
|
42
|
+
tableAliasRaw: tableAlias,
|
|
43
43
|
}),
|
|
44
44
|
selected: false,
|
|
45
|
-
}))
|
|
45
|
+
})),
|
|
46
46
|
);
|
|
47
47
|
|
|
48
48
|
if (tableRules) {
|
|
@@ -50,7 +50,7 @@ export function getValidatedRules(
|
|
|
50
50
|
throw "INTERNAL ERROR: Unexpected case -> Empty table rules for " + this.name;
|
|
51
51
|
const throwFieldsErr = (
|
|
52
52
|
command: "select" | "update" | "delete" | "insert",
|
|
53
|
-
fieldType = "fields"
|
|
53
|
+
fieldType = "fields",
|
|
54
54
|
) => {
|
|
55
55
|
throw `Invalid publish.${this.name}.${command} rule -> ${fieldType} setting is missing.\nPlease specify allowed ${fieldType} in this format: "*" | { col_name: false } | { col1: true, col2: true }`;
|
|
56
56
|
},
|
|
@@ -106,7 +106,7 @@ export function getValidatedRules(
|
|
|
106
106
|
returningFields: parseFirstSpecifiedFieldFilter(
|
|
107
107
|
tableRules.update.returningFields,
|
|
108
108
|
tableRules.select?.fields,
|
|
109
|
-
tableRules.update.fields
|
|
109
|
+
tableRules.update.fields,
|
|
110
110
|
),
|
|
111
111
|
filterFields: this.parseFieldFilter(tableRules.update.filterFields),
|
|
112
112
|
};
|
|
@@ -121,7 +121,7 @@ export function getValidatedRules(
|
|
|
121
121
|
returningFields: parseFirstSpecifiedFieldFilter(
|
|
122
122
|
tableRules.insert.returningFields,
|
|
123
123
|
tableRules.select?.fields,
|
|
124
|
-
tableRules.insert.fields
|
|
124
|
+
tableRules.insert.fields,
|
|
125
125
|
),
|
|
126
126
|
};
|
|
127
127
|
}
|
|
@@ -16,7 +16,7 @@ const allowedComparators = FILTER_OPERANDS; //[">", "<", "=", "<=", ">=", "<>",
|
|
|
16
16
|
type Args = {
|
|
17
17
|
filter: AnyObject;
|
|
18
18
|
complexFilterKey: string;
|
|
19
|
-
|
|
19
|
+
tableAliasRaw: string | undefined;
|
|
20
20
|
allowed_colnames: string[];
|
|
21
21
|
columns: TableSchemaColumn[];
|
|
22
22
|
};
|
|
@@ -33,7 +33,7 @@ type Args = {
|
|
|
33
33
|
export const parseComplexFilter = ({
|
|
34
34
|
filter,
|
|
35
35
|
complexFilterKey,
|
|
36
|
-
|
|
36
|
+
tableAliasRaw,
|
|
37
37
|
allowed_colnames,
|
|
38
38
|
columns,
|
|
39
39
|
}: Args) => {
|
|
@@ -50,7 +50,7 @@ export const parseComplexFilter = ({
|
|
|
50
50
|
if (!allowed_colnames.includes(column)) {
|
|
51
51
|
throw `Dissallowed or Invalid column ${column}. Allowed columns: ${allowed_colnames}`;
|
|
52
52
|
}
|
|
53
|
-
return asNameAlias(column,
|
|
53
|
+
return asNameAlias(column, tableAliasRaw);
|
|
54
54
|
}
|
|
55
55
|
const { funcName, args } = parseFunctionObject(funcData);
|
|
56
56
|
const funcDef = parseFunction({
|
|
@@ -61,7 +61,7 @@ export const parseComplexFilter = ({
|
|
|
61
61
|
});
|
|
62
62
|
return funcDef.getQuery({
|
|
63
63
|
args,
|
|
64
|
-
|
|
64
|
+
tableAliasRaw,
|
|
65
65
|
allColumns: columns,
|
|
66
66
|
allowedFields: allowed_colnames,
|
|
67
67
|
});
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
isEmpty,
|
|
7
7
|
isObject,
|
|
8
8
|
} from "prostgles-types/dist";
|
|
9
|
-
import type { SortItem } from "../DboBuilder";
|
|
9
|
+
import type { PGIdentifier, SortItem } from "../DboBuilder";
|
|
10
10
|
import type { NewQueryJoin, SelectItemValidated } from "../QueryBuilder/QueryBuilder";
|
|
11
11
|
import { asNameAlias } from "../../utils/asNameAlias";
|
|
12
12
|
|
|
@@ -14,9 +14,9 @@ import { asNameAlias } from "../../utils/asNameAlias";
|
|
|
14
14
|
export const prepareSortItems = (
|
|
15
15
|
rawOrderBy: OrderBy | undefined,
|
|
16
16
|
allowed_cols: string[],
|
|
17
|
-
tableAlias:
|
|
17
|
+
tableAlias: PGIdentifier | undefined,
|
|
18
18
|
select: SelectItemValidated[],
|
|
19
|
-
joinQueries: NewQueryJoin[]
|
|
19
|
+
joinQueries: NewQueryJoin[],
|
|
20
20
|
): SortItem[] => {
|
|
21
21
|
if (!rawOrderBy) return [];
|
|
22
22
|
|
|
@@ -48,7 +48,7 @@ export const prepareSortItems = (
|
|
|
48
48
|
.filter(
|
|
49
49
|
(s) =>
|
|
50
50
|
s.type !== "joinedColumn" &&
|
|
51
|
-
(!s.fields.length || s.fields.every((f) => allowed_cols.includes(f)))
|
|
51
|
+
(!s.fields.length || s.fields.every((f) => allowed_cols.includes(f))),
|
|
52
52
|
)
|
|
53
53
|
.map((s) => s.alias);
|
|
54
54
|
|
|
@@ -59,15 +59,15 @@ export const prepareSortItems = (
|
|
|
59
59
|
...jq,
|
|
60
60
|
selectItem,
|
|
61
61
|
joinAlias,
|
|
62
|
-
key: `${joinAlias}.${selectItem.alias}`,
|
|
62
|
+
key: `${joinAlias.raw}.${selectItem.alias}`,
|
|
63
63
|
};
|
|
64
|
-
})
|
|
64
|
+
}),
|
|
65
65
|
);
|
|
66
66
|
const bad_param = orderBy.find(
|
|
67
67
|
({ key }) =>
|
|
68
68
|
!sortableNestedColumns.some((v) => v.key === key) &&
|
|
69
69
|
!validatedAggAliases.includes(key) &&
|
|
70
|
-
!allowed_cols.includes(key)
|
|
70
|
+
!allowed_cols.includes(key),
|
|
71
71
|
);
|
|
72
72
|
if (bad_param) {
|
|
73
73
|
throw "Invalid/disallowed orderBy fields or params: " + bad_param.key;
|
|
@@ -95,9 +95,9 @@ export const prepareSortItems = (
|
|
|
95
95
|
joinAlias,
|
|
96
96
|
selectItemAlias: selectItem.alias,
|
|
97
97
|
isNumeric: selectItem.tsDataType === "number",
|
|
98
|
-
wrapperQuerySortItem: `${asc ? "MIN" : "MAX"}(${asNameAlias(selectItem.alias, joinAlias)}${comparableDataTypeCast}) as ${sortItemAlias}`,
|
|
98
|
+
wrapperQuerySortItem: `${asc ? "MIN" : "MAX"}(${asNameAlias(selectItem.alias, joinAlias.raw)}${comparableDataTypeCast}) as ${sortItemAlias}`,
|
|
99
99
|
},
|
|
100
|
-
fieldQuery: `${
|
|
100
|
+
fieldQuery: `${joinAlias.escaped}.${sortItemAlias + (asc ? "" : " DESC")} ${nulls ? `NULLS ${nulls === "last" ? "LAST" : "FIRST"}` : ""}`,
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
/* Order by column index when possible to bypass name collision when ordering by a computed column.
|
|
@@ -106,7 +106,9 @@ export const prepareSortItems = (
|
|
|
106
106
|
|
|
107
107
|
const index = selectedAliases.indexOf(key) + 1;
|
|
108
108
|
let colKey =
|
|
109
|
-
index > 0 && !nullEmpty ?
|
|
109
|
+
index > 0 && !nullEmpty ?
|
|
110
|
+
index
|
|
111
|
+
: [tableAlias?.raw, key].filter(isDefined).map(asName).join(".");
|
|
110
112
|
if (nullEmpty) {
|
|
111
113
|
colKey = `nullif(trim(${colKey}::text), '')`;
|
|
112
114
|
}
|
|
@@ -150,7 +152,7 @@ const throwErr = (rawOrderBy: any) => {
|
|
|
150
152
|
|
|
151
153
|
const parseOrderObj = (
|
|
152
154
|
orderBy: any,
|
|
153
|
-
expectOne = false
|
|
155
|
+
expectOne = false,
|
|
154
156
|
): {
|
|
155
157
|
key: string;
|
|
156
158
|
asc: boolean;
|
|
@@ -171,7 +173,7 @@ const parseOrderObj = (
|
|
|
171
173
|
nullEmpty: { enum: [false, true, null], optional: true },
|
|
172
174
|
} as const,
|
|
173
175
|
orderBy,
|
|
174
|
-
"orderBy"
|
|
176
|
+
"orderBy",
|
|
175
177
|
);
|
|
176
178
|
if (data) {
|
|
177
179
|
const { key, asc = true, nulls, nullEmpty = false } = data;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { AnyObject, FieldFilter} from "prostgles-types/dist";
|
|
1
|
+
import type { AnyObject, FieldFilter } from "prostgles-types/dist";
|
|
2
2
|
import { getKeys, isDefined, isObject } from "prostgles-types/dist";
|
|
3
3
|
import type { ParsedTableRule } from "../../PublishParser/PublishParser";
|
|
4
|
-
import type { ExistsFilterConfig, Filter, LocalParams } from "../DboBuilder";
|
|
4
|
+
import type { ExistsFilterConfig, Filter, LocalParams, PGIdentifier } from "../DboBuilder";
|
|
5
5
|
import { getCondition } from "../getCondition";
|
|
6
6
|
import { type SelectItemValidated } from "../QueryBuilder/QueryBuilder";
|
|
7
7
|
import type { ViewHandler } from "./ViewHandler";
|
|
@@ -12,7 +12,7 @@ export type PrepareWhereParams = {
|
|
|
12
12
|
forcedFilter?: AnyObject;
|
|
13
13
|
filterFields?: FieldFilter;
|
|
14
14
|
addWhere?: boolean;
|
|
15
|
-
tableAlias?:
|
|
15
|
+
tableAlias?: PGIdentifier;
|
|
16
16
|
localParams: LocalParams | undefined;
|
|
17
17
|
tableRule: ParsedTableRule | undefined;
|
|
18
18
|
isHaving?: boolean;
|
|
@@ -20,7 +20,7 @@ export type PrepareWhereParams = {
|
|
|
20
20
|
|
|
21
21
|
export async function prepareWhere(
|
|
22
22
|
this: ViewHandler,
|
|
23
|
-
params: PrepareWhereParams
|
|
23
|
+
params: PrepareWhereParams,
|
|
24
24
|
): Promise<{
|
|
25
25
|
condition: string;
|
|
26
26
|
where: string;
|
|
@@ -48,7 +48,7 @@ export async function prepareWhere(
|
|
|
48
48
|
const parseFullFilter = async (
|
|
49
49
|
f: any,
|
|
50
50
|
parentFilter: any = null,
|
|
51
|
-
isForcedFilterBypass: boolean
|
|
51
|
+
isForcedFilterBypass: boolean,
|
|
52
52
|
): Promise<string> => {
|
|
53
53
|
if (!f) throw "Invalid/missing group filter provided";
|
|
54
54
|
if (!isObject(f)) throw "\nInvalid filter\nExpecting an object but got -> " + JSON.stringify(f);
|
|
@@ -71,7 +71,7 @@ export async function prepareWhere(
|
|
|
71
71
|
const operand = $and ? " AND " : " OR ";
|
|
72
72
|
const conditions = (
|
|
73
73
|
await Promise.all(
|
|
74
|
-
group.map(async (gf) => await parseFullFilter(gf, group, isForcedFilterBypass))
|
|
74
|
+
group.map(async (gf) => await parseFullFilter(gf, group, isForcedFilterBypass)),
|
|
75
75
|
)
|
|
76
76
|
).filter((c) => c);
|
|
77
77
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { asName, pickKeys } from "prostgles-types";
|
|
2
2
|
import { parseFilterItem } from "../Filtering";
|
|
3
3
|
import type { ParsedTableRule } from "../PublishParser/PublishParser";
|
|
4
|
-
import type { ExistsFilterConfig, LocalParams } from "./DboBuilder";
|
|
4
|
+
import type { ExistsFilterConfig, LocalParams, PGIdentifier } from "./DboBuilder";
|
|
5
5
|
import { pgp } from "./DboBuilder";
|
|
6
6
|
import { FUNCTIONS } from "./QueryBuilder/Functions/Functions";
|
|
7
7
|
import { type SelectItemValidated } from "./QueryBuilder/QueryBuilder";
|
|
@@ -24,7 +24,7 @@ export async function getCondition(
|
|
|
24
24
|
filter: any;
|
|
25
25
|
select: SelectItemValidated[] | undefined;
|
|
26
26
|
allowed_colnames: string[];
|
|
27
|
-
tableAlias?:
|
|
27
|
+
tableAlias?: PGIdentifier;
|
|
28
28
|
localParams?: LocalParams;
|
|
29
29
|
tableRules?: ParsedTableRule;
|
|
30
30
|
isHaving?: boolean;
|
|
@@ -63,7 +63,7 @@ export async function getCondition(
|
|
|
63
63
|
args: funcArgs,
|
|
64
64
|
allColumns: this.columns,
|
|
65
65
|
allowedFields: allowed_colnames,
|
|
66
|
-
tableAlias,
|
|
66
|
+
tableAliasRaw: tableAlias?.raw,
|
|
67
67
|
}),
|
|
68
68
|
);
|
|
69
69
|
});
|
|
@@ -74,11 +74,7 @@ export async function getCondition(
|
|
|
74
74
|
await Promise.all(
|
|
75
75
|
existsConfigs.map(
|
|
76
76
|
async (existsConfig) =>
|
|
77
|
-
await getExistsCondition.bind(this)(
|
|
78
|
-
existsConfig,
|
|
79
|
-
tableAlias && asName(tableAlias),
|
|
80
|
-
localParams,
|
|
81
|
-
),
|
|
77
|
+
await getExistsCondition.bind(this)(existsConfig, tableAlias?.escaped, localParams),
|
|
82
78
|
),
|
|
83
79
|
)
|
|
84
80
|
).join(" AND ");
|
|
@@ -94,7 +90,7 @@ export async function getCondition(
|
|
|
94
90
|
if (!p.select) throw new Error("Computed column filter requires p.select.fields");
|
|
95
91
|
computedColConditions.push(
|
|
96
92
|
compCol.getQuery({
|
|
97
|
-
tableAlias,
|
|
93
|
+
tableAliasRaw: tableAlias?.raw,
|
|
98
94
|
allowedFields: p.select.fields,
|
|
99
95
|
allColumns: this.columns,
|
|
100
96
|
|
|
@@ -147,7 +143,7 @@ export async function getCondition(
|
|
|
147
143
|
fields: [f.name],
|
|
148
144
|
getQuery: (tableAlias) =>
|
|
149
145
|
f.getQuery({
|
|
150
|
-
tableAlias,
|
|
146
|
+
tableAliasRaw: tableAlias,
|
|
151
147
|
allColumns: this.columns,
|
|
152
148
|
allowedFields: allowed_colnames,
|
|
153
149
|
}),
|
|
@@ -163,7 +159,7 @@ export async function getCondition(
|
|
|
163
159
|
const complexFilterCondition = parseComplexFilter({
|
|
164
160
|
filter,
|
|
165
161
|
complexFilterKey,
|
|
166
|
-
tableAlias,
|
|
162
|
+
tableAliasRaw: tableAlias?.raw,
|
|
167
163
|
allowed_colnames,
|
|
168
164
|
columns: this.columns,
|
|
169
165
|
});
|
|
@@ -223,7 +219,7 @@ export async function getCondition(
|
|
|
223
219
|
const f = pickKeys(filter, filterKeys);
|
|
224
220
|
const q = parseFilterItem({
|
|
225
221
|
filter: f,
|
|
226
|
-
tableAlias,
|
|
222
|
+
tableAliasRaw: tableAlias?.raw,
|
|
227
223
|
select: allowedSelect,
|
|
228
224
|
allowedColumnNames:
|
|
229
225
|
!tableRules ?
|
|
@@ -76,7 +76,7 @@ export async function getSubscribeRelatedTables(
|
|
|
76
76
|
* Avoid nested exists error. Will affect performance
|
|
77
77
|
*/
|
|
78
78
|
for (const j of newQuery.joins ?? []) {
|
|
79
|
-
await pushRelatedTable(j.table, j.joinPath);
|
|
79
|
+
await pushRelatedTable(j.table.raw, j.joinPath);
|
|
80
80
|
}
|
|
81
81
|
for (const e of newQuery.whereOpts.exists.filter((e) => e.isJoined)) {
|
|
82
82
|
for (const [index, pathItem] of e.parsedPath.entries()) {
|
package/lib/Filtering.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
FilterDataType,
|
|
3
|
-
FullFilter} from "prostgles-types";
|
|
1
|
+
import type { FilterDataType, FullFilter } from "prostgles-types";
|
|
4
2
|
import {
|
|
5
3
|
BetweenFilterKeys,
|
|
6
4
|
CompareFilterKeys,
|
|
@@ -47,7 +45,7 @@ export const FILTER_OPERAND_TO_SQL_OPERAND = Object.fromEntries(
|
|
|
47
45
|
else if (filterOperand === "$isDistinctFrom") sqlOperand = "IS DISTINCT FROM";
|
|
48
46
|
else if (filterOperand === "$isNotDistinctFrom") sqlOperand = "IS NOT DISTINCT FROM";
|
|
49
47
|
return [filterOperand, sqlOperand];
|
|
50
|
-
})
|
|
48
|
+
}),
|
|
51
49
|
) as Record<(typeof FILTER_OPERANDS)[number], string>;
|
|
52
50
|
|
|
53
51
|
/**
|
|
@@ -57,12 +55,12 @@ export const FILTER_OPERAND_TO_SQL_OPERAND = Object.fromEntries(
|
|
|
57
55
|
type ParseFilterItemArgs = {
|
|
58
56
|
filter: FullFilter<void, void> | undefined;
|
|
59
57
|
select: SelectItemValidated[] | undefined;
|
|
60
|
-
|
|
58
|
+
tableAliasRaw: string | undefined;
|
|
61
59
|
allowedColumnNames: string[];
|
|
62
60
|
};
|
|
63
61
|
|
|
64
62
|
export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
65
|
-
const { filter: _f, select,
|
|
63
|
+
const { filter: _f, select, tableAliasRaw, allowedColumnNames } = args;
|
|
66
64
|
|
|
67
65
|
if (!_f || isEmpty(_f)) return "";
|
|
68
66
|
|
|
@@ -84,9 +82,9 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
84
82
|
parseFilterItem({
|
|
85
83
|
filter: { [fk]: _f[fk] },
|
|
86
84
|
select,
|
|
87
|
-
|
|
85
|
+
tableAliasRaw,
|
|
88
86
|
allowedColumnNames,
|
|
89
|
-
})
|
|
87
|
+
}),
|
|
90
88
|
)
|
|
91
89
|
.sort() /* sorted to ensure duplicate subscription channels are not created due to different condition order */
|
|
92
90
|
.join(" AND ");
|
|
@@ -106,7 +104,7 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
106
104
|
const dissallowedFields = fields.filter((fname) => !allowedColumnNames.includes(fname));
|
|
107
105
|
if (dissallowedFields.length) {
|
|
108
106
|
throw new Error(
|
|
109
|
-
`Invalid/disallowed columns found in filter: ${dissallowedFields.join(", ")}
|
|
107
|
+
`Invalid/disallowed columns found in filter: ${dissallowedFields.join(", ")}`,
|
|
110
108
|
);
|
|
111
109
|
}
|
|
112
110
|
}
|
|
@@ -114,7 +112,7 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
114
112
|
const getLeftQ = (selItm: SelectItemValidated) => {
|
|
115
113
|
validateSelectedItemFilter(selItem);
|
|
116
114
|
if (selItm.type === "function" || selItm.type === "aggregation") return selItm.getQuery();
|
|
117
|
-
return selItm.getQuery(
|
|
115
|
+
return selItm.getQuery(tableAliasRaw);
|
|
118
116
|
};
|
|
119
117
|
|
|
120
118
|
/**
|
|
@@ -131,14 +129,14 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
131
129
|
/* See if dot notation. Pick the best matching starting string */
|
|
132
130
|
if (select) {
|
|
133
131
|
selItem = select.find((s) =>
|
|
134
|
-
dot_notation_delims.find((delimiter) => fKey.startsWith(s.alias + delimiter))
|
|
132
|
+
dot_notation_delims.find((delimiter) => fKey.startsWith(s.alias + delimiter)),
|
|
135
133
|
);
|
|
136
134
|
validateSelectedItemFilter(selItem);
|
|
137
135
|
}
|
|
138
136
|
if (!selItem) {
|
|
139
137
|
return mErr(
|
|
140
138
|
"Bad filter. Could not match to a column or alias or dot notation" +
|
|
141
|
-
select?.map((s) => s.alias).join(", ")
|
|
139
|
+
select?.map((s) => s.alias).join(", "),
|
|
142
140
|
);
|
|
143
141
|
}
|
|
144
142
|
|
|
@@ -148,7 +146,7 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
148
146
|
if (remainingStr.startsWith("->")) {
|
|
149
147
|
/** Has shorthand operand 'col->>key.<>' */
|
|
150
148
|
const matchingOperand = CompareFilterKeys.find((operand) =>
|
|
151
|
-
remainingStr.endsWith(`.${operand}`)
|
|
149
|
+
remainingStr.endsWith(`.${operand}`),
|
|
152
150
|
);
|
|
153
151
|
if (matchingOperand) {
|
|
154
152
|
remainingStr = remainingStr.slice(0, -matchingOperand.length - 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prostgles-server",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.449",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -38,16 +38,16 @@
|
|
|
38
38
|
],
|
|
39
39
|
"homepage": "https://prostgles.com",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@aws-sdk/client-ses": "^3.
|
|
42
|
-
"@aws-sdk/credential-provider-node": "^3.972.
|
|
41
|
+
"@aws-sdk/client-ses": "^3.993.0",
|
|
42
|
+
"@aws-sdk/credential-provider-node": "^3.972.10",
|
|
43
43
|
"@types/passport": "^1.0.17",
|
|
44
|
-
"@types/passport-facebook": "^3.0.
|
|
44
|
+
"@types/passport-facebook": "^3.0.4",
|
|
45
45
|
"@types/passport-github2": "^1.2.9",
|
|
46
|
-
"@types/passport-google-oauth20": "^2.0.
|
|
46
|
+
"@types/passport-google-oauth20": "^2.0.17",
|
|
47
47
|
"@types/passport-microsoft": "^1.0.3",
|
|
48
48
|
"check-disk-space": "^3.4.0",
|
|
49
|
-
"file-type": "^18.
|
|
50
|
-
"nodemailer": "^7.0.
|
|
49
|
+
"file-type": "^18.7.0",
|
|
50
|
+
"nodemailer": "^7.0.13",
|
|
51
51
|
"passport": "^0.7.0",
|
|
52
52
|
"passport-facebook": "^3.0.0",
|
|
53
53
|
"passport-github2": "^0.1.12",
|
|
@@ -56,23 +56,23 @@
|
|
|
56
56
|
"passport-oauth2": "^1.8.0",
|
|
57
57
|
"pg": "^8.15.6",
|
|
58
58
|
"pg-cursor": "^2.17.0",
|
|
59
|
-
"pg-promise": "^12.6.
|
|
60
|
-
"prostgles-types": "^4.0.
|
|
59
|
+
"pg-promise": "^12.6.1",
|
|
60
|
+
"prostgles-types": "^4.0.211"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@eslint/js": "^9.22.0",
|
|
64
|
-
"@types/express": "^4.17.
|
|
64
|
+
"@types/express": "^4.17.25",
|
|
65
65
|
"@types/json-schema": "^7.0.15",
|
|
66
|
-
"@types/node": "^22.
|
|
67
|
-
"@types/nodemailer": "^6.4.
|
|
68
|
-
"@types/pg": "^8.
|
|
66
|
+
"@types/node": "^22.19.11",
|
|
67
|
+
"@types/nodemailer": "^6.4.22",
|
|
68
|
+
"@types/pg": "^8.16.0",
|
|
69
69
|
"@types/pg-cursor": "^2.7.2",
|
|
70
|
-
"@types/sharp": "^0.30.
|
|
70
|
+
"@types/sharp": "^0.30.5",
|
|
71
71
|
"eslint": "^9.39.2",
|
|
72
72
|
"eslint-plugin-security": "^3.0.1",
|
|
73
|
-
"prettier": "^3.
|
|
74
|
-
"socket.io": "^4.8.
|
|
75
|
-
"typescript": "^5.
|
|
76
|
-
"typescript-eslint": "^8.
|
|
73
|
+
"prettier": "^3.8.1",
|
|
74
|
+
"socket.io": "^4.8.3",
|
|
75
|
+
"typescript": "^5.9.3",
|
|
76
|
+
"typescript-eslint": "^8.56.0"
|
|
77
77
|
}
|
|
78
78
|
}
|