orange-orm 4.4.2 → 4.5.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/README.md +1 -1
  2. package/package.json +12 -6
  3. package/src/client/clientMap.js +2 -0
  4. package/src/client/createProviders.js +12 -0
  5. package/src/client/index.js +6 -3
  6. package/src/client/index.mjs +8 -3
  7. package/src/client/map.js +1 -0
  8. package/src/createDomain.js +11 -16
  9. package/src/d1/newDatabase.js +119 -0
  10. package/src/d1/newPool.js +19 -0
  11. package/src/d1/newTransaction.js +82 -0
  12. package/src/d1/pool/end.js +13 -0
  13. package/src/d1/pool/newGenericPool.js +53 -0
  14. package/src/d1/wrapQuery.js +22 -0
  15. package/src/d1test.js +35 -0
  16. package/src/emitEvent.js +6 -4
  17. package/src/emptyFilter.js +12 -12
  18. package/src/getManyDto/newQuery.js +5 -5
  19. package/src/getManyDto/query/newSingleQuery.js +5 -5
  20. package/src/getManyDto.js +25 -24
  21. package/src/hostExpress/cycle.ts +211 -0
  22. package/src/hostExpress/executePath.js +360 -357
  23. package/src/hostLocal.js +8 -8
  24. package/src/index.d.ts +2 -0
  25. package/src/index.js +19 -15
  26. package/src/map.d.ts +3 -0
  27. package/src/mssql/newDatabase.js +19 -31
  28. package/src/mssql/newPool.js +2 -2
  29. package/src/mssql/newTransaction.js +5 -4
  30. package/src/mssql/pool/newGenericPool.js +1 -1
  31. package/src/mySql/deleteFromSql.js +1 -1
  32. package/src/mySql/insert.js +5 -5
  33. package/src/mySql/insertSql.js +2 -3
  34. package/src/mySql/lastInsertedSql.js +3 -4
  35. package/src/mySql/newDatabase.js +20 -34
  36. package/src/mySql/newPool.js +10 -10
  37. package/src/mySql/newTransaction.js +3 -3
  38. package/src/mySql/pool/newGenericPool.js +2 -3
  39. package/src/mySql/quote.js +1 -0
  40. package/src/newImmutable.js +1 -2
  41. package/src/oracle/deleteFromSql.js +1 -1
  42. package/src/oracle/formatDateOut.js +1 -1
  43. package/src/oracle/insert.js +6 -6
  44. package/src/oracle/insertSql.js +6 -14
  45. package/src/oracle/lastInsertedSql.js +3 -3
  46. package/src/oracle/mergeSql.js +3 -6
  47. package/src/oracle/newDatabase.js +18 -33
  48. package/src/oracle/newInsertCommandCore.js +3 -3
  49. package/src/oracle/newPool.js +10 -10
  50. package/src/oracle/newTransaction.js +3 -2
  51. package/src/oracle/pool/newGenericPool.js +2 -2
  52. package/src/oracle/quote.js +1 -0
  53. package/src/oracle/wrapQuery.js +0 -3
  54. package/src/patchRow.js +2 -2
  55. package/src/patchTable.js +6 -5
  56. package/src/pg/deleteFromSql.js +1 -1
  57. package/src/pg/formatDateOut.js +1 -2
  58. package/src/pg/insert.js +3 -3
  59. package/src/pg/insertSql.js +2 -7
  60. package/src/pg/lastInsertedSql.js +1 -2
  61. package/src/pg/newDatabase.js +20 -37
  62. package/src/pg/newPool.js +10 -10
  63. package/src/pg/newTransaction.js +3 -2
  64. package/src/pg/pool/newPgPool.js +2 -2
  65. package/src/pg/quote.js +2 -0
  66. package/src/pg/schema.js +2 -2
  67. package/src/{mySql/pool/defaults.js → poolDefaults.js} +0 -2
  68. package/src/query.js +2 -2
  69. package/src/sap/deleteFromSql.js +1 -1
  70. package/src/sap/formatDateOut.js +1 -1
  71. package/src/sap/insert.js +5 -5
  72. package/src/sap/insertSql.js +4 -5
  73. package/src/sap/lastInsertedSql.js +3 -3
  74. package/src/sap/mergeSql.js +1 -2
  75. package/src/sap/newDatabase.js +23 -34
  76. package/src/sap/newPool.js +2 -2
  77. package/src/sap/newTransaction.js +3 -2
  78. package/src/sap/quote.js +1 -0
  79. package/src/sqlite/deleteFromSql.js +1 -1
  80. package/src/sqlite/insert.js +5 -5
  81. package/src/sqlite/insertSql.js +2 -2
  82. package/src/sqlite/lastInsertedSql.js +2 -2
  83. package/src/sqlite/newDatabase.js +16 -32
  84. package/src/sqlite/newPool.js +10 -10
  85. package/src/sqlite/newTransaction.js +3 -2
  86. package/src/sqlite/pool/newGenericPool.js +2 -1
  87. package/src/sqlite/quote.js +1 -0
  88. package/src/table/aggregate.js +1 -1
  89. package/src/table/begin.js +5 -5
  90. package/src/table/cascadeDelete.js +2 -2
  91. package/src/table/column/binary/newDecode.js +2 -2
  92. package/src/table/column/binary/newEncode.js +3 -4
  93. package/src/table/column/boolean/newDecode.js +1 -1
  94. package/src/table/column/boolean/newEncode.js +6 -6
  95. package/src/table/column/date/formatOut.js +3 -5
  96. package/src/table/column/date/newDecode.js +2 -2
  97. package/src/table/column/date/newEncode.js +8 -8
  98. package/src/table/column/date.js +1 -1
  99. package/src/table/column/dateWithTimeZone/newEncode.js +3 -4
  100. package/src/table/column/dateWithTimeZone.js +1 -1
  101. package/src/table/column/encodeFilterArg.js +3 -3
  102. package/src/table/column/equal.js +3 -3
  103. package/src/table/column/extractAlias.js +0 -2
  104. package/src/table/column/greaterThan.js +3 -3
  105. package/src/table/column/greaterThanOrEqual.js +3 -3
  106. package/src/table/column/guid/newDecode.js +1 -1
  107. package/src/table/column/guid/newEncode.js +3 -3
  108. package/src/table/column/in.js +3 -3
  109. package/src/table/column/json/formatOut.js +3 -3
  110. package/src/table/column/json/newDecode.js +3 -3
  111. package/src/table/column/json/newEncode.js +6 -6
  112. package/src/table/column/json.js +2 -1
  113. package/src/table/column/lessThan.js +3 -3
  114. package/src/table/column/lessThanOrEqual.js +4 -4
  115. package/src/table/column/negotiateRawSqlFilter.js +9 -9
  116. package/src/table/column/newBoolean.js +9 -9
  117. package/src/table/column/newColumn.js +21 -21
  118. package/src/table/column/newDecodeCore.js +1 -1
  119. package/src/table/column/notEqual.js +3 -3
  120. package/src/table/column/numeric/newDecode.js +2 -2
  121. package/src/table/column/numeric/newEncode.js +3 -3
  122. package/src/table/column/string/contains.js +2 -1
  123. package/src/table/column/string/containsCore.js +5 -5
  124. package/src/table/column/string/endsWith.js +1 -1
  125. package/src/table/column/string/endsWithCore.js +4 -4
  126. package/src/table/column/string/iContains.js +2 -1
  127. package/src/table/column/string/iEndsWith.js +1 -1
  128. package/src/table/column/string/iEqual.js +3 -3
  129. package/src/table/column/string/iStartsWith.js +1 -1
  130. package/src/table/column/string/newEncode.js +3 -3
  131. package/src/table/column/string/startsWith.js +1 -1
  132. package/src/table/column/string/startsWithCore.js +4 -4
  133. package/src/table/column/string.js +14 -14
  134. package/src/table/commands/beginCommand.js +2 -2
  135. package/src/table/commands/compressChanges.js +2 -2
  136. package/src/table/commands/delete/newSingleCommand.js +5 -5
  137. package/src/table/commands/delete/singleCommand/joinSql.js +12 -12
  138. package/src/table/commands/delete/singleCommand/newSingleCommandCore.js +2 -2
  139. package/src/table/commands/delete/singleCommand/selectSql.js +6 -6
  140. package/src/table/commands/delete/singleCommand/subFilter.js +11 -11
  141. package/src/table/commands/delete/singleCommand/whereSql.js +2 -2
  142. package/src/table/commands/getChangeSet.js +2 -2
  143. package/src/table/commands/insert/getSqlTemplate.js +16 -16
  144. package/src/table/commands/lastCommandMatches.js +2 -2
  145. package/src/table/commands/newDeleteCommand.js +5 -5
  146. package/src/table/commands/newGetLastInsertedCommand.js +4 -4
  147. package/src/table/commands/newGetLastInsertedCommandCore.js +5 -5
  148. package/src/table/commands/newInsertCommand.js +0 -1
  149. package/src/table/commands/newInsertCommandCore.js +3 -3
  150. package/src/table/commands/newRow.js +4 -4
  151. package/src/table/commands/newUpdateCommand.js +4 -4
  152. package/src/table/commands/newUpdateCommandCore.js +4 -4
  153. package/src/table/commands/pushCommand.js +2 -2
  154. package/src/table/commit.js +13 -11
  155. package/src/table/count.js +8 -8
  156. package/src/table/delete.js +4 -4
  157. package/src/table/deleteSessionContext.js +4 -13
  158. package/src/table/executeQueries/executeChanges.js +3 -3
  159. package/src/table/executeQueries/executeQueriesCore.js +2 -2
  160. package/src/table/executeQueries/executeQuery.js +2 -2
  161. package/src/table/executeQueries/resolveExecuteQuery.js +4 -4
  162. package/src/table/executeQueries.js +4 -4
  163. package/src/table/getFromDbById.js +1 -1
  164. package/src/table/getMany.js +7 -7
  165. package/src/table/getManyDto.js +3 -4
  166. package/src/table/getSessionContext.js +4 -4
  167. package/src/table/getSessionSingleton.js +3 -2
  168. package/src/table/groupBy/newQuery.js +4 -4
  169. package/src/table/groupBy.js +9 -9
  170. package/src/table/insert.js +10 -13
  171. package/src/table/joinRelation/getRelatives.js +6 -6
  172. package/src/table/newGetRelated.js +3 -3
  173. package/src/table/newManyRelation.js +9 -9
  174. package/src/table/newOneRelation.js +9 -9
  175. package/src/table/newPrimaryKeyFilter.js +6 -6
  176. package/src/table/newQuery.js +5 -5
  177. package/src/table/newRelatedTable.js +2 -2
  178. package/src/table/newRowCache.js +17 -17
  179. package/src/table/newThrow.js +2 -2
  180. package/src/table/oneRelation/getRelatives.js +5 -5
  181. package/src/table/popChanges.js +3 -3
  182. package/src/table/promise.js +2 -8
  183. package/src/table/query/extractLimit.js +2 -2
  184. package/src/table/query/extractOffset.js +2 -2
  185. package/src/table/query/extractOrderBy.js +2 -2
  186. package/src/table/query/newSingleQuery.js +7 -7
  187. package/src/table/query/singleQuery/columnSql/joinLegToColumnSql.js +5 -5
  188. package/src/table/query/singleQuery/columnSql/newJoinedColumnSql.js +2 -2
  189. package/src/table/query/singleQuery/columnSql/newShallowColumnSql.js +4 -4
  190. package/src/table/query/singleQuery/joinSql/joinLegToJoinSql.js +2 -2
  191. package/src/table/query/singleQuery/joinSql/joinLegToShallowJoinSql.js +2 -2
  192. package/src/table/query/singleQuery/joinSql/newDiscriminatorSql.js +2 -2
  193. package/src/table/query/singleQuery/joinSql/newShallowJoinSql.js +5 -5
  194. package/src/table/query/singleQuery/joinSql/newShallowJoinSqlCore.js +6 -5
  195. package/src/table/query/singleQuery/joinSql/oneLegToJoinSql.js +2 -2
  196. package/src/table/query/singleQuery/joinSql/oneLegToShallowJoinSql.js +2 -2
  197. package/src/table/query/singleQuery/negotiateExclusive.js +2 -2
  198. package/src/table/query/singleQuery/newColumnSql.js +3 -3
  199. package/src/table/query/singleQuery/newDiscriminatorSql.js +2 -2
  200. package/src/table/query/singleQuery/newJoinSql.js +6 -6
  201. package/src/table/query/singleQuery/newWhereSql.js +3 -3
  202. package/src/table/quote.js +4 -4
  203. package/src/table/relatedTable/aggregate.js +2 -2
  204. package/src/table/relatedTable/all.js +5 -5
  205. package/src/table/relatedTable/any.js +3 -3
  206. package/src/table/relatedTable/childColumn.js +12 -12
  207. package/src/table/relatedTable/columnAggregate.js +3 -3
  208. package/src/table/relatedTable/columnAggregateGroup.js +11 -11
  209. package/src/table/relatedTable/joinSql.js +5 -5
  210. package/src/table/relatedTable/joinSqlArray.js +3 -3
  211. package/src/table/relatedTable/none.js +3 -3
  212. package/src/table/relatedTable/relatedColumn.js +13 -13
  213. package/src/table/relatedTable/selectSql.js +2 -2
  214. package/src/table/relatedTable/subFilter.js +4 -4
  215. package/src/table/relatedTable/where.js +3 -3
  216. package/src/table/relatedTable/whereSql.js +2 -2
  217. package/src/table/relation/manyCache/synchronizeAdded.js +2 -2
  218. package/src/table/relation/manyCache/synchronizeChanged.js +3 -3
  219. package/src/table/relation/manyCache/synchronizeRemoved.js +2 -2
  220. package/src/table/relation/newForeignKeyFilter.js +2 -2
  221. package/src/table/relation/newManyCache.js +16 -16
  222. package/src/table/relation/newOneCache.js +6 -6
  223. package/src/table/releaseDbClient.js +4 -4
  224. package/src/table/resultToPromise.js +1 -3
  225. package/src/table/resultToRows/dbRowToRow.js +8 -8
  226. package/src/table/resultToRows/dbRowsToRows.js +2 -2
  227. package/src/table/resultToRows/decodeDbRow.js +2 -2
  228. package/src/table/resultToRows/delete/removeFromCache.js +6 -6
  229. package/src/table/resultToRows/delete.js +6 -6
  230. package/src/table/resultToRows/newDecodeDbRow.js +19 -18
  231. package/src/table/resultToRows/toDto.js +3 -3
  232. package/src/table/resultToRows.js +3 -3
  233. package/src/table/rollback.js +21 -11
  234. package/src/table/rowArray/negotiateNextTick.js +1 -2
  235. package/src/table/setSessionSingleton.js +6 -3
  236. package/src/table/tryGetFirstFromDb.js +4 -4
  237. package/src/table/tryGetFromCacheById.js +3 -3
  238. package/src/table/tryGetFromDbById/extractStrategy.js +2 -2
  239. package/src/table/tryGetFromDbById.js +8 -6
  240. package/src/table/tryGetSessionContext.js +5 -10
  241. package/src/table/tryReleaseDbClient.js +2 -2
  242. package/src/table/updateField.js +4 -4
  243. package/src/table/where.js +2 -2
  244. package/src/table.js +58 -51
  245. package/src/tedious/deleteFromSql.js +1 -1
  246. package/src/tedious/formatDateOut.js +1 -1
  247. package/src/tedious/getManyDto/newQueryCore.js +5 -5
  248. package/src/tedious/getManyDto/query/newSingleQuery.js +5 -5
  249. package/src/tedious/getManyDto/query/newSubQueries/joinLegToQuery.js +3 -3
  250. package/src/tedious/getManyDto/query/newSubQueries/manyLegToQuery.js +3 -3
  251. package/src/tedious/getManyDto/query/newSubQueries/oneLegToQuery.js +4 -4
  252. package/src/tedious/getManyDto/query/newSubQueries.js +8 -8
  253. package/src/tedious/getManyDto/query/singleQuery/newShallowColumnSql.js +5 -6
  254. package/src/tedious/getManyDto.js +6 -6
  255. package/src/tedious/insert.js +3 -3
  256. package/src/tedious/insertSql.js +3 -3
  257. package/src/tedious/newDatabase.js +17 -30
  258. package/src/tedious/newPool.js +10 -10
  259. package/src/tedious/newTransaction.js +4 -5
  260. package/src/tedious/pool/newGenericPool.js +1 -1
  261. package/src/tedious/quote.js +1 -0
  262. package/src/mssql/pool/defaults.js +0 -45
  263. package/src/oracle/pool/defaults.js +0 -45
  264. package/src/pg/pool/defaults.js +0 -45
  265. package/src/sqlite/pool/defaults.js +0 -45
  266. package/src/tedious/pool/defaults.js +0 -45
@@ -3,14 +3,6 @@ const emptyFilter = require('../emptyFilter');
3
3
  const negotiateRawSqlFilter = require('../table/column/negotiateRawSqlFilter');
4
4
  let getMeta = require('./getMeta');
5
5
  let isSafe = Symbol();
6
- let _ops = {
7
- and: emptyFilter.and,
8
- or: emptyFilter.or,
9
- not: emptyFilter.not,
10
- AND: emptyFilter.and,
11
- OR: emptyFilter.or,
12
- NOT: emptyFilter.not
13
- };
14
6
 
15
7
  let _allowedOps = {
16
8
  and: true,
@@ -69,431 +61,442 @@ let _allowedOps = {
69
61
  self: true,
70
62
  };
71
63
 
72
- async function executePath({ table, JSONFilter, baseFilter, customFilters = {}, request, response, readonly, disableBulkDeletes, isHttp, client }) {
73
- let allowedOps = { ..._allowedOps, insert: !readonly, ...extractRelations(getMeta(table)) };
74
- let ops = { ..._ops, ...getCustomFilterPaths(customFilters), getManyDto, getMany, aggregate, count, delete: _delete, cascadeDelete, update, replace };
75
-
76
- let res = await parseFilter(JSONFilter, table);
77
- if (res === undefined)
78
- return {};
79
- else
80
- return res;
81
-
82
- function parseFilter(json, table) {
83
- if (isFilter(json)) {
84
- let subFilters = [];
85
-
86
- let anyAllNone = tryGetAnyAllNone(json.path, table);
87
- if (anyAllNone) {
88
- if (isHttp)
89
- validateArgs(json.args[0]);
90
- const f = anyAllNone(x => parseFilter(json.args[0], x));
91
- f.isSafe = isSafe;
92
- return f;
64
+ function _executePath(context, ...rest) {
65
+
66
+ const _ops = {
67
+ and: emptyFilter.and.bind(null, context),
68
+ or: emptyFilter.or.bind(null, context),
69
+ not: emptyFilter.not.bind(null, context),
70
+ AND: emptyFilter.and.bind(null, context),
71
+ OR: emptyFilter.or.bind(null, context),
72
+ NOT: emptyFilter.not.bind(null, context),
73
+ };
74
+
75
+ return executePath(...rest);
76
+
77
+ async function executePath({ table, JSONFilter, baseFilter, customFilters = {}, request, response, readonly, disableBulkDeletes, isHttp, client }) {
78
+ let allowedOps = { ..._allowedOps, insert: !readonly, ...extractRelations(getMeta(table)) };
79
+ let ops = { ..._ops, ...getCustomFilterPaths(customFilters), getManyDto, getMany, aggregate, count, delete: _delete, cascadeDelete, update, replace };
80
+
81
+ let res = await parseFilter(JSONFilter, table);
82
+ if (res === undefined)
83
+ return {};
84
+ else
85
+ return res;
86
+
87
+ function parseFilter(json, table) {
88
+ if (isFilter(json)) {
89
+ let subFilters = [];
90
+
91
+ let anyAllNone = tryGetAnyAllNone(json.path, table);
92
+ if (anyAllNone) {
93
+ if (isHttp)
94
+ validateArgs(json.args[0]);
95
+ const f = anyAllNone(context, x => parseFilter(json.args[0], x));
96
+ f.isSafe = isSafe;
97
+ return f;
98
+ }
99
+ else {
100
+ for (let i = 0; i < json.args.length; i++) {
101
+ subFilters.push(parseFilter(json.args[i], nextTable(json.path, table)));
102
+ }
103
+ }
104
+ return executePath(json.path, subFilters);
93
105
  }
94
- else {
95
- for (let i = 0; i < json.args.length; i++) {
96
- subFilters.push(parseFilter(json.args[i], nextTable(json.path, table)));
106
+ else if (Array.isArray(json)) {
107
+ const result = [];
108
+ for (let i = 0; i < json.length; i++) {
109
+ result.push(parseFilter(json[i], table));
110
+ }
111
+ return result;
112
+ }
113
+ return json;
114
+
115
+ function tryGetAnyAllNone(path, table) {
116
+ path = path.split('.');
117
+ for (let i = 0; i < path.length; i++) {
118
+ table = table[path[i]];
119
+ }
120
+
121
+ let ops = new Set(['all', 'any', 'none', 'where', '_aggregate']);
122
+ // let ops = new Set(['all', 'any', 'none', 'where']);
123
+ let last = path.slice(-1)[0];
124
+ if (ops.has(last) || (table && (table._primaryColumns || (table.any && table.all))))
125
+ return table;
126
+ }
127
+
128
+ function executePath(path, args) {
129
+ if (path in ops) {
130
+ if (isHttp)
131
+ validateArgs(args);
132
+ let op = ops[path].apply(null, args);
133
+ if (op.then)
134
+ return op.then((o) => {
135
+ setSafe(o);
136
+ return o;
137
+ });
138
+ setSafe(op);
139
+ return op;
140
+ }
141
+ let pathArray = path.split('.');
142
+ let target = table;
143
+ let op = pathArray[pathArray.length - 1];
144
+ if (!allowedOps[op] && isHttp) {
145
+
146
+ let e = new Error('Disallowed operator ' + op);
147
+ // @ts-ignore
148
+ e.status = 403;
149
+ throw e;
150
+
151
+ }
152
+ for (let i = 0; i < pathArray.length; i++) {
153
+ target = target[pathArray[i]];
97
154
  }
155
+
156
+ if (!target)
157
+ throw new Error(`Method '${path}' does not exist`);
158
+ let res = target.apply(null, [context, ...args]);
159
+ setSafe(res);
160
+ return res;
98
161
  }
99
- return executePath(json.path, subFilters);
100
162
  }
101
- else if (Array.isArray(json)) {
102
- const result = [];
103
- for (let i = 0; i < json.length; i++) {
104
- result.push(parseFilter(json[i], table));
163
+
164
+ async function invokeBaseFilter() {
165
+ if (typeof baseFilter === 'function') {
166
+ const res = await baseFilter.apply(null, [bindDb(client), request, response]);
167
+ if (!res)
168
+ return;
169
+ const JSONFilter = JSON.parse(JSON.stringify(res));
170
+ //@ts-ignore
171
+ return executePath({ table, JSONFilter, request, response });
105
172
  }
106
- return result;
173
+ else
174
+ return;
107
175
  }
108
- return json;
109
176
 
110
- function tryGetAnyAllNone(path, table) {
111
- path = path.split('.');
112
- for (let i = 0; i < path.length; i++) {
113
- table = table[path[i]];
177
+ function getCustomFilterPaths(customFilters) {
178
+ return getLeafNames(customFilters);
179
+
180
+ function getLeafNames(obj, result = {}, current = 'customFilters.') {
181
+ for (let p in obj) {
182
+ if (typeof obj[p] === 'object' && obj[p] !== null)
183
+ getLeafNames(obj[p], result, current + p + '.');
184
+ else
185
+ result[current + p] = resolveFilter.bind(null, obj[p]);
186
+ }
187
+ return result;
188
+ }
189
+
190
+ async function resolveFilter(fn, ...args) {
191
+ const context = { db: bindDb(client), request, response };
192
+ let res = fn.apply(null, [context, ...args]);
193
+ if (res.then)
194
+ res = await res;
195
+ const JSONFilter = JSON.parse(JSON.stringify(res));
196
+ //@ts-ignore
197
+ return executePath({ table, JSONFilter, request, response });
114
198
  }
199
+ }
115
200
 
116
- let ops = new Set(['all', 'any', 'none', 'where', '_aggregate']);
117
- // let ops = new Set(['all', 'any', 'none', 'where']);
201
+ function nextTable(path, table) {
202
+ path = path.split('.');
203
+ let ops = new Set(['all', 'any', 'none']);
118
204
  let last = path.slice(-1)[0];
119
- if (ops.has(last) || (table && (table._primaryColumns || (table.any && table.all))))
205
+ if (ops.has(last)) {
206
+ for (let i = 0; i < path.length - 1; i++) {
207
+ table = table[path[i]];
208
+ }
120
209
  return table;
210
+ }
211
+ else {
212
+ let lastObj = table;
213
+ for (let i = 0; i < path.length; i++) {
214
+ if (lastObj)
215
+ lastObj = lastObj[path[i]];
216
+ }
217
+ if (lastObj?._shallow)
218
+ return lastObj._shallow;
219
+ else return table;
220
+ }
121
221
  }
122
222
 
123
- function executePath(path, args) {
124
- if (path in ops) {
125
- if (isHttp)
126
- validateArgs(args);
127
- let op = ops[path].apply(null, args);
128
- if (op.then)
129
- return op.then((o) => {
130
- setSafe(o);
131
- return o;
132
- });
133
- setSafe(op);
134
- return op;
223
+ async function _delete(filter) {
224
+ if (readonly || disableBulkDeletes) {
225
+ let e = new Error('Bulk deletes are not allowed. Parameter "disableBulkDeletes" must be true.');
226
+ // @ts-ignore
227
+ e.status = 403;
228
+ throw e;
135
229
  }
136
- let pathArray = path.split('.');
137
- let target = table;
138
- let op = pathArray[pathArray.length - 1];
139
- if (!allowedOps[op] && isHttp) {
230
+ filter = negotiateFilter(filter);
231
+ const _baseFilter = await invokeBaseFilter();
232
+ if (_baseFilter)
233
+ filter = filter.and(context, _baseFilter);
234
+ let args = [context, filter].concat(Array.prototype.slice.call(arguments).slice(1));
235
+ return table.delete.apply(null, args);
236
+ }
140
237
 
141
- let e = new Error('Disallowed operator ' + op);
238
+ async function cascadeDelete(filter) {
239
+ if (readonly || disableBulkDeletes) {
240
+ const e = new Error('Bulk deletes are not allowed. Parameter "disableBulkDeletes" must be true.');
142
241
  // @ts-ignore
143
242
  e.status = 403;
144
243
  throw e;
145
244
 
146
245
  }
147
- for (let i = 0; i < pathArray.length; i++) {
148
- target = target[pathArray[i]];
149
- }
150
-
151
- if (!target)
152
- throw new Error(`Method '${path}' does not exist`);
153
- let res = target.apply(null, args);
154
- setSafe(res);
155
- return res;
246
+ filter = negotiateFilter(filter);
247
+ const _baseFilter = await invokeBaseFilter();
248
+ if (_baseFilter)
249
+ filter = filter.and(context, _baseFilter);
250
+ let args = [context, filter].concat(Array.prototype.slice.call(arguments).slice(1));
251
+ return table.cascadeDelete.apply(null, args);
156
252
  }
157
- }
158
-
159
-
160
253
 
161
- async function invokeBaseFilter() {
162
- if (typeof baseFilter === 'function') {
163
- const res = await baseFilter.apply(null, [bindDb(client), request, response]);
164
- if (!res)
165
- return;
166
- const JSONFilter = JSON.parse(JSON.stringify(res));
167
- //@ts-ignore
168
- return executePath({ table, JSONFilter, request, response });
254
+ function negotiateFilter(filter) {
255
+ if (filter)
256
+ return negotiateRawSqlFilter(context, filter, table, true);
257
+ else
258
+ return emptyFilter;
169
259
  }
170
- else
171
- return;
172
- }
173
-
174
- function getCustomFilterPaths(customFilters) {
175
- return getLeafNames(customFilters);
176
260
 
177
- function getLeafNames(obj, result = {}, current = 'customFilters.') {
178
- for (let p in obj) {
179
- if (typeof obj[p] === 'object' && obj[p] !== null)
180
- getLeafNames(obj[p], result, current + p + '.');
181
- else
182
- result[current + p] = resolveFilter.bind(null, obj[p]);
183
- }
184
- return result;
261
+ async function count(filter, strategy) {
262
+ validateStrategy(table, strategy);
263
+ filter = negotiateFilter(filter);
264
+ const _baseFilter = await invokeBaseFilter();
265
+ if (_baseFilter)
266
+ filter = filter.and(context, _baseFilter);
267
+ let args = [context, filter].concat(Array.prototype.slice.call(arguments).slice(1));
268
+ return table.count.apply(null, args);
185
269
  }
186
270
 
187
- async function resolveFilter(fn, ...args) {
188
- const context = { db: bindDb(client), request, response };
189
- let res = fn.apply(null, [context, ...args]);
190
- if (res.then)
191
- res = await res;
192
- const JSONFilter = JSON.parse(JSON.stringify(res));
193
- //@ts-ignore
194
- return executePath({ table, JSONFilter, request, response });
271
+ async function getManyDto(filter, strategy) {
272
+ validateStrategy(table, strategy);
273
+ filter = negotiateFilter(filter);
274
+ const _baseFilter = await invokeBaseFilter();
275
+ if (_baseFilter)
276
+ filter = filter.and(context, _baseFilter);
277
+ let args = [context, filter].concat(Array.prototype.slice.call(arguments).slice(1));
278
+ await negotiateWhereAndAggregate(strategy);
279
+ return table.getManyDto.apply(null, args);
195
280
  }
196
- }
197
281
 
198
- function nextTable(path, table) {
199
- path = path.split('.');
200
- let ops = new Set(['all', 'any', 'none']);
201
- let last = path.slice(-1)[0];
202
- if (ops.has(last)) {
203
- for (let i = 0; i < path.length - 1; i++) {
204
- table = table[path[i]];
205
- }
206
- return table;
282
+ async function replace(subject, strategy = { insertAndForget: true }) {
283
+ validateStrategy(table, strategy);
284
+ const refinedStrategy = objectToStrategy(subject, {}, table);
285
+ const JSONFilter2 = {
286
+ path: 'getManyDto',
287
+ args: [subject, refinedStrategy]
288
+ };
289
+ const originals = await executePath({ table, JSONFilter: JSONFilter2, baseFilter, customFilters, request, response, readonly, disableBulkDeletes, isHttp, client });
290
+ const meta = getMeta(table);
291
+ const patch = createPatch(originals, Array.isArray(subject) ? subject : [subject], meta);
292
+ const { changed } = await table.patch(context, patch, { strategy });
293
+ if (Array.isArray(subject))
294
+ return changed;
295
+ else
296
+ return changed[0];
207
297
  }
208
- else {
209
- let lastObj = table;
210
- for (let i = 0; i < path.length; i++) {
211
- if (lastObj)
212
- lastObj = lastObj[path[i]];
298
+
299
+ async function update(subject, whereStrategy, strategy = { insertAndForget: true }) {
300
+ validateStrategy(table, strategy);
301
+ const refinedWhereStrategy = objectToStrategy(subject, whereStrategy, table);
302
+ const JSONFilter2 = {
303
+ path: 'getManyDto',
304
+ args: [null, refinedWhereStrategy]
305
+ };
306
+ const rows = await executePath({ table, JSONFilter: JSONFilter2, baseFilter, customFilters, request, response, readonly, disableBulkDeletes, isHttp, client });
307
+ const originals = new Array(rows.length);
308
+ for (let i = 0; i < rows.length; i++) {
309
+ const row = rows[i];
310
+ originals[i] = { ...row };
311
+ for (let p in subject) {
312
+ row[p] = subject[p];
313
+ }
213
314
  }
214
- if (lastObj?._shallow)
215
- return lastObj._shallow;
216
- else return table;
315
+ const meta = getMeta(table);
316
+ const patch = createPatch(originals, rows, meta);
317
+ const { changed } = await table.patch(context, patch, { strategy });
318
+ return changed;
217
319
  }
218
- }
219
320
 
220
- async function _delete(filter) {
221
- if (readonly || disableBulkDeletes) {
222
- let e = new Error('Bulk deletes are not allowed. Parameter "disableBulkDeletes" must be true.');
223
- // @ts-ignore
224
- e.status = 403;
225
- throw e;
321
+ function objectToStrategy(object, whereStrategy, table, strategy = {}) {
322
+ strategy = { ...whereStrategy, ...strategy };
323
+ if (Array.isArray(object)) {
324
+ for (let i = 0; i < object.length; i++) {
325
+ objectToStrategy(object[i], table, strategy);
326
+ }
327
+ return;
328
+ }
329
+ for (let name in object) {
330
+ const relation = table[name]?._relation;
331
+ if (relation && !relation.columns) {//notJoin, that is one or many
332
+ strategy[name] = {};
333
+ objectToStrategy(object[name], whereStrategy?.[name], table[name], strategy[name]);
334
+ }
335
+ else
336
+ strategy[name] = true;
337
+ }
338
+ return strategy;
226
339
  }
227
- filter = negotiateFilter(filter);
228
- const _baseFilter = await invokeBaseFilter();
229
- if (_baseFilter)
230
- filter = filter.and(_baseFilter);
231
- let args = [filter].concat(Array.prototype.slice.call(arguments).slice(1));
232
- return table.delete.apply(null, args);
233
- }
234
340
 
235
- async function cascadeDelete(filter) {
236
- if (readonly || disableBulkDeletes) {
237
- const e = new Error('Bulk deletes are not allowed. Parameter "disableBulkDeletes" must be true.');
238
- // @ts-ignore
239
- e.status = 403;
240
- throw e;
241
341
 
342
+ async function aggregate(filter, strategy) {
343
+ validateStrategy(table, strategy);
344
+ filter = negotiateFilter(filter);
345
+ const _baseFilter = await invokeBaseFilter();
346
+ if (_baseFilter)
347
+ filter = filter.and(context, _baseFilter);
348
+ let args = [context, filter].concat(Array.prototype.slice.call(arguments).slice(1));
349
+ await negotiateWhereAndAggregate(strategy);
350
+ return table.aggregate.apply(null, args);
242
351
  }
243
- filter = negotiateFilter(filter);
244
- const _baseFilter = await invokeBaseFilter();
245
- if (_baseFilter)
246
- filter = filter.and(_baseFilter);
247
- let args = [filter].concat(Array.prototype.slice.call(arguments).slice(1));
248
- return table.cascadeDelete.apply(null, args);
249
- }
250
-
251
- function negotiateFilter(filter) {
252
- if (filter)
253
- return negotiateRawSqlFilter(filter, table, true);
254
- else
255
- return emptyFilter;
256
- }
257
352
 
258
- async function count(filter, strategy) {
259
- validateStrategy(table, strategy);
260
- filter = negotiateFilter(filter);
261
- const _baseFilter = await invokeBaseFilter();
262
- if (_baseFilter)
263
- filter = filter.and(_baseFilter);
264
- let args = [filter].concat(Array.prototype.slice.call(arguments).slice(1));
265
- return table.count.apply(null, args);
266
- }
267
353
 
268
- async function getManyDto(filter, strategy) {
269
- validateStrategy(table, strategy);
270
- filter = negotiateFilter(filter);
271
- const _baseFilter = await invokeBaseFilter();
272
- if (_baseFilter)
273
- filter = filter.and(_baseFilter);
274
- let args = [filter].concat(Array.prototype.slice.call(arguments).slice(1));
275
- await negotiateWhereAndAggregate(strategy);
276
- return table.getManyDto.apply(null, args);
277
- }
278
354
 
279
- async function replace(subject, strategy = { insertAndForget: true }) {
280
- validateStrategy(table, strategy);
281
- const refinedStrategy = objectToStrategy(subject, {}, table);
282
- const JSONFilter2 = {
283
- path: 'getManyDto',
284
- args: [subject, refinedStrategy]
285
- };
286
- const originals = await executePath({ table, JSONFilter: JSONFilter2, baseFilter, customFilters, request, response, readonly, disableBulkDeletes, isHttp, client });
287
- const meta = getMeta(table);
288
- const patch = createPatch(originals, Array.isArray(subject) ? subject : [subject], meta);
289
- const { changed } = await table.patch(patch, { strategy });
290
- if (Array.isArray(subject))
291
- return changed;
292
- else
293
- return changed[0];
294
- }
355
+ async function negotiateWhereAndAggregate(strategy) {
356
+ if (typeof strategy !== 'object')
357
+ return;
295
358
 
296
- async function update(subject, whereStrategy, strategy = { insertAndForget: true }) {
297
- validateStrategy(table, strategy);
298
- const refinedWhereStrategy = objectToStrategy(subject, whereStrategy, table);
299
- const JSONFilter2 = {
300
- path: 'getManyDto',
301
- args: [null, refinedWhereStrategy]
302
- };
303
- const rows = await executePath({ table, JSONFilter: JSONFilter2, baseFilter, customFilters, request, response, readonly, disableBulkDeletes, isHttp, client });
304
- const originals = new Array(rows.length);
305
- for (let i = 0; i < rows.length; i++) {
306
- const row = rows[i];
307
- originals[i] = { ...row };
308
- for (let p in subject) {
309
- row[p] = subject[p];
359
+ for (let name in strategy) {
360
+ const target = strategy[name];
361
+ if (isFilter(target))
362
+ strategy[name] = await parseFilter(strategy[name], table);
363
+ else
364
+ await negotiateWhereAndAggregate(strategy[name]);
310
365
  }
311
- }
312
- const meta = getMeta(table);
313
- const patch = createPatch(originals, rows, meta);
314
- const { changed } = await table.patch(patch, { strategy });
315
- return changed;
316
- }
317
366
 
318
- function objectToStrategy(object, whereStrategy, table, strategy = {}) {
319
- strategy = {...whereStrategy, ...strategy};
320
- if (Array.isArray(object)) {
321
- for (let i = 0; i < object.length; i++) {
322
- objectToStrategy(object[i], table, strategy);
323
- }
324
- return;
325
- }
326
- for (let name in object) {
327
- const relation = table[name]?._relation;
328
- if (relation && !relation.columns) {//notJoin, that is one or many
329
- strategy[name] = {};
330
- objectToStrategy(object[name], whereStrategy?.[name], table[name], strategy[name]);
331
- }
332
- else
333
- strategy[name] = true;
334
367
  }
335
- return strategy;
336
- }
337
368
 
369
+ async function getMany(filter, strategy) {
370
+ validateStrategy(table, strategy);
371
+ filter = negotiateFilter(filter);
372
+ const _baseFilter = await invokeBaseFilter();
373
+ if (_baseFilter)
374
+ filter = filter.and(context, _baseFilter);
375
+ let args = [context, filter].concat(Array.prototype.slice.call(arguments).slice(1));
376
+ await negotiateWhereAndAggregate(strategy);
377
+ return table.getMany.apply(null, args);
378
+ }
338
379
 
339
- async function aggregate(filter, strategy) {
340
- validateStrategy(table, strategy);
341
- filter = negotiateFilter(filter);
342
- const _baseFilter = await invokeBaseFilter();
343
- if (_baseFilter)
344
- filter = filter.and(_baseFilter);
345
- let args = [filter].concat(Array.prototype.slice.call(arguments).slice(1));
346
- await negotiateWhereAndAggregate(strategy);
347
- return table.aggregate.apply(null, args);
348
380
  }
349
381
 
350
-
351
-
352
- async function negotiateWhereAndAggregate(strategy) {
353
- if (typeof strategy !== 'object')
382
+ function validateStrategy(table, strategy) {
383
+ if (!strategy || !table)
354
384
  return;
355
385
 
356
- for (let name in strategy) {
357
- const target = strategy[name];
358
- if (isFilter(target))
359
- strategy[name] = await parseFilter(strategy[name], table);
360
- else
361
- await negotiateWhereAndAggregate(strategy[name]);
386
+ for (let p in strategy) {
387
+ validateOffset(strategy);
388
+ validateLimit(strategy);
389
+ validateOrderBy(table, strategy);
390
+ validateStrategy(table[p], strategy[p]);
362
391
  }
363
-
364
392
  }
365
393
 
366
- async function getMany(filter, strategy) {
367
- validateStrategy(table, strategy);
368
- filter = negotiateFilter(filter);
369
- const _baseFilter = await invokeBaseFilter();
370
- if (_baseFilter)
371
- filter = filter.and(_baseFilter);
372
- let args = [filter].concat(Array.prototype.slice.call(arguments).slice(1));
373
- await negotiateWhereAndAggregate(strategy);
374
- return table.getMany.apply(null, args);
394
+ function validateLimit(strategy) {
395
+ if (!('limit' in strategy) || Number.isInteger(strategy.limit))
396
+ return;
397
+ const e = new Error('Invalid limit: ' + strategy.limit);
398
+ // @ts-ignore
399
+ e.status = 400;
375
400
  }
376
401
 
377
- }
378
-
379
- function validateStrategy(table, strategy) {
380
- if (!strategy || !table)
381
- return;
382
-
383
- for (let p in strategy) {
384
- validateOffset(strategy);
385
- validateLimit(strategy);
386
- validateOrderBy(table, strategy);
387
- validateStrategy(table[p], strategy[p]);
402
+ function validateOffset(strategy) {
403
+ if (!('offset' in strategy) || Number.isInteger(strategy.offset))
404
+ return;
405
+ const e = new Error('Invalid offset: ' + strategy.offset);
406
+ // @ts-ignore
407
+ e.status = 400;
408
+ throw e;
388
409
  }
389
- }
390
410
 
391
- function validateLimit(strategy) {
392
- if (!('limit' in strategy) || Number.isInteger(strategy.limit))
393
- return;
394
- const e = new Error('Invalid limit: ' + strategy.limit);
395
- // @ts-ignore
396
- e.status = 400;
397
- }
398
-
399
- function validateOffset(strategy) {
400
- if (!('offset' in strategy) || Number.isInteger(strategy.offset))
401
- return;
402
- const e = new Error('Invalid offset: ' + strategy.offset);
403
- // @ts-ignore
404
- e.status = 400;
405
- throw e;
406
- }
411
+ function validateOrderBy(table, strategy) {
412
+ if (!('orderBy' in strategy) || !table)
413
+ return;
414
+ let orderBy = strategy.orderBy;
415
+ if (!Array.isArray(orderBy))
416
+ orderBy = [orderBy];
417
+ orderBy.reduce(validate, []);
418
+
419
+ function validate(_, element) {
420
+ let parts = element.split(' ').filter(x => {
421
+ x = x.toLowerCase();
422
+ return (!(x === '' || x === 'asc' || x === 'desc'));
423
+ });
424
+ for (let p of parts) {
425
+ let col = table[p];
426
+ if (!(col && col.equal)) {
427
+ const e = new Error('Unknown column: ' + p);
428
+ // @ts-ignore
429
+ e.status = 400;
430
+ throw e;
431
+ }
432
+ }
433
+ }
434
+ }
407
435
 
408
- function validateOrderBy(table, strategy) {
409
- if (!('orderBy' in strategy) || !table)
410
- return;
411
- let orderBy = strategy.orderBy;
412
- if (!Array.isArray(orderBy))
413
- orderBy = [orderBy];
414
- orderBy.reduce(validate, []);
415
-
416
- function validate(_, element) {
417
- let parts = element.split(' ').filter(x => {
418
- x = x.toLowerCase();
419
- return (!(x === '' || x === 'asc' || x === 'desc'));
420
- });
421
- for (let p of parts) {
422
- let col = table[p];
423
- if (!(col && col.equal)) {
424
- const e = new Error('Unknown column: ' + p);
436
+ function validateArgs() {
437
+ for (let i = 0; i < arguments.length; i++) {
438
+ const filter = arguments[i];
439
+ if (!filter)
440
+ continue;
441
+ if (filter && filter.isSafe === isSafe)
442
+ continue;
443
+ if (filter.sql || typeof (filter) === 'string') {
444
+ const e = new Error('Raw filters are disallowed');
425
445
  // @ts-ignore
426
- e.status = 400;
446
+ e.status = 403;
427
447
  throw e;
428
448
  }
429
- }
430
- }
431
- }
449
+ if (Array.isArray(filter))
450
+ for (let i = 0; i < filter.length; i++) {
432
451
 
433
- function validateArgs() {
434
- for (let i = 0; i < arguments.length; i++) {
435
- const filter = arguments[i];
436
- if (!filter)
437
- continue;
438
- if (filter && filter.isSafe === isSafe)
439
- continue;
440
- if (filter.sql || typeof (filter) === 'string') {
441
- const e = new Error('Raw filters are disallowed');
442
- // @ts-ignore
443
- e.status = 403;
444
- throw e;
452
+ validateArgs(filter[i]);
453
+ }
445
454
  }
446
- if (Array.isArray(filter))
447
- for (let i = 0; i < filter.length; i++) {
448
455
 
449
- validateArgs(filter[i]);
450
- }
451
456
  }
452
457
 
453
- }
458
+ function isFilter(json) {
459
+ return json instanceof Object && 'path' in json && 'args' in json;
460
+ }
454
461
 
455
- function isFilter(json) {
456
- return json instanceof Object && 'path' in json && 'args' in json;
457
- }
462
+ function setSafe(o) {
463
+ if (o instanceof Object)
464
+ Object.defineProperty(o, 'isSafe', {
465
+ value: isSafe,
466
+ enumerable: false
458
467
 
459
- function setSafe(o) {
460
- if (o instanceof Object)
461
- Object.defineProperty(o, 'isSafe', {
462
- value: isSafe,
463
- enumerable: false
468
+ });
469
+ }
464
470
 
465
- });
466
- }
471
+ function extractRelations(obj) {
472
+ let flattened = {};
467
473
 
468
- function extractRelations(obj) {
469
- let flattened = {};
474
+ function helper(relations) {
475
+ Object.keys(relations).forEach(key => {
470
476
 
471
- function helper(relations) {
472
- Object.keys(relations).forEach(key => {
477
+ flattened[key] = true;
473
478
 
474
- flattened[key] = true;
479
+ if (typeof relations[key] === 'object' && Object.keys(relations[key]?.relations)?.length > 0) {
480
+ helper(relations[key].relations);
481
+ }
482
+ });
483
+ }
475
484
 
476
- if (typeof relations[key] === 'object' && Object.keys(relations[key]?.relations)?.length > 0) {
477
- helper(relations[key].relations);
478
- }
479
- });
485
+ helper(obj.relations);
486
+
487
+ return flattened;
480
488
  }
481
489
 
482
- helper(obj.relations);
490
+ function bindDb(client) {
491
+ var domain = context;
492
+ let p = domain.run(() => true);
483
493
 
484
- return flattened;
485
- }
494
+ function run(fn) {
495
+ return p.then(domain.run.bind(domain, fn));
496
+ }
486
497
 
487
- function bindDb(client) {
488
- // @ts-ignore
489
- var domain = process.domain;
490
- let p = domain.run(() => true);
498
+ return client({ transaction: run });
491
499
 
492
- function run(fn) {
493
- return p.then(domain.run.bind(domain, fn));
494
500
  }
495
-
496
- return client({ transaction: run });
497
-
498
501
  }
499
- module.exports = executePath;
502
+ module.exports = _executePath;