import Context from '../ctx' ; import { TypeOf } from '.' ; export const isAnArray = x => Array . isArray ( x ) ; export const isNotAnArray = x => ! isAnArray ( x ) ; const hasDuplicates = ( array ) => ( new Set ( array ) ) . size !== array . length ; /**
 * Array
 */ export default class ArrayContext < Ctx extends Context , Maybe extends null | undefined | TypeOf < Ctx > [ ] = TypeOf < Ctx > [ ] > extends Context < TypeOf < Ctx > [ ] | Maybe > { public readonly name = 'Array' ; public readonly ctx : Context | undefined ; constructor ( ctx ? , optional = false , nullable = false ) { super ( optional , nullable ) ; this . ctx = ctx ; this . push ( v => isNotAnArray ( v ) ? new Error ( 'must-be-an-array' ) : true ) ; if ( ctx ) { this . each ( ctx ) ; } } /**
     * 配列の値がユニークでない場合(=重複した項目がある場合)エラーにします
     */ public unique ( ) { this . push ( v => hasDuplicates ( v ) ? new Error ( 'must-be-unique' ) : true , 'unique' ) ; return this ; } param min param max public range ( min , max ) { this . min ( min ) ; this . max ( max ) ; return this ; } param threshold public min ( threshold ) { this . push ( v => v . length < threshold ? new Error ( 'invalid-range' ) : true , 'min' ) ; return this ; } param threshold public max ( threshold ) { this . push ( v => v . length > threshold ? new Error ( 'invalid-range' ) : true , 'max' ) ; return this ; } param length public length ( length ) { this . push ( v => v . length !== length ? new Error ( 'invalid-length' ) : true , 'length' ) ; return this ; } param index param validator public item ( index , validator ) { const validate = validator instanceof Context ? validator . test : validator ; this . push ( v => { const result = validate ( v [ index ] ) ; if ( result === false ) { return new Error ( 'invalid-item' ) ; } else if ( result instanceof Error ) { return result ; } else { return true ; } } , 'item' ) ; return this ; } param validator public each ( validator ) { const validate = validator instanceof Context ? validator . test : validator ; this . push ( v => { let err ; v . some ( ( x , i , s ) => { const result = validate ( x , i , s ) ; if ( result === false ) { err = new Error ( 'invalid-item' ) ; return true ; } else if ( result instanceof Error ) { err = result ; return true ; } else { return false ; } } ) ; if ( err ) return err ; return true ; } , 'each' ) ; return this ; } public getType ( ) { if ( this . ctx ) { return super . getType ( this . ctx . getType ( ) + '[]' ) ; } else { return super . getType ( ) ; } } public makeOptional ( ) { return new ArrayContext ( this . ctx , true , false ) ; } public makeNullable ( ) { return new ArrayContext ( this . ctx , false , true ) ; } public makeOptionalNullable ( ) { return new ArrayContext ( this . ctx , true , true ) ; } }