prostgles-server 4.2.157 → 4.2.159

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 (159) hide show
  1. package/dist/Auth/AuthHandler.js +2 -2
  2. package/dist/Auth/AuthHandler.js.map +1 -1
  3. package/dist/Auth/AuthTypes.d.ts +4 -8
  4. package/dist/Auth/AuthTypes.d.ts.map +1 -1
  5. package/dist/Auth/setAuthProviders.d.ts +1 -1
  6. package/dist/Auth/setAuthProviders.d.ts.map +1 -1
  7. package/dist/Auth/setAuthProviders.js +6 -7
  8. package/dist/Auth/setAuthProviders.js.map +1 -1
  9. package/dist/Auth/setEmailProvider.d.ts +1 -1
  10. package/dist/Auth/setEmailProvider.d.ts.map +1 -1
  11. package/dist/Auth/setEmailProvider.js +22 -2
  12. package/dist/Auth/setEmailProvider.js.map +1 -1
  13. package/dist/Auth/setupAuthRoutes.js +1 -1
  14. package/dist/Auth/setupAuthRoutes.js.map +1 -1
  15. package/dist/Prostgles.d.ts +1 -0
  16. package/dist/Prostgles.d.ts.map +1 -1
  17. package/dist/Prostgles.js +6 -0
  18. package/dist/Prostgles.js.map +1 -1
  19. package/dist/initProstgles.d.ts.map +1 -1
  20. package/dist/initProstgles.js +2 -6
  21. package/dist/initProstgles.js.map +1 -1
  22. package/package.json +1 -1
  23. package/lib/Auth/AuthHandler.ts +0 -436
  24. package/lib/Auth/AuthTypes.ts +0 -285
  25. package/lib/Auth/getSafeReturnURL.ts +0 -35
  26. package/lib/Auth/sendEmail.ts +0 -83
  27. package/lib/Auth/setAuthProviders.ts +0 -129
  28. package/lib/Auth/setEmailProvider.ts +0 -63
  29. package/lib/Auth/setupAuthRoutes.ts +0 -161
  30. package/lib/DBEventsManager.ts +0 -178
  31. package/lib/DBSchemaBuilder.ts +0 -225
  32. package/lib/DboBuilder/DboBuilder.ts +0 -319
  33. package/lib/DboBuilder/DboBuilderTypes.ts +0 -361
  34. package/lib/DboBuilder/QueryBuilder/Functions.ts +0 -1153
  35. package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +0 -288
  36. package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +0 -263
  37. package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +0 -271
  38. package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +0 -136
  39. package/lib/DboBuilder/QueryBuilder/prepareHaving.ts +0 -22
  40. package/lib/DboBuilder/QueryStreamer.ts +0 -250
  41. package/lib/DboBuilder/TableHandler/DataValidator.ts +0 -428
  42. package/lib/DboBuilder/TableHandler/TableHandler.ts +0 -205
  43. package/lib/DboBuilder/TableHandler/delete.ts +0 -115
  44. package/lib/DboBuilder/TableHandler/insert.ts +0 -183
  45. package/lib/DboBuilder/TableHandler/insertTest.ts +0 -78
  46. package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +0 -62
  47. package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +0 -134
  48. package/lib/DboBuilder/TableHandler/update.ts +0 -126
  49. package/lib/DboBuilder/TableHandler/updateBatch.ts +0 -49
  50. package/lib/DboBuilder/TableHandler/updateFile.ts +0 -48
  51. package/lib/DboBuilder/TableHandler/upsert.ts +0 -34
  52. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +0 -393
  53. package/lib/DboBuilder/ViewHandler/count.ts +0 -38
  54. package/lib/DboBuilder/ViewHandler/find.ts +0 -153
  55. package/lib/DboBuilder/ViewHandler/getExistsCondition.ts +0 -73
  56. package/lib/DboBuilder/ViewHandler/getExistsFilters.ts +0 -74
  57. package/lib/DboBuilder/ViewHandler/getInfo.ts +0 -32
  58. package/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts +0 -84
  59. package/lib/DboBuilder/ViewHandler/parseComplexFilter.ts +0 -96
  60. package/lib/DboBuilder/ViewHandler/parseFieldFilter.ts +0 -105
  61. package/lib/DboBuilder/ViewHandler/parseJoinPath.ts +0 -208
  62. package/lib/DboBuilder/ViewHandler/prepareSortItems.ts +0 -163
  63. package/lib/DboBuilder/ViewHandler/prepareWhere.ts +0 -90
  64. package/lib/DboBuilder/ViewHandler/size.ts +0 -37
  65. package/lib/DboBuilder/ViewHandler/subscribe.ts +0 -118
  66. package/lib/DboBuilder/ViewHandler/validateViewRules.ts +0 -70
  67. package/lib/DboBuilder/dboBuilderUtils.ts +0 -222
  68. package/lib/DboBuilder/getColumns.ts +0 -114
  69. package/lib/DboBuilder/getCondition.ts +0 -201
  70. package/lib/DboBuilder/getSubscribeRelatedTables.ts +0 -190
  71. package/lib/DboBuilder/getTablesForSchemaPostgresSQL.ts +0 -426
  72. package/lib/DboBuilder/insertNestedRecords.ts +0 -355
  73. package/lib/DboBuilder/parseUpdateRules.ts +0 -187
  74. package/lib/DboBuilder/prepareShortestJoinPaths.ts +0 -186
  75. package/lib/DboBuilder/runSQL.ts +0 -182
  76. package/lib/DboBuilder/runTransaction.ts +0 -50
  77. package/lib/DboBuilder/sqlErrCodeToMsg.ts +0 -254
  78. package/lib/DboBuilder/uploadFile.ts +0 -69
  79. package/lib/Event_Trigger_Tags.ts +0 -118
  80. package/lib/FileManager/FileManager.ts +0 -358
  81. package/lib/FileManager/getValidatedFileType.ts +0 -69
  82. package/lib/FileManager/initFileManager.ts +0 -187
  83. package/lib/FileManager/upload.ts +0 -62
  84. package/lib/FileManager/uploadStream.ts +0 -79
  85. package/lib/Filtering.ts +0 -463
  86. package/lib/JSONBValidation/validate_jsonb_schema_sql.ts +0 -502
  87. package/lib/JSONBValidation/validation.ts +0 -143
  88. package/lib/Logging.ts +0 -127
  89. package/lib/PostgresNotifListenManager.ts +0 -143
  90. package/lib/Prostgles.ts +0 -479
  91. package/lib/ProstglesTypes.ts +0 -196
  92. package/lib/PubSubManager/PubSubManager.ts +0 -609
  93. package/lib/PubSubManager/addSub.ts +0 -138
  94. package/lib/PubSubManager/addSync.ts +0 -141
  95. package/lib/PubSubManager/getCreatePubSubManagerError.ts +0 -72
  96. package/lib/PubSubManager/getPubSubManagerInitQuery.ts +0 -662
  97. package/lib/PubSubManager/initPubSubManager.ts +0 -79
  98. package/lib/PubSubManager/notifListener.ts +0 -173
  99. package/lib/PubSubManager/orphanTriggerCheck.ts +0 -70
  100. package/lib/PubSubManager/pushSubData.ts +0 -55
  101. package/lib/PublishParser/PublishParser.ts +0 -162
  102. package/lib/PublishParser/getFileTableRules.ts +0 -124
  103. package/lib/PublishParser/getSchemaFromPublish.ts +0 -141
  104. package/lib/PublishParser/getTableRulesWithoutFileTable.ts +0 -177
  105. package/lib/PublishParser/publishTypesAndUtils.ts +0 -399
  106. package/lib/RestApi.ts +0 -127
  107. package/lib/SchemaWatch/SchemaWatch.ts +0 -90
  108. package/lib/SchemaWatch/createSchemaWatchEventTrigger.ts +0 -3
  109. package/lib/SchemaWatch/getValidatedWatchSchemaType.ts +0 -45
  110. package/lib/SchemaWatch/getWatchSchemaTagList.ts +0 -27
  111. package/lib/SyncReplication.ts +0 -557
  112. package/lib/TableConfig/TableConfig.ts +0 -468
  113. package/lib/TableConfig/getColumnDefinitionQuery.ts +0 -111
  114. package/lib/TableConfig/getConstraintDefinitionQueries.ts +0 -95
  115. package/lib/TableConfig/getFutureTableSchema.ts +0 -64
  116. package/lib/TableConfig/getPGIndexes.ts +0 -53
  117. package/lib/TableConfig/getTableColumnQueries.ts +0 -129
  118. package/lib/TableConfig/initTableConfig.ts +0 -326
  119. package/lib/index.ts +0 -13
  120. package/lib/initProstgles.ts +0 -322
  121. package/lib/onSocketConnected.ts +0 -102
  122. package/lib/runClientRequest.ts +0 -129
  123. package/lib/shortestPath.ts +0 -122
  124. package/lib/typeTests/DBoGenerated.d.ts +0 -320
  125. package/lib/typeTests/dboTypeCheck.ts +0 -81
  126. package/lib/utils.ts +0 -15
  127. package/tests/client/hooks.spec.ts +0 -205
  128. package/tests/client/index.ts +0 -139
  129. package/tests/client/package-lock.json +0 -637
  130. package/tests/client/package.json +0 -26
  131. package/tests/client/renderReactHook.ts +0 -177
  132. package/tests/client/tsconfig.json +0 -15
  133. package/tests/client/useProstgles.spec.ts +0 -120
  134. package/tests/clientFileTests.spec.ts +0 -102
  135. package/tests/clientOnlyQueries.spec.ts +0 -667
  136. package/tests/clientRestApi.spec.ts +0 -82
  137. package/tests/config_test/DBoGenerated.d.ts +0 -407
  138. package/tests/config_test/index.html +0 -109
  139. package/tests/config_test/index.js +0 -86
  140. package/tests/config_test/index.js.map +0 -1
  141. package/tests/config_test/index.ts +0 -91
  142. package/tests/config_test/init.sql +0 -48
  143. package/tests/config_test/package.json +0 -29
  144. package/tests/config_test/tsconfig.json +0 -23
  145. package/tests/config_testDBoGenerated.d.ts +0 -407
  146. package/tests/isomorphicQueries.spec.ts +0 -1493
  147. package/tests/server/DBoGenerated.d.ts +0 -537
  148. package/tests/server/index.html +0 -73
  149. package/tests/server/index.ts +0 -289
  150. package/tests/server/init.sql +0 -224
  151. package/tests/server/package-lock.json +0 -2164
  152. package/tests/server/package.json +0 -25
  153. package/tests/server/publishTypeCheck.ts +0 -136
  154. package/tests/server/server.ts +0 -35
  155. package/tests/server/testPublish.ts +0 -147
  156. package/tests/server/testTableConfig.ts +0 -156
  157. package/tests/server/tsconfig.json +0 -22
  158. package/tests/serverOnlyQueries.spec.ts +0 -32
  159. package/tests/test.sh +0 -20
@@ -1,38 +0,0 @@
1
- import { SelectParams } from "prostgles-types";
2
- import { TableRule } from "../../PublishParser/publishTypesAndUtils";
3
- import { Filter, LocalParams } from "../DboBuilder";
4
- import { getErrorAsObject, getSerializedClientErrorFromPGError, withUserRLS } from "../dboBuilderUtils";
5
- import { ViewHandler } from "./ViewHandler";
6
-
7
- export async function count(this: ViewHandler, _filter?: Filter, selectParams?: SelectParams, _param3_unused?: undefined, table_rules?: TableRule, localParams?: LocalParams): Promise<number> {
8
- const filter = _filter || {};
9
- const { limit: _limit, ...selectParamsWithoutLimit } = selectParams ?? {};
10
- const start = Date.now();
11
- try {
12
- const result = await this.find(filter, { select: selectParamsWithoutLimit?.select ?? "", limit: 0 }, undefined, table_rules, localParams)
13
- .then(async _allowed => {
14
- const findQuery = await this.find(
15
- filter,
16
- selectParamsWithoutLimit,
17
- undefined,
18
- table_rules,
19
- { ...localParams, returnQuery: "noRLS", bypassLimit: true }
20
- ) as unknown as string;
21
- const query = [
22
- withUserRLS(localParams, ""),
23
- "SELECT COUNT(*)",
24
- "FROM (",
25
- findQuery,
26
- ") t"
27
- ].join("\n");
28
- const handler = this.tx?.t ?? this.db;
29
- return handler.one(query).then(({ count }) => +count);
30
- });
31
-
32
- await this._log({ command: "count", localParams, data: { filter }, duration: Date.now() - start });
33
- return result;
34
- } catch (e) {
35
- await this._log({ command: "count", localParams, data: { filter }, duration: Date.now() - start, error: getErrorAsObject(e) });
36
- throw getSerializedClientErrorFromPGError(e, { type: "tableMethod", localParams, view: this });
37
- }
38
- }
@@ -1,153 +0,0 @@
1
-
2
- import { SelectParams, isObject } from "prostgles-types";
3
- import { TableRule } from "../../PublishParser/PublishParser";
4
- import { Filter, LocalParams, getClientErrorFromPGError, getErrorAsObject, getSerializedClientErrorFromPGError, withUserRLS } from "../DboBuilder";
5
- import { getNewQuery } from "../QueryBuilder/getNewQuery";
6
- import { getSelectQuery } from "../QueryBuilder/getSelectQuery";
7
- import { NewQuery } from "../QueryBuilder/QueryBuilder";
8
- import { canRunSQL } from "../runSQL";
9
- import { TableHandler } from "../TableHandler/TableHandler";
10
- import { ViewHandler } from "./ViewHandler";
11
-
12
- export const find = async function(this: ViewHandler, filter?: Filter, selectParams?: SelectParams, _?: undefined, tableRules?: TableRule, localParams?: LocalParams): Promise<any[]> {
13
- const start = Date.now();
14
- const command = selectParams?.limit === 1 && selectParams?.returnType === "row"? "findOne" : "find";
15
- try {
16
- filter = filter || {};
17
- const allowedReturnTypes = Object.keys({
18
- row: 1, statement: 1, value: 1, values: 1,
19
- "statement-no-rls": 1, "statement-where": 1,
20
- } satisfies Record<Required<SelectParams>["returnType"], 1>);
21
-
22
- const { returnType } = selectParams || {};
23
- if (returnType && !allowedReturnTypes.includes(returnType)) {
24
- throw `returnType (${returnType}) can only be ${allowedReturnTypes.join(" OR ")}`
25
- }
26
-
27
- const { testRule = false } = localParams || {};
28
-
29
- if (testRule) return [];
30
- if (selectParams) {
31
- const validParamNames = Object.keys({
32
- "select": 1, "orderBy": 1, "offset": 1, "limit": 1,
33
- "returnType": 1, "groupBy": 1, "having": 1
34
- } satisfies Record<keyof SelectParams, 1>);
35
-
36
- const invalidParams = Object.keys(selectParams).filter(k => !validParamNames.includes(k as any));
37
- if (invalidParams && invalidParams.length) throw "Invalid params: " + invalidParams.join(", ") + " \n Expecting: " + validParamNames.join(", ");
38
- }
39
-
40
- /* Validate publish */
41
- if (tableRules) {
42
-
43
- if (!tableRules.select) throw "select rules missing for " + this.name;
44
- const fields = tableRules.select.fields;
45
- const maxLimit = tableRules.select.maxLimit;
46
-
47
- if (<any>tableRules.select !== "*" && typeof tableRules.select !== "boolean" && !isObject(tableRules.select)) {
48
- throw `\nInvalid publish.${this.name}.select\nExpecting any of: "*" | { fields: "*" } | true | false`;
49
- }
50
- if (!fields) {
51
- throw ` invalid ${this.name}.select rule -> fields (required) setting missing.\nExpecting any of: "*" | { col_name: false } | { col1: true, col2: true }`;
52
- }
53
- if (maxLimit && !Number.isInteger(maxLimit)) {
54
- throw ` invalid publish.${this.name}.select.maxLimit -> expecting integer but got ` + maxLimit;
55
- }
56
- }
57
-
58
- const _selectParams = selectParams ?? {}
59
- const selectParamsLimitCheck = localParams?.bypassLimit && !Number.isFinite(_selectParams.limit)? { ..._selectParams, limit: null } : { limit: 1000, ..._selectParams }
60
- const newQuery = await getNewQuery(
61
- this,
62
- filter,
63
- selectParamsLimitCheck,
64
- _,
65
- tableRules,
66
- localParams,
67
- );
68
-
69
- const queryWithoutRLS = getSelectQuery(
70
- this,
71
- newQuery,
72
- undefined,
73
- !!selectParamsLimitCheck?.groupBy
74
- );
75
-
76
- const queryWithRLS = withUserRLS(localParams, queryWithoutRLS);
77
- if (testRule) {
78
- try {
79
- await this.db.any(withUserRLS(localParams, "EXPLAIN " + queryWithRLS));
80
- return [];
81
- } catch (e) {
82
- console.error(e);
83
- throw `Internal error: publish config is not valid for publish.${this.name}.select `
84
- }
85
- }
86
-
87
- /** Used for subscribe */
88
- if(localParams?.returnNewQuery) return (newQuery as unknown as any);
89
- if (localParams?.returnQuery) {
90
- if(localParams?.returnQuery === "where-condition"){
91
- return newQuery.whereOpts.condition as any;
92
- }
93
- return ((localParams?.returnQuery === "noRLS"? queryWithoutRLS : queryWithRLS) as unknown as any[]);
94
- }
95
-
96
- const result = await runQueryReturnType({
97
- queryWithoutRLS,
98
- queryWithRLS,
99
- returnType,
100
- handler: this,
101
- localParams,
102
- newQuery,
103
- });
104
-
105
- await this._log({ command, localParams, data: { filter, selectParams }, duration: Date.now() - start });
106
- return result;
107
- } catch (e) {
108
- this._log({ command, localParams, data: { filter, selectParams }, duration: Date.now() - start, error: getErrorAsObject(e) });
109
- throw getSerializedClientErrorFromPGError(e, { type: "tableMethod", localParams, view: this });
110
- }
111
- }
112
-
113
- type RunQueryReturnTypeArgs = {
114
- queryWithRLS: string;
115
- queryWithoutRLS: string;
116
- returnType: SelectParams["returnType"];
117
- handler: ViewHandler | TableHandler;
118
- localParams: LocalParams | undefined;
119
- newQuery: NewQuery | undefined;
120
- };
121
-
122
- export const runQueryReturnType = async ({ newQuery, handler, localParams, queryWithRLS, queryWithoutRLS, returnType,}: RunQueryReturnTypeArgs) => {
123
-
124
- const query = queryWithRLS;
125
- const sqlTypes = ["statement", "statement-no-rls", "statement-where"];
126
- if(!returnType || returnType === "values"){
127
-
128
- return handler.dbHandler.any(query).then(data => {
129
- if (returnType === "values") {
130
- return data.map(d => Object.values(d)[0]);
131
- }
132
- return data;
133
- }).catch(err => getClientErrorFromPGError(err, { type: "tableMethod", localParams, view: handler, }));
134
-
135
- } else if (sqlTypes.some(v => v === returnType)) {
136
- if (!(await canRunSQL(handler.dboBuilder.prostgles, localParams))) {
137
- throw `Not allowed: {returnType: ${JSON.stringify(returnType)}} requires execute sql privileges `
138
- }
139
- if(returnType === "statement-no-rls"){
140
- return queryWithoutRLS as any;
141
- }
142
- if(returnType === "statement-where"){
143
- if(!newQuery) throw `returnType ${returnType} not possible for this command type`;
144
- return newQuery.whereOpts.condition as any;
145
- }
146
- return query as unknown as any[];
147
-
148
- } else if (["row", "value"].includes(returnType)) {
149
- return handler.dbHandler.oneOrNone(query).then(data => {
150
- return (data && returnType === "value") ? Object.values(data)[0] : data;
151
- }).catch(err => getClientErrorFromPGError(err, { type: "tableMethod", localParams, view: handler, }));
152
- }
153
- }
@@ -1,73 +0,0 @@
1
- import { AnyObject, EXISTS_KEY, EXISTS_KEYS, FieldFilter, asName } from "prostgles-types";
2
- import { LocalParams, ExistsFilterConfig } from "../DboBuilder";
3
- import { ViewHandler } from "./ViewHandler";
4
- import { TableRule } from "../../PublishParser/PublishParser";
5
- import { TableHandler } from "../TableHandler/TableHandler";
6
- import { getTableJoinQuery } from "./getTableJoinQuery";
7
-
8
-
9
- export async function getExistsCondition(this: ViewHandler, eConfig: ExistsFilterConfig, localParams: LocalParams | undefined): Promise<string> {
10
-
11
- const thisTable = this.name;
12
- const isNotExists = ["$notExists", "$notExistsJoined"].includes(eConfig.existType);
13
-
14
- const { targetTableFilter } = eConfig;
15
-
16
- /* Nested $exists is not allowed */
17
- if (targetTableFilter && Object.keys(targetTableFilter).find(fk => EXISTS_KEYS.includes(fk as EXISTS_KEY))) {
18
- throw { stack: ["prepareExistCondition()"], message: "Nested exists dissallowed" };
19
- }
20
-
21
- let t2Rules: TableRule | undefined = undefined,
22
- forcedFilter: AnyObject | undefined,
23
- filterFields: FieldFilter | undefined,
24
- tableAlias;
25
-
26
- /* Check if allowed to view data - forcedFilters will bypass this check through isForcedFilterBypass */
27
- if (localParams?.isRemoteRequest && !localParams?.socket && !localParams?.httpReq) {
28
- throw "Unexpected: localParams isRemoteRequest and missing socket/httpReq: ";
29
- }
30
- const targetTable = eConfig.isJoined? eConfig.parsedPath.at(-1)!.table : eConfig.targetTable;
31
- if ((localParams?.socket || localParams?.httpReq) && this.dboBuilder.publishParser) {
32
-
33
- t2Rules = await this.dboBuilder.publishParser.getValidatedRequestRuleWusr({
34
- tableName: targetTable,
35
- command: "find",
36
- localParams
37
- }) as TableRule;
38
-
39
- if (!t2Rules || !t2Rules.select) throw "Dissallowed";
40
- ({ forcedFilter, filterFields } = t2Rules.select);
41
- }
42
-
43
- const tableHandler = this.dboBuilder.dbo[targetTable] as TableHandler
44
- const finalWhere = (await tableHandler.prepareWhere({
45
- select: undefined,
46
- filter: targetTableFilter,
47
- forcedFilter,
48
- filterFields,
49
- addWhere: false,
50
- tableAlias,
51
- localParams,
52
- tableRule: t2Rules
53
- })).where
54
-
55
- let innerQuery = [
56
- `SELECT 1`,
57
- `FROM ${asName(targetTable)}`,
58
- `${finalWhere ? `WHERE ${finalWhere}` : ""}`
59
- ].join("\n");
60
-
61
- if(eConfig.isJoined){
62
- const { query } = getTableJoinQuery({
63
- path: eConfig.parsedPath,
64
- rootTableAlias: thisTable,
65
- type: "EXISTS",
66
- finalWhere,
67
- });
68
- innerQuery = query;
69
- }
70
-
71
- return `${isNotExists ? " NOT " : " "} EXISTS ( \n${innerQuery} \n) `;
72
-
73
- }
@@ -1,74 +0,0 @@
1
- import { EXISTS_KEY, EXISTS_KEYS, getKeys } from "prostgles-types";
2
- import { ExistsFilterConfig } from "../DboBuilder";
3
- import { ViewHandler } from "./ViewHandler";
4
- import { parseJoinPath } from "./parseJoinPath";
5
-
6
- export const getExistsFilters = (filter: any, viewHandler: ViewHandler): ExistsFilterConfig[] => {
7
-
8
- /* Exists join filter */
9
- const ERR = "Invalid exists filter. \nExpecting something like: \n | { $exists: { tableName.tableName2: Filter } } \n | { $exists: { \"**.tableName3\": Filter } }\n | { path: string[]; filter: AnyObject }"
10
- const existsConfigs: ExistsFilterConfig[] = getKeys(filter)
11
- .filter((k ): k is typeof EXISTS_KEYS[number] => EXISTS_KEYS.includes(k as EXISTS_KEY) && !!Object.keys(filter[k] ?? {}).length)
12
- .map(key => {
13
-
14
- const isJoined = key.toLowerCase().includes("join");
15
- const filterValue = filter[key];
16
-
17
-
18
- /**
19
- * type ExistsJoined =
20
- * | { "table1.table2": { column: filterValue } }
21
- * | { path: string[]; filter: AnyObject }
22
- */
23
- const dataKeys = Object.keys(filterValue);
24
- const isDetailed = dataKeys.length === 2 && dataKeys.every(key => ["path", "filter"].includes(key));
25
-
26
- const firstKey = dataKeys[0]!;
27
-
28
- /**
29
- * Non joined exists are never detailed
30
- */
31
- if(!isJoined){
32
- const format = `Expecting single table in exists filter. Example: { $exists: { tableName: Filter } }`
33
- if(isDetailed){
34
- throw `Exists filters cannot be detailed. ${format}`
35
- }
36
- const targetTable = firstKey;
37
- if (!viewHandler.dboBuilder.dbo[targetTable]) {
38
- throw `Table ${JSON.stringify(targetTable)} not found. ${format}`
39
- }
40
- const res: ExistsFilterConfig = {
41
- isJoined: false,
42
- existType: key as EXISTS_KEY,
43
- targetTableFilter: filterValue[firstKey],
44
- targetTable: firstKey,
45
- }
46
- return res;
47
- }
48
-
49
- /**
50
- * Prevent some errors with table names that contain "."
51
- */
52
- const firstKeyIsATable = !!viewHandler.dboBuilder.dbo[firstKey];
53
- const [path, targetTableFilter] = isDetailed? [filterValue.path, filterValue.filter] : [(firstKeyIsATable? [firstKey] : firstKey.split(".")), filterValue[firstKey]];
54
-
55
- if (!path.length) {
56
- throw ERR + "\nBut got: " + JSON.stringify(filterValue);
57
- }
58
-
59
- return {
60
- isJoined: true,
61
- existType: key as EXISTS_KEY,
62
- path,
63
- parsedPath: parseJoinPath({
64
- rawPath: path,
65
- rootTable: viewHandler.name,
66
- viewHandler,
67
- allowMultiOrJoin: true,
68
- }),
69
- targetTableFilter,
70
- }
71
- });
72
-
73
- return existsConfigs;
74
- }
@@ -1,32 +0,0 @@
1
- import {
2
- TableInfo as TInfo
3
- } from "prostgles-types/dist";
4
- import { TableRule } from "../../PublishParser/PublishParser";
5
- import { LocalParams } from "../DboBuilder";
6
- import { ViewHandler } from "./ViewHandler";
7
-
8
- export async function getInfo(this: ViewHandler, lang?: string, param2?: any, param3?: any, tableRules?: TableRule, localParams?: LocalParams): Promise<TInfo> {
9
- const p = this.getValidatedRules(tableRules, localParams);
10
- if (!p.getInfo) {
11
- await this._log({ command: "getInfo", localParams, data: { lang }, duration: 0, error: "Not allowed" });
12
- throw "Not allowed";
13
- }
14
-
15
- const fileTableName = this.dboBuilder.prostgles?.opts?.fileTable?.tableName;
16
-
17
- await this._log({ command: "getInfo", localParams, data: { lang }, duration: 0 });
18
- return {
19
- oid: this.tableOrViewInfo.oid,
20
- comment: this.tableOrViewInfo.comment,
21
- info: this.dboBuilder.prostgles?.tableConfigurator?.getTableInfo({ tableName: this.name, lang }),
22
- isFileTable: !this.is_media? undefined : {
23
- allowedNestedInserts: tableRules?.insert?.allowedNestedInserts
24
- },
25
- isView: this.is_view,
26
- hasFiles: Boolean(!this.is_media && fileTableName && this.columns.some(c => c.references?.some(r => r.ftable === fileTableName))),
27
- fileTableName,
28
- dynamicRules: {
29
- update: Boolean(tableRules?.update?.dynamicFields?.length)
30
- }
31
- }
32
- }
@@ -1,84 +0,0 @@
1
- import { asName } from "prostgles-types";
2
- import { ParsedJoinPath } from "./parseJoinPath";
3
-
4
- type getTableJoinsArgs = {
5
- rootTableAlias: string;
6
- type: "INNER" | "LEFT" | "EXISTS";
7
- finalWhere?: string;
8
- path: ParsedJoinPath[];
9
- }
10
- export const getTableJoinQuery = ({ path, type, rootTableAlias, finalWhere }: getTableJoinsArgs): { targetAlias: string; query: string } => {
11
-
12
- const [firstPath] = path;
13
- if(!firstPath){
14
- throw `Cannot create join query for empty path`;
15
- }
16
- const aliasSufix = "jd";
17
- const getTableAlias = (table: string, pathIndex: number) => asName(`${aliasSufix}_${pathIndex}_${table}`);
18
-
19
- const query = path.map(({ table, on }, i) => {
20
- if(!on) throw "on missing";
21
- const tableName = table;
22
- const tableAlias = getTableAlias(table, i);
23
- const prevTableAlias = i === 0? rootTableAlias : getTableAlias(path[i-1]!.table, i-1);
24
-
25
- const onCondition = getJoinOnCondition({ on, leftAlias: prevTableAlias, rightAlias: tableAlias });
26
-
27
- const isExists = type === "EXISTS"
28
- const joinType = isExists? "INNER" : type;
29
- const keyword = `${joinType} JOIN`;
30
- const isLast = i === path.length - 1;
31
- const isFirst = !i;
32
-
33
- /**
34
- * rootTable joins to first path
35
- * first path joins to target table through inner joins
36
- */
37
- const whereJoinCondition = (isLast && isExists) ?
38
- `WHERE (${getJoinOnCondition({
39
- on: firstPath.on,
40
- leftAlias: rootTableAlias,
41
- rightAlias: getTableAlias(firstPath.table, 0)
42
- })})` : "";
43
-
44
- const tableSelect = (isExists && isLast)? [
45
- `(`,
46
- ` SELECT *`,
47
- ` FROM ${tableName}`,
48
- (finalWhere? ` WHERE ${finalWhere}` : ""),
49
- `)`
50
- ].filter(v=>v).join("\n") : tableName;
51
- if(isExists && isFirst){
52
- return [
53
- `SELECT 1`,
54
- `FROM ${tableSelect} ${tableAlias}`,
55
- whereJoinCondition
56
- ].filter(v=>v).join("\n");
57
- }
58
-
59
- return [
60
- `${keyword} ${tableSelect} ${tableAlias}`,
61
- ` ON ${onCondition}`,
62
- whereJoinCondition
63
- ].filter(v=>v).join("\n");
64
-
65
- }).join("\n");
66
-
67
- return {
68
- query,
69
- targetAlias: getTableAlias(path.at(-1)!.table, path.length - 1)
70
- }
71
- }
72
-
73
- type GetJoinOnConditionArgs = {
74
- on: Record<string, string>[];
75
- leftAlias: string;
76
- rightAlias: string;
77
- getLeftColName?: (col: string) => string;
78
- getRightColName?: (col: string) => string;
79
- }
80
- export const getJoinOnCondition = ({ on, leftAlias, rightAlias, getLeftColName = asName, getRightColName = asName }: GetJoinOnConditionArgs ) => {
81
- return on.map(constraint => Object.entries(constraint).map(([leftCol, rightCol]) => {
82
- return `${leftAlias}.${getLeftColName(leftCol)} = ${rightAlias}.${getRightColName(rightCol)}`;
83
- }).join(" AND ")).join(" OR ")
84
- }
@@ -1,96 +0,0 @@
1
- import { AnyObject, isObject } from "prostgles-types";
2
- import { FILTER_OPERANDS, FILTER_OPERAND_TO_SQL_OPERAND, parseFilterRightValue } from "../../Filtering";
3
- import { FUNCTIONS, parseFunction } from "../QueryBuilder/Functions";
4
- import { asNameAlias, parseFunctionObject } from "../QueryBuilder/QueryBuilder";
5
- import { TableSchemaColumn } from "../DboBuilderTypes";
6
- import { asValue } from "../../PubSubManager/PubSubManager";
7
-
8
- const allowedComparators = FILTER_OPERANDS; //[">", "<", "=", "<=", ">=", "<>", "!="]
9
- type Args = {
10
- filter: AnyObject;
11
- complexFilterKey: string;
12
- tableAlias: string | undefined;
13
- allowed_colnames: string[];
14
- columns: TableSchemaColumn[];
15
- }
16
-
17
- /* Parse complex filters
18
- {
19
- $filter: [
20
- { $func: [...] },
21
- "=",
22
- value | { $func: [..] }
23
- ]
24
- }
25
- */
26
- export const parseComplexFilter = ({
27
- filter,
28
- complexFilterKey,
29
- tableAlias,
30
- allowed_colnames,
31
- columns,
32
- }: Args) => {
33
-
34
- /**
35
- * { $funcName: [arg1, arg2] }
36
- * { $column: "column_name" }
37
- */
38
- const getFuncQuery = (funcData: AnyObject): string => {
39
- if(isObject(funcData) && "$column" in funcData){
40
- const column = funcData["$column"]
41
- if(typeof column !== "string"){
42
- throw `expecting: \n { $column: "column_name" } received:\n ${JSON.stringify(funcData)}`;
43
- }
44
- if(!allowed_colnames.includes(column)){
45
- throw `Dissallowed or Invalid column ${column}. Allowed columns: ${allowed_colnames}`;
46
- }
47
- return asNameAlias(column, tableAlias)
48
- }
49
- const { funcName, args } = parseFunctionObject(funcData);
50
- const funcDef = parseFunction({ func: funcName, args, functions: FUNCTIONS, allowedFields: allowed_colnames });
51
- return funcDef.getQuery({ args, tableAlias, allColumns: columns, allowedFields: allowed_colnames });
52
- }
53
-
54
- const complexFilter = filter[complexFilterKey];
55
- if (!Array.isArray(complexFilter)) {
56
- throw `Invalid $filter. Must contain an array of at least element but got: ${JSON.stringify(complexFilter)} `
57
- }
58
- const [leftFilter, comparator, rightFilterOrValue] = complexFilter;
59
-
60
- const leftVal = getFuncQuery(leftFilter);
61
- let result = leftVal;
62
- if (comparator) {
63
- if (typeof comparator !== "string" || !allowedComparators.includes(comparator as any)) {
64
- throw `Invalid $filter. comparator ${JSON.stringify(comparator)} is not valid. Expecting one of: ${allowedComparators}`;
65
- }
66
- if (!rightFilterOrValue) {
67
- throw "Invalid $filter. Expecting a value or function after the comparator";
68
- }
69
- const maybeValidComparator = comparator as keyof typeof FILTER_OPERAND_TO_SQL_OPERAND;
70
- const sqlOperand = FILTER_OPERAND_TO_SQL_OPERAND[maybeValidComparator];
71
- if(!sqlOperand){
72
- throw `Invalid $filter. comparator ${comparator} is not valid. Expecting one of: ${allowedComparators}`;
73
- }
74
-
75
- let rightVal = isObject(rightFilterOrValue) ?
76
- getFuncQuery(rightFilterOrValue) :
77
- parseFilterRightValue(rightFilterOrValue, {
78
- selectItem: undefined,
79
- expect: ["$in", "$nin"].includes(comparator)? "csv" : undefined
80
- });
81
- if(maybeValidComparator === "$between" || maybeValidComparator === "$notBetween"){
82
-
83
- if(!Array.isArray(rightVal) || rightVal.length !== 2){
84
- throw "Between filter expects an array of two values";
85
- }
86
- rightVal = asValue(rightVal[0]) + " AND " + asValue(rightVal[1]);
87
- }
88
- if (leftVal === rightVal){
89
- throw "Invalid $filter. Cannot compare two identical function signatures: " + JSON.stringify(leftFilter);
90
- }
91
-
92
- result += ` ${sqlOperand} ${rightVal}`;
93
- }
94
-
95
- return result;
96
- }
@@ -1,105 +0,0 @@
1
- import { FieldFilter, getKeys } from "prostgles-types";
2
- import { isPlainObject } from "../DboBuilder";
3
-
4
- /**
5
- * Filter string array
6
- * @param {FieldFilter} fieldParams - { col1: 0, col2: 0 } | { col1: true, col2: true } | "*" | ["key1", "key2"] | []
7
- * @param {boolean} allow_empty - allow empty select. defaults to true
8
- */
9
- export const parseFieldFilter = <AllowedKeys extends string[]>(
10
- fieldParams: FieldFilter<Record<AllowedKeys[number], any>> = "*",
11
- allow_empty = true,
12
- all_cols: AllowedKeys
13
- ): AllowedKeys | [""] => {
14
-
15
- if (!all_cols) throw "all_cols missing"
16
- const all_fields = all_cols;// || this.column_names.slice(0);
17
- let colNames: AllowedKeys = [] as any;
18
- const initialParams = JSON.stringify(fieldParams);
19
-
20
- if (fieldParams) {
21
-
22
- /*
23
- "field1, field2, field4" | "*"
24
- */
25
- if (typeof fieldParams === "string") {
26
- fieldParams = fieldParams.split(",").map(k => k.trim());
27
- }
28
-
29
- /* string[] */
30
- if (Array.isArray(fieldParams) && !fieldParams.find(f => typeof f !== "string")) {
31
- /*
32
- ["*"]
33
- */
34
- if (fieldParams[0] === "*") {
35
- return all_fields.slice(0) as typeof all_fields;
36
-
37
- /*
38
- [""]
39
- */
40
- } else if (fieldParams[0] === "") {
41
- if (allow_empty) {
42
- return [""];
43
- } else {
44
- throw "Empty value not allowed";
45
- }
46
- /*
47
- ["field1", "field2", "field3"]
48
- */
49
- } else {
50
- colNames = fieldParams.slice(0) as AllowedKeys;
51
- }
52
-
53
- /*
54
- { field1: true, field2: true } = only field1 and field2
55
- { field1: false, field2: false } = all fields except field1 and field2
56
- */
57
- } else if (isPlainObject(fieldParams)) {
58
-
59
- if (!getKeys(fieldParams).length) {
60
- return [] as unknown as typeof all_fields; //all_fields.slice(0) as typeof all_fields;
61
- }
62
-
63
- const keys = getKeys(fieldParams as {
64
- [key: string]: boolean | 0 | 1;
65
- }) as AllowedKeys;
66
- if (keys[0] === "") {
67
- if (allow_empty) {
68
- return [""];
69
- } else {
70
- throw "Empty value not allowed";
71
- }
72
- }
73
-
74
- validate(keys);
75
-
76
- keys.forEach(key => {
77
- const allowedVals = [true, false, 0, 1];
78
- if (!allowedVals.includes((fieldParams as any)[key])) throw `Invalid field selection value for: { ${key}: ${(fieldParams as any)[key]} }. \n Allowed values: ${allowedVals.join(" OR ")}`
79
- })
80
-
81
- const allowed = keys.filter(key => (fieldParams as any)[key]),
82
- disallowed = keys.filter(key => !(fieldParams as any)[key]);
83
-
84
-
85
- if (disallowed && disallowed.length) {
86
- return all_fields.filter(col => !disallowed.includes(col)) as typeof all_fields;
87
- } else {
88
- return [...allowed] as any;
89
- }
90
-
91
- } else {
92
- throw " Unrecognised field filter.\nExpecting any of: string | string[] | { [field]: boolean } \n Received -> " + initialParams;
93
- }
94
-
95
- validate(colNames);
96
- }
97
- return colNames as any;
98
-
99
- function validate(cols: AllowedKeys) {
100
- const bad_keys = cols.filter(col => !all_fields.includes(col));
101
- if (bad_keys && bad_keys.length) {
102
- throw "\nUnrecognised or illegal fields: " + bad_keys.join(", ");
103
- }
104
- }
105
- }