summaryrefslogtreecommitdiff
path: root/node_modules/@jet/environment/metrics/event-linter.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/@jet/environment/metrics/event-linter.js')
-rw-r--r--node_modules/@jet/environment/metrics/event-linter.js155
1 files changed, 155 insertions, 0 deletions
diff --git a/node_modules/@jet/environment/metrics/event-linter.js b/node_modules/@jet/environment/metrics/event-linter.js
new file mode 100644
index 0000000..172afe7
--- /dev/null
+++ b/node_modules/@jet/environment/metrics/event-linter.js
@@ -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 \ No newline at end of file