@identityinvest/subsume
Version:
CommonJS version of subsume 4.0.0. See https://github.com/mifi/commonify
147 lines (114 loc) • 3.53 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _uniqueString = _interopRequireDefault(require("@identityinvest/unique-string"));
var _escapeStringRegexp = _interopRequireDefault(require("@identityinvest/escape-string-regexp"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class Subsume {
static parse(text, id) {
return new Subsume(id).parse(text);
}
static parseAll(text, ids) {
if (ids && !Array.isArray(ids)) {
throw new TypeError('IDs is supposed to be an array');
}
const result = {
data: new Map(),
rest: text
};
const idList = ids ? ids : Subsume._extractIDs(text);
if (!ids) {
try {
Subsume._checkIntegrity(text);
} catch (error) {
throw new Error(`Could not parse because the string's integrity is compromised: ${error.message}`);
}
}
for (const id of idList) {
if (result.data.get(id)) {
throw new Error('IDs aren\'t supposed to be repeated at the same level in a string');
}
const parseResult = Subsume.parse(result.rest, id);
result.data.set(id, parseResult.data);
result.rest = parseResult.rest;
}
return result;
}
static _extractIDs(text) {
try {
Subsume._checkIntegrity(text);
} catch (error) {
throw new Error(`Could not extract IDs because the string's integrity is compromised: ${error.message}`);
}
const idRegex = /@@\[(.{32})]@@.*##\[\1]##/g;
const idList = [];
let match;
do {
match = idRegex.exec(text);
if (match) {
const [, id] = match;
idList.push(id);
}
} while (match);
return idList;
}
static _checkIntegrity(text) {
const delimiterRegex = /([#|@])\1\[(.{32})]\1{2}/g;
const ids = new Map();
const idStack = [];
let match;
do {
match = delimiterRegex.exec(text);
if (match) {
const [, embedToken, id] = match;
if (embedToken === '@') {
let map = ids;
for (const element of idStack) {
map = map.get(element);
}
if (map.get(id)) {
throw new Error('There are duplicate IDs in the same scope.');
}
map.set(id, new Map());
idStack.push(id);
} else {
idStack.pop();
}
}
} while (match);
if (idStack.length > 0) {
throw new Error('There is a mismatch between prefixes and suffixes');
}
return ids;
}
constructor(id) {
if (id && (id.includes('@@[') || id.includes('##['))) {
throw new Error('`@@[` and `##[` cannot be used in the ID');
}
this.id = id ? id : (0, _uniqueString.default)();
this.prefix = `@@[${this.id}]@@`;
this.postfix = `##[${this.id}]##`;
this.regex = new RegExp((0, _escapeStringRegexp.default)(this.prefix) + '([\\S\\s]*)' + (0, _escapeStringRegexp.default)(this.postfix), 'g');
}
compose(text) {
return this.prefix + text + this.postfix;
}
parse(text) {
try {
Subsume._checkIntegrity(text);
} catch (error) {
throw new Error(`Could not extract IDs because the string's integrity is compromised: ${error.message}`);
}
const returnValue = {};
returnValue.rest = text.replace(this.regex, (m, p1) => {
if (p1) {
returnValue.data = p1;
}
return '';
});
return returnValue;
}
}
exports.default = Subsume;