UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

548 lines (547 loc) • 25.4 kB
import { r as __exportAll } from "./rolldown-runtime-Dr7-SnC6.mjs"; //#region node_modules/.pnpm/uc.micro@3.0.0/node_modules/uc.micro/build/index.mjs var build_exports = /* @__PURE__ */ __exportAll({ Any: () => Any, Cc: () => Cc, Cf: () => Cf, P: () => P, S: () => S, Z: () => Z }); const Any = /[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; const Cc = /[\0-\x1F\x7F-\x9F]/; const Cf = /[\xAD\u0600-\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD80D[\uDC30-\uDC3F]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/; const P = /[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B4E\u1B4F\u1B5A-\u1B60\u1B7D-\u1B7F\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDD6E\uDEAD\uDED0\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9\uDFD4\uDFD5\uDFD7\uDFD8]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09\uDFE1]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDD6D-\uDD6F\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD839\uDDFF|\uD83A[\uDD5E\uDD5F]/; const S = /[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C1\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2429\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E5\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBD2\uFD40-\uFD4F\uFD90\uFD91\uFDC8-\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD803[\uDD8E\uDD8F\uDED1-\uDED8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDC00-\uDCEF\uDCFA-\uDCFC\uDD00-\uDEB3\uDEBA-\uDED0\uDEE0-\uDEF0\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED8\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0-\uDCBB\uDCC0\uDCC1\uDCD0-\uDCD8\uDD00-\uDE57\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF-\uDEF8\uDF00-\uDF92\uDF94-\uDFEF\uDFFA]/; const Z = /[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/; //#endregion //#region node_modules/.pnpm/linkify-it@6.1.0/node_modules/linkify-it/build/index.mjs var REBuilder = class { src_Any = Any.source; src_Cc = Cc.source; src_Z = Z.source; src_P = P.source; src_ZPCc = [ this.src_Z, this.src_P, this.src_Cc ].join("|"); src_ZCc = [this.src_Z, this.src_Cc].join("|"); cache = {}; opts = { maxLength: 1e4, urlAuth: false, schema_names: [] }; constructor(opts = {}) { this.opts = { ...this.opts, ...opts }; } set(opts = {}) { this.opts = { ...this.opts, ...opts }; this.cache = {}; return this; } escapeRE(str) { return str.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); } nestedPairRE(open, close, depth = 4) { const openRE = this.escapeRE(open); const closeRE = this.escapeRE(close); const atom = `(?:(?!${this.src_ZCc}|${openRE}|${closeRE}).)`; let pair = `${openRE}${atom}{0,1000}${closeRE}`; for (let level = 2; level <= depth; level++) pair = `${openRE}(?:${atom}|${pair}){0,1000}${closeRE}`; return pair; } get_text_separators() { return this.cache.text_separators ??= /[><\uff5c]/; } get_pseudo_letter() { return this.cache.src_pseudo_letter ??= new RegExp(`(?:(?!${this.get_text_separators().source}|${this.src_ZPCc})${this.src_Any})`); } get_ipv4_addr() { return this.cache.src_ip4 ??= /* @__PURE__ */ new RegExp("(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])[.]){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])"); } get_ipv6_addr() { const h16 = "[0-9A-Fa-f]{1,4}"; const ls32 = `(?:(?:${h16}:${h16})|${this.get_ipv4_addr().source})`; return this.cache.src_ip6_addr ??= new RegExp(`(?:(?:${h16}:){6}${ls32}|::(?:${h16}:){5}${ls32}|(?:${h16})?::(?:${h16}:){4}${ls32}|(?:(?:${h16}:){0,1}${h16})?::(?:${h16}:){3}${ls32}|(?:(?:${h16}:){0,2}${h16})?::(?:${h16}:){2}${ls32}|(?:(?:${h16}:){0,3}${h16})?::${h16}:${ls32}|(?:(?:${h16}:){0,4}${h16})?::${ls32}|(?:(?:${h16}:){0,5}${h16})?::${h16}|(?:(?:${h16}:){0,6}${h16})?::)`); } get_ipv6_url_host() { return this.cache.src_ip6_host ??= new RegExp(`\\[${this.get_ipv6_addr().source}\\]`); } get_ipv6_mail_host() { return this.cache.src_ipv6_mail_host ??= new RegExp(`\\[IPv6:${this.get_ipv6_addr().source}\\]`); } get_auth() { return this.cache.src_auth ??= new RegExp(`(?:(?:(?!${this.src_ZCc}|[@/\\[\\]()]).){1,50}@)?`); } get_port() { return this.cache.src_port ??= /* @__PURE__ */ new RegExp("(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?"); } get_host_terminator() { return this.cache.src_host_terminator ??= new RegExp(`(?=$|${this.get_text_separators().source}|${this.src_ZPCc})(?!${this.opts["---"] ? "-(?!--)|" : "-|"}_|:\\d|\\.-|\\.(?!$|${this.src_ZPCc}))`); } get_path_terminator() { return this.cache.src_path_terminator ??= new RegExp(`${this.src_ZPCc}|${this.get_text_separators().source}`); } get_path() { return this.cache.src_path ??= new RegExp(`(?:[/?#](?:${this.nestedPairRE("[", "]")}|${this.nestedPairRE("(", ")")}|${this.nestedPairRE("{", "}")}|\\"(?:(?!${this.src_ZCc}|["]).){1,100}\\"|\\'(?:(?!${this.src_ZCc}|[']).){1,100}\\'|\\'(?=${this.get_pseudo_letter().source}|[-])|\\.{2,20}[:]?[a-zA-Z0-9%/&]|\\.(?!${this.src_ZCc}|[.]|$)|` + (this.opts["---"] ? "\\-(?!--(?:[^-]|$))(?:-{0,19})|" : "\\-{1,20}|") + `,(?!${this.src_ZCc}|$)|;(?!${this.src_ZCc}|$)|\\!{1,20}(?!${this.src_ZCc}|[!]|$)|\\?(?!${this.src_ZCc}|[?]|$)|` + this.get_path_extra().source + `[\\\\/:%@#&=_~*]|(?!${this.get_path_terminator().source}).){1,${this.opts.maxLength}}|\\/)?`); } get_mail_name() { return this.cache.src_mail_name ??= /* @__PURE__ */ new RegExp("[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9](?:[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9]|[.](?=[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9])){0,63}"); } get_xn() { return this.cache.src_xn ??= /* @__PURE__ */ new RegExp("xn--[a-z0-9\\-]{1,59}"); } get_tld() { if (this.cache.tld) return this.cache.tld; const tlds_src = [...new Set(this.opts.tlds || [])].sort().reverse().join("|"); this.cache.tld = new RegExp(`${tlds_src || "$#none#$"}|${this.get_xn().source}`); return this.cache.tld; } get_domain_root() { return this.cache.src_domain_root ??= new RegExp("(?:" + this.get_xn().source + `|${this.get_pseudo_letter().source}{1,63})`); } get_domain() { return this.cache.src_domain ??= new RegExp("(?:" + this.get_xn().source + `|(?:${this.get_pseudo_letter().source})|(?:${this.get_pseudo_letter().source}(?:-|${this.get_pseudo_letter().source}){0,61}${this.get_pseudo_letter().source}))`); } get_url_host_port() { return this.cache.url_host_port ??= new RegExp("(?:" + this.get_ipv6_url_host().source + `|(?:(?:(?:${this.get_domain().source})\\.){0,10}${this.get_domain().source}))` + this.get_port().source + this.get_host_terminator().source); } get_fuzzy_url_host_port() { return this.cache.fuzzy_url_host_port ??= new RegExp("(?:" + (this.opts.fuzzyIP ? this.get_ipv4_addr().source + "|" : "") + `(?:(?:(?:${this.get_domain().source})\\.){1,10}(?:${this.get_tld().source})))` + this.get_host_terminator().source); } get_mail_host() { return this.cache.src_mail_host ??= new RegExp("(?:" + this.get_ipv6_mail_host().source + `|(?:(?:(?:${this.get_domain().source})\\.){0,4}${this.get_domain().source}))` + this.get_host_terminator().source); } get_fuzzy_mail_host() { return this.cache.src_fuzzy_mail_host ??= new RegExp("(?:" + this.get_ipv6_mail_host().source + `|(?:(?:(?:${this.get_domain().source})[.]){1,4}${this.get_domain_root().source}))` + this.get_host_terminator().source); } get_path_extra() { return this.cache.src_path_extra ??= /* @__PURE__ */ new RegExp(""); } get_fuzzy_mail_host_search() { return this.cache.mail_fuzzy_host_search ??= new RegExp(`@${this.get_fuzzy_mail_host().source}`, "ig"); } get_fuzzy_link_search() { return this.cache.link_fuzzy_search ??= new RegExp(`(^|(?![.:/\\-_@])(?:[$+<=>^\`|\uff5c]|${this.src_ZPCc}))(?:(?![$+<=>^\`|\uff5c])${this.get_fuzzy_url_host_port().source}${this.get_path().source})`, "ig"); } get_http_validator() { return this.cache.http_validator ??= new RegExp("\\/\\/" + (this.opts.urlAuth ? this.get_auth().source : "") + this.get_url_host_port().source + this.get_path().source, "iy"); } get_relative_proto_validator() { return this.cache.relative_proto_validator ??= new RegExp((this.opts.urlAuth ? this.get_auth().source : "") + `(?:localhost|${this.get_ipv6_url_host().source}|(?:(?:${this.get_domain().source})[.]){1,10}${this.get_domain_root().source})` + this.get_port().source + this.get_host_terminator().source + this.get_path().source, "iy"); } get_mail_name_validator() { return this.cache.mail_name_validator ??= new RegExp(`(?:^|${this.get_text_separators().source}|"|\\(|${this.src_ZCc})(${this.get_mail_name().source})$`); } get_mailto_validator() { return this.cache.mailto_validator ??= new RegExp(`${this.get_mail_name().source}@${this.get_mail_host().source}`, "iy"); } get_schema_names() { return this.cache.schema_names ??= new RegExp((this.opts.schema_names || []).map((name) => this.escapeRE(name)).join("|")); } get_schema_search() { return this.cache.schema_search ??= new RegExp(`(^|(?!_)(?:[><\uff5c]|${this.src_ZPCc}))(${this.get_schema_names().source})`, "ig"); } get_schema_at_start() { return this.cache.schema_at_start ??= new RegExp(`^${this.get_schema_search().source}`, "i"); } }; var web_schema = { validate: (text, pos, self) => { const re = self.re.get_http_validator(); re.lastIndex = pos; const m = re.exec(text); return m ? m[0].length : 0; }, normalize: (match, self) => self.normalize(match) }; var defaultSchemas = { "http:": web_schema, "https:": web_schema, "ftp:": web_schema, "//": { validate: function(text, pos, self) { const re = self.re.get_relative_proto_validator(); re.lastIndex = pos; const m = re.exec(text); if (m) { if (pos >= 3 && text[pos - 3] === ":") return 0; if (pos >= 3 && text[pos - 3] === "/") return 0; return m[0].length; } return 0; }, normalize: (match, self) => self.normalize(match) }, "mailto:": { validate: function(text, pos, self) { const re = self.re.get_mailto_validator(); re.lastIndex = pos; const m = re.exec(text); return m ? m[0].length : 0; }, normalize: (match, self) => self.normalize(match) } }; var tlds_2ch = "a:cdefgilmnoqrstuwxz|b:abdefghijmnorstvwyz|c:acdfghiklmnoruvwxyz|d:ejkmoz|e:cegrstu|f:ijkmor|g:abdefghilmnpqrstuwy|h:kmnrtu|i:delmnoqrst|j:emop|k:eghimnprwyz|l:abcikrstuvy|m:acdeghklmnopqrstuvwxyz|n:acefgilopruz|o:m|p:aefghklmnrstwy|q:a|r:eosuw|s:abcdeghijklmnortuvxyz|t:cdfghjklmnortvwz|u:agksyz|v:aceginu|w:fs|y:et|z:amw"; var tlds_default = "biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф"; function unpackTlds() { const result = tlds_default.split("|"); tlds_2ch.split("|").forEach((item) => { const sep = item.indexOf(":"); const prefix = item.slice(0, sep); for (const suffix of item.slice(sep + 1)) result.push(prefix + suffix); }); return result; } var defaultOptions = { fuzzyLink: false, fuzzyEmail: true, fuzzyIP: false, "---": false, tlds: unpackTlds(), urlAuth: false, maxLength: 1e4 }; /** * Match result returned by {@link LinkifyIt.match} and * {@link LinkifyIt.matchAtStart}. * * @category types */ var Match = class { /** Prefix (protocol) for matched string. Empty for fuzzy links. */ schema; /** First position of matched string. */ index; /** Next position after matched string. */ lastIndex; /** Matched string. */ raw; /** Normalized text of matched string. */ text; /** Normalized URL of matched string. */ url; constructor(text, schema, index, lastIndex) { const raw = text.slice(index, lastIndex); this.schema = schema.toLowerCase(); this.index = index; this.lastIndex = lastIndex; this.raw = raw; this.text = raw; this.url = raw; } }; /** Linkifier instance. */ var LinkifyIt = class { __opts__; __schemas__; re; /** * Creates new linkifier instance. * * By default understands: * * - `http(s)://...` , `ftp://...`, `mailto:...` & `//...` links * - "fuzzy" emails (foo@bar.com). * * See {@link LinkifyConstructorOptions} for available options. * * @param options Recognition options. * * @example * ```javascript * import { LinkifyIt } from 'linkify-it' * * const linkify = new LinkifyIt({ fuzzyLink: true }) * * linkify * .tlds(require('tlds')) // Reload with full TLD list * .tlds('onion', true) // Add unofficial `.onion` domain * .add('ftp:', null) // Disable `ftp:` protocol * .set({ fuzzyIP: true }) // Enable IPs in fuzzy links * * console.log(linkify.test('Site github.com!')) // true * console.log(linkify.match('Site github.com!')) * ``` */ constructor(options = {}) { const { rebuilder, ...linkifyOptions } = options; this.__opts__ = { ...defaultOptions, ...linkifyOptions }; this.__schemas__ = { ...defaultSchemas }; this.re = rebuilder || new REBuilder(); this.re.set({ ...this.__opts__, schema_names: Object.keys(this.__schemas__) }); } /** * Add new rule definition. * * `schema` is a link prefix (usually, protocol name with `:` at the end, * `skype:` for example). `linkify-it` makes sure that prefix is not * preceded with alphanumeric char and symbols. Only whitespaces and * punctuation allowed. * * `definition` is a rule to check tail after link prefix. To disable an * existing rule, pass `null`. * * @param schema Rule name (fixed pattern prefix). * @param definition Schema definition, or `null` to disable the rule. * * See [twitter mentions example](https://github.com/markdown-it/linkify-it/blob/master/examples/twitter.mjs). */ add(schema, definition = null) { if (!definition) delete this.__schemas__[schema]; else { const def = { normalize: (match, self) => self.normalize(match), ...definition }; this.__schemas__[schema] = def; } this.re.set({ ...this.__opts__, schema_names: Object.keys(this.__schemas__) }); return this; } /** * Set recognition options for links without schema. * * @param options Recognition options. */ set(options = {}) { this.__opts__ = { ...this.__opts__, ...options }; this.re.set({ ...this.__opts__, schema_names: Object.keys(this.__schemas__) }); return this; } /** * Searches linkifiable pattern and returns `true` on success or `false` on fail. * * @param text Text to scan. */ test(text) { if (!text.length) return false; let m, re; re = this.re.get_schema_search(); re.lastIndex = 0; while ((m = re.exec(text)) !== null) if (this.testSchemaAt(text, m[2], re.lastIndex)) return true; if (this.__opts__.fuzzyLink && this.__schemas__["http:"]) { re = this.re.get_fuzzy_link_search(); re.lastIndex = 0; if (re.exec(text) !== null) return true; } if (this.__opts__.fuzzyEmail && this.__schemas__["mailto:"]) { if (text.indexOf("@") >= 0) { const mailHostRe = this.re.get_fuzzy_mail_host_search(); const mailNameRe = this.re.get_mail_name_validator(); mailHostRe.lastIndex = 0; while ((m = mailHostRe.exec(text)) !== null) { const name = text.slice(Math.max(0, m.index - 65), m.index); if (mailNameRe.test(name)) return true; } } } return false; } /** * Similar to {@link LinkifyIt.test} but checks only specific protocol tail exactly * at given position. Returns length of found pattern (0 on fail). * * @param text Text to scan. * @param schema Rule (schema) name. * @param pos Text offset to check from. */ testSchemaAt(text, schema, pos) { if (!this.__schemas__[schema.toLowerCase()]) return 0; return this.__schemas__[schema.toLowerCase()].validate(text.slice(0, pos + this.__opts__.maxLength), pos, this); } /** * Returns array of found link descriptions or `null` on fail. We strongly * recommend to use {@link LinkifyIt.test} first, for best speed. * * @param text Text to scan. */ match(text) { const result = []; const schemaRe = this.re.get_schema_search(); let fuzzyLinkRe; let mailHostRe; let mailNameRe; let fuzzyLinkCandidate; let fuzzyEmailCandidate; let schemaPrefix; let schemaDone = false; let fuzzyLinkDone = false; let fuzzyEmailDone = false; let pos = 0; if (!text.length) return null; schemaRe.lastIndex = 0; if (this.__opts__.fuzzyLink && this.__schemas__["http:"]) { fuzzyLinkRe = this.re.get_fuzzy_link_search(); fuzzyLinkRe.lastIndex = 0; } if (this.__opts__.fuzzyEmail && this.__schemas__["mailto:"]) { mailHostRe = this.re.get_fuzzy_mail_host_search(); mailHostRe.lastIndex = 0; mailNameRe = this.re.get_mail_name_validator(); } for (;;) { const scanFrom = Math.max(pos - 1, 0); if (mailHostRe && mailNameRe && !fuzzyEmailDone && (!fuzzyEmailCandidate || fuzzyEmailCandidate.index < pos)) { if (mailHostRe.lastIndex < scanFrom) mailHostRe.lastIndex = scanFrom; for (;;) { const m = mailHostRe.exec(text); if (!m) { fuzzyEmailDone = true; fuzzyEmailCandidate = void 0; break; } const name = mailNameRe.exec(text.slice(Math.max(0, m.index - 65), m.index)); if (!name) continue; fuzzyEmailCandidate = { schema: "mailto:", index: m.index - name[1].length, lastIndex: m.index + m[0].length }; if (fuzzyEmailCandidate.index >= pos) break; if (mailHostRe.lastIndex < scanFrom) mailHostRe.lastIndex = scanFrom; } } if (fuzzyLinkRe && !fuzzyLinkDone && (!fuzzyLinkCandidate || fuzzyLinkCandidate.index < pos)) { if (fuzzyLinkRe.lastIndex < scanFrom) fuzzyLinkRe.lastIndex = scanFrom; for (;;) { const m = fuzzyLinkRe.exec(text); if (!m) { fuzzyLinkDone = true; fuzzyLinkCandidate = void 0; break; } fuzzyLinkCandidate = { schema: "", index: m.index + m[1].length, lastIndex: m.index + m[0].length }; if (fuzzyLinkCandidate.index >= pos) break; if (fuzzyLinkRe.lastIndex < scanFrom) fuzzyLinkRe.lastIndex = scanFrom; } } let fuzzyCandidate = fuzzyEmailCandidate; if (!fuzzyCandidate || fuzzyLinkCandidate && (fuzzyLinkCandidate.index < fuzzyCandidate.index || fuzzyLinkCandidate.index === fuzzyCandidate.index && fuzzyLinkCandidate.lastIndex > fuzzyCandidate.lastIndex)) fuzzyCandidate = fuzzyLinkCandidate; let schemaCandidate; if (!schemaDone) for (;;) { if (!schemaPrefix) { if (schemaRe.lastIndex < scanFrom) schemaRe.lastIndex = scanFrom; const m = schemaRe.exec(text); if (!m) { schemaDone = true; break; } schemaPrefix = { schema: m[2], index: m.index + m[1].length, lastIndex: m.index + m[0].length }; } if (schemaPrefix.index < pos) { schemaPrefix = void 0; continue; } if (fuzzyCandidate && schemaPrefix.index > fuzzyCandidate.index) break; const prefix = schemaPrefix; schemaPrefix = void 0; const len = this.testSchemaAt(text, prefix.schema, prefix.lastIndex); if (len) { schemaCandidate = { schema: prefix.schema, index: prefix.index, lastIndex: prefix.lastIndex + len }; break; } } let candidate = schemaCandidate; if (!candidate || fuzzyEmailCandidate && (fuzzyEmailCandidate.index < candidate.index || fuzzyEmailCandidate.index === candidate.index && fuzzyEmailCandidate.lastIndex > candidate.lastIndex)) candidate = fuzzyEmailCandidate; if (!candidate || fuzzyLinkCandidate && (fuzzyLinkCandidate.index < candidate.index || fuzzyLinkCandidate.index === candidate.index && fuzzyLinkCandidate.lastIndex > candidate.lastIndex)) candidate = fuzzyLinkCandidate; if (!candidate) break; if (candidate === fuzzyEmailCandidate) fuzzyEmailCandidate = void 0; else if (candidate === fuzzyLinkCandidate) fuzzyLinkCandidate = void 0; const match = new Match(text, candidate.schema, candidate.index, candidate.lastIndex); if (match.schema) this.__schemas__[match.schema].normalize(match, this); else this.normalize(match); result.push(match); pos = candidate.lastIndex; } if (result.length) return result; return null; } /** * Returns fully-formed (not fuzzy) link if it starts at the beginning * of the string, and null otherwise. * * @param text Text to scan. */ matchAtStart(text) { if (!text.length) return null; const m = this.re.get_schema_at_start().exec(text); if (!m) return null; const len = this.testSchemaAt(text, m[2], m[0].length); if (!len) return null; const match = new Match(text, m[2], m.index + m[1].length, m.index + m[0].length + len); this.__schemas__[match.schema].normalize(match, this); return match; } /** * Load (or merge) new TLDs list. Those are used for fuzzy links (without * prefix) to avoid false positives. By default this algorithm is used: * * - hostname with any 2-letter root zones are ok. * - biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф * are ok. * - encoded (`xn--...`) root zones are ok. * * If list is replaced, then exact match for 2-chars root zones will be checked. * * @param list List of TLDs. * @param keepOld Merge with current list if `true` (`false` by default). */ tlds(list, keepOld = false) { list = Array.isArray(list) ? list : [list]; if (!keepOld) this.__opts__.tlds = list; else this.__opts__.tlds = this.__opts__.tlds.concat(list); this.re.set({ ...this.__opts__, schema_names: Object.keys(this.__schemas__) }); return this; } /** * Default normalizer (if schema does not define its own). * * @param match Match to normalize. */ normalize(match) { if (!match.schema) match.url = `http://${match.url}`; if (match.schema === "mailto:" && !/^mailto:/i.test(match.url)) match.url = `mailto:${match.url}`; } }; //#endregion export { build_exports as i, P as n, S as r, LinkifyIt as t };