UNPKG

irctokens

Version:
138 lines 4.08 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Line = void 0; exports.tokenise = tokenise; const const_1 = require("./const"); const formatting_1 = require("./formatting"); const hostmask_1 = require("./hostmask"); class Line { tags; source; command; params; constructor({ tags, source, command, params }) { this.tags = tags; this.source = source; this.command = command; this.params = params; } #hostmask; get hostmask() { if (this.source) { if (!this.#hostmask) this.#hostmask = (0, hostmask_1.hostmask)(this.source); return this.#hostmask; } else { throw new TypeError('cannot parse hostmask from null source'); } } format() { return (0, formatting_1.format)({ tags: this.tags, source: this.source, command: this.command, params: this.params, }); } withSource(source) { return new Line({ tags: this.tags, source, command: this.command, params: this.params, }); } copy() { return new Line(this); } } exports.Line = Line; function unescapeTag(value) { let unescaped = ''; if (!value) return unescaped; const escaped = value.split(''); while (escaped.length) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const current = escaped.shift(); if (current === '\\') { if (escaped.length) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const next = escaped.shift(); const duo = `${current}${next}`; const index = const_1.TAG_ESCAPED.indexOf(duo); if (index > -1) unescaped += const_1.TAG_UNESCAPED[index]; else unescaped += next; } } else { unescaped += current; } } return unescaped; } function _tokenise(line) { let value = line; let tags; if (value.startsWith('@')) { let tagsS; [tagsS, value] = value.substring(1).split(/ (.*)/); tags = {}; for (const part of tagsS.split(';')) { const [key, val] = part.split(/=(.*)/); tags[key] = unescapeTag(val); } } let trailing; [value, trailing] = value.split(/ :(.*)/); const params = value.split(' ').filter(part => !!part); let source; if (params[0].startsWith(':')) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion source = (params.shift()).substring(1); } if (!params.length) throw TypeError('Cannot tokenise command-less line'); // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const command = (params.shift()).toLocaleUpperCase(); if (typeof trailing === 'string') params.push(trailing); return new Line({ tags, source, command, params, }); } function tokenise(line, encoding = 'utf8', fallback = 'latin1') { let dline = ''; const decoder = new TextDecoder(encoding, { fatal: true }); const fallbackDecoder = new TextDecoder(fallback, { fatal: true }); if (line instanceof Uint8Array) { if (line[0] === '@'.charCodeAt(0)) { const idx = line.indexOf(' '.charCodeAt(0)); const tagsB = line.slice(0, idx + 1); line = line.slice(idx + 1); dline += decoder.decode(tagsB); } try { dline += decoder.decode(line); } catch { dline += fallbackDecoder.decode(line); } } else { dline = line; } for (const badchar of ['\x00', '\r', '\n']) { if (dline.includes(badchar)) { [dline] = dline.split(badchar); } } return _tokenise(dline); } //# sourceMappingURL=line.js.map