forked from off-topic/apps.apple.com
init commit
This commit is contained in:
155
node_modules/@jet/environment/metrics/event-linter.js
generated
vendored
Normal file
155
node_modules/@jet/environment/metrics/event-linter.js
generated
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EventLinter = void 0;
|
||||
const object_reader_1 = require("../json/reader/object-reader");
|
||||
const optional_1 = require("../types/optional");
|
||||
const numerics = require("./helpers/numerics");
|
||||
/**
|
||||
* A type which applies common business rules to metrics fields
|
||||
* and generates events which are ready for posting to Figaro.
|
||||
*
|
||||
* The common business rules are:
|
||||
* - Add base event fields provided by linter configuration provider object
|
||||
* - Set clientBuiltType and resourceRevNum fields based on EventLinterEnvironment object values
|
||||
* - Set xpSendMethod field to "jet-js"
|
||||
* - Combine pageType and pageId using compound separator provided by linter configuration provider
|
||||
* and set result to "page" field.
|
||||
* - Apply event field de-resolution rules provided by linter configuration provider object
|
||||
* - Set the "position" field for events of "media" type.
|
||||
*/
|
||||
class EventLinter {
|
||||
/**
|
||||
* Create an event linter.
|
||||
*
|
||||
* @param options - The options which specify various behaviors of the new linter.
|
||||
* This object will be frozen.
|
||||
*/
|
||||
constructor(options) {
|
||||
this.options = Object.freeze(options);
|
||||
}
|
||||
// MARK: Public Properties
|
||||
/**
|
||||
* Topic to use if an event fields blob does not specify one.
|
||||
*/
|
||||
get defaultTopic() {
|
||||
return this.options.defaultTopic;
|
||||
}
|
||||
// MARK: Utilities
|
||||
/**
|
||||
* Reduce the accuracy of fields in a blob according to
|
||||
* a given array of rules provided by linter configuration object.
|
||||
*
|
||||
* @param eventFields - The fields of an event to reduce the accuracy of.
|
||||
* @param rules - An array of de-resolution rules to apply to event fields.
|
||||
*/
|
||||
applyDeResolutionRules(eventFields, rules) {
|
||||
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
|
||||
for (const rule of rules) {
|
||||
const value = eventFieldsReader.asNumber(rule.fieldName);
|
||||
if ((0, optional_1.isNothing)(value)) {
|
||||
continue;
|
||||
}
|
||||
let magnitude = rule.magnitude;
|
||||
if ((0, optional_1.isNothing)(magnitude)) {
|
||||
magnitude = 1024 * 1024;
|
||||
}
|
||||
let significantDigits = rule.significantDigits;
|
||||
if ((0, optional_1.isNothing)(significantDigits)) {
|
||||
significantDigits = 2;
|
||||
}
|
||||
if (magnitude <= 0.0 || significantDigits < 0.0) {
|
||||
// This is the failure mode from MetricsKit.
|
||||
eventFields[rule.fieldName] = Number.NaN;
|
||||
continue;
|
||||
}
|
||||
const scaledValue = value / magnitude;
|
||||
eventFields[rule.fieldName] = numerics.reduceSignificantDigits(scaledValue, significantDigits);
|
||||
}
|
||||
}
|
||||
// MARK: Rules
|
||||
/**
|
||||
* Apply the rules which are universal to all metrics events
|
||||
* to a given metrics fields linter.
|
||||
*
|
||||
* @param eventFields - The fields which will be used to construct a built event.
|
||||
* @param topic - The topic the built event will be submitted to.
|
||||
*/
|
||||
decorateCommonEventFields(eventFields, topic) {
|
||||
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
|
||||
const configurationProvider = this.options.configuration;
|
||||
// - Base metrics fields.
|
||||
const baseFields = configurationProvider.baseFields(topic);
|
||||
if ((0, optional_1.isSome)(baseFields)) {
|
||||
Object.assign(eventFields, baseFields);
|
||||
}
|
||||
// - Universal basic fields.
|
||||
eventFields["clientBuildType"] = this.options.environment.buildType;
|
||||
eventFields["resourceRevNum"] = this.options.environment.jsVersion;
|
||||
eventFields["xpSendMethod"] = "jet-js";
|
||||
// - Page.
|
||||
const pageType = eventFieldsReader.asString("pageType");
|
||||
const pageId = eventFieldsReader.asString("pageId");
|
||||
if ((0, optional_1.isSome)(pageType) && (0, optional_1.isSome)(pageId) && (0, optional_1.isNothing)(eventFields["page"])) {
|
||||
const bagValue = configurationProvider.compoundSeparator(topic);
|
||||
const separator = (0, optional_1.isSome)(bagValue) ? (0, optional_1.unwrapOptional)(bagValue) : "_";
|
||||
eventFields["page"] = `${pageType}${separator}${pageId}`;
|
||||
}
|
||||
// - Field value resolution reduction.
|
||||
const rules = configurationProvider.deResolutionRules(topic);
|
||||
this.applyDeResolutionRules(eventFields, rules);
|
||||
}
|
||||
/**
|
||||
* Apply the rules specific to the `media` event.
|
||||
*
|
||||
* @param eventFields - The fields which will be used to construct a built event.
|
||||
*/
|
||||
decorateMediaEventEvents(eventFields) {
|
||||
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
|
||||
const position = eventFieldsReader.asNumber("position");
|
||||
if ((0, optional_1.isSome)(position)) {
|
||||
eventFields["position"] = Math.round(position);
|
||||
}
|
||||
}
|
||||
// MARK: Decorating Event Fields
|
||||
/**
|
||||
* Lint metrics event fields by applying the common business rules to a given fields blob.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* Note: A deep copy of event fields is created by linter using `JSON.parse(JSON.stringify(eventFields))`.
|
||||
* The original event fields are not modified.
|
||||
*
|
||||
* @param eventFields - The fields to decorate.
|
||||
* @param context - The additional event linter context to be passed to all
|
||||
* event linter rules. This is a free-form object so clients can pass custom
|
||||
* context information.
|
||||
* @returns Decorated fields ready for creating a metrics event.
|
||||
*/
|
||||
lint(eventFields, context = {}) {
|
||||
const eventFieldsReader = new object_reader_1.ObjectReader(eventFields);
|
||||
const eventType = eventFieldsReader.asString("eventType");
|
||||
if (this.options.isLoggingEnabled) {
|
||||
console.log(`Building event for event type: ${eventType !== null && eventType !== void 0 ? eventType : "<null>"}`);
|
||||
}
|
||||
// Make sure we have a deep copy of an object.
|
||||
const decoratedEventFields = JSON.parse(JSON.stringify(eventFields));
|
||||
const value = eventFieldsReader.asString("topic");
|
||||
const topic = (0, optional_1.isSome)(value) ? (0, optional_1.unwrapOptional)(value) : this.options.defaultTopic;
|
||||
this.decorateCommonEventFields(decoratedEventFields, topic);
|
||||
switch (eventType) {
|
||||
case "media" /* MetricsEventType.media */:
|
||||
this.decorateMediaEventEvents(decoratedEventFields);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (const rule of this.options.rules) {
|
||||
rule.apply(decoratedEventFields, context);
|
||||
}
|
||||
return {
|
||||
fields: decoratedEventFields,
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.EventLinter = EventLinter;
|
||||
//# sourceMappingURL=event-linter.js.map
|
||||
Reference in New Issue
Block a user