diff options
Diffstat (limited to 'node_modules/@jet/environment/metrics/event-linter.js')
| -rw-r--r-- | node_modules/@jet/environment/metrics/event-linter.js | 155 |
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 |
