Skip to content

Commit b416812

Browse files
committed
refactor: reorganize policy parsing and loading logic
1 parent 6e7ae07 commit b416812

File tree

1 file changed

+48
-16
lines changed

1 file changed

+48
-16
lines changed

src/persist/helper.ts

+48-16
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,47 @@
11
import { Model } from '../model';
22
import { parse } from 'csv-parse/sync';
33

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 {
610
if (!line || line.trimStart().charAt(0) === '#') {
7-
return;
11+
return null;
812
}
913

10-
const rawTokens = parse(line, {
14+
return parse(line, {
1115
delimiter: ',',
1216
skip_empty_lines: true,
1317
trim: true,
1418
relax_quotes: true,
1519
});
20+
}
21+
}
1622

17-
if (!rawTokens || rawTokens.length === 0 || !rawTokens[0]) {
18-
return;
19-
}
23+
export class BracketAwareCsvParser implements IPolicyParser {
24+
private readonly baseParser: IPolicyParser;
2025

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+
}
2235

36+
const tokens = rawTokens[0];
2337
const processedTokens: string[] = [];
2438
let currentToken = '';
2539
let bracketCount = 0;
2640

2741
for (const token of tokens) {
2842
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--;
3445
}
3546

3647
currentToken += (currentToken ? ',' : '') + token;
@@ -45,11 +56,24 @@ export class Helper {
4556
throw new Error(`Unmatched brackets in policy line: ${line}`);
4657
}
4758

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]) {
4973
return;
5074
}
5175

52-
let key = processedTokens[0].trim();
76+
let key = tokens[0][0].trim();
5377
if (key.startsWith('"') && key.endsWith('"')) {
5478
key = key.slice(1, -1);
5579
}
@@ -65,7 +89,7 @@ export class Helper {
6589
return;
6690
}
6791

68-
const values = processedTokens.slice(1).map((v) => {
92+
const values = tokens[0].slice(1).map((v) => {
6993
if (v.startsWith('"') && v.endsWith('"')) {
7094
v = v.slice(1, -1);
7195
}
@@ -75,3 +99,11 @@ export class Helper {
7599
policy.policy.push(values);
76100
}
77101
}
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

Comments
 (0)