arch-unit-ts
Version:
115 lines • 5.45 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ResultMatcher = exports.PackageMatcher = void 0;
const Optional_1 = require("../../../common/domain/Optional");
class PackageMatcher {
static ILLEGAL_ALTERNATION_PATTERN = new RegExp('\\[[^|]*]');
static ILLEGAL_NESTED_GROUP_PATTERN = new RegExp(this.nestedGroupRegex('(', ')', '(') +
'|' +
this.nestedGroupRegex('(', ')', '[') +
'|' +
this.nestedGroupRegex('[', ']', '(') +
'|' +
this.nestedGroupRegex('[', ']', '['));
static PACKAGE_CONTROL_SYMBOLS = Array.from(['*', '(', ')', '.', '|', '[', ']']);
static OPT_LETTERS_AT_START = '(?:^\\w*)?';
static OPT_LETTERS_AT_END = '(?:\\w*$)?';
static ARBITRARY_PACKAGES = '\\.(?:\\w+\\.)*';
static TWO_DOTS_REGEX = `(?:${PackageMatcher.OPT_LETTERS_AT_START}${PackageMatcher.ARBITRARY_PACKAGES}${PackageMatcher.OPT_LETTERS_AT_END})?`;
static TWO_STAR_CAPTURE_LITERAL = '(**)';
static TWO_STAR_CAPTURE_REGEX = '(\\w+(?:\\.\\w+)*)';
static TWO_STAR_REGEX_MARKER = '#%#%#';
packagePattern;
constructor(packageIdentifier) {
this.validate(packageIdentifier);
this.packagePattern = new RegExp(this.convertToRegex(packageIdentifier));
}
static of(packageIdentifier) {
return new PackageMatcher(packageIdentifier);
}
convertToRegex(packageIdentifier) {
return packageIdentifier
.replace(new RegExp('\\[(.*?)]', 'g'), '(?:$1)')
.replaceAll(PackageMatcher.TWO_STAR_CAPTURE_LITERAL, PackageMatcher.TWO_STAR_REGEX_MARKER)
.replaceAll('*', '\\w+')
.replaceAll('.', '\\.')
.replaceAll(PackageMatcher.TWO_STAR_REGEX_MARKER, PackageMatcher.TWO_STAR_CAPTURE_REGEX)
.replaceAll('\\.\\.', PackageMatcher.TWO_DOTS_REGEX);
}
validate(packageIdentifier) {
if (packageIdentifier.includes('...')) {
throw new Error("Package Identifier may not contain more than two '.' in a row");
}
if (packageIdentifier.replace('(**)', '').includes('**')) {
throw new Error("Package Identifier may not contain more than one '*' in a row");
}
if (packageIdentifier.includes('(..)')) {
throw new Error('Package Identifier does not support capturing via (..), use (**) instead');
}
if (PackageMatcher.ILLEGAL_ALTERNATION_PATTERN.test(packageIdentifier)) {
throw new Error("Package Identifier does not allow alternation brackets '[]' without specifying any alternative via '|' inside");
}
if (this.containsToplevelAlternation(packageIdentifier)) {
throw new Error("Package Identifier only supports '|' inside of '[]' or '()'");
}
if (PackageMatcher.ILLEGAL_NESTED_GROUP_PATTERN.test(packageIdentifier)) {
throw new Error("Package Identifier does not support nesting '()' or '[]' within other '()' or '[]'");
}
this.validateCharacters(packageIdentifier);
}
containsToplevelAlternation(packageIdentifier) {
const prefixesBeforeAlternation = [];
for (let alternationIndex = 0; alternationIndex < packageIdentifier.length; alternationIndex++) {
if (packageIdentifier.charAt(alternationIndex) === '|') {
prefixesBeforeAlternation.push(packageIdentifier.substring(0, alternationIndex));
}
}
return prefixesBeforeAlternation.some(beforeAlternation => this.sameNumberOfOccurrences(beforeAlternation, '(', ')') && this.sameNumberOfOccurrences(beforeAlternation, '[', ']'));
}
sameNumberOfOccurrences(word, first, second) {
return word.split(first).length - 1 === word.split(second).length - 1;
}
validateCharacters(packageIdentifier) {
for (let i = 0; i < packageIdentifier.length; i++) {
const char = packageIdentifier.charAt(i);
if (!/[a-zA-Z0-9-@_$]/.test(char) && !PackageMatcher.PACKAGE_CONTROL_SYMBOLS.includes(char)) {
throw new Error(`Package Identifier ${packageIdentifier} may only consist of valid typescript identifier parts or the symbols '.)(*'`);
}
}
}
exactMatches(aPackage) {
return new RegExp('^' + this.packagePattern.source + '$').test(aPackage);
}
partialMatches(aPackage) {
return this.packagePattern.test(aPackage);
}
match(aPackage) {
const matcher = this.packagePattern.exec(aPackage);
return matcher !== null ? Optional_1.Optional.of(new ResultMatcher(matcher)) : Optional_1.Optional.empty();
}
static nestedGroupRegex(outerOpeningChar, outerClosingChar, nestedOpeningChar) {
return '\\' + outerOpeningChar + '[^\\' + outerClosingChar + ']*\\' + nestedOpeningChar;
}
}
exports.PackageMatcher = PackageMatcher;
class ResultMatcher {
matcher;
constructor(matcher) {
this.matcher = matcher;
}
getNumberOfGroups() {
return this.matcher.length - 1;
}
getGroup(index) {
return this.matcher[index];
}
static TO_GROUPS(input) {
const arrayResultMatchers = [];
for (let iterator = 1; iterator <= input.getNumberOfGroups(); iterator++) {
arrayResultMatchers.push(input.getGroup(iterator));
}
return arrayResultMatchers;
}
}
exports.ResultMatcher = ResultMatcher;
//# sourceMappingURL=PackageMatcher.js.map