@@ -4,6 +4,7 @@ import {SchemaNode, TypeScriptType} from './node';
4
4
5
5
6
6
export class InvalidSchema extends JsonSchemaErrorBase { }
7
+ export class InvalidValueError extends JsonSchemaErrorBase { }
7
8
export class MissingImplementationError extends JsonSchemaErrorBase { }
8
9
export class SettingReadOnlyPropertyError extends JsonSchemaErrorBase { }
9
10
@@ -151,8 +152,9 @@ export abstract class NonLeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
151
152
// Helper function to create a child based on its schema.
152
153
protected _createChildProperty < T > ( name : string , value : T , forward : SchemaTreeNode < T > ,
153
154
schema : Schema , define = true ) : SchemaTreeNode < T > {
154
-
155
- let type : string = schema [ 'oneOf' ] ? 'oneOf' : schema [ 'type' ] ;
155
+ const type : string =
156
+ ( 'oneOf' in schema ) ? 'oneOf' :
157
+ ( 'enum' in schema ) ? 'enum' : schema [ 'type' ] ;
156
158
let Klass : { new ( arg : TreeNodeConstructorArgument < any > ) : SchemaTreeNode < any > } = null ;
157
159
158
160
switch ( type ) {
@@ -163,6 +165,7 @@ export abstract class NonLeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
163
165
case 'number' : Klass = NumberSchemaTreeNode ; break ;
164
166
case 'integer' : Klass = IntegerSchemaTreeNode ; break ;
165
167
168
+ case 'enum' : Klass = EnumSchemaTreeNode ; break ;
166
169
case 'oneOf' : Klass = OneOfSchemaTreeNode ; break ;
167
170
168
171
default :
@@ -327,7 +330,8 @@ export class ArraySchemaTreeNode extends NonLeafSchemaTreeNode<Array<any>> {
327
330
this . _set ( metaData . value , true , false ) ;
328
331
329
332
// Keep the item's schema as a schema node. This is important to keep type information.
330
- this . _itemPrototype = this . _createChildProperty ( '' , null , null , metaData . schema [ 'items' ] ) ;
333
+ this . _itemPrototype = this . _createChildProperty (
334
+ '' , null , null , metaData . schema [ 'items' ] , false ) ;
331
335
}
332
336
333
337
_set ( value : any , init : boolean , force : boolean ) {
@@ -397,7 +401,7 @@ export abstract class LeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
397
401
super ( metaData ) ;
398
402
this . _defined = ! ( metaData . value === undefined || metaData . value === null ) ;
399
403
if ( 'default' in metaData . schema ) {
400
- this . _default = metaData . schema [ 'default' ] ;
404
+ this . _default = this . convert ( metaData . schema [ 'default' ] ) ;
401
405
}
402
406
}
403
407
@@ -415,8 +419,15 @@ export abstract class LeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
415
419
throw new SettingReadOnlyPropertyError ( ) ;
416
420
}
417
421
422
+ let convertedValue : T | null = this . convert ( v ) ;
423
+ if ( convertedValue === null || convertedValue === undefined ) {
424
+ if ( this . required ) {
425
+ throw new InvalidValueError ( `Invalid value "${ v } " on a required field.` ) ;
426
+ }
427
+ }
428
+
418
429
this . dirty = true ;
419
- this . _value = this . convert ( v ) ;
430
+ this . _value = convertedValue ;
420
431
}
421
432
422
433
destroy ( ) {
@@ -448,6 +459,38 @@ class StringSchemaTreeNode extends LeafSchemaTreeNode<string> {
448
459
}
449
460
450
461
462
+ class EnumSchemaTreeNode extends StringSchemaTreeNode {
463
+ private _enumValues : string [ ] ;
464
+
465
+ constructor ( metaData : TreeNodeConstructorArgument < string > ) {
466
+ super ( metaData ) ;
467
+
468
+ if ( ! Array . isArray ( metaData . schema [ 'enum' ] ) ) {
469
+ throw new InvalidSchema ( ) ;
470
+ }
471
+ this . _enumValues = [ ] . concat ( metaData . schema [ 'enum' ] ) ;
472
+ this . set ( metaData . value , true ) ;
473
+ }
474
+
475
+ protected _isInEnum ( value : string ) {
476
+ return this . _enumValues . some ( v => v === value ) ;
477
+ }
478
+
479
+ isCompatible ( v : any ) {
480
+ return ( typeof v == 'string' || v instanceof String ) && this . _isInEnum ( '' + v ) ;
481
+ }
482
+ convert ( v : any ) {
483
+ if ( v === undefined ) {
484
+ return undefined ;
485
+ }
486
+ if ( v === null || ! this . _isInEnum ( '' + v ) ) {
487
+ return null ;
488
+ }
489
+ return '' + v ;
490
+ }
491
+ }
492
+
493
+
451
494
class BooleanSchemaTreeNode extends LeafSchemaTreeNode < boolean > {
452
495
serialize ( serializer : Serializer ) { serializer . outputBoolean ( this ) ; }
453
496
0 commit comments