New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@featurevisor/sdk

Package Overview
Dependencies
Maintainers
1
Versions
115
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@featurevisor/sdk - npm Package Compare versions

Comparing version 0.36.0 to 0.37.0

11

CHANGELOG.md

@@ -6,2 +6,13 @@ # Change Log

# [0.37.0](https://github.com/fahad19/featurevisor/compare/v0.36.0...v0.37.0) (2023-07-14)
### Features
* renamed Attributes (object) to Context ([#101](https://github.com/fahad19/featurevisor/issues/101)) ([c392ad5](https://github.com/fahad19/featurevisor/commit/c392ad5f1b6100167aa5637b131f08036a7f5a55))
# [0.36.0](https://github.com/fahad19/featurevisor/compare/v0.35.0...v0.36.0) (2023-07-13)

@@ -8,0 +19,0 @@

2

dist/index.js

@@ -1,2 +0,2 @@

!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FeaturevisorSDK=t():e.FeaturevisorSDK=t()}(this,(()=>(()=>{var e={480:(e,t,r)=>{"use strict";r.r(t),r.d(t,{compare:()=>n,compareVersions:()=>i,satisfies:()=>o,validate:()=>a});const i=(e,t)=>{const r=u(e),i=u(t),a=r.pop(),n=i.pop(),o=d(r,i);return 0!==o?o:a&&n?d(a.split("."),n.split(".")):a||n?a?-1:1:0},a=e=>"string"==typeof e&&/^[v\d]/.test(e)&&s.test(e),n=(e,t,r)=>{g(r);const a=i(e,t);return v[r].includes(a)},o=(e,t)=>{if(t.includes("||"))return t.split("||").some((t=>o(e,t)));if(t.includes(" "))return t.trim().replace(/\s{2,}/g," ").split(" ").every((t=>o(e,t)));const r=t.match(/^([<>=~^]+)/),i=r?r[1]:"=";if("^"!==i&&"~"!==i)return n(e,t,i);const[a,s,l,,f]=u(e),[c,v,h,,g]=u(t),y=[a,s,l],p=[c,null!=v?v:"x",null!=h?h:"x"];if(g){if(!f)return!1;if(0!==d(y,p))return!1;if(-1===d(f.split("."),g.split(".")))return!1}const b=p.findIndex((e=>"0"!==e))+1,m="~"===i?2:b>1?b:1;return 0===d(y.slice(0,m),p.slice(0,m))&&-1!==d(y.slice(m),p.slice(m))},s=/^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i,u=e=>{if("string"!=typeof e)throw new TypeError("Invalid argument expected string");const t=e.match(s);if(!t)throw new Error(`Invalid argument not valid semver ('${e}' received)`);return t.shift(),t},l=e=>"*"===e||"x"===e||"X"===e,f=e=>{const t=parseInt(e,10);return isNaN(t)?e:t},c=(e,t)=>{if(l(e)||l(t))return 0;const[r,i]=((e,t)=>typeof e!=typeof t?[String(e),String(t)]:[e,t])(f(e),f(t));return r>i?1:r<i?-1:0},d=(e,t)=>{for(let r=0;r<Math.max(e.length,t.length);r++){const i=c(e[r]||"0",t[r]||"0");if(0!==i)return i}return 0},v={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]},h=Object.keys(v),g=e=>{if("string"!=typeof e)throw new TypeError("Invalid operator type, expected string but got "+typeof e);if(-1===h.indexOf(e))throw new Error(`Invalid operator, expected one of ${h.join("|")}`)}},77:e=>{!function(){const t=e=>(new TextEncoder).encode(e);function r(e,r){let i,a,n,o,s,u,l,f;for("string"==typeof e&&(e=t(e)),i=3&e.length,a=e.length-i,n=r,s=3432918353,u=461845907,f=0;f<a;)l=255&e[f]|(255&e[++f])<<8|(255&e[++f])<<16|(255&e[++f])<<24,++f,l=(65535&l)*s+(((l>>>16)*s&65535)<<16)&4294967295,l=l<<15|l>>>17,l=(65535&l)*u+(((l>>>16)*u&65535)<<16)&4294967295,n^=l,n=n<<13|n>>>19,o=5*(65535&n)+((5*(n>>>16)&65535)<<16)&4294967295,n=27492+(65535&o)+((58964+(o>>>16)&65535)<<16);switch(l=0,i){case 3:l^=(255&e[f+2])<<16;case 2:l^=(255&e[f+1])<<8;case 1:l^=255&e[f],l=(65535&l)*s+(((l>>>16)*s&65535)<<16)&4294967295,l=l<<15|l>>>17,l=(65535&l)*u+(((l>>>16)*u&65535)<<16)&4294967295,n^=l}return n^=e.length,n^=n>>>16,n=2246822507*(65535&n)+((2246822507*(n>>>16)&65535)<<16)&4294967295,n^=n>>>13,n=3266489909*(65535&n)+((3266489909*(n>>>16)&65535)<<16)&4294967295,n^=n>>>16,n>>>0}const i=r;i.v2=function(e,r){"string"==typeof e&&(e=t(e));let i,a=e.length,n=r^a,o=0;for(;a>=4;)i=255&e[o]|(255&e[++o])<<8|(255&e[++o])<<16|(255&e[++o])<<24,i=1540483477*(65535&i)+((1540483477*(i>>>16)&65535)<<16),i^=i>>>24,i=1540483477*(65535&i)+((1540483477*(i>>>16)&65535)<<16),n=1540483477*(65535&n)+((1540483477*(n>>>16)&65535)<<16)^i,a-=4,++o;switch(a){case 3:n^=(255&e[o+2])<<16;case 2:n^=(255&e[o+1])<<8;case 1:n^=255&e[o],n=1540483477*(65535&n)+((1540483477*(n>>>16)&65535)<<16)}return n^=n>>>13,n=1540483477*(65535&n)+((1540483477*(n>>>16)&65535)<<16),n^=n>>>15,n>>>0},i.v3=r,e.exports=i}()},725:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getBucketedNumber=t.MAX_BUCKETED_NUMBER=void 0;var i=r(77),a=Math.pow(2,32);t.MAX_BUCKETED_NUMBER=1e5,t.getBucketedNumber=function(e){var r=i.v3(e,1)/a;return Math.floor(r*t.MAX_BUCKETED_NUMBER)}},243:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.allConditionsAreMatched=t.conditionIsMatched=void 0;var i=r(480);function a(e,t){var r=e.attribute,a=e.operator,n=e.value;if("equals"===a)return t[r]===n;if("notEquals"===a)return t[r]!==n;if("before"===a||"after"===a){var o=(u=t[r])instanceof Date?u:new Date(u),s=n instanceof Date?n:new Date(n);return"before"===a?o<s:o>s}if("string"==typeof t[r]&&Array.isArray(n)){var u=t[r];if("in"===a)return-1!==n.indexOf(u);if("notIn"===a)return-1===n.indexOf(u)}else if("string"==typeof t[r]&&"string"==typeof n){if(u=t[r],"contains"===a)return-1!==u.indexOf(n);if("notContains"===a)return-1===u.indexOf(n);if("startsWith"===a)return u.startsWith(n);if("endsWith"===a)return u.endsWith(n);if("semverEquals"===a)return 0===(0,i.compareVersions)(u,n);if("semverNotEquals"===a)return 0!==(0,i.compareVersions)(u,n);if("semverGreaterThan"===a)return 1===(0,i.compareVersions)(u,n);if("semverGreaterThanOrEquals"===a)return(0,i.compareVersions)(u,n)>=0;if("semverLessThan"===a)return-1===(0,i.compareVersions)(u,n);if("semverLessThanOrEquals"===a)return(0,i.compareVersions)(u,n)<=0}else if("number"==typeof t[r]&&"number"==typeof n){if(u=t[r],"greaterThan"===a)return u>n;if("greaterThanOrEquals"===a)return u>=n;if("lessThan"===a)return u<n;if("lessThanOrEquals"===a)return u<=n}return!1}t.conditionIsMatched=a,t.allConditionsAreMatched=function e(t,r){return"attribute"in t?a(t,r):"and"in t&&Array.isArray(t.and)?t.and.every((function(t){return e(t,r)})):"or"in t&&Array.isArray(t.or)?t.or.some((function(t){return e(t,r)})):"not"in t&&Array.isArray(t.not)?t.not.every((function(i){return!1===e({and:t.not},r)})):!!Array.isArray(t)&&t.every((function(t){return e(t,r)}))}},913:(e,t)=>{"use strict";function r(e,t){if("string"==typeof e[t]&&"*"!==e[t])try{e[t]=JSON.parse(e[t])}catch(e){console.error("Error parsing JSON",e)}return e}Object.defineProperty(t,"__esModule",{value:!0}),t.DatafileReader=t.parseJsonConditionsIfStringified=void 0,t.parseJsonConditionsIfStringified=r;var i=function(){function e(e){this.schemaVersion=e.schemaVersion,this.revision=e.revision,this.segments=e.segments,this.attributes=e.attributes,this.features=e.features}return e.prototype.getRevision=function(){return this.revision},e.prototype.getSchemaVersion=function(){return this.schemaVersion},e.prototype.getAllAttributes=function(){return this.attributes},e.prototype.getAttribute=function(e){return this.attributes.find((function(t){return t.key===e}))},e.prototype.getSegment=function(e){var t=this.segments.find((function(t){return t.key===e}));if(t)return r(t,"conditions")},e.prototype.getFeature=function(e){var t=this.features.find((function(t){return t.key===e}));if(t)return t},e}();t.DatafileReader=i},186:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Emitter=void 0;var r=function(){function e(){this._listeners={}}return e.prototype.addListener=function(e,t){void 0===this._listeners[e]&&(this._listeners[e]=[]),this._listeners[e].push(t)},e.prototype.removeListener=function(e,t){if(void 0!==this._listeners[e]){var r=this._listeners[e].indexOf(t);-1!==r&&this._listeners[e].splice(r,1)}},e.prototype.removeAllListeners=function(e){var t=this;e?this._listeners[e]=[]:Object.keys(this._listeners).forEach((function(e){t._listeners[e]=[]}))},e.prototype.emit=function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];void 0!==this._listeners[e]&&this._listeners[e].forEach((function(e){e.apply(void 0,t)}))},e}();t.Emitter=r},522:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.findForceFromFeature=t.getMatchedTrafficAndAllocation=t.getMatchedAllocation=void 0;var i=r(590),a=r(243);function n(e,t){for(var r=0,i=e.allocation;r<i.length;r++){var a=i[r],n=a.range,o=n[0],s=n[1];if(a.range&&o<=t&&s>=t)return a}}t.getMatchedAllocation=n,t.getMatchedTrafficAndAllocation=function(e,t,r,a,o){var s;return{matchedTraffic:e.find((function(e){return!!(0,i.allGroupSegmentsAreMatched)("string"==typeof e.segments&&"*"!==e.segments?JSON.parse(e.segments):e.segments,t,a)&&!!(s=n(e,r))})),matchedAllocation:s}},t.findForceFromFeature=function(e,t,r){if(e.force)return e.force.find((function(e){return e.conditions?(0,a.allConditionsAreMatched)(e.conditions,t):!!e.segments&&(0,i.allGroupSegmentsAreMatched)(e.segments,t,r)}))}},97:function(e,t,r){"use strict";var i=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var a=Object.getOwnPropertyDescriptor(t,r);a&&!("get"in a?!t.__esModule:a.writable||a.configurable)||(a={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,a)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),a=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||i(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),a(r(725),t),a(r(681),t),a(r(687),t),a(r(243),t)},681:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createInstance=t.FeaturevisorInstance=t.getValueByType=t.EvaluationReason=void 0;var i,a=r(687),n=r(913),o=r(186),s=r(725),u=r(522),l=r(243),f=r(590),c=".",d={schemaVersion:"1",revision:"unknown",attributes:[],segments:[],features:[]};function v(e,t){return t?t(e):fetch(e).then((function(e){return e.json()}))}function h(e,t){try{if(void 0===e)return;switch(t){case"string":return"string"==typeof e?e:void 0;case"integer":return parseInt(e,10);case"double":return parseFloat(e);case"boolean":return!0===e;case"array":return Array.isArray(e)?e:void 0;case"object":return"object"==typeof e?e:void 0;default:return e}}catch(e){return}}!function(e){e.NOT_FOUND="not_found",e.FORCED="forced",e.INITIAL="initial",e.STICKY="sticky",e.RULE="rule",e.ALLOCATED="allocated",e.DEFAULTED="defaulted",e.OVERRIDE="override",e.ERROR="error"}(i=t.EvaluationReason||(t.EvaluationReason={})),t.getValueByType=h;var g=function(){function e(e){var t=this;this.bucketKeySeparator=e.bucketKeySeparator||c,this.configureBucketKey=e.configureBucketKey,this.configureBucketValue=e.configureBucketValue,this.datafileUrl=e.datafileUrl,this.handleDatafileFetch=e.handleDatafileFetch,this.initialFeatures=e.initialFeatures,this.interceptAttributes=e.interceptAttributes,this.logger=e.logger||(0,a.createLogger)(),this.refreshInterval=e.refreshInterval,this.stickyFeatures=e.stickyFeatures,this.emitter=new o.Emitter,this.statuses={ready:!1,refreshInProgress:!1},e.onReady&&this.emitter.addListener("ready",e.onReady),e.onRefresh&&this.emitter.addListener("refresh",e.onRefresh),e.onUpdate&&this.emitter.addListener("update",e.onUpdate),e.onActivation&&this.emitter.addListener("activation",e.onActivation);var r=this.emitter.addListener.bind(this.emitter);this.on=r,this.addListener=r;var i=this.emitter.removeListener.bind(this.emitter);if(this.off=i,this.removeListener=i,this.removeAllListeners=this.emitter.removeAllListeners.bind(this.emitter),e.datafileUrl)this.setDatafile(e.datafile||d),v(e.datafileUrl,e.handleDatafileFetch).then((function(e){t.setDatafile(e),t.statuses.ready=!0,t.emitter.emit("ready"),t.refreshInterval&&t.startRefreshing()})).catch((function(e){t.logger.error("failed to fetch datafile",{error:e})}));else{if(!e.datafile)throw new Error("Featurevisor SDK instance cannot be created without both `datafile` and `datafileUrl` options");this.setDatafile(e.datafile),this.statuses.ready=!0,setTimeout((function(){t.emitter.emit("ready")}),0)}}return e.prototype.setDatafile=function(e){try{this.datafileReader=new n.DatafileReader("string"==typeof e?JSON.parse(e):e)}catch(e){this.logger.error("could not parse datafile",{error:e})}},e.prototype.setStickyFeatures=function(e){this.stickyFeatures=e},e.prototype.getRevision=function(){return this.datafileReader.getRevision()},e.prototype.getFeature=function(e){return"string"==typeof e?this.datafileReader.getFeature(e):e},e.prototype.getBucketKey=function(e,t){var r,i,a=e.key;if("string"==typeof e.bucketBy)r="plain",i=[e.bucketBy];else if(Array.isArray(e.bucketBy))r="and",i=e.bucketBy;else{if("object"!=typeof e.bucketBy||!Array.isArray(e.bucketBy.or))throw this.logger.error("invalid bucketBy",{featureKey:a,bucketBy:e.bucketBy}),new Error("invalid bucketBy");r="or",i=e.bucketBy.or}var n=[];i.forEach((function(e){var i=t[e];void 0!==i&&("plain"===r||"and"===r||0===n.length)&&n.push(i)})),n.push(a);var o=n.join(this.bucketKeySeparator);return this.configureBucketKey?this.configureBucketKey(e,t,o):o},e.prototype.getBucketValue=function(e,t){var r=this.getBucketKey(e,t),i=(0,s.getBucketedNumber)(r);return this.configureBucketValue?this.configureBucketValue(e,t,i):i},e.prototype.isReady=function(){return this.statuses.ready},e.prototype.refresh=function(){var e=this;return this.logger.debug("refreshing datafile"),this.statuses.refreshInProgress?this.logger.warn("refresh in progress, skipping"):this.datafileUrl?(this.statuses.refreshInProgress=!0,void v(this.datafileUrl,this.handleDatafileFetch).then((function(t){var r=e.getRevision()!==t.revision;e.setDatafile(t),e.logger.info("refreshed datafile"),e.emitter.emit("refresh"),r&&e.emitter.emit("update"),e.statuses.refreshInProgress=!1})).catch((function(t){e.logger.error("failed to refresh datafile",{error:t}),e.statuses.refreshInProgress=!1}))):this.logger.error("cannot refresh since `datafileUrl` is not provided")},e.prototype.startRefreshing=function(){var e=this;return this.datafileUrl?this.intervalId?this.logger.warn("refreshing has already started"):this.refreshInterval?void(this.intervalId=setInterval((function(){e.refresh()}),1e3*this.refreshInterval)):this.logger.warn("no `refreshInterval` option provided"):this.logger.error("cannot start refreshing since `datafileUrl` is not provided")},e.prototype.stopRefreshing=function(){if(!this.intervalId)return this.logger.warn("refreshing has not started yet");clearInterval(this.intervalId)},e.prototype.evaluateVariation=function(e,t){var r;void 0===t&&(t={});try{var a="string"==typeof e?e:e.key;if(this.stickyFeatures&&this.stickyFeatures[a]&&void 0!==(n=this.stickyFeatures[a].variation))return r={featureKey:a,reason:i.STICKY,variationValue:n},this.logger.debug("using sticky variation",r),r;if(this.statuses&&!this.statuses.ready&&this.initialFeatures&&this.initialFeatures[a]&&void 0!==this.initialFeatures[a].variation){var n=this.initialFeatures[a].variation;return r={featureKey:a,reason:i.INITIAL,variationValue:n},this.logger.debug("using initial variation",r),r}var o=this.getFeature(e);if(!o)return r={featureKey:a,reason:i.NOT_FOUND},this.logger.warn("feature not found in datafile",r),r;var s=this.interceptAttributes?this.interceptAttributes(t):t,l=(0,u.findForceFromFeature)(o,t,this.datafileReader);if(l&&l.variation){var f=o.variations.find((function(e){return e.value===l.variation}));if(f)return r={featureKey:o.key,reason:i.FORCED,variation:f},this.logger.debug("forced variation found",r),r}var c=this.getBucketValue(o,s),d=(0,u.getMatchedTrafficAndAllocation)(o.traffic,s,c,this.datafileReader,this.logger),v=d.matchedTraffic,h=d.matchedAllocation;if(v){if(v.variation){var g=o.variations.find((function(e){return e.value===v.variation}));if(g)return r={featureKey:o.key,reason:i.RULE,variation:g,bucketValue:c,ruleKey:v.key},this.logger.debug("override from rule",r),r}if(h&&h.variation){var y=o.variations.find((function(e){return e.value===h.variation}));if(y)return r={featureKey:o.key,reason:i.ALLOCATED,bucketValue:c,variation:y},this.logger.debug("allocated variation",r),r}}var p=o.variations.find((function(e){return e.value===o.defaultVariation}));return p?(r={featureKey:o.key,reason:i.DEFAULTED,bucketValue:c,variation:p},this.logger.debug("using default variation",r),r):(r={featureKey:o.key,reason:i.ERROR,bucketValue:c},this.logger.error("no matched variation",r),r)}catch(t){return{featureKey:"string"==typeof e?e:e.key,reason:i.ERROR,error:t}}},e.prototype.getVariation=function(e,t){void 0===t&&(t={});try{var r=this.evaluateVariation(e,t);return void 0!==r.variationValue?r.variationValue:r.variation?r.variation.value:void 0}catch(t){return void this.logger.error("getVariation",{featureKey:e,error:t})}},e.prototype.getVariationBoolean=function(e,t){return void 0===t&&(t={}),h(this.getVariation(e,t),"boolean")},e.prototype.getVariationString=function(e,t){return void 0===t&&(t={}),h(this.getVariation(e,t),"string")},e.prototype.getVariationInteger=function(e,t){return void 0===t&&(t={}),h(this.getVariation(e,t),"integer")},e.prototype.getVariationDouble=function(e,t){return void 0===t&&(t={}),h(this.getVariation(e,t),"double")},e.prototype.activate=function(e,t){void 0===t&&(t={});try{var r=this.evaluateVariation(e,t),i=r.variation?r.variation.value:r.variationValue;if(void 0===i)return;var a=this.interceptAttributes?this.interceptAttributes(t):t,n={};return this.datafileReader.getAllAttributes().filter((function(e){return!0===e.capture})).forEach((function(e){void 0!==a[e.key]&&(n[e.key]=t[e.key])})),this.emitter.emit("activation",e,i,a,n,r),i}catch(t){return void this.logger.error("activate",{featureKey:e,error:t})}},e.prototype.activateBoolean=function(e,t){return void 0===t&&(t={}),h(this.activate(e,t),"boolean")},e.prototype.activateString=function(e,t){return void 0===t&&(t={}),h(this.activate(e,t),"string")},e.prototype.activateInteger=function(e,t){return void 0===t&&(t={}),h(this.activate(e,t),"integer")},e.prototype.activateDouble=function(e,t){return void 0===t&&(t={}),h(this.activate(e,t),"double")},e.prototype.evaluateVariable=function(e,t,r){var a,n=this;void 0===r&&(r={});try{var o="string"==typeof e?e:e.key;if(this.stickyFeatures&&this.stickyFeatures[o]&&this.stickyFeatures[o].variables){var s=this.stickyFeatures[o].variables[t];if(void 0!==s)return a={featureKey:o,reason:i.STICKY,variableKey:t,variableValue:s},this.logger.debug("using sticky variable",a),a}if(this.statuses&&!this.statuses.ready&&this.initialFeatures&&this.initialFeatures[o]&&this.initialFeatures[o].variables&&void 0!==this.initialFeatures[o].variables[t])return a={featureKey:o,reason:i.INITIAL,variableKey:t,variableValue:this.initialFeatures[o].variables[t]},this.logger.debug("using initial variable",a),a;var c=this.getFeature(e);if(!c)return a={featureKey:o,reason:i.NOT_FOUND,variableKey:t},this.logger.warn("feature not found in datafile",a),a;var d=Array.isArray(c.variablesSchema)?c.variablesSchema.find((function(e){return e.key===t})):void 0;if(!d)return a={featureKey:o,reason:i.NOT_FOUND,variableKey:t},this.logger.warn("variable schema not found",a),a;var v=this.interceptAttributes?this.interceptAttributes(r):r,h=(0,u.findForceFromFeature)(c,r,this.datafileReader);if(h&&h.variables&&void 0!==h.variables[t])return a={featureKey:c.key,reason:i.FORCED,variableKey:t,variableSchema:d,variableValue:h.variables[t]},this.logger.debug("forced variable",a),a;var g=this.getBucketValue(c,v),y=(0,u.getMatchedTrafficAndAllocation)(c.traffic,v,g,this.datafileReader,this.logger),p=y.matchedTraffic,b=y.matchedAllocation;if(p){if(p.variables&&void 0!==p.variables[t])return a={featureKey:c.key,reason:i.RULE,variableKey:t,variableSchema:d,variableValue:p.variables[t],bucketValue:g,ruleKey:p.key},this.logger.debug("override from rule",a),a;if(b&&b.variation){var m=c.variations.find((function(e){return e.value===b.variation}));if(m&&m.variables){var k=m.variables.find((function(e){return e.key===t}));if(k){if(k.overrides){var A=k.overrides.find((function(e){return e.conditions?(0,l.allConditionsAreMatched)("string"==typeof e.conditions?JSON.parse(e.conditions):e.conditions,v):!!e.segments&&(0,f.allGroupSegmentsAreMatched)("string"==typeof e.segments&&"*"!==e.segments?JSON.parse(e.segments):e.segments,v,n.datafileReader)}));if(A)return a={featureKey:c.key,reason:i.OVERRIDE,variableKey:t,variableSchema:d,variableValue:A.value,bucketValue:g,ruleKey:p.key},this.logger.debug("variable override",a),a}if(void 0!==k.value)return a={featureKey:c.key,reason:i.ALLOCATED,variableKey:t,variableSchema:d,variableValue:k.value,bucketValue:g,ruleKey:p.key},this.logger.debug("allocated variable",a),a}}}}return a={featureKey:c.key,reason:i.DEFAULTED,variableKey:t,variableSchema:d,variableValue:d.defaultValue,bucketValue:g},this.logger.debug("using default value",a),a}catch(r){return{featureKey:"string"==typeof e?e:e.key,reason:i.ERROR,variableKey:t,error:r}}},e.prototype.getVariable=function(e,t,r){void 0===r&&(r={});try{var i=this.evaluateVariable(e,t,r);return void 0!==i.variableValue?i.variableSchema&&"json"===i.variableSchema.type&&"string"==typeof i.variableValue?JSON.parse(i.variableValue):i.variableValue:void 0}catch(r){return void this.logger.error("getVariable",{featureKey:e,variableKey:t,error:r})}},e.prototype.getVariableBoolean=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"boolean")},e.prototype.getVariableString=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"string")},e.prototype.getVariableInteger=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"integer")},e.prototype.getVariableDouble=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"double")},e.prototype.getVariableArray=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"array")},e.prototype.getVariableObject=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"object")},e.prototype.getVariableJSON=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"json")},e}();t.FeaturevisorInstance=g,t.createInstance=function(e){return new g(e)}},687:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createLogger=t.Logger=t.defaultLogHandler=t.defaultLogLevels=t.loggerPrefix=void 0,t.loggerPrefix="[Featurevisor]",t.defaultLogLevels=["warn","error"],t.defaultLogHandler=function(e,r,i){switch(void 0===i&&(i={}),e){case"debug":console.log(t.loggerPrefix,r,i);case"info":console.info(t.loggerPrefix,r,i);case"warn":console.warn(t.loggerPrefix,r,i);case"error":console.error(t.loggerPrefix,r,i)}};var r=function(){function e(e){this.levels=e.levels,this.handle=e.handler}return e.prototype.setLevels=function(e){this.levels=e},e.prototype.log=function(e,t,r){-1!==this.levels.indexOf(e)&&this.handle(e,t,r)},e.prototype.debug=function(e,t){this.log("debug",e,t)},e.prototype.info=function(e,t){this.log("info",e,t)},e.prototype.warn=function(e,t){this.log("warn",e,t)},e.prototype.error=function(e,t){this.log("error",e,t)},e}();t.Logger=r,t.createLogger=function(e){void 0===e&&(e={});var i=e.levels||t.defaultLogLevels,a=e.handler||t.defaultLogHandler;return new r({levels:i,handler:a})}},590:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.allGroupSegmentsAreMatched=t.segmentIsMatched=void 0;var i=r(243);function a(e,t){return(0,i.allConditionsAreMatched)(e.conditions,t)}t.segmentIsMatched=a,t.allGroupSegmentsAreMatched=function e(t,r,i){if("*"===t)return!0;if("string"==typeof t){var n=i.getSegment(t);return!!n&&a(n,r)}if("object"==typeof t){if("and"in t&&Array.isArray(t.and))return t.and.every((function(t){return e(t,r,i)}));if("or"in t&&Array.isArray(t.or))return t.or.some((function(t){return e(t,r,i)}));if("not"in t&&Array.isArray(t.not))return t.not.every((function(t){return!1===e(t,r,i)}))}return!!Array.isArray(t)&&t.every((function(t){return e(t,r,i)}))}}},t={};function r(i){var a=t[i];if(void 0!==a)return a.exports;var n=t[i]={exports:{}};return e[i].call(n.exports,n,n.exports,r),n.exports}return r.d=(e,t)=>{for(var i in t)r.o(t,i)&&!r.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r(97)})()));
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.FeaturevisorSDK=t():e.FeaturevisorSDK=t()}(this,(()=>(()=>{var e={480:(e,t,r)=>{"use strict";r.r(t),r.d(t,{compare:()=>n,compareVersions:()=>i,satisfies:()=>o,validate:()=>a});const i=(e,t)=>{const r=u(e),i=u(t),a=r.pop(),n=i.pop(),o=d(r,i);return 0!==o?o:a&&n?d(a.split("."),n.split(".")):a||n?a?-1:1:0},a=e=>"string"==typeof e&&/^[v\d]/.test(e)&&s.test(e),n=(e,t,r)=>{g(r);const a=i(e,t);return v[r].includes(a)},o=(e,t)=>{if(t.includes("||"))return t.split("||").some((t=>o(e,t)));if(t.includes(" "))return t.trim().replace(/\s{2,}/g," ").split(" ").every((t=>o(e,t)));const r=t.match(/^([<>=~^]+)/),i=r?r[1]:"=";if("^"!==i&&"~"!==i)return n(e,t,i);const[a,s,l,,f]=u(e),[c,v,h,,g]=u(t),y=[a,s,l],p=[c,null!=v?v:"x",null!=h?h:"x"];if(g){if(!f)return!1;if(0!==d(y,p))return!1;if(-1===d(f.split("."),g.split(".")))return!1}const b=p.findIndex((e=>"0"!==e))+1,m="~"===i?2:b>1?b:1;return 0===d(y.slice(0,m),p.slice(0,m))&&-1!==d(y.slice(m),p.slice(m))},s=/^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i,u=e=>{if("string"!=typeof e)throw new TypeError("Invalid argument expected string");const t=e.match(s);if(!t)throw new Error(`Invalid argument not valid semver ('${e}' received)`);return t.shift(),t},l=e=>"*"===e||"x"===e||"X"===e,f=e=>{const t=parseInt(e,10);return isNaN(t)?e:t},c=(e,t)=>{if(l(e)||l(t))return 0;const[r,i]=((e,t)=>typeof e!=typeof t?[String(e),String(t)]:[e,t])(f(e),f(t));return r>i?1:r<i?-1:0},d=(e,t)=>{for(let r=0;r<Math.max(e.length,t.length);r++){const i=c(e[r]||"0",t[r]||"0");if(0!==i)return i}return 0},v={">":[1],">=":[0,1],"=":[0],"<=":[-1,0],"<":[-1]},h=Object.keys(v),g=e=>{if("string"!=typeof e)throw new TypeError("Invalid operator type, expected string but got "+typeof e);if(-1===h.indexOf(e))throw new Error(`Invalid operator, expected one of ${h.join("|")}`)}},77:e=>{!function(){const t=e=>(new TextEncoder).encode(e);function r(e,r){let i,a,n,o,s,u,l,f;for("string"==typeof e&&(e=t(e)),i=3&e.length,a=e.length-i,n=r,s=3432918353,u=461845907,f=0;f<a;)l=255&e[f]|(255&e[++f])<<8|(255&e[++f])<<16|(255&e[++f])<<24,++f,l=(65535&l)*s+(((l>>>16)*s&65535)<<16)&4294967295,l=l<<15|l>>>17,l=(65535&l)*u+(((l>>>16)*u&65535)<<16)&4294967295,n^=l,n=n<<13|n>>>19,o=5*(65535&n)+((5*(n>>>16)&65535)<<16)&4294967295,n=27492+(65535&o)+((58964+(o>>>16)&65535)<<16);switch(l=0,i){case 3:l^=(255&e[f+2])<<16;case 2:l^=(255&e[f+1])<<8;case 1:l^=255&e[f],l=(65535&l)*s+(((l>>>16)*s&65535)<<16)&4294967295,l=l<<15|l>>>17,l=(65535&l)*u+(((l>>>16)*u&65535)<<16)&4294967295,n^=l}return n^=e.length,n^=n>>>16,n=2246822507*(65535&n)+((2246822507*(n>>>16)&65535)<<16)&4294967295,n^=n>>>13,n=3266489909*(65535&n)+((3266489909*(n>>>16)&65535)<<16)&4294967295,n^=n>>>16,n>>>0}const i=r;i.v2=function(e,r){"string"==typeof e&&(e=t(e));let i,a=e.length,n=r^a,o=0;for(;a>=4;)i=255&e[o]|(255&e[++o])<<8|(255&e[++o])<<16|(255&e[++o])<<24,i=1540483477*(65535&i)+((1540483477*(i>>>16)&65535)<<16),i^=i>>>24,i=1540483477*(65535&i)+((1540483477*(i>>>16)&65535)<<16),n=1540483477*(65535&n)+((1540483477*(n>>>16)&65535)<<16)^i,a-=4,++o;switch(a){case 3:n^=(255&e[o+2])<<16;case 2:n^=(255&e[o+1])<<8;case 1:n^=255&e[o],n=1540483477*(65535&n)+((1540483477*(n>>>16)&65535)<<16)}return n^=n>>>13,n=1540483477*(65535&n)+((1540483477*(n>>>16)&65535)<<16),n^=n>>>15,n>>>0},i.v3=r,e.exports=i}()},725:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getBucketedNumber=t.MAX_BUCKETED_NUMBER=void 0;var i=r(77),a=Math.pow(2,32);t.MAX_BUCKETED_NUMBER=1e5,t.getBucketedNumber=function(e){var r=i.v3(e,1)/a;return Math.floor(r*t.MAX_BUCKETED_NUMBER)}},243:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.allConditionsAreMatched=t.conditionIsMatched=void 0;var i=r(480);function a(e,t){var r=e.attribute,a=e.operator,n=e.value;if("equals"===a)return t[r]===n;if("notEquals"===a)return t[r]!==n;if("before"===a||"after"===a){var o=(u=t[r])instanceof Date?u:new Date(u),s=n instanceof Date?n:new Date(n);return"before"===a?o<s:o>s}if("string"==typeof t[r]&&Array.isArray(n)){var u=t[r];if("in"===a)return-1!==n.indexOf(u);if("notIn"===a)return-1===n.indexOf(u)}else if("string"==typeof t[r]&&"string"==typeof n){if(u=t[r],"contains"===a)return-1!==u.indexOf(n);if("notContains"===a)return-1===u.indexOf(n);if("startsWith"===a)return u.startsWith(n);if("endsWith"===a)return u.endsWith(n);if("semverEquals"===a)return 0===(0,i.compareVersions)(u,n);if("semverNotEquals"===a)return 0!==(0,i.compareVersions)(u,n);if("semverGreaterThan"===a)return 1===(0,i.compareVersions)(u,n);if("semverGreaterThanOrEquals"===a)return(0,i.compareVersions)(u,n)>=0;if("semverLessThan"===a)return-1===(0,i.compareVersions)(u,n);if("semverLessThanOrEquals"===a)return(0,i.compareVersions)(u,n)<=0}else if("number"==typeof t[r]&&"number"==typeof n){if(u=t[r],"greaterThan"===a)return u>n;if("greaterThanOrEquals"===a)return u>=n;if("lessThan"===a)return u<n;if("lessThanOrEquals"===a)return u<=n}return!1}t.conditionIsMatched=a,t.allConditionsAreMatched=function e(t,r){return"attribute"in t?a(t,r):"and"in t&&Array.isArray(t.and)?t.and.every((function(t){return e(t,r)})):"or"in t&&Array.isArray(t.or)?t.or.some((function(t){return e(t,r)})):"not"in t&&Array.isArray(t.not)?t.not.every((function(i){return!1===e({and:t.not},r)})):!!Array.isArray(t)&&t.every((function(t){return e(t,r)}))}},913:(e,t)=>{"use strict";function r(e,t){if("string"==typeof e[t]&&"*"!==e[t])try{e[t]=JSON.parse(e[t])}catch(e){console.error("Error parsing JSON",e)}return e}Object.defineProperty(t,"__esModule",{value:!0}),t.DatafileReader=t.parseJsonConditionsIfStringified=void 0,t.parseJsonConditionsIfStringified=r;var i=function(){function e(e){this.schemaVersion=e.schemaVersion,this.revision=e.revision,this.segments=e.segments,this.attributes=e.attributes,this.features=e.features}return e.prototype.getRevision=function(){return this.revision},e.prototype.getSchemaVersion=function(){return this.schemaVersion},e.prototype.getAllAttributes=function(){return this.attributes},e.prototype.getAttribute=function(e){return this.attributes.find((function(t){return t.key===e}))},e.prototype.getSegment=function(e){var t=this.segments.find((function(t){return t.key===e}));if(t)return r(t,"conditions")},e.prototype.getFeature=function(e){var t=this.features.find((function(t){return t.key===e}));if(t)return t},e}();t.DatafileReader=i},186:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Emitter=void 0;var r=function(){function e(){this._listeners={}}return e.prototype.addListener=function(e,t){void 0===this._listeners[e]&&(this._listeners[e]=[]),this._listeners[e].push(t)},e.prototype.removeListener=function(e,t){if(void 0!==this._listeners[e]){var r=this._listeners[e].indexOf(t);-1!==r&&this._listeners[e].splice(r,1)}},e.prototype.removeAllListeners=function(e){var t=this;e?this._listeners[e]=[]:Object.keys(this._listeners).forEach((function(e){t._listeners[e]=[]}))},e.prototype.emit=function(e){for(var t=[],r=1;r<arguments.length;r++)t[r-1]=arguments[r];void 0!==this._listeners[e]&&this._listeners[e].forEach((function(e){e.apply(void 0,t)}))},e}();t.Emitter=r},522:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.findForceFromFeature=t.getMatchedTrafficAndAllocation=t.getMatchedAllocation=void 0;var i=r(590),a=r(243);function n(e,t){for(var r=0,i=e.allocation;r<i.length;r++){var a=i[r],n=a.range,o=n[0],s=n[1];if(a.range&&o<=t&&s>=t)return a}}t.getMatchedAllocation=n,t.getMatchedTrafficAndAllocation=function(e,t,r,a,o){var s;return{matchedTraffic:e.find((function(e){return!!(0,i.allGroupSegmentsAreMatched)("string"==typeof e.segments&&"*"!==e.segments?JSON.parse(e.segments):e.segments,t,a)&&!!(s=n(e,r))})),matchedAllocation:s}},t.findForceFromFeature=function(e,t,r){if(e.force)return e.force.find((function(e){return e.conditions?(0,a.allConditionsAreMatched)(e.conditions,t):!!e.segments&&(0,i.allGroupSegmentsAreMatched)(e.segments,t,r)}))}},97:function(e,t,r){"use strict";var i=this&&this.__createBinding||(Object.create?function(e,t,r,i){void 0===i&&(i=r);var a=Object.getOwnPropertyDescriptor(t,r);a&&!("get"in a?!t.__esModule:a.writable||a.configurable)||(a={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,i,a)}:function(e,t,r,i){void 0===i&&(i=r),e[i]=t[r]}),a=this&&this.__exportStar||function(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||i(t,e,r)};Object.defineProperty(t,"__esModule",{value:!0}),a(r(725),t),a(r(681),t),a(r(687),t),a(r(243),t)},681:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createInstance=t.FeaturevisorInstance=t.getValueByType=t.EvaluationReason=void 0;var i,a=r(687),n=r(913),o=r(186),s=r(725),u=r(522),l=r(243),f=r(590),c=".",d={schemaVersion:"1",revision:"unknown",attributes:[],segments:[],features:[]};function v(e,t){return t?t(e):fetch(e).then((function(e){return e.json()}))}function h(e,t){try{if(void 0===e)return;switch(t){case"string":return"string"==typeof e?e:void 0;case"integer":return parseInt(e,10);case"double":return parseFloat(e);case"boolean":return!0===e;case"array":return Array.isArray(e)?e:void 0;case"object":return"object"==typeof e?e:void 0;default:return e}}catch(e){return}}!function(e){e.NOT_FOUND="not_found",e.FORCED="forced",e.INITIAL="initial",e.STICKY="sticky",e.RULE="rule",e.ALLOCATED="allocated",e.DEFAULTED="defaulted",e.OVERRIDE="override",e.ERROR="error"}(i=t.EvaluationReason||(t.EvaluationReason={})),t.getValueByType=h;var g=function(){function e(e){var t=this;this.bucketKeySeparator=e.bucketKeySeparator||c,this.configureBucketKey=e.configureBucketKey,this.configureBucketValue=e.configureBucketValue,this.datafileUrl=e.datafileUrl,this.handleDatafileFetch=e.handleDatafileFetch,this.initialFeatures=e.initialFeatures,this.interceptContext=e.interceptContext,this.logger=e.logger||(0,a.createLogger)(),this.refreshInterval=e.refreshInterval,this.stickyFeatures=e.stickyFeatures,this.emitter=new o.Emitter,this.statuses={ready:!1,refreshInProgress:!1},e.onReady&&this.emitter.addListener("ready",e.onReady),e.onRefresh&&this.emitter.addListener("refresh",e.onRefresh),e.onUpdate&&this.emitter.addListener("update",e.onUpdate),e.onActivation&&this.emitter.addListener("activation",e.onActivation);var r=this.emitter.addListener.bind(this.emitter);this.on=r,this.addListener=r;var i=this.emitter.removeListener.bind(this.emitter);if(this.off=i,this.removeListener=i,this.removeAllListeners=this.emitter.removeAllListeners.bind(this.emitter),e.datafileUrl)this.setDatafile(e.datafile||d),v(e.datafileUrl,e.handleDatafileFetch).then((function(e){t.setDatafile(e),t.statuses.ready=!0,t.emitter.emit("ready"),t.refreshInterval&&t.startRefreshing()})).catch((function(e){t.logger.error("failed to fetch datafile",{error:e})}));else{if(!e.datafile)throw new Error("Featurevisor SDK instance cannot be created without both `datafile` and `datafileUrl` options");this.setDatafile(e.datafile),this.statuses.ready=!0,setTimeout((function(){t.emitter.emit("ready")}),0)}}return e.prototype.setDatafile=function(e){try{this.datafileReader=new n.DatafileReader("string"==typeof e?JSON.parse(e):e)}catch(e){this.logger.error("could not parse datafile",{error:e})}},e.prototype.setStickyFeatures=function(e){this.stickyFeatures=e},e.prototype.getRevision=function(){return this.datafileReader.getRevision()},e.prototype.getFeature=function(e){return"string"==typeof e?this.datafileReader.getFeature(e):e},e.prototype.getBucketKey=function(e,t){var r,i,a=e.key;if("string"==typeof e.bucketBy)r="plain",i=[e.bucketBy];else if(Array.isArray(e.bucketBy))r="and",i=e.bucketBy;else{if("object"!=typeof e.bucketBy||!Array.isArray(e.bucketBy.or))throw this.logger.error("invalid bucketBy",{featureKey:a,bucketBy:e.bucketBy}),new Error("invalid bucketBy");r="or",i=e.bucketBy.or}var n=[];i.forEach((function(e){var i=t[e];void 0!==i&&("plain"===r||"and"===r||0===n.length)&&n.push(i)})),n.push(a);var o=n.join(this.bucketKeySeparator);return this.configureBucketKey?this.configureBucketKey(e,t,o):o},e.prototype.getBucketValue=function(e,t){var r=this.getBucketKey(e,t),i=(0,s.getBucketedNumber)(r);return this.configureBucketValue?this.configureBucketValue(e,t,i):i},e.prototype.isReady=function(){return this.statuses.ready},e.prototype.refresh=function(){var e=this;return this.logger.debug("refreshing datafile"),this.statuses.refreshInProgress?this.logger.warn("refresh in progress, skipping"):this.datafileUrl?(this.statuses.refreshInProgress=!0,void v(this.datafileUrl,this.handleDatafileFetch).then((function(t){var r=e.getRevision()!==t.revision;e.setDatafile(t),e.logger.info("refreshed datafile"),e.emitter.emit("refresh"),r&&e.emitter.emit("update"),e.statuses.refreshInProgress=!1})).catch((function(t){e.logger.error("failed to refresh datafile",{error:t}),e.statuses.refreshInProgress=!1}))):this.logger.error("cannot refresh since `datafileUrl` is not provided")},e.prototype.startRefreshing=function(){var e=this;return this.datafileUrl?this.intervalId?this.logger.warn("refreshing has already started"):this.refreshInterval?void(this.intervalId=setInterval((function(){e.refresh()}),1e3*this.refreshInterval)):this.logger.warn("no `refreshInterval` option provided"):this.logger.error("cannot start refreshing since `datafileUrl` is not provided")},e.prototype.stopRefreshing=function(){if(!this.intervalId)return this.logger.warn("refreshing has not started yet");clearInterval(this.intervalId)},e.prototype.evaluateVariation=function(e,t){var r;void 0===t&&(t={});try{var a="string"==typeof e?e:e.key;if(this.stickyFeatures&&this.stickyFeatures[a]&&void 0!==(n=this.stickyFeatures[a].variation))return r={featureKey:a,reason:i.STICKY,variationValue:n},this.logger.debug("using sticky variation",r),r;if(this.statuses&&!this.statuses.ready&&this.initialFeatures&&this.initialFeatures[a]&&void 0!==this.initialFeatures[a].variation){var n=this.initialFeatures[a].variation;return r={featureKey:a,reason:i.INITIAL,variationValue:n},this.logger.debug("using initial variation",r),r}var o=this.getFeature(e);if(!o)return r={featureKey:a,reason:i.NOT_FOUND},this.logger.warn("feature not found in datafile",r),r;var s=this.interceptContext?this.interceptContext(t):t,l=(0,u.findForceFromFeature)(o,t,this.datafileReader);if(l&&l.variation){var f=o.variations.find((function(e){return e.value===l.variation}));if(f)return r={featureKey:o.key,reason:i.FORCED,variation:f},this.logger.debug("forced variation found",r),r}var c=this.getBucketValue(o,s),d=(0,u.getMatchedTrafficAndAllocation)(o.traffic,s,c,this.datafileReader,this.logger),v=d.matchedTraffic,h=d.matchedAllocation;if(v){if(v.variation){var g=o.variations.find((function(e){return e.value===v.variation}));if(g)return r={featureKey:o.key,reason:i.RULE,variation:g,bucketValue:c,ruleKey:v.key},this.logger.debug("override from rule",r),r}if(h&&h.variation){var y=o.variations.find((function(e){return e.value===h.variation}));if(y)return r={featureKey:o.key,reason:i.ALLOCATED,bucketValue:c,variation:y},this.logger.debug("allocated variation",r),r}}var p=o.variations.find((function(e){return e.value===o.defaultVariation}));return p?(r={featureKey:o.key,reason:i.DEFAULTED,bucketValue:c,variation:p},this.logger.debug("using default variation",r),r):(r={featureKey:o.key,reason:i.ERROR,bucketValue:c},this.logger.error("no matched variation",r),r)}catch(t){return{featureKey:"string"==typeof e?e:e.key,reason:i.ERROR,error:t}}},e.prototype.getVariation=function(e,t){void 0===t&&(t={});try{var r=this.evaluateVariation(e,t);return void 0!==r.variationValue?r.variationValue:r.variation?r.variation.value:void 0}catch(t){return void this.logger.error("getVariation",{featureKey:e,error:t})}},e.prototype.getVariationBoolean=function(e,t){return void 0===t&&(t={}),h(this.getVariation(e,t),"boolean")},e.prototype.getVariationString=function(e,t){return void 0===t&&(t={}),h(this.getVariation(e,t),"string")},e.prototype.getVariationInteger=function(e,t){return void 0===t&&(t={}),h(this.getVariation(e,t),"integer")},e.prototype.getVariationDouble=function(e,t){return void 0===t&&(t={}),h(this.getVariation(e,t),"double")},e.prototype.activate=function(e,t){void 0===t&&(t={});try{var r=this.evaluateVariation(e,t),i=r.variation?r.variation.value:r.variationValue;if(void 0===i)return;var a=this.interceptContext?this.interceptContext(t):t,n={};return this.datafileReader.getAllAttributes().filter((function(e){return!0===e.capture})).forEach((function(e){void 0!==a[e.key]&&(n[e.key]=t[e.key])})),this.emitter.emit("activation",e,i,a,n,r),i}catch(t){return void this.logger.error("activate",{featureKey:e,error:t})}},e.prototype.activateBoolean=function(e,t){return void 0===t&&(t={}),h(this.activate(e,t),"boolean")},e.prototype.activateString=function(e,t){return void 0===t&&(t={}),h(this.activate(e,t),"string")},e.prototype.activateInteger=function(e,t){return void 0===t&&(t={}),h(this.activate(e,t),"integer")},e.prototype.activateDouble=function(e,t){return void 0===t&&(t={}),h(this.activate(e,t),"double")},e.prototype.evaluateVariable=function(e,t,r){var a,n=this;void 0===r&&(r={});try{var o="string"==typeof e?e:e.key;if(this.stickyFeatures&&this.stickyFeatures[o]&&this.stickyFeatures[o].variables){var s=this.stickyFeatures[o].variables[t];if(void 0!==s)return a={featureKey:o,reason:i.STICKY,variableKey:t,variableValue:s},this.logger.debug("using sticky variable",a),a}if(this.statuses&&!this.statuses.ready&&this.initialFeatures&&this.initialFeatures[o]&&this.initialFeatures[o].variables&&void 0!==this.initialFeatures[o].variables[t])return a={featureKey:o,reason:i.INITIAL,variableKey:t,variableValue:this.initialFeatures[o].variables[t]},this.logger.debug("using initial variable",a),a;var c=this.getFeature(e);if(!c)return a={featureKey:o,reason:i.NOT_FOUND,variableKey:t},this.logger.warn("feature not found in datafile",a),a;var d=Array.isArray(c.variablesSchema)?c.variablesSchema.find((function(e){return e.key===t})):void 0;if(!d)return a={featureKey:o,reason:i.NOT_FOUND,variableKey:t},this.logger.warn("variable schema not found",a),a;var v=this.interceptContext?this.interceptContext(r):r,h=(0,u.findForceFromFeature)(c,r,this.datafileReader);if(h&&h.variables&&void 0!==h.variables[t])return a={featureKey:c.key,reason:i.FORCED,variableKey:t,variableSchema:d,variableValue:h.variables[t]},this.logger.debug("forced variable",a),a;var g=this.getBucketValue(c,v),y=(0,u.getMatchedTrafficAndAllocation)(c.traffic,v,g,this.datafileReader,this.logger),p=y.matchedTraffic,b=y.matchedAllocation;if(p){if(p.variables&&void 0!==p.variables[t])return a={featureKey:c.key,reason:i.RULE,variableKey:t,variableSchema:d,variableValue:p.variables[t],bucketValue:g,ruleKey:p.key},this.logger.debug("override from rule",a),a;if(b&&b.variation){var m=c.variations.find((function(e){return e.value===b.variation}));if(m&&m.variables){var k=m.variables.find((function(e){return e.key===t}));if(k){if(k.overrides){var V=k.overrides.find((function(e){return e.conditions?(0,l.allConditionsAreMatched)("string"==typeof e.conditions?JSON.parse(e.conditions):e.conditions,v):!!e.segments&&(0,f.allGroupSegmentsAreMatched)("string"==typeof e.segments&&"*"!==e.segments?JSON.parse(e.segments):e.segments,v,n.datafileReader)}));if(V)return a={featureKey:c.key,reason:i.OVERRIDE,variableKey:t,variableSchema:d,variableValue:V.value,bucketValue:g,ruleKey:p.key},this.logger.debug("variable override",a),a}if(void 0!==k.value)return a={featureKey:c.key,reason:i.ALLOCATED,variableKey:t,variableSchema:d,variableValue:k.value,bucketValue:g,ruleKey:p.key},this.logger.debug("allocated variable",a),a}}}}return a={featureKey:c.key,reason:i.DEFAULTED,variableKey:t,variableSchema:d,variableValue:d.defaultValue,bucketValue:g},this.logger.debug("using default value",a),a}catch(r){return{featureKey:"string"==typeof e?e:e.key,reason:i.ERROR,variableKey:t,error:r}}},e.prototype.getVariable=function(e,t,r){void 0===r&&(r={});try{var i=this.evaluateVariable(e,t,r);return void 0!==i.variableValue?i.variableSchema&&"json"===i.variableSchema.type&&"string"==typeof i.variableValue?JSON.parse(i.variableValue):i.variableValue:void 0}catch(r){return void this.logger.error("getVariable",{featureKey:e,variableKey:t,error:r})}},e.prototype.getVariableBoolean=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"boolean")},e.prototype.getVariableString=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"string")},e.prototype.getVariableInteger=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"integer")},e.prototype.getVariableDouble=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"double")},e.prototype.getVariableArray=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"array")},e.prototype.getVariableObject=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"object")},e.prototype.getVariableJSON=function(e,t,r){return void 0===r&&(r={}),h(this.getVariable(e,t,r),"json")},e}();t.FeaturevisorInstance=g,t.createInstance=function(e){return new g(e)}},687:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.createLogger=t.Logger=t.defaultLogHandler=t.defaultLogLevels=t.loggerPrefix=void 0,t.loggerPrefix="[Featurevisor]",t.defaultLogLevels=["warn","error"],t.defaultLogHandler=function(e,r,i){switch(void 0===i&&(i={}),e){case"debug":console.log(t.loggerPrefix,r,i);case"info":console.info(t.loggerPrefix,r,i);case"warn":console.warn(t.loggerPrefix,r,i);case"error":console.error(t.loggerPrefix,r,i)}};var r=function(){function e(e){this.levels=e.levels,this.handle=e.handler}return e.prototype.setLevels=function(e){this.levels=e},e.prototype.log=function(e,t,r){-1!==this.levels.indexOf(e)&&this.handle(e,t,r)},e.prototype.debug=function(e,t){this.log("debug",e,t)},e.prototype.info=function(e,t){this.log("info",e,t)},e.prototype.warn=function(e,t){this.log("warn",e,t)},e.prototype.error=function(e,t){this.log("error",e,t)},e}();t.Logger=r,t.createLogger=function(e){void 0===e&&(e={});var i=e.levels||t.defaultLogLevels,a=e.handler||t.defaultLogHandler;return new r({levels:i,handler:a})}},590:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.allGroupSegmentsAreMatched=t.segmentIsMatched=void 0;var i=r(243);function a(e,t){return(0,i.allConditionsAreMatched)(e.conditions,t)}t.segmentIsMatched=a,t.allGroupSegmentsAreMatched=function e(t,r,i){if("*"===t)return!0;if("string"==typeof t){var n=i.getSegment(t);return!!n&&a(n,r)}if("object"==typeof t){if("and"in t&&Array.isArray(t.and))return t.and.every((function(t){return e(t,r,i)}));if("or"in t&&Array.isArray(t.or))return t.or.some((function(t){return e(t,r,i)}));if("not"in t&&Array.isArray(t.not))return t.not.every((function(t){return!1===e(t,r,i)}))}return!!Array.isArray(t)&&t.every((function(t){return e(t,r,i)}))}}},t={};function r(i){var a=t[i];if(void 0!==a)return a.exports;var n=t[i]={exports:{}};return e[i].call(n.exports,n,n.exports,r),n.exports}return r.d=(e,t)=>{for(var i in t)r.o(t,i)&&!r.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r(97)})()));
//# sourceMappingURL=index.js.map

@@ -1,3 +0,3 @@

import { Attributes, Condition, PlainCondition } from "@featurevisor/types";
export declare function conditionIsMatched(condition: PlainCondition, attributes: Attributes): boolean;
export declare function allConditionsAreMatched(conditions: Condition[] | Condition, attributes: Attributes): boolean;
import { Context, Condition, PlainCondition } from "@featurevisor/types";
export declare function conditionIsMatched(condition: PlainCondition, context: Context): boolean;
export declare function allConditionsAreMatched(conditions: Condition[] | Condition, context: Context): boolean;
import { compareVersions } from "compare-versions";
export function conditionIsMatched(condition, attributes) {
export function conditionIsMatched(condition, context) {
var attribute = condition.attribute, operator = condition.operator, value = condition.value;
if (operator === "equals") {
return attributes[attribute] === value;
return context[attribute] === value;
}
else if (operator === "notEquals") {
return attributes[attribute] !== value;
return context[attribute] !== value;
}
else if (operator === "before" || operator === "after") {
// date comparisons
var valueInAttributes = attributes[attribute];
var dateInAttributes = valueInAttributes instanceof Date ? valueInAttributes : new Date(valueInAttributes);
var valueInContext = context[attribute];
var dateInContext = valueInContext instanceof Date ? valueInContext : new Date(valueInContext);
var dateInCondition = value instanceof Date ? value : new Date(value);
return operator === "before"
? dateInAttributes < dateInCondition
: dateInAttributes > dateInCondition;
? dateInContext < dateInCondition
: dateInContext > dateInCondition;
}
else if (typeof attributes[attribute] === "string" && Array.isArray(value)) {
else if (typeof context[attribute] === "string" && Array.isArray(value)) {
// array
var valueInAttributes = attributes[attribute];
var valueInContext = context[attribute];
if (operator === "in") {
return value.indexOf(valueInAttributes) !== -1;
return value.indexOf(valueInContext) !== -1;
}
else if (operator === "notIn") {
return value.indexOf(valueInAttributes) === -1;
return value.indexOf(valueInContext) === -1;
}
}
else if (typeof attributes[attribute] === "string" && typeof value === "string") {
else if (typeof context[attribute] === "string" && typeof value === "string") {
// string
var valueInAttributes = attributes[attribute];
var valueInContext = context[attribute];
if (operator === "contains") {
return valueInAttributes.indexOf(value) !== -1;
return valueInContext.indexOf(value) !== -1;
}
else if (operator === "notContains") {
return valueInAttributes.indexOf(value) === -1;
return valueInContext.indexOf(value) === -1;
}
else if (operator === "startsWith") {
return valueInAttributes.startsWith(value);
return valueInContext.startsWith(value);
}
else if (operator === "endsWith") {
return valueInAttributes.endsWith(value);
return valueInContext.endsWith(value);
}
else if (operator === "semverEquals") {
return compareVersions(valueInAttributes, value) === 0;
return compareVersions(valueInContext, value) === 0;
}
else if (operator === "semverNotEquals") {
return compareVersions(valueInAttributes, value) !== 0;
return compareVersions(valueInContext, value) !== 0;
}
else if (operator === "semverGreaterThan") {
return compareVersions(valueInAttributes, value) === 1;
return compareVersions(valueInContext, value) === 1;
}
else if (operator === "semverGreaterThanOrEquals") {
return compareVersions(valueInAttributes, value) >= 0;
return compareVersions(valueInContext, value) >= 0;
}
else if (operator === "semverLessThan") {
return compareVersions(valueInAttributes, value) === -1;
return compareVersions(valueInContext, value) === -1;
}
else if (operator === "semverLessThanOrEquals") {
return compareVersions(valueInAttributes, value) <= 0;
return compareVersions(valueInContext, value) <= 0;
}
}
else if (typeof attributes[attribute] === "number" && typeof value === "number") {
else if (typeof context[attribute] === "number" && typeof value === "number") {
// numeric
var valueInAttributes = attributes[attribute];
var valueInContext = context[attribute];
if (operator === "greaterThan") {
return valueInAttributes > value;
return valueInContext > value;
}
else if (operator === "greaterThanOrEquals") {
return valueInAttributes >= value;
return valueInContext >= value;
}
else if (operator === "lessThan") {
return valueInAttributes < value;
return valueInContext < value;
}
else if (operator === "lessThanOrEquals") {
return valueInAttributes <= value;
return valueInContext <= value;
}

@@ -81,11 +81,11 @@ }

}
export function allConditionsAreMatched(conditions, attributes) {
export function allConditionsAreMatched(conditions, context) {
if ("attribute" in conditions) {
return conditionIsMatched(conditions, attributes);
return conditionIsMatched(conditions, context);
}
if ("and" in conditions && Array.isArray(conditions.and)) {
return conditions.and.every(function (c) { return allConditionsAreMatched(c, attributes); });
return conditions.and.every(function (c) { return allConditionsAreMatched(c, context); });
}
if ("or" in conditions && Array.isArray(conditions.or)) {
return conditions.or.some(function (c) { return allConditionsAreMatched(c, attributes); });
return conditions.or.some(function (c) { return allConditionsAreMatched(c, context); });
}

@@ -96,7 +96,7 @@ if ("not" in conditions && Array.isArray(conditions.not)) {

and: conditions.not,
}, attributes) === false;
}, context) === false;
});
}
if (Array.isArray(conditions)) {
return conditions.every(function (c) { return allConditionsAreMatched(c, attributes); });
return conditions.every(function (c) { return allConditionsAreMatched(c, context); });
}

@@ -103,0 +103,0 @@ return false;

@@ -1,2 +0,2 @@

import { Allocation, Attributes, Traffic, Feature, Force } from "@featurevisor/types";
import { Allocation, Context, Traffic, Feature, Force } from "@featurevisor/types";
import { DatafileReader } from "./datafileReader";

@@ -9,3 +9,3 @@ import { Logger } from "./logger";

}
export declare function getMatchedTrafficAndAllocation(traffic: Traffic[], attributes: Attributes, bucketValue: number, datafileReader: DatafileReader, logger: Logger): MatchedTrafficAndAllocation;
export declare function findForceFromFeature(feature: Feature, attributes: Attributes, datafileReader: DatafileReader): Force | undefined;
export declare function getMatchedTrafficAndAllocation(traffic: Traffic[], context: Context, bucketValue: number, datafileReader: DatafileReader, logger: Logger): MatchedTrafficAndAllocation;
export declare function findForceFromFeature(feature: Feature, context: Context, datafileReader: DatafileReader): Force | undefined;

@@ -13,6 +13,6 @@ import { allGroupSegmentsAreMatched } from "./segments";

}
export function getMatchedTrafficAndAllocation(traffic, attributes, bucketValue, datafileReader, logger) {
export function getMatchedTrafficAndAllocation(traffic, context, bucketValue, datafileReader, logger) {
var matchedAllocation;
var matchedTraffic = traffic.find(function (t) {
if (!allGroupSegmentsAreMatched(typeof t.segments === "string" && t.segments !== "*" ? JSON.parse(t.segments) : t.segments, attributes, datafileReader)) {
if (!allGroupSegmentsAreMatched(typeof t.segments === "string" && t.segments !== "*" ? JSON.parse(t.segments) : t.segments, context, datafileReader)) {
return false;

@@ -31,3 +31,3 @@ }

}
export function findForceFromFeature(feature, attributes, datafileReader) {
export function findForceFromFeature(feature, context, datafileReader) {
if (!feature.force) {

@@ -38,6 +38,6 @@ return undefined;

if (f.conditions) {
return allConditionsAreMatched(f.conditions, attributes);
return allConditionsAreMatched(f.conditions, context);
}
if (f.segments) {
return allGroupSegmentsAreMatched(f.segments, attributes, datafileReader);
return allGroupSegmentsAreMatched(f.segments, context, datafileReader);
}

@@ -44,0 +44,0 @@ return false;

@@ -1,8 +0,8 @@

import { Attributes, BucketKey, BucketValue, DatafileContent, Feature, FeatureKey, InitialFeatures, StickyFeatures, VariableType, VariableValue, VariationType, VariationValue, Variation, RuleKey, VariableKey, VariableSchema } from "@featurevisor/types";
import { Context, BucketKey, BucketValue, DatafileContent, Feature, FeatureKey, InitialFeatures, StickyFeatures, VariableType, VariableValue, VariationType, VariationValue, Variation, RuleKey, VariableKey, VariableSchema } from "@featurevisor/types";
import { Logger } from "./logger";
import { Emitter } from "./emitter";
export type ReadyCallback = () => void;
export type ActivationCallback = (featureName: string, variation: VariationValue, attributes: Attributes, captureAttributes: Attributes) => void;
export type ConfigureBucketKey = (feature: any, attributes: any, bucketKey: BucketKey) => BucketKey;
export type ConfigureBucketValue = (feature: any, attributes: any, bucketValue: BucketValue) => BucketValue;
export type ActivationCallback = (featureName: string, variation: VariationValue, context: Context, captureContext: Context) => void;
export type ConfigureBucketKey = (feature: any, context: any, bucketKey: BucketKey) => BucketKey;
export type ConfigureBucketValue = (feature: any, context: any, bucketValue: BucketValue) => BucketValue;
export interface Statuses {

@@ -12,2 +12,3 @@ ready: boolean;

}
export type InterceptContext = (context: Context) => Context;
export interface InstanceOptions {

@@ -21,3 +22,3 @@ bucketKeySeparator?: string;

initialFeatures?: InitialFeatures;
interceptAttributes?: (attributes: Attributes) => Attributes;
interceptContext?: InterceptContext;
logger?: Logger;

@@ -65,3 +66,3 @@ onActivation?: ActivationCallback;

private initialFeatures?;
private interceptAttributes?;
private interceptContext?;
private logger;

@@ -102,30 +103,30 @@ private refreshInterval?;

*/
evaluateVariation(featureKey: FeatureKey | Feature, attributes?: Attributes): Evaluation;
getVariation(featureKey: FeatureKey | Feature, attributes?: Attributes): VariationValue | undefined;
getVariationBoolean(featureKey: FeatureKey | Feature, attributes?: Attributes): boolean | undefined;
getVariationString(featureKey: FeatureKey | Feature, attributes?: Attributes): string | undefined;
getVariationInteger(featureKey: FeatureKey | Feature, attributes?: Attributes): number | undefined;
getVariationDouble(featureKey: FeatureKey | Feature, attributes?: Attributes): number | undefined;
evaluateVariation(featureKey: FeatureKey | Feature, context?: Context): Evaluation;
getVariation(featureKey: FeatureKey | Feature, context?: Context): VariationValue | undefined;
getVariationBoolean(featureKey: FeatureKey | Feature, context?: Context): boolean | undefined;
getVariationString(featureKey: FeatureKey | Feature, context?: Context): string | undefined;
getVariationInteger(featureKey: FeatureKey | Feature, context?: Context): number | undefined;
getVariationDouble(featureKey: FeatureKey | Feature, context?: Context): number | undefined;
/**
* Activate
*/
activate(featureKey: FeatureKey, attributes?: Attributes): VariationValue | undefined;
activateBoolean(featureKey: FeatureKey, attributes?: Attributes): boolean | undefined;
activateString(featureKey: FeatureKey, attributes?: Attributes): string | undefined;
activateInteger(featureKey: FeatureKey, attributes?: Attributes): number | undefined;
activateDouble(featureKey: FeatureKey, attributes?: Attributes): number | undefined;
activate(featureKey: FeatureKey, context?: Context): VariationValue | undefined;
activateBoolean(featureKey: FeatureKey, context?: Context): boolean | undefined;
activateString(featureKey: FeatureKey, context?: Context): string | undefined;
activateInteger(featureKey: FeatureKey, context?: Context): number | undefined;
activateDouble(featureKey: FeatureKey, context?: Context): number | undefined;
/**
* Variable
*/
evaluateVariable(featureKey: FeatureKey | Feature, variableKey: VariableKey, attributes?: Attributes): Evaluation;
getVariable(featureKey: FeatureKey | Feature, variableKey: string, attributes?: Attributes): VariableValue | undefined;
getVariableBoolean(featureKey: FeatureKey | Feature, variableKey: string, attributes?: Attributes): boolean | undefined;
getVariableString(featureKey: FeatureKey | Feature, variableKey: string, attributes?: Attributes): string | undefined;
getVariableInteger(featureKey: FeatureKey | Feature, variableKey: string, attributes?: Attributes): number | undefined;
getVariableDouble(featureKey: FeatureKey | Feature, variableKey: string, attributes?: Attributes): number | undefined;
getVariableArray(featureKey: FeatureKey | Feature, variableKey: string, attributes?: Attributes): string[] | undefined;
getVariableObject<T>(featureKey: FeatureKey | Feature, variableKey: string, attributes?: Attributes): T | undefined;
getVariableJSON<T>(featureKey: FeatureKey | Feature, variableKey: string, attributes?: Attributes): T | undefined;
evaluateVariable(featureKey: FeatureKey | Feature, variableKey: VariableKey, context?: Context): Evaluation;
getVariable(featureKey: FeatureKey | Feature, variableKey: string, context?: Context): VariableValue | undefined;
getVariableBoolean(featureKey: FeatureKey | Feature, variableKey: string, context?: Context): boolean | undefined;
getVariableString(featureKey: FeatureKey | Feature, variableKey: string, context?: Context): string | undefined;
getVariableInteger(featureKey: FeatureKey | Feature, variableKey: string, context?: Context): number | undefined;
getVariableDouble(featureKey: FeatureKey | Feature, variableKey: string, context?: Context): number | undefined;
getVariableArray(featureKey: FeatureKey | Feature, variableKey: string, context?: Context): string[] | undefined;
getVariableObject<T>(featureKey: FeatureKey | Feature, variableKey: string, context?: Context): T | undefined;
getVariableJSON<T>(featureKey: FeatureKey | Feature, variableKey: string, context?: Context): T | undefined;
}
export declare function createInstance(options: InstanceOptions): FeaturevisorInstance;
export {};

@@ -71,3 +71,3 @@ import { createLogger } from "./logger";

this.initialFeatures = options.initialFeatures;
this.interceptAttributes = options.interceptAttributes;
this.interceptContext = options.interceptContext;
this.logger = options.logger || createLogger();

@@ -152,3 +152,3 @@ this.refreshInterval = options.refreshInterval;

*/
FeaturevisorInstance.prototype.getBucketKey = function (feature, attributes) {
FeaturevisorInstance.prototype.getBucketKey = function (feature, context) {
var featureKey = feature.key;

@@ -175,3 +175,3 @@ var type;

attributeKeys.forEach(function (attributeKey) {
var attributeValue = attributes[attributeKey];
var attributeValue = context[attributeKey];
if (typeof attributeValue === "undefined") {

@@ -193,11 +193,11 @@ return;

if (this.configureBucketKey) {
return this.configureBucketKey(feature, attributes, result);
return this.configureBucketKey(feature, context, result);
}
return result;
};
FeaturevisorInstance.prototype.getBucketValue = function (feature, attributes) {
var bucketKey = this.getBucketKey(feature, attributes);
FeaturevisorInstance.prototype.getBucketValue = function (feature, context) {
var bucketKey = this.getBucketKey(feature, context);
var value = getBucketedNumber(bucketKey);
if (this.configureBucketValue) {
return this.configureBucketValue(feature, attributes, value);
return this.configureBucketValue(feature, context, value);
}

@@ -267,4 +267,4 @@ return value;

*/
FeaturevisorInstance.prototype.evaluateVariation = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
FeaturevisorInstance.prototype.evaluateVariation = function (featureKey, context) {
if (context === void 0) { context = {}; }
var evaluation;

@@ -311,7 +311,5 @@ try {

}
var finalAttributes = this.interceptAttributes
? this.interceptAttributes(attributes)
: attributes;
var finalContext = this.interceptContext ? this.interceptContext(context) : context;
// forced
var force_1 = findForceFromFeature(feature_1, attributes, this.datafileReader);
var force_1 = findForceFromFeature(feature_1, context, this.datafileReader);
if (force_1 && force_1.variation) {

@@ -330,4 +328,4 @@ var variation_1 = feature_1.variations.find(function (v) { return v.value === force_1.variation; });

// bucketing
var bucketValue = this.getBucketValue(feature_1, finalAttributes);
var _a = getMatchedTrafficAndAllocation(feature_1.traffic, finalAttributes, bucketValue, this.datafileReader, this.logger), matchedTraffic_1 = _a.matchedTraffic, matchedAllocation_1 = _a.matchedAllocation;
var bucketValue = this.getBucketValue(feature_1, finalContext);
var _a = getMatchedTrafficAndAllocation(feature_1.traffic, finalContext, bucketValue, this.datafileReader, this.logger), matchedTraffic_1 = _a.matchedTraffic, matchedAllocation_1 = _a.matchedAllocation;
if (matchedTraffic_1) {

@@ -394,6 +392,6 @@ // override from rule

};
FeaturevisorInstance.prototype.getVariation = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
FeaturevisorInstance.prototype.getVariation = function (featureKey, context) {
if (context === void 0) { context = {}; }
try {
var evaluation = this.evaluateVariation(featureKey, attributes);
var evaluation = this.evaluateVariation(featureKey, context);
if (typeof evaluation.variationValue !== "undefined") {

@@ -412,20 +410,20 @@ return evaluation.variationValue;

};
FeaturevisorInstance.prototype.getVariationBoolean = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variationValue = this.getVariation(featureKey, attributes);
FeaturevisorInstance.prototype.getVariationBoolean = function (featureKey, context) {
if (context === void 0) { context = {}; }
var variationValue = this.getVariation(featureKey, context);
return getValueByType(variationValue, "boolean");
};
FeaturevisorInstance.prototype.getVariationString = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variationValue = this.getVariation(featureKey, attributes);
FeaturevisorInstance.prototype.getVariationString = function (featureKey, context) {
if (context === void 0) { context = {}; }
var variationValue = this.getVariation(featureKey, context);
return getValueByType(variationValue, "string");
};
FeaturevisorInstance.prototype.getVariationInteger = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variationValue = this.getVariation(featureKey, attributes);
FeaturevisorInstance.prototype.getVariationInteger = function (featureKey, context) {
if (context === void 0) { context = {}; }
var variationValue = this.getVariation(featureKey, context);
return getValueByType(variationValue, "integer");
};
FeaturevisorInstance.prototype.getVariationDouble = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variationValue = this.getVariation(featureKey, attributes);
FeaturevisorInstance.prototype.getVariationDouble = function (featureKey, context) {
if (context === void 0) { context = {}; }
var variationValue = this.getVariation(featureKey, context);
return getValueByType(variationValue, "double");

@@ -436,6 +434,6 @@ };

*/
FeaturevisorInstance.prototype.activate = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
FeaturevisorInstance.prototype.activate = function (featureKey, context) {
if (context === void 0) { context = {}; }
try {
var evaluation = this.evaluateVariation(featureKey, attributes);
var evaluation = this.evaluateVariation(featureKey, context);
var variationValue = evaluation.variation

@@ -447,6 +445,4 @@ ? evaluation.variation.value

}
var finalAttributes_1 = this.interceptAttributes
? this.interceptAttributes(attributes)
: attributes;
var captureAttributes_1 = {};
var finalContext_1 = this.interceptContext ? this.interceptContext(context) : context;
var captureContext_1 = {};
var attributesForCapturing = this.datafileReader

@@ -456,7 +452,7 @@ .getAllAttributes()

attributesForCapturing.forEach(function (a) {
if (typeof finalAttributes_1[a.key] !== "undefined") {
captureAttributes_1[a.key] = attributes[a.key];
if (typeof finalContext_1[a.key] !== "undefined") {
captureContext_1[a.key] = context[a.key];
}
});
this.emitter.emit("activation", featureKey, variationValue, finalAttributes_1, captureAttributes_1, evaluation);
this.emitter.emit("activation", featureKey, variationValue, finalContext_1, captureContext_1, evaluation);
return variationValue;

@@ -469,20 +465,20 @@ }

};
FeaturevisorInstance.prototype.activateBoolean = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variationValue = this.activate(featureKey, attributes);
FeaturevisorInstance.prototype.activateBoolean = function (featureKey, context) {
if (context === void 0) { context = {}; }
var variationValue = this.activate(featureKey, context);
return getValueByType(variationValue, "boolean");
};
FeaturevisorInstance.prototype.activateString = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variationValue = this.activate(featureKey, attributes);
FeaturevisorInstance.prototype.activateString = function (featureKey, context) {
if (context === void 0) { context = {}; }
var variationValue = this.activate(featureKey, context);
return getValueByType(variationValue, "string");
};
FeaturevisorInstance.prototype.activateInteger = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variationValue = this.activate(featureKey, attributes);
FeaturevisorInstance.prototype.activateInteger = function (featureKey, context) {
if (context === void 0) { context = {}; }
var variationValue = this.activate(featureKey, context);
return getValueByType(variationValue, "integer");
};
FeaturevisorInstance.prototype.activateDouble = function (featureKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variationValue = this.activate(featureKey, attributes);
FeaturevisorInstance.prototype.activateDouble = function (featureKey, context) {
if (context === void 0) { context = {}; }
var variationValue = this.activate(featureKey, context);
return getValueByType(variationValue, "double");

@@ -493,5 +489,5 @@ };

*/
FeaturevisorInstance.prototype.evaluateVariable = function (featureKey, variableKey, attributes) {
FeaturevisorInstance.prototype.evaluateVariable = function (featureKey, variableKey, context) {
var _this = this;
if (attributes === void 0) { attributes = {}; }
if (context === void 0) { context = {}; }
var evaluation;

@@ -554,7 +550,5 @@ try {

}
var finalAttributes_2 = this.interceptAttributes
? this.interceptAttributes(attributes)
: attributes;
var finalContext_2 = this.interceptContext ? this.interceptContext(context) : context;
// forced
var force = findForceFromFeature(feature, attributes, this.datafileReader);
var force = findForceFromFeature(feature, context, this.datafileReader);
if (force && force.variables && typeof force.variables[variableKey] !== "undefined") {

@@ -572,4 +566,4 @@ evaluation = {

// bucketing
var bucketValue = this.getBucketValue(feature, finalAttributes_2);
var _a = getMatchedTrafficAndAllocation(feature.traffic, finalAttributes_2, bucketValue, this.datafileReader, this.logger), matchedTraffic = _a.matchedTraffic, matchedAllocation_2 = _a.matchedAllocation;
var bucketValue = this.getBucketValue(feature, finalContext_2);
var _a = getMatchedTrafficAndAllocation(feature.traffic, finalContext_2, bucketValue, this.datafileReader, this.logger), matchedTraffic = _a.matchedTraffic, matchedAllocation_2 = _a.matchedAllocation;
if (matchedTraffic) {

@@ -600,3 +594,3 @@ // override from rule

if (o.conditions) {
return allConditionsAreMatched(typeof o.conditions === "string" ? JSON.parse(o.conditions) : o.conditions, finalAttributes_2);
return allConditionsAreMatched(typeof o.conditions === "string" ? JSON.parse(o.conditions) : o.conditions, finalContext_2);
}

@@ -606,3 +600,3 @@ if (o.segments) {

? JSON.parse(o.segments)
: o.segments, finalAttributes_2, _this.datafileReader);
: o.segments, finalContext_2, _this.datafileReader);
}

@@ -664,6 +658,6 @@ return false;

};
FeaturevisorInstance.prototype.getVariable = function (featureKey, variableKey, attributes) {
if (attributes === void 0) { attributes = {}; }
FeaturevisorInstance.prototype.getVariable = function (featureKey, variableKey, context) {
if (context === void 0) { context = {}; }
try {
var evaluation = this.evaluateVariable(featureKey, variableKey, attributes);
var evaluation = this.evaluateVariable(featureKey, variableKey, context);
if (typeof evaluation.variableValue !== "undefined") {

@@ -684,35 +678,35 @@ if (evaluation.variableSchema &&

};
FeaturevisorInstance.prototype.getVariableBoolean = function (featureKey, variableKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variableValue = this.getVariable(featureKey, variableKey, attributes);
FeaturevisorInstance.prototype.getVariableBoolean = function (featureKey, variableKey, context) {
if (context === void 0) { context = {}; }
var variableValue = this.getVariable(featureKey, variableKey, context);
return getValueByType(variableValue, "boolean");
};
FeaturevisorInstance.prototype.getVariableString = function (featureKey, variableKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variableValue = this.getVariable(featureKey, variableKey, attributes);
FeaturevisorInstance.prototype.getVariableString = function (featureKey, variableKey, context) {
if (context === void 0) { context = {}; }
var variableValue = this.getVariable(featureKey, variableKey, context);
return getValueByType(variableValue, "string");
};
FeaturevisorInstance.prototype.getVariableInteger = function (featureKey, variableKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variableValue = this.getVariable(featureKey, variableKey, attributes);
FeaturevisorInstance.prototype.getVariableInteger = function (featureKey, variableKey, context) {
if (context === void 0) { context = {}; }
var variableValue = this.getVariable(featureKey, variableKey, context);
return getValueByType(variableValue, "integer");
};
FeaturevisorInstance.prototype.getVariableDouble = function (featureKey, variableKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variableValue = this.getVariable(featureKey, variableKey, attributes);
FeaturevisorInstance.prototype.getVariableDouble = function (featureKey, variableKey, context) {
if (context === void 0) { context = {}; }
var variableValue = this.getVariable(featureKey, variableKey, context);
return getValueByType(variableValue, "double");
};
FeaturevisorInstance.prototype.getVariableArray = function (featureKey, variableKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variableValue = this.getVariable(featureKey, variableKey, attributes);
FeaturevisorInstance.prototype.getVariableArray = function (featureKey, variableKey, context) {
if (context === void 0) { context = {}; }
var variableValue = this.getVariable(featureKey, variableKey, context);
return getValueByType(variableValue, "array");
};
FeaturevisorInstance.prototype.getVariableObject = function (featureKey, variableKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variableValue = this.getVariable(featureKey, variableKey, attributes);
FeaturevisorInstance.prototype.getVariableObject = function (featureKey, variableKey, context) {
if (context === void 0) { context = {}; }
var variableValue = this.getVariable(featureKey, variableKey, context);
return getValueByType(variableValue, "object");
};
FeaturevisorInstance.prototype.getVariableJSON = function (featureKey, variableKey, attributes) {
if (attributes === void 0) { attributes = {}; }
var variableValue = this.getVariable(featureKey, variableKey, attributes);
FeaturevisorInstance.prototype.getVariableJSON = function (featureKey, variableKey, context) {
if (context === void 0) { context = {}; }
var variableValue = this.getVariable(featureKey, variableKey, context);
return getValueByType(variableValue, "json");

@@ -719,0 +713,0 @@ };

@@ -1,4 +0,4 @@

import { Attributes, GroupSegment, Segment } from "@featurevisor/types";
import { Context, GroupSegment, Segment } from "@featurevisor/types";
import { DatafileReader } from "./datafileReader";
export declare function segmentIsMatched(segment: Segment, attributes: Attributes): boolean;
export declare function allGroupSegmentsAreMatched(groupSegments: GroupSegment | GroupSegment[] | "*", attributes: Attributes, datafileReader: DatafileReader): boolean;
export declare function segmentIsMatched(segment: Segment, context: Context): boolean;
export declare function allGroupSegmentsAreMatched(groupSegments: GroupSegment | GroupSegment[] | "*", context: Context, datafileReader: DatafileReader): boolean;
import { allConditionsAreMatched } from "./conditions";
export function segmentIsMatched(segment, attributes) {
return allConditionsAreMatched(segment.conditions, attributes);
export function segmentIsMatched(segment, context) {
return allConditionsAreMatched(segment.conditions, context);
}
export function allGroupSegmentsAreMatched(groupSegments, attributes, datafileReader) {
export function allGroupSegmentsAreMatched(groupSegments, context, datafileReader) {
if (groupSegments === "*") {

@@ -12,3 +12,3 @@ return true;

if (segment) {
return segmentIsMatched(segment, attributes);
return segmentIsMatched(segment, context);
}

@@ -20,3 +20,3 @@ return false;

return groupSegments.and.every(function (groupSegment) {
return allGroupSegmentsAreMatched(groupSegment, attributes, datafileReader);
return allGroupSegmentsAreMatched(groupSegment, context, datafileReader);
});

@@ -26,3 +26,3 @@ }

return groupSegments.or.some(function (groupSegment) {
return allGroupSegmentsAreMatched(groupSegment, attributes, datafileReader);
return allGroupSegmentsAreMatched(groupSegment, context, datafileReader);
});

@@ -32,3 +32,3 @@ }

return groupSegments.not.every(function (groupSegment) {
return allGroupSegmentsAreMatched(groupSegment, attributes, datafileReader) === false;
return allGroupSegmentsAreMatched(groupSegment, context, datafileReader) === false;
});

@@ -39,3 +39,3 @@ }

return groupSegments.every(function (groupSegment) {
return allGroupSegmentsAreMatched(groupSegment, attributes, datafileReader);
return allGroupSegmentsAreMatched(groupSegment, context, datafileReader);
});

@@ -42,0 +42,0 @@ }

{
"name": "@featurevisor/sdk",
"version": "0.36.0",
"version": "0.37.0",
"description": "Featurevisor SDK for Node.js and the browser",

@@ -45,7 +45,7 @@ "main": "dist/index.js",

"dependencies": {
"@featurevisor/types": "^0.36.0",
"@featurevisor/types": "^0.37.0",
"compare-versions": "^6.0.0-rc.1",
"murmurhash": "^2.0.1"
},
"gitHead": "a8591d17d227b56f93cb59d13de7fce4d20b2890"
"gitHead": "1944f2ea8e86d07c7031720cd0b407bea547d0cb"
}

@@ -17,3 +17,3 @@ # @featurevisor/sdk <!-- omit in toc -->

- [`initialFeatures`](#initialfeatures)
- [`interceptAttributes`](#interceptattributes)
- [`interceptContext`](#interceptcontext)
- [`logger`](#logger)

@@ -74,3 +74,3 @@ - [`onActivation`](#onactivation)

const sdk = createInstance({
configureBucketKey: (feature, attributes, bucketKey) => {
configureBucketKey: (feature, context, bucketKey) => {
return bucketKey;

@@ -90,3 +90,3 @@ }

const sdk = createInstance({
configureBucketValue: (feature, attributes, bucketValue) => {
configureBucketValue: (feature, context, bucketValue) => {
return bucketValue; // 0 to 100,000

@@ -149,3 +149,3 @@ }

### `interceptAttributes`
### `interceptContext`

@@ -155,6 +155,6 @@ - Type: `function`

Intercept given attributes before they are used to bucket the user:
Intercept given context before they are used to bucket the user:
```js
const defaultAttributes = {
const defaultContext = {
platform: "web",

@@ -168,6 +168,6 @@ locale: "en-US",

const sdk = createInstance({
interceptAttributes: (attributes) => {
interceptContext: (context) => {
return {
...defaultAttributes,
...attributes,
...defaultContext,
...context,
};

@@ -207,3 +207,3 @@ }

const sdk = createInstance({
onActivation: (featureKey, variation, attributes, captureAttributes) => {
onActivation: (featureKey, variation, context, captureContext) => {
// do something with the activated feature

@@ -214,3 +214,3 @@ }

`captureAttributes` will only contain attributes that are marked as `capture: true` in the Attributes' YAML files.
`captureContext` will only contain attributes that are marked as `capture: true` in the Attributes' YAML files.

@@ -307,3 +307,3 @@ ### `onReady`

> `getVariation(featureKey: string, attributes: Attributes): VariationValue`
> `getVariation(featureKey: string, context: Context): VariationValue`

@@ -319,3 +319,3 @@ Also supports additional type specific methods:

> `getVariable(featureKey: string, variableKey: string, attributes: Attributes): VariableValue`
> `getVariable(featureKey: string, variableKey: string, context: Context): VariableValue`

@@ -334,3 +334,3 @@ Also supports additional type specific methods:

> `activate(featureKey: string, attributes: Attributes): VariationValue`
> `activate(featureKey: string, context: Context): VariationValue`

@@ -337,0 +337,0 @@ Same as `getVariation`, but also calls the `onActivation` callback.

import { compareVersions } from "compare-versions";
import { Attributes, Condition, PlainCondition } from "@featurevisor/types";
import { Context, Condition, PlainCondition } from "@featurevisor/types";
export function conditionIsMatched(condition: PlainCondition, attributes: Attributes): boolean {
export function conditionIsMatched(condition: PlainCondition, context: Context): boolean {
const { attribute, operator, value } = condition;
if (operator === "equals") {
return attributes[attribute] === value;
return context[attribute] === value;
} else if (operator === "notEquals") {
return attributes[attribute] !== value;
return context[attribute] !== value;
} else if (operator === "before" || operator === "after") {
// date comparisons
const valueInAttributes = attributes[attribute] as string | Date;
const valueInContext = context[attribute] as string | Date;
const dateInAttributes =
valueInAttributes instanceof Date ? valueInAttributes : new Date(valueInAttributes);
const dateInContext =
valueInContext instanceof Date ? valueInContext : new Date(valueInContext);
const dateInCondition = value instanceof Date ? value : new Date(value as string);
return operator === "before"
? dateInAttributes < dateInCondition
: dateInAttributes > dateInCondition;
} else if (typeof attributes[attribute] === "string" && Array.isArray(value)) {
? dateInContext < dateInCondition
: dateInContext > dateInCondition;
} else if (typeof context[attribute] === "string" && Array.isArray(value)) {
// array
const valueInAttributes = attributes[attribute] as string;
const valueInContext = context[attribute] as string;
if (operator === "in") {
return value.indexOf(valueInAttributes) !== -1;
return value.indexOf(valueInContext) !== -1;
} else if (operator === "notIn") {
return value.indexOf(valueInAttributes) === -1;
return value.indexOf(valueInContext) === -1;
}
} else if (typeof attributes[attribute] === "string" && typeof value === "string") {
} else if (typeof context[attribute] === "string" && typeof value === "string") {
// string
const valueInAttributes = attributes[attribute] as string;
const valueInContext = context[attribute] as string;
if (operator === "contains") {
return valueInAttributes.indexOf(value) !== -1;
return valueInContext.indexOf(value) !== -1;
} else if (operator === "notContains") {
return valueInAttributes.indexOf(value) === -1;
return valueInContext.indexOf(value) === -1;
} else if (operator === "startsWith") {
return valueInAttributes.startsWith(value);
return valueInContext.startsWith(value);
} else if (operator === "endsWith") {
return valueInAttributes.endsWith(value);
return valueInContext.endsWith(value);
} else if (operator === "semverEquals") {
return compareVersions(valueInAttributes, value) === 0;
return compareVersions(valueInContext, value) === 0;
} else if (operator === "semverNotEquals") {
return compareVersions(valueInAttributes, value) !== 0;
return compareVersions(valueInContext, value) !== 0;
} else if (operator === "semverGreaterThan") {
return compareVersions(valueInAttributes, value) === 1;
return compareVersions(valueInContext, value) === 1;
} else if (operator === "semverGreaterThanOrEquals") {
return compareVersions(valueInAttributes, value) >= 0;
return compareVersions(valueInContext, value) >= 0;
} else if (operator === "semverLessThan") {
return compareVersions(valueInAttributes, value) === -1;
return compareVersions(valueInContext, value) === -1;
} else if (operator === "semverLessThanOrEquals") {
return compareVersions(valueInAttributes, value) <= 0;
return compareVersions(valueInContext, value) <= 0;
}
} else if (typeof attributes[attribute] === "number" && typeof value === "number") {
} else if (typeof context[attribute] === "number" && typeof value === "number") {
// numeric
const valueInAttributes = attributes[attribute] as number;
const valueInContext = context[attribute] as number;
if (operator === "greaterThan") {
return valueInAttributes > value;
return valueInContext > value;
} else if (operator === "greaterThanOrEquals") {
return valueInAttributes >= value;
return valueInContext >= value;
} else if (operator === "lessThan") {
return valueInAttributes < value;
return valueInContext < value;
} else if (operator === "lessThanOrEquals") {
return valueInAttributes <= value;
return valueInContext <= value;
}

@@ -77,14 +77,14 @@ }

conditions: Condition[] | Condition,
attributes: Attributes,
context: Context,
): boolean {
if ("attribute" in conditions) {
return conditionIsMatched(conditions, attributes);
return conditionIsMatched(conditions, context);
}
if ("and" in conditions && Array.isArray(conditions.and)) {
return conditions.and.every((c) => allConditionsAreMatched(c, attributes));
return conditions.and.every((c) => allConditionsAreMatched(c, context));
}
if ("or" in conditions && Array.isArray(conditions.or)) {
return conditions.or.some((c) => allConditionsAreMatched(c, attributes));
return conditions.or.some((c) => allConditionsAreMatched(c, context));
}

@@ -99,3 +99,3 @@

},
attributes,
context,
) === false,

@@ -106,3 +106,3 @@ );

if (Array.isArray(conditions)) {
return conditions.every((c) => allConditionsAreMatched(c, attributes));
return conditions.every((c) => allConditionsAreMatched(c, context));
}

@@ -109,0 +109,0 @@

@@ -1,2 +0,2 @@

import { Allocation, Attributes, Traffic, Feature, Force } from "@featurevisor/types";
import { Allocation, Context, Traffic, Feature, Force } from "@featurevisor/types";
import { DatafileReader } from "./datafileReader";

@@ -29,3 +29,3 @@ import { allGroupSegmentsAreMatched } from "./segments";

traffic: Traffic[],
attributes: Attributes,
context: Context,
bucketValue: number,

@@ -41,3 +41,3 @@ datafileReader: DatafileReader,

typeof t.segments === "string" && t.segments !== "*" ? JSON.parse(t.segments) : t.segments,
attributes,
context,
datafileReader,

@@ -66,3 +66,3 @@ )

feature: Feature,
attributes: Attributes,
context: Context,
datafileReader: DatafileReader,

@@ -76,7 +76,7 @@ ): Force | undefined {

if (f.conditions) {
return allConditionsAreMatched(f.conditions, attributes);
return allConditionsAreMatched(f.conditions, context);
}
if (f.segments) {
return allGroupSegmentsAreMatched(f.segments, attributes, datafileReader);
return allGroupSegmentsAreMatched(f.segments, context, datafileReader);
}

@@ -83,0 +83,0 @@

@@ -76,3 +76,3 @@ import { DatafileContent } from "@featurevisor/types";

},
configureBucketKey: function (feature, attributes, bucketKey) {
configureBucketKey: function (feature, context, bucketKey) {
capturedBucketKey = bucketKey;

@@ -121,3 +121,3 @@

},
configureBucketKey: function (feature, attributes, bucketKey) {
configureBucketKey: function (feature, context, bucketKey) {
capturedBucketKey = bucketKey;

@@ -167,3 +167,3 @@

},
configureBucketKey: function (feature, attributes, bucketKey) {
configureBucketKey: function (feature, context, bucketKey) {
capturedBucketKey = bucketKey;

@@ -191,3 +191,3 @@

it("should intercept attributes", function () {
it("should intercept context", function () {
let intercepted = false;

@@ -221,7 +221,7 @@

},
interceptAttributes: function (attributes) {
interceptContext: function (context) {
intercepted = true;
return {
...attributes,
...context,
};

@@ -228,0 +228,0 @@ },

import {
Attributes,
Context,
AttributeValue,

@@ -34,9 +34,9 @@ BucketKey,

variation: VariationValue,
attributes: Attributes,
captureAttributes: Attributes,
context: Context,
captureContext: Context,
) => void;
export type ConfigureBucketKey = (feature, attributes, bucketKey: BucketKey) => BucketKey;
export type ConfigureBucketKey = (feature, context, bucketKey: BucketKey) => BucketKey;
export type ConfigureBucketValue = (feature, attributes, bucketValue: BucketValue) => BucketValue;
export type ConfigureBucketValue = (feature, context, bucketValue: BucketValue) => BucketValue;

@@ -50,2 +50,4 @@ export interface Statuses {

export type InterceptContext = (context: Context) => Context;
export interface InstanceOptions {

@@ -59,3 +61,3 @@ bucketKeySeparator?: string;

initialFeatures?: InitialFeatures;
interceptAttributes?: (attributes: Attributes) => Attributes;
interceptContext?: InterceptContext;
logger?: Logger;

@@ -162,3 +164,3 @@ onActivation?: ActivationCallback;

private initialFeatures?: InitialFeatures;
private interceptAttributes?: (attributes: Attributes) => Attributes;
private interceptContext?: InterceptContext;
private logger: Logger;

@@ -189,3 +191,3 @@ private refreshInterval?: number; // seconds

this.initialFeatures = options.initialFeatures;
this.interceptAttributes = options.interceptAttributes;
this.interceptContext = options.interceptContext;
this.logger = options.logger || createLogger();

@@ -289,3 +291,3 @@ this.refreshInterval = options.refreshInterval;

*/
private getBucketKey(feature: Feature, attributes: Attributes): BucketKey {
private getBucketKey(feature: Feature, context: Context): BucketKey {
const featureKey = feature.key;

@@ -314,3 +316,3 @@

attributeKeys.forEach((attributeKey) => {
const attributeValue = attributes[attributeKey];
const attributeValue = context[attributeKey];

@@ -336,3 +338,3 @@ if (typeof attributeValue === "undefined") {

if (this.configureBucketKey) {
return this.configureBucketKey(feature, attributes, result);
return this.configureBucketKey(feature, context, result);
}

@@ -343,4 +345,4 @@

private getBucketValue(feature: Feature, attributes: Attributes): BucketValue {
const bucketKey = this.getBucketKey(feature, attributes);
private getBucketValue(feature: Feature, context: Context): BucketValue {
const bucketKey = this.getBucketKey(feature, context);

@@ -350,3 +352,3 @@ const value = getBucketedNumber(bucketKey);

if (this.configureBucketValue) {
return this.configureBucketValue(feature, attributes, value);
return this.configureBucketValue(feature, context, value);
}

@@ -432,3 +434,3 @@

*/
evaluateVariation(featureKey: FeatureKey | Feature, attributes: Attributes = {}): Evaluation {
evaluateVariation(featureKey: FeatureKey | Feature, context: Context = {}): Evaluation {
let evaluation: Evaluation;

@@ -491,8 +493,6 @@

const finalAttributes = this.interceptAttributes
? this.interceptAttributes(attributes)
: attributes;
const finalContext = this.interceptContext ? this.interceptContext(context) : context;
// forced
const force = findForceFromFeature(feature, attributes, this.datafileReader);
const force = findForceFromFeature(feature, context, this.datafileReader);

@@ -516,7 +516,7 @@ if (force && force.variation) {

// bucketing
const bucketValue = this.getBucketValue(feature, finalAttributes);
const bucketValue = this.getBucketValue(feature, finalContext);
const { matchedTraffic, matchedAllocation } = getMatchedTrafficAndAllocation(
feature.traffic,
finalAttributes,
finalContext,
bucketValue,

@@ -605,6 +605,6 @@ this.datafileReader,

featureKey: FeatureKey | Feature,
attributes: Attributes = {},
context: Context = {},
): VariationValue | undefined {
try {
const evaluation = this.evaluateVariation(featureKey, attributes);
const evaluation = this.evaluateVariation(featureKey, context);

@@ -629,5 +629,5 @@ if (typeof evaluation.variationValue !== "undefined") {

featureKey: FeatureKey | Feature,
attributes: Attributes = {},
context: Context = {},
): boolean | undefined {
const variationValue = this.getVariation(featureKey, attributes);
const variationValue = this.getVariation(featureKey, context);

@@ -637,7 +637,4 @@ return getValueByType(variationValue, "boolean") as boolean | undefined;

getVariationString(
featureKey: FeatureKey | Feature,
attributes: Attributes = {},
): string | undefined {
const variationValue = this.getVariation(featureKey, attributes);
getVariationString(featureKey: FeatureKey | Feature, context: Context = {}): string | undefined {
const variationValue = this.getVariation(featureKey, context);

@@ -647,7 +644,4 @@ return getValueByType(variationValue, "string") as string | undefined;

getVariationInteger(
featureKey: FeatureKey | Feature,
attributes: Attributes = {},
): number | undefined {
const variationValue = this.getVariation(featureKey, attributes);
getVariationInteger(featureKey: FeatureKey | Feature, context: Context = {}): number | undefined {
const variationValue = this.getVariation(featureKey, context);

@@ -657,7 +651,4 @@ return getValueByType(variationValue, "integer") as number | undefined;

getVariationDouble(
featureKey: FeatureKey | Feature,
attributes: Attributes = {},
): number | undefined {
const variationValue = this.getVariation(featureKey, attributes);
getVariationDouble(featureKey: FeatureKey | Feature, context: Context = {}): number | undefined {
const variationValue = this.getVariation(featureKey, context);

@@ -670,5 +661,5 @@ return getValueByType(variationValue, "double") as number | undefined;

*/
activate(featureKey: FeatureKey, attributes: Attributes = {}): VariationValue | undefined {
activate(featureKey: FeatureKey, context: Context = {}): VariationValue | undefined {
try {
const evaluation = this.evaluateVariation(featureKey, attributes);
const evaluation = this.evaluateVariation(featureKey, context);
const variationValue = evaluation.variation

@@ -682,7 +673,5 @@ ? evaluation.variation.value

const finalAttributes = this.interceptAttributes
? this.interceptAttributes(attributes)
: attributes;
const finalContext = this.interceptContext ? this.interceptContext(context) : context;
const captureAttributes: Attributes = {};
const captureContext: Context = {};

@@ -694,4 +683,4 @@ const attributesForCapturing = this.datafileReader

attributesForCapturing.forEach((a) => {
if (typeof finalAttributes[a.key] !== "undefined") {
captureAttributes[a.key] = attributes[a.key];
if (typeof finalContext[a.key] !== "undefined") {
captureContext[a.key] = context[a.key];
}

@@ -704,4 +693,4 @@ });

variationValue,
finalAttributes,
captureAttributes,
finalContext,
captureContext,
evaluation,

@@ -718,4 +707,4 @@ );

activateBoolean(featureKey: FeatureKey, attributes: Attributes = {}): boolean | undefined {
const variationValue = this.activate(featureKey, attributes);
activateBoolean(featureKey: FeatureKey, context: Context = {}): boolean | undefined {
const variationValue = this.activate(featureKey, context);

@@ -725,4 +714,4 @@ return getValueByType(variationValue, "boolean") as boolean | undefined;

activateString(featureKey: FeatureKey, attributes: Attributes = {}): string | undefined {
const variationValue = this.activate(featureKey, attributes);
activateString(featureKey: FeatureKey, context: Context = {}): string | undefined {
const variationValue = this.activate(featureKey, context);

@@ -732,4 +721,4 @@ return getValueByType(variationValue, "string") as string | undefined;

activateInteger(featureKey: FeatureKey, attributes: Attributes = {}): number | undefined {
const variationValue = this.activate(featureKey, attributes);
activateInteger(featureKey: FeatureKey, context: Context = {}): number | undefined {
const variationValue = this.activate(featureKey, context);

@@ -739,4 +728,4 @@ return getValueByType(variationValue, "integer") as number | undefined;

activateDouble(featureKey: FeatureKey, attributes: Attributes = {}): number | undefined {
const variationValue = this.activate(featureKey, attributes);
activateDouble(featureKey: FeatureKey, context: Context = {}): number | undefined {
const variationValue = this.activate(featureKey, context);

@@ -752,3 +741,3 @@ return getValueByType(variationValue, "double") as number | undefined;

variableKey: VariableKey,
attributes: Attributes = {},
context: Context = {},
): Evaluation {

@@ -831,8 +820,6 @@ let evaluation: Evaluation;

const finalAttributes = this.interceptAttributes
? this.interceptAttributes(attributes)
: attributes;
const finalContext = this.interceptContext ? this.interceptContext(context) : context;
// forced
const force = findForceFromFeature(feature, attributes, this.datafileReader);
const force = findForceFromFeature(feature, context, this.datafileReader);

@@ -854,7 +841,7 @@ if (force && force.variables && typeof force.variables[variableKey] !== "undefined") {

// bucketing
const bucketValue = this.getBucketValue(feature, finalAttributes);
const bucketValue = this.getBucketValue(feature, finalContext);
const { matchedTraffic, matchedAllocation } = getMatchedTrafficAndAllocation(
feature.traffic,
finalAttributes,
finalContext,
bucketValue,

@@ -899,3 +886,3 @@ this.datafileReader,

typeof o.conditions === "string" ? JSON.parse(o.conditions) : o.conditions,
finalAttributes,
finalContext,
);

@@ -909,3 +896,3 @@ }

: o.segments,
finalAttributes,
finalContext,
this.datafileReader,

@@ -983,6 +970,6 @@ );

variableKey: string,
attributes: Attributes = {},
context: Context = {},
): VariableValue | undefined {
try {
const evaluation = this.evaluateVariable(featureKey, variableKey, attributes);
const evaluation = this.evaluateVariable(featureKey, variableKey, context);

@@ -1012,5 +999,5 @@ if (typeof evaluation.variableValue !== "undefined") {

variableKey: string,
attributes: Attributes = {},
context: Context = {},
): boolean | undefined {
const variableValue = this.getVariable(featureKey, variableKey, attributes);
const variableValue = this.getVariable(featureKey, variableKey, context);

@@ -1023,5 +1010,5 @@ return getValueByType(variableValue, "boolean") as boolean | undefined;

variableKey: string,
attributes: Attributes = {},
context: Context = {},
): string | undefined {
const variableValue = this.getVariable(featureKey, variableKey, attributes);
const variableValue = this.getVariable(featureKey, variableKey, context);

@@ -1034,5 +1021,5 @@ return getValueByType(variableValue, "string") as string | undefined;

variableKey: string,
attributes: Attributes = {},
context: Context = {},
): number | undefined {
const variableValue = this.getVariable(featureKey, variableKey, attributes);
const variableValue = this.getVariable(featureKey, variableKey, context);

@@ -1045,5 +1032,5 @@ return getValueByType(variableValue, "integer") as number | undefined;

variableKey: string,
attributes: Attributes = {},
context: Context = {},
): number | undefined {
const variableValue = this.getVariable(featureKey, variableKey, attributes);
const variableValue = this.getVariable(featureKey, variableKey, context);

@@ -1056,5 +1043,5 @@ return getValueByType(variableValue, "double") as number | undefined;

variableKey: string,
attributes: Attributes = {},
context: Context = {},
): string[] | undefined {
const variableValue = this.getVariable(featureKey, variableKey, attributes);
const variableValue = this.getVariable(featureKey, variableKey, context);

@@ -1067,5 +1054,5 @@ return getValueByType(variableValue, "array") as string[] | undefined;

variableKey: string,
attributes: Attributes = {},
context: Context = {},
): T | undefined {
const variableValue = this.getVariable(featureKey, variableKey, attributes);
const variableValue = this.getVariable(featureKey, variableKey, context);

@@ -1078,5 +1065,5 @@ return getValueByType(variableValue, "object") as T | undefined;

variableKey: string,
attributes: Attributes = {},
context: Context = {},
): T | undefined {
const variableValue = this.getVariable(featureKey, variableKey, attributes);
const variableValue = this.getVariable(featureKey, variableKey, context);

@@ -1083,0 +1070,0 @@ return getValueByType(variableValue, "json") as T | undefined;

@@ -1,7 +0,7 @@

import { Attributes, GroupSegment, Segment, Condition } from "@featurevisor/types";
import { Context, GroupSegment, Segment, Condition } from "@featurevisor/types";
import { allConditionsAreMatched } from "./conditions";
import { DatafileReader } from "./datafileReader";
export function segmentIsMatched(segment: Segment, attributes: Attributes): boolean {
return allConditionsAreMatched(segment.conditions as Condition | Condition[], attributes);
export function segmentIsMatched(segment: Segment, context: Context): boolean {
return allConditionsAreMatched(segment.conditions as Condition | Condition[], context);
}

@@ -11,3 +11,3 @@

groupSegments: GroupSegment | GroupSegment[] | "*",
attributes: Attributes,
context: Context,
datafileReader: DatafileReader,

@@ -23,3 +23,3 @@ ): boolean {

if (segment) {
return segmentIsMatched(segment, attributes);
return segmentIsMatched(segment, context);
}

@@ -33,3 +33,3 @@

return groupSegments.and.every((groupSegment) =>
allGroupSegmentsAreMatched(groupSegment, attributes, datafileReader),
allGroupSegmentsAreMatched(groupSegment, context, datafileReader),
);

@@ -40,3 +40,3 @@ }

return groupSegments.or.some((groupSegment) =>
allGroupSegmentsAreMatched(groupSegment, attributes, datafileReader),
allGroupSegmentsAreMatched(groupSegment, context, datafileReader),
);

@@ -48,3 +48,3 @@ }

(groupSegment) =>
allGroupSegmentsAreMatched(groupSegment, attributes, datafileReader) === false,
allGroupSegmentsAreMatched(groupSegment, context, datafileReader) === false,
);

@@ -56,3 +56,3 @@ }

return groupSegments.every((groupSegment) =>
allGroupSegmentsAreMatched(groupSegment, attributes, datafileReader),
allGroupSegmentsAreMatched(groupSegment, context, datafileReader),
);

@@ -59,0 +59,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc