hypertune
Version:
[Hypertune](https://www.hypertune.com/) is the most flexible platform for feature flags, A/B testing, analytics and app configuration. Built with full end-to-end type-safety, Git-style version control and local, synchronous, in-memory flag evaluation. Opt
78 lines • 3.75 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.complexFormExpressionEvaluationError = void 0;
exports.default = evaluate;
const constants_1 = require("../constants");
const nullThrows_1 = __importDefault(require("./nullThrows"));
const reductionLogs_1 = require("./reductionLogs");
exports.complexFormExpressionEvaluationError = `After evaluating your expression, the result was still in a complex form. ${constants_1.breakingSchemaChangesError}`;
/**
* Expression evaluation takes a fully reduced expression in "normal form" and
* converts it to a JSON value. It returns this value with "logs" that track
* all of the expressions we've needed to evaluate to compute this final value.
*/
// TODO: Pass in Expr<Expr> instead of Expr<Expr | null> to avoid null checks?
function evaluate(expression // Must be a fully reduced expression
) {
const thisLogs = (0, reductionLogs_1.mergeLogs)(expression.logs, (0, reductionLogs_1.getExpressionEvaluationCountLogs)(expression));
switch (expression.type) {
case "NoOpExpression":
return { value: true, logs: thisLogs, shouldLogEvaluation: false };
case "BooleanExpression":
case "IntExpression":
case "FloatExpression":
case "StringExpression":
case "RegexExpression":
case "EnumExpression":
return {
value: expression.value,
logs: thisLogs,
shouldLogEvaluation: true,
};
case "ObjectExpression": {
const fieldEvaluations = Object.fromEntries(Object.keys(expression.fields).map((fieldName) => [
fieldName,
evaluate((0, nullThrows_1.default)(expression.fields[fieldName], "null object field")),
]));
const value = Object.fromEntries([
[constants_1.graphqlTypeNameKey, expression.objectTypeName],
...Object.entries(fieldEvaluations).map(([fieldName, evaluation]) => [
fieldName,
evaluation.value,
]),
]);
const logs = (0, reductionLogs_1.mergeLogs)(thisLogs, ...Object.values(fieldEvaluations).map((evaluation) => evaluation.logs));
return { value, logs, shouldLogEvaluation: true };
}
case "ListExpression": {
const itemEvaluations = expression.items.map((item) => evaluate((0, nullThrows_1.default)(item, "null list item")));
const value = itemEvaluations.map((evaluation) => evaluation.value);
const logs = (0, reductionLogs_1.mergeLogs)(thisLogs, ...itemEvaluations.map((evaluation) => evaluation.logs));
return { value, logs, shouldLogEvaluation: true };
}
case "GetFieldExpression":
case "UpdateObjectExpression":
case "SwitchExpression":
case "EnumSwitchExpression":
case "ComparisonExpression":
case "ArithmeticExpression":
case "RoundNumberExpression":
case "StringifyNumberExpression":
case "StringConcatExpression":
case "GetUrlQueryParameterExpression":
case "SplitExpression":
case "LogEventExpression":
case "FunctionExpression":
case "VariableExpression":
case "ApplicationExpression":
throw new Error(exports.complexFormExpressionEvaluationError);
default: {
const neverExpression = expression;
throw new Error(`unexpected expression: ${JSON.stringify(neverExpression)}`);
}
}
}
//# sourceMappingURL=evaluate.js.map