@@ -10,6 +10,7 @@ import {Binding, BindingTag} from './binding';
10
10
import { BindingAddress , BindingKey } from './binding-key' ;
11
11
import { ResolutionOptions , ResolutionSession } from './resolution-session' ;
12
12
import { BoundValue , getDeepProperty , isPromiseLike } from './value-promise' ;
13
+ import { BindingFilter , filterByKey , filterByTag } from './binding-filter' ;
13
14
14
15
const debug = debugModule ( 'loopback:context' ) ;
15
16
@@ -21,7 +22,15 @@ export class Context {
21
22
* Name of the context
22
23
*/
23
24
readonly name : string ;
25
+
26
+ /**
27
+ * Key to binding map as the internal registry
28
+ */
24
29
protected readonly registry : Map < string , Binding > = new Map ( ) ;
30
+
31
+ /**
32
+ * Parent context
33
+ */
25
34
protected _parent ?: Context ;
26
35
27
36
/**
@@ -127,61 +136,25 @@ export class Context {
127
136
return undefined ;
128
137
}
129
138
130
- /**
131
- * Convert a wildcard pattern to RegExp
132
- * @param pattern A wildcard string with `*` and `?` as special characters.
133
- * - `*` matches zero or more characters except `.` and `:`
134
- * - `?` matches exactly one character except `.` and `:`
135
- */
136
- private wildcardToRegExp ( pattern : string ) : RegExp {
137
- // Escape reserved chars for RegExp:
138
- // `- \ ^ $ + . ( ) | { } [ ] :`
139
- let regexp = pattern . replace ( / [ \- \[ \] \/ \{ \} \( \) \+ \. \\ \^ \$ \| \: ] / g, '\\$&' ) ;
140
- // Replace wildcard chars `*` and `?`
141
- // `*` matches zero or more characters except `.` and `:`
142
- // `?` matches one character except `.` and `:`
143
- regexp = regexp . replace ( / \* / g, '[^.:]*' ) . replace ( / \? / g, '[^.:]' ) ;
144
- return new RegExp ( `^${ regexp } $` ) ;
145
- }
146
-
147
139
/**
148
140
* Find bindings using the key pattern
149
- * @param pattern A regexp or wildcard pattern with optional `*` and `?`. If
150
- * it matches the binding key, the binding is included. For a wildcard:
141
+ * @param pattern A filter function, a regexp or a wildcard pattern with
142
+ * optional `*` and `?`. Find returns such bindings where the key matches
143
+ * the provided pattern.
144
+ *
145
+ * For a wildcard:
151
146
* - `*` matches zero or more characters except `.` and `:`
152
147
* - `?` matches exactly one character except `.` and `:`
148
+ *
149
+ * For a filter function:
150
+ * - return `true` to include the binding in the results
151
+ * - return `false` to exclude it.
153
152
*/
154
153
find < ValueType = BoundValue > (
155
- pattern ?: string | RegExp ,
156
- ) : Readonly < Binding < ValueType > > [ ] ;
157
-
158
- /**
159
- * Find bindings using a filter function
160
- * @param filter A function to test on the binding. It returns `true` to
161
- * include the binding or `false` to exclude the binding.
162
- */
163
- find < ValueType = BoundValue > (
164
- filter : ( binding : Readonly < Binding < ValueType > > ) => boolean ,
165
- ) : Readonly < Binding < ValueType > > [ ] ;
166
-
167
- find < ValueType = BoundValue > (
168
- pattern ?:
169
- | string
170
- | RegExp
171
- | ( ( binding : Readonly < Binding < ValueType > > ) => boolean ) ,
154
+ pattern ?: string | RegExp | BindingFilter ,
172
155
) : Readonly < Binding < ValueType > > [ ] {
173
- let bindings : Readonly < Binding > [ ] = [ ] ;
174
- let filter : ( binding : Readonly < Binding > ) => boolean ;
175
- if ( ! pattern ) {
176
- filter = binding => true ;
177
- } else if ( typeof pattern === 'string' ) {
178
- const regex = this . wildcardToRegExp ( pattern ) ;
179
- filter = binding => regex . test ( binding . key ) ;
180
- } else if ( pattern instanceof RegExp ) {
181
- filter = binding => pattern . test ( binding . key ) ;
182
- } else {
183
- filter = pattern ;
184
- }
156
+ const bindings : Readonly < Binding > [ ] = [ ] ;
157
+ const filter = filterByKey ( pattern ) ;
185
158
186
159
for ( const b of this . registry . values ( ) ) {
187
160
if ( filter ( b ) ) bindings . push ( b ) ;
@@ -208,22 +181,7 @@ export class Context {
208
181
findByTag < ValueType = BoundValue > (
209
182
tagFilter : BindingTag | RegExp ,
210
183
) : Readonly < Binding < ValueType > > [ ] {
211
- if ( typeof tagFilter === 'string' || tagFilter instanceof RegExp ) {
212
- const regexp =
213
- typeof tagFilter === 'string'
214
- ? this . wildcardToRegExp ( tagFilter )
215
- : tagFilter ;
216
- return this . find ( b => Array . from ( b . tagNames ) . some ( t => regexp ! . test ( t ) ) ) ;
217
- }
218
-
219
- return this . find ( b => {
220
- for ( const t in tagFilter ) {
221
- // One tag name/value does not match
222
- if ( b . tagMap [ t ] !== tagFilter [ t ] ) return false ;
223
- }
224
- // All tag name/value pairs match
225
- return true ;
226
- } ) ;
184
+ return this . find ( filterByTag ( tagFilter ) ) ;
227
185
}
228
186
229
187
protected _mergeWithParent < ValueType > (
0 commit comments