UNPKG

pomljs

Version:

Prompt Orchestration Markup Language

1 lines 72.3 kB
{"version":3,"file":"file.cjs","sources":["../.build/file.js"],"sourcesContent":["/**\n * Handles the files (with .poml extension).\n */\nimport { parse as parseXML } from '@xml-tools/parser';\nimport { buildAst } from '@xml-tools/ast';\nimport * as React from 'react';\nimport { ReadError, SourceProvider, findComponentByAlias, findComponentByAliasOrUndefined, listComponents } from './base';\nimport { deepMerge, parseText, readSource } from './util';\nimport { StyleSheetProvider, ErrorCollection } from './base';\nimport { getSuggestions } from './util/xmlContentAssist';\nimport { existsSync, readFileSync } from 'fs';\nimport path from 'path';\nimport { POML_VERSION } from './version';\nexport class PomlFile {\n text;\n sourcePath;\n config;\n ast;\n cst;\n tokenVector;\n documentRange;\n disabledComponents = new Set();\n constructor(text, options, sourcePath) {\n this.config = {\n trim: options?.trim ?? true,\n autoAddPoml: options?.autoAddPoml ?? true,\n crlfToLf: options?.crlfToLf ?? true\n };\n this.text = this.config.crlfToLf ? text.replace(/\\r\\n/g, '\\n') : text;\n this.sourcePath = sourcePath;\n if (this.sourcePath) {\n const envFile = this.sourcePath.replace(/(source\\.)?\\.poml$/i, '.env');\n if (existsSync(envFile)) {\n try {\n const envText = readFileSync(envFile, 'utf8');\n const match = envText.match(/^SOURCE_PATH=(.*)$/m);\n if (match) {\n // The real source path is specified in the .env file.\n this.sourcePath = match[1];\n }\n }\n catch {\n /* ignore */\n }\n }\n }\n this.documentRange = { start: 0, end: text.length - 1 };\n let { ast, cst, tokenVector, errors } = this.readXml(text);\n let addPoml = undefined;\n if (this.config.autoAddPoml && text.slice(5).toLowerCase() !== '<poml') {\n if (!ast || !ast.rootElement) {\n // Invalid XML. Treating it as a free text.\n addPoml = '<poml syntax=\"text\" whiteSpace=\"pre\">';\n }\n else if (\n // Valid XML, but contains e.g., multiple root elements.\n (ast.rootElement.position.startOffset > 0 &&\n !this.testAllCommentsAndSpace(0, ast.rootElement.position.startOffset - 1, tokenVector)) ||\n (ast.rootElement.position.endOffset + 1 < text.length &&\n !this.testAllCommentsAndSpace(ast.rootElement.position.endOffset + 1, text.length - 1, tokenVector))) {\n addPoml = '<poml syntax=\"markdown\">';\n }\n }\n if (addPoml) {\n this.documentRange = { start: addPoml.length, end: text.length - 1 + addPoml.length };\n this.config.trim = options?.trim ?? false; // TODO: this is an ad-hoc fix.\n let { ast, cst, tokenVector, errors } = this.readXml(addPoml + text + '</poml>');\n this.ast = ast;\n this.cst = cst;\n this.tokenVector = tokenVector;\n // Report errors\n for (const error of errors) {\n ErrorCollection.add(error);\n }\n }\n else {\n this.ast = ast;\n this.cst = cst;\n this.tokenVector = tokenVector;\n for (const error of errors) {\n ErrorCollection.add(error);\n }\n }\n }\n readXml(text) {\n const { cst, tokenVector, lexErrors, parseErrors } = parseXML(text);\n const errors = [];\n for (const lexError of lexErrors) {\n errors.push(this.formatError(lexError.message, {\n start: this.ensureRange(lexError.offset),\n end: this.ensureRange(lexError.offset)\n }, lexErrors));\n }\n for (const parseError of parseErrors) {\n let startOffset = parseError.token.startOffset;\n let endOffset = parseError.token.endOffset;\n if (isNaN(startOffset) &&\n (endOffset === undefined || isNaN(endOffset)) &&\n parseError.previousToken) {\n startOffset = parseError.previousToken.endOffset;\n endOffset = parseError.previousToken.endOffset;\n }\n errors.push(this.formatError(parseError.message, {\n start: this.ensureRange(startOffset),\n end: endOffset ? this.ensureRange(endOffset) : this.ensureRange(startOffset)\n }, parseError));\n }\n let ast = undefined;\n try {\n ast = buildAst(cst, tokenVector);\n }\n catch (e) {\n errors.push(this.formatError('Error building AST', {\n start: this.ensureRange(0),\n end: this.ensureRange(text.length)\n }, e));\n }\n return { ast, cst, tokenVector, errors };\n }\n testAllCommentsAndSpace(startOffset, endOffset, tokens) {\n // start to end, inclusive. It must not be in the middle of a token.\n const tokensFiltered = tokens.filter((token) => token.startOffset >= startOffset && (token.endOffset ?? token.startOffset) <= endOffset);\n return tokensFiltered.every((token) => {\n if (token.tokenType.name === 'SEA_WS' || token.tokenType.name === 'Comment') {\n return true;\n }\n else if (/^\\s*$/.test(token.image)) {\n return true;\n }\n return false;\n });\n }\n readJsonElement(parent, tagName) {\n const element = xmlElementContents(parent).filter(i => i.type === 'XMLElement' && i.name?.toLowerCase() === tagName.toLowerCase());\n if (element.length === 0) {\n return undefined;\n }\n if (element.length > 1) {\n this.reportError(`Multiple ${tagName} element found.`, {\n start: this.ensureRange(element[0].position.startOffset),\n end: this.ensureRange(element[element.length - 1].position.endOffset)\n });\n return undefined;\n }\n const text = xmlElementText(element[0]);\n try {\n return JSON.parse(text);\n }\n catch (e) {\n this.reportError(e !== undefined && e.message\n ? e.message\n : `Error parsing JSON: ${text}`, this.xmlElementRange(element[0]), e);\n return undefined;\n }\n }\n xmlRootElement() {\n if (!this.ast || !this.ast.rootElement) {\n this.reportError('Root element is invalid.', {\n start: this.ensureRange(this.documentRange.start),\n end: this.ensureRange(this.documentRange.end)\n });\n return undefined;\n }\n else {\n return this.ast.rootElement;\n }\n }\n react(context) {\n const rootElement = this.xmlRootElement();\n if (rootElement) {\n // See whether stylesheet and context is available\n const stylesheet = this.readJsonElement(rootElement, 'stylesheet');\n context = deepMerge(context || {}, this.readJsonElement(rootElement, 'context') || {});\n let parsedElement = this.parseXmlElement(rootElement, context || {}, {});\n if (stylesheet) {\n parsedElement = React.createElement(StyleSheetProvider, { stylesheet }, parsedElement);\n }\n if (this.sourcePath) {\n parsedElement = React.createElement(SourceProvider, { source: this.sourcePath }, parsedElement);\n }\n return parsedElement;\n }\n else {\n return React.createElement(React.Fragment, null);\n }\n }\n getHoverToken(offset) {\n const realOffset = this.recoverPosition(offset);\n if (!this.ast || !this.ast.rootElement) {\n return undefined;\n }\n return this.findTokenInElement(this.ast.rootElement, realOffset);\n }\n getCompletions(offset) {\n const realOffset = this.recoverPosition(offset);\n if (!this.ast || !this.ast.rootElement) {\n return [];\n }\n return getSuggestions({\n ast: this.ast,\n cst: this.cst,\n tokenVector: this.tokenVector,\n offset: realOffset,\n providers: {\n // 1. There are more types(scenarios) of suggestions providers (see api.d.ts)\n // 2. Multiple providers may be supplied for a single scenario.\n elementName: [this.handleElementNameCompletion(realOffset)],\n elementNameClose: [this.handleElementNameCloseCompletion(realOffset)],\n attributeName: [this.handleAttributeNameCompletion(realOffset)],\n attributeValue: [this.handleAttributeValueCompletion(realOffset)]\n }\n });\n }\n formatError(msg, range, cause) {\n return ReadError.fromProps(msg, {\n originalStartIndex: range?.start,\n originalEndIndex: range?.end,\n sourcePath: this.sourcePath\n }, { cause: cause });\n }\n reportError(msg, range, cause) {\n ErrorCollection.add(this.formatError(msg, range, cause));\n }\n /**\n * Template related functions only usable in standalone poml files.\n * It's not available for POML expressed with JSX or Python SDK.\n */\n handleForLoop(element, context) {\n const forLoop = element.attributes.find(attr => attr.key?.toLowerCase() === 'for');\n if (!forLoop) {\n // No for loop found.\n return [];\n }\n const forLoopValue = forLoop.value;\n if (!forLoopValue) {\n this.reportError('for attribute value is expected.', this.xmlElementRange(element));\n return [];\n }\n const [itemName, listName] = forLoopValue.match(/(.+)\\s+in\\s+(.+)/)?.slice(1) || [null, null];\n if (!itemName || !listName) {\n this.reportError('item in list syntax is expected in for attribute.', this.xmlAttributeValueRange(forLoop));\n return [];\n }\n const list = this.evaluateExpression(listName, context, this.xmlAttributeValueRange(forLoop));\n if (!Array.isArray(list)) {\n this.reportError('List is expected in for attribute.', this.xmlAttributeValueRange(forLoop));\n return [];\n }\n return list.map((item, index) => {\n const loop = {\n index: index,\n length: list.length,\n first: index === 0,\n last: index === list.length - 1\n };\n return { loop: loop, [itemName]: item };\n });\n }\n handleIfCondition = (element, context) => {\n const ifCondition = element.attributes.find(attr => attr.key?.toLowerCase() === 'if');\n if (!ifCondition) {\n // No if condition found.\n return true;\n }\n const ifConditionValue = ifCondition.value;\n if (!ifConditionValue) {\n this.reportError('if attribute value is expected.', this.xmlAttributeValueRange(ifCondition));\n return false;\n }\n const condition = this.evaluateExpression(ifConditionValue, context, this.xmlAttributeValueRange(ifCondition), true);\n if (condition) {\n return true;\n }\n else {\n return false;\n }\n };\n handleLet = (element, context) => {\n if (element.name?.toLowerCase() !== 'let') {\n return false;\n }\n const source = xmlAttribute(element, 'src')?.value;\n const type = xmlAttribute(element, 'type')?.value;\n const name = xmlAttribute(element, 'name')?.value;\n const value = xmlAttribute(element, 'value')?.value;\n // Case 1: <let name=\"var1\" src=\"/path/to/file\" />, case insensitive\n // or <let src=\"/path/to/file\" />, case insensitive\n if (source) {\n let content;\n try {\n content = readSource(source, this.sourcePath ? path.dirname(this.sourcePath) : undefined, type);\n }\n catch (e) {\n this.reportError(e !== undefined && e.message\n ? e.message\n : `Error reading source: ${source}`, this.xmlAttributeValueRange(xmlAttribute(element, 'src')), e);\n return true;\n }\n if (!name) {\n if (content && typeof content === 'object') {\n Object.assign(context, content);\n }\n else {\n this.reportError('name attribute is expected when the source is not an object.', this.xmlElementRange(element));\n }\n }\n else {\n context[name] = content;\n }\n return true;\n }\n // Case 2: <let name=\"var1\" value=\"{{ expression }}\" />, case insensitive\n if (value) {\n if (!name) {\n this.reportError('name attribute is expected when <let> contains two attributes.', this.xmlElementRange(element));\n return true;\n }\n const evaluated = this.evaluateExpression(value, context, this.xmlAttributeValueRange(xmlAttribute(element, 'value')), true);\n context[name] = evaluated;\n return true;\n }\n // Case 3: <let>{ JSON }</let>\n // or <let name=\"var1\" type=\"number\">{ JSON }</let>\n if (element.textContents.length > 0) {\n const text = xmlElementText(element);\n let content;\n try {\n content = parseText(text, type);\n }\n catch (e) {\n this.reportError(e !== undefined && e.message\n ? e.message\n : `Error parsing text as type ${type}: ${text}`, this.xmlElementRange(element), e);\n return true;\n }\n if (!name) {\n if (content && typeof content === 'object') {\n Object.assign(context, content);\n }\n else {\n this.reportError('name attribute is expected when the source is not an object.', this.xmlElementRange(element));\n }\n }\n else {\n context[name] = content;\n }\n return true;\n }\n this.reportError('Invalid <let> element.', this.xmlElementRange(element));\n return true;\n };\n handleAttribute = (attribute, context) => {\n if (!attribute.key || !attribute.value) {\n return;\n }\n if (attribute.key.toLowerCase() === 'for' || attribute.key.toLowerCase() === 'if') {\n return;\n }\n const key = hyphenToCamelCase(attribute.key);\n const value = this.handleText(attribute.value, context, this.xmlAttributeValueRange(attribute));\n if (value.length === 1) {\n return [key, value[0]];\n }\n else {\n return [key, value];\n }\n };\n handleInclude = (element, context) => {\n if (element.name?.toLowerCase() !== 'include') {\n return undefined;\n }\n const src = xmlAttribute(element, 'src');\n if (!src || !src.value) {\n this.reportError('src attribute is expected.', this.xmlElementRange(element));\n return React.createElement(React.Fragment, null);\n }\n const source = src.value;\n let text;\n try {\n text = readSource(source, this.sourcePath ? path.dirname(this.sourcePath) : undefined, 'string');\n }\n catch (e) {\n this.reportError(e !== undefined && e.message\n ? e.message\n : `Error reading source: ${source}`, this.xmlAttributeValueRange(src), e);\n return React.createElement(React.Fragment, null);\n }\n const includePath = this.sourcePath && !path.isAbsolute(source)\n ? path.join(path.dirname(this.sourcePath), source)\n : source;\n const included = new PomlFile(text, this.config, includePath);\n const root = included.xmlRootElement();\n if (!root) {\n return React.createElement(React.Fragment, null);\n }\n let contents = [];\n if (root.name?.toLowerCase() === 'poml') {\n contents = xmlElementContents(root);\n }\n else {\n contents = [root];\n }\n const resultNodes = [];\n contents.forEach((el, idx) => {\n if (el.type === 'XMLTextContent') {\n resultNodes.push(...included\n .handleText(el.text ?? '', context, included.xmlElementRange(el))\n .map(v => typeof v === 'object' && v !== null && !React.isValidElement(v)\n ? JSON.stringify(v)\n : v));\n }\n else if (el.type === 'XMLElement') {\n const child = included.parseXmlElement(el, context, {});\n resultNodes.push(React.isValidElement(child) ? React.cloneElement(child, { key: `child-${idx}` }) : child);\n }\n });\n if (resultNodes.length === 1) {\n return React.createElement(React.Fragment, null, resultNodes[0]);\n }\n return React.createElement(React.Fragment, null, resultNodes);\n };\n handleMeta = (element) => {\n if (element.name?.toLowerCase() !== 'meta') {\n return false;\n }\n const minVersion = xmlAttribute(element, 'minVersion')?.value;\n if (minVersion && compareVersions(POML_VERSION, minVersion) < 0) {\n this.reportError(`POML version ${minVersion} or higher is required`, this.xmlAttributeValueRange(xmlAttribute(element, 'minVersion')));\n }\n const maxVersion = xmlAttribute(element, 'maxVersion')?.value;\n if (maxVersion && compareVersions(POML_VERSION, maxVersion) > 0) {\n this.reportError(`POML version ${maxVersion} or lower is required`, this.xmlAttributeValueRange(xmlAttribute(element, 'maxVersion')));\n }\n const comps = xmlAttribute(element, 'components')?.value;\n if (comps) {\n comps.split(/[,\\s]+/).forEach(token => {\n token = token.trim();\n if (!token) {\n return;\n }\n const op = token[0];\n const name = token.slice(1).toLowerCase().trim();\n if (!name) {\n return;\n }\n if (op === '+') {\n this.disabledComponents.delete(name);\n }\n else if (op === '-') {\n this.disabledComponents.add(name);\n }\n else {\n this.reportError(`Invalid component operation: ${op}. Use + to enable or - to disable.`, this.xmlAttributeValueRange(xmlAttribute(element, 'components')));\n }\n });\n }\n return true;\n };\n unescapeText = (text) => {\n return text\n .replace(/#lt;/g, '<')\n .replace(/#gt;/g, '>')\n .replace(/#amp;/g, '&')\n .replace(/#quot;/g, '\"')\n .replace(/#apos;/g, \"'\")\n .replace(/#hash;/g, '#')\n .replace(/#lbrace;/g, '{')\n .replace(/#rbrace;/g, '}');\n };\n handleText = (text, context, position) => {\n let curlyMatch;\n let replacedPrefixLength = 0;\n let results = [];\n const regex = /{{\\s*(.+?)\\s*}}(?!})/gm;\n while ((curlyMatch = regex.exec(text))) {\n const curlyExpression = curlyMatch[1];\n const value = this.evaluateExpression(curlyExpression, context, position\n ? {\n start: position.start + curlyMatch.index,\n end: position.start + curlyMatch.index + curlyMatch[0].length - 1\n }\n : undefined);\n if (this.config.trim && curlyMatch[0] === text.trim()) {\n return [value];\n }\n if (curlyMatch.index > replacedPrefixLength) {\n results.push(this.unescapeText(text.slice(replacedPrefixLength, curlyMatch.index)));\n }\n results.push(value);\n replacedPrefixLength = curlyMatch.index + curlyMatch[0].length;\n }\n if (text.length > replacedPrefixLength) {\n results.push(this.unescapeText(text.slice(replacedPrefixLength)));\n }\n if (results.length > 0 && results.every(r => typeof r === 'string' || typeof r === 'number')) {\n return [results.map(r => r.toString()).join('')];\n }\n return results;\n };\n evaluateExpression(expression, context, range, stripCurlyBrackets = false) {\n try {\n if (stripCurlyBrackets) {\n const curlyMatch = expression.match(/^\\s*{{\\s*(.+?)\\s*}}\\s*$/m);\n if (curlyMatch) {\n expression = curlyMatch[1];\n }\n }\n return evalWithVariables(expression, context || {});\n }\n catch (e) {\n this.reportError(e !== undefined && e.message\n ? e.message\n : `Error evaluating expression: ${expression}`, range, e);\n return '';\n }\n }\n /**\n * Parse the XML element and return the corresponding React element.\n *\n * @param element The element to be converted.\n * @param globalContext The context can be carried over when the function returns.\n * @param localContext The context that is only available in the current element and its children.\n */\n parseXmlElement(element, globalContext, localContext) {\n // Let. Always set the global.\n if (this.handleLet(element, globalContext)) {\n return React.createElement(React.Fragment, null);\n }\n if (this.handleMeta(element)) {\n return React.createElement(React.Fragment, null);\n }\n const tagName = element.name;\n if (!tagName) {\n // Probably already had an invalid syntax error.\n return React.createElement(React.Fragment, null);\n }\n const isInclude = tagName.toLowerCase() === 'include';\n // Common logic for handling for-loops\n const forLoops = this.handleForLoop(element, globalContext);\n const forLoopedContext = forLoops.length > 0 ? forLoops : [{}];\n const resultElements = [];\n for (let i = 0; i < forLoopedContext.length; i++) {\n const currentLocal = { ...localContext, ...forLoopedContext[i] };\n const context = { ...globalContext, ...currentLocal };\n // Common logic for handling if-conditions\n if (!this.handleIfCondition(element, context)) {\n continue;\n }\n let elementToAdd = null;\n if (isInclude) {\n // Logic for <include> tags\n const included = this.handleInclude(element, context);\n if (included) {\n // Add a key if we are in a loop with multiple items\n if (forLoopedContext.length > 1) {\n elementToAdd = React.createElement(React.Fragment, { key: `include-${i}` }, included);\n }\n else {\n elementToAdd = included;\n }\n }\n }\n else {\n // Logic for all other components\n const component = findComponentByAlias(tagName, this.disabledComponents);\n if (typeof component === 'string') {\n // Add a read error\n this.reportError(component, this.xmlOpenNameRange(element));\n // Return empty fragment to prevent rendering this element\n // You might want to 'continue' the loop as well.\n return React.createElement(React.Fragment, null);\n }\n const attrib = element.attributes.reduce((acc, attribute) => {\n const [key, value] = this.handleAttribute(attribute, context) || [null, null];\n if (key && value !== null) {\n acc[key] = value;\n }\n return acc;\n }, {});\n // Retain the position of current element for future diagnostics\n const range = this.xmlElementRange(element);\n attrib.originalStartIndex = range.start;\n attrib.originalEndIndex = range.end;\n // Add key attribute for react\n if (!attrib.key && forLoopedContext.length > 1) {\n attrib.key = `key-${i}`;\n }\n const contents = xmlElementContents(element).filter(el => {\n // Filter out stylesheet and context element in the root poml element\n if (tagName === 'poml' &&\n el.type === 'XMLElement' &&\n ['context', 'stylesheet'].includes(el.name?.toLowerCase() ?? '')) {\n return false;\n }\n else {\n return true;\n }\n });\n const avoidObject = (el) => {\n if (typeof el === 'object' && el !== null && !React.isValidElement(el)) {\n return JSON.stringify(el);\n }\n return el;\n };\n const processedContents = contents.reduce((acc, el, i) => {\n if (el.type === 'XMLTextContent') {\n // const isFirst = i === 0,\n // isLast = i === contents.length - 1;\n // const text = this.config.trim ? trimText(el.text || '', isFirst, isLast) : el.text || '';\n acc.push(...this.handleText(el.text ?? '', { ...globalContext, ...currentLocal }, this.xmlElementRange(el)).map(avoidObject));\n }\n else if (el.type === 'XMLElement') {\n acc.push(this.parseXmlElement(el, globalContext, currentLocal));\n }\n return acc;\n }, []);\n elementToAdd = React.createElement(component.render.bind(component), attrib, ...processedContents);\n }\n if (elementToAdd) {\n // If we have an element to add, push it to the result elements.\n resultElements.push(elementToAdd);\n }\n }\n // Common logic for returning the final result\n if (resultElements.length === 1) {\n return resultElements[0];\n }\n else {\n // Cases where there are multiple elements or zero elements.\n return React.createElement(React.Fragment, null, resultElements);\n }\n }\n recoverPosition(position) {\n return position + this.documentRange.start;\n }\n ensureRange(position) {\n return Math.max(Math.min(position, this.documentRange.end) - this.documentRange.start, 0);\n }\n xmlElementRange(element) {\n return {\n start: this.ensureRange(element.position.startOffset),\n end: this.ensureRange(element.position.endOffset)\n };\n }\n xmlOpenNameRange(element) {\n if (element.syntax.openName) {\n return {\n start: this.ensureRange(element.syntax.openName.startOffset),\n end: this.ensureRange(element.syntax.openName.endOffset)\n };\n }\n else {\n return this.xmlElementRange(element);\n }\n }\n xmlCloseNameRange(element) {\n if (element.syntax.closeName) {\n return {\n start: this.ensureRange(element.syntax.closeName.startOffset),\n end: this.ensureRange(element.syntax.closeName.endOffset)\n };\n }\n else {\n return this.xmlElementRange(element);\n }\n }\n xmlAttributeKeyRange(element) {\n if (element.syntax.key) {\n return {\n start: this.ensureRange(element.syntax.key.startOffset),\n end: this.ensureRange(element.syntax.key.endOffset)\n };\n }\n else {\n return this.xmlElementRange(element);\n }\n }\n xmlAttributeValueRange(element) {\n if (element.syntax.value) {\n return {\n start: this.ensureRange(element.syntax.value.startOffset),\n end: this.ensureRange(element.syntax.value.endOffset)\n };\n }\n else {\n return this.xmlElementRange(element);\n }\n }\n findTokenInElement(element, offset) {\n if (element.name) {\n if (element.syntax.openName &&\n element.syntax.openName.startOffset <= offset &&\n offset <= element.syntax.openName.endOffset) {\n return {\n type: 'element',\n range: this.xmlOpenNameRange(element),\n element: element.name\n };\n }\n if (element.syntax.closeName &&\n element.syntax.closeName.startOffset <= offset &&\n offset <= element.syntax.closeName.endOffset) {\n return {\n type: 'element',\n range: this.xmlCloseNameRange(element),\n element: element.name\n };\n }\n for (const attrib of element.attributes) {\n if (attrib.key &&\n attrib.syntax.key &&\n attrib.syntax.key.startOffset <= offset &&\n offset <= attrib.syntax.key.endOffset) {\n return {\n type: 'attribute',\n range: this.xmlAttributeKeyRange(attrib),\n element: element.name,\n attribute: attrib.key\n };\n }\n }\n }\n for (const child of element.subElements) {\n const result = this.findTokenInElement(child, offset);\n if (result) {\n return result;\n }\n }\n }\n handleElementNameCompletion(offset) {\n return ({ element, prefix }) => {\n const candidates = this.findComponentWithPrefix(prefix, true);\n return candidates.map(candidate => {\n return {\n type: 'element',\n range: {\n start: this.ensureRange(offset - (prefix ? prefix.length : 0)),\n end: this.ensureRange(offset - 1)\n },\n element: candidate\n };\n });\n };\n }\n handleElementNameCloseCompletion(offset) {\n return ({ element, prefix }) => {\n const candidates = [];\n const excludedComponents = [];\n if (element.name) {\n candidates.push(element.name);\n const component = findComponentByAliasOrUndefined(element.name, this.disabledComponents);\n if (component !== undefined) {\n excludedComponents.push(component.name);\n }\n }\n if (prefix) {\n candidates.push(...this.findComponentWithPrefix(prefix, true, excludedComponents));\n }\n return candidates.map(candidate => {\n return {\n type: 'element',\n range: {\n start: this.ensureRange(offset - (prefix ? prefix.length : 0)),\n end: this.ensureRange(offset - 1)\n },\n element: candidate\n };\n });\n };\n }\n handleAttributeNameCompletion(offset) {\n return ({ element, prefix }) => {\n if (!element.name) {\n return [];\n }\n const component = findComponentByAliasOrUndefined(element.name, this.disabledComponents);\n const parameters = component?.parameters();\n if (!component || !parameters) {\n return [];\n }\n const candidates = [];\n for (const parameter of parameters) {\n if (parameter.name.toLowerCase().startsWith(prefix?.toLowerCase() ?? '')) {\n candidates.push({\n type: 'attribute',\n range: {\n start: this.ensureRange(offset - (prefix ? prefix.length : 0)),\n end: this.ensureRange(offset - 1)\n },\n element: component.name,\n attribute: parameter.name\n });\n }\n }\n return candidates;\n };\n }\n handleAttributeValueCompletion(offset) {\n return ({ element, attribute, prefix }) => {\n if (!element.name) {\n return [];\n }\n const component = findComponentByAliasOrUndefined(element.name, this.disabledComponents);\n const parameters = component?.parameters();\n if (!component || !parameters) {\n return [];\n }\n const candidates = [];\n for (const parameter of parameters) {\n if (parameter.name.toLowerCase() === attribute.key?.toLowerCase()) {\n for (const choice of parameter.choices) {\n if (choice.toLowerCase().startsWith(prefix?.toLowerCase() ?? '')) {\n candidates.push({\n type: 'attributeValue',\n range: {\n start: this.ensureRange(offset - (prefix ? prefix.length : 0)),\n end: this.ensureRange(offset - 1)\n },\n element: component.name,\n attribute: parameter.name,\n value: choice\n });\n }\n }\n }\n }\n return candidates;\n };\n }\n findComponentWithPrefix(prefix, publicOnly, excludedComponents) {\n const candidates = [];\n for (const component of listComponents()) {\n if (publicOnly && !component.isPublic()) {\n continue;\n }\n if (excludedComponents && excludedComponents.includes(component.name)) {\n continue;\n }\n let nameMatch = undefined;\n if (!prefix || component.name.toLowerCase().startsWith(prefix.toLowerCase())) {\n nameMatch = component.name;\n }\n else {\n const candidates = [];\n for (const alias of component.getAliases()) {\n if (alias.toLowerCase().startsWith(prefix.toLowerCase())) {\n candidates.push(alias);\n // One component can have at most one alias match.\n break;\n }\n }\n // Match hyphen case.\n for (const alias of component.getAliases(false)) {\n const aliasHyphen = camelToHyphenCase(alias);\n if (aliasHyphen.startsWith(prefix.toLowerCase())) {\n candidates.push(aliasHyphen);\n break;\n }\n }\n // Try to see if there is a match in the exact case.\n for (const candidate of candidates) {\n if (candidate.startsWith(prefix)) {\n nameMatch = candidate;\n break;\n }\n }\n if (!nameMatch && candidates) {\n nameMatch = candidates[0];\n }\n }\n if (nameMatch) {\n candidates.push(nameMatch);\n }\n }\n return candidates;\n }\n}\n/**\n * XML utility functions.\n */\nconst evalWithVariables = (text, context) => {\n const variableNames = Object.keys(context);\n const variableValues = Object.values(context);\n const fn = new Function(...variableNames, `return ${text}`);\n return fn(...variableValues);\n};\nconst hyphenToCamelCase = (text) => {\n return text.replace(/-([a-z])/g, g => g[1].toUpperCase());\n};\nconst camelToHyphenCase = (text) => {\n return text.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n};\n/**\n * Compares two semantic version strings (e.g., \"1.2.3\").\n *\n * @param a - The first version string in the format \"x.y.z\".\n * @param b - The second version string in the format \"x.y.z\".\n * @returns -1 if `a` is less than `b`, 1 if `a` is greater than `b`, and 0 if they are equal.\n */\nconst compareVersions = (a, b) => {\n const pa = a.split('.').map(n => parseInt(n, 10));\n const pb = b.split('.').map(n => parseInt(n, 10));\n for (let i = 0; i < Math.max(pa.length, pb.length); i++) {\n const na = pa[i] || 0;\n const nb = pb[i] || 0;\n if (na > nb) {\n return 1;\n }\n if (na < nb) {\n return -1;\n }\n }\n return 0;\n};\nconst xmlAttribute = (element, key) => {\n return element.attributes.find(attr => attr.key?.toLowerCase() === key.toLowerCase());\n};\nconst xmlElementContents = (element) => {\n return [...element.subElements, ...element.textContents].sort((i, j) => i.position.startOffset - j.position.startOffset);\n};\nconst xmlElementText = (element) => {\n return element.textContents.map(content => content.text || '').join(' ');\n};\n//# sourceMappingURL=file.js.map"],"names":["existsSync","readFileSync","ErrorCollection","parseXML","ast","buildAst","deepMerge","React","StyleSheetProvider","SourceProvider","getSuggestions","ReadError","readSource","parseText","POML_VERSION","findComponentByAlias","findComponentByAliasOrUndefined","listComponents"],"mappings":"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