@getanthill/datastore
Version:
Event-Sourced Datastore
114 lines • 3.81 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const events_1 = require("events");
const ajv_1 = __importDefault(require("ajv"));
const ajv_formats_1 = __importDefault(require("ajv-formats"));
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
const merge_1 = __importDefault(require("lodash/merge"));
const DEFAULT_SPEC = {
asyncapi: '2.2.0',
info: {
title: 'MQTT API',
version: '0.1.0',
// termsOfService: '',
contact: {},
license: {
name: 'MIT',
url: 'https://opensource.org/licenses/MIT',
},
},
tags: [],
channels: {},
components: {
schemas: {
authorization: {
type: 'string',
description: 'Authorization token',
},
},
},
};
class BrokerClient extends events_1.EventEmitter {
constructor(config, telemetry) {
super();
this.topics = new Map();
this.config = config;
this.telemetry = telemetry;
this.ajv = new ajv_1.default({
useDefaults: true,
coerceTypes: false,
strict: false,
});
(0, ajv_formats_1.default)(this.ajv);
this.spec = (0, merge_1.default)((0, cloneDeep_1.default)(DEFAULT_SPEC), config.spec);
}
logOnInvalid(event, route) {
const err = new assert_1.default.AssertionError({
message: 'Event schema validation error',
expected: null,
actual: {
event,
errors: route.validate.errors,
},
});
/* @ts-ignore */
this.telemetry?.logger[this.config.logLeverOnInvalidMessage ?? 'error']('[services#broker] Message is invalid', {
err,
event,
schema: route.validate.schema,
errors: route.validate.errors,
acked: true,
});
}
mapTopic(topic, schema) {
const topicWithNamespace = this.topicWithNamespace(topic);
return {
original: topic,
topic: topicWithNamespace.replace(BrokerClient.REGEXP_MATCH_PATH_PARAMETERS, '+'),
regexp: new RegExp(topicWithNamespace.replace(BrokerClient.REGEXP_MATCH_PATH_PARAMETERS, '([^\\/]+)')),
paramNames: (topic.match(BrokerClient.REGEXP_MATCH_PATH_PARAMETERS) ?? []).map((p) => p.slice(1, -1)),
params: {},
validate: this.ajv.compile(schema),
};
}
parseTopic(topic, route) {
const values = route.regexp.exec(topic).slice(1);
const params = {};
values.forEach((v, i) => (params[route.paramNames[i]] = v));
return {
...route,
params,
};
}
getRoute(topic) {
for (const entry of this.topics.values()) {
if (entry.regexp.test(topic)) {
return entry;
}
}
return null;
}
topicWithNamespace(topic) {
return ((this.config.namespace !== '' ? this.config.namespace + '/' : '') + topic);
}
addChannelToSpec(topic, schema) {
this.spec.channels[this.topicWithNamespace(topic)] = {
publish: {
message: {
payload: {
type: 'object',
additionalProperties: false,
properties: schema,
},
},
},
};
}
}
BrokerClient.REGEXP_MATCH_PATH_PARAMETERS = /\{([a-z_]+)\}/g;
exports.default = BrokerClient;
//# sourceMappingURL=broker.js.map