@cleverbrush/schema 0.0.6 → 0.0.7
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/dist/schemaValidator.js +4 -0
- package/package.json +2 -2
- package/src/schemaValidator.test.ts +208 -0
- package/src/schemaValidator.ts +7 -0
package/dist/schemaValidator.js
CHANGED
|
@@ -128,6 +128,10 @@ class SchemaValidator {
|
|
|
128
128
|
return await this.validateDefaultType(schema, obj);
|
|
129
129
|
}
|
|
130
130
|
else if (typeof this.schemas[schema] !== 'undefined') {
|
|
131
|
+
if (Array.isArray(this.schemas[schema].schema)) {
|
|
132
|
+
return this.validate(this.schemas[schema]
|
|
133
|
+
.schema, obj);
|
|
134
|
+
}
|
|
131
135
|
const objSchema = (0, deep_1.deepExtend)(defaultSchemas.object, this.schemas[schema].schema);
|
|
132
136
|
const res = await (0, validateObject_1.validateObject)(obj, objSchema, this);
|
|
133
137
|
if (!res.valid)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cleverbrush/schema",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"object schema validator",
|
|
6
6
|
"schema",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"build": "tsc"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@cleverbrush/deep": "0.0.
|
|
22
|
+
"@cleverbrush/deep": "0.0.7"
|
|
23
23
|
},
|
|
24
24
|
"types": "./dist/index.d.ts"
|
|
25
25
|
}
|
|
@@ -912,3 +912,211 @@ test('Validate - one of - 1', async () => {
|
|
|
912
912
|
);
|
|
913
913
|
expect(result).toHaveProperty('valid', true);
|
|
914
914
|
});
|
|
915
|
+
|
|
916
|
+
test('Validate schema', async () => {
|
|
917
|
+
const authorsReportSpecificationSchema = {
|
|
918
|
+
properties: {
|
|
919
|
+
type: {
|
|
920
|
+
type: 'string',
|
|
921
|
+
equals: 'author'
|
|
922
|
+
},
|
|
923
|
+
start: 'Date',
|
|
924
|
+
end: 'Date',
|
|
925
|
+
selectionStart: 'Date',
|
|
926
|
+
selectionEnd: 'Date',
|
|
927
|
+
granularity: ['day', 'week', 'month'],
|
|
928
|
+
metrics: {
|
|
929
|
+
type: 'array',
|
|
930
|
+
ofType: [
|
|
931
|
+
'articlesPublished',
|
|
932
|
+
'searchReferrers',
|
|
933
|
+
'socialReferrers',
|
|
934
|
+
'views',
|
|
935
|
+
'visitors',
|
|
936
|
+
'newVisitors'
|
|
937
|
+
]
|
|
938
|
+
},
|
|
939
|
+
filters: {
|
|
940
|
+
type: 'object',
|
|
941
|
+
properties: {
|
|
942
|
+
author: 'AuthorFilter'
|
|
943
|
+
// publication: 'PublicationFilter',
|
|
944
|
+
// article: 'ArticleFilter'
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
},
|
|
948
|
+
validators: [
|
|
949
|
+
(value) =>
|
|
950
|
+
value.start <= value.end &&
|
|
951
|
+
value.selectionStart <= value.selectionEnd &&
|
|
952
|
+
value.selectionStart >= value.start &&
|
|
953
|
+
value.selectionStart <= value.end &&
|
|
954
|
+
value.selectionEnd >= value.start &&
|
|
955
|
+
value.selectionEnd <= value.end
|
|
956
|
+
? {
|
|
957
|
+
valid: true
|
|
958
|
+
}
|
|
959
|
+
: {
|
|
960
|
+
valid: false,
|
|
961
|
+
errors: [
|
|
962
|
+
'selectionStart <=> selectionEnd should be inside the start <=> end interval'
|
|
963
|
+
]
|
|
964
|
+
}
|
|
965
|
+
]
|
|
966
|
+
};
|
|
967
|
+
|
|
968
|
+
const validator = new SchemaValidator()
|
|
969
|
+
.addSchemaType('Date', {
|
|
970
|
+
validators: [
|
|
971
|
+
(value) =>
|
|
972
|
+
value instanceof Date && !Number.isNaN(value)
|
|
973
|
+
? {
|
|
974
|
+
valid: true
|
|
975
|
+
}
|
|
976
|
+
: {
|
|
977
|
+
valid: false,
|
|
978
|
+
errors: ['should be a valid Date object']
|
|
979
|
+
}
|
|
980
|
+
]
|
|
981
|
+
})
|
|
982
|
+
.addSchemaType('EqualsFilterCondition', {
|
|
983
|
+
properties: {
|
|
984
|
+
operation: {
|
|
985
|
+
type: 'string',
|
|
986
|
+
equals: 'equals'
|
|
987
|
+
},
|
|
988
|
+
value: ['object', 'string', 'number']
|
|
989
|
+
}
|
|
990
|
+
})
|
|
991
|
+
.addSchemaType('GreaterThanFilterCondition', {
|
|
992
|
+
properties: {
|
|
993
|
+
operation: {
|
|
994
|
+
type: 'string',
|
|
995
|
+
equals: 'greater_than'
|
|
996
|
+
},
|
|
997
|
+
value: 'number'
|
|
998
|
+
}
|
|
999
|
+
})
|
|
1000
|
+
.addSchemaType('LessThanFilterCondition', {
|
|
1001
|
+
properties: {
|
|
1002
|
+
operation: {
|
|
1003
|
+
type: 'string',
|
|
1004
|
+
equals: 'less_than'
|
|
1005
|
+
},
|
|
1006
|
+
value: 'number'
|
|
1007
|
+
}
|
|
1008
|
+
})
|
|
1009
|
+
.addSchemaType('ContainsFilterCondition', {
|
|
1010
|
+
properties: {
|
|
1011
|
+
operation: {
|
|
1012
|
+
type: 'string',
|
|
1013
|
+
equals: 'contains'
|
|
1014
|
+
},
|
|
1015
|
+
value: [
|
|
1016
|
+
'string',
|
|
1017
|
+
'number',
|
|
1018
|
+
{
|
|
1019
|
+
type: 'array',
|
|
1020
|
+
ofType: ['string', 'number']
|
|
1021
|
+
}
|
|
1022
|
+
]
|
|
1023
|
+
}
|
|
1024
|
+
})
|
|
1025
|
+
.addSchemaType('LikeFilterCondition', {
|
|
1026
|
+
properties: {
|
|
1027
|
+
operation: 'like',
|
|
1028
|
+
value: 'string'
|
|
1029
|
+
}
|
|
1030
|
+
})
|
|
1031
|
+
.addSchemaType('BetweenFilterCondition', {
|
|
1032
|
+
properties: {
|
|
1033
|
+
operation: 'between',
|
|
1034
|
+
from: 'number',
|
|
1035
|
+
to: 'number'
|
|
1036
|
+
},
|
|
1037
|
+
validators: [
|
|
1038
|
+
(value) =>
|
|
1039
|
+
value.from <= value.to
|
|
1040
|
+
? { valid: true }
|
|
1041
|
+
: { valid: false, error: ['from must be <= to'] }
|
|
1042
|
+
]
|
|
1043
|
+
})
|
|
1044
|
+
.addSchemaType('StringFilterCondition', [
|
|
1045
|
+
'EqualsFilterCondition',
|
|
1046
|
+
'LikeFilterCondition'
|
|
1047
|
+
])
|
|
1048
|
+
.addSchemaType('AuthorFilter', {
|
|
1049
|
+
properties: {
|
|
1050
|
+
fullName: 'StringFilterCondition'
|
|
1051
|
+
}
|
|
1052
|
+
})
|
|
1053
|
+
.addSchemaType(
|
|
1054
|
+
'AuthorsReportSpecification',
|
|
1055
|
+
authorsReportSpecificationSchema as ObjectSchemaDefinitionParam<any>
|
|
1056
|
+
);
|
|
1057
|
+
|
|
1058
|
+
/**
|
|
1059
|
+
* @type {import('smg-iq/editorial-analytics.reports').AuthorsReportSpecification}
|
|
1060
|
+
*/
|
|
1061
|
+
let reportSpec = {
|
|
1062
|
+
type: 'author',
|
|
1063
|
+
start: new Date(2021, 0, 1),
|
|
1064
|
+
end: new Date(),
|
|
1065
|
+
selectionStart: new Date(2022, 0, 1),
|
|
1066
|
+
selectionEnd: new Date(2022, 2, 1),
|
|
1067
|
+
granularity: 'day',
|
|
1068
|
+
metrics: [
|
|
1069
|
+
'articlesPublished',
|
|
1070
|
+
'searchReferrers',
|
|
1071
|
+
'socialReferrers',
|
|
1072
|
+
'views',
|
|
1073
|
+
'visitors',
|
|
1074
|
+
'newVisitors'
|
|
1075
|
+
],
|
|
1076
|
+
filters: {
|
|
1077
|
+
author: {
|
|
1078
|
+
fullName: {
|
|
1079
|
+
operation: 'between',
|
|
1080
|
+
value: 'some name'
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
let result = await validator.schemas.AuthorsReportSpecification.validate(
|
|
1087
|
+
reportSpec
|
|
1088
|
+
);
|
|
1089
|
+
|
|
1090
|
+
expect(result).toHaveProperty('valid', false);
|
|
1091
|
+
|
|
1092
|
+
reportSpec = {
|
|
1093
|
+
type: 'author',
|
|
1094
|
+
start: new Date(2021, 0, 1),
|
|
1095
|
+
end: new Date(),
|
|
1096
|
+
selectionStart: new Date(2022, 0, 1),
|
|
1097
|
+
selectionEnd: new Date(2022, 2, 1),
|
|
1098
|
+
granularity: 'day',
|
|
1099
|
+
metrics: [
|
|
1100
|
+
'articlesPublished',
|
|
1101
|
+
'searchReferrers',
|
|
1102
|
+
'socialReferrers',
|
|
1103
|
+
'views',
|
|
1104
|
+
'visitors',
|
|
1105
|
+
'newVisitors'
|
|
1106
|
+
],
|
|
1107
|
+
filters: {
|
|
1108
|
+
author: {
|
|
1109
|
+
fullName: {
|
|
1110
|
+
operation: 'equals',
|
|
1111
|
+
value: 'some name'
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
1115
|
+
};
|
|
1116
|
+
|
|
1117
|
+
result = await validator.schemas.AuthorsReportSpecification.validate(
|
|
1118
|
+
reportSpec
|
|
1119
|
+
);
|
|
1120
|
+
|
|
1121
|
+
expect(result).toHaveProperty('valid', true);
|
|
1122
|
+
});
|
package/src/schemaValidator.ts
CHANGED
|
@@ -202,6 +202,13 @@ export default class SchemaValidator<T = Record<string, never>>
|
|
|
202
202
|
obj
|
|
203
203
|
);
|
|
204
204
|
} else if (typeof this.schemas[schema as keyof T] !== 'undefined') {
|
|
205
|
+
if (Array.isArray(this.schemas[schema as keyof T].schema)) {
|
|
206
|
+
return this.validate(
|
|
207
|
+
this.schemas[schema as keyof T]
|
|
208
|
+
.schema as any as Schema<any>,
|
|
209
|
+
obj
|
|
210
|
+
);
|
|
211
|
+
}
|
|
205
212
|
const objSchema = deepExtend(
|
|
206
213
|
defaultSchemas.object,
|
|
207
214
|
this.schemas[schema as keyof T].schema
|