@featurevisor/sdk 2.6.7 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","mappings":"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","sources":["webpack://@featurevisor/sdk/./src/compareVersions.ts","webpack://@featurevisor/sdk/./src/conditions.ts","webpack://@featurevisor/sdk/./src/bucketer.ts","webpack://@featurevisor/sdk/./src/murmurhash.ts","webpack://@featurevisor/sdk/./src/logger.ts","webpack://@featurevisor/sdk/./src/hooks.ts","webpack://@featurevisor/sdk/./src/emitter.ts","webpack://@featurevisor/sdk/./src/datafileReader.ts","webpack://@featurevisor/sdk/./src/evaluate.ts","webpack://@featurevisor/sdk/./src/events.ts","webpack://@featurevisor/sdk/./src/child.ts","webpack://@featurevisor/sdk/./src/helpers.ts","webpack://@featurevisor/sdk/./src/instance.ts"],"sourcesContent":["// taken from: https://github.com/omichelsen/compare-versions\n// this is done to avoid loading the whole package\n\n/*\nThe MIT License (MIT)\n\nCopyright (c) 2015-2021 Ole Michelsen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n */\n\nexport const semver =\n /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\nexport const validateAndParse = (version: string) => {\n if (typeof version !== \"string\") {\n throw new TypeError(\"Invalid argument expected string\");\n }\n const match = version.match(semver);\n if (!match) {\n throw new Error(`Invalid argument not valid semver ('${version}' received)`);\n }\n match.shift();\n return match;\n};\n\nconst isWildcard = (s: string) => s === \"*\" || s === \"x\" || s === \"X\";\n\nconst forceType = (a: string | number, b: string | number) =>\n typeof a !== typeof b ? [String(a), String(b)] : [a, b];\n\nconst tryParse = (v: string) => {\n const n = parseInt(v, 10);\n return isNaN(n) ? v : n;\n};\n\nconst compareStrings = (a: string, b: string) => {\n if (isWildcard(a) || isWildcard(b)) return 0;\n const [ap, bp] = forceType(tryParse(a), tryParse(b));\n if (ap > bp) return 1;\n if (ap < bp) return -1;\n return 0;\n};\n\nexport const compareSegments = (\n a: string | string[] | RegExpMatchArray,\n b: string | string[] | RegExpMatchArray,\n) => {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const r = compareStrings(a[i] || \"0\", b[i] || \"0\");\n if (r !== 0) return r;\n }\n return 0;\n};\n\nexport const compareVersions = (v1: string, v2: string) => {\n // validate input and split into segments\n const n1 = validateAndParse(v1);\n const n2 = validateAndParse(v2);\n\n // pop off the patch\n const p1 = n1.pop();\n const p2 = n2.pop();\n\n // validate numbers\n const r = compareSegments(n1, n2);\n if (r !== 0) return r;\n\n // validate pre-release\n if (p1 && p2) {\n return compareSegments(p1.split(\".\"), p2.split(\".\"));\n } else if (p1 || p2) {\n return p1 ? -1 : 1;\n }\n\n return 0;\n};\n","import type { Context, PlainCondition, AttributeValue } from \"@featurevisor/types\";\n\nimport { GetRegex } from \"./datafileReader\";\nimport { compareVersions } from \"./compareVersions\";\n\nexport function getValueFromContext(obj, path): AttributeValue {\n if (path.indexOf(\".\") === -1) {\n return obj[path];\n }\n\n return path.split(\".\").reduce((o, i) => (o ? o[i] : undefined), obj);\n}\n\nexport function conditionIsMatched(\n condition: PlainCondition,\n context: Context,\n getRegex: GetRegex,\n): boolean {\n const { attribute, operator, value, regexFlags } = condition;\n const contextValueFromPath = getValueFromContext(context, attribute) as AttributeValue;\n\n if (operator === \"equals\") {\n return contextValueFromPath === value;\n } else if (operator === \"notEquals\") {\n return contextValueFromPath !== value;\n } else if (operator === \"before\" || operator === \"after\") {\n // date comparisons\n const valueInContext = contextValueFromPath as string | Date;\n\n const dateInContext =\n valueInContext instanceof Date ? valueInContext : new Date(valueInContext);\n const dateInCondition = value instanceof Date ? value : new Date(value as string);\n\n return operator === \"before\"\n ? dateInContext < dateInCondition\n : dateInContext > dateInCondition;\n } else if (\n Array.isArray(value) &&\n ([\"string\", \"number\"].indexOf(typeof contextValueFromPath) !== -1 ||\n contextValueFromPath === null)\n ) {\n // in / notIn (where condition value is an array)\n const valueInContext = contextValueFromPath as string;\n\n if (operator === \"in\") {\n return value.indexOf(valueInContext) !== -1;\n } else if (operator === \"notIn\") {\n return value.indexOf(valueInContext) === -1;\n }\n } else if (typeof contextValueFromPath === \"string\" && typeof value === \"string\") {\n // string\n const valueInContext = contextValueFromPath as string;\n\n if (operator === \"contains\") {\n return valueInContext.indexOf(value) !== -1;\n } else if (operator === \"notContains\") {\n return valueInContext.indexOf(value) === -1;\n } else if (operator === \"startsWith\") {\n return valueInContext.startsWith(value);\n } else if (operator === \"endsWith\") {\n return valueInContext.endsWith(value);\n } else if (operator === \"semverEquals\") {\n return compareVersions(valueInContext, value) === 0;\n } else if (operator === \"semverNotEquals\") {\n return compareVersions(valueInContext, value) !== 0;\n } else if (operator === \"semverGreaterThan\") {\n return compareVersions(valueInContext, value) === 1;\n } else if (operator === \"semverGreaterThanOrEquals\") {\n return compareVersions(valueInContext, value) >= 0;\n } else if (operator === \"semverLessThan\") {\n return compareVersions(valueInContext, value) === -1;\n } else if (operator === \"semverLessThanOrEquals\") {\n return compareVersions(valueInContext, value) <= 0;\n } else if (operator === \"matches\") {\n const regex = getRegex(value, regexFlags || \"\");\n return regex.test(valueInContext);\n } else if (operator === \"notMatches\") {\n const regex = getRegex(value, regexFlags || \"\");\n return !regex.test(valueInContext);\n }\n } else if (typeof contextValueFromPath === \"number\" && typeof value === \"number\") {\n // numeric\n const valueInContext = contextValueFromPath as number;\n\n if (operator === \"greaterThan\") {\n return valueInContext > value;\n } else if (operator === \"greaterThanOrEquals\") {\n return valueInContext >= value;\n } else if (operator === \"lessThan\") {\n return valueInContext < value;\n } else if (operator === \"lessThanOrEquals\") {\n return valueInContext <= value;\n }\n } else if (operator === \"exists\") {\n return typeof contextValueFromPath !== \"undefined\";\n } else if (operator === \"notExists\") {\n return typeof contextValueFromPath === \"undefined\";\n } else if (Array.isArray(contextValueFromPath) && typeof value === \"string\") {\n // includes / notIncludes (where context value is an array)\n const valueInContext = contextValueFromPath as string[];\n\n if (operator === \"includes\") {\n return valueInContext.indexOf(value) > -1;\n } else if (operator === \"notIncludes\") {\n return valueInContext.indexOf(value) === -1;\n }\n }\n\n return false;\n}\n","import type { Context, AttributeValue, FeatureKey, BucketBy } from \"@featurevisor/types\";\n\nimport { Logger } from \"./logger\";\nimport { getValueFromContext } from \"./conditions\";\nimport { MurmurHashV3 } from \"./murmurhash\";\n\nexport type BucketKey = string;\nexport type BucketValue = number; // 0 to 100,000 (100% * 1000 to include three decimal places in same integer)\n\n/**\n * Generic hashing\n */\nconst HASH_SEED = 1;\nconst MAX_HASH_VALUE = Math.pow(2, 32);\n\nexport const MAX_BUCKETED_NUMBER = 100000; // 100% * 1000 to include three decimal places in the same integer value\n\nexport function getBucketedNumber(bucketKey: string): BucketValue {\n const hashValue = MurmurHashV3(bucketKey, HASH_SEED);\n const ratio = hashValue / MAX_HASH_VALUE;\n\n return Math.floor(ratio * MAX_BUCKETED_NUMBER);\n}\n\n/**\n * Bucket key\n */\nconst DEFAULT_BUCKET_KEY_SEPARATOR = \".\";\n\nexport interface GetBucketKeyOptions {\n featureKey: FeatureKey;\n bucketBy: BucketBy;\n context: Context;\n\n logger: Logger;\n}\n\nexport function getBucketKey(options: GetBucketKeyOptions): BucketKey {\n const {\n featureKey,\n bucketBy,\n context,\n\n logger,\n } = options;\n\n let type;\n let attributeKeys;\n\n if (typeof bucketBy === \"string\") {\n type = \"plain\";\n attributeKeys = [bucketBy];\n } else if (Array.isArray(bucketBy)) {\n type = \"and\";\n attributeKeys = bucketBy;\n } else if (typeof bucketBy === \"object\" && Array.isArray(bucketBy.or)) {\n type = \"or\";\n attributeKeys = bucketBy.or;\n } else {\n logger.error(\"invalid bucketBy\", { featureKey, bucketBy });\n\n throw new Error(\"invalid bucketBy\");\n }\n\n const bucketKey: AttributeValue[] = [];\n\n attributeKeys.forEach((attributeKey) => {\n const attributeValue = getValueFromContext(context, attributeKey);\n\n if (typeof attributeValue === \"undefined\") {\n return;\n }\n\n if (type === \"plain\" || type === \"and\") {\n bucketKey.push(attributeValue);\n } else {\n // or\n if (bucketKey.length === 0) {\n bucketKey.push(attributeValue);\n }\n }\n });\n\n bucketKey.push(featureKey);\n\n return bucketKey.join(DEFAULT_BUCKET_KEY_SEPARATOR);\n}\n","// v3 function taken from: https://github.com/perezd/node-murmurhash\n// this has been done to avoid loading v2 function which is not used in the SDK\n\n/**\n * Copyright (c) 2020 Gary Court, Derek Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\nconst createBuffer = (val) => new TextEncoder().encode(val);\n\nexport function MurmurHashV3(key, seed) {\n if (typeof key === \"string\") key = createBuffer(key);\n\n let remainder, bytes, h1, h1b, c1, c2, k1, i;\n\n remainder = key.length & 3; // key.length % 4\n bytes = key.length - remainder;\n h1 = seed;\n c1 = 0xcc9e2d51;\n c2 = 0x1b873593;\n i = 0;\n\n while (i < bytes) {\n k1 =\n (key[i] & 0xff) |\n ((key[++i] & 0xff) << 8) |\n ((key[++i] & 0xff) << 16) |\n ((key[++i] & 0xff) << 24);\n ++i;\n\n k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\n\n h1 ^= k1;\n h1 = (h1 << 13) | (h1 >>> 19);\n h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;\n h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);\n }\n\n k1 = 0;\n\n switch (remainder) {\n case 3:\n k1 ^= (key[i + 2] & 0xff) << 16;\n case 2:\n k1 ^= (key[i + 1] & 0xff) << 8;\n case 1:\n k1 ^= key[i] & 0xff;\n\n k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\n h1 ^= k1;\n }\n\n h1 ^= key.length;\n\n h1 ^= h1 >>> 16;\n h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;\n h1 ^= h1 >>> 13;\n h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff;\n h1 ^= h1 >>> 16;\n\n return h1 >>> 0;\n}\n","export type LogLevel = \"fatal\" | \"error\" | \"warn\" | \"info\" | \"debug\";\n\nexport type LogMessage = string;\n\nexport interface LogDetails {\n [key: string]: any;\n}\n\nexport type LogHandler = (level: LogLevel, message: LogMessage, details?: LogDetails) => void;\n\nexport interface CreateLoggerOptions {\n level?: LogLevel;\n handler?: LogHandler;\n}\n\nexport const loggerPrefix = \"[Featurevisor]\";\n\nexport const defaultLogHandler: LogHandler = function defaultLogHandler(\n level,\n message,\n details = {},\n) {\n let method = \"log\";\n\n if (level === \"info\") {\n method = \"info\";\n } else if (level === \"warn\") {\n method = \"warn\";\n } else if (level === \"error\") {\n method = \"error\";\n }\n\n console[method](loggerPrefix, message, details);\n};\n\nexport class Logger {\n static allLevels: LogLevel[] = [\n \"fatal\",\n \"error\",\n \"warn\",\n \"info\",\n\n // not enabled by default\n \"debug\",\n ];\n\n static defaultLevel: LogLevel = \"info\";\n\n private level: LogLevel;\n private handle: LogHandler;\n\n constructor(options: CreateLoggerOptions) {\n this.level = options.level || Logger.defaultLevel;\n this.handle = options.handler || defaultLogHandler;\n }\n\n setLevel(level: LogLevel) {\n this.level = level;\n }\n\n log(level: LogLevel, message: LogMessage, details?: LogDetails) {\n const shouldHandle = Logger.allLevels.indexOf(this.level) >= Logger.allLevels.indexOf(level);\n\n if (!shouldHandle) {\n return;\n }\n\n this.handle(level, message, details);\n }\n\n debug(message: LogMessage, details?: LogDetails) {\n this.log(\"debug\", message, details);\n }\n\n info(message: LogMessage, details?: LogDetails) {\n this.log(\"info\", message, details);\n }\n\n warn(message: LogMessage, details?: LogDetails) {\n this.log(\"warn\", message, details);\n }\n\n error(message: LogMessage, details?: LogDetails) {\n this.log(\"error\", message, details);\n }\n}\n\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n return new Logger(options);\n}\n","import type { BucketBy, Context, FeatureKey } from \"@featurevisor/types\";\n\nimport type { EvaluateOptions, Evaluation } from \"./evaluate\";\nimport type { Logger } from \"./logger\";\nimport type { BucketKey, BucketValue } from \"./bucketer\";\n\n/**\n * bucketKey\n */\nexport interface ConfigureBucketKeyOptions {\n featureKey: FeatureKey;\n context: Context;\n bucketBy: BucketBy;\n bucketKey: string; // the initial bucket key, which can be modified by hooks\n}\n\nexport type ConfigureBucketKey = (options: ConfigureBucketKeyOptions) => BucketKey;\n\n/**\n * bucketValue\n */\nexport interface ConfigureBucketValueOptions {\n featureKey: FeatureKey;\n bucketKey: string;\n context: Context;\n bucketValue: number; // the initial bucket value, which can be modified by hooks\n}\n\nexport type ConfigureBucketValue = (options: ConfigureBucketValueOptions) => BucketValue;\n\n/**\n * Hooks\n */\nexport interface Hook {\n name: string;\n\n before?: (options: EvaluateOptions) => EvaluateOptions;\n\n bucketKey?: ConfigureBucketKey;\n\n bucketValue?: ConfigureBucketValue;\n\n after?: (evaluation: Evaluation, options: EvaluateOptions) => Evaluation;\n}\n\nexport interface HooksManagerOptions {\n hooks?: Hook[];\n logger: Logger;\n}\n\nexport class HooksManager {\n private hooks: Hook[] = [];\n private logger: Logger;\n\n constructor(options: HooksManagerOptions) {\n this.logger = options.logger;\n\n if (options.hooks) {\n options.hooks.forEach((hook) => {\n this.add(hook);\n });\n }\n }\n\n add(hook: Hook): (() => void) | undefined {\n if (this.hooks.some((existingHook) => existingHook.name === hook.name)) {\n this.logger.error(`Hook with name \"${hook.name}\" already exists.`, {\n name: hook.name,\n hook: hook,\n });\n\n return;\n }\n\n this.hooks.push(hook);\n\n return () => {\n this.remove(hook.name);\n };\n }\n\n remove(name: string): void {\n this.hooks = this.hooks.filter((hook) => hook.name !== name);\n }\n\n getAll(): Hook[] {\n return this.hooks;\n }\n}\n","export type EventName = \"datafile_set\" | \"context_set\" | \"sticky_set\";\n\nexport type EventDetails = Record<string, unknown>;\n\nexport type EventCallback = (details: EventDetails) => void;\n\nexport type Listeners = Record<EventName, EventCallback[]> | {}; // eslint-disable-line\n\nexport class Emitter {\n listeners: Listeners;\n\n constructor() {\n this.listeners = {};\n }\n\n on(eventName: EventName, callback: EventCallback) {\n if (!this.listeners[eventName]) {\n this.listeners[eventName] = [];\n }\n\n const listeners = this.listeners[eventName];\n listeners.push(callback);\n\n let isActive = true;\n\n return function unsubscribe() {\n if (!isActive) {\n return;\n }\n\n isActive = false;\n\n const index = listeners.indexOf(callback);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n };\n }\n\n trigger(eventName: EventName, details: EventDetails = {}) {\n const listeners = this.listeners[eventName];\n\n if (!listeners) {\n return;\n }\n\n listeners.forEach(function (listener) {\n try {\n listener(details);\n } catch (err) {\n console.error(err);\n }\n });\n }\n\n clearAll() {\n this.listeners = {};\n }\n}\n","import type {\n Feature,\n Segment,\n DatafileContent,\n SegmentKey,\n FeatureKey,\n Context,\n Traffic,\n Allocation,\n GroupSegment,\n Condition,\n Force,\n} from \"@featurevisor/types\";\n\nimport { conditionIsMatched } from \"./conditions\";\nimport { Logger } from \"./logger\";\n\nexport type GetRegex = (regexString: string, regexFlags: string) => RegExp;\n\nexport interface DatafileReaderOptions {\n datafile: DatafileContent;\n logger: Logger;\n}\n\nexport interface ForceResult {\n force?: Force;\n forceIndex?: number;\n}\n\nexport class DatafileReader {\n private schemaVersion: string;\n private revision: string;\n\n private segments: Record<SegmentKey, Segment>;\n private features: Record<FeatureKey, Feature>;\n\n private logger: Logger;\n\n // done to avoid creating new RegExp objects for the same regex string and flags.\n // kept here to avoid memory leaks.\n // if datafile is reset, this cache will be cleared.\n private regexCache: Record<string, RegExp>;\n\n constructor(options: DatafileReaderOptions) {\n const { datafile, logger } = options;\n\n this.logger = logger;\n\n this.schemaVersion = datafile.schemaVersion;\n this.revision = datafile.revision;\n\n this.segments = datafile.segments;\n this.features = datafile.features;\n\n this.regexCache = {};\n }\n\n getRevision(): string {\n return this.revision;\n }\n\n getSchemaVersion(): string {\n return this.schemaVersion;\n }\n\n getSegment(segmentKey: SegmentKey): Segment | undefined {\n const segment = this.segments[segmentKey];\n\n if (!segment) {\n return undefined;\n }\n\n segment.conditions = this.parseConditionsIfStringified(segment.conditions);\n\n return segment;\n }\n\n getFeatureKeys(): string[] {\n return Object.keys(this.features);\n }\n\n getFeature(featureKey: FeatureKey): Feature | undefined {\n return this.features[featureKey];\n }\n\n getVariableKeys(featureKey: FeatureKey): string[] {\n const feature = this.getFeature(featureKey);\n\n if (!feature) {\n return [];\n }\n\n return Object.keys(feature.variablesSchema || {});\n }\n\n hasVariations(featureKey: FeatureKey): boolean {\n const feature = this.getFeature(featureKey);\n\n if (!feature) {\n return false;\n }\n\n return Array.isArray(feature.variations) && feature.variations.length > 0;\n }\n\n getRegex(regexString: string, regexFlags?: string): RegExp {\n const flags = regexFlags || \"\";\n const cacheKey = `${regexString}-${flags}`;\n\n if (this.regexCache[cacheKey]) {\n return this.regexCache[cacheKey];\n }\n\n const regex = new RegExp(regexString, flags);\n this.regexCache[cacheKey] = regex;\n\n return regex;\n }\n\n allConditionsAreMatched(conditions: Condition[] | Condition, context: Context): boolean {\n if (typeof conditions === \"string\") {\n if (conditions === \"*\") {\n return true;\n }\n\n return false;\n }\n\n const getRegex = (regexString: string, regexFlags: string) =>\n this.getRegex(regexString, regexFlags);\n\n if (\"attribute\" in conditions) {\n try {\n return conditionIsMatched(conditions, context, getRegex);\n } catch (e) {\n this.logger.warn(e.message, {\n error: e,\n details: {\n condition: conditions,\n context,\n },\n });\n\n return false;\n }\n }\n\n if (\"and\" in conditions && Array.isArray(conditions.and)) {\n return conditions.and.every((c) => this.allConditionsAreMatched(c, context));\n }\n\n if (\"or\" in conditions && Array.isArray(conditions.or)) {\n return conditions.or.some((c) => this.allConditionsAreMatched(c, context));\n }\n\n if (\"not\" in conditions && Array.isArray(conditions.not)) {\n return conditions.not.every(\n () =>\n this.allConditionsAreMatched(\n {\n and: conditions.not,\n },\n context,\n ) === false,\n );\n }\n\n if (Array.isArray(conditions)) {\n return conditions.every((c) => this.allConditionsAreMatched(c, context));\n }\n\n return false;\n }\n\n segmentIsMatched(segment: Segment, context: Context): boolean {\n return this.allConditionsAreMatched(segment.conditions as Condition | Condition[], context);\n }\n\n allSegmentsAreMatched(\n groupSegments: GroupSegment | GroupSegment[] | \"*\",\n context: Context,\n ): boolean {\n if (groupSegments === \"*\") {\n return true;\n }\n\n if (typeof groupSegments === \"string\") {\n const segment = this.getSegment(groupSegments);\n\n if (segment) {\n return this.segmentIsMatched(segment, context);\n }\n\n return false;\n }\n\n if (typeof groupSegments === \"object\") {\n if (\"and\" in groupSegments && Array.isArray(groupSegments.and)) {\n return groupSegments.and.every((groupSegment) =>\n this.allSegmentsAreMatched(groupSegment, context),\n );\n }\n\n if (\"or\" in groupSegments && Array.isArray(groupSegments.or)) {\n return groupSegments.or.some((groupSegment) =>\n this.allSegmentsAreMatched(groupSegment, context),\n );\n }\n\n if (\"not\" in groupSegments && Array.isArray(groupSegments.not)) {\n return groupSegments.not.every(\n (groupSegment) => this.allSegmentsAreMatched(groupSegment, context) === false,\n );\n }\n }\n\n if (Array.isArray(groupSegments)) {\n return groupSegments.every((groupSegment) =>\n this.allSegmentsAreMatched(groupSegment, context),\n );\n }\n\n return false;\n }\n\n getMatchedTraffic(traffic: Traffic[], context: Context): Traffic | undefined {\n return traffic.find((t) => {\n if (!this.allSegmentsAreMatched(this.parseSegmentsIfStringified(t.segments), context)) {\n return false;\n }\n\n return true;\n });\n }\n\n getMatchedAllocation(traffic: Traffic, bucketValue: number): Allocation | undefined {\n if (!traffic.allocation) {\n return undefined;\n }\n\n for (const allocation of traffic.allocation) {\n const [start, end] = allocation.range;\n\n if (allocation.range && start <= bucketValue && end >= bucketValue) {\n return allocation;\n }\n }\n\n return undefined;\n }\n\n getMatchedForce(featureKey: FeatureKey | Feature, context: Context): ForceResult {\n const result: ForceResult = {\n force: undefined,\n forceIndex: undefined,\n };\n\n const feature = typeof featureKey === \"string\" ? this.getFeature(featureKey) : featureKey;\n\n if (!feature || !feature.force) {\n return result;\n }\n\n for (let i = 0; i < feature.force.length; i++) {\n const currentForce = feature.force[i];\n\n if (\n currentForce.conditions &&\n this.allConditionsAreMatched(\n this.parseConditionsIfStringified(currentForce.conditions),\n context,\n )\n ) {\n result.force = currentForce;\n result.forceIndex = i;\n break;\n }\n\n if (\n currentForce.segments &&\n this.allSegmentsAreMatched(this.parseSegmentsIfStringified(currentForce.segments), context)\n ) {\n result.force = currentForce;\n result.forceIndex = i;\n break;\n }\n }\n\n return result;\n }\n\n parseConditionsIfStringified(conditions: Condition | Condition[]): Condition | Condition[] {\n if (typeof conditions !== \"string\") {\n // already parsed\n return conditions;\n }\n\n if (conditions === \"*\") {\n // everyone\n return conditions;\n }\n\n try {\n return JSON.parse(conditions);\n } catch (e) {\n this.logger.error(\"Error parsing conditions\", {\n error: e,\n details: {\n conditions,\n },\n });\n\n return conditions;\n }\n }\n\n parseSegmentsIfStringified(\n segments: GroupSegment | GroupSegment[],\n ): GroupSegment | GroupSegment[] {\n if (typeof segments === \"string\" && (segments.startsWith(\"{\") || segments.startsWith(\"[\"))) {\n return JSON.parse(segments);\n }\n\n return segments;\n }\n}\n","import type {\n FeatureKey,\n Context,\n RuleKey,\n Traffic,\n Force,\n Required,\n Variation,\n VariationValue,\n VariableKey,\n VariableValue,\n VariableSchema,\n EvaluatedFeature,\n StickyFeatures,\n Allocation,\n} from \"@featurevisor/types\";\n\nimport { Logger } from \"./logger\";\nimport { HooksManager } from \"./hooks\";\nimport { DatafileReader } from \"./datafileReader\";\nimport { BucketKey, BucketValue, getBucketKey, getBucketedNumber } from \"./bucketer\";\n\nexport enum EvaluationReason {\n // feature specific\n FEATURE_NOT_FOUND = \"feature_not_found\", // feature is not found in datafile\n DISABLED = \"disabled\", // feature is disabled\n REQUIRED = \"required\", // required features are not enabled\n OUT_OF_RANGE = \"out_of_range\", // out of range when mutually exclusive experiments are involved via Groups\n\n // variations specific\n NO_VARIATIONS = \"no_variations\", // feature has no variations\n VARIATION_DISABLED = \"variation_disabled\", // feature is disabled, and variation's disabledVariationValue is used\n\n // variable specific\n VARIABLE_NOT_FOUND = \"variable_not_found\", // variable's schema is not defined in the feature\n VARIABLE_DEFAULT = \"variable_default\", // default variable value used\n VARIABLE_DISABLED = \"variable_disabled\", // feature is disabled, and variable's disabledValue is used\n VARIABLE_OVERRIDE = \"variable_override\", // variable overridden from inside a variation\n\n // common\n NO_MATCH = \"no_match\", // no rules matched\n FORCED = \"forced\", // against a forced rule\n STICKY = \"sticky\", // against a sticky feature\n RULE = \"rule\", // against a regular rule\n ALLOCATED = \"allocated\", // regular allocation based on bucketing\n\n ERROR = \"error\", // error\n}\n\ntype EvaluationType = \"flag\" | \"variation\" | \"variable\";\n\nexport interface Evaluation {\n // required\n type: EvaluationType;\n featureKey: FeatureKey;\n reason: EvaluationReason;\n\n // common\n bucketKey?: BucketKey;\n bucketValue?: BucketValue;\n ruleKey?: RuleKey;\n error?: Error;\n enabled?: boolean;\n traffic?: Traffic;\n forceIndex?: number;\n force?: Force;\n required?: Required[];\n sticky?: EvaluatedFeature;\n\n // variation\n variation?: Variation;\n variationValue?: VariationValue;\n\n // variable\n variableKey?: VariableKey;\n variableValue?: VariableValue;\n variableSchema?: VariableSchema;\n}\n\nexport interface EvaluateDependencies {\n context: Context;\n\n logger: Logger;\n hooksManager: HooksManager;\n datafileReader: DatafileReader;\n\n // OverrideOptions\n sticky?: StickyFeatures;\n\n defaultVariationValue?: VariationValue;\n defaultVariableValue?: VariableValue;\n}\n\nexport interface EvaluateParams {\n type: EvaluationType;\n featureKey: FeatureKey;\n variableKey?: VariableKey;\n}\n\nexport type EvaluateOptions = EvaluateParams & EvaluateDependencies;\n\nexport function evaluateWithHooks(opts: EvaluateOptions): Evaluation {\n try {\n const { hooksManager } = opts;\n const hooks = hooksManager.getAll();\n\n // run before hooks\n let options = opts;\n for (const hook of hooksManager.getAll()) {\n if (hook.before) {\n options = hook.before(options);\n }\n }\n\n // evaluate\n let evaluation = evaluate(options);\n\n // default: variation\n if (\n typeof options.defaultVariationValue !== \"undefined\" &&\n evaluation.type === \"variation\" &&\n typeof evaluation.variationValue === \"undefined\"\n ) {\n evaluation.variationValue = options.defaultVariationValue;\n }\n\n // default: variable\n if (\n typeof options.defaultVariableValue !== \"undefined\" &&\n evaluation.type === \"variable\" &&\n typeof evaluation.variableValue === \"undefined\"\n ) {\n evaluation.variableValue = options.defaultVariableValue;\n }\n\n // run after hooks\n for (const hook of hooks) {\n if (hook.after) {\n evaluation = hook.after(evaluation, options);\n }\n }\n\n return evaluation;\n } catch (e) {\n const { type, featureKey, variableKey, logger } = opts;\n\n const evaluation: Evaluation = {\n type,\n featureKey,\n variableKey,\n reason: EvaluationReason.ERROR,\n error: e,\n };\n\n logger.error(\"error during evaluation\", evaluation);\n\n return evaluation;\n }\n}\n\nexport function evaluate(options: EvaluateOptions): Evaluation {\n const { type, featureKey, variableKey, context, logger, datafileReader, sticky, hooksManager } =\n options;\n\n const hooks = hooksManager.getAll();\n let evaluation: Evaluation;\n\n try {\n /**\n * Root flag evaluation\n */\n let flag: Evaluation;\n if (type !== \"flag\") {\n // needed by variation and variable evaluations\n flag = evaluate({\n ...options,\n type: \"flag\",\n });\n\n if (flag.enabled === false) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.DISABLED,\n };\n\n const feature = datafileReader.getFeature(featureKey);\n\n // serve variable default value if feature is disabled (if explicitly specified)\n if (type === \"variable\") {\n if (\n feature &&\n variableKey &&\n feature.variablesSchema &&\n feature.variablesSchema[variableKey]\n ) {\n const variableSchema = feature.variablesSchema[variableKey];\n\n if (typeof variableSchema.disabledValue !== \"undefined\") {\n // disabledValue: <value>\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_DISABLED,\n variableKey,\n variableValue: variableSchema.disabledValue,\n variableSchema,\n enabled: false,\n };\n } else if (variableSchema.useDefaultWhenDisabled) {\n // useDefaultWhenDisabled: true\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_DEFAULT,\n variableKey,\n variableValue: variableSchema.defaultValue,\n variableSchema,\n enabled: false,\n };\n }\n }\n }\n\n // serve disabled variation value if feature is disabled (if explicitly specified)\n if (type === \"variation\" && feature && feature.disabledVariationValue) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIATION_DISABLED,\n variationValue: feature.disabledVariationValue,\n enabled: false,\n };\n }\n\n logger.debug(\"feature is disabled\", evaluation);\n\n return evaluation;\n }\n }\n\n /**\n * Sticky\n */\n if (sticky && sticky[featureKey]) {\n // flag\n if (type === \"flag\" && typeof sticky[featureKey].enabled !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.STICKY,\n sticky: sticky[featureKey],\n enabled: sticky[featureKey].enabled,\n };\n\n logger.debug(\"using sticky enabled\", evaluation);\n\n return evaluation;\n }\n\n // variation\n if (type === \"variation\") {\n const variationValue = sticky[featureKey].variation;\n\n if (typeof variationValue !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.STICKY,\n variationValue,\n };\n\n logger.debug(\"using sticky variation\", evaluation);\n\n return evaluation;\n }\n }\n\n // variable\n if (variableKey) {\n const variables = sticky[featureKey].variables;\n\n if (variables) {\n const result = variables[variableKey];\n\n if (typeof result !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.STICKY,\n variableKey,\n variableValue: result,\n };\n\n logger.debug(\"using sticky variable\", evaluation);\n\n return evaluation;\n }\n }\n }\n }\n\n /**\n * Feature\n */\n const feature =\n typeof featureKey === \"string\" ? datafileReader.getFeature(featureKey) : featureKey;\n\n // feature: not found\n if (!feature) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.FEATURE_NOT_FOUND,\n };\n\n logger.warn(\"feature not found\", evaluation);\n\n return evaluation;\n }\n\n // feature: deprecated\n if (type === \"flag\" && feature.deprecated) {\n logger.warn(\"feature is deprecated\", { featureKey });\n }\n\n // variableSchema\n let variableSchema: VariableSchema | undefined;\n\n if (variableKey) {\n if (feature.variablesSchema && feature.variablesSchema[variableKey]) {\n variableSchema = feature.variablesSchema[variableKey];\n }\n\n // variable schema not found\n if (!variableSchema) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_NOT_FOUND,\n variableKey,\n };\n\n logger.warn(\"variable schema not found\", evaluation);\n\n return evaluation;\n }\n\n if (variableSchema.deprecated) {\n logger.warn(\"variable is deprecated\", {\n featureKey,\n variableKey,\n });\n }\n }\n\n // variation: no variations\n if (type === \"variation\" && (!feature.variations || feature.variations.length === 0)) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.NO_VARIATIONS,\n };\n\n logger.warn(\"no variations\", evaluation);\n\n return evaluation;\n }\n\n /**\n * Forced\n */\n const { force, forceIndex } = datafileReader.getMatchedForce(feature, context);\n\n if (force) {\n // flag\n if (type === \"flag\" && typeof force.enabled !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.FORCED,\n forceIndex,\n force,\n enabled: force.enabled,\n };\n\n logger.debug(\"forced enabled found\", evaluation);\n\n return evaluation;\n }\n\n // variation\n if (type === \"variation\" && force.variation && feature.variations) {\n const variation = feature.variations.find((v) => v.value === force.variation);\n\n if (variation) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.FORCED,\n forceIndex,\n force,\n variation,\n };\n\n logger.debug(\"forced variation found\", evaluation);\n\n return evaluation;\n }\n }\n\n // variable\n if (variableKey && force.variables && typeof force.variables[variableKey] !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.FORCED,\n forceIndex,\n force,\n variableKey,\n variableSchema,\n variableValue: force.variables[variableKey],\n };\n\n logger.debug(\"forced variable\", evaluation);\n\n return evaluation;\n }\n }\n\n /**\n * Required\n */\n if (type === \"flag\" && feature.required && feature.required.length > 0) {\n const requiredFeaturesAreEnabled = feature.required.every((required) => {\n let requiredKey;\n let requiredVariation;\n\n if (typeof required === \"string\") {\n requiredKey = required;\n } else {\n requiredKey = required.key;\n requiredVariation = required.variation;\n }\n\n const requiredEvaluation = evaluate({\n ...options,\n type: \"flag\",\n featureKey: requiredKey,\n });\n const requiredIsEnabled = requiredEvaluation.enabled;\n\n if (!requiredIsEnabled) {\n return false;\n }\n\n if (typeof requiredVariation !== \"undefined\") {\n const requiredVariationEvaluation = evaluate({\n ...options,\n type: \"variation\",\n featureKey: requiredKey,\n });\n\n let requiredVariationValue;\n\n if (requiredVariationEvaluation.variationValue) {\n requiredVariationValue = requiredVariationEvaluation.variationValue;\n } else if (requiredVariationEvaluation.variation) {\n requiredVariationValue = requiredVariationEvaluation.variation.value;\n }\n\n return requiredVariationValue === requiredVariation;\n }\n\n return true;\n });\n\n if (!requiredFeaturesAreEnabled) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.REQUIRED,\n required: feature.required,\n enabled: requiredFeaturesAreEnabled,\n };\n\n logger.debug(\"required features not enabled\", evaluation);\n\n return evaluation;\n }\n }\n\n /**\n * Bucketing\n */\n // bucketKey\n let bucketKey = getBucketKey({\n featureKey,\n bucketBy: feature.bucketBy,\n context,\n\n logger,\n });\n for (const hook of hooks) {\n if (hook.bucketKey) {\n bucketKey = hook.bucketKey({\n featureKey,\n context,\n bucketBy: feature.bucketBy,\n bucketKey,\n });\n }\n }\n\n // bucketValue\n let bucketValue = getBucketedNumber(bucketKey);\n\n for (const hook of hooks) {\n if (hook.bucketValue) {\n bucketValue = hook.bucketValue({\n featureKey,\n bucketKey,\n context,\n bucketValue,\n });\n }\n }\n\n let matchedTraffic: Traffic | undefined;\n let matchedAllocation: Allocation | undefined;\n\n if (type !== \"flag\") {\n matchedTraffic = datafileReader.getMatchedTraffic(feature.traffic, context);\n\n if (matchedTraffic) {\n matchedAllocation = datafileReader.getMatchedAllocation(matchedTraffic, bucketValue);\n }\n } else {\n matchedTraffic = datafileReader.getMatchedTraffic(feature.traffic, context);\n }\n\n if (matchedTraffic) {\n // percentage: 0\n if (matchedTraffic.percentage === 0) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n enabled: false,\n };\n\n logger.debug(\"matched rule with 0 percentage\", evaluation);\n\n return evaluation;\n }\n\n // flag\n if (type === \"flag\") {\n // flag: check if mutually exclusive\n if (feature.ranges && feature.ranges.length > 0) {\n const matchedRange = feature.ranges.find((range) => {\n return bucketValue >= range[0] && bucketValue < range[1];\n });\n\n // matched\n if (matchedRange) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.ALLOCATED,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n enabled:\n typeof matchedTraffic.enabled === \"undefined\" ? true : matchedTraffic.enabled,\n };\n\n logger.debug(\"matched\", evaluation);\n\n return evaluation;\n }\n\n // no match\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.OUT_OF_RANGE,\n bucketKey,\n bucketValue,\n enabled: false,\n };\n\n logger.debug(\"not matched\", evaluation);\n\n return evaluation;\n }\n\n // flag: override from rule\n if (typeof matchedTraffic.enabled !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n enabled: matchedTraffic.enabled,\n };\n\n logger.debug(\"override from rule\", evaluation);\n\n return evaluation;\n }\n\n // treated as enabled because of matched traffic\n if (bucketValue <= matchedTraffic.percentage) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n enabled: true,\n };\n\n logger.debug(\"matched traffic\", evaluation);\n\n return evaluation;\n }\n }\n\n // variation\n if (type === \"variation\" && feature.variations) {\n // override from rule\n if (matchedTraffic.variation) {\n const variation = feature.variations.find((v) => v.value === matchedTraffic.variation);\n\n if (variation) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n variation,\n };\n\n logger.debug(\"override from rule\", evaluation);\n\n return evaluation;\n }\n }\n\n // regular allocation\n if (matchedAllocation && matchedAllocation.variation) {\n const variation = feature.variations.find((v) => v.value === matchedAllocation.variation);\n\n if (variation) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.ALLOCATED,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n variation,\n };\n\n logger.debug(\"allocated variation\", evaluation);\n\n return evaluation;\n }\n }\n }\n }\n\n // variable\n if (type === \"variable\" && variableKey) {\n // override from rule\n if (\n matchedTraffic &&\n matchedTraffic.variables &&\n typeof matchedTraffic.variables[variableKey] !== \"undefined\"\n ) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n variableKey,\n variableSchema,\n variableValue: matchedTraffic.variables[variableKey],\n };\n\n logger.debug(\"override from rule\", evaluation);\n\n return evaluation;\n }\n\n // check variations\n let variationValue;\n\n if (force && force.variation) {\n variationValue = force.variation;\n } else if (matchedTraffic && matchedTraffic.variation) {\n variationValue = matchedTraffic.variation;\n } else if (matchedAllocation && matchedAllocation.variation) {\n variationValue = matchedAllocation.variation;\n }\n\n if (variationValue && Array.isArray(feature.variations)) {\n const variation = feature.variations.find((v) => v.value === variationValue);\n\n if (variation && variation.variableOverrides && variation.variableOverrides[variableKey]) {\n const overrides = variation.variableOverrides[variableKey];\n\n const override = overrides.find((o) => {\n if (o.conditions) {\n return datafileReader.allConditionsAreMatched(\n typeof o.conditions === \"string\" && o.conditions !== \"*\"\n ? JSON.parse(o.conditions)\n : o.conditions,\n context,\n );\n }\n\n if (o.segments) {\n return datafileReader.allSegmentsAreMatched(\n datafileReader.parseSegmentsIfStringified(o.segments),\n context,\n );\n }\n\n return false;\n });\n\n if (override) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_OVERRIDE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic?.key,\n traffic: matchedTraffic,\n variableKey,\n variableSchema,\n variableValue: override.value,\n };\n\n logger.debug(\"variable override\", evaluation);\n\n return evaluation;\n }\n }\n\n if (\n variation &&\n variation.variables &&\n typeof variation.variables[variableKey] !== \"undefined\"\n ) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.ALLOCATED,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic?.key,\n traffic: matchedTraffic,\n variableKey,\n variableSchema,\n variableValue: variation.variables[variableKey],\n };\n\n logger.debug(\"allocated variable\", evaluation);\n\n return evaluation;\n }\n }\n }\n\n /**\n * Nothing matched\n */\n if (type === \"variation\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.NO_MATCH,\n bucketKey,\n bucketValue,\n };\n\n logger.debug(\"no matched variation\", evaluation);\n\n return evaluation;\n }\n\n if (type === \"variable\") {\n if (variableSchema) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_DEFAULT,\n bucketKey,\n bucketValue,\n variableKey,\n variableSchema,\n variableValue: variableSchema.defaultValue,\n };\n\n logger.debug(\"using default value\", evaluation);\n\n return evaluation;\n }\n\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_NOT_FOUND,\n variableKey,\n bucketKey,\n bucketValue,\n };\n\n logger.debug(\"variable not found\", evaluation);\n\n return evaluation;\n }\n\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.NO_MATCH,\n bucketKey,\n bucketValue,\n enabled: false,\n };\n\n logger.debug(\"nothing matched\", evaluation);\n\n return evaluation;\n } catch (e) {\n evaluation = {\n type,\n featureKey,\n variableKey,\n reason: EvaluationReason.ERROR,\n error: e,\n };\n\n logger.error(\"error\", evaluation);\n\n return evaluation;\n }\n}\n","import type { StickyFeatures, FeatureKey } from \"@featurevisor/types\";\n\nimport type { EventDetails } from \"./emitter\";\nimport type { DatafileReader } from \"./datafileReader\";\n\nexport function getParamsForStickySetEvent(\n previousStickyFeatures: StickyFeatures = {},\n newStickyFeatures: StickyFeatures = {},\n replace,\n): EventDetails {\n const keysBefore = Object.keys(previousStickyFeatures);\n const keysAfter = Object.keys(newStickyFeatures);\n\n const allKeys = [...keysBefore, ...keysAfter];\n const uniqueFeaturesAffected = allKeys.filter(\n (element, index) => allKeys.indexOf(element) === index,\n );\n\n return {\n features: uniqueFeaturesAffected,\n replaced: replace,\n };\n}\n\nexport function getParamsForDatafileSetEvent(\n previousDatafileReader: DatafileReader,\n newDatafileReader: DatafileReader,\n): EventDetails {\n const previousRevision = previousDatafileReader.getRevision();\n const previousFeatureKeys = previousDatafileReader.getFeatureKeys();\n\n const newRevision = newDatafileReader.getRevision();\n const newFeatureKeys = newDatafileReader.getFeatureKeys();\n\n // results\n const removedFeatures: FeatureKey[] = [];\n const changedFeatures: FeatureKey[] = [];\n const addedFeatures: FeatureKey[] = [];\n\n // checking against existing datafile\n for (const previousFeatureKey of previousFeatureKeys) {\n if (newFeatureKeys.indexOf(previousFeatureKey) === -1) {\n // feature was removed in new datafile\n removedFeatures.push(previousFeatureKey);\n\n continue;\n }\n\n // feature exists in both datafiles, check if it was changed\n const previousFeature = previousDatafileReader.getFeature(previousFeatureKey);\n const newFeature = newDatafileReader.getFeature(previousFeatureKey);\n\n if (previousFeature?.hash !== newFeature?.hash) {\n // feature was changed in new datafile\n changedFeatures.push(previousFeatureKey);\n }\n }\n\n // checking against new datafile\n for (const newFeatureKey of newFeatureKeys) {\n if (previousFeatureKeys.indexOf(newFeatureKey) === -1) {\n // feature was added in new datafile\n addedFeatures.push(newFeatureKey);\n }\n }\n\n // combine all affected feature keys\n const allAffectedFeatures: FeatureKey[] = [\n ...removedFeatures,\n ...changedFeatures,\n ...addedFeatures,\n ].filter((element, index, array) => array.indexOf(element) === index);\n\n const details = {\n revision: newRevision,\n previousRevision,\n revisionChanged: previousRevision !== newRevision,\n\n features: allAffectedFeatures,\n };\n\n return details;\n}\n","import type {\n Context,\n StickyFeatures,\n FeatureKey,\n VariationValue,\n VariableValue,\n EvaluatedFeatures,\n} from \"@featurevisor/types\";\n\nimport { EventName, EventCallback, Emitter } from \"./emitter\";\nimport type { FeaturevisorInstance, OverrideOptions } from \"./instance\";\nimport { getParamsForStickySetEvent } from \"./events\";\n\nexport class FeaturevisorChildInstance {\n private parent: FeaturevisorInstance;\n private context: Context;\n private sticky: StickyFeatures;\n private emitter: Emitter;\n\n constructor(options) {\n this.parent = options.parent;\n this.context = options.context;\n this.sticky = options.sticky || {};\n this.emitter = new Emitter();\n }\n\n on(eventName: EventName, callback: EventCallback) {\n if (eventName === \"context_set\" || eventName === \"sticky_set\") {\n return this.emitter.on(eventName, callback);\n }\n\n return this.parent.on(eventName, callback);\n }\n\n close() {\n this.emitter.clearAll();\n }\n\n setContext(context: Context, replace = false) {\n if (replace) {\n this.context = context;\n } else {\n this.context = { ...this.context, ...context };\n }\n\n this.emitter.trigger(\"context_set\", {\n context: this.context,\n replaced: replace,\n });\n }\n\n getContext(context?: Context): Context {\n return this.parent.getContext({\n ...this.context,\n ...context,\n });\n }\n\n setSticky(sticky: StickyFeatures, replace = false) {\n const previousStickyFeatures = this.sticky || {};\n\n if (replace) {\n this.sticky = { ...sticky };\n } else {\n this.sticky = {\n ...this.sticky,\n ...sticky,\n };\n }\n\n const params = getParamsForStickySetEvent(previousStickyFeatures, this.sticky, replace);\n\n this.emitter.trigger(\"sticky_set\", params);\n }\n\n isEnabled(featureKey: FeatureKey, context: Context = {}, options: OverrideOptions = {}): boolean {\n return this.parent.isEnabled(\n featureKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariation(\n featureKey: FeatureKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): VariationValue | null {\n return this.parent.getVariation(\n featureKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariable(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): VariableValue | null {\n return this.parent.getVariable(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableBoolean(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): boolean | null {\n return this.parent.getVariableBoolean(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableString(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): string | null {\n return this.parent.getVariableString(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableInteger(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): number | null {\n return this.parent.getVariableInteger(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableDouble(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): number | null {\n return this.parent.getVariableDouble(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableArray(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): string[] | null {\n return this.parent.getVariableArray(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableObject<T>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T | null {\n return this.parent.getVariableObject<T>(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableJSON<T>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T | null {\n return this.parent.getVariableJSON<T>(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getAllEvaluations(\n context: Context = {},\n featureKeys: string[] = [],\n options: OverrideOptions = {},\n ): EvaluatedFeatures {\n return this.parent.getAllEvaluations(\n {\n ...this.context,\n ...context,\n },\n featureKeys,\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n}\n","import type { VariableType, VariableValue } from \"@featurevisor/types\";\n\ntype FieldType = string | VariableType;\nexport type ValueType = VariableValue;\n\nexport function getValueByType(value: ValueType, fieldType: FieldType): ValueType {\n if (value === undefined) {\n return null;\n }\n\n switch (fieldType) {\n case \"string\":\n return typeof value === \"string\" ? value : null;\n case \"integer\":\n return parseInt(value as string, 10);\n case \"double\":\n return parseFloat(value as string);\n case \"boolean\":\n return value === true;\n case \"array\":\n return Array.isArray(value) ? value : null;\n case \"object\":\n return typeof value === \"object\" ? value : null;\n // @NOTE: `json` is not handled here intentionally\n default:\n return value;\n }\n}\n","import type {\n Context,\n Feature,\n FeatureKey,\n StickyFeatures,\n EvaluatedFeatures,\n EvaluatedFeature,\n VariableValue,\n VariationValue,\n VariableKey,\n DatafileContent,\n} from \"@featurevisor/types\";\n\nimport { createLogger, Logger, LogLevel } from \"./logger\";\nimport { HooksManager, Hook } from \"./hooks\";\nimport { Emitter, EventCallback, EventName } from \"./emitter\";\nimport { DatafileReader } from \"./datafileReader\";\nimport { Evaluation, EvaluateDependencies, evaluateWithHooks } from \"./evaluate\";\nimport { FeaturevisorChildInstance } from \"./child\";\nimport { getParamsForStickySetEvent, getParamsForDatafileSetEvent } from \"./events\";\nimport { getValueByType } from \"./helpers\";\n\nconst emptyDatafile: DatafileContent = {\n schemaVersion: \"2\",\n revision: \"unknown\",\n segments: {},\n features: {},\n};\n\nexport interface OverrideOptions {\n sticky?: StickyFeatures;\n\n defaultVariationValue?: VariationValue;\n defaultVariableValue?: VariableValue;\n}\n\nexport interface InstanceOptions {\n datafile?: DatafileContent | string;\n context?: Context;\n logLevel?: LogLevel;\n logger?: Logger;\n sticky?: StickyFeatures;\n hooks?: Hook[];\n}\n\nexport class FeaturevisorInstance {\n // from options\n private context: Context = {};\n private logger: Logger;\n private sticky?: StickyFeatures;\n\n // internally created\n private datafileReader: DatafileReader;\n private hooksManager: HooksManager;\n private emitter: Emitter;\n\n constructor(options: InstanceOptions) {\n // from options\n this.context = options.context || {};\n this.logger =\n options.logger ||\n createLogger({\n level: options.logLevel || Logger.defaultLevel,\n });\n this.hooksManager = new HooksManager({\n hooks: options.hooks || [],\n logger: this.logger,\n });\n this.emitter = new Emitter();\n this.sticky = options.sticky;\n\n // datafile\n this.datafileReader = new DatafileReader({\n datafile: emptyDatafile,\n logger: this.logger,\n });\n if (options.datafile) {\n this.datafileReader = new DatafileReader({\n datafile:\n typeof options.datafile === \"string\" ? JSON.parse(options.datafile) : options.datafile,\n logger: this.logger,\n });\n }\n\n this.logger.info(\"Featurevisor SDK initialized\");\n }\n\n setLogLevel(level: LogLevel) {\n this.logger.setLevel(level);\n }\n\n setDatafile(datafile: DatafileContent | string) {\n try {\n const newDatafileReader = new DatafileReader({\n datafile: typeof datafile === \"string\" ? JSON.parse(datafile) : datafile,\n logger: this.logger,\n });\n\n const details = getParamsForDatafileSetEvent(this.datafileReader, newDatafileReader);\n\n this.datafileReader = newDatafileReader;\n\n this.logger.info(\"datafile set\", details);\n this.emitter.trigger(\"datafile_set\", details);\n } catch (e) {\n this.logger.error(\"could not parse datafile\", { error: e });\n }\n }\n\n setSticky(sticky: StickyFeatures, replace = false) {\n const previousStickyFeatures = this.sticky || {};\n\n if (replace) {\n this.sticky = { ...sticky };\n } else {\n this.sticky = {\n ...this.sticky,\n ...sticky,\n };\n }\n\n const params = getParamsForStickySetEvent(previousStickyFeatures, this.sticky, replace);\n\n this.logger.info(\"sticky features set\", params);\n this.emitter.trigger(\"sticky_set\", params);\n }\n\n getRevision(): string {\n return this.datafileReader.getRevision();\n }\n\n getFeature(featureKey: string): Feature | undefined {\n return this.datafileReader.getFeature(featureKey);\n }\n\n addHook(hook: Hook) {\n return this.hooksManager.add(hook);\n }\n\n on(eventName: EventName, callback: EventCallback) {\n return this.emitter.on(eventName, callback);\n }\n\n close() {\n this.emitter.clearAll();\n }\n\n /**\n * Context\n */\n setContext(context: Context, replace = false) {\n if (replace) {\n this.context = context;\n } else {\n this.context = { ...this.context, ...context };\n }\n\n this.emitter.trigger(\"context_set\", {\n context: this.context,\n replaced: replace,\n });\n this.logger.debug(replace ? \"context replaced\" : \"context updated\", {\n context: this.context,\n replaced: replace,\n });\n }\n\n getContext(context?: Context): Context {\n return context\n ? {\n ...this.context,\n ...context,\n }\n : this.context;\n }\n\n spawn(context: Context = {}, options: OverrideOptions = {}): FeaturevisorChildInstance {\n return new FeaturevisorChildInstance({\n parent: this,\n context: this.getContext(context),\n sticky: options.sticky,\n });\n }\n\n /**\n * Flag\n */\n private getEvaluationDependencies(\n context: Context,\n options: OverrideOptions = {},\n ): EvaluateDependencies {\n return {\n context: this.getContext(context),\n\n logger: this.logger,\n hooksManager: this.hooksManager,\n datafileReader: this.datafileReader,\n\n // OverrideOptions\n sticky: options.sticky\n ? {\n ...this.sticky,\n ...options.sticky,\n }\n : this.sticky,\n defaultVariationValue: options.defaultVariationValue,\n defaultVariableValue: options.defaultVariableValue,\n };\n }\n\n evaluateFlag(\n featureKey: FeatureKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): Evaluation {\n return evaluateWithHooks({\n ...this.getEvaluationDependencies(context, options),\n type: \"flag\",\n featureKey,\n });\n }\n\n isEnabled(featureKey: FeatureKey, context: Context = {}, options: OverrideOptions = {}): boolean {\n try {\n const evaluation = this.evaluateFlag(featureKey, context, options);\n\n return evaluation.enabled === true;\n } catch (e) {\n this.logger.error(\"isEnabled\", { featureKey, error: e });\n\n return false;\n }\n }\n\n /**\n * Variation\n */\n evaluateVariation(\n featureKey: FeatureKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): Evaluation {\n return evaluateWithHooks({\n ...this.getEvaluationDependencies(context, options),\n type: \"variation\",\n featureKey,\n });\n }\n\n getVariation(\n featureKey: FeatureKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): VariationValue | null {\n try {\n const evaluation = this.evaluateVariation(featureKey, context, options);\n\n if (typeof evaluation.variationValue !== \"undefined\") {\n return evaluation.variationValue;\n }\n\n if (evaluation.variation) {\n return evaluation.variation.value;\n }\n\n return null;\n } catch (e) {\n this.logger.error(\"getVariation\", { featureKey, error: e });\n\n return null;\n }\n }\n\n /**\n * Variable\n */\n evaluateVariable(\n featureKey: FeatureKey,\n variableKey: VariableKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): Evaluation {\n return evaluateWithHooks({\n ...this.getEvaluationDependencies(context, options),\n type: \"variable\",\n featureKey,\n variableKey,\n });\n }\n\n getVariable(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): VariableValue | null {\n try {\n const evaluation = this.evaluateVariable(featureKey, variableKey, context, options);\n\n if (typeof evaluation.variableValue !== \"undefined\") {\n if (\n evaluation.variableSchema &&\n evaluation.variableSchema.type === \"json\" &&\n typeof evaluation.variableValue === \"string\"\n ) {\n return JSON.parse(evaluation.variableValue);\n }\n\n return evaluation.variableValue;\n }\n\n return null;\n } catch (e) {\n this.logger.error(\"getVariable\", { featureKey, variableKey, error: e });\n\n return null;\n }\n }\n\n getVariableBoolean(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): boolean | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"boolean\") as boolean | null;\n }\n\n getVariableString(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): string | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"string\") as string | null;\n }\n\n getVariableInteger(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): number | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"integer\") as number | null;\n }\n\n getVariableDouble(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): number | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"double\") as number | null;\n }\n\n getVariableArray(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): string[] | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"array\") as string[] | null;\n }\n\n getVariableObject<T>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"object\") as T | null;\n }\n\n getVariableJSON<T>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"json\") as T | null;\n }\n\n getAllEvaluations(\n context: Context = {},\n featureKeys: string[] = [],\n options: OverrideOptions = {},\n ): EvaluatedFeatures {\n const result: EvaluatedFeatures = {};\n\n const keys = featureKeys.length > 0 ? featureKeys : this.datafileReader.getFeatureKeys();\n for (const featureKey of keys) {\n // isEnabled\n const evaluatedFeature: EvaluatedFeature = {\n enabled: this.isEnabled(featureKey, context, options),\n };\n\n // variation\n if (this.datafileReader.hasVariations(featureKey)) {\n const variation = this.getVariation(featureKey, context, options);\n\n if (variation) {\n evaluatedFeature.variation = variation;\n }\n }\n\n // variables\n const variableKeys = this.datafileReader.getVariableKeys(featureKey);\n if (variableKeys.length > 0) {\n evaluatedFeature.variables = {};\n\n for (const variableKey of variableKeys) {\n evaluatedFeature.variables[variableKey] = this.getVariable(\n featureKey,\n variableKey,\n context,\n options,\n );\n }\n }\n\n result[featureKey] = evaluatedFeature;\n }\n\n return result;\n }\n}\n\nexport function createInstance(options: InstanceOptions = {}): FeaturevisorInstance {\n return new FeaturevisorInstance(options);\n}\n"],"names":["semver","validateAndParse","version","TypeError","match","Error","shift","isWildcard","s","tryParse","v","n","parseInt","isNaN","compareStrings","a","b","ap","bp","String","forceType","compareSegments","i","Math","max","length","r","compareVersions","v1","v2","n1","n2","p1","pop","p2","split","getValueFromContext","obj","path","indexOf","reduce","o","undefined","conditionIsMatched","condition","context","getRegex","attribute","operator","value","regexFlags","contextValueFromPath","dateInContext","Date","dateInCondition","Array","isArray","valueInContext","startsWith","endsWith","test","MAX_HASH_VALUE","pow","MAX_BUCKETED_NUMBER","getBucketedNumber","bucketKey","ratio","key","seed","val","remainder","bytes","h1","h1b","c1","c2","k1","TextEncoder","encode","MurmurHashV3","floor","getBucketKey","options","featureKey","bucketBy","logger","type","attributeKeys","or","error","forEach","attributeKey","attributeValue","push","join","loggerPrefix","defaultLogHandler","level","message","details","method","console","Logger","constructor","this","defaultLevel","handle","handler","setLevel","log","allLevels","debug","info","warn","createLogger","HooksManager","hooks","hook","add","some","existingHook","name","remove","filter","getAll","Emitter","listeners","on","eventName","callback","isActive","index","splice","trigger","listener","err","clearAll","DatafileReader","datafile","schemaVersion","revision","segments","features","regexCache","getRevision","getSchemaVersion","getSegment","segmentKey","segment","conditions","parseConditionsIfStringified","getFeatureKeys","Object","keys","getFeature","getVariableKeys","feature","variablesSchema","hasVariations","variations","regexString","flags","cacheKey","regex","RegExp","allConditionsAreMatched","e","and","every","c","not","segmentIsMatched","allSegmentsAreMatched","groupSegments","groupSegment","getMatchedTraffic","traffic","find","t","parseSegmentsIfStringified","getMatchedAllocation","bucketValue","allocation","start","end","range","getMatchedForce","result","force","forceIndex","currentForce","JSON","parse","EvaluationReason","evaluateWithHooks","opts","hooksManager","before","evaluation","evaluate","defaultVariationValue","variationValue","defaultVariableValue","variableValue","after","variableKey","reason","ERROR","datafileReader","sticky","flag","enabled","DISABLED","variableSchema","disabledValue","VARIABLE_DISABLED","useDefaultWhenDisabled","VARIABLE_DEFAULT","defaultValue","disabledVariationValue","VARIATION_DISABLED","STICKY","variation","variables","FEATURE_NOT_FOUND","deprecated","VARIABLE_NOT_FOUND","NO_VARIATIONS","FORCED","required","requiredFeaturesAreEnabled","requiredKey","requiredVariation","requiredVariationEvaluation","requiredVariationValue","REQUIRED","matchedTraffic","matchedAllocation","percentage","RULE","ruleKey","ranges","ALLOCATED","OUT_OF_RANGE","variableOverrides","override","VARIABLE_OVERRIDE","NO_MATCH","getParamsForStickySetEvent","previousStickyFeatures","newStickyFeatures","replace","allKeys","element","replaced","FeaturevisorChildInstance","parent","emitter","close","setContext","getContext","setSticky","params","isEnabled","getVariation","getVariable","getVariableBoolean","getVariableString","getVariableInteger","getVariableDouble","getVariableArray","getVariableObject","getVariableJSON","getAllEvaluations","featureKeys","getValueByType","fieldType","parseFloat","emptyDatafile","FeaturevisorInstance","logLevel","setLogLevel","setDatafile","newDatafileReader","previousDatafileReader","previousRevision","previousFeatureKeys","newRevision","newFeatureKeys","removedFeatures","changedFeatures","addedFeatures","previousFeatureKey","previousFeature","newFeature","hash","newFeatureKey","revisionChanged","array","getParamsForDatafileSetEvent","addHook","spawn","getEvaluationDependencies","evaluateFlag","evaluateVariation","evaluateVariable","evaluatedFeature","variableKeys","createInstance"],"sourceRoot":""}
1
+ {"version":3,"file":"index.mjs","mappings":"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","sources":["webpack://@featurevisor/sdk/./src/compareVersions.ts","webpack://@featurevisor/sdk/./src/conditions.ts","webpack://@featurevisor/sdk/./src/bucketer.ts","webpack://@featurevisor/sdk/./src/murmurhash.ts","webpack://@featurevisor/sdk/./src/logger.ts","webpack://@featurevisor/sdk/./src/hooks.ts","webpack://@featurevisor/sdk/./src/emitter.ts","webpack://@featurevisor/sdk/./src/datafileReader.ts","webpack://@featurevisor/sdk/./src/evaluate.ts","webpack://@featurevisor/sdk/./src/events.ts","webpack://@featurevisor/sdk/./src/child.ts","webpack://@featurevisor/sdk/./src/helpers.ts","webpack://@featurevisor/sdk/./src/instance.ts"],"sourcesContent":["// taken from: https://github.com/omichelsen/compare-versions\n// this is done to avoid loading the whole package\n\n/*\nThe MIT License (MIT)\n\nCopyright (c) 2015-2021 Ole Michelsen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n */\n\nexport const semver =\n /^[v^~<>=]*?(\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+)(?:\\.([x*]|\\d+))?(?:-([\\da-z\\-]+(?:\\.[\\da-z\\-]+)*))?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?)?)?$/i;\n\nexport const validateAndParse = (version: string) => {\n if (typeof version !== \"string\") {\n throw new TypeError(\"Invalid argument expected string\");\n }\n const match = version.match(semver);\n if (!match) {\n throw new Error(`Invalid argument not valid semver ('${version}' received)`);\n }\n match.shift();\n return match;\n};\n\nconst isWildcard = (s: string) => s === \"*\" || s === \"x\" || s === \"X\";\n\nconst forceType = (a: string | number, b: string | number) =>\n typeof a !== typeof b ? [String(a), String(b)] : [a, b];\n\nconst tryParse = (v: string) => {\n const n = parseInt(v, 10);\n return isNaN(n) ? v : n;\n};\n\nconst compareStrings = (a: string, b: string) => {\n if (isWildcard(a) || isWildcard(b)) return 0;\n const [ap, bp] = forceType(tryParse(a), tryParse(b));\n if (ap > bp) return 1;\n if (ap < bp) return -1;\n return 0;\n};\n\nexport const compareSegments = (\n a: string | string[] | RegExpMatchArray,\n b: string | string[] | RegExpMatchArray,\n) => {\n for (let i = 0; i < Math.max(a.length, b.length); i++) {\n const r = compareStrings(a[i] || \"0\", b[i] || \"0\");\n if (r !== 0) return r;\n }\n return 0;\n};\n\nexport const compareVersions = (v1: string, v2: string) => {\n // validate input and split into segments\n const n1 = validateAndParse(v1);\n const n2 = validateAndParse(v2);\n\n // pop off the patch\n const p1 = n1.pop();\n const p2 = n2.pop();\n\n // validate numbers\n const r = compareSegments(n1, n2);\n if (r !== 0) return r;\n\n // validate pre-release\n if (p1 && p2) {\n return compareSegments(p1.split(\".\"), p2.split(\".\"));\n } else if (p1 || p2) {\n return p1 ? -1 : 1;\n }\n\n return 0;\n};\n","import type { Context, PlainCondition, AttributeValue } from \"@featurevisor/types\";\n\nimport { GetRegex } from \"./datafileReader\";\nimport { compareVersions } from \"./compareVersions\";\n\nexport function getValueFromContext(obj, path): AttributeValue {\n if (path.indexOf(\".\") === -1) {\n return obj[path];\n }\n\n return path.split(\".\").reduce((o, i) => (o ? o[i] : undefined), obj);\n}\n\nexport function conditionIsMatched(\n condition: PlainCondition,\n context: Context,\n getRegex: GetRegex,\n): boolean {\n const { attribute, operator, value, regexFlags } = condition;\n const contextValueFromPath = getValueFromContext(context, attribute) as AttributeValue;\n\n if (operator === \"equals\") {\n return contextValueFromPath === value;\n } else if (operator === \"notEquals\") {\n return contextValueFromPath !== value;\n } else if (operator === \"before\" || operator === \"after\") {\n // date comparisons\n const valueInContext = contextValueFromPath as string | Date;\n\n const dateInContext =\n valueInContext instanceof Date ? valueInContext : new Date(valueInContext);\n const dateInCondition = value instanceof Date ? value : new Date(value as string);\n\n return operator === \"before\"\n ? dateInContext < dateInCondition\n : dateInContext > dateInCondition;\n } else if (\n Array.isArray(value) &&\n ([\"string\", \"number\"].indexOf(typeof contextValueFromPath) !== -1 ||\n contextValueFromPath === null)\n ) {\n // in / notIn (where condition value is an array)\n const valueInContext = contextValueFromPath as string;\n\n if (operator === \"in\") {\n return value.indexOf(valueInContext) !== -1;\n } else if (operator === \"notIn\") {\n return value.indexOf(valueInContext) === -1;\n }\n } else if (typeof contextValueFromPath === \"string\" && typeof value === \"string\") {\n // string\n const valueInContext = contextValueFromPath as string;\n\n if (operator === \"contains\") {\n return valueInContext.indexOf(value) !== -1;\n } else if (operator === \"notContains\") {\n return valueInContext.indexOf(value) === -1;\n } else if (operator === \"startsWith\") {\n return valueInContext.startsWith(value);\n } else if (operator === \"endsWith\") {\n return valueInContext.endsWith(value);\n } else if (operator === \"semverEquals\") {\n return compareVersions(valueInContext, value) === 0;\n } else if (operator === \"semverNotEquals\") {\n return compareVersions(valueInContext, value) !== 0;\n } else if (operator === \"semverGreaterThan\") {\n return compareVersions(valueInContext, value) === 1;\n } else if (operator === \"semverGreaterThanOrEquals\") {\n return compareVersions(valueInContext, value) >= 0;\n } else if (operator === \"semverLessThan\") {\n return compareVersions(valueInContext, value) === -1;\n } else if (operator === \"semverLessThanOrEquals\") {\n return compareVersions(valueInContext, value) <= 0;\n } else if (operator === \"matches\") {\n const regex = getRegex(value, regexFlags || \"\");\n return regex.test(valueInContext);\n } else if (operator === \"notMatches\") {\n const regex = getRegex(value, regexFlags || \"\");\n return !regex.test(valueInContext);\n }\n } else if (typeof contextValueFromPath === \"number\" && typeof value === \"number\") {\n // numeric\n const valueInContext = contextValueFromPath as number;\n\n if (operator === \"greaterThan\") {\n return valueInContext > value;\n } else if (operator === \"greaterThanOrEquals\") {\n return valueInContext >= value;\n } else if (operator === \"lessThan\") {\n return valueInContext < value;\n } else if (operator === \"lessThanOrEquals\") {\n return valueInContext <= value;\n }\n } else if (operator === \"exists\") {\n return typeof contextValueFromPath !== \"undefined\";\n } else if (operator === \"notExists\") {\n return typeof contextValueFromPath === \"undefined\";\n } else if (Array.isArray(contextValueFromPath) && typeof value === \"string\") {\n // includes / notIncludes (where context value is an array)\n const valueInContext = contextValueFromPath as string[];\n\n if (operator === \"includes\") {\n return valueInContext.indexOf(value) > -1;\n } else if (operator === \"notIncludes\") {\n return valueInContext.indexOf(value) === -1;\n }\n }\n\n return false;\n}\n","import type { Context, AttributeValue, FeatureKey, BucketBy } from \"@featurevisor/types\";\n\nimport { Logger } from \"./logger\";\nimport { getValueFromContext } from \"./conditions\";\nimport { MurmurHashV3 } from \"./murmurhash\";\n\nexport type BucketKey = string;\nexport type BucketValue = number; // 0 to 100,000 (100% * 1000 to include three decimal places in same integer)\n\n/**\n * Generic hashing\n */\nconst HASH_SEED = 1;\nconst MAX_HASH_VALUE = Math.pow(2, 32);\n\nexport const MAX_BUCKETED_NUMBER = 100000; // 100% * 1000 to include three decimal places in the same integer value\n\nexport function getBucketedNumber(bucketKey: string): BucketValue {\n const hashValue = MurmurHashV3(bucketKey, HASH_SEED);\n const ratio = hashValue / MAX_HASH_VALUE;\n\n return Math.floor(ratio * MAX_BUCKETED_NUMBER);\n}\n\n/**\n * Bucket key\n */\nconst DEFAULT_BUCKET_KEY_SEPARATOR = \".\";\n\nexport interface GetBucketKeyOptions {\n featureKey: FeatureKey;\n bucketBy: BucketBy;\n context: Context;\n\n logger: Logger;\n}\n\nexport function getBucketKey(options: GetBucketKeyOptions): BucketKey {\n const {\n featureKey,\n bucketBy,\n context,\n\n logger,\n } = options;\n\n let type;\n let attributeKeys;\n\n if (typeof bucketBy === \"string\") {\n type = \"plain\";\n attributeKeys = [bucketBy];\n } else if (Array.isArray(bucketBy)) {\n type = \"and\";\n attributeKeys = bucketBy;\n } else if (typeof bucketBy === \"object\" && Array.isArray(bucketBy.or)) {\n type = \"or\";\n attributeKeys = bucketBy.or;\n } else {\n logger.error(\"invalid bucketBy\", { featureKey, bucketBy });\n\n throw new Error(\"invalid bucketBy\");\n }\n\n const bucketKey: AttributeValue[] = [];\n\n attributeKeys.forEach((attributeKey) => {\n const attributeValue = getValueFromContext(context, attributeKey);\n\n if (typeof attributeValue === \"undefined\") {\n return;\n }\n\n if (type === \"plain\" || type === \"and\") {\n bucketKey.push(attributeValue);\n } else {\n // or\n if (bucketKey.length === 0) {\n bucketKey.push(attributeValue);\n }\n }\n });\n\n bucketKey.push(featureKey);\n\n return bucketKey.join(DEFAULT_BUCKET_KEY_SEPARATOR);\n}\n","// v3 function taken from: https://github.com/perezd/node-murmurhash\n// this has been done to avoid loading v2 function which is not used in the SDK\n\n/**\n * Copyright (c) 2020 Gary Court, Derek Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n */\n\nconst createBuffer = (val) => new TextEncoder().encode(val);\n\nexport function MurmurHashV3(key, seed) {\n if (typeof key === \"string\") key = createBuffer(key);\n\n let remainder, bytes, h1, h1b, c1, c2, k1, i;\n\n remainder = key.length & 3; // key.length % 4\n bytes = key.length - remainder;\n h1 = seed;\n c1 = 0xcc9e2d51;\n c2 = 0x1b873593;\n i = 0;\n\n while (i < bytes) {\n k1 =\n (key[i] & 0xff) |\n ((key[++i] & 0xff) << 8) |\n ((key[++i] & 0xff) << 16) |\n ((key[++i] & 0xff) << 24);\n ++i;\n\n k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\n\n h1 ^= k1;\n h1 = (h1 << 13) | (h1 >>> 19);\n h1b = ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;\n h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);\n }\n\n k1 = 0;\n\n switch (remainder) {\n case 3:\n k1 ^= (key[i + 2] & 0xff) << 16;\n case 2:\n k1 ^= (key[i + 1] & 0xff) << 8;\n case 1:\n k1 ^= key[i] & 0xff;\n\n k1 = ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;\n k1 = (k1 << 15) | (k1 >>> 17);\n k1 = ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;\n h1 ^= k1;\n }\n\n h1 ^= key.length;\n\n h1 ^= h1 >>> 16;\n h1 = ((h1 & 0xffff) * 0x85ebca6b + ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) & 0xffffffff;\n h1 ^= h1 >>> 13;\n h1 = ((h1 & 0xffff) * 0xc2b2ae35 + ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) & 0xffffffff;\n h1 ^= h1 >>> 16;\n\n return h1 >>> 0;\n}\n","export type LogLevel = \"fatal\" | \"error\" | \"warn\" | \"info\" | \"debug\";\n\nexport type LogMessage = string;\n\nexport interface LogDetails {\n [key: string]: any;\n}\n\nexport type LogHandler = (level: LogLevel, message: LogMessage, details?: LogDetails) => void;\n\nexport interface CreateLoggerOptions {\n level?: LogLevel;\n handler?: LogHandler;\n}\n\nexport const loggerPrefix = \"[Featurevisor]\";\n\nexport const defaultLogHandler: LogHandler = function defaultLogHandler(\n level,\n message,\n details = {},\n) {\n let method = \"log\";\n\n if (level === \"info\") {\n method = \"info\";\n } else if (level === \"warn\") {\n method = \"warn\";\n } else if (level === \"error\") {\n method = \"error\";\n }\n\n console[method](loggerPrefix, message, details);\n};\n\nexport class Logger {\n static allLevels: LogLevel[] = [\n \"fatal\",\n \"error\",\n \"warn\",\n \"info\",\n\n // not enabled by default\n \"debug\",\n ];\n\n static defaultLevel: LogLevel = \"info\";\n\n private level: LogLevel;\n private handle: LogHandler;\n\n constructor(options: CreateLoggerOptions) {\n this.level = options.level || Logger.defaultLevel;\n this.handle = options.handler || defaultLogHandler;\n }\n\n setLevel(level: LogLevel) {\n this.level = level;\n }\n\n log(level: LogLevel, message: LogMessage, details?: LogDetails) {\n const shouldHandle = Logger.allLevels.indexOf(this.level) >= Logger.allLevels.indexOf(level);\n\n if (!shouldHandle) {\n return;\n }\n\n this.handle(level, message, details);\n }\n\n debug(message: LogMessage, details?: LogDetails) {\n this.log(\"debug\", message, details);\n }\n\n info(message: LogMessage, details?: LogDetails) {\n this.log(\"info\", message, details);\n }\n\n warn(message: LogMessage, details?: LogDetails) {\n this.log(\"warn\", message, details);\n }\n\n error(message: LogMessage, details?: LogDetails) {\n this.log(\"error\", message, details);\n }\n}\n\nexport function createLogger(options: CreateLoggerOptions = {}): Logger {\n return new Logger(options);\n}\n","import type { BucketBy, Context, FeatureKey } from \"@featurevisor/types\";\n\nimport type { EvaluateOptions, Evaluation } from \"./evaluate\";\nimport type { Logger } from \"./logger\";\nimport type { BucketKey, BucketValue } from \"./bucketer\";\n\n/**\n * bucketKey\n */\nexport interface ConfigureBucketKeyOptions {\n featureKey: FeatureKey;\n context: Context;\n bucketBy: BucketBy;\n bucketKey: string; // the initial bucket key, which can be modified by hooks\n}\n\nexport type ConfigureBucketKey = (options: ConfigureBucketKeyOptions) => BucketKey;\n\n/**\n * bucketValue\n */\nexport interface ConfigureBucketValueOptions {\n featureKey: FeatureKey;\n bucketKey: string;\n context: Context;\n bucketValue: number; // the initial bucket value, which can be modified by hooks\n}\n\nexport type ConfigureBucketValue = (options: ConfigureBucketValueOptions) => BucketValue;\n\n/**\n * Hooks\n */\nexport interface Hook {\n name: string;\n\n before?: (options: EvaluateOptions) => EvaluateOptions;\n\n bucketKey?: ConfigureBucketKey;\n\n bucketValue?: ConfigureBucketValue;\n\n after?: (evaluation: Evaluation, options: EvaluateOptions) => Evaluation;\n}\n\nexport interface HooksManagerOptions {\n hooks?: Hook[];\n logger: Logger;\n}\n\nexport class HooksManager {\n private hooks: Hook[] = [];\n private logger: Logger;\n\n constructor(options: HooksManagerOptions) {\n this.logger = options.logger;\n\n if (options.hooks) {\n options.hooks.forEach((hook) => {\n this.add(hook);\n });\n }\n }\n\n add(hook: Hook): (() => void) | undefined {\n if (this.hooks.some((existingHook) => existingHook.name === hook.name)) {\n this.logger.error(`Hook with name \"${hook.name}\" already exists.`, {\n name: hook.name,\n hook: hook,\n });\n\n return;\n }\n\n this.hooks.push(hook);\n\n return () => {\n this.remove(hook.name);\n };\n }\n\n remove(name: string): void {\n this.hooks = this.hooks.filter((hook) => hook.name !== name);\n }\n\n getAll(): Hook[] {\n return this.hooks;\n }\n}\n","export type EventName = \"datafile_set\" | \"context_set\" | \"sticky_set\";\n\nexport type EventDetails = Record<string, unknown>;\n\nexport type EventCallback = (details: EventDetails) => void;\n\nexport type Listeners = Record<EventName, EventCallback[]> | {}; // eslint-disable-line\n\nexport class Emitter {\n listeners: Listeners;\n\n constructor() {\n this.listeners = {};\n }\n\n on(eventName: EventName, callback: EventCallback) {\n if (!this.listeners[eventName]) {\n this.listeners[eventName] = [];\n }\n\n const listeners = this.listeners[eventName];\n listeners.push(callback);\n\n let isActive = true;\n\n return function unsubscribe() {\n if (!isActive) {\n return;\n }\n\n isActive = false;\n\n const index = listeners.indexOf(callback);\n if (index !== -1) {\n listeners.splice(index, 1);\n }\n };\n }\n\n trigger(eventName: EventName, details: EventDetails = {}) {\n const listeners = this.listeners[eventName];\n\n if (!listeners) {\n return;\n }\n\n listeners.forEach(function (listener) {\n try {\n listener(details);\n } catch (err) {\n console.error(err);\n }\n });\n }\n\n clearAll() {\n this.listeners = {};\n }\n}\n","import type {\n Feature,\n Segment,\n DatafileContent,\n SegmentKey,\n FeatureKey,\n Context,\n Traffic,\n Allocation,\n GroupSegment,\n Condition,\n Force,\n} from \"@featurevisor/types\";\n\nimport { conditionIsMatched } from \"./conditions\";\nimport { Logger } from \"./logger\";\n\nexport type GetRegex = (regexString: string, regexFlags: string) => RegExp;\n\nexport interface DatafileReaderOptions {\n datafile: DatafileContent;\n logger: Logger;\n}\n\nexport interface ForceResult {\n force?: Force;\n forceIndex?: number;\n}\n\nexport class DatafileReader {\n private schemaVersion: string;\n private revision: string;\n\n private segments: Record<SegmentKey, Segment>;\n private features: Record<FeatureKey, Feature>;\n\n private logger: Logger;\n\n // done to avoid creating new RegExp objects for the same regex string and flags.\n // kept here to avoid memory leaks.\n // if datafile is reset, this cache will be cleared.\n private regexCache: Record<string, RegExp>;\n\n constructor(options: DatafileReaderOptions) {\n const { datafile, logger } = options;\n\n this.logger = logger;\n\n this.schemaVersion = datafile.schemaVersion;\n this.revision = datafile.revision;\n\n this.segments = datafile.segments;\n this.features = datafile.features;\n\n this.regexCache = {};\n }\n\n getRevision(): string {\n return this.revision;\n }\n\n getSchemaVersion(): string {\n return this.schemaVersion;\n }\n\n getSegment(segmentKey: SegmentKey): Segment | undefined {\n const segment = this.segments[segmentKey];\n\n if (!segment) {\n return undefined;\n }\n\n segment.conditions = this.parseConditionsIfStringified(segment.conditions);\n\n return segment;\n }\n\n getFeatureKeys(): string[] {\n return Object.keys(this.features);\n }\n\n getFeature(featureKey: FeatureKey): Feature | undefined {\n return this.features[featureKey];\n }\n\n getVariableKeys(featureKey: FeatureKey): string[] {\n const feature = this.getFeature(featureKey);\n\n if (!feature) {\n return [];\n }\n\n return Object.keys(feature.variablesSchema || {});\n }\n\n hasVariations(featureKey: FeatureKey): boolean {\n const feature = this.getFeature(featureKey);\n\n if (!feature) {\n return false;\n }\n\n return Array.isArray(feature.variations) && feature.variations.length > 0;\n }\n\n getRegex(regexString: string, regexFlags?: string): RegExp {\n const flags = regexFlags || \"\";\n const cacheKey = `${regexString}-${flags}`;\n\n if (this.regexCache[cacheKey]) {\n return this.regexCache[cacheKey];\n }\n\n const regex = new RegExp(regexString, flags);\n this.regexCache[cacheKey] = regex;\n\n return regex;\n }\n\n allConditionsAreMatched(conditions: Condition[] | Condition, context: Context): boolean {\n if (typeof conditions === \"string\") {\n if (conditions === \"*\") {\n return true;\n }\n\n return false;\n }\n\n const getRegex = (regexString: string, regexFlags: string) =>\n this.getRegex(regexString, regexFlags);\n\n if (\"attribute\" in conditions) {\n try {\n return conditionIsMatched(conditions, context, getRegex);\n } catch (e) {\n this.logger.warn(e.message, {\n error: e,\n details: {\n condition: conditions,\n context,\n },\n });\n\n return false;\n }\n }\n\n if (\"and\" in conditions && Array.isArray(conditions.and)) {\n return conditions.and.every((c) => this.allConditionsAreMatched(c, context));\n }\n\n if (\"or\" in conditions && Array.isArray(conditions.or)) {\n return conditions.or.some((c) => this.allConditionsAreMatched(c, context));\n }\n\n if (\"not\" in conditions && Array.isArray(conditions.not)) {\n return conditions.not.every(\n () =>\n this.allConditionsAreMatched(\n {\n and: conditions.not,\n },\n context,\n ) === false,\n );\n }\n\n if (Array.isArray(conditions)) {\n return conditions.every((c) => this.allConditionsAreMatched(c, context));\n }\n\n return false;\n }\n\n segmentIsMatched(segment: Segment, context: Context): boolean {\n return this.allConditionsAreMatched(segment.conditions as Condition | Condition[], context);\n }\n\n allSegmentsAreMatched(\n groupSegments: GroupSegment | GroupSegment[] | \"*\",\n context: Context,\n ): boolean {\n if (groupSegments === \"*\") {\n return true;\n }\n\n if (typeof groupSegments === \"string\") {\n const segment = this.getSegment(groupSegments);\n\n if (segment) {\n return this.segmentIsMatched(segment, context);\n }\n\n return false;\n }\n\n if (typeof groupSegments === \"object\") {\n if (\"and\" in groupSegments && Array.isArray(groupSegments.and)) {\n return groupSegments.and.every((groupSegment) =>\n this.allSegmentsAreMatched(groupSegment, context),\n );\n }\n\n if (\"or\" in groupSegments && Array.isArray(groupSegments.or)) {\n return groupSegments.or.some((groupSegment) =>\n this.allSegmentsAreMatched(groupSegment, context),\n );\n }\n\n if (\"not\" in groupSegments && Array.isArray(groupSegments.not)) {\n return groupSegments.not.every(\n (groupSegment) => this.allSegmentsAreMatched(groupSegment, context) === false,\n );\n }\n }\n\n if (Array.isArray(groupSegments)) {\n return groupSegments.every((groupSegment) =>\n this.allSegmentsAreMatched(groupSegment, context),\n );\n }\n\n return false;\n }\n\n getMatchedTraffic(traffic: Traffic[], context: Context): Traffic | undefined {\n return traffic.find((t) => {\n if (!this.allSegmentsAreMatched(this.parseSegmentsIfStringified(t.segments), context)) {\n return false;\n }\n\n return true;\n });\n }\n\n getMatchedAllocation(traffic: Traffic, bucketValue: number): Allocation | undefined {\n if (!traffic.allocation) {\n return undefined;\n }\n\n for (const allocation of traffic.allocation) {\n const [start, end] = allocation.range;\n\n if (allocation.range && start <= bucketValue && end >= bucketValue) {\n return allocation;\n }\n }\n\n return undefined;\n }\n\n getMatchedForce(featureKey: FeatureKey | Feature, context: Context): ForceResult {\n const result: ForceResult = {\n force: undefined,\n forceIndex: undefined,\n };\n\n const feature = typeof featureKey === \"string\" ? this.getFeature(featureKey) : featureKey;\n\n if (!feature || !feature.force) {\n return result;\n }\n\n for (let i = 0; i < feature.force.length; i++) {\n const currentForce = feature.force[i];\n\n if (\n currentForce.conditions &&\n this.allConditionsAreMatched(\n this.parseConditionsIfStringified(currentForce.conditions),\n context,\n )\n ) {\n result.force = currentForce;\n result.forceIndex = i;\n break;\n }\n\n if (\n currentForce.segments &&\n this.allSegmentsAreMatched(this.parseSegmentsIfStringified(currentForce.segments), context)\n ) {\n result.force = currentForce;\n result.forceIndex = i;\n break;\n }\n }\n\n return result;\n }\n\n parseConditionsIfStringified(conditions: Condition | Condition[]): Condition | Condition[] {\n if (typeof conditions !== \"string\") {\n // already parsed\n return conditions;\n }\n\n if (conditions === \"*\") {\n // everyone\n return conditions;\n }\n\n try {\n return JSON.parse(conditions);\n } catch (e) {\n this.logger.error(\"Error parsing conditions\", {\n error: e,\n details: {\n conditions,\n },\n });\n\n return conditions;\n }\n }\n\n parseSegmentsIfStringified(\n segments: GroupSegment | GroupSegment[],\n ): GroupSegment | GroupSegment[] {\n if (typeof segments === \"string\" && (segments.startsWith(\"{\") || segments.startsWith(\"[\"))) {\n return JSON.parse(segments);\n }\n\n return segments;\n }\n}\n","import type {\n FeatureKey,\n Context,\n RuleKey,\n Traffic,\n Force,\n Required,\n Variation,\n VariationValue,\n VariableKey,\n VariableValue,\n VariableSchema,\n EvaluatedFeature,\n StickyFeatures,\n Allocation,\n} from \"@featurevisor/types\";\n\nimport { Logger } from \"./logger\";\nimport { HooksManager } from \"./hooks\";\nimport { DatafileReader } from \"./datafileReader\";\nimport { BucketKey, BucketValue, getBucketKey, getBucketedNumber } from \"./bucketer\";\n\nexport enum EvaluationReason {\n // feature specific\n FEATURE_NOT_FOUND = \"feature_not_found\", // feature is not found in datafile\n DISABLED = \"disabled\", // feature is disabled\n REQUIRED = \"required\", // required features are not enabled\n OUT_OF_RANGE = \"out_of_range\", // out of range when mutually exclusive experiments are involved via Groups\n\n // variations specific\n NO_VARIATIONS = \"no_variations\", // feature has no variations\n VARIATION_DISABLED = \"variation_disabled\", // feature is disabled, and variation's disabledVariationValue is used\n\n // variable specific\n VARIABLE_NOT_FOUND = \"variable_not_found\", // variable's schema is not defined in the feature\n VARIABLE_DEFAULT = \"variable_default\", // default variable value used\n VARIABLE_DISABLED = \"variable_disabled\", // feature is disabled, and variable's disabledValue is used\n VARIABLE_OVERRIDE = \"variable_override\", // variable overridden from inside a variation\n\n // common\n NO_MATCH = \"no_match\", // no rules matched\n FORCED = \"forced\", // against a forced rule\n STICKY = \"sticky\", // against a sticky feature\n RULE = \"rule\", // against a regular rule\n ALLOCATED = \"allocated\", // regular allocation based on bucketing\n\n ERROR = \"error\", // error\n}\n\ntype EvaluationType = \"flag\" | \"variation\" | \"variable\";\n\nexport interface Evaluation {\n // required\n type: EvaluationType;\n featureKey: FeatureKey;\n reason: EvaluationReason;\n\n // common\n bucketKey?: BucketKey;\n bucketValue?: BucketValue;\n ruleKey?: RuleKey;\n error?: Error;\n enabled?: boolean;\n traffic?: Traffic;\n forceIndex?: number;\n force?: Force;\n required?: Required[];\n sticky?: EvaluatedFeature;\n\n // variation\n variation?: Variation;\n variationValue?: VariationValue;\n\n // variable\n variableKey?: VariableKey;\n variableValue?: VariableValue;\n variableSchema?: VariableSchema;\n}\n\nexport interface EvaluateDependencies {\n context: Context;\n\n logger: Logger;\n hooksManager: HooksManager;\n datafileReader: DatafileReader;\n\n // OverrideOptions\n sticky?: StickyFeatures;\n\n defaultVariationValue?: VariationValue;\n defaultVariableValue?: VariableValue;\n}\n\nexport interface EvaluateParams {\n type: EvaluationType;\n featureKey: FeatureKey;\n variableKey?: VariableKey;\n}\n\nexport type EvaluateOptions = EvaluateParams & EvaluateDependencies;\n\nexport function evaluateWithHooks(opts: EvaluateOptions): Evaluation {\n try {\n const { hooksManager } = opts;\n const hooks = hooksManager.getAll();\n\n // run before hooks\n let options = opts;\n for (const hook of hooksManager.getAll()) {\n if (hook.before) {\n options = hook.before(options);\n }\n }\n\n // evaluate\n let evaluation = evaluate(options);\n\n // default: variation\n if (\n typeof options.defaultVariationValue !== \"undefined\" &&\n evaluation.type === \"variation\" &&\n typeof evaluation.variationValue === \"undefined\"\n ) {\n evaluation.variationValue = options.defaultVariationValue;\n }\n\n // default: variable\n if (\n typeof options.defaultVariableValue !== \"undefined\" &&\n evaluation.type === \"variable\" &&\n typeof evaluation.variableValue === \"undefined\"\n ) {\n evaluation.variableValue = options.defaultVariableValue;\n }\n\n // run after hooks\n for (const hook of hooks) {\n if (hook.after) {\n evaluation = hook.after(evaluation, options);\n }\n }\n\n return evaluation;\n } catch (e) {\n const { type, featureKey, variableKey, logger } = opts;\n\n const evaluation: Evaluation = {\n type,\n featureKey,\n variableKey,\n reason: EvaluationReason.ERROR,\n error: e,\n };\n\n logger.error(\"error during evaluation\", evaluation);\n\n return evaluation;\n }\n}\n\nexport function evaluate(options: EvaluateOptions): Evaluation {\n const { type, featureKey, variableKey, context, logger, datafileReader, sticky, hooksManager } =\n options;\n\n const hooks = hooksManager.getAll();\n let evaluation: Evaluation;\n\n try {\n /**\n * Root flag evaluation\n */\n let flag: Evaluation;\n if (type !== \"flag\") {\n // needed by variation and variable evaluations\n flag = evaluate({\n ...options,\n type: \"flag\",\n });\n\n if (flag.enabled === false) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.DISABLED,\n };\n\n const feature = datafileReader.getFeature(featureKey);\n\n // serve variable default value if feature is disabled (if explicitly specified)\n if (type === \"variable\") {\n if (\n feature &&\n variableKey &&\n feature.variablesSchema &&\n feature.variablesSchema[variableKey]\n ) {\n const variableSchema = feature.variablesSchema[variableKey];\n\n if (typeof variableSchema.disabledValue !== \"undefined\") {\n // disabledValue: <value>\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_DISABLED,\n variableKey,\n variableValue: variableSchema.disabledValue,\n variableSchema,\n enabled: false,\n };\n } else if (variableSchema.useDefaultWhenDisabled) {\n // useDefaultWhenDisabled: true\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_DEFAULT,\n variableKey,\n variableValue: variableSchema.defaultValue,\n variableSchema,\n enabled: false,\n };\n }\n }\n }\n\n // serve disabled variation value if feature is disabled (if explicitly specified)\n if (type === \"variation\" && feature && feature.disabledVariationValue) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIATION_DISABLED,\n variationValue: feature.disabledVariationValue,\n enabled: false,\n };\n }\n\n logger.debug(\"feature is disabled\", evaluation);\n\n return evaluation;\n }\n }\n\n /**\n * Sticky\n */\n if (sticky && sticky[featureKey]) {\n // flag\n if (type === \"flag\" && typeof sticky[featureKey].enabled !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.STICKY,\n sticky: sticky[featureKey],\n enabled: sticky[featureKey].enabled,\n };\n\n logger.debug(\"using sticky enabled\", evaluation);\n\n return evaluation;\n }\n\n // variation\n if (type === \"variation\") {\n const variationValue = sticky[featureKey].variation;\n\n if (typeof variationValue !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.STICKY,\n variationValue,\n };\n\n logger.debug(\"using sticky variation\", evaluation);\n\n return evaluation;\n }\n }\n\n // variable\n if (variableKey) {\n const variables = sticky[featureKey].variables;\n\n if (variables) {\n const result = variables[variableKey];\n\n if (typeof result !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.STICKY,\n variableKey,\n variableValue: result,\n };\n\n logger.debug(\"using sticky variable\", evaluation);\n\n return evaluation;\n }\n }\n }\n }\n\n /**\n * Feature\n */\n const feature =\n typeof featureKey === \"string\" ? datafileReader.getFeature(featureKey) : featureKey;\n\n // feature: not found\n if (!feature) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.FEATURE_NOT_FOUND,\n };\n\n logger.warn(\"feature not found\", evaluation);\n\n return evaluation;\n }\n\n // feature: deprecated\n if (type === \"flag\" && feature.deprecated) {\n logger.warn(\"feature is deprecated\", { featureKey });\n }\n\n // variableSchema\n let variableSchema: VariableSchema | undefined;\n\n if (variableKey) {\n if (feature.variablesSchema && feature.variablesSchema[variableKey]) {\n variableSchema = feature.variablesSchema[variableKey];\n }\n\n // variable schema not found\n if (!variableSchema) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_NOT_FOUND,\n variableKey,\n };\n\n logger.warn(\"variable schema not found\", evaluation);\n\n return evaluation;\n }\n\n if (variableSchema.deprecated) {\n logger.warn(\"variable is deprecated\", {\n featureKey,\n variableKey,\n });\n }\n }\n\n // variation: no variations\n if (type === \"variation\" && (!feature.variations || feature.variations.length === 0)) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.NO_VARIATIONS,\n };\n\n logger.warn(\"no variations\", evaluation);\n\n return evaluation;\n }\n\n /**\n * Forced\n */\n const { force, forceIndex } = datafileReader.getMatchedForce(feature, context);\n\n if (force) {\n // flag\n if (type === \"flag\" && typeof force.enabled !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.FORCED,\n forceIndex,\n force,\n enabled: force.enabled,\n };\n\n logger.debug(\"forced enabled found\", evaluation);\n\n return evaluation;\n }\n\n // variation\n if (type === \"variation\" && force.variation && feature.variations) {\n const variation = feature.variations.find((v) => v.value === force.variation);\n\n if (variation) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.FORCED,\n forceIndex,\n force,\n variation,\n };\n\n logger.debug(\"forced variation found\", evaluation);\n\n return evaluation;\n }\n }\n\n // variable\n if (variableKey && force.variables && typeof force.variables[variableKey] !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.FORCED,\n forceIndex,\n force,\n variableKey,\n variableSchema,\n variableValue: force.variables[variableKey],\n };\n\n logger.debug(\"forced variable\", evaluation);\n\n return evaluation;\n }\n }\n\n /**\n * Required\n */\n if (type === \"flag\" && feature.required && feature.required.length > 0) {\n const requiredFeaturesAreEnabled = feature.required.every((required) => {\n let requiredKey;\n let requiredVariation;\n\n if (typeof required === \"string\") {\n requiredKey = required;\n } else {\n requiredKey = required.key;\n requiredVariation = required.variation;\n }\n\n const requiredEvaluation = evaluate({\n ...options,\n type: \"flag\",\n featureKey: requiredKey,\n });\n const requiredIsEnabled = requiredEvaluation.enabled;\n\n if (!requiredIsEnabled) {\n return false;\n }\n\n if (typeof requiredVariation !== \"undefined\") {\n const requiredVariationEvaluation = evaluate({\n ...options,\n type: \"variation\",\n featureKey: requiredKey,\n });\n\n let requiredVariationValue;\n\n if (requiredVariationEvaluation.variationValue) {\n requiredVariationValue = requiredVariationEvaluation.variationValue;\n } else if (requiredVariationEvaluation.variation) {\n requiredVariationValue = requiredVariationEvaluation.variation.value;\n }\n\n return requiredVariationValue === requiredVariation;\n }\n\n return true;\n });\n\n if (!requiredFeaturesAreEnabled) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.REQUIRED,\n required: feature.required,\n enabled: requiredFeaturesAreEnabled,\n };\n\n logger.debug(\"required features not enabled\", evaluation);\n\n return evaluation;\n }\n }\n\n /**\n * Bucketing\n */\n // bucketKey\n let bucketKey = getBucketKey({\n featureKey,\n bucketBy: feature.bucketBy,\n context,\n\n logger,\n });\n for (const hook of hooks) {\n if (hook.bucketKey) {\n bucketKey = hook.bucketKey({\n featureKey,\n context,\n bucketBy: feature.bucketBy,\n bucketKey,\n });\n }\n }\n\n // bucketValue\n let bucketValue = getBucketedNumber(bucketKey);\n\n for (const hook of hooks) {\n if (hook.bucketValue) {\n bucketValue = hook.bucketValue({\n featureKey,\n bucketKey,\n context,\n bucketValue,\n });\n }\n }\n\n let matchedTraffic: Traffic | undefined;\n let matchedAllocation: Allocation | undefined;\n\n if (type !== \"flag\") {\n matchedTraffic = datafileReader.getMatchedTraffic(feature.traffic, context);\n\n if (matchedTraffic) {\n matchedAllocation = datafileReader.getMatchedAllocation(matchedTraffic, bucketValue);\n }\n } else {\n matchedTraffic = datafileReader.getMatchedTraffic(feature.traffic, context);\n }\n\n if (matchedTraffic) {\n // percentage: 0\n if (matchedTraffic.percentage === 0) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n enabled: false,\n };\n\n logger.debug(\"matched rule with 0 percentage\", evaluation);\n\n return evaluation;\n }\n\n // flag\n if (type === \"flag\") {\n // flag: check if mutually exclusive\n if (feature.ranges && feature.ranges.length > 0) {\n const matchedRange = feature.ranges.find((range) => {\n return bucketValue >= range[0] && bucketValue < range[1];\n });\n\n // matched\n if (matchedRange) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.ALLOCATED,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n enabled:\n typeof matchedTraffic.enabled === \"undefined\" ? true : matchedTraffic.enabled,\n };\n\n logger.debug(\"matched\", evaluation);\n\n return evaluation;\n }\n\n // no match\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.OUT_OF_RANGE,\n bucketKey,\n bucketValue,\n enabled: false,\n };\n\n logger.debug(\"not matched\", evaluation);\n\n return evaluation;\n }\n\n // flag: override from rule\n if (typeof matchedTraffic.enabled !== \"undefined\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n enabled: matchedTraffic.enabled,\n };\n\n logger.debug(\"override from rule\", evaluation);\n\n return evaluation;\n }\n\n // treated as enabled because of matched traffic\n if (bucketValue <= matchedTraffic.percentage) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n enabled: true,\n };\n\n logger.debug(\"matched traffic\", evaluation);\n\n return evaluation;\n }\n }\n\n // variation\n if (type === \"variation\" && feature.variations) {\n // override from rule\n if (matchedTraffic.variation) {\n const variation = feature.variations.find((v) => v.value === matchedTraffic.variation);\n\n if (variation) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n variation,\n };\n\n logger.debug(\"override from rule\", evaluation);\n\n return evaluation;\n }\n }\n\n // regular allocation\n if (matchedAllocation && matchedAllocation.variation) {\n const variation = feature.variations.find((v) => v.value === matchedAllocation.variation);\n\n if (variation) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.ALLOCATED,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n variation,\n };\n\n logger.debug(\"allocated variation\", evaluation);\n\n return evaluation;\n }\n }\n }\n }\n\n // variable\n if (type === \"variable\" && variableKey) {\n // override from rule\n if (\n matchedTraffic &&\n matchedTraffic.variables &&\n typeof matchedTraffic.variables[variableKey] !== \"undefined\"\n ) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.RULE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic.key,\n traffic: matchedTraffic,\n variableKey,\n variableSchema,\n variableValue: matchedTraffic.variables[variableKey],\n };\n\n logger.debug(\"override from rule\", evaluation);\n\n return evaluation;\n }\n\n // check variations\n let variationValue;\n\n if (force && force.variation) {\n variationValue = force.variation;\n } else if (matchedTraffic && matchedTraffic.variation) {\n variationValue = matchedTraffic.variation;\n } else if (matchedAllocation && matchedAllocation.variation) {\n variationValue = matchedAllocation.variation;\n }\n\n if (variationValue && Array.isArray(feature.variations)) {\n const variation = feature.variations.find((v) => v.value === variationValue);\n\n if (variation && variation.variableOverrides && variation.variableOverrides[variableKey]) {\n const overrides = variation.variableOverrides[variableKey];\n\n const override = overrides.find((o) => {\n if (o.conditions) {\n return datafileReader.allConditionsAreMatched(\n typeof o.conditions === \"string\" && o.conditions !== \"*\"\n ? JSON.parse(o.conditions)\n : o.conditions,\n context,\n );\n }\n\n if (o.segments) {\n return datafileReader.allSegmentsAreMatched(\n datafileReader.parseSegmentsIfStringified(o.segments),\n context,\n );\n }\n\n return false;\n });\n\n if (override) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_OVERRIDE,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic?.key,\n traffic: matchedTraffic,\n variableKey,\n variableSchema,\n variableValue: override.value,\n };\n\n logger.debug(\"variable override\", evaluation);\n\n return evaluation;\n }\n }\n\n if (\n variation &&\n variation.variables &&\n typeof variation.variables[variableKey] !== \"undefined\"\n ) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.ALLOCATED,\n bucketKey,\n bucketValue,\n ruleKey: matchedTraffic?.key,\n traffic: matchedTraffic,\n variableKey,\n variableSchema,\n variableValue: variation.variables[variableKey],\n };\n\n logger.debug(\"allocated variable\", evaluation);\n\n return evaluation;\n }\n }\n }\n\n /**\n * Nothing matched\n */\n if (type === \"variation\") {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.NO_MATCH,\n bucketKey,\n bucketValue,\n };\n\n logger.debug(\"no matched variation\", evaluation);\n\n return evaluation;\n }\n\n if (type === \"variable\") {\n if (variableSchema) {\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_DEFAULT,\n bucketKey,\n bucketValue,\n variableKey,\n variableSchema,\n variableValue: variableSchema.defaultValue,\n };\n\n logger.debug(\"using default value\", evaluation);\n\n return evaluation;\n }\n\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.VARIABLE_NOT_FOUND,\n variableKey,\n bucketKey,\n bucketValue,\n };\n\n logger.debug(\"variable not found\", evaluation);\n\n return evaluation;\n }\n\n evaluation = {\n type,\n featureKey,\n reason: EvaluationReason.NO_MATCH,\n bucketKey,\n bucketValue,\n enabled: false,\n };\n\n logger.debug(\"nothing matched\", evaluation);\n\n return evaluation;\n } catch (e) {\n evaluation = {\n type,\n featureKey,\n variableKey,\n reason: EvaluationReason.ERROR,\n error: e,\n };\n\n logger.error(\"error\", evaluation);\n\n return evaluation;\n }\n}\n","import type { StickyFeatures, FeatureKey } from \"@featurevisor/types\";\n\nimport type { EventDetails } from \"./emitter\";\nimport type { DatafileReader } from \"./datafileReader\";\n\nexport function getParamsForStickySetEvent(\n previousStickyFeatures: StickyFeatures = {},\n newStickyFeatures: StickyFeatures = {},\n replace,\n): EventDetails {\n const keysBefore = Object.keys(previousStickyFeatures);\n const keysAfter = Object.keys(newStickyFeatures);\n\n const allKeys = [...keysBefore, ...keysAfter];\n const uniqueFeaturesAffected = allKeys.filter(\n (element, index) => allKeys.indexOf(element) === index,\n );\n\n return {\n features: uniqueFeaturesAffected,\n replaced: replace,\n };\n}\n\nexport function getParamsForDatafileSetEvent(\n previousDatafileReader: DatafileReader,\n newDatafileReader: DatafileReader,\n): EventDetails {\n const previousRevision = previousDatafileReader.getRevision();\n const previousFeatureKeys = previousDatafileReader.getFeatureKeys();\n\n const newRevision = newDatafileReader.getRevision();\n const newFeatureKeys = newDatafileReader.getFeatureKeys();\n\n // results\n const removedFeatures: FeatureKey[] = [];\n const changedFeatures: FeatureKey[] = [];\n const addedFeatures: FeatureKey[] = [];\n\n // checking against existing datafile\n for (const previousFeatureKey of previousFeatureKeys) {\n if (newFeatureKeys.indexOf(previousFeatureKey) === -1) {\n // feature was removed in new datafile\n removedFeatures.push(previousFeatureKey);\n\n continue;\n }\n\n // feature exists in both datafiles, check if it was changed\n const previousFeature = previousDatafileReader.getFeature(previousFeatureKey);\n const newFeature = newDatafileReader.getFeature(previousFeatureKey);\n\n if (previousFeature?.hash !== newFeature?.hash) {\n // feature was changed in new datafile\n changedFeatures.push(previousFeatureKey);\n }\n }\n\n // checking against new datafile\n for (const newFeatureKey of newFeatureKeys) {\n if (previousFeatureKeys.indexOf(newFeatureKey) === -1) {\n // feature was added in new datafile\n addedFeatures.push(newFeatureKey);\n }\n }\n\n // combine all affected feature keys\n const allAffectedFeatures: FeatureKey[] = [\n ...removedFeatures,\n ...changedFeatures,\n ...addedFeatures,\n ].filter((element, index, array) => array.indexOf(element) === index);\n\n const details = {\n revision: newRevision,\n previousRevision,\n revisionChanged: previousRevision !== newRevision,\n\n features: allAffectedFeatures,\n };\n\n return details;\n}\n","import type {\n Context,\n StickyFeatures,\n FeatureKey,\n VariationValue,\n VariableValue,\n EvaluatedFeatures,\n} from \"@featurevisor/types\";\n\nimport { EventName, EventCallback, Emitter } from \"./emitter\";\nimport type { FeaturevisorInstance, OverrideOptions } from \"./instance\";\nimport { getParamsForStickySetEvent } from \"./events\";\n\nexport class FeaturevisorChildInstance {\n private parent: FeaturevisorInstance;\n private context: Context;\n private sticky: StickyFeatures;\n private emitter: Emitter;\n\n constructor(options) {\n this.parent = options.parent;\n this.context = options.context;\n this.sticky = options.sticky || {};\n this.emitter = new Emitter();\n }\n\n on(eventName: EventName, callback: EventCallback) {\n if (eventName === \"context_set\" || eventName === \"sticky_set\") {\n return this.emitter.on(eventName, callback);\n }\n\n return this.parent.on(eventName, callback);\n }\n\n close() {\n this.emitter.clearAll();\n }\n\n setContext(context: Context, replace = false) {\n if (replace) {\n this.context = context;\n } else {\n this.context = { ...this.context, ...context };\n }\n\n this.emitter.trigger(\"context_set\", {\n context: this.context,\n replaced: replace,\n });\n }\n\n getContext(context?: Context): Context {\n return this.parent.getContext({\n ...this.context,\n ...context,\n });\n }\n\n setSticky(sticky: StickyFeatures, replace = false) {\n const previousStickyFeatures = this.sticky || {};\n\n if (replace) {\n this.sticky = { ...sticky };\n } else {\n this.sticky = {\n ...this.sticky,\n ...sticky,\n };\n }\n\n const params = getParamsForStickySetEvent(previousStickyFeatures, this.sticky, replace);\n\n this.emitter.trigger(\"sticky_set\", params);\n }\n\n isEnabled(featureKey: FeatureKey, context: Context = {}, options: OverrideOptions = {}): boolean {\n return this.parent.isEnabled(\n featureKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariation(\n featureKey: FeatureKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): VariationValue | null {\n return this.parent.getVariation(\n featureKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariable(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): VariableValue | null {\n return this.parent.getVariable(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableBoolean(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): boolean | null {\n return this.parent.getVariableBoolean(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableString(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): string | null {\n return this.parent.getVariableString(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableInteger(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): number | null {\n return this.parent.getVariableInteger(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableDouble(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): number | null {\n return this.parent.getVariableDouble(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableArray<T = string>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T[] | null {\n return this.parent.getVariableArray<T>(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableObject<T>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T | null {\n return this.parent.getVariableObject<T>(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getVariableJSON<T>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T | null {\n return this.parent.getVariableJSON<T>(\n featureKey,\n variableKey,\n {\n ...this.context,\n ...context,\n },\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n\n getAllEvaluations(\n context: Context = {},\n featureKeys: string[] = [],\n options: OverrideOptions = {},\n ): EvaluatedFeatures {\n return this.parent.getAllEvaluations(\n {\n ...this.context,\n ...context,\n },\n featureKeys,\n {\n sticky: this.sticky,\n ...options,\n },\n );\n }\n}\n","import type { VariableType, VariableValue } from \"@featurevisor/types\";\n\ntype FieldType = string | VariableType;\nexport type ValueType = VariableValue;\n\nexport function getValueByType(value: ValueType, fieldType: FieldType): ValueType {\n if (value === undefined) {\n return null;\n }\n\n switch (fieldType) {\n case \"string\":\n return typeof value === \"string\" ? value : null;\n case \"integer\":\n return parseInt(value as string, 10);\n case \"double\":\n return parseFloat(value as string);\n case \"boolean\":\n return value === true;\n case \"array\":\n return Array.isArray(value) ? value : null;\n case \"object\":\n return typeof value === \"object\" ? value : null;\n // @NOTE: `json` is not handled here intentionally\n default:\n return value;\n }\n}\n","import type {\n Context,\n Feature,\n FeatureKey,\n StickyFeatures,\n EvaluatedFeatures,\n EvaluatedFeature,\n VariableValue,\n VariationValue,\n VariableKey,\n DatafileContent,\n} from \"@featurevisor/types\";\n\nimport { createLogger, Logger, LogLevel } from \"./logger\";\nimport { HooksManager, Hook } from \"./hooks\";\nimport { Emitter, EventCallback, EventName } from \"./emitter\";\nimport { DatafileReader } from \"./datafileReader\";\nimport { Evaluation, EvaluateDependencies, evaluateWithHooks } from \"./evaluate\";\nimport { FeaturevisorChildInstance } from \"./child\";\nimport { getParamsForStickySetEvent, getParamsForDatafileSetEvent } from \"./events\";\nimport { getValueByType } from \"./helpers\";\n\nconst emptyDatafile: DatafileContent = {\n schemaVersion: \"2\",\n revision: \"unknown\",\n segments: {},\n features: {},\n};\n\nexport interface OverrideOptions {\n sticky?: StickyFeatures;\n\n defaultVariationValue?: VariationValue;\n defaultVariableValue?: VariableValue;\n}\n\nexport interface InstanceOptions {\n datafile?: DatafileContent | string;\n context?: Context;\n logLevel?: LogLevel;\n logger?: Logger;\n sticky?: StickyFeatures;\n hooks?: Hook[];\n}\n\nexport class FeaturevisorInstance {\n // from options\n private context: Context = {};\n private logger: Logger;\n private sticky?: StickyFeatures;\n\n // internally created\n private datafileReader: DatafileReader;\n private hooksManager: HooksManager;\n private emitter: Emitter;\n\n constructor(options: InstanceOptions) {\n // from options\n this.context = options.context || {};\n this.logger =\n options.logger ||\n createLogger({\n level: options.logLevel || Logger.defaultLevel,\n });\n this.hooksManager = new HooksManager({\n hooks: options.hooks || [],\n logger: this.logger,\n });\n this.emitter = new Emitter();\n this.sticky = options.sticky;\n\n // datafile\n this.datafileReader = new DatafileReader({\n datafile: emptyDatafile,\n logger: this.logger,\n });\n if (options.datafile) {\n this.datafileReader = new DatafileReader({\n datafile:\n typeof options.datafile === \"string\" ? JSON.parse(options.datafile) : options.datafile,\n logger: this.logger,\n });\n }\n\n this.logger.info(\"Featurevisor SDK initialized\");\n }\n\n setLogLevel(level: LogLevel) {\n this.logger.setLevel(level);\n }\n\n setDatafile(datafile: DatafileContent | string) {\n try {\n const newDatafileReader = new DatafileReader({\n datafile: typeof datafile === \"string\" ? JSON.parse(datafile) : datafile,\n logger: this.logger,\n });\n\n const details = getParamsForDatafileSetEvent(this.datafileReader, newDatafileReader);\n\n this.datafileReader = newDatafileReader;\n\n this.logger.info(\"datafile set\", details);\n this.emitter.trigger(\"datafile_set\", details);\n } catch (e) {\n this.logger.error(\"could not parse datafile\", { error: e });\n }\n }\n\n setSticky(sticky: StickyFeatures, replace = false) {\n const previousStickyFeatures = this.sticky || {};\n\n if (replace) {\n this.sticky = { ...sticky };\n } else {\n this.sticky = {\n ...this.sticky,\n ...sticky,\n };\n }\n\n const params = getParamsForStickySetEvent(previousStickyFeatures, this.sticky, replace);\n\n this.logger.info(\"sticky features set\", params);\n this.emitter.trigger(\"sticky_set\", params);\n }\n\n getRevision(): string {\n return this.datafileReader.getRevision();\n }\n\n getFeature(featureKey: string): Feature | undefined {\n return this.datafileReader.getFeature(featureKey);\n }\n\n addHook(hook: Hook) {\n return this.hooksManager.add(hook);\n }\n\n on(eventName: EventName, callback: EventCallback) {\n return this.emitter.on(eventName, callback);\n }\n\n close() {\n this.emitter.clearAll();\n }\n\n /**\n * Context\n */\n setContext(context: Context, replace = false) {\n if (replace) {\n this.context = context;\n } else {\n this.context = { ...this.context, ...context };\n }\n\n this.emitter.trigger(\"context_set\", {\n context: this.context,\n replaced: replace,\n });\n this.logger.debug(replace ? \"context replaced\" : \"context updated\", {\n context: this.context,\n replaced: replace,\n });\n }\n\n getContext(context?: Context): Context {\n return context\n ? {\n ...this.context,\n ...context,\n }\n : this.context;\n }\n\n spawn(context: Context = {}, options: OverrideOptions = {}): FeaturevisorChildInstance {\n return new FeaturevisorChildInstance({\n parent: this,\n context: this.getContext(context),\n sticky: options.sticky,\n });\n }\n\n /**\n * Flag\n */\n private getEvaluationDependencies(\n context: Context,\n options: OverrideOptions = {},\n ): EvaluateDependencies {\n return {\n context: this.getContext(context),\n\n logger: this.logger,\n hooksManager: this.hooksManager,\n datafileReader: this.datafileReader,\n\n // OverrideOptions\n sticky: options.sticky\n ? {\n ...this.sticky,\n ...options.sticky,\n }\n : this.sticky,\n defaultVariationValue: options.defaultVariationValue,\n defaultVariableValue: options.defaultVariableValue,\n };\n }\n\n evaluateFlag(\n featureKey: FeatureKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): Evaluation {\n return evaluateWithHooks({\n ...this.getEvaluationDependencies(context, options),\n type: \"flag\",\n featureKey,\n });\n }\n\n isEnabled(featureKey: FeatureKey, context: Context = {}, options: OverrideOptions = {}): boolean {\n try {\n const evaluation = this.evaluateFlag(featureKey, context, options);\n\n return evaluation.enabled === true;\n } catch (e) {\n this.logger.error(\"isEnabled\", { featureKey, error: e });\n\n return false;\n }\n }\n\n /**\n * Variation\n */\n evaluateVariation(\n featureKey: FeatureKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): Evaluation {\n return evaluateWithHooks({\n ...this.getEvaluationDependencies(context, options),\n type: \"variation\",\n featureKey,\n });\n }\n\n getVariation(\n featureKey: FeatureKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): VariationValue | null {\n try {\n const evaluation = this.evaluateVariation(featureKey, context, options);\n\n if (typeof evaluation.variationValue !== \"undefined\") {\n return evaluation.variationValue;\n }\n\n if (evaluation.variation) {\n return evaluation.variation.value;\n }\n\n return null;\n } catch (e) {\n this.logger.error(\"getVariation\", { featureKey, error: e });\n\n return null;\n }\n }\n\n /**\n * Variable\n */\n evaluateVariable(\n featureKey: FeatureKey,\n variableKey: VariableKey,\n context: Context = {},\n options: OverrideOptions = {},\n ): Evaluation {\n return evaluateWithHooks({\n ...this.getEvaluationDependencies(context, options),\n type: \"variable\",\n featureKey,\n variableKey,\n });\n }\n\n getVariable(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): VariableValue | null {\n try {\n const evaluation = this.evaluateVariable(featureKey, variableKey, context, options);\n\n if (typeof evaluation.variableValue !== \"undefined\") {\n if (\n evaluation.variableSchema &&\n evaluation.variableSchema.type === \"json\" &&\n typeof evaluation.variableValue === \"string\"\n ) {\n return JSON.parse(evaluation.variableValue);\n }\n\n return evaluation.variableValue;\n }\n\n return null;\n } catch (e) {\n this.logger.error(\"getVariable\", { featureKey, variableKey, error: e });\n\n return null;\n }\n }\n\n getVariableBoolean(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): boolean | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"boolean\") as boolean | null;\n }\n\n getVariableString(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): string | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"string\") as string | null;\n }\n\n getVariableInteger(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): number | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"integer\") as number | null;\n }\n\n getVariableDouble(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): number | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"double\") as number | null;\n }\n\n getVariableArray<T = string>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T[] | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"array\") as T[] | null;\n }\n\n getVariableObject<T>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"object\") as T | null;\n }\n\n getVariableJSON<T>(\n featureKey: FeatureKey,\n variableKey: string,\n context: Context = {},\n options: OverrideOptions = {},\n ): T | null {\n const variableValue = this.getVariable(featureKey, variableKey, context, options);\n\n return getValueByType(variableValue, \"json\") as T | null;\n }\n\n getAllEvaluations(\n context: Context = {},\n featureKeys: string[] = [],\n options: OverrideOptions = {},\n ): EvaluatedFeatures {\n const result: EvaluatedFeatures = {};\n\n const keys = featureKeys.length > 0 ? featureKeys : this.datafileReader.getFeatureKeys();\n for (const featureKey of keys) {\n // isEnabled\n const evaluatedFeature: EvaluatedFeature = {\n enabled: this.isEnabled(featureKey, context, options),\n };\n\n // variation\n if (this.datafileReader.hasVariations(featureKey)) {\n const variation = this.getVariation(featureKey, context, options);\n\n if (variation) {\n evaluatedFeature.variation = variation;\n }\n }\n\n // variables\n const variableKeys = this.datafileReader.getVariableKeys(featureKey);\n if (variableKeys.length > 0) {\n evaluatedFeature.variables = {};\n\n for (const variableKey of variableKeys) {\n evaluatedFeature.variables[variableKey] = this.getVariable(\n featureKey,\n variableKey,\n context,\n options,\n );\n }\n }\n\n result[featureKey] = evaluatedFeature;\n }\n\n return result;\n }\n}\n\nexport function createInstance(options: InstanceOptions = {}): FeaturevisorInstance {\n return new FeaturevisorInstance(options);\n}\n"],"names":["semver","validateAndParse","version","TypeError","match","Error","shift","isWildcard","s","tryParse","v","n","parseInt","isNaN","compareStrings","a","b","ap","bp","String","forceType","compareSegments","i","Math","max","length","r","compareVersions","v1","v2","n1","n2","p1","pop","p2","split","getValueFromContext","obj","path","indexOf","reduce","o","undefined","conditionIsMatched","condition","context","getRegex","attribute","operator","value","regexFlags","contextValueFromPath","dateInContext","Date","dateInCondition","Array","isArray","valueInContext","startsWith","endsWith","test","MAX_HASH_VALUE","pow","MAX_BUCKETED_NUMBER","getBucketedNumber","bucketKey","ratio","key","seed","val","remainder","bytes","h1","h1b","c1","c2","k1","TextEncoder","encode","MurmurHashV3","floor","getBucketKey","options","featureKey","bucketBy","logger","type","attributeKeys","or","error","forEach","attributeKey","attributeValue","push","join","loggerPrefix","defaultLogHandler","level","message","details","method","console","Logger","constructor","this","defaultLevel","handle","handler","setLevel","log","allLevels","debug","info","warn","createLogger","HooksManager","hooks","hook","add","some","existingHook","name","remove","filter","getAll","Emitter","listeners","on","eventName","callback","isActive","index","splice","trigger","listener","err","clearAll","DatafileReader","datafile","schemaVersion","revision","segments","features","regexCache","getRevision","getSchemaVersion","getSegment","segmentKey","segment","conditions","parseConditionsIfStringified","getFeatureKeys","Object","keys","getFeature","getVariableKeys","feature","variablesSchema","hasVariations","variations","regexString","flags","cacheKey","regex","RegExp","allConditionsAreMatched","e","and","every","c","not","segmentIsMatched","allSegmentsAreMatched","groupSegments","groupSegment","getMatchedTraffic","traffic","find","t","parseSegmentsIfStringified","getMatchedAllocation","bucketValue","allocation","start","end","range","getMatchedForce","result","force","forceIndex","currentForce","JSON","parse","EvaluationReason","evaluateWithHooks","opts","hooksManager","before","evaluation","evaluate","defaultVariationValue","variationValue","defaultVariableValue","variableValue","after","variableKey","reason","ERROR","datafileReader","sticky","flag","enabled","DISABLED","variableSchema","disabledValue","VARIABLE_DISABLED","useDefaultWhenDisabled","VARIABLE_DEFAULT","defaultValue","disabledVariationValue","VARIATION_DISABLED","STICKY","variation","variables","FEATURE_NOT_FOUND","deprecated","VARIABLE_NOT_FOUND","NO_VARIATIONS","FORCED","required","requiredFeaturesAreEnabled","requiredKey","requiredVariation","requiredVariationEvaluation","requiredVariationValue","REQUIRED","matchedTraffic","matchedAllocation","percentage","RULE","ruleKey","ranges","ALLOCATED","OUT_OF_RANGE","variableOverrides","override","VARIABLE_OVERRIDE","NO_MATCH","getParamsForStickySetEvent","previousStickyFeatures","newStickyFeatures","replace","allKeys","element","replaced","FeaturevisorChildInstance","parent","emitter","close","setContext","getContext","setSticky","params","isEnabled","getVariation","getVariable","getVariableBoolean","getVariableString","getVariableInteger","getVariableDouble","getVariableArray","getVariableObject","getVariableJSON","getAllEvaluations","featureKeys","getValueByType","fieldType","parseFloat","emptyDatafile","FeaturevisorInstance","logLevel","setLogLevel","setDatafile","newDatafileReader","previousDatafileReader","previousRevision","previousFeatureKeys","newRevision","newFeatureKeys","removedFeatures","changedFeatures","addedFeatures","previousFeatureKey","previousFeature","newFeature","hash","newFeatureKey","revisionChanged","array","getParamsForDatafileSetEvent","addHook","spawn","getEvaluationDependencies","evaluateFlag","evaluateVariation","evaluateVariable","evaluatedFeature","variableKeys","createInstance"],"sourceRoot":""}
@@ -59,7 +59,7 @@ export declare class FeaturevisorInstance {
59
59
  getVariableString(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string | null;
60
60
  getVariableInteger(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
61
61
  getVariableDouble(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
62
- getVariableArray(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string[] | null;
62
+ getVariableArray<T = string>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T[] | null;
63
63
  getVariableObject<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
64
64
  getVariableJSON<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
65
65
  getAllEvaluations(context?: Context, featureKeys?: string[], options?: OverrideOptions): EvaluatedFeatures;
package/lib/child.d.ts CHANGED
@@ -19,7 +19,7 @@ export declare class FeaturevisorChildInstance {
19
19
  getVariableString(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string | null;
20
20
  getVariableInteger(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
21
21
  getVariableDouble(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
22
- getVariableArray(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string[] | null;
22
+ getVariableArray<T = string>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T[] | null;
23
23
  getVariableObject<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
24
24
  getVariableJSON<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
25
25
  getAllEvaluations(context?: Context, featureKeys?: string[], options?: OverrideOptions): EvaluatedFeatures;
package/lib/instance.d.ts CHANGED
@@ -59,7 +59,7 @@ export declare class FeaturevisorInstance {
59
59
  getVariableString(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string | null;
60
60
  getVariableInteger(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
61
61
  getVariableDouble(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): number | null;
62
- getVariableArray(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): string[] | null;
62
+ getVariableArray<T = string>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T[] | null;
63
63
  getVariableObject<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
64
64
  getVariableJSON<T>(featureKey: FeatureKey, variableKey: string, context?: Context, options?: OverrideOptions): T | null;
65
65
  getAllEvaluations(context?: Context, featureKeys?: string[], options?: OverrideOptions): EvaluatedFeatures;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@featurevisor/sdk",
3
- "version": "2.6.7",
3
+ "version": "2.10.0",
4
4
  "description": "Featurevisor SDK for Node.js and the browser",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.mjs",
@@ -49,7 +49,7 @@
49
49
  },
50
50
  "license": "MIT",
51
51
  "dependencies": {
52
- "@featurevisor/types": "2.6.7"
52
+ "@featurevisor/types": "2.10.0"
53
53
  },
54
- "gitHead": "369725e89e88f886a88bf52c22d55961bf04e9f6"
54
+ "gitHead": "0cbe15fb45fd08ebd70125f1604ae7fe7e20756a"
55
55
  }
package/src/child.ts CHANGED
@@ -205,13 +205,13 @@ export class FeaturevisorChildInstance {
205
205
  );
206
206
  }
207
207
 
208
- getVariableArray(
208
+ getVariableArray<T = string>(
209
209
  featureKey: FeatureKey,
210
210
  variableKey: string,
211
211
  context: Context = {},
212
212
  options: OverrideOptions = {},
213
- ): string[] | null {
214
- return this.parent.getVariableArray(
213
+ ): T[] | null {
214
+ return this.parent.getVariableArray<T>(
215
215
  featureKey,
216
216
  variableKey,
217
217
  {