1
1
import { Model } from '../model' ;
2
2
import { parse } from 'csv-parse/sync' ;
3
3
4
- export class Helper {
5
- public static loadPolicyLine ( line : string , model : Model ) : void {
4
+ export interface IPolicyParser {
5
+ parse ( line : string ) : string [ ] [ ] | null ;
6
+ }
7
+
8
+ export class BasicCsvParser implements IPolicyParser {
9
+ parse ( line : string ) : string [ ] [ ] | null {
6
10
if ( ! line || line . trimStart ( ) . charAt ( 0 ) === '#' ) {
7
- return ;
11
+ return null ;
8
12
}
9
13
10
- const rawTokens = parse ( line , {
14
+ return parse ( line , {
11
15
delimiter : ',' ,
12
16
skip_empty_lines : true ,
13
17
trim : true ,
14
18
relax_quotes : true ,
15
19
} ) ;
20
+ }
21
+ }
16
22
17
- if ( ! rawTokens || rawTokens . length === 0 || ! rawTokens [ 0 ] ) {
18
- return ;
19
- }
23
+ export class BracketAwareCsvParser implements IPolicyParser {
24
+ private readonly baseParser : IPolicyParser ;
20
25
21
- const tokens : string [ ] = rawTokens [ 0 ] ;
26
+ constructor ( baseParser : IPolicyParser = new BasicCsvParser ( ) ) {
27
+ this . baseParser = baseParser ;
28
+ }
29
+
30
+ parse ( line : string ) : string [ ] [ ] | null {
31
+ const rawTokens = this . baseParser . parse ( line ) ;
32
+ if ( ! rawTokens || ! rawTokens [ 0 ] ) {
33
+ return null ;
34
+ }
22
35
36
+ const tokens = rawTokens [ 0 ] ;
23
37
const processedTokens : string [ ] = [ ] ;
24
38
let currentToken = '' ;
25
39
let bracketCount = 0 ;
26
40
27
41
for ( const token of tokens ) {
28
42
for ( const char of token ) {
29
- if ( char === '(' ) {
30
- bracketCount ++ ;
31
- } else if ( char === ')' ) {
32
- bracketCount -- ;
33
- }
43
+ if ( char === '(' ) bracketCount ++ ;
44
+ else if ( char === ')' ) bracketCount -- ;
34
45
}
35
46
36
47
currentToken += ( currentToken ? ',' : '' ) + token ;
@@ -45,11 +56,24 @@ export class Helper {
45
56
throw new Error ( `Unmatched brackets in policy line: ${ line } ` ) ;
46
57
}
47
58
48
- if ( processedTokens . length === 0 ) {
59
+ return processedTokens . length > 0 ? [ processedTokens ] : null ;
60
+ }
61
+ }
62
+
63
+ export class PolicyLoader {
64
+ private readonly parser : IPolicyParser ;
65
+
66
+ constructor ( parser : IPolicyParser = new BracketAwareCsvParser ( ) ) {
67
+ this . parser = parser ;
68
+ }
69
+
70
+ loadPolicyLine ( line : string , model : Model ) : void {
71
+ const tokens = this . parser . parse ( line ) ;
72
+ if ( ! tokens || ! tokens [ 0 ] ) {
49
73
return ;
50
74
}
51
75
52
- let key = processedTokens [ 0 ] . trim ( ) ;
76
+ let key = tokens [ 0 ] [ 0 ] . trim ( ) ;
53
77
if ( key . startsWith ( '"' ) && key . endsWith ( '"' ) ) {
54
78
key = key . slice ( 1 , - 1 ) ;
55
79
}
@@ -65,7 +89,7 @@ export class Helper {
65
89
return ;
66
90
}
67
91
68
- const values = processedTokens . slice ( 1 ) . map ( ( v ) => {
92
+ const values = tokens [ 0 ] . slice ( 1 ) . map ( ( v ) => {
69
93
if ( v . startsWith ( '"' ) && v . endsWith ( '"' ) ) {
70
94
v = v . slice ( 1 , - 1 ) ;
71
95
}
@@ -75,3 +99,11 @@ export class Helper {
75
99
policy . policy . push ( values ) ;
76
100
}
77
101
}
102
+
103
+ export class Helper {
104
+ private static readonly policyLoader = new PolicyLoader ( ) ;
105
+
106
+ public static loadPolicyLine ( line : string , model : Model ) : void {
107
+ Helper . policyLoader . loadPolicyLine ( line , model ) ;
108
+ }
109
+ }
0 commit comments