@@ -33,69 +33,112 @@ export class ParameterPropertyHandlerRange implements IParameterPropertyHandler
33
33
* @param param The parameter.
34
34
*/
35
35
public captureType ( value : Resource , param : Resource ) : Resource {
36
+ if ( this . hasParamValueValidType ( value , param , param . property . range ) ) {
37
+ return value ;
38
+ }
39
+ this . throwIncorrectTypeError ( value , param ) ;
40
+ }
41
+
42
+ /**
43
+ * Apply the given datatype to the given literal.
44
+ * Checks if the datatype is correct and casts to the correct js type.
45
+ * Will throw an error if the type has an invalid value.
46
+ * Will be ignored if the value is not a literal or the type is not recognized.
47
+ * @param value The value.
48
+ * @param param The parameter.
49
+ * @param paramRange The parameter's range.
50
+ */
51
+ public hasParamValueValidType ( value : Resource , param : Resource , paramRange : Resource ) : boolean {
36
52
if ( value . type === 'Literal' ) {
37
53
let parsed ;
38
- switch ( param . property . range . value ) {
54
+ switch ( paramRange . value ) {
55
+ case IRIS_XSD . string :
56
+ return true ;
39
57
case IRIS_XSD . boolean :
40
58
if ( value . value === 'true' ) {
41
59
( < any > value . term ) . valueRaw = true ;
42
60
} else if ( value . value === 'false' ) {
43
61
( < any > value . term ) . valueRaw = false ;
44
62
} else {
45
- this . throwIncorrectTypeError ( value , param ) ;
63
+ return false ;
46
64
}
47
- break ;
65
+ return true ;
48
66
case IRIS_XSD . integer :
49
67
case IRIS_XSD . number :
50
68
case IRIS_XSD . int :
51
69
case IRIS_XSD . byte :
52
70
case IRIS_XSD . long :
53
71
parsed = Number . parseInt ( value . value , 10 ) ;
54
72
if ( Number . isNaN ( parsed ) ) {
55
- this . throwIncorrectTypeError ( value , param ) ;
56
- } else {
57
- // ParseInt also parses floats to ints!
58
- if ( String ( parsed ) !== value . value ) {
59
- this . throwIncorrectTypeError ( value , param ) ;
60
- }
61
- ( < any > value . term ) . valueRaw = parsed ;
73
+ return false ;
74
+ }
75
+ // ParseInt also parses floats to ints!
76
+ if ( String ( parsed ) !== value . value ) {
77
+ return false ;
62
78
}
63
- break ;
79
+ ( < any > value . term ) . valueRaw = parsed ;
80
+ return true ;
64
81
case IRIS_XSD . float :
65
82
case IRIS_XSD . decimal :
66
83
case IRIS_XSD . double :
67
84
parsed = Number . parseFloat ( value . value ) ;
68
85
if ( Number . isNaN ( parsed ) ) {
69
- this . throwIncorrectTypeError ( value , param ) ;
70
- } else {
71
- ( < any > value . term ) . valueRaw = parsed ;
86
+ return false ;
72
87
}
73
- break ;
88
+ ( < any > value . term ) . valueRaw = parsed ;
89
+ return true ;
74
90
case IRIS_RDF . JSON :
75
91
try {
76
92
parsed = JSON . parse ( value . value ) ;
77
93
( < any > value . term ) . valueRaw = parsed ;
78
94
} catch {
79
- this . throwIncorrectTypeError ( value , param ) ;
95
+ return false ;
80
96
}
81
- break ;
97
+ return true ;
82
98
}
83
- } else if ( ! value . isA ( 'Variable' ) && param . property . range && ! value . isA ( param . property . range . term ) ) {
99
+ }
100
+
101
+ if ( ! value . isA ( 'Variable' ) && paramRange && ! value . isA ( paramRange . term ) ) {
102
+ // Check if the param type is a composed type
103
+ if ( paramRange . isA ( 'ParameterRangeComposedUnion' ) ) {
104
+ return paramRange . properties . parameterRangeComposedChildren
105
+ . some ( child => this . hasParamValueValidType ( value , param , child ) ) ;
106
+ }
107
+ if ( paramRange . isA ( 'ParameterRangeComposedIntersection' ) ) {
108
+ return paramRange . properties . parameterRangeComposedChildren
109
+ . every ( child => this . hasParamValueValidType ( value , param , child ) ) ;
110
+ }
111
+
84
112
// Check if this param defines a field with sub-params
85
- if ( param . property . range . properties . parameters . length > 0 ) {
113
+ if ( paramRange . properties . parameters . length > 0 ) {
86
114
// TODO: Add support for type-checking nested fields with collectEntries
87
115
} else {
88
- this . throwIncorrectTypeError ( value , param ) ;
116
+ return false ;
89
117
}
90
118
}
91
- return value ;
119
+
120
+ return true ;
92
121
}
93
122
94
- protected throwIncorrectTypeError ( value : Resource , parameter : Resource ) : void {
123
+ protected throwIncorrectTypeError ( value : Resource , parameter : Resource ) : never {
95
124
const withTypes = value . properties . types . length > 0 ? ` with types "${ value . properties . types . map ( resource => resource . value ) } "` : '' ;
96
- throw new ErrorResourcesContext ( `The value "${ value . value } "${ withTypes } for parameter "${ parameter . value } " is not of required range type "${ parameter . property . range . value } "` , {
125
+ throw new ErrorResourcesContext ( `The value "${ value . value } "${ withTypes } for parameter "${ parameter . value } " is not of required range type "${ this . rangeToDisplayString ( parameter . property . range ) } "` , {
97
126
value,
98
127
parameter,
99
128
} ) ;
100
129
}
130
+
131
+ protected rangeToDisplayString ( paramRange : Resource ) : string {
132
+ if ( paramRange . isA ( 'ParameterRangeComposedUnion' ) ) {
133
+ return paramRange . properties . parameterRangeComposedChildren
134
+ . map ( child => this . rangeToDisplayString ( child ) )
135
+ . join ( ' | ' ) ;
136
+ }
137
+ if ( paramRange . isA ( 'ParameterRangeComposedIntersection' ) ) {
138
+ return paramRange . properties . parameterRangeComposedChildren
139
+ . map ( child => this . rangeToDisplayString ( child ) )
140
+ . join ( ' & ' ) ;
141
+ }
142
+ return paramRange . value ;
143
+ }
101
144
}
0 commit comments