import type PKPass from "./PKPass" ; import * as Schemas from "./schemas" ; import * as Utils from "./utils" ; import * as Messages from "./messages" ; see https const passInstanceSymbol = Symbol ( "passInstance" ) ; const sharedKeysPoolSymbol = Symbol ( "keysPool" ) ; export default class FieldsArray extends Array < Schemas . Field > { private [ passInstanceSymbol ] : InstanceType < typeof PKPass > ; private [ sharedKeysPoolSymbol ] : Set < string > ; constructor ( passInstance , keysPool , ... args ) { super ( ... args ) ; this [ passInstanceSymbol ] = passInstance ; this [ sharedKeysPoolSymbol ] = keysPool ; } push ( ... items ) { const validItems = registerWithValidation ( this , ... items ) ; return super . push ( ... validItems ) ; } pop ( ) { return unregisterItems ( this , ( ) => super . pop ( ) ) ; } splice ( start , deleteCount , ... items ) { const validItems = registerWithValidation ( this , ... items ) ; for ( let i = start ; i < start + deleteCount ; i ++ ) { this [ sharedKeysPoolSymbol ] . delete ( this [ i ] . key ) ; } return super . splice ( start , deleteCount , ... validItems ) ; } shift ( ) { return unregisterItems ( this , ( ) => super . shift ( ) ) ; } unshift ( ... items ) { const validItems = registerWithValidation ( this , ... items ) ; return super . unshift ( ... validItems ) ; } } function registerWithValidation ( instance , ... items ) { Utils . assertUnfrozen ( instance [ passInstanceSymbol ] ) ; let validItems = [ ] ; for ( let i = items . length , field ; ( field = items [ -- i ] ) ; ) { try { Schemas . assertValidity ( Schemas . Field , field , Messages . FIELDS . INVALID ) ; if ( instance [ sharedKeysPoolSymbol ] . has ( field . key ) ) { throw Messages . format ( Messages . FIELDS . REPEATED_KEY , field . key ) ; } instance [ sharedKeysPoolSymbol ] . add ( field . key ) ; validItems . push ( field ) ; } catch ( err ) { console . warn ( err ) ; } } return validItems ; } function unregisterItems ( instance , removeFn ) { Utils . assertUnfrozen ( instance [ passInstanceSymbol ] ) ; const element = removeFn ( ) ; instance [ sharedKeysPoolSymbol ] . delete ( element . key ) ; return element ; }