@abedmurrar/objection 4.0.0-alpha.0 → 4.0.0-beta.0

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 +279 -363
  129. package/lib/relations/RelationDeleteOperation.js +16 -22
  130. package/lib/relations/RelationFindOperation.js +100 -133
  131. package/lib/relations/RelationInsertOperation.js +19 -27
  132. package/lib/relations/RelationOwner.js +167 -204
  133. package/lib/relations/RelationProperty.js +177 -217
  134. package/lib/relations/RelationUpdateOperation.js +16 -23
  135. package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +11 -16
  136. package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +24 -35
  137. package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +30 -41
  138. package/lib/relations/belongsToOne/BelongsToOneRelation.js +33 -41
  139. package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +38 -53
  140. package/lib/relations/hasMany/HasManyInsertOperation.js +35 -51
  141. package/lib/relations/hasMany/HasManyRelateOperation.js +38 -54
  142. package/lib/relations/hasMany/HasManyRelation.js +30 -38
  143. package/lib/relations/hasMany/HasManyUnrelateOperation.js +19 -26
  144. package/lib/relations/hasOne/HasOneRelation.js +4 -7
  145. package/lib/relations/hasOneThrough/HasOneThroughRelation.js +4 -7
  146. package/lib/relations/manyToMany/ManyToManyModifyMixin.js +67 -90
  147. package/lib/relations/manyToMany/ManyToManyRelation.js +349 -451
  148. package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +19 -26
  149. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +3 -5
  150. package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +14 -20
  151. package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +3 -7
  152. package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +71 -94
  153. package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +31 -43
  154. package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +50 -67
  155. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +4 -7
  156. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +20 -27
  157. package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +5 -10
  158. package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +3 -5
  159. package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +55 -72
  160. package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +3 -7
  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,325 +1,278 @@
1
1
  'use strict';
2
-
3
2
  const Ajv = require('ajv');
4
3
  const addFormats = require('ajv-formats');
5
4
  const { Validator } = require('./Validator');
6
5
  const { ValidationErrorType } = require('../model/ValidationError');
7
- const { isObject, once, cloneDeep: lodashCloneDeep, omit } = require('../utils/objectUtils');
8
-
6
+ const { isObject, cloneDeep: cloneDeepValue, omit } = require('../utils/objectUtils');
9
7
  class AjvValidator extends Validator {
10
- static init(self, conf) {
11
- super.init(self, conf);
12
-
13
- self.ajvOptions = Object.assign({}, conf.options, {
14
- allErrors: true,
15
- });
16
-
17
- // Create a normal Ajv instance.
18
- self.ajv = new Ajv(
19
- Object.assign(
20
- {
21
- useDefaults: true,
22
- },
23
- self.ajvOptions,
24
- ),
25
- );
26
-
27
- // Create an instance that doesn't set default values. We need this one
28
- // to validate `patch` objects (objects that have a subset of properties).
29
- self.ajvNoDefaults = new Ajv(
30
- Object.assign({}, self.ajvOptions, {
31
- useDefaults: false,
32
- }),
33
- );
34
-
35
- // A cache for the compiled validator functions.
36
- self.cache = new Map();
37
-
38
- const setupAjv = (ajv) => {
39
- if (conf.onCreateAjv) {
40
- conf.onCreateAjv(ajv);
41
- }
42
- // Only add Ajv formats if they weren't added in user-space already
43
- if (!ajv.formats['date-time']) {
44
- addFormats(ajv);
45
- }
46
- };
47
-
48
- setupAjv(self.ajv);
49
- setupAjv(self.ajvNoDefaults);
50
- }
51
-
52
- beforeValidate({ json, model, options, ctx }) {
53
- ctx.jsonSchema = model.constructor.getJsonSchema();
54
-
55
- // Objection model's have a `$beforeValidate` hook that is allowed to modify the schema.
56
- // We need to clone the schema in case the function modifies it. We only do this in the
57
- // rare case that the given model has implemented the hook.
58
- if (model.$beforeValidate !== model.$objectionModelClass.prototype.$beforeValidate) {
59
- ctx.jsonSchema = cloneDeep(ctx.jsonSchema);
60
- const ret = model.$beforeValidate(ctx.jsonSchema, json, options);
61
-
62
- if (ret !== undefined) {
63
- ctx.jsonSchema = ret;
64
- }
8
+ static init(self, conf) {
9
+ super.init(self, conf);
10
+ self.ajvOptions = Object.assign({}, conf.options, {
11
+ allErrors: true,
12
+ });
13
+ // Create a normal Ajv instance.
14
+ self.ajv = new Ajv(Object.assign({
15
+ useDefaults: true,
16
+ }, self.ajvOptions));
17
+ // Create an instance that doesn't set default values. We need this one
18
+ // to validate `patch` objects (objects that have a subset of properties).
19
+ self.ajvNoDefaults = new Ajv(Object.assign({}, self.ajvOptions, {
20
+ useDefaults: false,
21
+ }));
22
+ // Caches for the compiled validator functions: by the serialized schema,
23
+ // and by the schema object for the schemas of model classes.
24
+ self.cache = new Map();
25
+ self.schemaCache = new WeakMap();
26
+ const setupAjv = (ajv) => {
27
+ if (conf.onCreateAjv) {
28
+ conf.onCreateAjv(ajv);
29
+ }
30
+ // Only add Ajv formats if they weren't added in user-space already
31
+ if (!ajv.formats['date-time']) {
32
+ addFormats(ajv);
33
+ }
34
+ };
35
+ setupAjv(self.ajv);
36
+ setupAjv(self.ajvNoDefaults);
65
37
  }
66
- }
67
-
68
- validate({ json, model, options, ctx }) {
69
- if (!ctx.jsonSchema) {
70
- return json;
38
+ beforeValidate({ json, model, options, ctx }) {
39
+ ctx.jsonSchema = model.constructor.getJsonSchema();
40
+ // Objection model's have a `$beforeValidate` hook that is allowed to modify the schema.
41
+ // We need to clone the schema in case the function modifies it. We only do this in the
42
+ // rare case that the given model has implemented the hook.
43
+ if (model.$beforeValidate !== model.$objectionModelClass.prototype.$beforeValidate) {
44
+ ctx.jsonSchema = cloneDeep(ctx.jsonSchema);
45
+ const ret = model.$beforeValidate(ctx.jsonSchema, json, options);
46
+ if (ret !== undefined) {
47
+ ctx.jsonSchema = ret;
48
+ }
49
+ }
71
50
  }
72
-
73
- const modelClass = model.constructor;
74
- const validator = this.getValidator(modelClass, ctx.jsonSchema, !!options.patch);
75
-
76
- // We need to clone the input json if we are about to set default values.
77
- if (!options.mutable && !options.patch && setsDefaultValues(ctx.jsonSchema)) {
78
- json = cloneDeep(json);
51
+ validate({ json, model, options, ctx }) {
52
+ if (!ctx.jsonSchema) {
53
+ return json;
54
+ }
55
+ const modelClass = model.constructor;
56
+ const validator = this.getValidator(modelClass, ctx.jsonSchema, !!options.patch);
57
+ // We need to clone the input json if we are about to set default values.
58
+ if (!options.mutable && !options.patch && setsDefaultValues(ctx.jsonSchema)) {
59
+ json = cloneDeep(json);
60
+ }
61
+ validator.call(model, json);
62
+ const error = parseValidationError(validator.errors, modelClass, options, this.ajvOptions);
63
+ if (error) {
64
+ throw error;
65
+ }
66
+ return json;
79
67
  }
80
-
81
- validator.call(model, json);
82
- const error = parseValidationError(validator.errors, modelClass, options, this.ajvOptions);
83
-
84
- if (error) {
85
- throw error;
68
+ getValidator(modelClass, jsonSchema, isPatchObject) {
69
+ // Use the Ajv custom serializer if provided.
70
+ const createCacheKey = this.ajvOptions.serialize || JSON.stringify;
71
+ // The compiled validators are cached by the serialized schema. In the
72
+ // common case where jsonSchema is the model class's own schema, they are
73
+ // also cached by the schema object, so the costly createCacheKey function
74
+ // runs once per schema object. Classes bound to a knex instance share their
75
+ // validator with the class they are bound from, and a bound class can have
76
+ // a schema of its own, so the cache isn't keyed by the class name.
77
+ const isClassSchema = jsonSchema === modelClass.getJsonSchema() && isObject(jsonSchema);
78
+ let validators = isClassSchema ? this.schemaCache.get(jsonSchema) : undefined;
79
+ let validator = null;
80
+ if (!validators) {
81
+ const cacheKey = createCacheKey(jsonSchema);
82
+ validators = this.cache.get(cacheKey);
83
+ if (!validators) {
84
+ validators = {
85
+ // Validator created for the schema object without `required` properties
86
+ // using the Ajv instance that doesn't set default values.
87
+ patchValidator: null,
88
+ // Validator created for the unmodified schema.
89
+ normalValidator: null,
90
+ };
91
+ this.cache.set(cacheKey, validators);
92
+ }
93
+ if (isClassSchema) {
94
+ this.schemaCache.set(jsonSchema, validators);
95
+ }
96
+ }
97
+ if (isPatchObject) {
98
+ validator = validators.patchValidator;
99
+ if (!validator) {
100
+ validator = this.compilePatchValidator(jsonSchema);
101
+ validators.patchValidator = validator;
102
+ }
103
+ }
104
+ else {
105
+ validator = validators.normalValidator;
106
+ if (!validator) {
107
+ validator = this.compileNormalValidator(jsonSchema);
108
+ validators.normalValidator = validator;
109
+ }
110
+ }
111
+ return validator;
86
112
  }
87
-
88
- return json;
89
- }
90
-
91
- getValidator(modelClass, jsonSchema, isPatchObject) {
92
- // Use the Ajv custom serializer if provided.
93
- const createCacheKey = this.ajvOptions.serialize || JSON.stringify;
94
-
95
- // Optimization for the common case where jsonSchema is never modified.
96
- // In that case we don't need to call the costly createCacheKey function.
97
- const cacheKey =
98
- jsonSchema === modelClass.getJsonSchema()
99
- ? modelClass.uniqueTag()
100
- : createCacheKey(jsonSchema);
101
-
102
- let validators = this.cache.get(cacheKey);
103
- let validator = null;
104
-
105
- if (!validators) {
106
- validators = {
107
- // Validator created for the schema object without `required` properties
108
- // using the Ajv instance that doesn't set default values.
109
- patchValidator: null,
110
-
111
- // Validator created for the unmodified schema.
112
- normalValidator: null,
113
- };
114
-
115
- this.cache.set(cacheKey, validators);
113
+ compilePatchValidator(jsonSchema) {
114
+ jsonSchema = jsonSchemaWithoutRequired(jsonSchema);
115
+ // We need to use the ajv instance that doesn't set the default values.
116
+ return this.ajvNoDefaults.compile(jsonSchema);
116
117
  }
117
-
118
- if (isPatchObject) {
119
- validator = validators.patchValidator;
120
-
121
- if (!validator) {
122
- validator = this.compilePatchValidator(jsonSchema);
123
- validators.patchValidator = validator;
124
- }
125
- } else {
126
- validator = validators.normalValidator;
127
-
128
- if (!validator) {
129
- validator = this.compileNormalValidator(jsonSchema);
130
- validators.normalValidator = validator;
131
- }
118
+ compileNormalValidator(jsonSchema) {
119
+ return this.ajv.compile(jsonSchema);
132
120
  }
133
-
134
- return validator;
135
- }
136
-
137
- compilePatchValidator(jsonSchema) {
138
- jsonSchema = jsonSchemaWithoutRequired(jsonSchema);
139
- // We need to use the ajv instance that doesn't set the default values.
140
- return this.ajvNoDefaults.compile(jsonSchema);
141
- }
142
-
143
- compileNormalValidator(jsonSchema) {
144
- return this.ajv.compile(jsonSchema);
145
- }
146
121
  }
147
-
148
122
  function parseValidationError(errors, modelClass, options, ajvOptions) {
149
- if (!errors) {
150
- return null;
151
- }
152
-
153
- let relationNames = modelClass.getRelationNames();
154
- let errorHash = {};
155
- let numErrors = 0;
156
-
157
- for (const error of errors) {
158
- // If additionalProperties = false, relations can pop up as additionalProperty
159
- // errors. Skip those.
160
- if (
161
- error.params &&
162
- error.params.additionalProperty &&
163
- relationNames.includes(error.params.additionalProperty)
164
- ) {
165
- continue;
123
+ if (!errors) {
124
+ return null;
166
125
  }
167
-
168
- let path = error.instancePath.replace(/\//g, '.');
169
-
170
- if (error.params) {
171
- if (error.params.missingProperty) {
172
- path += `.${error.params.missingProperty}`;
173
- } else if (error.params.additionalProperty) {
174
- path += `.${error.params.additionalProperty}`;
175
- }
126
+ const relationNames = modelClass.getRelationNames();
127
+ const errorHash = {};
128
+ let numErrors = 0;
129
+ for (const error of errors) {
130
+ // If additionalProperties = false, relations can pop up as additionalProperty
131
+ // errors. Skip those.
132
+ if (error.params &&
133
+ error.params.additionalProperty &&
134
+ relationNames.includes(error.params.additionalProperty)) {
135
+ continue;
136
+ }
137
+ let path = error.instancePath.replace(/\//g, '.');
138
+ if (error.params) {
139
+ if (error.params.missingProperty) {
140
+ path += `.${error.params.missingProperty}`;
141
+ }
142
+ else if (error.params.additionalProperty) {
143
+ path += `.${error.params.additionalProperty}`;
144
+ }
145
+ }
146
+ const key = `${options.dataPath || ''}${path}`.substring(1);
147
+ // More than one error can occur for the same key in Ajv, merge them in the array:
148
+ const array = errorHash[key] || (errorHash[key] = []);
149
+ // Prepare error object
150
+ const errorObj = {
151
+ message: error.message,
152
+ keyword: error.keyword,
153
+ params: error.params,
154
+ };
155
+ // Add data if verbose enabled
156
+ if (ajvOptions.verbose) {
157
+ errorObj.data = error.data;
158
+ }
159
+ // Use unshift instead of push so that the last error ends up at [0],
160
+ // preserving previous behavior where only the last error was stored.
161
+ array.unshift(errorObj);
162
+ ++numErrors;
176
163
  }
177
-
178
- const key = `${options.dataPath || ''}${path}`.substring(1);
179
-
180
- // More than one error can occur for the same key in Ajv, merge them in the array:
181
- const array = errorHash[key] || (errorHash[key] = []);
182
-
183
- // Prepare error object
184
- const errorObj = {
185
- message: error.message,
186
- keyword: error.keyword,
187
- params: error.params,
188
- };
189
-
190
- // Add data if verbose enabled
191
- if (ajvOptions.verbose) {
192
- errorObj.data = error.data;
164
+ if (numErrors === 0) {
165
+ return null;
193
166
  }
194
-
195
- // Use unshift instead of push so that the last error ends up at [0],
196
- // preserving previous behavior where only the last error was stored.
197
- array.unshift(errorObj);
198
-
199
- ++numErrors;
200
- }
201
-
202
- if (numErrors === 0) {
203
- return null;
204
- }
205
-
206
- return modelClass.createValidationError({
207
- type: ValidationErrorType.ModelValidation,
208
- data: errorHash,
209
- });
167
+ return modelClass.createValidationError({
168
+ type: ValidationErrorType.ModelValidation,
169
+ data: errorHash,
170
+ });
210
171
  }
211
-
212
172
  function cloneDeep(obj) {
213
- if (isObject(obj) && obj.$isObjectionModel) {
214
- return obj.$clone();
215
- } else {
216
- return lodashCloneDeep(obj);
217
- }
173
+ if (isObject(obj) && obj.$isObjectionModel) {
174
+ return obj.$clone();
175
+ }
176
+ else {
177
+ return cloneDeepValue(obj);
178
+ }
218
179
  }
219
-
180
+ // Whether a schema has default values is checked for every validated model,
181
+ // so the answer is cached per schema object.
182
+ const setsDefaultValuesCache = new WeakMap();
220
183
  function setsDefaultValues(jsonSchema) {
221
- return jsonSchema && jsonSchema.properties && hasDefaults(jsonSchema.properties);
184
+ if (!isObject(jsonSchema)) {
185
+ return jsonSchema && jsonSchema.properties && hasDefaults(jsonSchema.properties);
186
+ }
187
+ let result = setsDefaultValuesCache.get(jsonSchema);
188
+ if (result === undefined) {
189
+ result = !!(jsonSchema.properties && hasDefaults(jsonSchema.properties));
190
+ setsDefaultValuesCache.set(jsonSchema, result);
191
+ }
192
+ return result;
222
193
  }
223
-
224
194
  function hasDefaults(obj) {
225
- if (Array.isArray(obj)) {
226
- return arrayHasDefaults(obj);
227
- } else {
228
- return objectHasDefaults(obj);
229
- }
195
+ if (Array.isArray(obj)) {
196
+ return arrayHasDefaults(obj);
197
+ }
198
+ else {
199
+ return objectHasDefaults(obj);
200
+ }
230
201
  }
231
-
232
202
  function arrayHasDefaults(arr) {
233
- for (let i = 0, l = arr.length; i < l; ++i) {
234
- const val = arr[i];
235
-
236
- if (isObject(val) && hasDefaults(val)) {
237
- return true;
203
+ for (let i = 0, l = arr.length; i < l; ++i) {
204
+ const val = arr[i];
205
+ if (isObject(val) && hasDefaults(val)) {
206
+ return true;
207
+ }
238
208
  }
239
- }
240
-
241
- return false;
209
+ return false;
242
210
  }
243
-
244
211
  function objectHasDefaults(obj) {
245
- const keys = Object.keys(obj);
246
-
247
- for (let i = 0, l = keys.length; i < l; ++i) {
248
- const key = keys[i];
249
-
250
- if (key === 'default') {
251
- return true;
252
- } else {
253
- const val = obj[key];
254
-
255
- if (isObject(val) && hasDefaults(val)) {
256
- return true;
257
- }
212
+ const keys = Object.keys(obj);
213
+ for (let i = 0, l = keys.length; i < l; ++i) {
214
+ const key = keys[i];
215
+ if (key === 'default') {
216
+ return true;
217
+ }
218
+ else {
219
+ const val = obj[key];
220
+ if (isObject(val) && hasDefaults(val)) {
221
+ return true;
222
+ }
223
+ }
258
224
  }
259
- }
260
-
261
- return false;
225
+ return false;
262
226
  }
263
-
264
227
  function jsonSchemaWithoutRequired(jsonSchema) {
265
- const subSchemaProps = ['anyOf', 'oneOf', 'allOf', 'not', 'then', 'else', 'properties'];
266
- return Object.assign(
267
- omit(jsonSchema, ['required', ...subSchemaProps]),
268
- ...subSchemaProps.map((prop) => subSchemaWithoutRequired(jsonSchema, prop)),
269
- jsonSchema && jsonSchema.definitions && Object.keys(jsonSchema.definitions).length > 0
270
- ? {
271
- definitions: Object.assign(
272
- ...Object.keys(jsonSchema.definitions).map((prop) => ({
273
- [prop]: jsonSchemaWithoutRequired(jsonSchema.definitions[prop]),
274
- })),
275
- ),
228
+ const subSchemaProps = ['anyOf', 'oneOf', 'allOf', 'not', 'then', 'else', 'properties'];
229
+ return Object.assign(omit(jsonSchema, ['required', ...subSchemaProps]), ...subSchemaProps.map((prop) => subSchemaWithoutRequired(jsonSchema, prop)), jsonSchema && jsonSchema.definitions && Object.keys(jsonSchema.definitions).length > 0
230
+ ? {
231
+ definitions: Object.assign(...Object.keys(jsonSchema.definitions).map((prop) => ({
232
+ [prop]: jsonSchemaWithoutRequired(jsonSchema.definitions[prop]),
233
+ }))),
276
234
  }
277
- : {},
278
- jsonSchema.discriminator && jsonSchema.discriminator.propertyName
279
- ? { required: [jsonSchema.discriminator.propertyName] }
280
- : {},
281
- );
235
+ : {}, jsonSchema.discriminator && jsonSchema.discriminator.propertyName
236
+ ? { required: [jsonSchema.discriminator.propertyName] }
237
+ : {});
282
238
  }
283
-
284
239
  function subSchemaWithoutRequired(jsonSchema, prop) {
285
- if (jsonSchema[prop]) {
286
- if (Array.isArray(jsonSchema[prop])) {
287
- const schemaArray = jsonSchemaArrayWithoutRequired(jsonSchema[prop]);
288
-
289
- if (schemaArray.length !== 0) {
290
- return {
291
- [prop]: schemaArray,
292
- };
293
- } else {
240
+ if (jsonSchema[prop]) {
241
+ if (Array.isArray(jsonSchema[prop])) {
242
+ const schemaArray = jsonSchemaArrayWithoutRequired(jsonSchema[prop]);
243
+ if (schemaArray.length !== 0) {
244
+ return {
245
+ [prop]: schemaArray,
246
+ };
247
+ }
248
+ else {
249
+ return {};
250
+ }
251
+ }
252
+ else if (jsonSchema.type === 'object' && prop === 'properties') {
253
+ return {
254
+ [prop]: Object.fromEntries(Object.entries(jsonSchema[prop]).map(([key, schema]) => [
255
+ key,
256
+ jsonSchemaWithoutRequired(schema),
257
+ ])),
258
+ };
259
+ }
260
+ else {
261
+ return {
262
+ [prop]: jsonSchemaWithoutRequired(jsonSchema[prop]),
263
+ };
264
+ }
265
+ }
266
+ else {
294
267
  return {};
295
- }
296
- } else if (jsonSchema.type === 'object' && prop === 'properties') {
297
- return {
298
- [prop]: Object.fromEntries(
299
- Object.entries(jsonSchema[prop]).map(([key, schema]) => [
300
- key,
301
- jsonSchemaWithoutRequired(schema),
302
- ]),
303
- ),
304
- };
305
- } else {
306
- return {
307
- [prop]: jsonSchemaWithoutRequired(jsonSchema[prop]),
308
- };
309
268
  }
310
- } else {
311
- return {};
312
- }
313
269
  }
314
-
315
270
  function jsonSchemaArrayWithoutRequired(jsonSchemaArray) {
316
- return jsonSchemaArray.map(jsonSchemaWithoutRequired).filter(isNotEmptyObject);
271
+ return jsonSchemaArray.map(jsonSchemaWithoutRequired).filter(isNotEmptyObject);
317
272
  }
318
-
319
273
  function isNotEmptyObject(obj) {
320
- return Object.keys(obj).length !== 0;
274
+ return Object.keys(obj).length !== 0;
321
275
  }
322
-
323
276
  module.exports = {
324
- AjvValidator,
277
+ AjvValidator,
325
278
  };