1- import * as fs from 'fs' ;
2- import * as yaml from 'yaml' ;
1+ import { readFileSync } from 'fs' ;
2+ import { parse as parseYaml } from 'yaml' ;
33import { EmitterWebhookEvent } from '@octokit/webhooks' ;
44
5+ // define filter config type
6+ interface FilterConfig {
7+ include ?: { [ key : string ] : { [ key : string ] : string | string [ ] } } ;
8+ exclude ?: { [ key : string ] : { [ key : string ] : string | string [ ] } } ;
9+ }
10+
511// read in filter config, from a YAML file called "filter.yml" in the root of the repo
612// if the file doesn't exist, or is invalid YAML, we handle that gracefully
7- let filter_config : any ;
13+ let filter_config : FilterConfig | undefined ;
814
915try {
10- filter_config = yaml . parse ( fs . readFileSync ( 'filter.yml' , 'utf8' ) ) ;
16+ filter_config = parseYaml ( readFileSync ( 'filter.yml' , 'utf8' ) ) ;
1117} catch ( error ) {
1218 // if the file doesn't exist, or can't be parsed, that's fine, we'll just use the default filter, which is to let everything through
1319 // we do log the error
1420 console . log ( error ) ;
1521}
1622
17- export const eventFilter = ( event : EmitterWebhookEvent ) : boolean => {
23+ export const eventFilter = ! validateFilterConfig ( filter_config ) ? ( _ : EmitterWebhookEvent ) => true : ( event : EmitterWebhookEvent ) : boolean => {
1824 if ( filter_config === undefined ) return true ;
1925
2026 const event_name = event . name ;
@@ -30,16 +36,33 @@ export const eventFilter = (event: EmitterWebhookEvent): boolean => {
3036 // we can include or exclude by any string-valued key in the payload, and we can match a single string, or an array of options
3137 const payload = event . payload as unknown as { [ key : string ] : unknown } ;
3238
33- const include_filter = filter_config . include [ event_name ] ;
34- if ( ! applyFilter ( payload , include_filter , true ) ) return false ;
39+ if ( filter_config . include !== undefined && event_name in filter_config . include ) {
40+ const include_filter = filter_config . include [ event_name ] ;
41+ if ( ! applyFilter ( payload , include_filter , true ) ) return false ;
42+ }
43+
44+ if ( filter_config . exclude !== undefined && event_name in filter_config . exclude ) {
45+ const exclude_filter = filter_config . exclude [ event_name ] ;
46+ if ( applyFilter ( payload , exclude_filter , false ) ) return false ;
47+ }
48+
49+ return true ;
50+ }
3551
36- const exclude_filter = filter_config . exclude [ event_name ] ;
37- if ( applyFilter ( payload , exclude_filter , false ) ) return false ;
52+ function validateFilterConfig ( config : FilterConfig | undefined ) : boolean {
53+ if ( config === undefined ) {
54+ console . error ( "Filter config is undefined" ) ;
55+ return false ;
56+ }
3857
58+ if ( config . include === undefined && config . exclude === undefined ) {
59+ console . error ( "Filter config has neither an include nor an exclude property" ) ;
60+ return false ;
61+ }
3962 return true ;
4063}
4164
42- function applyFilter ( payload : { [ key : string ] : unknown } , filter : { [ key : string ] : String | Array < String > } , sense : boolean ) : boolean {
65+ function applyFilter ( payload : { [ key : string ] : unknown } , filter : { [ key : string ] : string | string [ ] } , sense : boolean ) : boolean {
4366 if ( filter === undefined ) return sense ;
4467
4568 const matches : boolean = Object . keys ( filter ) . every ( key => {
0 commit comments