prostgles-server 4.2.448 → 4.2.450

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.
Files changed (77) hide show
  1. package/dist/DboBuilder/DboBuilderTypes.d.ts +11 -7
  2. package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
  3. package/dist/DboBuilder/DboBuilderTypes.js.map +1 -1
  4. package/dist/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.js +1 -1
  5. package/dist/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.js.map +1 -1
  6. package/dist/DboBuilder/QueryBuilder/Functions/Functions.d.ts +1 -1
  7. package/dist/DboBuilder/QueryBuilder/Functions/Functions.d.ts.map +1 -1
  8. package/dist/DboBuilder/QueryBuilder/Functions/Functions.js +31 -31
  9. package/dist/DboBuilder/QueryBuilder/Functions/Functions.js.map +1 -1
  10. package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts +5 -5
  11. package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts.map +1 -1
  12. package/dist/DboBuilder/QueryBuilder/QueryBuilder.js +1 -1
  13. package/dist/DboBuilder/QueryBuilder/QueryBuilder.js.map +1 -1
  14. package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts +2 -1
  15. package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts.map +1 -1
  16. package/dist/DboBuilder/QueryBuilder/getJoinQuery.js +12 -10
  17. package/dist/DboBuilder/QueryBuilder/getJoinQuery.js.map +1 -1
  18. package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts +2 -2
  19. package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts.map +1 -1
  20. package/dist/DboBuilder/QueryBuilder/getNewQuery.js +2 -2
  21. package/dist/DboBuilder/QueryBuilder/getNewQuery.js.map +1 -1
  22. package/dist/DboBuilder/QueryBuilder/getSelectQuery.d.ts.map +1 -1
  23. package/dist/DboBuilder/QueryBuilder/getSelectQuery.js +6 -12
  24. package/dist/DboBuilder/QueryBuilder/getSelectQuery.js.map +1 -1
  25. package/dist/DboBuilder/TableRules/getValidatedRules.d.ts.map +1 -1
  26. package/dist/DboBuilder/TableRules/getValidatedRules.js +33 -35
  27. package/dist/DboBuilder/TableRules/getValidatedRules.js.map +1 -1
  28. package/dist/DboBuilder/ViewHandler/parseComplexFilter.d.ts +2 -2
  29. package/dist/DboBuilder/ViewHandler/parseComplexFilter.d.ts.map +1 -1
  30. package/dist/DboBuilder/ViewHandler/parseComplexFilter.js +3 -3
  31. package/dist/DboBuilder/ViewHandler/parseComplexFilter.js.map +1 -1
  32. package/dist/DboBuilder/ViewHandler/prepareSortItems.d.ts +2 -2
  33. package/dist/DboBuilder/ViewHandler/prepareSortItems.d.ts.map +1 -1
  34. package/dist/DboBuilder/ViewHandler/prepareSortItems.js +6 -4
  35. package/dist/DboBuilder/ViewHandler/prepareSortItems.js.map +1 -1
  36. package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts +2 -2
  37. package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts.map +1 -1
  38. package/dist/DboBuilder/getCondition.d.ts +2 -2
  39. package/dist/DboBuilder/getCondition.d.ts.map +1 -1
  40. package/dist/DboBuilder/getCondition.js +6 -6
  41. package/dist/DboBuilder/getCondition.js.map +1 -1
  42. package/dist/DboBuilder/getSubscribeRelatedTables.js +1 -1
  43. package/dist/DboBuilder/getSubscribeRelatedTables.js.map +1 -1
  44. package/dist/Filtering.d.ts +1 -1
  45. package/dist/Filtering.d.ts.map +1 -1
  46. package/dist/Filtering.js +3 -3
  47. package/dist/Filtering.js.map +1 -1
  48. package/dist/PublishParser/PublishParser.d.ts +1 -0
  49. package/dist/PublishParser/PublishParser.d.ts.map +1 -1
  50. package/dist/PublishParser/PublishParser.js +52 -2
  51. package/dist/PublishParser/PublishParser.js.map +1 -1
  52. package/dist/PublishParser/getSchemaFromPublish.js +1 -1
  53. package/dist/PublishParser/getSchemaFromPublish.js.map +1 -1
  54. package/dist/PublishParser/getTableRulesWithoutFileTable.js +1 -1
  55. package/dist/PublishParser/getTableRulesWithoutFileTable.js.map +1 -1
  56. package/dist/PublishParser/publishTypesAndUtils.d.ts +14 -1
  57. package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
  58. package/eslint.config.mjs +2 -2
  59. package/lib/DboBuilder/DboBuilderTypes.ts +12 -7
  60. package/lib/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.ts +1 -1
  61. package/lib/DboBuilder/QueryBuilder/Functions/Functions.ts +66 -62
  62. package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +6 -6
  63. package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +16 -12
  64. package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +5 -5
  65. package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +11 -17
  66. package/lib/DboBuilder/TableRules/getValidatedRules.ts +39 -40
  67. package/lib/DboBuilder/ViewHandler/parseComplexFilter.ts +4 -4
  68. package/lib/DboBuilder/ViewHandler/prepareSortItems.ts +14 -12
  69. package/lib/DboBuilder/ViewHandler/prepareWhere.ts +6 -6
  70. package/lib/DboBuilder/getCondition.ts +8 -12
  71. package/lib/DboBuilder/getSubscribeRelatedTables.ts +1 -1
  72. package/lib/Filtering.ts +11 -13
  73. package/lib/PublishParser/PublishParser.ts +62 -5
  74. package/lib/PublishParser/getSchemaFromPublish.ts +1 -1
  75. package/lib/PublishParser/getTableRulesWithoutFileTable.ts +2 -2
  76. package/lib/PublishParser/publishTypesAndUtils.ts +23 -1
  77. package/package.json +18 -18
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
- tableAlias: string | undefined;
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, tableAlias, allowedColumnNames } = args;
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
- tableAlias,
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(tableAlias);
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);
@@ -1,4 +1,4 @@
1
- import { getKeys, includes, pickKeys } from "prostgles-types";
1
+ import { getObjectEntries, includes, isDefined, pickKeys } from "prostgles-types";
2
2
  import { getClientRequestIPsInfo } from "../Auth/AuthHandler";
3
3
  import type { AuthClientRequest, AuthResultWithSID } from "../Auth/AuthTypes";
4
4
  import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
@@ -212,10 +212,61 @@ export class PublishParser {
212
212
  }
213
213
  const tableScope = scope.tables?.[args.tableName];
214
214
  if (!tableScope) return;
215
- return pickKeys(
216
- tableRules,
217
- getKeys(tableScope).filter((k) => tableScope[k]),
218
- );
215
+
216
+ const tableHandler = this.dbo[args.tableName];
217
+ if (!tableHandler) {
218
+ throw "INTERNAL ERROR: table handler not found for " + args.tableName;
219
+ }
220
+ const validatedTableRules = tableHandler.getValidatedRules?.(tableRules);
221
+ if (!validatedTableRules) {
222
+ throw "INTERNAL ERROR: getValidatedRules is missing for " + args.tableName;
223
+ }
224
+
225
+ /** Make sure the scope does not allow things outside the validatedTableRules */
226
+ const result = fromEntries(
227
+ getObjectEntries(tableScope)
228
+ .map(([ruleName, ruleScope]) => {
229
+ if (!ruleScope) return undefined;
230
+ const rule = tableRules[ruleName];
231
+ const validatedRule = validatedTableRules[ruleName];
232
+ if (!validatedRule || !rule) {
233
+ throw `Invalid scope: ${args.tableName}.${ruleName}. The publish does not allow this command.`;
234
+ }
235
+ if (ruleScope === true) {
236
+ return [ruleName, validatedRule] as const;
237
+ }
238
+ const scopeFields = tableHandler.parseFieldFilter!(ruleScope.fields);
239
+ const scopeForcedFilter =
240
+ "forcedFilter" in ruleScope ? ruleScope.forcedFilter : undefined;
241
+
242
+ const ruleFields = "fields" in validatedRule ? validatedRule.fields : undefined;
243
+ for (const field of scopeFields) {
244
+ if (!ruleFields?.includes(field)) {
245
+ throw `Invalid scope: ${args.tableName}.${ruleName}. The field "${field}" is not allowed to be selected according to the publish rules.`;
246
+ }
247
+ }
248
+ if (!scopeFields.length) {
249
+ throw `Invalid scope: ${args.tableName}.${ruleName}. At least one field must be selected.`;
250
+ }
251
+ const ruleForcedFilter =
252
+ "forcedFilter" in validatedRule ? validatedRule.forcedFilter : undefined;
253
+ const combinedForcedFilter =
254
+ scopeForcedFilter && ruleForcedFilter ?
255
+ { $and: [scopeForcedFilter, ruleForcedFilter] }
256
+ : scopeForcedFilter || ruleForcedFilter;
257
+
258
+ return [
259
+ ruleName,
260
+ {
261
+ ...rule,
262
+ fields: fromEntries(scopeFields.map((field) => [field, 1] as const)),
263
+ ...(scopeForcedFilter ? { forcedFilter: combinedForcedFilter } : {}),
264
+ } as any,
265
+ ] as const;
266
+ })
267
+ .filter(isDefined),
268
+ ) as ParsedTableRule;
269
+ return result;
219
270
  };
220
271
  if (this.dbo[args.tableName]?.is_media) {
221
272
  const { rules: fileTableRules } = await getFileTableRules.bind(this)(
@@ -256,3 +307,9 @@ function applyParamsIfFunc<T>(
256
307
  //@ts-ignore
257
308
  return maybeFunc;
258
309
  }
310
+
311
+ export const fromEntries = <K extends string | number | symbol, V>(
312
+ entries: readonly (readonly [K, V])[],
313
+ ): Record<K, V> => {
314
+ return Object.fromEntries(entries) as Record<K, V>;
315
+ };
@@ -144,7 +144,7 @@ export async function getSchemaFromPublish(
144
144
 
145
145
  throw {
146
146
  ...getErrorAsObject(e),
147
- publish_path: `publish.${tableName}.${method}: \n -> ${e}`,
147
+ publish_path: `publish.${tableName}.${method}`,
148
148
  };
149
149
  }
150
150
  }
@@ -1,4 +1,4 @@
1
- import { getKeys, isObject } from "prostgles-types";
1
+ import { getKeys, includes, isObject } from "prostgles-types";
2
2
  import type { AuthResultWithSID } from "../Auth/AuthTypes";
3
3
  import type { TableHandler } from "../DboBuilder/TableHandler/TableHandler";
4
4
  import type { ViewHandler } from "../DboBuilder/ViewHandler/ViewHandler";
@@ -73,7 +73,7 @@ export async function getTableRulesWithoutFileTable(
73
73
  });
74
74
 
75
75
  /* All methods allowed. Add no limits for table rules */
76
- if ([true, "*"].includes(rawTableRule as any)) {
76
+ if (includes([true, "*"], rawTableRule)) {
77
77
  parsedTableRule = {};
78
78
  MY_RULES.filter((r) => r.no_limits).forEach((r) => {
79
79
  parsedTableRule[r.rule] = { ...(r.no_limits as object) } as any;
@@ -506,7 +506,29 @@ export type DbTableInfo = {
506
506
  export type PermissionScope = {
507
507
  sql?: "commited" | "rolledback";
508
508
  /** TODO: this should match publish types */
509
- tables?: Record<string, Partial<Record<"select" | "update" | "delete" | "insert", boolean>>>;
509
+ tables?: Record<
510
+ string,
511
+ Partial<{
512
+ select:
513
+ | true
514
+ | {
515
+ fields: FieldFilter;
516
+ forcedFilter: AnyObject;
517
+ };
518
+ insert:
519
+ | true
520
+ | {
521
+ fields: FieldFilter;
522
+ };
523
+ update:
524
+ | true
525
+ | {
526
+ fields: FieldFilter;
527
+ forcedFilter: AnyObject;
528
+ };
529
+ delete: true;
530
+ }>
531
+ >;
510
532
  methods?: Record<string, boolean>;
511
533
  };
512
534
  export type PublishParams<S = void, SUser extends SessionUser = SessionUser> = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prostgles-server",
3
- "version": "4.2.448",
3
+ "version": "4.2.450",
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.985.0",
42
- "@aws-sdk/credential-provider-node": "^3.972.4",
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.3",
44
+ "@types/passport-facebook": "^3.0.4",
45
45
  "@types/passport-github2": "^1.2.9",
46
- "@types/passport-google-oauth20": "^2.0.16",
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.5.0",
50
- "nodemailer": "^7.0.12",
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.0",
60
- "prostgles-types": "^4.0.209"
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.21",
64
+ "@types/express": "^4.17.25",
65
65
  "@types/json-schema": "^7.0.15",
66
- "@types/node": "^22.10.2",
67
- "@types/nodemailer": "^6.4.17",
68
- "@types/pg": "^8.15.1",
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.4",
70
+ "@types/sharp": "^0.30.5",
71
71
  "eslint": "^9.39.2",
72
72
  "eslint-plugin-security": "^3.0.1",
73
- "prettier": "^3.4.2",
74
- "socket.io": "^4.8.1",
75
- "typescript": "^5.3.3",
76
- "typescript-eslint": "^8.38.0"
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
  }