UNPKG

@convo-lang/convo-lang

Version:
96 lines 3.2 kB
import { parseXml } from "@iyio/common"; import { isConvoComponentMode } from "./convo-types.js"; /** * Finds the component type of a message. */ export const getConvoMessageComponentMode = (content) => { const types = (content ? /^\s*```([^\n]*).*```\s*$/s.exec(content) : null)?.[1]?.trim().split(' '); if (!types) { return undefined; } const last = types[types.length - 1]; return isConvoComponentMode(last) ? last : undefined; }; const convoComponentCacheKey = Symbol('convoComponentCacheKey'); /** * Parses message content as a convo component. Components are written in xml. The parsed component * is cached and stored on the message using a private symbol. * @param msg The message to parse */ export const getConvoMessageComponent = (msg) => { if (!msg?.content) { return undefined; } const cached = msg[convoComponentCacheKey]; if (cached) { return cached; } const comp = parseConvoComponent(msg.content); if (comp) { msg[convoComponentCacheKey] = comp; } return comp; }; const transformComponentReg = /^(\w+)\s+(\w+)(\s+(\w+))?(\s+\?\s*(!?\s*.*))?$/; /** * Parses the value of the `transformComponent` tag * @param value [groupName] {componentName} {propType} [?[!] condition] */ export const parseConvoComponentTransform = (value) => { if (!value) { return undefined; } const m = transformComponentReg.exec(value); if (!m) { return undefined; } const hasGroup = m[4] ? true : false; const ni = hasGroup ? 2 : 1; return { componentName: m[ni] ?? '', propType: m[hasGroup ? ni + 2 : 2] ?? '', groupName: (hasGroup ? m[1] : m[ni]) || undefined, condition: m[6]?.trim() || undefined, }; }; const mdFenceReg = /^[\n\s]*```[^\n]*/; const jsonReg = /^[\n\s]*\{/; export const parseConvoMessageComponents = (content, defaultComponentName) => { const fenceMatch = mdFenceReg.exec(content); if (fenceMatch) { content = content.substring(fenceMatch[0].length).trim(); if (content.endsWith('```')) { content = content.substring(0, content.length - 3); } } if (jsonReg.test(content)) { const json = JSON.parse(content); return [{ isJson: true, name: defaultComponentName ?? 'Json', atts: json ? ((typeof json === 'object') ? json : { value: json }) : { value: json }, }]; } else { return parseXml(content, { parseJsonAtts: true }).result; } }; /** * Parses message content as a convo component. Components are written in xml. * @param content string content to parse */ export const parseConvoComponent = (content) => { if (!content) { return undefined; } const codeBlockMatch = /^\s*```[^\n]*(.*)```\s*$/s.exec(content); if (codeBlockMatch?.[1]) { content = codeBlockMatch[1]; } const xml = parseXml(content, { parseJsonAtts: true, stopOnFirstNode: true }); if (xml.error) { console.error('convo component parsing failed', xml.error); } return xml.result?.[0]; }; //# sourceMappingURL=convo-component-lib.js.map