prostgles-server 2.0.114 → 2.0.118
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.d.ts +9 -2
- package/dist/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder.js +33 -2
- package/dist/DboBuilder.js.map +1 -1
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +26 -4
- package/dist/Prostgles.js.map +1 -1
- package/dist/QueryBuilder.d.ts.map +1 -1
- package/dist/QueryBuilder.js +32 -11
- package/dist/QueryBuilder.js.map +1 -1
- package/lib/DboBuilder.ts +39 -3
- package/lib/Prostgles.ts +36 -8
- package/lib/QueryBuilder.ts +31 -12
- package/package.json +1 -1
- package/tests/client/PID.txt +1 -1
- package/tests/client/package-lock.json +15 -27
- package/tests/client/package.json +1 -1
- package/tests/server/media/{65a9f585-3fc6-46d9-aece-1ba88f58aa8d.txt → 4a99306b-8b60-4463-bdd7-adfa7010592a.txt} +0 -0
- package/tests/server/media/{920d2684-0f59-4af6-bea0-4a0c199e699f.txt → 4f0d2827-bca7-4992-b92d-4376b3ac0064.txt} +0 -0
- package/tests/server/media/{c4dce0df-ebde-46df-bddd-6e92eb33f5f9.txt → 5aa4cae6-c9c0-4cdc-afea-f11cb883dd96.txt} +0 -0
- package/tests/server/media/{f7c959c7-5fed-4843-bb6f-096f7ad0d644.txt → dcf6cc8c-1f2b-4a98-8b95-78469e2cd337.txt} +0 -0
- package/tests/server/package-lock.json +1 -1
package/lib/Prostgles.ts
CHANGED
|
@@ -1093,20 +1093,25 @@ type DboTableCommand = Request & DboTable & {
|
|
|
1093
1093
|
const RULE_TO_METHODS = [
|
|
1094
1094
|
{
|
|
1095
1095
|
rule: "getColumns",
|
|
1096
|
+
sqlRule: "select",
|
|
1096
1097
|
methods: ["getColumns"],
|
|
1097
1098
|
no_limits: true,
|
|
1098
1099
|
allowed_params: [],
|
|
1100
|
+
table_only: false,
|
|
1099
1101
|
hint: ` expecting false | true | undefined`
|
|
1100
1102
|
},
|
|
1101
1103
|
{
|
|
1102
1104
|
rule: "getInfo",
|
|
1105
|
+
sqlRule: "select",
|
|
1103
1106
|
methods: ["getInfo"],
|
|
1104
1107
|
no_limits: true,
|
|
1105
1108
|
allowed_params: [],
|
|
1109
|
+
table_only: false,
|
|
1106
1110
|
hint: ` expecting false | true | undefined`
|
|
1107
1111
|
},
|
|
1108
1112
|
{
|
|
1109
1113
|
rule: "insert",
|
|
1114
|
+
sqlRule: "insert",
|
|
1110
1115
|
methods: ["insert", "upsert"],
|
|
1111
1116
|
no_limits: <SelectRule>{ fields: "*" },
|
|
1112
1117
|
table_only: true,
|
|
@@ -1115,6 +1120,7 @@ const RULE_TO_METHODS = [
|
|
|
1115
1120
|
},
|
|
1116
1121
|
{
|
|
1117
1122
|
rule: "update",
|
|
1123
|
+
sqlRule: "update",
|
|
1118
1124
|
methods: ["update", "upsert", "updateBatch"],
|
|
1119
1125
|
no_limits: <UpdateRule>{ fields: "*", filterFields: "*", returningFields: "*" },
|
|
1120
1126
|
table_only: true,
|
|
@@ -1123,13 +1129,16 @@ const RULE_TO_METHODS = [
|
|
|
1123
1129
|
},
|
|
1124
1130
|
{
|
|
1125
1131
|
rule: "select",
|
|
1132
|
+
sqlRule: "select",
|
|
1126
1133
|
methods: ["findOne", "find", "count"],
|
|
1127
1134
|
no_limits: <SelectRule>{ fields: "*", filterFields: "*" },
|
|
1135
|
+
table_only: false,
|
|
1128
1136
|
allowed_params: <Array<keyof SelectRule>>["fields", "filterFields", "forcedFilter", "validate", "maxLimit"] ,
|
|
1129
1137
|
hint: ` expecting "*" | true | { fields: ( string | string[] | {} ) }`
|
|
1130
1138
|
},
|
|
1131
1139
|
{
|
|
1132
1140
|
rule: "delete",
|
|
1141
|
+
sqlRule: "delete",
|
|
1133
1142
|
methods: ["delete", "remove"],
|
|
1134
1143
|
no_limits: <DeleteRule>{ filterFields: "*" } ,
|
|
1135
1144
|
table_only: true,
|
|
@@ -1137,20 +1146,24 @@ const RULE_TO_METHODS = [
|
|
|
1137
1146
|
hint: ` expecting "*" | true | { filterFields: ( string | string[] | {} ) } \n Will use "select", "update", "delete" and "insert" rules`
|
|
1138
1147
|
},
|
|
1139
1148
|
{
|
|
1140
|
-
rule: "sync",
|
|
1149
|
+
rule: "sync",
|
|
1150
|
+
sqlRule: "select",
|
|
1151
|
+
methods: ["sync", "unsync"],
|
|
1141
1152
|
no_limits: null,
|
|
1142
1153
|
table_only: true,
|
|
1143
1154
|
allowed_params: <Array<keyof SyncRule>>["id_fields", "synced_field", "sync_type", "allow_delete", "throttle", "batch_size"],
|
|
1144
1155
|
hint: ` expecting "*" | true | { id_fields: string[], synced_field: string }`
|
|
1145
1156
|
},
|
|
1146
1157
|
{
|
|
1147
|
-
rule: "subscribe",
|
|
1158
|
+
rule: "subscribe",
|
|
1159
|
+
sqlRule: "select",
|
|
1160
|
+
methods: ["unsubscribe", "subscribe", "subscribeOne"],
|
|
1148
1161
|
no_limits: <SubscribeRule>{ throttle: 0 },
|
|
1149
1162
|
table_only: true,
|
|
1150
1163
|
allowed_params: <Array<keyof SubscribeRule>>["throttle"],
|
|
1151
1164
|
hint: ` expecting "*" | true | { throttle: number } \n Will use "select" rules`
|
|
1152
1165
|
}
|
|
1153
|
-
];
|
|
1166
|
+
] as const;
|
|
1154
1167
|
// const ALL_PUBLISH_METHODS = ["update", "upsert", "delete", "insert", "find", "findOne", "subscribe", "unsubscribe", "sync", "unsync", "remove"];
|
|
1155
1168
|
// const ALL_PUBLISH_METHODS = RULE_TO_METHODS.map(r => r.methods).flat();
|
|
1156
1169
|
|
|
@@ -1239,7 +1252,7 @@ export class PublishParser {
|
|
|
1239
1252
|
|
|
1240
1253
|
if(!command || !tableName) throw "command OR tableName are missing";
|
|
1241
1254
|
|
|
1242
|
-
let rtm = RULE_TO_METHODS.find(rtms => rtms.methods.includes(command));
|
|
1255
|
+
let rtm = RULE_TO_METHODS.find(rtms => (rtms.methods as any).includes(command));
|
|
1243
1256
|
if(!rtm){
|
|
1244
1257
|
throw "Invalid command: " + command;
|
|
1245
1258
|
}
|
|
@@ -1285,7 +1298,9 @@ export class PublishParser {
|
|
|
1285
1298
|
let table_rules = _publish[tableName];// applyParamsIfFunc(_publish[tableName], localParams, this.dbo, this.db, user);
|
|
1286
1299
|
|
|
1287
1300
|
/* Get view or table specific rules */
|
|
1288
|
-
const
|
|
1301
|
+
const tHandler = (this.dbo[tableName] as TableHandler | ViewHandler);
|
|
1302
|
+
|
|
1303
|
+
const is_view = tHandler.is_view,
|
|
1289
1304
|
MY_RULES = RULE_TO_METHODS.filter(r => !is_view || !r.table_only);
|
|
1290
1305
|
|
|
1291
1306
|
// if(tableName === "various") console.warn(1033, MY_RULES)
|
|
@@ -1295,7 +1310,14 @@ export class PublishParser {
|
|
|
1295
1310
|
if([true, "*"].includes(table_rules as any)){
|
|
1296
1311
|
table_rules = {};
|
|
1297
1312
|
MY_RULES.map(r => {
|
|
1298
|
-
|
|
1313
|
+
/** Check PG User privileges */
|
|
1314
|
+
if(
|
|
1315
|
+
tHandler.tableOrViewInfo.privileges[r.sqlRule]
|
|
1316
|
+
){
|
|
1317
|
+
table_rules[r.rule] = { ...r.no_limits };
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
|
|
1299
1321
|
});
|
|
1300
1322
|
// if(tableName === "various") console.warn(1042, table_rules)
|
|
1301
1323
|
}
|
|
@@ -1315,7 +1337,7 @@ export class PublishParser {
|
|
|
1315
1337
|
|
|
1316
1338
|
if(table_rules[r.rule]){
|
|
1317
1339
|
/* Add implied methods if not falsy */
|
|
1318
|
-
r.methods.map(method => {
|
|
1340
|
+
(r.methods as any).map(method => {
|
|
1319
1341
|
if(table_rules[method] === undefined){
|
|
1320
1342
|
const publishedTable = (table_rules as PublishTable);
|
|
1321
1343
|
if(method === "updateBatch" && !publishedTable.update){
|
|
@@ -1340,11 +1362,17 @@ export class PublishParser {
|
|
|
1340
1362
|
|
|
1341
1363
|
ruleKeys.filter(m => table_rules[m])
|
|
1342
1364
|
.find(method => {
|
|
1343
|
-
let rm = MY_RULES.find(r => r.rule === method || r.methods.includes(method));
|
|
1365
|
+
let rm = MY_RULES.find(r => r.rule === method || (r.methods as any).includes(method));
|
|
1344
1366
|
if(!rm){
|
|
1345
1367
|
throw `Invalid rule in publish.${tableName} -> ${method} \nExpecting any of: ${flat(MY_RULES.map(r => [r.rule, ...r.methods])).join(", ")}`;
|
|
1346
1368
|
}
|
|
1347
1369
|
|
|
1370
|
+
/** Check user privileges */
|
|
1371
|
+
if(!tHandler.tableOrViewInfo.privileges[rm.sqlRule]){
|
|
1372
|
+
delete table_rules[method];
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1348
1376
|
/* Check RULES for invalid params */
|
|
1349
1377
|
/* Methods do not have params -> They use them from rules */
|
|
1350
1378
|
if(method === rm.rule){
|
package/lib/QueryBuilder.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License. See LICENSE in the project root for license information.
|
|
5
5
|
*--------------------------------------------------------------------------------------------*/
|
|
6
6
|
|
|
7
|
-
import { pgp, Filter, LocalParams, isPlainObject, TableHandler, ViewHandler } from "./DboBuilder";
|
|
7
|
+
import { pgp, Filter, LocalParams, isPlainObject, TableHandler, ViewHandler, postgresToTsType } from "./DboBuilder";
|
|
8
8
|
import { TableRule, flat } from "./Prostgles";
|
|
9
9
|
import { SelectParamsBasic as SelectParams, isEmpty, FieldFilter, asName, TextFilter_FullTextSearchFilterKeys, TS_PG_Types, ColumnInfo } from "prostgles-types";
|
|
10
10
|
import { get } from "./utils";
|
|
@@ -698,19 +698,38 @@ export const FUNCTIONS: FunctionSpec[] = [
|
|
|
698
698
|
// res = `CASE WHEN position(${term} IN ${col}) > 0 THEN TRUE ELSE FALSE END`;
|
|
699
699
|
|
|
700
700
|
} else if(returnType === "object" || returnType === "boolean"){
|
|
701
|
+
const hasChars = Boolean(term && /[a-z]/i.test(term));
|
|
702
|
+
const _cols = cols.map(c => {
|
|
703
|
+
const colInfo = allColumns.find(ac => ac.name === c);
|
|
704
|
+
return {
|
|
705
|
+
key: c,
|
|
706
|
+
colInfo
|
|
707
|
+
}
|
|
708
|
+
})
|
|
709
|
+
.filter(c => !c.colInfo || c.colInfo.udt_name !== "bytea")
|
|
710
|
+
.filter(c =>
|
|
711
|
+
/** Exclude numeric columns when the search tern contains a character */
|
|
712
|
+
!hasChars ||
|
|
713
|
+
c.colInfo?.udt_name &&
|
|
714
|
+
postgresToTsType(c.colInfo.udt_name) !== "number"
|
|
715
|
+
);
|
|
716
|
+
if(!_cols.length){
|
|
717
|
+
return (returnType === "boolean")? "FALSE" : "NULL"
|
|
718
|
+
}
|
|
701
719
|
res = `CASE
|
|
702
|
-
${
|
|
703
|
-
|
|
704
|
-
const colNameEscaped = asNameAlias(c, tableAlias)
|
|
720
|
+
${_cols
|
|
721
|
+
.map(c => {
|
|
722
|
+
const colNameEscaped = asNameAlias(c.key, tableAlias)
|
|
705
723
|
let colSelect = `${colNameEscaped}::TEXT`;
|
|
706
|
-
const isTstamp = colInfo?.udt_name.startsWith("timestamp");
|
|
707
|
-
if(isTstamp || colInfo?.udt_name === "date"){
|
|
708
|
-
colSelect = `( CASE WHEN ${colNameEscaped} IS NULL THEN ''
|
|
724
|
+
const isTstamp = c.colInfo?.udt_name.startsWith("timestamp");
|
|
725
|
+
if(isTstamp || c.colInfo?.udt_name === "date"){
|
|
726
|
+
colSelect = `( CASE WHEN ${colNameEscaped} IS NULL THEN ''
|
|
727
|
+
ELSE concat_ws(' ',
|
|
709
728
|
${colNameEscaped}::TEXT,
|
|
710
|
-
${isTstamp? `'TZ' || to_char(${colNameEscaped}, 'OF'), `: ''}
|
|
711
|
-
to_char(${colNameEscaped}, '
|
|
712
|
-
'Q' || to_char(${colNameEscaped}, 'Q'),
|
|
713
|
-
'WK' || to_char(${colNameEscaped}, 'WW')
|
|
729
|
+
${isTstamp? `'TZ' || trim(to_char(${colNameEscaped}, 'OF')), `: ''}
|
|
730
|
+
trim(to_char(${colNameEscaped}, 'Day Month')),
|
|
731
|
+
'Q' || trim(to_char(${colNameEscaped}, 'Q')),
|
|
732
|
+
'WK' || trim(to_char(${colNameEscaped}, 'WW'))
|
|
714
733
|
) END)`
|
|
715
734
|
}
|
|
716
735
|
let colTxt = `COALESCE(${colSelect}, '')`; // position(${term} IN ${colTxt}) > 0
|
|
@@ -723,7 +742,7 @@ export const FUNCTIONS: FunctionSpec[] = [
|
|
|
723
742
|
return `
|
|
724
743
|
WHEN ${colTxt} ${matchCase? "LIKE" : "ILIKE"} ${asValue('%' + rawTerm + '%')}
|
|
725
744
|
THEN json_build_object(
|
|
726
|
-
${asValue(c)},
|
|
745
|
+
${asValue(c.key)},
|
|
727
746
|
${makeTextMatcherArray(
|
|
728
747
|
colTxt,
|
|
729
748
|
term
|
package/package.json
CHANGED
package/tests/client/PID.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
14900
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@types/node": "^14.14.16",
|
|
13
13
|
"@types/socket.io-client": "^1.4.35",
|
|
14
|
-
"prostgles-client": "^1.5.
|
|
14
|
+
"prostgles-client": "^1.5.130",
|
|
15
15
|
"prostgles-types": "^1.5.68",
|
|
16
16
|
"socket.io-client": "^4.2.0"
|
|
17
17
|
}
|
|
@@ -114,22 +114,17 @@
|
|
|
114
114
|
"integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
|
|
115
115
|
},
|
|
116
116
|
"node_modules/prostgles-client": {
|
|
117
|
-
"version": "1.5.
|
|
118
|
-
"resolved": "https://registry.npmjs.org/prostgles-client/-/prostgles-client-1.5.
|
|
119
|
-
"integrity": "sha512-
|
|
117
|
+
"version": "1.5.130",
|
|
118
|
+
"resolved": "https://registry.npmjs.org/prostgles-client/-/prostgles-client-1.5.130.tgz",
|
|
119
|
+
"integrity": "sha512-Dd3b1JY7avcZ2oS5avCQ5KyzLaQTaYDzDE/q9bIiY7R5JJsesGKoRsqJISuNWyGYeVCY93n+r/EN88v0Jsj48A==",
|
|
120
120
|
"dependencies": {
|
|
121
|
-
"prostgles-types": "^1.5.
|
|
121
|
+
"prostgles-types": "^1.5.121"
|
|
122
122
|
}
|
|
123
123
|
},
|
|
124
|
-
"node_modules/prostgles-client/node_modules/prostgles-types": {
|
|
125
|
-
"version": "1.5.120",
|
|
126
|
-
"resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-1.5.120.tgz",
|
|
127
|
-
"integrity": "sha512-dWrXMJFhYmTKsiIBzYHTsCKXN6GoJGJe/lTohnkg9+drAhXbJvUrJ5nZ8LwYgkzG+wbWBwW82KIBGK6Zg4OqLw=="
|
|
128
|
-
},
|
|
129
124
|
"node_modules/prostgles-types": {
|
|
130
|
-
"version": "1.5.
|
|
131
|
-
"resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-1.5.
|
|
132
|
-
"integrity": "sha512-
|
|
125
|
+
"version": "1.5.121",
|
|
126
|
+
"resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-1.5.121.tgz",
|
|
127
|
+
"integrity": "sha512-9fzF/3tISjv1P6B0uV2ubZRKqblUvDG8K7+9INdcR8di2UOVD2vONgCgvFe7ZH12FyUC5q1OM1PUm41dgo9cqQ=="
|
|
133
128
|
},
|
|
134
129
|
"node_modules/socket.io-client": {
|
|
135
130
|
"version": "4.2.0",
|
|
@@ -280,24 +275,17 @@
|
|
|
280
275
|
"integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow=="
|
|
281
276
|
},
|
|
282
277
|
"prostgles-client": {
|
|
283
|
-
"version": "1.5.
|
|
284
|
-
"resolved": "https://registry.npmjs.org/prostgles-client/-/prostgles-client-1.5.
|
|
285
|
-
"integrity": "sha512-
|
|
278
|
+
"version": "1.5.130",
|
|
279
|
+
"resolved": "https://registry.npmjs.org/prostgles-client/-/prostgles-client-1.5.130.tgz",
|
|
280
|
+
"integrity": "sha512-Dd3b1JY7avcZ2oS5avCQ5KyzLaQTaYDzDE/q9bIiY7R5JJsesGKoRsqJISuNWyGYeVCY93n+r/EN88v0Jsj48A==",
|
|
286
281
|
"requires": {
|
|
287
|
-
"prostgles-types": "^1.5.
|
|
288
|
-
},
|
|
289
|
-
"dependencies": {
|
|
290
|
-
"prostgles-types": {
|
|
291
|
-
"version": "1.5.120",
|
|
292
|
-
"resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-1.5.120.tgz",
|
|
293
|
-
"integrity": "sha512-dWrXMJFhYmTKsiIBzYHTsCKXN6GoJGJe/lTohnkg9+drAhXbJvUrJ5nZ8LwYgkzG+wbWBwW82KIBGK6Zg4OqLw=="
|
|
294
|
-
}
|
|
282
|
+
"prostgles-types": "^1.5.121"
|
|
295
283
|
}
|
|
296
284
|
},
|
|
297
285
|
"prostgles-types": {
|
|
298
|
-
"version": "1.5.
|
|
299
|
-
"resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-1.5.
|
|
300
|
-
"integrity": "sha512-
|
|
286
|
+
"version": "1.5.121",
|
|
287
|
+
"resolved": "https://registry.npmjs.org/prostgles-types/-/prostgles-types-1.5.121.tgz",
|
|
288
|
+
"integrity": "sha512-9fzF/3tISjv1P6B0uV2ubZRKqblUvDG8K7+9INdcR8di2UOVD2vONgCgvFe7ZH12FyUC5q1OM1PUm41dgo9cqQ=="
|
|
301
289
|
},
|
|
302
290
|
"socket.io-client": {
|
|
303
291
|
"version": "4.2.0",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|