clean-insights-sdk
Version:
A privacy-preserving measurement framework.
271 lines (270 loc) • 10.2 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CampaignConsent = exports.FeatureConsent = exports.Consents = exports.Consent = exports.ConsentState = exports.Feature = void 0;
var dayjs_1 = __importDefault(require("dayjs"));
var Feature;
(function (Feature) {
Feature["lang"] = "lang";
Feature["ua"] = "ua";
})(Feature || (exports.Feature = Feature = {}));
var ConsentState;
(function (ConsentState) {
/**
A campaign with that ID doesn't exist or already expired.
*/
ConsentState["unconfigured"] = "unconfigured";
/**
There's no record of consent. User was probably never asked.
*/
ConsentState["unknown"] = "unknown";
/**
User denied consent. Don't ask again!
*/
ConsentState["denied"] = "denied";
/**
Consent was given, but consent period has not yet started.
*/
ConsentState["notStarted"] = "notStarted";
/**
Consent was given, but consent period is over. You might ask again for a new period.
*/
ConsentState["expired"] = "expired";
/**
Consent was given and is currently valid.
*/
ConsentState["granted"] = "granted";
})(ConsentState || (exports.ConsentState = ConsentState = {}));
var Consent = /** @class */ (function () {
/**
* @param {boolean|ConsentData} granted
* @param {dayjs.Dayjs=} start=NOW
* @param {dayjs.Dayjs=} end=NOW
*/
function Consent(granted, start, end) {
if (typeof granted === 'object' && granted) {
this.granted = granted.granted;
this.start = (0, dayjs_1.default)(granted.start);
this.end = (0, dayjs_1.default)(granted.end);
}
else {
this.granted = granted;
this.start = start ? (0, dayjs_1.default)(start) : (0, dayjs_1.default)();
this.end = end ? (0, dayjs_1.default)(end) : (0, dayjs_1.default)();
}
}
Object.defineProperty(Consent.prototype, "state", {
get: function () {
return this.granted ? ConsentState.granted : ConsentState.denied;
},
enumerable: false,
configurable: true
});
return Consent;
}());
exports.Consent = Consent;
var FeatureConsent = /** @class */ (function (_super) {
__extends(FeatureConsent, _super);
/**
* @param {Feature|string} feature
* @param {Consent} consent
*/
function FeatureConsent(feature, consent) {
var _this = _super.call(this, consent.granted, consent.start, consent.end) || this;
_this.feature = feature;
return _this;
}
return FeatureConsent;
}(Consent));
exports.FeatureConsent = FeatureConsent;
var CampaignConsent = /** @class */ (function (_super) {
__extends(CampaignConsent, _super);
/**
* @param {string} campaignId
* @param {Consent} consent
*/
function CampaignConsent(campaignId, consent) {
var _this = _super.call(this, consent.granted, consent.start, consent.end) || this;
_this.campaignId = campaignId;
return _this;
}
Object.defineProperty(CampaignConsent.prototype, "state", {
get: function () {
if (!this.granted) {
return ConsentState.denied;
}
var now = (0, dayjs_1.default)();
if (now.isBefore(this.start)) {
return ConsentState.notStarted;
}
if (now.isAfter(this.end)) {
return ConsentState.expired;
}
return ConsentState.granted;
},
enumerable: false,
configurable: true
});
return CampaignConsent;
}(Consent));
exports.CampaignConsent = CampaignConsent;
/**
* This class keeps track of all granted or denied consents of a user.
*
* There are two different types of consents:
* - Consents for common features like if we're allowed to evaluate the locale or a user agent.
* - Consents per measurement campaign.
*
* The time of the consent is recorded along with its state: If it was actually granted or denied.
*
* Consents for common features are given indefinitely, since they are only ever recorded along
* with running campaigns.
*
* Consents for campaigns only last for a certain amount of days.
*/
var Consents = /** @class */ (function () {
/**
*
* @param {Object=}json Optional data from JSON deserialization to assign.
*/
function Consents(json) {
this.features = {};
this.campaigns = {};
if (typeof json === 'object' && json) {
for (var feature in json.features) {
if (json.features.hasOwnProperty(feature)) {
this.features[feature] = new Consent(json.features[feature]);
}
}
for (var campaign in json.campaigns) {
if (json.campaigns.hasOwnProperty(campaign)) {
this.campaigns[campaign] = new Consent(json.campaigns[campaign]);
}
}
}
}
/**
* User consents to evaluate a `Feature`.
*
* @param {Feature} feature
* @returns {FeatureConsent}
*/
Consents.prototype.grantFeature = function (feature) {
// Don't overwrite original grant timestamp.
if (!this.features.hasOwnProperty(feature) || !this.features[feature].granted) {
this.features[feature] = new Consent(true);
}
return new FeatureConsent(feature, this.features[feature]);
};
/**
* User denies consent to evaluate a `Feature`.
*
* @param {Feature} feature
* @returns {FeatureConsent}
*/
Consents.prototype.denyFeature = function (feature) {
// Don't overwrite original deny timestamp.
if (!this.features.hasOwnProperty(feature) || this.features[feature].granted) {
this.features[feature] = new Consent(false);
}
return new FeatureConsent(feature, this.features[feature]);
};
/**
* Returns the consent for a given feature, if any available.
*
* @param {Feature|string} feature The feature to get the consent for.
* @returns {?FeatureConsent} the `FeatureConsent` for the given feature or `null`, if consent unknown.
*/
Consents.prototype.consentForFeature = function (feature) {
if (!this.features.hasOwnProperty(feature)) {
return null;
}
return new FeatureConsent(feature, this.features[feature]);
};
/**
* Checks the consent state of a feature.
*
* @param {Feature} feature The feature to check the consent state of.
* @returns {ConsentState} the current state of consent.
*/
Consents.prototype.stateOfFeature = function (feature) {
var _a, _b;
return (_b = (_a = this.consentForFeature(feature)) === null || _a === void 0 ? void 0 : _a.state) !== null && _b !== void 0 ? _b : ConsentState.unknown;
};
/**
* User consents to run a specific campaign.
*
* @param {string} campaignId
* The campaign ID.
* @param {Campaign} campaign
* The campaign.
* @returns {CampaignConsent}
*/
Consents.prototype.grantCampaign = function (campaignId, campaign) {
var period = campaign.nextTotalMeasurementPeriod;
if (period) {
// Always overwrite, since this might be a refreshed consent for a new period.
this.campaigns[campaignId] = new Consent(true, period.start, period.end);
}
else {
// Consent is technically granted, but has no effect, as start and end
// will be set the same.
this.campaigns[campaignId] = new Consent(true);
}
return new CampaignConsent(campaignId, this.campaigns[campaignId]);
};
/**
* User denies consent to run a specific campaign.
*
* @param {string} campaignId
* @returns {CampaignConsent}
*/
Consents.prototype.denyCampaign = function (campaignId) {
// Don't overwrite original deny timestamp.
if (!this.campaigns.hasOwnProperty(campaignId) || this.campaigns[campaignId].granted) {
this.campaigns[campaignId] = new Consent(false);
}
return new CampaignConsent(campaignId, this.campaigns[campaignId]);
};
/**
* Returns the consent for a given campaign, if any available.
*
* @param {string} campaignId The campaign ID to get the consent for.
* @returns {?CampaignConsent} the `CampaignConsent` for the given campaign or `null`, if consent unknown.
*/
Consents.prototype.consentForCampaign = function (campaignId) {
if (!this.campaigns.hasOwnProperty(campaignId)) {
return null;
}
return new CampaignConsent(campaignId, this.campaigns[campaignId]);
};
/**
* Checks the consent state of a campaign.
*
* @param {string} campaignId The campaign ID to check the consent state of.
* @returns {ConsentState} the current state of consent.
*/
Consents.prototype.stateOfCampaign = function (campaignId) {
var _a, _b;
return (_b = (_a = this.consentForCampaign(campaignId)) === null || _a === void 0 ? void 0 : _a.state) !== null && _b !== void 0 ? _b : ConsentState.unknown;
};
return Consents;
}());
exports.Consents = Consents;