88 AbilityTuple ,
99 ExtractSubjectType
1010} from './types' ;
11- import { wrapArray , detectSubjectType , mergePrioritized , getOrDefault , identity , isSubjectType } from './utils' ;
11+ import { wrapArray , detectSubjectType , mergePrioritized , getOrDefault , identity , isSubjectType , DETECT_SUBJECT_TYPE_STRATEGY } from './utils' ;
1212import { LinkedItem , linkedItem , unlinkItem , cloneLinkedItem } from './structures/LinkedItem' ;
1313
1414export interface RuleIndexOptions < A extends Abilities , C > extends Partial < RuleOptions < C > > {
@@ -91,12 +91,13 @@ type AbilitySubjectTypeParameters<T extends Abilities, IncludeField extends bool
9191export class RuleIndex < A extends Abilities , Conditions > {
9292 private _hasPerFieldRules : boolean = false ;
9393 private _events ?: Events < this> ;
94- private _indexedRules : IndexTree < A , Conditions > ;
94+ private _indexedRules : IndexTree < A , Conditions > = new Map ( ) ;
9595 private _rules : RawRuleFrom < A , Conditions > [ ] ;
9696 private readonly _ruleOptions : RuleOptions < Conditions > ;
97- private readonly _detectSubjectType : this[ 'detectSubjectType' ] ;
97+ private _detectSubjectType : this[ 'detectSubjectType' ] ;
9898 private readonly _anyAction : string ;
9999 private readonly _anySubjectType : string ;
100+ private readonly _hasCustomSubjectTypeDetection : boolean ;
100101 readonly [ ɵabilities ] ! : A ;
101102 readonly [ ɵconditions ] ! : Conditions ;
102103
@@ -111,9 +112,10 @@ export class RuleIndex<A extends Abilities, Conditions> {
111112 } ;
112113 this . _anyAction = options . anyAction || 'manage' ;
113114 this . _anySubjectType = options . anySubjectType || 'all' ;
114- this . _detectSubjectType = options . detectSubjectType || ( detectSubjectType as this[ 'detectSubjectType' ] ) ;
115115 this . _rules = rules ;
116- this . _indexedRules = this . _buildIndexFor ( rules ) ;
116+ this . _hasCustomSubjectTypeDetection = ! ! options . detectSubjectType ;
117+ this . _detectSubjectType = options . detectSubjectType || ( detectSubjectType as this[ 'detectSubjectType' ] ) ;
118+ this . _indexAndAnalyzeRules ( rules ) ;
117119 }
118120
119121 get rules ( ) {
@@ -135,14 +137,15 @@ export class RuleIndex<A extends Abilities, Conditions> {
135137
136138 this . _emit ( 'update' , event ) ;
137139 this . _rules = rules ;
138- this . _indexedRules = this . _buildIndexFor ( rules ) ;
140+ this . _indexAndAnalyzeRules ( rules ) ;
139141 this . _emit ( 'updated' , event ) ;
140142
141143 return this ;
142144 }
143145
144- private _buildIndexFor ( rawRules : RawRuleFrom < A , Conditions > [ ] ) {
146+ private _indexAndAnalyzeRules ( rawRules : RawRuleFrom < A , Conditions > [ ] ) {
145147 const indexedRules : IndexTree < A , Conditions > = new Map ( ) ;
148+ let typeOfSubjectType : string | undefined ;
146149
147150 for ( let i = rawRules . length - 1 ; i >= 0 ; i -- ) {
148151 const priority = rawRules . length - i - 1 ;
@@ -153,14 +156,24 @@ export class RuleIndex<A extends Abilities, Conditions> {
153156
154157 for ( let k = 0 ; k < subjects . length ; k ++ ) {
155158 const subjectRules = getOrDefault ( indexedRules , subjects [ k ] , defaultSubjectEntry ) ;
159+ if ( typeOfSubjectType === undefined ) {
160+ typeOfSubjectType = typeof subjects [ k ] ;
161+ }
162+ if ( typeof subjects [ k ] !== typeOfSubjectType && typeOfSubjectType !== 'mixed' ) {
163+ typeOfSubjectType = 'mixed' ;
164+ }
156165
157166 for ( let j = 0 ; j < actions . length ; j ++ ) {
158167 getOrDefault ( subjectRules , actions [ j ] , defaultActionEntry ) . rules . push ( rule ) ;
159168 }
160169 }
161170 }
162171
163- return indexedRules ;
172+ this . _indexedRules = indexedRules ;
173+ if ( typeOfSubjectType !== 'mixed' && ! this . _hasCustomSubjectTypeDetection ) {
174+ const detectSubjectType = DETECT_SUBJECT_TYPE_STRATEGY [ typeOfSubjectType as 'function' | 'string' ] || DETECT_SUBJECT_TYPE_STRATEGY . string ;
175+ this . _detectSubjectType = detectSubjectType as this[ 'detectSubjectType' ] ;
176+ }
164177 }
165178
166179 possibleRulesFor ( ...args : AbilitySubjectTypeParameters < A , false > ) : Rule < A , Conditions > [ ] ;
0 commit comments