objection 3.9.1 → 4.0.0-rc.2

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 (250) hide show
  1. package/lib/dbErrors/LICENSE +21 -0
  2. package/lib/dbErrors/errorCodes/mssql.js +19 -0
  3. package/lib/dbErrors/errorCodes/mysql.js +805 -0
  4. package/lib/dbErrors/errorCodes/postgres.js +241 -0
  5. package/lib/dbErrors/errors/CheckViolationError.js +10 -0
  6. package/lib/dbErrors/errors/ConstraintViolationError.js +3 -0
  7. package/lib/dbErrors/errors/DBError.js +9 -0
  8. package/lib/dbErrors/errors/DataError.js +3 -0
  9. package/lib/dbErrors/errors/ForeignKeyViolationError.js +11 -0
  10. package/lib/dbErrors/errors/NotNullViolationError.js +12 -0
  11. package/lib/dbErrors/errors/UniqueViolationError.js +12 -0
  12. package/lib/dbErrors/index.js +59 -0
  13. package/lib/dbErrors/parsers/mssql/DBError/CheckViolationError/parser.js +28 -0
  14. package/lib/dbErrors/parsers/mssql/DBError/DataError/parser.js +25 -0
  15. package/lib/dbErrors/parsers/mssql/DBError/ForeignKeyViolationError/parser.js +39 -0
  16. package/lib/dbErrors/parsers/mssql/DBError/NotNullViolationError/parser.js +30 -0
  17. package/lib/dbErrors/parsers/mssql/DBError/UniqueViolationError/parser.js +53 -0
  18. package/lib/dbErrors/parsers/mssql/DBError/parser.js +51 -0
  19. package/lib/dbErrors/parsers/mssql/DBError/util.js +16 -0
  20. package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +43 -0
  21. package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/NotNullViolationError/parser.js +29 -0
  22. package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/UniqueViolationError/parser.js +27 -0
  23. package/lib/dbErrors/parsers/mysql/DBError/ConstraintViolationError/parser.js +23 -0
  24. package/lib/dbErrors/parsers/mysql/DBError/DataError/parser.js +24 -0
  25. package/lib/dbErrors/parsers/mysql/DBError/parser.js +28 -0
  26. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/CheckViolationError/parser.js +18 -0
  27. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +18 -0
  28. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/NotNullViolationError/parser.js +18 -0
  29. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/UniqueViolationError/parser.js +40 -0
  30. package/lib/dbErrors/parsers/postgres/DBError/ConstraintViolationError/parser.js +25 -0
  31. package/lib/dbErrors/parsers/postgres/DBError/DataError/parser.js +16 -0
  32. package/lib/dbErrors/parsers/postgres/DBError/parser.js +27 -0
  33. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/CheckViolationError/parser.js +20 -0
  34. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/ForeignKeyViolationError/parser.js +20 -0
  35. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/NotNullViolationError/parser.js +27 -0
  36. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/UniqueViolationError/parser.js +28 -0
  37. package/lib/dbErrors/parsers/sqlite/DBError/ConstraintViolationError/parser.js +24 -0
  38. package/lib/dbErrors/parsers/sqlite/DBError/parser.js +23 -0
  39. package/lib/dbErrors/utils/sqlState.js +3 -0
  40. package/lib/initialize.js +1 -7
  41. package/lib/model/AjvValidator.js +51 -117
  42. package/lib/model/Model.js +84 -59
  43. package/lib/model/ModifierNotFoundError.js +1 -7
  44. package/lib/model/NotFoundError.js +1 -7
  45. package/lib/model/RelationDoesNotExistError.js +1 -7
  46. package/lib/model/ValidationError.js +3 -10
  47. package/lib/model/Validator.js +1 -7
  48. package/lib/model/getModel.js +7 -6
  49. package/lib/model/inheritModel.js +1 -7
  50. package/lib/model/modelBindKnex.js +4 -10
  51. package/lib/model/modelClone.js +5 -11
  52. package/lib/model/modelColPropMap.js +3 -10
  53. package/lib/model/modelId.js +3 -10
  54. package/lib/model/modelJsonAttributes.js +35 -16
  55. package/lib/model/modelParseRelations.js +2 -8
  56. package/lib/model/modelQueryProps.js +11 -23
  57. package/lib/model/modelSet.js +89 -41
  58. package/lib/model/modelTableMetadata.js +4 -11
  59. package/lib/model/modelToJson.js +6 -13
  60. package/lib/model/modelUtils.js +14 -13
  61. package/lib/model/modelValidate.js +3 -9
  62. package/lib/model/modelValues.js +5 -14
  63. package/lib/model/modelVisitor.js +1 -7
  64. package/lib/objection.js +33 -71
  65. package/lib/queryBuilder/FunctionBuilder.js +4 -11
  66. package/lib/queryBuilder/InternalOptions.js +4 -9
  67. package/lib/queryBuilder/JoinBuilder.js +5 -8
  68. package/lib/queryBuilder/QueryBuilder.js +126 -95
  69. package/lib/queryBuilder/QueryBuilderBase.js +41 -123
  70. package/lib/queryBuilder/QueryBuilderContext.js +2 -8
  71. package/lib/queryBuilder/QueryBuilderContextBase.js +2 -8
  72. package/lib/queryBuilder/QueryBuilderOperationSupport.js +7 -21
  73. package/lib/queryBuilder/QueryBuilderUserContext.js +1 -7
  74. package/lib/queryBuilder/RawBuilder.js +5 -13
  75. package/lib/queryBuilder/ReferenceBuilder.js +20 -48
  76. package/lib/queryBuilder/RelationExpression.js +18 -16
  77. package/lib/queryBuilder/StaticHookArguments.js +74 -16
  78. package/lib/queryBuilder/ValueBuilder.js +11 -13
  79. package/lib/queryBuilder/getJoinBuilder.js +10 -0
  80. package/lib/queryBuilder/graph/GraphLoader.js +314 -0
  81. package/lib/queryBuilder/graph/GraphNode.js +241 -0
  82. package/lib/queryBuilder/graph/GraphOptions.js +55 -248
  83. package/lib/queryBuilder/graph/GraphPlan.js +431 -0
  84. package/lib/queryBuilder/graph/GraphSchedule.js +513 -0
  85. package/lib/queryBuilder/graph/GraphUpsert.js +519 -412
  86. package/lib/queryBuilder/graph/GraphWriter.js +508 -0
  87. package/lib/queryBuilder/graph/graphKeys.js +929 -0
  88. package/lib/queryBuilder/join/JoinResultColumn.js +1 -7
  89. package/lib/queryBuilder/join/JoinResultParser.js +6 -11
  90. package/lib/queryBuilder/join/RelationJoiner.js +66 -84
  91. package/lib/queryBuilder/join/TableNode.js +2 -8
  92. package/lib/queryBuilder/join/TableTree.js +3 -9
  93. package/lib/queryBuilder/join/utils.js +5 -15
  94. package/lib/queryBuilder/jsonDialects/JsonDialect.js +51 -0
  95. package/lib/queryBuilder/jsonDialects/MySqlJsonDialect.js +81 -0
  96. package/lib/queryBuilder/jsonDialects/PostgresJsonDialect.js +45 -0
  97. package/lib/queryBuilder/jsonDialects/SqliteJsonDialect.js +67 -0
  98. package/lib/queryBuilder/jsonDialects/index.js +44 -0
  99. package/lib/queryBuilder/operations/DelegateOperation.js +2 -8
  100. package/lib/queryBuilder/operations/DeleteOperation.js +10 -39
  101. package/lib/queryBuilder/operations/FindByIdOperation.js +7 -12
  102. package/lib/queryBuilder/operations/FindByIdsOperation.js +4 -8
  103. package/lib/queryBuilder/operations/FindOperation.js +14 -34
  104. package/lib/queryBuilder/operations/FirstOperation.js +6 -10
  105. package/lib/queryBuilder/operations/FromOperation.js +3 -9
  106. package/lib/queryBuilder/operations/InsertAndFetchOperation.js +13 -12
  107. package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +4 -10
  108. package/lib/queryBuilder/operations/InsertGraphOperation.js +7 -18
  109. package/lib/queryBuilder/operations/InsertOperation.js +118 -45
  110. package/lib/queryBuilder/operations/InstanceDeleteOperation.js +5 -12
  111. package/lib/queryBuilder/operations/InstanceFindOperation.js +4 -11
  112. package/lib/queryBuilder/operations/InstanceInsertOperation.js +2 -8
  113. package/lib/queryBuilder/operations/InstanceUpdateOperation.js +7 -14
  114. package/lib/queryBuilder/operations/JoinRelatedOperation.js +5 -11
  115. package/lib/queryBuilder/operations/KnexOperation.js +2 -8
  116. package/lib/queryBuilder/operations/LimitPerParentOperation.js +7 -69
  117. package/lib/queryBuilder/operations/MergeOperation.js +5 -11
  118. package/lib/queryBuilder/operations/NoneOperation.js +2 -8
  119. package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +20 -49
  120. package/lib/queryBuilder/operations/OnBuildKnexOperation.js +2 -8
  121. package/lib/queryBuilder/operations/OnBuildOperation.js +2 -8
  122. package/lib/queryBuilder/operations/OnErrorOperation.js +2 -8
  123. package/lib/queryBuilder/operations/QueryBuilderOperation.js +1 -7
  124. package/lib/queryBuilder/operations/RangeOperation.js +11 -26
  125. package/lib/queryBuilder/operations/RelateOperation.js +2 -8
  126. package/lib/queryBuilder/operations/ReturningOperation.js +3 -9
  127. package/lib/queryBuilder/operations/RunAfterOperation.js +2 -12
  128. package/lib/queryBuilder/operations/RunBeforeOperation.js +2 -8
  129. package/lib/queryBuilder/operations/UnrelateOperation.js +2 -8
  130. package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +14 -17
  131. package/lib/queryBuilder/operations/UpdateOperation.js +32 -132
  132. package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +8 -11
  133. package/lib/queryBuilder/operations/UpsertGraphOperation.js +6 -12
  134. package/lib/queryBuilder/operations/WhereCompositeOperation.js +3 -9
  135. package/lib/queryBuilder/operations/WhereGroupOperation.js +2 -8
  136. package/lib/queryBuilder/operations/eager/EagerOperation.js +3 -9
  137. package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +72 -10
  138. package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +2 -8
  139. package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +23 -44
  140. package/lib/queryBuilder/operations/fieldExpressions.js +122 -0
  141. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +20 -0
  142. package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +44 -0
  143. package/lib/queryBuilder/operations/jsonApi/WhereJsonTypeOperation.js +14 -0
  144. package/lib/queryBuilder/operations/select/SelectOperation.js +11 -21
  145. package/lib/queryBuilder/operations/select/Selection.js +19 -17
  146. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +4 -10
  147. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +4 -10
  148. package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +4 -10
  149. package/lib/queryBuilder/operations/windowOrder.js +56 -0
  150. package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +3 -7
  151. package/lib/queryBuilder/parsers/relationExpressionParser.js +42 -43
  152. package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +39 -36
  153. package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +2 -8
  154. package/lib/queryBuilder/transformations/QueryTransformation.js +1 -7
  155. package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +3 -9
  156. package/lib/queryBuilder/transformations/index.js +3 -11
  157. package/lib/queryBuilder/whereGroups.js +9 -24
  158. package/lib/queryBuilder/withoutOrder.js +4 -11
  159. package/lib/relations/Relation.js +47 -28
  160. package/lib/relations/RelationDeleteOperation.js +4 -14
  161. package/lib/relations/RelationFindOperation.js +119 -90
  162. package/lib/relations/RelationInsertOperation.js +2 -8
  163. package/lib/relations/RelationOwner.js +5 -11
  164. package/lib/relations/RelationProperty.js +4 -10
  165. package/lib/relations/RelationUpdateOperation.js +4 -14
  166. package/lib/relations/RelationWriteResultOperation.js +15 -0
  167. package/lib/relations/belongsToMany/BelongsToManyDeleteOperation.js +23 -0
  168. package/lib/relations/belongsToMany/BelongsToManyFindOperation.js +35 -0
  169. package/lib/relations/belongsToMany/BelongsToManyInsertOperation.js +28 -0
  170. package/lib/relations/belongsToMany/BelongsToManyRelateOperation.js +16 -0
  171. package/lib/relations/belongsToMany/BelongsToManyRelation.js +276 -0
  172. package/lib/relations/belongsToMany/BelongsToManyUnrelateOperation.js +11 -0
  173. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +2 -8
  174. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +6 -11
  175. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +3 -9
  176. package/lib/relations/belongsToOne/BelongsToOneRelation.js +8 -19
  177. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +53 -27
  178. package/lib/relations/hasMany/HasManyInsertOperation.js +5 -10
  179. package/lib/relations/hasMany/HasManyRelateOperation.js +5 -11
  180. package/lib/relations/hasMany/HasManyRelation.js +9 -11
  181. package/lib/relations/hasMany/HasManyUnrelateOperation.js +3 -9
  182. package/lib/relations/hasOne/HasOneRelation.js +2 -8
  183. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +2 -8
  184. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +10 -15
  185. package/lib/relations/manyToMany/ManyToManyMySqlModifyMixin.js +2 -8
  186. package/lib/relations/manyToMany/ManyToManyRelation.js +82 -50
  187. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +2 -8
  188. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +5 -9
  189. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +2 -8
  190. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +3 -9
  191. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +20 -59
  192. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +6 -11
  193. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +4 -10
  194. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateMySqlOperation.js +3 -9
  195. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +5 -9
  196. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +3 -9
  197. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +3 -9
  198. package/lib/relations/manyToMany/update/ManyToManyUpdateMySqlOperation.js +3 -9
  199. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +5 -9
  200. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +64 -72
  201. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +3 -9
  202. package/lib/transaction.js +3 -9
  203. package/lib/utils/assert.js +3 -11
  204. package/lib/utils/buildUtils.js +2 -8
  205. package/lib/utils/classUtils.js +1 -7
  206. package/lib/utils/createModifier.js +2 -8
  207. package/lib/utils/identifierMapping.js +23 -27
  208. package/lib/utils/internalPropUtils.js +1 -7
  209. package/lib/utils/knexUtils.js +84 -40
  210. package/lib/utils/mixin.js +3 -10
  211. package/lib/utils/normalizeIds.js +2 -8
  212. package/lib/utils/objectUtils.js +41 -60
  213. package/lib/utils/parseFieldExpression.js +16 -16
  214. package/lib/utils/promiseUtils/after.js +2 -8
  215. package/lib/utils/promiseUtils/afterReturn.js +2 -8
  216. package/lib/utils/promiseUtils/index.js +7 -16
  217. package/lib/utils/promiseUtils/isPromise.js +2 -8
  218. package/lib/utils/promiseUtils/map.js +2 -8
  219. package/lib/utils/promiseUtils/mapAfterAllReturn.js +2 -8
  220. package/lib/utils/promiseUtils/try.js +2 -8
  221. package/lib/utils/resolveModel.js +10 -17
  222. package/lib/utils/tmpColumnUtils.js +2 -9
  223. package/lib/utils/warnings.js +2 -14
  224. package/package.json +25 -17
  225. package/typings/objection/index.d.ts +3217 -2179
  226. package/lib/.eslintrc.json +0 -8
  227. package/lib/model/graph/ModelGraph.js +0 -80
  228. package/lib/model/graph/ModelGraphBuilder.js +0 -241
  229. package/lib/model/graph/ModelGraphEdge.js +0 -52
  230. package/lib/model/graph/ModelGraphNode.js +0 -238
  231. package/lib/queryBuilder/graph/GraphAction.js +0 -69
  232. package/lib/queryBuilder/graph/GraphData.js +0 -53
  233. package/lib/queryBuilder/graph/GraphFetcher.js +0 -197
  234. package/lib/queryBuilder/graph/GraphNodeDbExistence.js +0 -184
  235. package/lib/queryBuilder/graph/GraphOperation.js +0 -27
  236. package/lib/queryBuilder/graph/delete/GraphDelete.js +0 -73
  237. package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +0 -88
  238. package/lib/queryBuilder/graph/insert/DeferredRelationGraphInsertAction.js +0 -58
  239. package/lib/queryBuilder/graph/insert/GraphInsert.js +0 -296
  240. package/lib/queryBuilder/graph/insert/GraphInsertAction.js +0 -233
  241. package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +0 -92
  242. package/lib/queryBuilder/graph/patch/GraphPatch.js +0 -20
  243. package/lib/queryBuilder/graph/patch/GraphPatchAction.js +0 -289
  244. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +0 -31
  245. package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +0 -126
  246. package/lib/queryBuilder/operations/jsonApi/WhereJsonHasPostgresOperation.js +0 -30
  247. package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectPostgresOperation.js +0 -37
  248. package/lib/queryBuilder/operations/jsonApi/WhereJsonPostgresOperation.js +0 -62
  249. package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +0 -192
  250. package/lib/utils/wrapDbError.js +0 -64
@@ -1,10 +1,8 @@
1
- 'use strict';
1
+ import { inheritModel } from './inheritModel.js';
2
+ import { staticHiddenProps } from './modelUtils.js';
3
+ import { defineNonEnumerableProperty } from './modelUtils.js';
2
4
 
3
- const { inheritModel } = require('./inheritModel');
4
- const { staticHiddenProps } = require('./modelUtils');
5
- const { defineNonEnumerableProperty } = require('./modelUtils');
6
-
7
- function bindKnex(modelClass, knex) {
5
+ export function bindKnex(modelClass, knex) {
8
6
  let BoundModelClass = getBoundModelFromCache(modelClass, knex);
9
7
 
10
8
  if (BoundModelClass === null) {
@@ -77,7 +75,3 @@ function bindRelations(modelClass, BoundModelClass, knex) {
77
75
 
78
76
  return BoundModelClass;
79
77
  }
80
-
81
- module.exports = {
82
- bindKnex,
83
- };
@@ -1,11 +1,9 @@
1
- 'use strict';
1
+ import { isObject, cloneDeep } from '../utils/objectUtils.js';
2
+ import { hiddenProps } from './modelUtils.js';
3
+ import { defineNonEnumerableProperty } from './modelUtils.js';
4
+ import { isInternalProp } from '../utils/internalPropUtils.js';
2
5
 
3
- const { isObject, cloneDeep } = require('../utils/objectUtils');
4
- const { hiddenProps } = require('./modelUtils');
5
- const { defineNonEnumerableProperty } = require('./modelUtils');
6
- const { isInternalProp } = require('../utils/internalPropUtils');
7
-
8
- function clone(model, shallow, stripInternal) {
6
+ export function clone(model, shallow, stripInternal) {
9
7
  let clone = null;
10
8
 
11
9
  const omitFromJson = model.$omitFromJson();
@@ -113,7 +111,3 @@ function copyHiddenProps(model, clone) {
113
111
 
114
112
  return clone;
115
113
  }
116
-
117
- module.exports = {
118
- clone,
119
- };
@@ -1,8 +1,6 @@
1
- 'use strict';
1
+ import { difference } from '../utils/objectUtils.js';
2
2
 
3
- const { difference } = require('../utils/objectUtils');
4
-
5
- function columnNameToPropertyName(modelClass, columnName) {
3
+ export function columnNameToPropertyName(modelClass, columnName) {
6
4
  const model = new modelClass();
7
5
  const addedProps = Object.keys(model.$parseDatabaseJson({}));
8
6
 
@@ -15,7 +13,7 @@ function columnNameToPropertyName(modelClass, columnName) {
15
13
  return propertyName || columnName;
16
14
  }
17
15
 
18
- function propertyNameToColumnName(modelClass, propertyName) {
16
+ export function propertyNameToColumnName(modelClass, propertyName) {
19
17
  const model = new modelClass();
20
18
  const addedCols = Object.keys(model.$formatDatabaseJson({}));
21
19
 
@@ -27,8 +25,3 @@ function propertyNameToColumnName(modelClass, propertyName) {
27
25
 
28
26
  return columnName || propertyName;
29
27
  }
30
-
31
- module.exports = {
32
- columnNameToPropertyName,
33
- propertyNameToColumnName,
34
- };
@@ -1,8 +1,6 @@
1
- 'use strict';
1
+ import { assertHasIdColumn } from '../utils/assert.js';
2
2
 
3
- const { assertHasIdColumn } = require('../utils/assert');
4
-
5
- function getSetId(model, maybeId) {
3
+ export function getSetId(model, maybeId) {
6
4
  if (maybeId !== undefined) {
7
5
  return setId(model, maybeId);
8
6
  } else {
@@ -10,7 +8,7 @@ function getSetId(model, maybeId) {
10
8
  }
11
9
  }
12
10
 
13
- function hasId(model) {
11
+ export function hasId(model) {
14
12
  const idProps = model.constructor.getIdPropertyArray();
15
13
  // Models without an `idColumn` never have an id.
16
14
  return idProps.length > 0 && model.$hasProps(idProps);
@@ -63,8 +61,3 @@ function getId(model) {
63
61
  return model[idProp];
64
62
  }
65
63
  }
66
-
67
- module.exports = {
68
- getSetId,
69
- hasId,
70
- };
@@ -1,12 +1,12 @@
1
- 'use strict';
1
+ import { asArray, isObject, flatten, isString } from '../utils/objectUtils.js';
2
+ import { isQueryProp } from './modelQueryProps.js';
3
+ import { isJsonParsedByDriver } from '../utils/knexUtils.js';
2
4
 
3
- const { asArray, isObject, flatten, isString } = require('../utils/objectUtils');
4
- const { isQueryProp } = require('./modelQueryProps');
5
-
6
- function parseJsonAttributes(json, modelClass) {
5
+ export function parseJsonAttributes(json, modelClass, knex) {
7
6
  const jsonAttr = modelClass.getJsonAttributes();
7
+ const format = getJsonColumnFormat(modelClass, knex);
8
8
 
9
- if (jsonAttr.length) {
9
+ if (jsonAttr.length && format !== 'parsed') {
10
10
  // JSON attributes may be returned as strings depending on the database and
11
11
  // the database client. Convert them to objects here.
12
12
  for (let i = 0, l = jsonAttr.length; i < l; ++i) {
@@ -14,7 +14,7 @@ function parseJsonAttributes(json, modelClass) {
14
14
  const value = json[attr];
15
15
 
16
16
  if (isString(value)) {
17
- const parsed = tryParseJson(value);
17
+ const parsed = format === 'text' ? parseJson(value, attr, modelClass) : tryParseJson(value);
18
18
 
19
19
  // tryParseJson returns undefined if parsing failed.
20
20
  if (parsed !== undefined) {
@@ -27,7 +27,7 @@ function parseJsonAttributes(json, modelClass) {
27
27
  return json;
28
28
  }
29
29
 
30
- function formatJsonAttributes(json, modelClass) {
30
+ export function formatJsonAttributes(json, modelClass) {
31
31
  const jsonAttr = modelClass.getJsonAttributes();
32
32
 
33
33
  if (jsonAttr.length) {
@@ -46,7 +46,7 @@ function formatJsonAttributes(json, modelClass) {
46
46
  return json;
47
47
  }
48
48
 
49
- function getJsonAttributes(modelClass) {
49
+ export function getJsonAttributes(modelClass) {
50
50
  let jsonAttributes = modelClass.jsonAttributes;
51
51
 
52
52
  if (Array.isArray(jsonAttributes)) {
@@ -85,6 +85,32 @@ function getPropertyTypes(prop) {
85
85
  return types;
86
86
  }
87
87
 
88
+ // Resolve 'auto' to 'parsed' for drivers that return JSON columns parsed, or
89
+ // else to `null`: JSON attributes may be text then, and are parsed leniently.
90
+ function getJsonColumnFormat(modelClass, knex) {
91
+ const { jsonColumnFormat } = modelClass;
92
+
93
+ if (jsonColumnFormat === 'auto') {
94
+ return knex && isJsonParsedByDriver(knex) ? 'parsed' : null;
95
+ } else if (jsonColumnFormat === 'text' || jsonColumnFormat === 'parsed') {
96
+ return jsonColumnFormat;
97
+ } else {
98
+ throw new Error(
99
+ `Invalid jsonColumnFormat of model '${modelClass.name}': '${jsonColumnFormat}'.`,
100
+ );
101
+ }
102
+ }
103
+
104
+ function parseJson(str, attr, modelClass) {
105
+ try {
106
+ return JSON.parse(str);
107
+ } catch (err) {
108
+ throw new Error(
109
+ `Invalid JSON in JSON attribute '${attr}' of model '${modelClass.name}': ${err.message}`,
110
+ );
111
+ }
112
+ }
113
+
88
114
  function tryParseJson(maybeJsonStr) {
89
115
  try {
90
116
  return JSON.parse(maybeJsonStr);
@@ -92,10 +118,3 @@ function tryParseJson(maybeJsonStr) {
92
118
  return undefined;
93
119
  }
94
120
  }
95
-
96
- module.exports = {
97
- parseJsonAttributes,
98
- formatJsonAttributes,
99
- getJsonAttributes,
100
- getPropertyTypes,
101
- };
@@ -1,8 +1,6 @@
1
- 'use strict';
1
+ import { isObject } from '../utils/objectUtils.js';
2
2
 
3
- const { isObject } = require('../utils/objectUtils');
4
-
5
- function parseRelationsIntoModelInstances(model, json, options = {}) {
3
+ export function parseRelationsIntoModelInstances(model, json, options = {}) {
6
4
  if (!options.cache) {
7
5
  options = Object.assign({}, options, {
8
6
  cache: new Map(),
@@ -76,7 +74,3 @@ function parseRelationObject(json, relation, options) {
76
74
  return json;
77
75
  }
78
76
  }
79
-
80
- module.exports = {
81
- parseRelationsIntoModelInstances,
82
- };
@@ -1,9 +1,7 @@
1
- 'use strict';
2
-
3
- const { isObject, isFunction, omit } = require('../utils/objectUtils');
4
- const { defineNonEnumerableProperty } = require('./modelUtils');
5
- const { isKnexRaw, isKnexQueryBuilder } = require('../utils/knexUtils');
6
- const { getFieldExpressionColumn } = require('../utils/parseFieldExpression');
1
+ import { isObject, isFunction, omit } from '../utils/objectUtils.js';
2
+ import { defineNonEnumerableProperty } from './modelUtils.js';
3
+ import { isKnexRaw, isKnexQueryBuilder } from '../utils/knexUtils.js';
4
+ import { getFieldExpressionColumn } from '../utils/parseFieldExpression.js';
7
5
 
8
6
  const QUERY_PROPS_PROPERTY = '$$queryProps';
9
7
  // The keys of the field expression query properties like `'data:a'` that were
@@ -14,7 +12,7 @@ const COMBINED_QUERY_PROPS_PROPERTY = '$$combinedQueryProps';
14
12
  // that they can be later merged back to its database json. A key holds either
15
13
  // a value or a query property, so the keys given in `json` replace the ones
16
14
  // that the model holds as the other kind.
17
- function splitQueryProps(model, json) {
15
+ export function splitQueryProps(model, json) {
18
16
  const keys = Object.keys(json);
19
17
  const oldQueryProps = model[QUERY_PROPS_PROPERTY];
20
18
 
@@ -61,7 +59,7 @@ function splitQueryProps(model, json) {
61
59
 
62
60
  // Omits the values that parsing and validation add to `json` for the keys that
63
61
  // `model` holds query properties for, like Ajv defaults.
64
- function omitQueryProps(model, json) {
62
+ export function omitQueryProps(model, json) {
65
63
  const keys = getQueryPropKeys(model);
66
64
  return keys.length > 0 ? omit(json, keys) : json;
67
65
  }
@@ -70,7 +68,7 @@ function omitQueryProps(model, json) {
70
68
  // assignment, `$set()` or a write that fetched the value from the database. We
71
69
  // do this when the model is passed to a write, and not when its database json
72
70
  // is built, so that the values set by its hooks don't override them.
73
- function removeOverriddenQueryProps(model) {
71
+ export function removeOverriddenQueryProps(model) {
74
72
  const queryProps = model[QUERY_PROPS_PROPERTY];
75
73
 
76
74
  if (queryProps) {
@@ -96,7 +94,7 @@ function removeOverriddenQueryProps(model) {
96
94
  // Removes the values that the hooks of a write set for the keys that `model`
97
95
  // holds query properties for. The query properties are written instead, so the
98
96
  // values must not count as given in later writes.
99
- function removeOverriddenValues(model) {
97
+ export function removeOverriddenValues(model) {
100
98
  for (const key of getQueryPropKeys(model)) {
101
99
  delete model[key];
102
100
  }
@@ -112,7 +110,7 @@ function hasQueryProps(json, keys) {
112
110
  return false;
113
111
  }
114
112
 
115
- function isQueryProp(value) {
113
+ export function isQueryProp(value) {
116
114
  if (!isObject(value)) {
117
115
  return false;
118
116
  }
@@ -126,7 +124,7 @@ function isQueryProp(value) {
126
124
  }
127
125
 
128
126
  // Merges and converts `model`'s query properties into `json`.
129
- function mergeQueryProps(model, json, omitProps, builder) {
127
+ export function mergeQueryProps(model, json, omitProps, builder) {
130
128
  json = convertExistingQueryProps(json, builder);
131
129
  json = convertAndMergeHiddenQueryProps(model, json, omitProps, builder);
132
130
 
@@ -177,7 +175,7 @@ function convertAndMergeHiddenQueryProps(model, json, omitProps, builder) {
177
175
  }
178
176
 
179
177
  // Returns the keys of the query properties that were split from `model`.
180
- function getQueryPropKeys(model) {
178
+ export function getQueryPropKeys(model) {
181
179
  const queryProps = model[QUERY_PROPS_PROPERTY];
182
180
  return queryProps ? Object.keys(queryProps) : [];
183
181
  }
@@ -214,13 +212,3 @@ function buildKnexRawConvertable(convertable, builder) {
214
212
  function isKnexRawConvertable(queryProp) {
215
213
  return isFunction(queryProp.toKnexRaw);
216
214
  }
217
-
218
- module.exports = {
219
- splitQueryProps,
220
- omitQueryProps,
221
- removeOverriddenQueryProps,
222
- removeOverriddenValues,
223
- mergeQueryProps,
224
- getQueryPropKeys,
225
- isQueryProp,
226
- };
@@ -1,11 +1,9 @@
1
- 'use strict';
1
+ import { isInternalProp } from '../utils/internalPropUtils.js';
2
+ import { splitQueryProps, omitQueryProps } from './modelQueryProps.js';
3
+ import { asArray, isFunction, isString, isPlainObject } from '../utils/objectUtils.js';
4
+ import { parseRelationsIntoModelInstances } from './modelParseRelations.js';
2
5
 
3
- const { isInternalProp } = require('../utils/internalPropUtils');
4
- const { splitQueryProps, omitQueryProps } = require('./modelQueryProps');
5
- const { isFunction, isString, isPlainObject } = require('../utils/objectUtils');
6
- const { parseRelationsIntoModelInstances } = require('./modelParseRelations');
7
-
8
- function setJson(model, json, options) {
6
+ export function setJson(model, json, options) {
9
7
  json = json || {};
10
8
  options = options || {};
11
9
 
@@ -34,8 +32,8 @@ function setJson(model, json, options) {
34
32
  return model;
35
33
  }
36
34
 
37
- function setDatabaseJson(model, json) {
38
- json = model.$parseDatabaseJson(json);
35
+ export function setDatabaseJson(model, json, options) {
36
+ json = model.$parseDatabaseJson(json, options);
39
37
 
40
38
  if (json) {
41
39
  const keys = Object.keys(json);
@@ -49,7 +47,7 @@ function setDatabaseJson(model, json) {
49
47
  return model;
50
48
  }
51
49
 
52
- function setFast(model, obj) {
50
+ export function setFast(model, obj) {
53
51
  if (obj) {
54
52
  // Don't try to set read-only properties. They can easily get here
55
53
  // through `fromJson` when parsing an object that was previously
@@ -75,16 +73,39 @@ function setFast(model, obj) {
75
73
  return model;
76
74
  }
77
75
 
78
- function setRelated(model, relation, models) {
76
+ export function setRelated(model, relation, models) {
77
+ relation = ensureRelation(model, relation);
78
+ const previous = model[relation.name];
79
+ assignRelated(model, relation, models);
80
+ syncForeignKeys(model, relation, model[relation.name], { previous });
81
+ return model;
82
+ }
83
+
84
+ export function appendRelated(model, relation, models) {
79
85
  relation = ensureRelation(model, relation);
80
86
 
81
87
  if (relation.isOneToOne()) {
88
+ return model.$setRelated(relation, models);
89
+ } else {
90
+ assignRelated(model, relation, models, { append: true });
91
+ syncForeignKeys(model, relation, models, { append: true });
92
+ }
93
+
94
+ return model;
95
+ }
96
+
97
+ // Assigns related models without syncing foreign keys, for the relation queries
98
+ // that set the keys themselves:
99
+ export function assignRelated(model, relation, models, { append = false } = {}) {
100
+ if (append && model[relation.name] && !relation.isOneToOne()) {
82
101
  if (Array.isArray(models)) {
83
- if (models.length === 0) {
84
- model[relation.name] = null;
85
- } else {
86
- model[relation.name] = models[0] || null;
87
- }
102
+ models.forEach((it) => model[relation.name].push(it));
103
+ } else if (models) {
104
+ model[relation.name].push(models);
105
+ }
106
+ } else if (relation.isOneToOne()) {
107
+ if (Array.isArray(models)) {
108
+ model[relation.name] = models[0] || null;
88
109
  } else {
89
110
  model[relation.name] = models || null;
90
111
  }
@@ -97,24 +118,6 @@ function setRelated(model, relation, models) {
97
118
  model[relation.name] = [models];
98
119
  }
99
120
  }
100
-
101
- return model;
102
- }
103
-
104
- function appendRelated(model, relation, models) {
105
- relation = ensureRelation(model, relation);
106
-
107
- if (!model[relation.name] || relation.isOneToOne()) {
108
- return model.$setRelated(relation, models);
109
- } else {
110
- if (Array.isArray(models)) {
111
- models.forEach((it) => model[relation.name].push(it));
112
- } else if (models) {
113
- model[relation.name].push(models);
114
- }
115
- }
116
-
117
- return model;
118
121
  }
119
122
 
120
123
  function ensureRelation(model, relation) {
@@ -125,10 +128,55 @@ function ensureRelation(model, relation) {
125
128
  }
126
129
  }
127
130
 
128
- module.exports = {
129
- setFast,
130
- setJson,
131
- setDatabaseJson,
132
- setRelated,
133
- appendRelated,
134
- };
131
+ // Let the foreign keys follow the relation: a `BelongsToOneRelation` points the
132
+ // owner to the related model, a `BelongsToManyRelation` to the related models,
133
+ // `HasOneRelation` and `HasManyRelation` point the related models to the owner,
134
+ // and the models that leave them to nothing. The keys of `ManyToManyRelation`
135
+ // and `HasOneThroughRelation` live in the join table.
136
+ function syncForeignKeys(model, relation, related, { previous = null, append = false } = {}) {
137
+ const { ownerProp, relatedProp } = relation;
138
+
139
+ if (relation.isObjectionBelongsToOneRelation) {
140
+ copyKey(relatedProp, related, ownerProp, model);
141
+ } else if (relation.isObjectionBelongsToManyRelation) {
142
+ // Models without a key are left out of the array:
143
+ const keys = asModels(related).map((it) => relatedProp.getProp(it, 0));
144
+
145
+ ownerProp.setProp(
146
+ model,
147
+ 0,
148
+ relation.changeKeys(append ? relation.getKeys(model) : [], { add: keys }),
149
+ );
150
+ } else if (relation.isObjectionHasManyRelation) {
151
+ const models = asModels(related);
152
+
153
+ for (const it of models) {
154
+ copyKey(ownerProp, model, relatedProp, it);
155
+ }
156
+
157
+ if (ownerProp.hasProps(model)) {
158
+ const key = ownerProp.propKey(model);
159
+
160
+ for (const it of asModels(previous)) {
161
+ // Only clear the keys that still point to the owner, not the keys of
162
+ // models that moved to another owner in the meantime:
163
+ if (!models.includes(it) && relatedProp.propKey(it) === key) {
164
+ copyKey(ownerProp, null, relatedProp, it);
165
+ }
166
+ }
167
+ }
168
+ }
169
+ }
170
+
171
+ // Copies the key of `source` to `target`, or clears it if there's none to copy:
172
+ function copyKey(sourceProp, source, targetProp, target) {
173
+ const hasKey = !!source && sourceProp.hasProps(source);
174
+
175
+ targetProp.forEach((i) => {
176
+ targetProp.setProp(target, i, hasKey ? sourceProp.getProp(source, i) : null);
177
+ });
178
+ }
179
+
180
+ function asModels(value) {
181
+ return asArray(value).filter(Boolean);
182
+ }
@@ -1,11 +1,9 @@
1
- 'use strict';
2
-
3
- const { defineNonEnumerableProperty } = require('./modelUtils');
4
- const { isPromise } = require('../utils/promiseUtils');
1
+ import { defineNonEnumerableProperty } from './modelUtils.js';
2
+ import { isPromise } from '../utils/promiseUtils/index.js';
5
3
 
6
4
  const TABLE_METADATA = '$$tableMetadata';
7
5
 
8
- function fetchTableMetadata(
6
+ export function fetchTableMetadata(
9
7
  modelClass,
10
8
  { parentBuilder = null, knex = null, force = false, table = null } = {},
11
9
  ) {
@@ -63,7 +61,7 @@ function fetchTableMetadata(
63
61
  }
64
62
  }
65
63
 
66
- function tableMetadata(modelClass, { table } = {}) {
64
+ export function tableMetadata(modelClass, { table } = {}) {
67
65
  if (modelClass.hasOwnProperty(TABLE_METADATA)) {
68
66
  const metadata = modelClass[TABLE_METADATA].get(table || modelClass.getTableName());
69
67
 
@@ -76,8 +74,3 @@ function tableMetadata(modelClass, { table } = {}) {
76
74
  return null;
77
75
  }
78
76
  }
79
-
80
- module.exports = {
81
- fetchTableMetadata,
82
- tableMetadata,
83
- };
@@ -1,12 +1,10 @@
1
- 'use strict';
2
-
3
- const { isInternalProp } = require('../utils/internalPropUtils');
4
- const { mergeQueryProps } = require('./modelQueryProps');
5
- const { isObject, hasOwn, cloneDeep, isFunction } = require('../utils/objectUtils');
6
- const { getFieldExpressionColumn } = require('../utils/parseFieldExpression');
1
+ import { isInternalProp } from '../utils/internalPropUtils.js';
2
+ import { mergeQueryProps } from './modelQueryProps.js';
3
+ import { isObject, hasOwn, cloneDeep, isFunction } from '../utils/objectUtils.js';
4
+ import { getFieldExpressionColumn } from '../utils/parseFieldExpression.js';
7
5
  const EMPTY_ARRAY = [];
8
6
 
9
- function toJson(model, optIn) {
7
+ export function toJson(model, optIn) {
10
8
  const modelClass = model.constructor;
11
9
 
12
10
  const opt = {
@@ -25,7 +23,7 @@ function toJson(model, optIn) {
25
23
  return json;
26
24
  }
27
25
 
28
- function toDatabaseJson(model, builder) {
26
+ export function toDatabaseJson(model, builder) {
29
27
  const modelClass = model.constructor;
30
28
 
31
29
  const opt = {
@@ -188,8 +186,3 @@ function toJsonArray(value, opt) {
188
186
 
189
187
  return ret;
190
188
  }
191
-
192
- module.exports = {
193
- toJson,
194
- toDatabaseJson,
195
- };
@@ -1,8 +1,6 @@
1
- 'use strict';
1
+ export const hiddenProps = ['$$queryProps', '$$combinedQueryProps', '$$isFromDatabase'];
2
2
 
3
- const hiddenProps = ['$$queryProps', '$$combinedQueryProps'];
4
-
5
- const staticHiddenProps = [
3
+ export const staticHiddenProps = [
6
4
  '$$knex',
7
5
  '$$validator',
8
6
  '$$jsonSchema',
@@ -19,7 +17,7 @@ const staticHiddenProps = [
19
17
  '$$virtualAttributes',
20
18
  ];
21
19
 
22
- function defineNonEnumerableProperty(obj, prop, value) {
20
+ export function defineNonEnumerableProperty(obj, prop, value) {
23
21
  Object.defineProperty(obj, prop, {
24
22
  enumerable: false,
25
23
  writable: true,
@@ -28,7 +26,17 @@ function defineNonEnumerableProperty(obj, prop, value) {
28
26
  });
29
27
  }
30
28
 
31
- function keyByProps(models, props) {
29
+ // Give `model` back the props that it left out of its database JSON, as
30
+ // returned by `$omitFromDatabaseJson()` before more were left out.
31
+ export function restoreOmitFromDatabaseJson(model, props) {
32
+ if (props) {
33
+ defineNonEnumerableProperty(model, '$$omitFromDatabaseJson', props);
34
+ } else {
35
+ delete model.$$omitFromDatabaseJson;
36
+ }
37
+ }
38
+
39
+ export function keyByProps(models, props) {
32
40
  const map = new Map();
33
41
 
34
42
  for (let i = 0, l = models.length; i < l; ++i) {
@@ -38,10 +46,3 @@ function keyByProps(models, props) {
38
46
 
39
47
  return map;
40
48
  }
41
-
42
- module.exports = {
43
- hiddenProps,
44
- staticHiddenProps,
45
- defineNonEnumerableProperty,
46
- keyByProps,
47
- };
@@ -1,9 +1,7 @@
1
- 'use strict';
1
+ import { clone } from './modelClone.js';
2
+ import { omitQueryProps } from './modelQueryProps.js';
2
3
 
3
- const { clone } = require('./modelClone');
4
- const { omitQueryProps } = require('./modelQueryProps');
5
-
6
- function validate(model, json, options = {}) {
4
+ export function validate(model, json, options = {}) {
7
5
  json = json || model;
8
6
 
9
7
  const inputJson = json;
@@ -43,7 +41,3 @@ function validate(model, json, options = {}) {
43
41
  return json;
44
42
  }
45
43
  }
46
-
47
- module.exports = {
48
- validate,
49
- };
@@ -1,12 +1,10 @@
1
- 'use strict';
2
-
3
- const { isObject } = require('../utils/objectUtils');
1
+ import { isObject } from '../utils/objectUtils.js';
4
2
 
5
3
  // Property keys needs to be prefixed with a non-numeric character so that
6
4
  // they are not considered indexes when used as object keys.
7
5
  const PROP_KEY_PREFIX = 'k_';
8
6
 
9
- function values(model, args) {
7
+ export function values(model, args) {
10
8
  switch (args.length) {
11
9
  case 1:
12
10
  return values1(model, args);
@@ -20,7 +18,7 @@ function values(model, args) {
20
18
  }
21
19
 
22
20
  // Turn the props of a model into a key to look up models by.
23
- function propKey(model, props) {
21
+ export function propKey(model, props) {
24
22
  if (props.length === 1) {
25
23
  return PROP_KEY_PREFIX + propToStr(model[props[0]]);
26
24
  } else {
@@ -35,7 +33,7 @@ function propKey(model, props) {
35
33
  }
36
34
 
37
35
  // Same as `propKey()`, for values that were already collected.
38
- function valuesKey(values) {
36
+ export function valuesKey(values) {
39
37
  if (values.length === 1) {
40
38
  return PROP_KEY_PREFIX + propToStr(values[0]);
41
39
  } else {
@@ -49,7 +47,7 @@ function valuesKey(values) {
49
47
  }
50
48
  }
51
49
 
52
- function hasProps(model, props) {
50
+ export function hasProps(model, props) {
53
51
  for (let i = 0; i < props.length; ++i) {
54
52
  const value = model[props[i]];
55
53
 
@@ -110,10 +108,3 @@ function compositePropToStr(value) {
110
108
  function isNullOrUndefined(val) {
111
109
  return val === null || val === undefined;
112
110
  }
113
-
114
- module.exports = {
115
- values,
116
- hasProps,
117
- propKey,
118
- valuesKey,
119
- };
@@ -1,6 +1,4 @@
1
- 'use strict';
2
-
3
- function visitModels(models, modelClass, visitor) {
1
+ export function visitModels(models, modelClass, visitor) {
4
2
  doVisit(models, modelClass, null, null, visitor);
5
3
  }
6
4
 
@@ -35,7 +33,3 @@ function visitOne(model, modelClass, parent, rel, visitor) {
35
33
  }
36
34
  }
37
35
  }
38
-
39
- module.exports = {
40
- visitModels,
41
- };