UNPKG

flagsmith-nodejs

Version:

Flagsmith lets you manage features flags and remote config across web, mobile and server side applications. Deliver true Continuous Integration. Get builds out faster. Control who has access to new features.

157 lines (156 loc) 5.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getEvaluationContext = void 0; const models_js_1 = require("../models.js"); const constants_js_1 = require("../../segments/constants.js"); const node_crypto_1 = require("node:crypto"); const util_js_1 = require("../../features/util.js"); function getEvaluationContext(environment, identity, overrideTraits, isEnvironmentEvaluation = false) { const environmentContext = mapEnvironmentModelToEvaluationContext(environment); if (isEnvironmentEvaluation) { return environmentContext; } const identityContext = identity ? mapIdentityModelToIdentityContext(identity, overrideTraits) : undefined; const context = { ...environmentContext, ...(identityContext && { identity: identityContext }) }; return context; } exports.getEvaluationContext = getEvaluationContext; function mapEnvironmentModelToEvaluationContext(environment) { const environmentContext = { key: environment.apiKey, name: environment.name }; const features = {}; for (const fs of environment.featureStates) { const variants = fs.multivariateFeatureStateValues?.length > 0 ? fs.multivariateFeatureStateValues.map(mv => ({ value: mv.multivariateFeatureOption.value, weight: mv.percentageAllocation, priority: mv.id ?? (0, util_js_1.uuidToBigInt)(mv.mvFsValueUuid) })) : undefined; features[fs.feature.name] = { key: fs.djangoID?.toString() || fs.featurestateUUID, name: fs.feature.name, enabled: fs.enabled, value: fs.getValue(), variants, priority: fs.featureSegment?.priority, metadata: { id: fs.feature.id } }; } const segmentOverrides = {}; for (const segment of environment.project.segments) { segmentOverrides[segment.id.toString()] = { key: segment.id.toString(), name: segment.name, rules: segment.rules.map(rule => mapSegmentRuleModelToRule(rule)), overrides: segment.featureStates.length > 0 ? segment.featureStates.map(fs => ({ key: fs.djangoID?.toString() || fs.featurestateUUID, name: fs.feature.name, enabled: fs.enabled, value: fs.getValue(), priority: fs.featureSegment?.priority, metadata: { id: fs.feature.id } })) : [], metadata: { source: models_js_1.SegmentSource.API, id: segment.id } }; } let identityOverrideSegments = {}; if (environment.identityOverrides && environment.identityOverrides.length > 0) { identityOverrideSegments = mapIdentityOverridesToSegments(environment.identityOverrides); } return { environment: environmentContext, features, segments: { ...segmentOverrides, ...identityOverrideSegments } }; } function mapIdentityModelToIdentityContext(identity, overrideTraits) { const traits = overrideTraits || identity.identityTraits; const traitsContext = {}; for (const trait of traits) { traitsContext[trait.traitKey] = trait.traitValue; } const identityContext = { identifier: identity.identifier, traits: traitsContext }; return identityContext; } function mapSegmentRuleModelToRule(rule) { return { type: rule.type, conditions: rule.conditions.map((condition) => ({ property: condition.property, operator: condition.operator, value: condition.value })), rules: rule.rules.map((subRule) => mapSegmentRuleModelToRule(subRule)) }; } function mapIdentityOverridesToSegments(identityOverrides) { const segments = {}; const featuresToIdentifiers = new Map(); for (const identity of identityOverrides) { if (!identity.identityFeatures || identity.identityFeatures.length === 0) { continue; } const sortedFeatures = [...identity.identityFeatures].sort((a, b) => a.feature.name.localeCompare(b.feature.name)); const overridesKey = sortedFeatures.map(fs => ({ name: fs.feature.name, enabled: fs.enabled, value: fs.getValue(), priority: -Infinity, metadata: { id: fs.feature.id } })); const overridesHash = (0, node_crypto_1.createHash)('sha1').update(JSON.stringify(overridesKey)).digest('hex'); if (!featuresToIdentifiers.has(overridesHash)) { featuresToIdentifiers.set(overridesHash, { identifiers: [], overrides: overridesKey }); } featuresToIdentifiers.get(overridesHash).identifiers.push(identity.identifier); } for (const [overrideHash, { identifiers, overrides }] of featuresToIdentifiers.entries()) { const segmentKey = `identity_override_${overrideHash}`; segments[segmentKey] = { key: segmentKey, name: constants_js_1.IDENTITY_OVERRIDE_SEGMENT_NAME, rules: [ { type: 'ALL', conditions: [ { property: '$.identity.identifier', operator: 'IN', value: identifiers.join(',') } ] } ], metadata: { source: models_js_1.SegmentSource.IDENTITY_OVERRIDE }, overrides: overrides }; } return segments; }