@mojaloop/event-sdk
Version:
Shared code for Event Logging
372 lines (366 loc) • 13.2 kB
JavaScript
/*****
License
--------------
Copyright © 2020-2025 Mojaloop Foundation
The Mojaloop files are made available by the Mojaloop Foundation under the Apache License, Version 2.0 (the "License") and you may not use these files except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, the Mojaloop files are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Contributors
--------------
This is the official list of the Mojaloop project contributors for this file.
Names of the original copyright holders (individuals or organizations)
should be listed with a '*' in the first column. People who have
contributed from an organization can be listed under the organization
that actually holds the copyright for their contributions (see the
Mojaloop Foundation for an example). Those individuals should have
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets <email>.
* Mojaloop Foundation
- Name Surname <name.surname@mojaloop.io>
- Ramiro González Maciel <ramiro@modusbox.com>
- Valentin Genev <valentin.genev@modusbox.com>
--------------
******/
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.actionDictionary = exports.logFilterMap = exports.HttpRequestOptions = exports.LogResponse = exports.LogResponseStatus = exports.EventTraceMetadata = exports.EventStateMetadata = exports.EventMetadata = exports.EventStatusType = exports.NullEventAction = exports.TraceEventAction = exports.AuditEventAction = exports.LogEventAction = exports.TraceEventTypeAction = exports.AuditEventTypeAction = exports.LogEventTypeAction = exports.EventType = exports.EventMessage = void 0;
const config_1 = __importDefault(require("../lib/config"));
const crypto = require('node:crypto');
const Uuid = crypto.randomUUID;
const TRACE_ID_REGEX = /^[0-9abcdef]{32}$/;
const SPAN_ID_REGEX = /^[0-9abcdef]{16}$/;
/**
* EventType represents the different types of events.
*/
var EventType;
(function (EventType) {
EventType["undefined"] = "undefined";
EventType["log"] = "log";
EventType["audit"] = "audit";
EventType["trace"] = "trace";
})(EventType || (exports.EventType = EventType = {}));
/**
* Actions for event type Log
*/
var LogEventAction;
(function (LogEventAction) {
LogEventAction["info"] = "info";
LogEventAction["debug"] = "debug";
LogEventAction["verbose"] = "verbose";
LogEventAction["performance"] = "perf";
LogEventAction["warning"] = "warn";
LogEventAction["error"] = "error";
})(LogEventAction || (exports.LogEventAction = LogEventAction = {}));
/**
* Actions for event type Audit
*/
var AuditEventAction;
(function (AuditEventAction) {
AuditEventAction["default"] = "default";
AuditEventAction["start"] = "start";
AuditEventAction["finish"] = "finish";
AuditEventAction["ingress"] = "ingress";
AuditEventAction["egress"] = "egress";
})(AuditEventAction || (exports.AuditEventAction = AuditEventAction = {}));
/**
* Actions for event type trace
*/
var TraceEventAction;
(function (TraceEventAction) {
TraceEventAction["span"] = "span";
})(TraceEventAction || (exports.TraceEventAction = TraceEventAction = {}));
var NullEventAction;
(function (NullEventAction) {
NullEventAction["undefined"] = "undefined";
})(NullEventAction || (exports.NullEventAction = NullEventAction = {}));
/**
* Enum that represents the event status types
*/
var EventStatusType;
(function (EventStatusType) {
EventStatusType["success"] = "success";
EventStatusType["failed"] = "failed";
})(EventStatusType || (exports.EventStatusType = EventStatusType = {}));
var HttpRequestOptions;
(function (HttpRequestOptions) {
HttpRequestOptions["w3c"] = "w3c";
HttpRequestOptions["xb3"] = "xb3";
})(HttpRequestOptions || (exports.HttpRequestOptions = HttpRequestOptions = {}));
/**
* Describes class for extracting types and their actions based on type input
*/
class TypeAction {
type;
action;
getType() {
return this.type;
}
getAction() {
return this.action;
}
constructor(typeAction) {
this.type = typeAction.type;
this.action = typeAction.action;
}
}
/**
* Returns new `TypeEventTypeAction` object with type = 'log'
*/
class LogEventTypeAction extends TypeAction {
static type = EventType.log;
static getType() {
return LogEventTypeAction.type;
}
constructor(actionParam = NullEventAction.undefined) {
if (typeof actionParam === 'object' && 'action' in actionParam)
super({ type: LogEventTypeAction.type, action: actionParam.action });
else
super({ type: LogEventTypeAction.type, action: actionParam });
}
}
exports.LogEventTypeAction = LogEventTypeAction;
/**
* Returns new `TypeEventTypeAction` object with type = 'audit'
*/
class AuditEventTypeAction extends TypeAction {
static type = EventType.audit;
static getType() {
return AuditEventTypeAction.type;
}
constructor(actionParam = NullEventAction.undefined) {
if (typeof actionParam === 'object' && 'action' in actionParam)
super({ type: AuditEventTypeAction.type, action: actionParam.action });
else
super({ type: AuditEventTypeAction.type, action: actionParam });
}
}
exports.AuditEventTypeAction = AuditEventTypeAction;
/**
* Returns new `TypeEventTypeAction` object with type = 'trace'
*/
class TraceEventTypeAction extends TypeAction {
static type = EventType.trace;
static getType() {
return TraceEventTypeAction.type;
}
constructor(actionParam = NullEventAction.undefined) {
if (typeof actionParam === 'object' && 'action' in actionParam)
super({ type: TraceEventTypeAction.type, action: actionParam.action });
else
super({ type: TraceEventTypeAction.type, action: actionParam });
}
}
exports.TraceEventTypeAction = TraceEventTypeAction;
// type requiredSampled = Required<{ readonly sampled: 0|1 }>
// type SpanContext = requiredSampled & Partial<TypeSpanContext>
class EventTraceMetadata {
service;
traceId;
spanId;
sampled; // = 0
flags; // = 0
parentSpanId;
startTimestamp = (new Date()).toISOString(); // ISO 8601
finishTimestamp;
tags;
tracestates;
constructor(spanContext) {
const { service = '', traceId = newTraceId(), spanId = newSpanId(), parentSpanId, sampled, flags, startTimestamp, tags = {}, tracestates = {}, finishTimestamp } = spanContext;
this.service = service;
if (!(TRACE_ID_REGEX.test(traceId))) {
throw new Error(`Invalid traceId: ${traceId}`);
}
this.traceId = traceId;
if (!(SPAN_ID_REGEX.test(spanId))) {
throw new Error(`Invalid spanId: ${spanId}`);
}
this.spanId = spanId;
if (parentSpanId && !(SPAN_ID_REGEX.test(parentSpanId))) {
throw new Error(`Invalid parentSpanId: ${parentSpanId}`);
}
this.parentSpanId = parentSpanId;
this.sampled = sampled; // ? sampled : this.sampled
this.flags = flags; // ? flags : this.flags
this.tags = tags;
this.tracestates = tracestates;
if (startTimestamp instanceof Date) {
this.startTimestamp = startTimestamp.toISOString(); // ISO 8601
}
else if (startTimestamp) {
this.startTimestamp = startTimestamp;
}
this.finishTimestamp = finishTimestamp;
return this;
}
}
exports.EventTraceMetadata = EventTraceMetadata;
class EventStateMetadata {
status = EventStatusType.success;
code;
description;
/**
* Creates new state object
* @param status
* @param code
* @param description
*/
constructor(status, code, description) {
this.status = status;
this.code = code;
this.description = description;
return this;
}
/**
* Creates success state object
* @param code
* @param description
*/
static success(code, description) {
return new EventStateMetadata(EventStatusType.success, code, description);
}
/**
* Creates failed state object
* @param code
* @param description
*/
static failed(code, description) {
return new EventStateMetadata(EventStatusType.failed, code, description);
}
}
exports.EventStateMetadata = EventStateMetadata;
class EventMetadata {
id = Uuid();
type = EventType.undefined;
action = NullEventAction.undefined;
createdAt; // ISO 8601
state;
responseTo;
/**
* Creates log type event metadata
* @param eventMetadata
*/
static log(eventMetadata) {
const typeAction = new LogEventTypeAction({ action: eventMetadata.action });
return new EventMetadata(Object.assign(eventMetadata, typeAction));
}
/**
* Creates trace type event metadata
* @param eventMetadata
*/
static trace(eventMetadata) {
const typeAction = new TraceEventTypeAction({ action: eventMetadata.action });
return new EventMetadata(Object.assign(eventMetadata, typeAction));
}
/**
* Creates audit type event metadata
* @param eventMetadata
*/
static audit(eventMetadata) {
const typeAction = new AuditEventTypeAction({ action: eventMetadata.action });
const a = (Object.assign(eventMetadata, typeAction));
return new EventMetadata(a);
}
/**
* Creates metadata object based on the passed message
* @param eventMetadata
*/
constructor(eventMetadata) {
const { createdAt = new Date().toISOString(), state, ...restParams } = eventMetadata;
if (createdAt instanceof Date) {
this.createdAt = createdAt.toISOString(); // ISO 8601
}
else {
this.createdAt = createdAt;
}
this.state = state;
Object.assign(this, restParams);
}
}
exports.EventMetadata = EventMetadata;
class EventMessage {
type = 'application/json';
content;
id = Uuid();
from;
to;
pp;
metadata;
/**
* Creates event message
* @param eventMessageContent message content based on the `TypeEventMessage`
*/
constructor(eventMessageContent) {
return Object.assign(this, eventMessageContent);
}
}
exports.EventMessage = EventMessage;
/**
* Defines the log responses
*/
var LogResponseStatus;
(function (LogResponseStatus) {
LogResponseStatus["UNDEFINED"] = "undefined";
LogResponseStatus["pending"] = "pending";
LogResponseStatus["accepted"] = "accepted";
LogResponseStatus["error"] = "error";
})(LogResponseStatus || (exports.LogResponseStatus = LogResponseStatus = {}));
class LogResponse {
status = LogResponseStatus.UNDEFINED;
constructor(status) {
this.status = status;
}
}
exports.LogResponse = LogResponse;
function newTraceId() {
return crypto.randomBytes(16).toString('hex');
}
function newSpanId() {
return crypto.randomBytes(8).toString('hex');
}
const actionDictionary = (() => {
const dict = {};
Object.values(EventType).forEach(type => {
dict[type] =
(!!type && type === EventType.log) ? Object.values(LogEventAction) :
(!!type && type === EventType.audit) ? Object.values(AuditEventAction) :
(!!type && type === EventType.trace) ? Object.values(TraceEventAction) :
Object.values(NullEventAction);
});
return dict;
})();
exports.actionDictionary = actionDictionary;
const logFilterMap = (() => {
let filterMap = new Map();
const getActionValue = (key, value) => {
const actionValue = (value === '*') ? actionDictionary[key] : [value];
return actionValue;
};
config_1.default.EVENT_LOGGER_LOG_FILTER.split(',').forEach(filter => {
const [key, value] = filter.trim().split(':');
if (key === '*') {
return filterMap = new Map(Object.entries(actionDictionary));
}
const valueToAdd = getActionValue(key, value);
if (!filterMap.has(key)) {
filterMap.set(key, valueToAdd);
}
else {
if (valueToAdd.length === actionDictionary[key].length) {
filterMap.set(key, valueToAdd);
}
else {
const valueToUpdate = filterMap.get(key);
if (!valueToUpdate.includes(valueToAdd[0])) {
valueToUpdate.push(valueToAdd[0]);
filterMap.set(key, valueToUpdate);
}
}
}
});
return filterMap;
})();
exports.logFilterMap = logFilterMap;
//# sourceMappingURL=EventMessage.js.map