@abedmurrar/objection 4.0.0-alpha.0 → 4.0.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 (192) hide show
  1. package/README.md +103 -67
  2. package/lib/index.mjs +6 -0
  3. package/lib/initialize.js +6 -9
  4. package/lib/model/AjvValidator.js +235 -282
  5. package/lib/model/Model.js +653 -823
  6. package/lib/model/ModifierNotFoundError.js +5 -7
  7. package/lib/model/NotFoundError.js +14 -18
  8. package/lib/model/RelationDoesNotExistError.js +6 -9
  9. package/lib/model/ValidationError.js +33 -41
  10. package/lib/model/Validator.js +15 -21
  11. package/lib/model/getModel.js +1 -3
  12. package/lib/model/graph/ModelGraph.js +44 -64
  13. package/lib/model/graph/ModelGraphBuilder.js +164 -217
  14. package/lib/model/graph/ModelGraphEdge.js +31 -43
  15. package/lib/model/graph/ModelGraphNode.js +192 -231
  16. package/lib/model/inheritModel.js +9 -18
  17. package/lib/model/modelBindKnex.js +48 -62
  18. package/lib/model/modelClone.js +79 -98
  19. package/lib/model/modelColPropMap.js +16 -26
  20. package/lib/model/modelConcurrency.js +24 -0
  21. package/lib/model/modelId.js +44 -49
  22. package/lib/model/modelJsonAttributes.js +56 -76
  23. package/lib/model/modelParseRelations.js +68 -67
  24. package/lib/model/modelQueryProps.js +76 -107
  25. package/lib/model/modelSet.js +92 -112
  26. package/lib/model/modelTableMetadata.js +60 -72
  27. package/lib/model/modelToJson.js +120 -150
  28. package/lib/model/modelUtils.js +30 -37
  29. package/lib/model/modelValidate.js +34 -42
  30. package/lib/model/modelValues.js +78 -91
  31. package/lib/model/modelVisitor.js +22 -29
  32. package/lib/objection.js +42 -67
  33. package/lib/queryBuilder/FunctionBuilder.js +231 -279
  34. package/lib/queryBuilder/InternalOptions.js +19 -24
  35. package/lib/queryBuilder/JoinBuilder.js +116 -149
  36. package/lib/queryBuilder/QueryBuilder.js +1009 -1271
  37. package/lib/queryBuilder/QueryBuilderBase.js +647 -865
  38. package/lib/queryBuilder/QueryBuilderContext.js +14 -21
  39. package/lib/queryBuilder/QueryBuilderContextBase.js +20 -29
  40. package/lib/queryBuilder/QueryBuilderOperationSupport.js +462 -536
  41. package/lib/queryBuilder/QueryBuilderUserContext.js +19 -25
  42. package/lib/queryBuilder/RawBuilder.js +58 -73
  43. package/lib/queryBuilder/ReferenceBuilder.js +232 -270
  44. package/lib/queryBuilder/RelationExpression.js +322 -380
  45. package/lib/queryBuilder/StaticHookArguments.js +94 -106
  46. package/lib/queryBuilder/ValueBuilder.js +100 -112
  47. package/lib/queryBuilder/expressions.js +86 -116
  48. package/lib/queryBuilder/functions/mysql.js +642 -697
  49. package/lib/queryBuilder/graph/GraphAction.js +44 -59
  50. package/lib/queryBuilder/graph/GraphData.js +7 -9
  51. package/lib/queryBuilder/graph/GraphFetcher.js +115 -151
  52. package/lib/queryBuilder/graph/GraphNodeDbExistence.js +114 -152
  53. package/lib/queryBuilder/graph/GraphOperation.js +16 -22
  54. package/lib/queryBuilder/graph/GraphOptions.js +143 -185
  55. package/lib/queryBuilder/graph/GraphUpsert.js +167 -241
  56. package/lib/queryBuilder/graph/delete/GraphDelete.js +8 -13
  57. package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +44 -62
  58. package/lib/queryBuilder/graph/insert/GraphInsert.js +99 -128
  59. package/lib/queryBuilder/graph/insert/GraphInsertAction.js +151 -193
  60. package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +57 -79
  61. package/lib/queryBuilder/graph/patch/GraphPatch.js +8 -13
  62. package/lib/queryBuilder/graph/patch/GraphPatchAction.js +181 -234
  63. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +16 -21
  64. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +80 -110
  65. package/lib/queryBuilder/join/JoinResultColumn.js +14 -18
  66. package/lib/queryBuilder/join/JoinResultParser.js +88 -101
  67. package/lib/queryBuilder/join/RelationJoiner.js +205 -288
  68. package/lib/queryBuilder/join/TableNode.js +117 -144
  69. package/lib/queryBuilder/join/TableTree.js +60 -76
  70. package/lib/queryBuilder/join/utils.js +10 -16
  71. package/lib/queryBuilder/operations/DelegateOperation.js +93 -133
  72. package/lib/queryBuilder/operations/DeleteOperation.js +33 -37
  73. package/lib/queryBuilder/operations/FindByIdOperation.js +20 -28
  74. package/lib/queryBuilder/operations/FindByIdsOperation.js +17 -23
  75. package/lib/queryBuilder/operations/FindOperation.js +114 -131
  76. package/lib/queryBuilder/operations/FirstOperation.js +14 -19
  77. package/lib/queryBuilder/operations/FromOperation.js +69 -88
  78. package/lib/queryBuilder/operations/InsertAndFetchOperation.js +28 -39
  79. package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +25 -35
  80. package/lib/queryBuilder/operations/InsertGraphOperation.js +77 -98
  81. package/lib/queryBuilder/operations/InsertOperation.js +132 -165
  82. package/lib/queryBuilder/operations/InstanceDeleteOperation.js +27 -36
  83. package/lib/queryBuilder/operations/InstanceFindOperation.js +9 -13
  84. package/lib/queryBuilder/operations/InstanceInsertOperation.js +13 -17
  85. package/lib/queryBuilder/operations/InstanceUpdateOperation.js +32 -46
  86. package/lib/queryBuilder/operations/JoinRelatedOperation.js +66 -86
  87. package/lib/queryBuilder/operations/KnexOperation.js +4 -7
  88. package/lib/queryBuilder/operations/MergeOperation.js +32 -45
  89. package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +131 -150
  90. package/lib/queryBuilder/operations/OnBuildKnexOperation.js +17 -23
  91. package/lib/queryBuilder/operations/OnBuildOperation.js +17 -23
  92. package/lib/queryBuilder/operations/OnErrorOperation.js +17 -23
  93. package/lib/queryBuilder/operations/QueryBuilderOperation.js +231 -270
  94. package/lib/queryBuilder/operations/RangeOperation.js +30 -40
  95. package/lib/queryBuilder/operations/RelateOperation.js +14 -21
  96. package/lib/queryBuilder/operations/ReturningOperation.js +12 -18
  97. package/lib/queryBuilder/operations/RunAfterOperation.js +17 -23
  98. package/lib/queryBuilder/operations/RunBeforeOperation.js +17 -23
  99. package/lib/queryBuilder/operations/UnrelateOperation.js +12 -17
  100. package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +48 -65
  101. package/lib/queryBuilder/operations/UpdateOperation.js +104 -129
  102. package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +25 -35
  103. package/lib/queryBuilder/operations/UpsertGraphOperation.js +36 -55
  104. package/lib/queryBuilder/operations/WhereCompositeOperation.js +30 -39
  105. package/lib/queryBuilder/operations/WhereInOperation.js +34 -36
  106. package/lib/queryBuilder/operations/eager/EagerOperation.js +37 -52
  107. package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +34 -44
  108. package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +4 -7
  109. package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +193 -251
  110. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +18 -25
  111. package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +25 -41
  112. package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +19 -20
  113. package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +23 -21
  114. package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +106 -118
  115. package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +79 -108
  116. package/lib/queryBuilder/operations/select/SelectOperation.js +37 -53
  117. package/lib/queryBuilder/operations/select/Selection.js +94 -105
  118. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +68 -101
  119. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +65 -75
  120. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +75 -84
  121. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +760 -859
  122. package/lib/queryBuilder/parsers/relationExpressionParser.js +840 -952
  123. package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +10 -15
  124. package/lib/queryBuilder/transformations/QueryTransformation.js +4 -6
  125. package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +35 -49
  126. package/lib/queryBuilder/transformations/index.js +3 -9
  127. package/lib/queryBuilder/whereScopes.js +158 -186
  128. package/lib/relations/Relation.js +293 -375
  129. package/lib/relations/RelationDeleteOperation.js +24 -28
  130. package/lib/relations/RelationFindOperation.js +108 -138
  131. package/lib/relations/RelationInsertOperation.js +24 -32
  132. package/lib/relations/RelationOwner.js +175 -209
  133. package/lib/relations/RelationProperty.js +186 -223
  134. package/lib/relations/RelationUpdateOperation.js +23 -29
  135. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +16 -21
  136. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +30 -41
  137. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +36 -47
  138. package/lib/relations/belongsToOne/BelongsToOneRelation.js +42 -50
  139. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +43 -58
  140. package/lib/relations/hasMany/HasManyInsertOperation.js +40 -56
  141. package/lib/relations/hasMany/HasManyRelateOperation.js +45 -61
  142. package/lib/relations/hasMany/HasManyRelation.js +38 -46
  143. package/lib/relations/hasMany/HasManyUnrelateOperation.js +25 -32
  144. package/lib/relations/hasOne/HasOneRelation.js +9 -12
  145. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +9 -12
  146. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +73 -95
  147. package/lib/relations/manyToMany/ManyToManyRelation.js +374 -473
  148. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +23 -30
  149. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +8 -10
  150. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +20 -25
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +8 -12
  152. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +77 -100
  153. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +37 -49
  154. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +58 -74
  155. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +10 -13
  156. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +26 -33
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +10 -15
  158. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +8 -10
  159. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +61 -78
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +8 -12
  161. package/lib/transaction.js +53 -83
  162. package/lib/utils/assert.js +15 -21
  163. package/lib/utils/buildUtils.js +17 -19
  164. package/lib/utils/classUtils.js +7 -11
  165. package/lib/utils/cloneDeep.js +365 -0
  166. package/lib/utils/createModifier.js +36 -41
  167. package/lib/utils/deprecate.js +8 -12
  168. package/lib/utils/identifierMapping.js +153 -192
  169. package/lib/utils/internalPropUtils.js +4 -8
  170. package/lib/utils/knexUtils.js +61 -56
  171. package/lib/utils/mixin.js +16 -23
  172. package/lib/utils/mysqlJsonPath.js +55 -40
  173. package/lib/utils/normalizeIds.js +110 -127
  174. package/lib/utils/objectUtils.js +236 -338
  175. package/lib/utils/parseFieldExpression.js +66 -44
  176. package/lib/utils/postgresJsonPath.js +48 -62
  177. package/lib/utils/promiseUtils/after.js +10 -13
  178. package/lib/utils/promiseUtils/afterReturn.js +10 -13
  179. package/lib/utils/promiseUtils/index.js +15 -17
  180. package/lib/utils/promiseUtils/isPromise.js +6 -9
  181. package/lib/utils/promiseUtils/map.js +75 -89
  182. package/lib/utils/promiseUtils/mapAfterAllReturn.js +17 -23
  183. package/lib/utils/promiseUtils/try.js +15 -18
  184. package/lib/utils/resolveModel.js +91 -94
  185. package/lib/utils/tmpColumnUtils.js +4 -13
  186. package/package.json +50 -23
  187. package/typings/objection/index.d.mts +362 -0
  188. package/typings/objection/index.d.ts +36 -9
  189. package/lib/.eslintrc.json +0 -8
  190. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +0 -97
  191. package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +0 -141
  192. package/lib/utils/clone.js +0 -2329
@@ -1,431 +1,373 @@
1
1
  'use strict';
2
-
3
2
  const parser = require('./parsers/relationExpressionParser');
4
3
  const { isObject, isNumber, isString, union } = require('../utils/objectUtils');
5
4
  const { RelationDoesNotExistError } = require('../model/RelationDoesNotExistError');
6
-
7
- class RelationExpressionParseError extends Error {}
5
+ class RelationExpressionParseError extends Error {
6
+ }
8
7
  class DuplicateRelationError extends RelationExpressionParseError {
9
- constructor(relationName) {
10
- super();
11
- this.relationName = relationName;
12
- }
8
+ constructor(relationName) {
9
+ super();
10
+ this.relationName = relationName;
11
+ }
13
12
  }
14
-
15
13
  class RelationExpression {
16
- constructor(node = newNode(), recursionDepth = 0) {
17
- this.node = node;
18
- this.recursionDepth = recursionDepth;
19
- }
20
-
21
- // Create a relation expression from a string, a pojo or another
22
- // RelationExpression instance.
23
- static create(expr) {
24
- if (isObject(expr)) {
25
- if (expr.isObjectionRelationExpression) {
26
- return expr;
27
- } else {
28
- return new RelationExpression(normalizeNode(expr));
29
- }
30
- } else if (isString(expr)) {
31
- if (expr.trim().length === 0) {
32
- return new RelationExpression();
33
- } else {
34
- try {
35
- return new RelationExpression(parse(expr));
36
- } catch (err) {
37
- if (err.duplicateRelationName) {
38
- throw new DuplicateRelationError(err.duplicateRelationName);
39
- } else {
40
- throw new RelationExpressionParseError(err.message);
41
- }
14
+ constructor(node = newNode(), recursionDepth = 0) {
15
+ this.node = node;
16
+ this.recursionDepth = recursionDepth;
17
+ }
18
+ // Create a relation expression from a string, a pojo or another
19
+ // RelationExpression instance.
20
+ static create(expr) {
21
+ if (isObject(expr)) {
22
+ if (expr.isObjectionRelationExpression) {
23
+ return expr;
24
+ }
25
+ else {
26
+ return new RelationExpression(normalizeNode(expr));
27
+ }
28
+ }
29
+ else if (isString(expr)) {
30
+ if (expr.trim().length === 0) {
31
+ return new RelationExpression();
32
+ }
33
+ else {
34
+ try {
35
+ return new RelationExpression(parse(expr));
36
+ }
37
+ catch (err) {
38
+ if (err.duplicateRelationName) {
39
+ throw new DuplicateRelationError(err.duplicateRelationName);
40
+ }
41
+ else {
42
+ throw new RelationExpressionParseError(err.message);
43
+ }
44
+ }
45
+ }
46
+ }
47
+ else {
48
+ return new RelationExpression();
49
+ }
50
+ }
51
+ // Create a relation expression from a model graph.
52
+ static fromModelGraph(graph) {
53
+ if (!graph) {
54
+ return new RelationExpression();
55
+ }
56
+ else {
57
+ return new RelationExpression(modelGraphToNode(graph, newNode()));
58
+ }
59
+ }
60
+ get maxRecursionDepth() {
61
+ if (isNumber(this.node.$recursive)) {
62
+ return this.node.$recursive;
63
+ }
64
+ else {
65
+ return this.node.$recursive ? Number.MAX_SAFE_INTEGER : 0;
66
+ }
67
+ }
68
+ get numChildren() {
69
+ return this.node.$childNames.length;
70
+ }
71
+ get isEmpty() {
72
+ return this.numChildren === 0;
73
+ }
74
+ // Merges this relation expression with another. `expr` can be a string,
75
+ // a pojo, or a RelationExpression instance.
76
+ merge(expr) {
77
+ expr = RelationExpression.create(expr);
78
+ if (this.isEmpty) {
79
+ // Nothing to merge.
80
+ return expr;
81
+ }
82
+ return new RelationExpression(mergeNodes(this.node, expr.node));
83
+ }
84
+ // Returns true if `expr` is contained by this expression. For example
85
+ // `a.b` is contained by `a.[b, c]`.
86
+ isSubExpression(expr) {
87
+ expr = RelationExpression.create(expr);
88
+ if (this.node.$allRecursive) {
89
+ return true;
90
+ }
91
+ if (expr.node.$allRecursive) {
92
+ return this.node.$allRecursive;
42
93
  }
43
- }
44
- } else {
45
- return new RelationExpression();
46
- }
47
- }
48
-
49
- // Create a relation expression from a model graph.
50
- static fromModelGraph(graph) {
51
- if (!graph) {
52
- return new RelationExpression();
53
- } else {
54
- return new RelationExpression(modelGraphToNode(graph, newNode()));
55
- }
56
- }
57
-
58
- get maxRecursionDepth() {
59
- if (isNumber(this.node.$recursive)) {
60
- return this.node.$recursive;
61
- } else {
62
- return this.node.$recursive ? Number.MAX_SAFE_INTEGER : 0;
63
- }
64
- }
65
-
66
- get numChildren() {
67
- return this.node.$childNames.length;
68
- }
69
-
70
- get isEmpty() {
71
- return this.numChildren === 0;
72
- }
73
-
74
- // Merges this relation expression with another. `expr` can be a string,
75
- // a pojo, or a RelationExpression instance.
76
- merge(expr) {
77
- expr = RelationExpression.create(expr);
78
-
79
- if (this.isEmpty) {
80
- // Nothing to merge.
81
- return expr;
82
- }
83
-
84
- return new RelationExpression(mergeNodes(this.node, expr.node));
85
- }
86
-
87
- // Returns true if `expr` is contained by this expression. For example
88
- // `a.b` is contained by `a.[b, c]`.
89
- isSubExpression(expr) {
90
- expr = RelationExpression.create(expr);
91
-
92
- if (this.node.$allRecursive) {
93
- return true;
94
- }
95
-
96
- if (expr.node.$allRecursive) {
97
- return this.node.$allRecursive;
98
- }
99
-
100
- if (this.node.$relation !== expr.node.$relation) {
101
- return false;
102
- }
103
-
104
- const maxRecursionDepth = expr.maxRecursionDepth;
105
-
106
- if (maxRecursionDepth > 0) {
107
- return this.node.$allRecursive || this.maxRecursionDepth >= maxRecursionDepth;
108
- }
109
-
110
- for (const childName of expr.node.$childNames) {
111
- const ownSubExpression = this.childExpression(childName);
112
- const subExpression = expr.childExpression(childName);
113
-
114
- if (!ownSubExpression || !ownSubExpression.isSubExpression(subExpression)) {
115
- return false;
116
- }
117
- }
118
-
119
- return true;
120
- }
121
-
122
- // Returns a RelationExpression for a child node or null if there
123
- // is no child with the given name `childName`.
124
- childExpression(childName) {
125
- if (
126
- this.node.$allRecursive ||
127
- (childName === this.node.$name && this.recursionDepth < this.maxRecursionDepth - 1)
128
- ) {
129
- return new RelationExpression(this.node, this.recursionDepth + 1);
130
- }
131
-
132
- const child = this.node[childName];
133
-
134
- if (child) {
135
- return new RelationExpression(child);
136
- } else {
137
- return null;
138
- }
139
- }
140
-
141
- // Loops throught all first level children.
142
- forEachChildExpression(modelClass, cb) {
143
- const maxRecursionDepth = this.maxRecursionDepth;
144
-
145
- if (this.node.$allRecursive) {
146
- for (const relationName of modelClass.getRelationNames()) {
147
- const node = newNode(relationName, true);
148
- const relation = modelClass.getRelationUnsafe(relationName);
149
- const childExpr = new RelationExpression(node);
150
-
151
- cb(childExpr, relation);
152
- }
153
- } else if (this.recursionDepth < maxRecursionDepth - 1) {
154
- const relation = modelClass.getRelationUnsafe(this.node.$relation) || null;
155
- const childExpr = new RelationExpression(this.node, this.recursionDepth + 1);
156
-
157
- cb(childExpr, relation);
158
- } else if (maxRecursionDepth === 0) {
159
- for (const childName of this.node.$childNames) {
160
- const node = this.node[childName];
161
- const relation = modelClass.getRelationUnsafe(node.$relation);
162
-
163
- if (!relation) {
164
- throw new RelationDoesNotExistError(node.$relation);
94
+ if (this.node.$relation !== expr.node.$relation) {
95
+ return false;
165
96
  }
166
-
167
- const childExpr = new RelationExpression(node);
168
-
169
- cb(childExpr, relation);
170
- }
171
- }
172
- }
173
-
174
- expressionsAtPath(path) {
175
- return findExpressionsAtPath(this, RelationExpression.create(path), []);
176
- }
177
-
178
- clone() {
179
- return new RelationExpression(cloneNode(this.node), this.recursionDepth);
180
- }
181
-
182
- toString() {
183
- return toString(this.node);
184
- }
185
-
186
- toPojo() {
187
- return cloneNode(this.node);
188
- }
189
-
190
- toJSON() {
191
- return this.toPojo();
192
- }
97
+ const maxRecursionDepth = expr.maxRecursionDepth;
98
+ if (maxRecursionDepth > 0) {
99
+ return this.node.$allRecursive || this.maxRecursionDepth >= maxRecursionDepth;
100
+ }
101
+ for (const childName of expr.node.$childNames) {
102
+ const ownSubExpression = this.childExpression(childName);
103
+ const subExpression = expr.childExpression(childName);
104
+ if (!ownSubExpression || !ownSubExpression.isSubExpression(subExpression)) {
105
+ return false;
106
+ }
107
+ }
108
+ return true;
109
+ }
110
+ // Returns a RelationExpression for a child node or null if there
111
+ // is no child with the given name `childName`.
112
+ childExpression(childName) {
113
+ if (this.node.$allRecursive ||
114
+ (childName === this.node.$name && this.recursionDepth < this.maxRecursionDepth - 1)) {
115
+ return new RelationExpression(this.node, this.recursionDepth + 1);
116
+ }
117
+ const child = this.node[childName];
118
+ if (child) {
119
+ return new RelationExpression(child);
120
+ }
121
+ else {
122
+ return null;
123
+ }
124
+ }
125
+ // Loops throught all first level children.
126
+ forEachChildExpression(modelClass, cb) {
127
+ const maxRecursionDepth = this.maxRecursionDepth;
128
+ if (this.node.$allRecursive) {
129
+ for (const relationName of modelClass.getRelationNames()) {
130
+ const node = newNode(relationName, true);
131
+ const relation = modelClass.getRelationUnsafe(relationName);
132
+ const childExpr = new RelationExpression(node);
133
+ cb(childExpr, relation);
134
+ }
135
+ }
136
+ else if (this.recursionDepth < maxRecursionDepth - 1) {
137
+ const relation = modelClass.getRelationUnsafe(this.node.$relation) || null;
138
+ const childExpr = new RelationExpression(this.node, this.recursionDepth + 1);
139
+ cb(childExpr, relation);
140
+ }
141
+ else if (maxRecursionDepth === 0) {
142
+ for (const childName of this.node.$childNames) {
143
+ const node = this.node[childName];
144
+ const relation = modelClass.getRelationUnsafe(node.$relation);
145
+ if (!relation) {
146
+ throw new RelationDoesNotExistError(node.$relation);
147
+ }
148
+ const childExpr = new RelationExpression(node);
149
+ cb(childExpr, relation);
150
+ }
151
+ }
152
+ }
153
+ expressionsAtPath(path) {
154
+ return findExpressionsAtPath(this, RelationExpression.create(path), []);
155
+ }
156
+ clone() {
157
+ return new RelationExpression(cloneNode(this.node), this.recursionDepth);
158
+ }
159
+ toString() {
160
+ return toString(this.node);
161
+ }
162
+ toPojo() {
163
+ return cloneNode(this.node);
164
+ }
165
+ toJSON() {
166
+ return this.toPojo();
167
+ }
193
168
  }
194
-
195
169
  const parseCache = new Map();
196
170
  function parse(str) {
197
- const cachedNode = parseCache.get(str);
198
-
199
- if (cachedNode) {
200
- return cloneNode(cachedNode);
201
- } else {
202
- const node = parser.parse(str);
203
- parseCache.set(str, cloneNode(node));
204
- return node;
205
- }
171
+ const cachedNode = parseCache.get(str);
172
+ if (cachedNode) {
173
+ return cloneNode(cachedNode);
174
+ }
175
+ else {
176
+ const node = parser.parse(str);
177
+ parseCache.set(str, cloneNode(node));
178
+ return node;
179
+ }
206
180
  }
207
-
208
181
  // All enumerable properties of a node that don't start with `$`
209
182
  // are child nodes.
210
183
  function getChildNames(node) {
211
- if (!node) {
212
- return [];
213
- }
214
-
215
- const childNames = [];
216
-
217
- for (const key of Object.keys(node)) {
218
- if (key[0] !== '$') {
219
- childNames.push(key);
220
- }
221
- }
222
-
223
- return childNames;
184
+ if (!node) {
185
+ return [];
186
+ }
187
+ const childNames = [];
188
+ for (const key of Object.keys(node)) {
189
+ if (key[0] !== '$') {
190
+ childNames.push(key);
191
+ }
192
+ }
193
+ return childNames;
224
194
  }
225
-
226
195
  function toString(node) {
227
- const childNames = node.$childNames;
228
-
229
- let childExpr = childNames.map((childName) => node[childName]).map(toString);
230
- let str = node.$relation;
231
-
232
- if (node.$recursive) {
233
- if (isNumber(node.$recursive)) {
234
- str += '.^' + node.$recursive;
235
- } else {
236
- str += '.^';
237
- }
238
- } else if (node.$allRecursive) {
239
- str += '.*';
240
- }
241
-
242
- if (childExpr.length > 1) {
243
- childExpr = `[${childExpr.join(', ')}]`;
244
- } else {
245
- childExpr = childExpr[0];
246
- }
247
-
248
- if (node.$modify.length) {
249
- str += `(${node.$modify.join(', ')})`;
250
- }
251
-
252
- if (node.$name !== node.$relation) {
253
- str += ` as ${node.$name}`;
254
- }
255
-
256
- if (childExpr) {
257
- if (str) {
258
- return `${str}.${childExpr}`;
259
- } else {
260
- return childExpr;
261
- }
262
- } else {
263
- return str;
264
- }
196
+ const childNames = node.$childNames;
197
+ let childExpr = childNames.map((childName) => node[childName]).map(toString);
198
+ let str = node.$relation;
199
+ if (node.$recursive) {
200
+ if (isNumber(node.$recursive)) {
201
+ str += '.^' + node.$recursive;
202
+ }
203
+ else {
204
+ str += '.^';
205
+ }
206
+ }
207
+ else if (node.$allRecursive) {
208
+ str += '.*';
209
+ }
210
+ if (childExpr.length > 1) {
211
+ childExpr = `[${childExpr.join(', ')}]`;
212
+ }
213
+ else {
214
+ childExpr = childExpr[0];
215
+ }
216
+ if (node.$modify.length) {
217
+ str += `(${node.$modify.join(', ')})`;
218
+ }
219
+ if (node.$name !== node.$relation) {
220
+ str += ` as ${node.$name}`;
221
+ }
222
+ if (childExpr) {
223
+ if (str) {
224
+ return `${str}.${childExpr}`;
225
+ }
226
+ else {
227
+ return childExpr;
228
+ }
229
+ }
230
+ else {
231
+ return str;
232
+ }
265
233
  }
266
-
267
234
  function cloneNode(node) {
268
- return normalizeNode(node);
235
+ return normalizeNode(node);
269
236
  }
270
-
271
237
  function modelGraphToNode(models, node) {
272
- if (!models) {
273
- return;
274
- }
275
-
276
- if (Array.isArray(models)) {
277
- for (let i = 0, l = models.length; i < l; ++i) {
278
- modelToNode(models[i], node);
279
- }
280
- } else {
281
- modelToNode(models, node);
282
- }
283
-
284
- return node;
238
+ if (!models) {
239
+ return;
240
+ }
241
+ if (Array.isArray(models)) {
242
+ for (let i = 0, l = models.length; i < l; ++i) {
243
+ modelToNode(models[i], node);
244
+ }
245
+ }
246
+ else {
247
+ modelToNode(models, node);
248
+ }
249
+ return node;
285
250
  }
286
-
287
251
  function modelToNode(model, node) {
288
- const modelClass = model.constructor;
289
- const relationNames = modelClass.getRelationNames();
290
-
291
- for (let r = 0, lr = relationNames.length; r < lr; ++r) {
292
- const relName = relationNames[r];
293
-
294
- if (model[relName] !== undefined) {
295
- let childNode = node[relName];
296
-
297
- if (!childNode) {
298
- childNode = newNode(relName);
299
- node[relName] = childNode;
300
- node.$childNames.push(relName);
301
- }
302
-
303
- modelGraphToNode(model[relName], childNode);
304
- }
305
- }
252
+ const modelClass = model.constructor;
253
+ const relationNames = modelClass.getRelationNames();
254
+ for (let r = 0, lr = relationNames.length; r < lr; ++r) {
255
+ const relName = relationNames[r];
256
+ if (model[relName] !== undefined) {
257
+ let childNode = node[relName];
258
+ if (!childNode) {
259
+ childNode = newNode(relName);
260
+ node[relName] = childNode;
261
+ node.$childNames.push(relName);
262
+ }
263
+ modelGraphToNode(model[relName], childNode);
264
+ }
265
+ }
306
266
  }
307
-
308
267
  function newNode(name = null, allRecusive = false) {
309
- return normalizeNode(null, name, allRecusive);
268
+ return normalizeNode(null, name, allRecusive);
310
269
  }
311
-
312
270
  function normalizeNode(node = null, name = null, allRecusive = false) {
313
- const normalized = {
314
- $name: normalizeName(node, name),
315
- $relation: normalizeRelation(node, name),
316
- $modify: normalizeModify(node),
317
- $recursive: normalizeRecursive(node),
318
- $allRecursive: normalizeAllRecursive(node, allRecusive),
319
- $childNames: normalizeChildNames(node),
320
- };
321
-
322
- for (const childName of normalized.$childNames) {
323
- const childNode = node[childName];
324
-
325
- if (isObject(childNode) || childNode === true) {
326
- normalized[childName] = normalizeNode(childNode, childName);
327
- }
328
- }
329
-
330
- return normalized;
271
+ const normalized = {
272
+ $name: normalizeName(node, name),
273
+ $relation: normalizeRelation(node, name),
274
+ $modify: normalizeModify(node),
275
+ $recursive: normalizeRecursive(node),
276
+ $allRecursive: normalizeAllRecursive(node, allRecusive),
277
+ $childNames: normalizeChildNames(node),
278
+ };
279
+ for (const childName of normalized.$childNames) {
280
+ const childNode = node[childName];
281
+ if (isObject(childNode) || childNode === true) {
282
+ normalized[childName] = normalizeNode(childNode, childName);
283
+ }
284
+ }
285
+ return normalized;
331
286
  }
332
-
333
287
  function normalizeName(node, name) {
334
- return (node && node.$name) || name || null;
288
+ return (node && node.$name) || name || null;
335
289
  }
336
-
337
290
  function normalizeRelation(node, name) {
338
- return (node && node.$relation) || name || null;
291
+ return (node && node.$relation) || name || null;
339
292
  }
340
-
341
293
  function normalizeModify(node) {
342
- if (!node || !node.$modify) {
343
- return [];
344
- }
345
-
346
- return Array.isArray(node.$modify) ? node.$modify.slice() : [node.$modify];
294
+ if (!node || !node.$modify) {
295
+ return [];
296
+ }
297
+ return Array.isArray(node.$modify) ? node.$modify.slice() : [node.$modify];
347
298
  }
348
-
349
299
  function normalizeRecursive(node) {
350
- return (node && node.$recursive) || false;
300
+ return (node && node.$recursive) || false;
351
301
  }
352
-
353
302
  function normalizeAllRecursive(node, allRecusive) {
354
- return (node && node.$allRecursive) || allRecusive || false;
303
+ return (node && node.$allRecursive) || allRecusive || false;
355
304
  }
356
-
357
305
  function normalizeChildNames(node) {
358
- return (node && node.$childNames && node.$childNames.slice()) || getChildNames(node);
306
+ return (node && node.$childNames && node.$childNames.slice()) || getChildNames(node);
359
307
  }
360
-
361
308
  function findExpressionsAtPath(target, path, results) {
362
- if (path.node.$childNames.length == 0) {
363
- // Path leaf reached, add target node to result set.
364
- results.push(target);
365
- } else {
366
- for (const childName of path.node.$childNames) {
367
- const pathChild = path.childExpression(childName);
368
- const targetChild = target.childExpression(childName);
369
-
370
- if (targetChild) {
371
- findExpressionsAtPath(targetChild, pathChild, results);
372
- }
373
- }
374
- }
375
-
376
- return results;
309
+ if (path.node.$childNames.length == 0) {
310
+ // Path leaf reached, add target node to result set.
311
+ results.push(target);
312
+ }
313
+ else {
314
+ for (const childName of path.node.$childNames) {
315
+ const pathChild = path.childExpression(childName);
316
+ const targetChild = target.childExpression(childName);
317
+ if (targetChild) {
318
+ findExpressionsAtPath(targetChild, pathChild, results);
319
+ }
320
+ }
321
+ }
322
+ return results;
377
323
  }
378
-
379
324
  function mergeNodes(node1, node2) {
380
- const node = {
381
- $name: node1.$name,
382
- $relation: node1.$relation,
383
- $modify: union(node1.$modify, node2.$modify),
384
- $recursive: mergeRecursion(node1.$recursive, node2.$recursive),
385
- $allRecursive: node1.$allRecursive || node2.$allRecursive,
386
- $childNames: null,
387
- };
388
-
389
- if (!node.$recursive && !node.$allRecursive) {
390
- node.$childNames = union(node1.$childNames, node2.$childNames);
391
-
392
- for (const childName of node.$childNames) {
393
- const child1 = node1[childName];
394
- const child2 = node2[childName];
395
-
396
- if (child1 && child2) {
397
- node[childName] = mergeNodes(child1, child2);
398
- } else {
399
- node[childName] = child1 || child2;
400
- }
401
- }
402
- } else {
403
- node.$childNames = [];
404
- }
405
-
406
- return node;
325
+ const node = {
326
+ $name: node1.$name,
327
+ $relation: node1.$relation,
328
+ $modify: union(node1.$modify, node2.$modify),
329
+ $recursive: mergeRecursion(node1.$recursive, node2.$recursive),
330
+ $allRecursive: node1.$allRecursive || node2.$allRecursive,
331
+ $childNames: null,
332
+ };
333
+ if (!node.$recursive && !node.$allRecursive) {
334
+ node.$childNames = union(node1.$childNames, node2.$childNames);
335
+ for (const childName of node.$childNames) {
336
+ const child1 = node1[childName];
337
+ const child2 = node2[childName];
338
+ if (child1 && child2) {
339
+ node[childName] = mergeNodes(child1, child2);
340
+ }
341
+ else {
342
+ node[childName] = child1 || child2;
343
+ }
344
+ }
345
+ }
346
+ else {
347
+ node.$childNames = [];
348
+ }
349
+ return node;
407
350
  }
408
-
409
351
  function mergeRecursion(rec1, rec2) {
410
- if (rec1 === true || rec2 === true) {
411
- return true;
412
- } else if (isNumber(rec1) && isNumber(rec2)) {
413
- return Math.max(rec1, rec2);
414
- } else {
415
- return rec1 || rec2;
416
- }
352
+ if (rec1 === true || rec2 === true) {
353
+ return true;
354
+ }
355
+ else if (isNumber(rec1) && isNumber(rec2)) {
356
+ return Math.max(rec1, rec2);
357
+ }
358
+ else {
359
+ return rec1 || rec2;
360
+ }
417
361
  }
418
-
419
362
  Object.defineProperties(RelationExpression.prototype, {
420
- isObjectionRelationExpression: {
421
- enumerable: false,
422
- writable: false,
423
- value: true,
424
- },
363
+ isObjectionRelationExpression: {
364
+ enumerable: false,
365
+ writable: false,
366
+ value: true,
367
+ },
425
368
  });
426
-
427
369
  module.exports = {
428
- RelationExpression,
429
- RelationExpressionParseError,
430
- DuplicateRelationError,
370
+ RelationExpression,
371
+ RelationExpressionParseError,
372
+ DuplicateRelationError,
431
373
  };