@@ -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,7 @@ 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 ( '' , null , null , metaData . schema [ 'items' ] , false ) ;
331
334
}
332
335
333
336
_set ( value : any , init : boolean , force : boolean ) {
@@ -397,7 +400,7 @@ export abstract class LeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
397
400
super ( metaData ) ;
398
401
this . _defined = ! ( metaData . value === undefined || metaData . value === null ) ;
399
402
if ( 'default' in metaData . schema ) {
400
- this . _default = metaData . schema [ 'default' ] ;
403
+ this . _default = this . convert ( metaData . schema [ 'default' ] ) ;
401
404
}
402
405
}
403
406
@@ -415,8 +418,15 @@ export abstract class LeafSchemaTreeNode<T> extends SchemaTreeNode<T> {
415
418
throw new SettingReadOnlyPropertyError ( ) ;
416
419
}
417
420
421
+ let convertedValue : T | null = this . convert ( v ) ;
422
+ if ( convertedValue === null || convertedValue === undefined ) {
423
+ if ( this . required ) {
424
+ throw new InvalidValueError ( `Invalid value "${ v } " on a required field.` ) ;
425
+ }
426
+ }
427
+
418
428
this . dirty = true ;
419
- this . _value = this . convert ( v ) ;
429
+ this . _value = convertedValue ;
420
430
}
421
431
422
432
destroy ( ) {
@@ -448,6 +458,38 @@ class StringSchemaTreeNode extends LeafSchemaTreeNode<string> {
448
458
}
449
459
450
460
461
+ class EnumSchemaTreeNode extends StringSchemaTreeNode {
462
+ private _enumValues : string [ ] ;
463
+
464
+ constructor ( metaData : TreeNodeConstructorArgument < string > ) {
465
+ super ( metaData ) ;
466
+
467
+ if ( ! Array . isArray ( metaData . schema [ 'enum' ] ) ) {
468
+ throw new InvalidSchema ( ) ;
469
+ }
470
+ this . _enumValues = [ ] . concat ( metaData . schema [ 'enum' ] ) ;
471
+ this . set ( metaData . value , true ) ;
472
+ }
473
+
474
+ protected _isInEnum ( value : string ) {
475
+ return this . _enumValues . some ( v => v === value ) ;
476
+ }
477
+
478
+ isCompatible ( v : any ) {
479
+ return ( typeof v == 'string' || v instanceof String ) && this . _isInEnum ( v ) ;
480
+ }
481
+ convert ( v : any ) {
482
+ if ( v === undefined ) {
483
+ return undefined ;
484
+ }
485
+ if ( v === null || ! this . _isInEnum ( '' + v ) ) {
486
+ return null ;
487
+ }
488
+ return '' + v ;
489
+ }
490
+ }
491
+
492
+
451
493
class BooleanSchemaTreeNode extends LeafSchemaTreeNode < boolean > {
452
494
serialize ( serializer : Serializer ) { serializer . outputBoolean ( this ) ; }
453
495
0 commit comments