configcat-common
Version:
ConfigCat is a configuration as a service that lets you manage your features and configurations without actually deploying new code.
220 lines (219 loc) • 12.4 kB
JavaScript
import { PrerequisiteFlagComparator, SegmentComparator, UserComparator } from "./ConfigJson";
import { isAllowedValue } from "./RolloutEvaluator";
import { formatStringList, isArray, isStringArray } from "./Utils";
var invalidValuePlaceholder = "<invalid value>";
var invalidNamePlaceholder = "<invalid name>";
var invalidOperatorPlaceholder = "<invalid operator>";
var invalidReferencePlaceholder = "<invalid reference>";
var stringListMaxLength = 10;
var EvaluateLogBuilder = /** @class */ (function () {
function EvaluateLogBuilder(eol) {
this.eol = eol;
this.log = "";
this.indent = "";
}
EvaluateLogBuilder.prototype.resetIndent = function () {
this.indent = "";
return this;
};
EvaluateLogBuilder.prototype.increaseIndent = function () {
this.indent += " ";
return this;
};
EvaluateLogBuilder.prototype.decreaseIndent = function () {
this.indent = this.indent.slice(0, -2);
return this;
};
EvaluateLogBuilder.prototype.newLine = function (text) {
this.log += this.eol + this.indent + (text !== null && text !== void 0 ? text : "");
return this;
};
EvaluateLogBuilder.prototype.append = function (text) {
this.log += text;
return this;
};
EvaluateLogBuilder.prototype.toString = function () {
return this.log;
};
EvaluateLogBuilder.prototype.appendUserConditionCore = function (comparisonAttribute, comparator, comparisonValue) {
return this.append("User." + comparisonAttribute + " " + formatUserComparator(comparator) + " '" + (comparisonValue !== null && comparisonValue !== void 0 ? comparisonValue : invalidValuePlaceholder) + "'");
};
EvaluateLogBuilder.prototype.appendUserConditionString = function (comparisonAttribute, comparator, comparisonValue, isSensitive) {
if (typeof comparisonValue !== "string") {
return this.appendUserConditionCore(comparisonAttribute, comparator);
}
return this.appendUserConditionCore(comparisonAttribute, comparator, !isSensitive ? comparisonValue : "<hashed value>");
};
EvaluateLogBuilder.prototype.appendUserConditionStringList = function (comparisonAttribute, comparator, comparisonValue, isSensitive) {
if (!isStringArray(comparisonValue)) {
return this.appendUserConditionCore(comparisonAttribute, comparator);
}
var valueText = "value", valuesText = "values";
var comparatorFormatted = formatUserComparator(comparator);
if (isSensitive) {
return this.append("User." + comparisonAttribute + " " + comparatorFormatted + " [<" + comparisonValue.length + " hashed " + (comparisonValue.length === 1 ? valueText : valuesText) + ">]");
}
else {
var comparisonValueFormatted = formatStringList(comparisonValue, stringListMaxLength, function (count) { return ", ... <" + count + " more " + (count === 1 ? valueText : valuesText) + ">"; });
return this.append("User." + comparisonAttribute + " " + comparatorFormatted + " [" + comparisonValueFormatted + "]");
}
};
EvaluateLogBuilder.prototype.appendUserConditionNumber = function (comparisonAttribute, comparator, comparisonValue, isDateTime) {
if (typeof comparisonValue !== "number") {
return this.appendUserConditionCore(comparisonAttribute, comparator);
}
var comparatorFormatted = formatUserComparator(comparator);
var date;
return isDateTime && !isNaN((date = new Date(comparisonValue * 1000))) // see https://stackoverflow.com/a/1353711/8656352
? this.append("User." + comparisonAttribute + " " + comparatorFormatted + " '" + comparisonValue + "' (" + date.toISOString() + " UTC)")
: this.append("User." + comparisonAttribute + " " + comparatorFormatted + " '" + comparisonValue + "'");
};
EvaluateLogBuilder.prototype.appendUserCondition = function (condition) {
var comparisonAttribute = typeof condition.comparisonAttribute === "string" ? condition.comparisonAttribute : invalidNamePlaceholder;
var comparator = condition.comparator;
switch (condition.comparator) {
case UserComparator.TextIsOneOf:
case UserComparator.TextIsNotOneOf:
case UserComparator.TextContainsAnyOf:
case UserComparator.TextNotContainsAnyOf:
case UserComparator.SemVerIsOneOf:
case UserComparator.SemVerIsNotOneOf:
case UserComparator.TextStartsWithAnyOf:
case UserComparator.TextNotStartsWithAnyOf:
case UserComparator.TextEndsWithAnyOf:
case UserComparator.TextNotEndsWithAnyOf:
case UserComparator.ArrayContainsAnyOf:
case UserComparator.ArrayNotContainsAnyOf:
return this.appendUserConditionStringList(comparisonAttribute, comparator, condition.comparisonValue, false);
case UserComparator.SemVerLess:
case UserComparator.SemVerLessOrEquals:
case UserComparator.SemVerGreater:
case UserComparator.SemVerGreaterOrEquals:
case UserComparator.TextEquals:
case UserComparator.TextNotEquals:
return this.appendUserConditionString(comparisonAttribute, comparator, condition.comparisonValue, false);
case UserComparator.NumberEquals:
case UserComparator.NumberNotEquals:
case UserComparator.NumberLess:
case UserComparator.NumberLessOrEquals:
case UserComparator.NumberGreater:
case UserComparator.NumberGreaterOrEquals:
return this.appendUserConditionNumber(comparisonAttribute, comparator, condition.comparisonValue);
case UserComparator.SensitiveTextIsOneOf:
case UserComparator.SensitiveTextIsNotOneOf:
case UserComparator.SensitiveTextStartsWithAnyOf:
case UserComparator.SensitiveTextNotStartsWithAnyOf:
case UserComparator.SensitiveTextEndsWithAnyOf:
case UserComparator.SensitiveTextNotEndsWithAnyOf:
case UserComparator.SensitiveArrayContainsAnyOf:
case UserComparator.SensitiveArrayNotContainsAnyOf:
return this.appendUserConditionStringList(comparisonAttribute, comparator, condition.comparisonValue, true);
case UserComparator.DateTimeBefore:
case UserComparator.DateTimeAfter:
return this.appendUserConditionNumber(comparisonAttribute, comparator, condition.comparisonValue, true);
case UserComparator.SensitiveTextEquals:
case UserComparator.SensitiveTextNotEquals:
return this.appendUserConditionString(comparisonAttribute, comparator, condition.comparisonValue, true);
default:
return this.appendUserConditionCore(comparisonAttribute, comparator, condition.comparisonValue);
}
};
EvaluateLogBuilder.prototype.appendPrerequisiteFlagCondition = function (condition, settings) {
var prerequisiteFlagKey = typeof condition.prerequisiteFlagKey !== "string" ? invalidNamePlaceholder :
!(condition.prerequisiteFlagKey in settings) ? invalidReferencePlaceholder :
condition.prerequisiteFlagKey;
var comparator = condition.comparator;
var comparisonValue = condition.comparisonValue;
return this.append("Flag '" + prerequisiteFlagKey + "' " + formatPrerequisiteFlagComparator(comparator) + " '" + valueToString(comparisonValue) + "'");
};
EvaluateLogBuilder.prototype.appendSegmentCondition = function (condition) {
var segment = condition.segment;
var comparator = condition.comparator;
var segmentName = segment == null ? invalidReferencePlaceholder :
typeof segment.name !== "string" || !segment.name ? invalidNamePlaceholder :
segment.name;
return this.append("User " + formatSegmentComparator(comparator) + " '" + segmentName + "'");
};
EvaluateLogBuilder.prototype.appendConditionResult = function (result) {
return this.append("" + result);
};
EvaluateLogBuilder.prototype.appendConditionConsequence = function (result) {
this.append(" => ").appendConditionResult(result);
return result ? this : this.append(", skipping the remaining AND conditions");
};
EvaluateLogBuilder.prototype.appendTargetingRuleThenPart = function (targetingRule, newLine) {
(newLine ? this.newLine() : this.append(" "))
.append("THEN");
var then = targetingRule.then;
return this.append(!isArray(then) ? " '" + valueToString(then.value) + "'" : " % options");
};
EvaluateLogBuilder.prototype.appendTargetingRuleConsequence = function (targetingRule, isMatchOrError, newLine) {
this.increaseIndent();
this.appendTargetingRuleThenPart(targetingRule, newLine)
.append(" => ").append(isMatchOrError === true ? "MATCH, applying rule" : isMatchOrError === false ? "no match" : isMatchOrError);
return this.decreaseIndent();
};
return EvaluateLogBuilder;
}());
export { EvaluateLogBuilder };
export function formatUserComparator(comparator) {
switch (comparator) {
case UserComparator.TextIsOneOf:
case UserComparator.SensitiveTextIsOneOf:
case UserComparator.SemVerIsOneOf: return "IS ONE OF";
case UserComparator.TextIsNotOneOf:
case UserComparator.SensitiveTextIsNotOneOf:
case UserComparator.SemVerIsNotOneOf: return "IS NOT ONE OF";
case UserComparator.TextContainsAnyOf: return "CONTAINS ANY OF";
case UserComparator.TextNotContainsAnyOf: return "NOT CONTAINS ANY OF";
case UserComparator.SemVerLess:
case UserComparator.NumberLess: return "<";
case UserComparator.SemVerLessOrEquals:
case UserComparator.NumberLessOrEquals: return "<=";
case UserComparator.SemVerGreater:
case UserComparator.NumberGreater: return ">";
case UserComparator.SemVerGreaterOrEquals:
case UserComparator.NumberGreaterOrEquals: return ">=";
case UserComparator.NumberEquals: return "=";
case UserComparator.NumberNotEquals: return "!=";
case UserComparator.DateTimeBefore: return "BEFORE";
case UserComparator.DateTimeAfter: return "AFTER";
case UserComparator.TextEquals:
case UserComparator.SensitiveTextEquals: return "EQUALS";
case UserComparator.TextNotEquals:
case UserComparator.SensitiveTextNotEquals: return "NOT EQUALS";
case UserComparator.TextStartsWithAnyOf:
case UserComparator.SensitiveTextStartsWithAnyOf: return "STARTS WITH ANY OF";
case UserComparator.TextNotStartsWithAnyOf:
case UserComparator.SensitiveTextNotStartsWithAnyOf: return "NOT STARTS WITH ANY OF";
case UserComparator.TextEndsWithAnyOf:
case UserComparator.SensitiveTextEndsWithAnyOf: return "ENDS WITH ANY OF";
case UserComparator.TextNotEndsWithAnyOf:
case UserComparator.SensitiveTextNotEndsWithAnyOf: return "NOT ENDS WITH ANY OF";
case UserComparator.ArrayContainsAnyOf:
case UserComparator.SensitiveArrayContainsAnyOf: return "ARRAY CONTAINS ANY OF";
case UserComparator.ArrayNotContainsAnyOf:
case UserComparator.SensitiveArrayNotContainsAnyOf: return "ARRAY NOT CONTAINS ANY OF";
default: return invalidOperatorPlaceholder;
}
}
export function formatUserCondition(condition) {
return new EvaluateLogBuilder("").appendUserCondition(condition).toString();
}
export function formatPrerequisiteFlagComparator(comparator) {
switch (comparator) {
case PrerequisiteFlagComparator.Equals: return "EQUALS";
case PrerequisiteFlagComparator.NotEquals: return "NOT EQUALS";
default: return invalidOperatorPlaceholder;
}
}
export function formatSegmentComparator(comparator) {
switch (comparator) {
case SegmentComparator.IsIn: return "IS IN SEGMENT";
case SegmentComparator.IsNotIn: return "IS NOT IN SEGMENT";
default: return invalidOperatorPlaceholder;
}
}
export function valueToString(value) {
return isAllowedValue(value) ? value.toString() : invalidValuePlaceholder;
}