@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.
- package/README.md +103 -67
- package/lib/index.mjs +6 -0
- package/lib/initialize.js +6 -9
- package/lib/model/AjvValidator.js +235 -282
- package/lib/model/Model.js +653 -823
- package/lib/model/ModifierNotFoundError.js +5 -7
- package/lib/model/NotFoundError.js +14 -18
- package/lib/model/RelationDoesNotExistError.js +6 -9
- package/lib/model/ValidationError.js +33 -41
- package/lib/model/Validator.js +15 -21
- package/lib/model/getModel.js +1 -3
- package/lib/model/graph/ModelGraph.js +44 -64
- package/lib/model/graph/ModelGraphBuilder.js +164 -217
- package/lib/model/graph/ModelGraphEdge.js +31 -43
- package/lib/model/graph/ModelGraphNode.js +192 -231
- package/lib/model/inheritModel.js +9 -18
- package/lib/model/modelBindKnex.js +48 -62
- package/lib/model/modelClone.js +79 -98
- package/lib/model/modelColPropMap.js +16 -26
- package/lib/model/modelConcurrency.js +24 -0
- package/lib/model/modelId.js +44 -49
- package/lib/model/modelJsonAttributes.js +56 -76
- package/lib/model/modelParseRelations.js +68 -67
- package/lib/model/modelQueryProps.js +76 -107
- package/lib/model/modelSet.js +92 -112
- package/lib/model/modelTableMetadata.js +60 -72
- package/lib/model/modelToJson.js +120 -150
- package/lib/model/modelUtils.js +30 -37
- package/lib/model/modelValidate.js +34 -42
- package/lib/model/modelValues.js +78 -91
- package/lib/model/modelVisitor.js +22 -29
- package/lib/objection.js +42 -67
- package/lib/queryBuilder/FunctionBuilder.js +231 -279
- package/lib/queryBuilder/InternalOptions.js +19 -24
- package/lib/queryBuilder/JoinBuilder.js +116 -149
- package/lib/queryBuilder/QueryBuilder.js +1009 -1271
- package/lib/queryBuilder/QueryBuilderBase.js +647 -865
- package/lib/queryBuilder/QueryBuilderContext.js +14 -21
- package/lib/queryBuilder/QueryBuilderContextBase.js +20 -29
- package/lib/queryBuilder/QueryBuilderOperationSupport.js +462 -536
- package/lib/queryBuilder/QueryBuilderUserContext.js +19 -25
- package/lib/queryBuilder/RawBuilder.js +58 -73
- package/lib/queryBuilder/ReferenceBuilder.js +232 -270
- package/lib/queryBuilder/RelationExpression.js +322 -380
- package/lib/queryBuilder/StaticHookArguments.js +94 -106
- package/lib/queryBuilder/ValueBuilder.js +100 -112
- package/lib/queryBuilder/expressions.js +86 -116
- package/lib/queryBuilder/functions/mysql.js +642 -697
- package/lib/queryBuilder/graph/GraphAction.js +44 -59
- package/lib/queryBuilder/graph/GraphData.js +7 -9
- package/lib/queryBuilder/graph/GraphFetcher.js +115 -151
- package/lib/queryBuilder/graph/GraphNodeDbExistence.js +114 -152
- package/lib/queryBuilder/graph/GraphOperation.js +16 -22
- package/lib/queryBuilder/graph/GraphOptions.js +143 -185
- package/lib/queryBuilder/graph/GraphUpsert.js +167 -241
- package/lib/queryBuilder/graph/delete/GraphDelete.js +8 -13
- package/lib/queryBuilder/graph/delete/GraphDeleteAction.js +44 -62
- package/lib/queryBuilder/graph/insert/GraphInsert.js +99 -128
- package/lib/queryBuilder/graph/insert/GraphInsertAction.js +151 -193
- package/lib/queryBuilder/graph/insert/JoinRowGraphInsertAction.js +57 -79
- package/lib/queryBuilder/graph/patch/GraphPatch.js +8 -13
- package/lib/queryBuilder/graph/patch/GraphPatchAction.js +181 -234
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsert.js +16 -21
- package/lib/queryBuilder/graph/recursiveUpsert/GraphRecursiveUpsertAction.js +80 -110
- package/lib/queryBuilder/join/JoinResultColumn.js +14 -18
- package/lib/queryBuilder/join/JoinResultParser.js +88 -101
- package/lib/queryBuilder/join/RelationJoiner.js +205 -288
- package/lib/queryBuilder/join/TableNode.js +117 -144
- package/lib/queryBuilder/join/TableTree.js +60 -76
- package/lib/queryBuilder/join/utils.js +10 -16
- package/lib/queryBuilder/operations/DelegateOperation.js +93 -133
- package/lib/queryBuilder/operations/DeleteOperation.js +33 -37
- package/lib/queryBuilder/operations/FindByIdOperation.js +20 -28
- package/lib/queryBuilder/operations/FindByIdsOperation.js +17 -23
- package/lib/queryBuilder/operations/FindOperation.js +114 -131
- package/lib/queryBuilder/operations/FirstOperation.js +14 -19
- package/lib/queryBuilder/operations/FromOperation.js +69 -88
- package/lib/queryBuilder/operations/InsertAndFetchOperation.js +28 -39
- package/lib/queryBuilder/operations/InsertGraphAndFetchOperation.js +25 -35
- package/lib/queryBuilder/operations/InsertGraphOperation.js +77 -98
- package/lib/queryBuilder/operations/InsertOperation.js +132 -165
- package/lib/queryBuilder/operations/InstanceDeleteOperation.js +27 -36
- package/lib/queryBuilder/operations/InstanceFindOperation.js +9 -13
- package/lib/queryBuilder/operations/InstanceInsertOperation.js +13 -17
- package/lib/queryBuilder/operations/InstanceUpdateOperation.js +32 -46
- package/lib/queryBuilder/operations/JoinRelatedOperation.js +66 -86
- package/lib/queryBuilder/operations/KnexOperation.js +4 -7
- package/lib/queryBuilder/operations/MergeOperation.js +32 -45
- package/lib/queryBuilder/operations/ObjectionToKnexConvertingOperation.js +131 -150
- package/lib/queryBuilder/operations/OnBuildKnexOperation.js +17 -23
- package/lib/queryBuilder/operations/OnBuildOperation.js +17 -23
- package/lib/queryBuilder/operations/OnErrorOperation.js +17 -23
- package/lib/queryBuilder/operations/QueryBuilderOperation.js +231 -270
- package/lib/queryBuilder/operations/RangeOperation.js +30 -40
- package/lib/queryBuilder/operations/RelateOperation.js +14 -21
- package/lib/queryBuilder/operations/ReturningOperation.js +12 -18
- package/lib/queryBuilder/operations/RunAfterOperation.js +17 -23
- package/lib/queryBuilder/operations/RunBeforeOperation.js +17 -23
- package/lib/queryBuilder/operations/UnrelateOperation.js +12 -17
- package/lib/queryBuilder/operations/UpdateAndFetchOperation.js +48 -65
- package/lib/queryBuilder/operations/UpdateOperation.js +104 -129
- package/lib/queryBuilder/operations/UpsertGraphAndFetchOperation.js +25 -35
- package/lib/queryBuilder/operations/UpsertGraphOperation.js +36 -55
- package/lib/queryBuilder/operations/WhereCompositeOperation.js +30 -39
- package/lib/queryBuilder/operations/WhereInOperation.js +34 -36
- package/lib/queryBuilder/operations/eager/EagerOperation.js +37 -52
- package/lib/queryBuilder/operations/eager/JoinEagerOperation.js +34 -44
- package/lib/queryBuilder/operations/eager/NaiveEagerOperation.js +4 -7
- package/lib/queryBuilder/operations/eager/WhereInEagerOperation.js +193 -251
- package/lib/queryBuilder/operations/jsonApi/WhereJsonHasOperation.js +18 -25
- package/lib/queryBuilder/operations/jsonApi/WhereJsonNotObjectOperation.js +25 -41
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOperation.js +19 -20
- package/lib/queryBuilder/operations/jsonApi/WhereJsonOverlapsOperation.js +23 -21
- package/lib/queryBuilder/operations/jsonApi/mysqlJsonApi.js +106 -118
- package/lib/queryBuilder/operations/jsonApi/postgresJsonApi.js +79 -108
- package/lib/queryBuilder/operations/select/SelectOperation.js +37 -53
- package/lib/queryBuilder/operations/select/Selection.js +94 -105
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeMsSqlOperation.js +68 -101
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeOperation.js +65 -75
- package/lib/queryBuilder/operations/whereInComposite/WhereInCompositeSqliteOperation.js +75 -84
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.js +760 -859
- package/lib/queryBuilder/parsers/relationExpressionParser.js +840 -952
- package/lib/queryBuilder/transformations/CompositeQueryTransformation.js +10 -15
- package/lib/queryBuilder/transformations/QueryTransformation.js +4 -6
- package/lib/queryBuilder/transformations/WrapMysqlModifySubqueryTransformation.js +35 -49
- package/lib/queryBuilder/transformations/index.js +3 -9
- package/lib/queryBuilder/whereScopes.js +158 -186
- package/lib/relations/Relation.js +279 -363
- package/lib/relations/RelationDeleteOperation.js +16 -22
- package/lib/relations/RelationFindOperation.js +100 -133
- package/lib/relations/RelationInsertOperation.js +19 -27
- package/lib/relations/RelationOwner.js +167 -204
- package/lib/relations/RelationProperty.js +177 -217
- package/lib/relations/RelationUpdateOperation.js +16 -23
- package/lib/relations/belongsToOne/BelongsToOneDeleteOperation.js +11 -16
- package/lib/relations/belongsToOne/BelongsToOneInsertOperation.js +24 -35
- package/lib/relations/belongsToOne/BelongsToOneRelateOperation.js +30 -41
- package/lib/relations/belongsToOne/BelongsToOneRelation.js +33 -41
- package/lib/relations/belongsToOne/BelongsToOneUnrelateOperation.js +38 -53
- package/lib/relations/hasMany/HasManyInsertOperation.js +35 -51
- package/lib/relations/hasMany/HasManyRelateOperation.js +38 -54
- package/lib/relations/hasMany/HasManyRelation.js +30 -38
- package/lib/relations/hasMany/HasManyUnrelateOperation.js +19 -26
- package/lib/relations/hasOne/HasOneRelation.js +4 -7
- package/lib/relations/hasOneThrough/HasOneThroughRelation.js +4 -7
- package/lib/relations/manyToMany/ManyToManyModifyMixin.js +67 -90
- package/lib/relations/manyToMany/ManyToManyRelation.js +349 -451
- package/lib/relations/manyToMany/ManyToManySqliteModifyMixin.js +19 -26
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperation.js +3 -5
- package/lib/relations/manyToMany/delete/ManyToManyDeleteOperationBase.js +14 -20
- package/lib/relations/manyToMany/delete/ManyToManyDeleteSqliteOperation.js +3 -7
- package/lib/relations/manyToMany/find/ManyToManyFindOperation.js +71 -94
- package/lib/relations/manyToMany/insert/ManyToManyInsertOperation.js +31 -43
- package/lib/relations/manyToMany/relate/ManyToManyRelateOperation.js +50 -67
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperation.js +4 -7
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateOperationBase.js +20 -27
- package/lib/relations/manyToMany/unrelate/ManyToManyUnrelateSqliteOperation.js +5 -10
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperation.js +3 -5
- package/lib/relations/manyToMany/update/ManyToManyUpdateOperationBase.js +55 -72
- package/lib/relations/manyToMany/update/ManyToManyUpdateSqliteOperation.js +3 -7
- package/lib/transaction.js +53 -83
- package/lib/utils/assert.js +15 -21
- package/lib/utils/buildUtils.js +17 -19
- package/lib/utils/classUtils.js +7 -11
- package/lib/utils/cloneDeep.js +365 -0
- package/lib/utils/createModifier.js +36 -41
- package/lib/utils/deprecate.js +8 -12
- package/lib/utils/identifierMapping.js +153 -192
- package/lib/utils/internalPropUtils.js +4 -8
- package/lib/utils/knexUtils.js +61 -56
- package/lib/utils/mixin.js +16 -23
- package/lib/utils/mysqlJsonPath.js +55 -40
- package/lib/utils/normalizeIds.js +110 -127
- package/lib/utils/objectUtils.js +236 -338
- package/lib/utils/parseFieldExpression.js +66 -44
- package/lib/utils/postgresJsonPath.js +48 -62
- package/lib/utils/promiseUtils/after.js +10 -13
- package/lib/utils/promiseUtils/afterReturn.js +10 -13
- package/lib/utils/promiseUtils/index.js +15 -17
- package/lib/utils/promiseUtils/isPromise.js +6 -9
- package/lib/utils/promiseUtils/map.js +75 -89
- package/lib/utils/promiseUtils/mapAfterAllReturn.js +17 -23
- package/lib/utils/promiseUtils/try.js +15 -18
- package/lib/utils/resolveModel.js +91 -94
- package/lib/utils/tmpColumnUtils.js +4 -13
- package/package.json +50 -23
- package/typings/objection/index.d.mts +362 -0
- package/typings/objection/index.d.ts +36 -9
- package/lib/.eslintrc.json +0 -8
- package/lib/queryBuilder/parsers/jsonFieldExpressionParser.pegjs +0 -97
- package/lib/queryBuilder/parsers/relationExpressionParser.pegjs +0 -141
- package/lib/utils/clone.js +0 -2329
|
@@ -1,83 +1,71 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { defineNonEnumerableProperty } = require('./modelUtils');
|
|
4
3
|
const { isPromise } = require('../utils/promiseUtils');
|
|
5
|
-
|
|
6
4
|
const TABLE_METADATA = '$$tableMetadata';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
5
|
+
function fetchTableMetadata(modelClass, { parentBuilder = null, knex = null, force = false, table = null } = {}) {
|
|
6
|
+
// The table isn't necessarily same as `modelClass.getTableName()` for example if
|
|
7
|
+
// a view is queried instead.
|
|
8
|
+
if (!table) {
|
|
9
|
+
if (parentBuilder) {
|
|
10
|
+
table = parentBuilder.tableNameFor(modelClass);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
table = modelClass.getTableName();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// Call tableMetadata first instead of accessing the cache directly beause
|
|
17
|
+
// tableMetadata may have been overriden.
|
|
18
|
+
let metadata = modelClass.tableMetadata({ table });
|
|
19
|
+
if (!force && metadata) {
|
|
20
|
+
return Promise.resolve(metadata);
|
|
21
|
+
}
|
|
22
|
+
// Memoize metadata but only for modelClass. The hasOwnProperty check
|
|
23
|
+
// will fail for subclasses and the value gets recreated.
|
|
24
|
+
if (!Object.hasOwn(modelClass, TABLE_METADATA)) {
|
|
25
|
+
defineNonEnumerableProperty(modelClass, TABLE_METADATA, new Map());
|
|
26
|
+
}
|
|
27
|
+
// The cache needs to be checked in addition to calling tableMetadata
|
|
28
|
+
// because the cache may contain a temporary promise in which case
|
|
29
|
+
// tableMetadata returns null.
|
|
30
|
+
metadata = modelClass[TABLE_METADATA].get(table);
|
|
31
|
+
if (!force && metadata) {
|
|
32
|
+
return Promise.resolve(metadata);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
const promise = modelClass
|
|
36
|
+
.query(knex)
|
|
37
|
+
.childQueryOf(parentBuilder)
|
|
38
|
+
.columnInfo({ table })
|
|
39
|
+
.then((columnInfo) => {
|
|
40
|
+
const metadata = {
|
|
41
|
+
columns: Object.keys(columnInfo),
|
|
42
|
+
};
|
|
43
|
+
modelClass[TABLE_METADATA].set(table, metadata);
|
|
44
|
+
return metadata;
|
|
45
|
+
})
|
|
46
|
+
.catch((err) => {
|
|
47
|
+
modelClass[TABLE_METADATA].delete(table);
|
|
48
|
+
throw err;
|
|
49
|
+
});
|
|
50
|
+
modelClass[TABLE_METADATA].set(table, promise);
|
|
51
|
+
return promise;
|
|
19
52
|
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Call tableMetadata first instead of accessing the cache directly beause
|
|
23
|
-
// tableMetadata may have been overriden.
|
|
24
|
-
let metadata = modelClass.tableMetadata({ table });
|
|
25
|
-
|
|
26
|
-
if (!force && metadata) {
|
|
27
|
-
return Promise.resolve(metadata);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Memoize metadata but only for modelClass. The hasOwnProperty check
|
|
31
|
-
// will fail for subclasses and the value gets recreated.
|
|
32
|
-
if (!modelClass.hasOwnProperty(TABLE_METADATA)) {
|
|
33
|
-
defineNonEnumerableProperty(modelClass, TABLE_METADATA, new Map());
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// The cache needs to be checked in addition to calling tableMetadata
|
|
37
|
-
// because the cache may contain a temporary promise in which case
|
|
38
|
-
// tableMetadata returns null.
|
|
39
|
-
metadata = modelClass[TABLE_METADATA].get(table);
|
|
40
|
-
|
|
41
|
-
if (!force && metadata) {
|
|
42
|
-
return Promise.resolve(metadata);
|
|
43
|
-
} else {
|
|
44
|
-
const promise = modelClass
|
|
45
|
-
.query(knex)
|
|
46
|
-
.childQueryOf(parentBuilder)
|
|
47
|
-
.columnInfo({ table })
|
|
48
|
-
.then((columnInfo) => {
|
|
49
|
-
const metadata = {
|
|
50
|
-
columns: Object.keys(columnInfo),
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
modelClass[TABLE_METADATA].set(table, metadata);
|
|
54
|
-
return metadata;
|
|
55
|
-
})
|
|
56
|
-
.catch((err) => {
|
|
57
|
-
modelClass[TABLE_METADATA].delete(table);
|
|
58
|
-
throw err;
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
modelClass[TABLE_METADATA].set(table, promise);
|
|
62
|
-
return promise;
|
|
63
|
-
}
|
|
64
53
|
}
|
|
65
|
-
|
|
66
54
|
function tableMetadata(modelClass, { table } = {}) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
55
|
+
if (Object.hasOwn(modelClass, TABLE_METADATA)) {
|
|
56
|
+
const metadata = modelClass[TABLE_METADATA].get(table || modelClass.getTableName());
|
|
57
|
+
if (isPromise(metadata)) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
return metadata;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
return null;
|
|
74
66
|
}
|
|
75
|
-
} else {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
67
|
}
|
|
79
|
-
|
|
80
68
|
module.exports = {
|
|
81
|
-
|
|
82
|
-
|
|
69
|
+
fetchTableMetadata,
|
|
70
|
+
tableMetadata,
|
|
83
71
|
};
|
package/lib/model/modelToJson.js
CHANGED
|
@@ -1,187 +1,157 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { isInternalProp } = require('../utils/internalPropUtils');
|
|
4
3
|
const { mergeQueryProps } = require('./modelQueryProps');
|
|
5
4
|
const { isObject, cloneDeep, isFunction } = require('../utils/objectUtils');
|
|
6
5
|
const EMPTY_ARRAY = [];
|
|
7
|
-
|
|
8
6
|
function toJson(model, optIn) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
json = model.$formatJson(json);
|
|
22
|
-
|
|
23
|
-
return json;
|
|
7
|
+
const modelClass = model.constructor;
|
|
8
|
+
const opt = {
|
|
9
|
+
virtuals: getVirtuals(optIn),
|
|
10
|
+
shallow: isShallow(optIn),
|
|
11
|
+
omit: getOmit(optIn, modelClass),
|
|
12
|
+
pick: null,
|
|
13
|
+
omitFromJson: model.$omitFromJson() || null,
|
|
14
|
+
cloneObjects: modelClass.cloneObjectAttributes,
|
|
15
|
+
};
|
|
16
|
+
let json = toExternalJsonImpl(model, opt);
|
|
17
|
+
json = model.$formatJson(json);
|
|
18
|
+
return json;
|
|
24
19
|
}
|
|
25
|
-
|
|
26
20
|
function toDatabaseJson(model, builder) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
json = model.$formatDatabaseJson(json);
|
|
40
|
-
|
|
41
|
-
return mergeQueryProps(model, json, opt.omitFromJson, builder);
|
|
21
|
+
const modelClass = model.constructor;
|
|
22
|
+
const opt = {
|
|
23
|
+
virtuals: false,
|
|
24
|
+
shallow: true,
|
|
25
|
+
omit: modelClass.getRelationNames(),
|
|
26
|
+
pick: getPick(modelClass),
|
|
27
|
+
omitFromJson: model.$omitFromDatabaseJson() || null,
|
|
28
|
+
cloneObjects: modelClass.cloneObjectAttributes,
|
|
29
|
+
};
|
|
30
|
+
let json = toDatabaseJsonImpl(model, opt);
|
|
31
|
+
json = model.$formatDatabaseJson(json);
|
|
32
|
+
return mergeQueryProps(model, json, opt.omitFromJson, builder);
|
|
42
33
|
}
|
|
43
|
-
|
|
44
34
|
function getVirtuals(opt) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
35
|
+
if (!opt) {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
else if (Array.isArray(opt.virtuals)) {
|
|
39
|
+
return opt.virtuals;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
return opt.virtuals !== false;
|
|
43
|
+
}
|
|
52
44
|
}
|
|
53
|
-
|
|
54
45
|
function isShallow(opt) {
|
|
55
|
-
|
|
46
|
+
return !!opt && !!opt.shallow;
|
|
56
47
|
}
|
|
57
|
-
|
|
58
48
|
function getOmit(opt, modelClass) {
|
|
59
|
-
|
|
49
|
+
return isShallow(opt) ? modelClass.getRelationNames() : null;
|
|
60
50
|
}
|
|
61
|
-
|
|
62
51
|
function getPick(modelClass) {
|
|
63
|
-
|
|
64
|
-
|
|
52
|
+
const jsonSchema = modelClass.getJsonSchema();
|
|
53
|
+
return (jsonSchema && modelClass.pickJsonSchemaProperties && jsonSchema.properties) || null;
|
|
65
54
|
}
|
|
66
|
-
|
|
67
55
|
function toExternalJsonImpl(model, opt) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
assignVirtualAttributes(json, model, vAttr, opt);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return json;
|
|
56
|
+
const json = {};
|
|
57
|
+
const keys = Object.keys(model);
|
|
58
|
+
const vAttr = getVirtualAttributes(model, opt);
|
|
59
|
+
for (let i = 0, l = keys.length; i < l; ++i) {
|
|
60
|
+
const key = keys[i];
|
|
61
|
+
const value = model[key];
|
|
62
|
+
assignJsonValue(json, key, value, opt);
|
|
63
|
+
}
|
|
64
|
+
if (vAttr.length !== 0) {
|
|
65
|
+
assignVirtualAttributes(json, model, vAttr, opt);
|
|
66
|
+
}
|
|
67
|
+
return json;
|
|
84
68
|
}
|
|
85
|
-
|
|
86
69
|
function getVirtualAttributes(model, opt) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
70
|
+
if (Array.isArray(opt.virtuals)) {
|
|
71
|
+
return opt.virtuals;
|
|
72
|
+
}
|
|
73
|
+
else if (opt.virtuals === true) {
|
|
74
|
+
return model.constructor.getVirtualAttributes();
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
return EMPTY_ARRAY;
|
|
78
|
+
}
|
|
94
79
|
}
|
|
95
|
-
|
|
96
80
|
function toDatabaseJsonImpl(model, opt) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return json;
|
|
81
|
+
const json = {};
|
|
82
|
+
const keys = Object.keys(model);
|
|
83
|
+
for (let i = 0, l = keys.length; i < l; ++i) {
|
|
84
|
+
const key = keys[i];
|
|
85
|
+
const value = model[key];
|
|
86
|
+
assignJsonValue(json, key, value, opt);
|
|
87
|
+
}
|
|
88
|
+
return json;
|
|
108
89
|
}
|
|
109
|
-
|
|
110
90
|
function assignJsonValue(json, key, value, opt) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
}
|
|
91
|
+
const type = typeof value;
|
|
92
|
+
if (type !== 'function' &&
|
|
93
|
+
type !== 'undefined' &&
|
|
94
|
+
!isInternalProp(key) &&
|
|
95
|
+
!shouldOmit(opt, key) &&
|
|
96
|
+
shouldPick(opt, key)) {
|
|
97
|
+
if (isObject(value)) {
|
|
98
|
+
json[key] = toJsonObject(value, opt);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
json[key] = value;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
126
104
|
}
|
|
127
|
-
|
|
128
105
|
function shouldOmit(opt, key) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
(opt.omitFromJson !== null && opt.omitFromJson.includes(key))
|
|
132
|
-
);
|
|
106
|
+
return ((opt.omit !== null && opt.omit.includes(key)) ||
|
|
107
|
+
(opt.omitFromJson !== null && opt.omitFromJson.includes(key)));
|
|
133
108
|
}
|
|
134
|
-
|
|
135
109
|
function shouldPick(opt, key) {
|
|
136
|
-
|
|
110
|
+
return opt.pick === null || key in opt.pick;
|
|
137
111
|
}
|
|
138
|
-
|
|
139
112
|
function assignVirtualAttributes(json, model, vAttr, opt) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
assignJsonValue(json, key, value, opt);
|
|
149
|
-
}
|
|
113
|
+
for (let i = 0, l = vAttr.length; i < l; ++i) {
|
|
114
|
+
const key = vAttr[i];
|
|
115
|
+
let value = model[key];
|
|
116
|
+
if (isFunction(value)) {
|
|
117
|
+
value = value.call(model);
|
|
118
|
+
}
|
|
119
|
+
assignJsonValue(json, key, value, opt);
|
|
120
|
+
}
|
|
150
121
|
}
|
|
151
|
-
|
|
152
122
|
function toJsonObject(value, opt) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
123
|
+
if (Array.isArray(value)) {
|
|
124
|
+
return toJsonArray(value, opt);
|
|
125
|
+
}
|
|
126
|
+
else if (value.$isObjectionModel) {
|
|
127
|
+
// No branch for $toDatabaseJson here since there is never a need
|
|
128
|
+
// to have nested models in database rows.
|
|
129
|
+
return value.$toJson(opt);
|
|
130
|
+
}
|
|
131
|
+
else if (Buffer.isBuffer(value)) {
|
|
132
|
+
return value;
|
|
133
|
+
}
|
|
134
|
+
else if (opt.cloneObjects) {
|
|
135
|
+
return cloneDeep(value);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
166
140
|
}
|
|
167
|
-
|
|
168
141
|
function toJsonArray(value, opt) {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return ret;
|
|
142
|
+
const ret = new Array(value.length);
|
|
143
|
+
for (let i = 0, l = ret.length; i < l; ++i) {
|
|
144
|
+
const item = value[i];
|
|
145
|
+
if (isObject(item)) {
|
|
146
|
+
ret[i] = toJsonObject(item, opt);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
ret[i] = item;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return ret;
|
|
182
153
|
}
|
|
183
|
-
|
|
184
154
|
module.exports = {
|
|
185
|
-
|
|
186
|
-
|
|
155
|
+
toJson,
|
|
156
|
+
toDatabaseJson,
|
|
187
157
|
};
|
package/lib/model/modelUtils.js
CHANGED
|
@@ -1,47 +1,40 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const hiddenProps = ['$$queryProps'];
|
|
4
|
-
|
|
5
3
|
const staticHiddenProps = [
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
4
|
+
'$$knex',
|
|
5
|
+
'$$validator',
|
|
6
|
+
'$$jsonSchema',
|
|
7
|
+
'$$colToProp',
|
|
8
|
+
'$$propToCol',
|
|
9
|
+
'$$relationMappings',
|
|
10
|
+
'$$relations',
|
|
11
|
+
'$$relationNames',
|
|
12
|
+
'$$jsonAttributes',
|
|
13
|
+
'$$columnNameMappers',
|
|
14
|
+
'$$tableMetadata',
|
|
15
|
+
'$$readOnlyAttributes',
|
|
16
|
+
'$$idRelationProperty',
|
|
17
|
+
'$$virtualAttributes',
|
|
20
18
|
];
|
|
21
|
-
|
|
22
19
|
function defineNonEnumerableProperty(obj, prop, value) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
Object.defineProperty(obj, prop, {
|
|
21
|
+
enumerable: false,
|
|
22
|
+
writable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
value,
|
|
25
|
+
});
|
|
29
26
|
}
|
|
30
|
-
|
|
31
27
|
function keyByProps(models, props) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
return map;
|
|
28
|
+
const map = new Map();
|
|
29
|
+
for (let i = 0, l = models.length; i < l; ++i) {
|
|
30
|
+
const model = models[i];
|
|
31
|
+
map.set(model.$propKey(props), model);
|
|
32
|
+
}
|
|
33
|
+
return map;
|
|
40
34
|
}
|
|
41
|
-
|
|
42
35
|
module.exports = {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
hiddenProps,
|
|
37
|
+
staticHiddenProps,
|
|
38
|
+
defineNonEnumerableProperty,
|
|
39
|
+
keyByProps,
|
|
47
40
|
};
|
|
@@ -1,48 +1,40 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
2
|
const { clone } = require('./modelClone');
|
|
4
|
-
|
|
5
3
|
function validate(model, json, options = {}) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
json
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// If we cloned `json`, we need to copy the possible default values.
|
|
40
|
-
return inputJson.$set(json);
|
|
41
|
-
} else {
|
|
42
|
-
return json;
|
|
43
|
-
}
|
|
4
|
+
json = json || model;
|
|
5
|
+
const inputJson = json;
|
|
6
|
+
const validatingModelInstance = inputJson && inputJson.$isObjectionModel;
|
|
7
|
+
if (options.skipValidation) {
|
|
8
|
+
return json;
|
|
9
|
+
}
|
|
10
|
+
if (validatingModelInstance) {
|
|
11
|
+
// Strip away relations and other internal stuff.
|
|
12
|
+
// TODO 1: This should use `json.$toJson()` since we always validate the input representation!
|
|
13
|
+
// TODO 2: This should also keep the relations in the object because some validators may
|
|
14
|
+
// depend on the relations.
|
|
15
|
+
json = clone(json, true, true);
|
|
16
|
+
// We can mutate `json` now that we took a copy of it.
|
|
17
|
+
options = Object.assign({}, options, { mutable: true });
|
|
18
|
+
}
|
|
19
|
+
const modelClass = model.constructor;
|
|
20
|
+
const validator = modelClass.getValidator();
|
|
21
|
+
const args = {
|
|
22
|
+
options,
|
|
23
|
+
model,
|
|
24
|
+
json,
|
|
25
|
+
ctx: Object.create(null),
|
|
26
|
+
};
|
|
27
|
+
validator.beforeValidate(args);
|
|
28
|
+
json = validator.validate(args);
|
|
29
|
+
validator.afterValidate(args);
|
|
30
|
+
if (validatingModelInstance) {
|
|
31
|
+
// If we cloned `json`, we need to copy the possible default values.
|
|
32
|
+
return inputJson.$set(json);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
return json;
|
|
36
|
+
}
|
|
44
37
|
}
|
|
45
|
-
|
|
46
38
|
module.exports = {
|
|
47
|
-
|
|
39
|
+
validate,
|
|
48
40
|
};
|