@subsocial/utils
Version:
JavaScript utils for Subsocial blockchain.
190 lines (189 loc) • 7.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SocialRemark = void 0;
const types_1 = require("./types");
const config_1 = require("./config");
const decorators_1 = require("./decorators");
class SocialRemark {
constructor() {
this.msgParsed = null;
this.protNames = new Set(config_1.SocialRemarkConfig.getInstance().config.protNames);
this.versions = new Set(config_1.SocialRemarkConfig.getInstance().config.versions);
this.destinations = new Set(config_1.SocialRemarkConfig.getInstance().config.destinations);
this.actions = new Set(config_1.SocialRemarkConfig.getInstance().config.actions);
this.msgDelimiter = '::';
}
/**
* Set global config for all new SocialRemark instances
* @param data: SocialRemarkConfigData
*/
static setConfig(data) {
config_1.SocialRemarkConfig.getInstance().setConfig(data);
}
/**
* Get SocialRemark full data, if it's available. Otherwise, go throw error.
*/
get source() {
if (!this.msgParsed)
throw new Error('Message is not available.');
return this.msgParsed;
}
/**
* Get SocialRemark instance source content, if it's valid and available.
*/
get content() {
return this.msgParsed && this.msgParsed.valid
? this.msgParsed.content
: null;
}
/**
* Get SocialRemark instance version, if it's valid and available.
*/
get version() {
return this.msgParsed ? this.msgParsed.version : null;
}
/**
* Is SocialRemark valid.
*/
get isValidMessage() {
return !!this.msgParsed && this.msgParsed.valid;
}
/**
* Convert bytes to string.
* @param src: unknown
*/
static bytesToString(src) {
if (!src || !Buffer.isBuffer(src))
return '';
return Buffer.from(src).toString('utf-8');
}
/**
* Create SocialRemark from raw string remark message.
* @param maybeRemarkMsg: unknown
*/
fromMessage(maybeRemarkMsg) {
this.maybeRemarkMsg = maybeRemarkMsg;
this.parseMsg(maybeRemarkMsg);
return this;
}
/**
* Create SocialRemark from source map.
* @param rmrkSrc: SubSclSource<SocialRemarkMessageAction>
*/
fromSource(rmrkSrc) {
this.isRemarkSourceValid(rmrkSrc);
try {
this.msgParsed = Object.assign(Object.assign({}, rmrkSrc), { valid: true });
const contentPropsMap =
// @ts-ignore
types_1.REMARK_CONTENT_VERSION_ACTION_MAP[rmrkSrc.version][rmrkSrc.action];
for (const contentPropName in contentPropsMap) {
// @ts-ignore
this.msgParsed.content[contentPropName] = (0, decorators_1.decorateRemarkContentValue)(this.msgParsed.action, contentPropName,
// @ts-ignore
rmrkSrc.content[contentPropName]);
}
}
catch (e) {
console.log(e);
throw new Error('Error has been occurred during remark message creation.');
}
return this;
}
/**
* Encode SocialRemark source to remark string.
*/
toMessage() {
if (!this.isValidMessage)
throw new Error('Remark is not valid for build message.');
const msg = [];
msg.push(this.source.protName);
msg.push(this.source.version);
msg.push(this.source.destination);
msg.push(this.source.action);
try {
const contentPropsMap =
// @ts-ignore
types_1.REMARK_CONTENT_VERSION_ACTION_MAP[this.source.version][this.source.action];
for (const contentPropName in contentPropsMap) {
// @ts-ignore
msg[contentPropsMap[contentPropName]] = (0, decorators_1.decorateRemarkContentValue)(this.source.action, contentPropName,
// @ts-ignore
this.source.content[contentPropName]);
}
}
catch (e) {
console.log(e);
throw new Error('Error has been occurred during remark message creation.');
}
//TODO add validations
return msg.join(this.msgDelimiter);
}
/**
* ====== Private functionality ======
*/
parseMsg(srcMsg) {
if (!srcMsg || typeof srcMsg !== 'string')
return;
const chunkedMsg = (Buffer.isBuffer(srcMsg) ? SocialRemark.bytesToString(srcMsg) : srcMsg).split(this.msgDelimiter);
if (!chunkedMsg ||
chunkedMsg.length === 0 ||
!this.isValidProtName(chunkedMsg[0]) ||
!this.isValidVersion(chunkedMsg[1]) ||
!this.isValidDestination(chunkedMsg[2]) ||
!this.isValidAction(chunkedMsg[3]))
return;
this.msgParsed = {
protName: chunkedMsg[0],
version: chunkedMsg[1],
destination: chunkedMsg[2],
action: chunkedMsg[3],
valid: false,
content: null
};
try {
const contentPropsMap =
// @ts-ignore
types_1.REMARK_CONTENT_VERSION_ACTION_MAP[this.msgParsed.version][this.msgParsed.action];
for (const contentPropName in contentPropsMap) {
// @ts-ignore
if (!this.msgParsed.content)
this.msgParsed.content = {};
// @ts-ignore
this.msgParsed.content[contentPropName] = (0, decorators_1.decorateRemarkContentValue)(this.msgParsed.action, contentPropName,
// @ts-ignore
chunkedMsg[contentPropsMap[contentPropName]]);
}
this.msgParsed.valid = true;
}
catch (e) {
console.log(e);
}
}
isValidProtName(src) {
return !!(src && this.protNames.has(src));
}
isValidVersion(src) {
return !!(src && this.versions.has(src));
}
isValidDestination(src) {
return !!(src && this.destinations.has(src));
}
isValidAction(src) {
return !!(src && this.actions.has(src));
}
isRemarkSourceValid(rmrkSrc) {
if (!rmrkSrc)
throw new Error('Remark source is invalid - source has not been provided.');
if (!this.isValidProtName(rmrkSrc.protName))
throw new Error(`Remark source is invalid - protocol name "${rmrkSrc.protName}" has been provided but expected - "${[...this.protNames.keys()].join(' || ')}"`);
if (!this.isValidVersion(rmrkSrc.version))
throw new Error(`Remark source is invalid - protocol version "${rmrkSrc.version}" has been provided but expected - "${[...this.versions.keys()].join(' || ')}"`);
if (!this.isValidDestination(rmrkSrc.destination))
throw new Error(`Remark source is invalid - destination "${rmrkSrc.destination}" has been provided but expected - "${[...this.destinations.keys()].join(' || ')}"`);
if (!this.isValidAction(rmrkSrc.action))
throw new Error(`Remark source is invalid - action "${rmrkSrc.action}" has been provided but expected - "${[...this.actions.keys()].join(' || ')}"`);
return true;
}
}
exports.SocialRemark = SocialRemark;