@featurevisor/core
Version:
Core package of Featurevisor for Node.js usage
157 lines • 5.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.evaluatePlugin = void 0;
exports.evaluateFeature = evaluateFeature;
const sdk_1 = require("@featurevisor/sdk");
const config_1 = require("../config");
const builder_1 = require("../builder");
function printEvaluationDetails(evaluation) {
const ignoreKeys = ["featureKey", "variableKey", "traffic", "force"];
for (const [key, value] of Object.entries(evaluation)) {
if (ignoreKeys.indexOf(key) !== -1) {
continue;
}
if (key === "variation") {
console.log(`-`, `${key}:`, value?.value);
continue;
}
if (key === "variableSchema") {
console.log(`-`, `variableType:`, value.type);
console.log(`-`, `defaultValue:`, value.defaultValue);
continue;
}
console.log(`-`, `${key}:`, value);
}
}
function printLogs(logs) {
logs.forEach((log) => {
console.log(`[${log.level}] ${log.message}`, log.details);
console.log("");
});
}
function printHeader(message) {
console.log("\n\n###############");
console.log(`# ${message}`);
console.log("###############\n");
}
async function evaluateFeature(deps, options) {
const { datasource, projectConfig } = deps;
const existingState = await datasource.readState(options.environment || false);
const datafileContent = await (0, builder_1.buildDatafile)(projectConfig, datasource, {
schemaVersion: options.schemaVersion || config_1.SCHEMA_VERSION,
revision: "include-all-features",
environment: options.environment || false,
inflate: options.inflate,
}, existingState);
let logs = [];
const f = (0, sdk_1.createInstance)({
datafile: datafileContent,
logger: (0, sdk_1.createLogger)({
level: "debug",
handler: (level, message, details) => {
logs.push({
level,
message,
details,
});
},
}),
});
const flagEvaluation = f.evaluateFlag(options.feature, options.context);
const flagEvaluationLogs = [...logs];
logs = [];
const variationEvaluation = f.evaluateVariation(options.feature, options.context);
const variationEvaluationLogs = [...logs];
logs = [];
const variableEvaluations = {};
const variableEvaluationLogs = {};
const feature = f.getFeature(options.feature);
if (feature?.variablesSchema) {
const variableKeys = Array.isArray(feature.variablesSchema)
? feature.variablesSchema
: Object.keys(feature.variablesSchema);
variableKeys.forEach((variableKey) => {
const variableEvaluation = f.evaluateVariable(options.feature, variableKey, options.context);
variableEvaluationLogs[variableKey] = [...logs];
logs = [];
variableEvaluations[variableKey] = variableEvaluation;
});
}
const allEvaluations = {
flag: flagEvaluation,
variation: variationEvaluation,
variables: variableEvaluations,
};
if (options.json) {
console.log(options.pretty ? JSON.stringify(allEvaluations, null, 2) : JSON.stringify(allEvaluations));
return;
}
console.log("");
console.log(`Evaluating feature "${options.feature}" in environment "${options.environment}"...`);
console.log(`Against context: ${JSON.stringify(options.context)}`);
// flag
printHeader("Is enabled?");
if (options.verbose) {
printLogs(flagEvaluationLogs);
}
console.log("Value:", flagEvaluation.enabled);
console.log("\nDetails:\n");
printEvaluationDetails(flagEvaluation);
// variation
printHeader("Variation");
if (feature?.variations) {
if (options.verbose) {
printLogs(variationEvaluationLogs);
}
console.log("Value:", JSON.stringify(variationEvaluation.variation?.value));
console.log("\nDetails:\n");
printEvaluationDetails(variationEvaluation);
}
else {
console.log("No variations defined.");
}
// variables
if (feature?.variablesSchema) {
for (const [key, value] of Object.entries(variableEvaluations)) {
printHeader(`Variable: ${key}`);
if (options.verbose) {
printLogs(variableEvaluationLogs[key]);
}
console.log("Value:", typeof value.variableValue !== "undefined"
? JSON.stringify(value.variableValue)
: value.variableValue);
console.log("\nDetails:\n");
printEvaluationDetails(value);
}
}
else {
printHeader("Variables");
console.log("No variables defined.");
}
}
exports.evaluatePlugin = {
command: "evaluate",
handler: async ({ rootDirectoryPath, projectConfig, datasource, parsed }) => {
await evaluateFeature({
rootDirectoryPath,
projectConfig,
datasource,
options: parsed,
}, {
environment: parsed.environment,
feature: parsed.feature,
context: parsed.context ? JSON.parse(parsed.context) : {},
// @NOTE: introduce optional --at?
json: parsed.json,
pretty: parsed.pretty,
verbose: parsed.verbose,
});
},
examples: [
{
command: 'evaluate --environment=production --feature=my_feature --context=\'{"userId": "123"}\'',
description: "evaluate a feature against provided context",
},
],
};
//# sourceMappingURL=index.js.map