@dpml/core
Version:
DPML Core: Implementations of base compiler, and provide a simple framework for domain developers.
1,693 lines (1,680 loc) • 177 kB
JavaScript
import { Command } from 'commander';
import * as xml2js from 'xml2js';
import fs from 'fs/promises';
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
// src/core/cli/commandUtils.ts
function mergeDefaultOptions(options) {
return {
defaultDomain: "core",
...options
};
}
__name(mergeDefaultOptions, "mergeDefaultOptions");
function getCommandPath(command, parentPath) {
let path = command.name;
if (parentPath) {
path = `${parentPath} ${path}`;
}
if (command.category && !parentPath) {
path = `${command.category} ${path}`;
}
return path;
}
__name(getCommandPath, "getCommandPath");
function validateCommands(commands) {
const pathSet = /* @__PURE__ */ new Set();
const crossDomainMap = /* @__PURE__ */ new Map();
function validateCommandTree(command, parentPath) {
const path = getCommandPath(command, parentPath);
if (pathSet.has(path)) {
throw new Error(`\u91CD\u590D\u7684\u547D\u4EE4\u5B9A\u4E49: ${path}`);
}
pathSet.add(path);
if (!parentPath && command.name) {
const domain = command.category || "default";
const registeredDomains = crossDomainMap.get(command.name) || [];
if (registeredDomains.length > 0 && !registeredDomains.includes(domain)) {
const conflictDomains = registeredDomains.join(", ");
console.warn(`\u8B66\u544A: \u547D\u4EE4 "${command.name}" \u5728\u591A\u4E2A\u9886\u57DF\u4E2D\u5B9A\u4E49: ${conflictDomains} \u548C ${domain}`);
}
if (!registeredDomains.includes(domain)) {
crossDomainMap.set(command.name, [
...registeredDomains,
domain
]);
}
}
if (command.subcommands && command.subcommands.length > 0) {
for (const subcommand of command.subcommands) {
validateCommandTree(subcommand, path);
}
}
}
__name(validateCommandTree, "validateCommandTree");
for (const command of commands) {
validateCommandTree(command);
}
}
__name(validateCommands, "validateCommands");
// src/core/cli/CLIAdapter.ts
var _CLIAdapter = class _CLIAdapter {
/**
* 创建CLI适配器
*
* @param name CLI名称
* @param version CLI版本
* @param description CLI描述
*/
constructor(name, version, description) {
/**
* Commander程序实例
*/
__publicField(this, "program");
/**
* 已注册的命令路径集合
*/
__publicField(this, "commandPaths");
this.program = new Command(name).version(version).description(description);
this.commandPaths = /* @__PURE__ */ new Set();
if (typeof this.program.exitOverride === "function" && process.env.NODE_ENV !== "test" && !process.env.VITEST) {
this.program.exitOverride();
}
}
/**
* 注册命令
*
* @param command 命令定义
* @param parentPath 父命令路径
*/
setupCommand(command, parentPath) {
const path = getCommandPath(command, parentPath);
if (this.commandPaths.has(path)) {
throw new Error(`\u91CD\u590D\u7684\u547D\u4EE4\u5B9A\u4E49: ${path}`);
}
this.commandPaths.add(path);
const parentCommand = parentPath ? this.findParentCommand(parentPath) : this.program;
const cmd = parentCommand.command(command.name);
if (command.description) {
cmd.description(command.description);
}
if (command.arguments && command.arguments.length > 0) {
for (const arg of command.arguments) {
const name = arg.required ? arg.name : `${arg.name} [value]`;
cmd.argument(name, arg.description, arg.defaultValue);
}
}
if (command.options && command.options.length > 0) {
for (const opt of command.options) {
if (opt.defaultValue !== void 0) {
if (typeof opt.defaultValue === "number") {
cmd.option(opt.flags, opt.description || "", (value) => Number(value), opt.defaultValue);
} else {
cmd.option(opt.flags, opt.description || "", opt.defaultValue);
}
} else {
cmd.option(opt.flags, opt.description || "");
}
}
}
if (command.action) {
cmd.action(async (...args) => {
try {
await command.action(...args);
} catch (err) {
this.handleError(err, command);
throw err;
}
});
}
if (command.subcommands && command.subcommands.length > 0) {
for (const subcommand of command.subcommands) {
this.setupCommand(subcommand, path);
}
}
}
/**
* 注册领域命令
*
* @deprecated 此方法已弃用,请使用setupCommand直接注册命令。提供此方法仅为向后兼容。
* @param domain 领域名称
* @param commands 命令定义数组
*/
setupDomainCommands(domain, commands) {
for (const command of commands) {
this.setupCommand({
...command,
category: domain
});
}
}
/**
* 显示CLI帮助信息
*/
showHelp() {
console.log(`dpml - Deepractice\u63D0\u793A\u8BCD\u6807\u8BB0\u8BED\u8A00`);
console.log(`\u7248\u672C: ${this.program.version()}`);
console.log(`\u7528\u6CD5: dpml [\u9009\u9879] [\u547D\u4EE4]`);
console.log(`
\u53EF\u7528\u547D\u4EE4:`);
const domainCommands = /* @__PURE__ */ new Map();
const standaloneCommands = [];
this.program.commands.forEach((cmd) => {
const isDomainCommand = this.program.commands.some((otherCmd) => otherCmd.commands && otherCmd.commands.some((subCmd) => subCmd.name() === cmd.name()));
if (!isDomainCommand && cmd.commands && cmd.commands.length > 0) {
domainCommands.set(cmd.name(), cmd.commands);
} else if (cmd.name() !== "help") {
standaloneCommands.push(cmd);
}
});
if (domainCommands.size > 0) {
console.log(` \u9886\u57DF\u547D\u4EE4:`);
for (const [domain, commands] of domainCommands.entries()) {
console.log(` ${domain.padEnd(12)} ${domain}\u9886\u57DF\u547D\u4EE4\u96C6\u5408`);
}
console.log("");
}
for (const [domain, commands] of domainCommands.entries()) {
console.log(` ${domain}\u9886\u57DF\u547D\u4EE4:`);
for (const cmd of commands) {
console.log(` ${domain} ${cmd.name().padEnd(10)} ${cmd.description()}`);
}
console.log("");
}
if (standaloneCommands.length > 0) {
console.log(` \u901A\u7528\u547D\u4EE4:`);
for (const cmd of standaloneCommands) {
console.log(` ${cmd.name().padEnd(15)} ${cmd.description()}`);
}
console.log("");
}
const helpCommand = this.program.commands.find((cmd) => cmd.name() === "help");
if (helpCommand) {
console.log(` ${helpCommand.name().padEnd(15)} ${helpCommand.description()}`);
}
console.log(`
\u83B7\u53D6\u547D\u4EE4\u5E2E\u52A9:
dpml <\u547D\u4EE4> --help
dpml <\u9886\u57DF> <\u547D\u4EE4> --help`);
}
/**
* 显示版本信息
*/
showVersion() {
const version = this.program.version();
console.log(`dpml \u7248\u672C: ${version}`);
console.log(`Node.js \u7248\u672C: ${process.version}`);
console.log(`\u5E73\u53F0: ${process.platform} ${process.arch}`);
}
/**
* 解析命令行参数
*
* @param argv 命令行参数数组,默认为process.argv
*/
async parse(argv) {
try {
await this.program.parseAsync(argv || process.argv);
} catch (err) {
if (err && typeof err === "object" && "code" in err) {
const code = err.code;
if (code === "commander.helpDisplayed" || code === "commander.version") {
return;
}
}
if (process.env.NODE_ENV === "test" || process.env.VITEST) {
return;
}
throw err;
}
}
/**
* 查找父命令
*
* @param parentPath 父命令路径
* @returns 父命令对象
* @private
*/
findParentCommand(parentPath) {
const parts = parentPath.split(" ");
let currentCommand = this.program;
for (const part of parts) {
if (!part) continue;
const found = currentCommand.commands.find((cmd) => cmd.name() === part);
if (!found) {
throw new Error(`\u627E\u4E0D\u5230\u547D\u4EE4: ${part} (\u5728\u8DEF\u5F84 ${parentPath} \u4E2D)`);
}
currentCommand = found;
}
return currentCommand;
}
/**
* 处理命令执行错误
*
* @param error 捕获的错误
* @param command 相关的命令定义(可选)
*/
handleError(error, command) {
console.error(`\u6267\u884C\u9519\u8BEF: ${error.message}`);
if (error.name === "ValidationError") {
console.error("\u9A8C\u8BC1\u9519\u8BEF: \u8BF7\u68C0\u67E5\u8F93\u5165\u53C2\u6570\u662F\u5426\u7B26\u5408\u8981\u6C42");
} else if (error.name === "CommandError") {
console.error("\u547D\u4EE4\u9519\u8BEF: \u547D\u4EE4\u6267\u884C\u5931\u8D25");
} else if (error.message.includes("Missing required argument")) {
console.error("\u53C2\u6570\u9519\u8BEF: \u7F3A\u5C11\u5FC5\u9700\u7684\u53C2\u6570");
if (command) {
console.error(`\u547D\u4EE4 "${command.name}" \u9700\u8981\u4EE5\u4E0B\u53C2\u6570:`);
command.arguments?.filter((arg) => arg.required).forEach((arg) => {
console.error(` - ${arg.name}: ${arg.description}`);
});
}
} else if (error.message.includes("option")) {
console.error("\u9009\u9879\u9519\u8BEF: \u9009\u9879\u683C\u5F0F\u6216\u503C\u65E0\u6548");
}
if (command) {
console.error(`
\u5C1D\u8BD5\u4F7F\u7528 --help \u9009\u9879\u67E5\u770B\u547D\u4EE4 "${command.name}" \u7684\u5E2E\u52A9\u4FE1\u606F`);
} else {
console.error("\n\u5C1D\u8BD5\u4F7F\u7528 --help \u9009\u9879\u67E5\u770B\u53EF\u7528\u547D\u4EE4");
}
if (process.env.NODE_ENV !== "test" && !process.env.VITEST) {
process.exit(1);
}
}
};
__name(_CLIAdapter, "CLIAdapter");
var CLIAdapter = _CLIAdapter;
// src/core/cli/cliService.ts
function createCLI(options, commands) {
const mergedOptions = mergeDefaultOptions(options);
validateCommands(commands);
const adapter = new CLIAdapter(mergedOptions.name, mergedOptions.version, mergedOptions.description);
setupGlobalOptions(adapter, mergedOptions);
setupUserCommands(adapter, commands);
return {
execute: /* @__PURE__ */ __name(async (argv) => {
try {
await adapter.parse(argv);
} catch (error) {
if (error && typeof error === "object" && "code" in error) {
const code = error.code;
if (code === "commander.helpDisplayed" || code === "commander.help" || code === "commander.version") {
return;
}
}
console.error("Command execution error:", error);
if (process.env.NODE_ENV !== "test" && !process.env.VITEST) {
process.exit(1);
}
throw error;
}
}, "execute"),
showHelp: /* @__PURE__ */ __name(() => adapter.showHelp(), "showHelp"),
showVersion: /* @__PURE__ */ __name(() => adapter.showVersion(), "showVersion"),
registerCommands: /* @__PURE__ */ __name((externalCommands) => {
validateCommands(externalCommands);
registerExternalCommands(adapter, externalCommands);
}, "registerCommands")
};
}
__name(createCLI, "createCLI");
function setupGlobalOptions(adapter, options) {
console.log(`CLI initialized: ${options.name} v${options.version}`);
console.log(`Default domain: ${options.defaultDomain}`);
}
__name(setupGlobalOptions, "setupGlobalOptions");
function setupUserCommands(adapter, commands) {
const domainCommands = /* @__PURE__ */ new Map();
commands.forEach((command) => {
const domain = command.category || "default";
if (!domainCommands.has(domain)) {
domainCommands.set(domain, []);
}
domainCommands.get(domain).push(command);
});
domainCommands.forEach((cmds, domain) => {
if (domain === "default") {
cmds.forEach((cmd) => adapter.setupCommand(cmd));
return;
}
const domainCommand = {
name: domain,
description: `Commands for ${domain} domain`,
action: /* @__PURE__ */ __name(() => {
console.log(`
Available commands for ${domain} domain:`);
cmds.forEach((cmd) => {
console.log(` ${domain} ${cmd.name.padEnd(10)} ${cmd.description}`);
});
console.log(`
Use 'dpml ${domain} --help' for more information`);
}, "action")
};
adapter.setupCommand(domainCommand);
cmds.forEach((cmd) => {
const { category, ...cmdWithoutCategory } = cmd;
adapter.setupCommand(cmdWithoutCategory, domain);
});
if (domain === "core") {
cmds.forEach((cmd) => {
cmd.name;
adapter.setupCommand({
...cmd,
category: void 0,
description: `${cmd.description} (Alias for core domain command)`
});
});
}
});
}
__name(setupUserCommands, "setupUserCommands");
function registerExternalCommands(adapter, commands) {
const domainCommands = /* @__PURE__ */ new Map();
commands.forEach((command) => {
const domain = command.category || "default";
if (!domainCommands.has(domain)) {
domainCommands.set(domain, []);
}
domainCommands.get(domain).push(command);
});
domainCommands.forEach((cmds, domain) => {
if (domain === "default") {
cmds.forEach((cmd) => adapter.setupCommand(cmd));
return;
}
cmds.forEach((cmd) => {
const { category, ...cmdWithoutCategory } = cmd;
adapter.setupCommand(cmdWithoutCategory, domain);
});
});
}
__name(registerExternalCommands, "registerExternalCommands");
// src/api/cli.ts
function createCLI2(options, commands) {
return createCLI(options, commands);
}
__name(createCLI2, "createCLI");
// src/types/ParseError.ts
var ParseErrorCode = /* @__PURE__ */ function(ParseErrorCode2) {
ParseErrorCode2["UNKNOWN_ERROR"] = "PARSE_UNKNOWN_ERROR";
ParseErrorCode2["INVALID_CONTENT"] = "PARSE_INVALID_CONTENT";
ParseErrorCode2["XML_SYNTAX_ERROR"] = "PARSE_XML_SYNTAX_ERROR";
ParseErrorCode2["XML_INVALID_TAG"] = "PARSE_XML_INVALID_TAG";
ParseErrorCode2["XML_MISSING_CLOSING_TAG"] = "PARSE_XML_MISSING_CLOSING_TAG";
ParseErrorCode2["XML_INVALID_ATTRIBUTE"] = "PARSE_XML_INVALID_ATTRIBUTE";
ParseErrorCode2["DPML_INVALID_STRUCTURE"] = "PARSE_DPML_INVALID_STRUCTURE";
ParseErrorCode2["DPML_INVALID_TAG"] = "PARSE_DPML_INVALID_TAG";
ParseErrorCode2["DPML_INVALID_ATTRIBUTE"] = "PARSE_DPML_INVALID_ATTRIBUTE";
ParseErrorCode2["DPML_MISSING_REQUIRED_TAG"] = "PARSE_DPML_MISSING_REQUIRED_TAG";
ParseErrorCode2["DPML_MISSING_REQUIRED_ATTRIBUTE"] = "PARSE_DPML_MISSING_REQUIRED_ATTRIBUTE";
return ParseErrorCode2;
}({});
var _ParseError = class _ParseError extends Error {
/**
* 创建解析错误实例
* @param message 错误消息
* @param code 错误代码
* @param position 位置信息
* @param source 源代码片段
* @param cause 原始错误
*/
constructor(message, code = "PARSE_UNKNOWN_ERROR", position, source, cause) {
super(message);
/**
* 错误代码
*/
__publicField(this, "code");
/**
* 错误位置信息
*/
__publicField(this, "position");
/**
* 源代码片段
*/
__publicField(this, "source");
/**
* 原始错误
*/
__publicField(this, "cause");
this.name = this.constructor.name;
this.code = code;
this.position = position;
this.source = source;
this.cause = cause;
Object.setPrototypeOf(this, _ParseError.prototype);
}
/**
* 格式化错误信息,包含位置和上下文
* @returns 格式化的错误信息
*/
formatMessage() {
let formattedMessage = `[${this.code}] ${this.message}`;
if (this.position) {
const { startLine, startColumn, fileName } = this.position;
const location = fileName ? `${fileName}:${startLine}:${startColumn}` : `\u884C ${startLine}, \u5217 ${startColumn}`;
formattedMessage += `
\u4F4D\u7F6E: ${location}`;
}
if (this.source) {
formattedMessage += `
\u6E90\u7801: "${this.source}"`;
}
if (this.cause instanceof Error) {
formattedMessage += `
\u539F\u56E0: ${this.cause.message}`;
}
return formattedMessage;
}
/**
* 重写toString方法,提供更详细的错误信息
* @returns 格式化的错误字符串
*/
toString() {
return this.formatMessage();
}
};
__name(_ParseError, "ParseError");
var ParseError = _ParseError;
var _XMLParseError = class _XMLParseError extends ParseError {
/**
* 创建XML解析错误实例
* @param message 错误消息
* @param code 错误代码
* @param position 位置信息
* @param source 源代码片段
* @param cause 原始错误
*/
constructor(message, code = "PARSE_XML_SYNTAX_ERROR", position, source, cause) {
super(message, code, position, source, cause);
/**
* 错误上下文片段
* 包含错误位置附近的内容
*/
__publicField(this, "contextFragment");
Object.setPrototypeOf(this, _XMLParseError.prototype);
}
/**
* 从原始XML解析错误创建XMLParseError
* @param error 原始错误
* @param content XML内容
* @param fileName 文件名
* @returns XML解析错误
*/
static fromError(error, content, fileName) {
const message = error instanceof Error ? error.message : String(error);
const position = _XMLParseError.extractPositionFromMessage(message, fileName);
const source = content ? position ? _XMLParseError.extractSourceSnippet(content, position.startLine, position.startColumn) : content.substring(0, Math.min(30, content.length)) : void 0;
return new _XMLParseError(message, "PARSE_XML_SYNTAX_ERROR", position, source, error);
}
/**
* 从错误消息中提取位置信息
* @param message 错误消息
* @param fileName 文件名
* @returns 源码位置信息或undefined
*/
static extractPositionFromMessage(message, fileName) {
const lineColMatch = message.match(/[Ll]ine[:\s]+(\d+)[\s,]+[Cc]olumn[:\s]+(\d+)/);
if (lineColMatch) {
const startLine = parseInt(lineColMatch[1], 10);
const startColumn = parseInt(lineColMatch[2], 10);
return {
startLine,
startColumn,
endLine: startLine,
endColumn: startColumn + 1,
fileName
};
}
return void 0;
}
/**
* 从内容中提取源代码片段
* @param content 完整内容
* @param line 行号
* @param column 列号
* @returns 源代码片段
*/
static extractSourceSnippet(content, line, column) {
const lines = content.split("\n");
if (line <= 0 || line > lines.length) {
return "";
}
const errorLine = lines[line - 1];
const start = Math.max(0, column - 15);
const end = Math.min(errorLine.length, column + 15);
return errorLine.substring(start, end);
}
/**
* 格式化错误信息,包含位置和上下文
* @returns 格式化的错误信息
*/
formatMessage() {
let formattedMessage = super.formatMessage();
if (this.contextFragment) {
formattedMessage += `
\u4E0A\u4E0B\u6587: "${this.contextFragment}"`;
}
return formattedMessage;
}
};
__name(_XMLParseError, "XMLParseError");
var XMLParseError = _XMLParseError;
var _DPMLParseError = class _DPMLParseError extends ParseError {
/**
* 创建DPML解析错误实例
* @param message 错误消息
* @param code 错误代码
* @param position 位置信息
* @param source 源代码片段
* @param cause 原始错误
*/
constructor(message, code = "PARSE_DPML_INVALID_STRUCTURE", position, source, cause) {
super(message, code, position, source, cause);
Object.setPrototypeOf(this, _DPMLParseError.prototype);
}
/**
* 创建缺少必需标签的错误
* @param tagName 标签名
* @param position 位置信息
* @returns DPML解析错误
*/
static createMissingRequiredTagError(tagName, position) {
return new _DPMLParseError(`\u7F3A\u5C11\u5FC5\u9700\u7684\u6807\u7B7E: ${tagName}`, "PARSE_DPML_MISSING_REQUIRED_TAG", position);
}
/**
* 创建缺少必需属性的错误
* @param attributeName 属性名
* @param tagName 标签名
* @param position 位置信息
* @returns DPML解析错误
*/
static createMissingRequiredAttributeError(attributeName, tagName, position) {
return new _DPMLParseError(`\u6807\u7B7E <${tagName}> \u7F3A\u5C11\u5FC5\u9700\u7684\u5C5E\u6027: ${attributeName}`, "PARSE_DPML_MISSING_REQUIRED_ATTRIBUTE", position);
}
/**
* 创建无效标签错误
* @param tagName 标签名
* @param position 位置信息
* @returns DPML解析错误
*/
static createInvalidTagError(tagName, position) {
return new _DPMLParseError(`\u65E0\u6548\u7684DPML\u6807\u7B7E: ${tagName}`, "PARSE_DPML_INVALID_TAG", position);
}
/**
* 创建无效属性错误
* @param attributeName 属性名
* @param tagName 标签名
* @param position 位置信息
* @returns DPML解析错误
*/
static createInvalidAttributeError(attributeName, tagName, position) {
return new _DPMLParseError(`\u6807\u7B7E <${tagName}> \u5305\u542B\u65E0\u6548\u7684\u5C5E\u6027: ${attributeName}`, "PARSE_DPML_INVALID_ATTRIBUTE", position);
}
};
__name(_DPMLParseError, "DPMLParseError");
var DPMLParseError = _DPMLParseError;
// src/types/TransformContext.ts
var _TransformContext = class _TransformContext {
/**
* 创建上下文实例
* @param processingResult 原始处理结果
* @param initialData 可选的初始数据
*/
constructor(processingResult, initialData) {
/**
* 存储上下文数据的内部Map
*/
__publicField(this, "data");
/**
* 原始处理结果引用
*/
__publicField(this, "processingResult");
this.processingResult = processingResult;
this.data = /* @__PURE__ */ new Map();
if (initialData) {
Object.entries(initialData).forEach(([key, value]) => {
this.data.set(key, value);
});
}
}
/**
* 类型安全的数据存储
* @template T 值的类型
* @param key 存储键
* @param value 存储值
*/
set(key, value) {
this.data.set(key, value);
}
/**
* 类型安全的数据获取
* @template T 期望的返回类型
* @param key 获取键
* @returns 获取的值,若不存在则返回undefined
*/
get(key) {
return this.data.get(key);
}
/**
* 检查键是否存在
* @param key 检查键
* @returns 是否存在
*/
has(key) {
return this.data.has(key);
}
/**
* 获取原始文档
* @returns 文档对象
*/
getDocument() {
return this.processingResult.document;
}
/**
* 获取引用关系
* @returns 引用映射
*/
getReferences() {
return this.processingResult.references;
}
/**
* 获取验证结果
* @returns 验证结果对象
*/
getValidation() {
return this.processingResult.validation;
}
/**
* 检查文档有效性
* @returns 是否有效
*/
isDocumentValid() {
return this.processingResult.isValid;
}
/**
* 获取所有结果
* @returns 所有存储的数据
*/
getAllResults() {
const results = {};
this.data.forEach((value, key) => {
results[key] = value;
});
return results;
}
};
__name(_TransformContext, "TransformContext");
var TransformContext = _TransformContext;
// src/types/FrameworkError.ts
var _ConfigurationError = class _ConfigurationError extends Error {
/**
* 创建配置错误实例
* @param message 错误消息
*/
constructor(message) {
super(message);
this.name = "ConfigurationError";
Object.setPrototypeOf(this, _ConfigurationError.prototype);
}
};
__name(_ConfigurationError, "ConfigurationError");
var ConfigurationError = _ConfigurationError;
var _CompilationError = class _CompilationError extends Error {
/**
* 创建编译错误实例
* @param message 错误消息
* @param cause 可选的原始错误
*/
constructor(message, cause) {
super(message);
__publicField(this, "cause");
this.cause = cause;
this.name = "CompilationError";
Object.setPrototypeOf(this, _CompilationError.prototype);
}
};
__name(_CompilationError, "CompilationError");
var CompilationError = _CompilationError;
// src/types/log.ts
var LogLevel = /* @__PURE__ */ function(LogLevel2) {
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
LogLevel2[LogLevel2["WARN"] = 2] = "WARN";
LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
LogLevel2[LogLevel2["FATAL"] = 4] = "FATAL";
return LogLevel2;
}({});
// src/types/CLIErrors.ts
var _DuplicateCommandError = class _DuplicateCommandError extends Error {
/**
* 创建命令重复错误实例
* @param commandPath 重复命令的路径
*/
constructor(commandPath) {
super(`Duplicate command definition: ${commandPath}`);
__publicField(this, "commandPath");
this.commandPath = commandPath;
this.name = "DuplicateCommandError";
Object.setPrototypeOf(this, _DuplicateCommandError.prototype);
}
};
__name(_DuplicateCommandError, "DuplicateCommandError");
var DuplicateCommandError = _DuplicateCommandError;
var _InvalidCommandError = class _InvalidCommandError extends Error {
/**
* 创建无效命令错误实例
* @param message 错误消息
* @param commandName 命令名称
*/
constructor(message, commandName) {
super(commandName ? `Invalid command "${commandName}": ${message}` : message);
__publicField(this, "commandName");
this.commandName = commandName;
this.name = "InvalidCommandError";
Object.setPrototypeOf(this, _InvalidCommandError.prototype);
}
};
__name(_InvalidCommandError, "InvalidCommandError");
var InvalidCommandError = _InvalidCommandError;
var _CommandExecutionError = class _CommandExecutionError extends Error {
/**
* 创建命令执行错误实例
* @param message 错误消息
* @param commandPath 命令路径
* @param cause 原始错误
*/
constructor(message, commandPath, cause) {
super(`Error executing command "${commandPath}": ${message}`);
__publicField(this, "commandPath");
__publicField(this, "cause");
this.commandPath = commandPath, this.cause = cause;
this.name = "CommandExecutionError";
Object.setPrototypeOf(this, _CommandExecutionError.prototype);
}
};
__name(_CommandExecutionError, "CommandExecutionError");
var CommandExecutionError = _CommandExecutionError;
// src/core/parsing/errors.ts
function createSuccessResult(data, warnings = []) {
return {
success: true,
data,
warnings: warnings.length > 0 ? warnings : void 0
};
}
__name(createSuccessResult, "createSuccessResult");
function createErrorResult(error) {
return {
success: false,
error
};
}
__name(createErrorResult, "createErrorResult");
// src/core/parsing/DPMLAdapter.ts
var _DPMLAdapter = class _DPMLAdapter {
/**
* 创建适配器并注入依赖
* @param options 解析配置选项
* @param xmlAdapter XML适配器实例
*/
constructor(options, xmlAdapter) {
/**
* XML适配器实例
*/
__publicField(this, "xmlAdapter");
/**
* 解析配置选项
*/
__publicField(this, "options");
this.options = options || {};
this.xmlAdapter = xmlAdapter;
}
/**
* 解析DPML内容,构建文档对象模型
* @param content DPML内容字符串
* @returns DPML文档对象
* @throws {DPMLParseError|XMLParseError} 当解析失败时抛出
*/
parse(content) {
try {
this.prevalidateXML(content);
const isLargeContent = this.isLargeContent(content);
const xmlResult = this.xmlAdapter.parse(content);
this.validateXMLResult(xmlResult, content);
const rootNode = isLargeContent ? this.convertToDPMLOptimized(xmlResult) : this.convertToDPML(xmlResult);
const document = this.createDPMLDocument(rootNode);
return document;
} catch (error) {
throw this.enhanceError(error, content);
}
}
/**
* 异步解析DPML内容
* @param content DPML内容字符串
* @returns DPML文档对象Promise
* @throws {DPMLParseError|XMLParseError} 当解析失败时抛出
*/
async parseAsync(content) {
try {
this.prevalidateXML(content);
const isLargeContent = this.isLargeContent(content);
const xmlResult = await this.xmlAdapter.parseAsync(content);
this.validateXMLResult(xmlResult, content);
let rootNode;
if (isLargeContent) {
rootNode = await this.convertToDPMLAsyncOptimized(xmlResult);
} else {
rootNode = await new Promise((resolve) => {
setTimeout(() => {
resolve(this.convertToDPML(xmlResult));
}, 0);
});
}
const document = this.createDPMLDocument(rootNode);
return document;
} catch (error) {
throw this.enhanceError(error, content);
}
}
/**
* 预验证XML有效性
* 检查常见的XML语法错误,如未关闭的标签
* @param content XML内容
*/
prevalidateXML(content) {
if (!content || content.trim() === "") {
throw new DPMLParseError("\u7A7A\u7684DPML\u5185\u5BB9", ParseErrorCode.DPML_INVALID_STRUCTURE, {
startLine: 1,
startColumn: 1,
endLine: 1,
endColumn: 1,
fileName: this.options.fileName
}, content);
}
const openTagPattern = /<([a-zA-Z][\w:\-\.]*)[^>]*?>/g;
const closeTagPattern = /<\/([a-zA-Z][\w:\-\.]*)[^>]*?>/g;
const selfClosingPattern = /<([a-zA-Z][\w:\-\.]*)[^>]*?\/>/g;
const openTags = [];
const closeTags = [];
const selfClosingTags = [];
let match;
while ((match = openTagPattern.exec(content)) !== null) {
const tagName = match[1];
if (tagName) openTags.push(tagName);
}
while ((match = closeTagPattern.exec(content)) !== null) {
const tagName = match[1];
if (tagName) closeTags.push(tagName);
}
while ((match = selfClosingPattern.exec(content)) !== null) {
const tagName = match[1];
if (tagName) selfClosingTags.push(tagName);
}
if (openTags.length - selfClosingTags.length > closeTags.length) {
const unclosedTags = [
...openTags
];
for (const tag of [
...closeTags,
...selfClosingTags
]) {
const index = unclosedTags.indexOf(tag);
if (index !== -1) {
unclosedTags.splice(index, 1);
}
}
if (unclosedTags.length > 0) {
throw new DPMLParseError(`\u672A\u5173\u95ED\u7684\u6807\u7B7E: <${unclosedTags[0]}>`, ParseErrorCode.DPML_INVALID_STRUCTURE, void 0, content.substring(0, 100));
}
}
}
/**
* 检查内容是否为大型文档
* @param content DPML内容
* @returns 是否为大型文档
*/
isLargeContent(content) {
const threshold = this.options.memoryOptimization?.largeFileThreshold || 2 * 1024 * 1024;
if (this.options.memoryOptimization?.enabled) {
return content.length > threshold;
}
if (content.length > 10 * 1024 * 1024) {
return true;
}
return content.length > threshold;
}
/**
* 创建DPML文档对象
* @param rootNode 根节点
* @returns DPML文档对象
*/
createDPMLDocument(rootNode) {
const metadata = {
sourceFileName: this.options.fileName,
createdAt: /* @__PURE__ */ new Date(),
size: this.calculateDocumentSize(rootNode)
};
const nodesById = this.buildNodeMap(rootNode);
this.validateReferences(rootNode, nodesById);
const document = {};
Object.defineProperties(document, {
rootNode: {
value: rootNode,
writable: false,
enumerable: true,
configurable: false
},
nodesById: {
value: nodesById,
writable: false,
enumerable: true,
configurable: false
},
metadata: {
value: metadata,
writable: false,
enumerable: true,
configurable: false
}
});
return document;
}
/**
* 计算文档大小
* @param rootNode 根节点
* @returns 文档大小(节点数)
*/
calculateDocumentSize(rootNode) {
let size = 1;
const countNodes = /* @__PURE__ */ __name((node) => {
if (node.children && node.children.length > 0) {
size += node.children.length;
node.children.forEach(countNodes);
}
}, "countNodes");
countNodes(rootNode);
return size;
}
/**
* 将XML节点转换为DPML节点(针对大文件优化版本)
* 使用递归分批处理以避免调用栈溢出
* @param xmlNode XML节点
* @returns DPML节点
*/
convertToDPMLOptimized(xmlNode) {
const rootDPMLNode = this.createDPMLNode(xmlNode);
const queue = [];
if (xmlNode.children && xmlNode.children.length > 0) {
xmlNode.children.forEach((childXml) => {
const childDPML = this.createDPMLNode(childXml);
rootDPMLNode.children.push(childDPML);
Object.defineProperty(childDPML, "parent", {
value: rootDPMLNode,
writable: false,
enumerable: true,
configurable: false
});
queue.push({
xmlNode: childXml,
dpmlNode: childDPML
});
});
}
while (queue.length > 0) {
const { xmlNode: currentXmlNode, dpmlNode: currentDPMLNode } = queue.shift();
if (currentXmlNode.children && currentXmlNode.children.length > 0) {
currentXmlNode.children.forEach((childXml) => {
const childDPML = this.createDPMLNode(childXml);
currentDPMLNode.children.push(childDPML);
Object.defineProperty(childDPML, "parent", {
value: currentDPMLNode,
writable: false,
enumerable: true,
configurable: false
});
queue.push({
xmlNode: childXml,
dpmlNode: childDPML
});
});
}
}
return rootDPMLNode;
}
/**
* 创建单个DPML节点(不递归处理子节点)
* @param xmlNode XML节点
* @returns DPML节点
*/
createDPMLNode(xmlNode) {
const attributes = /* @__PURE__ */ new Map();
if (xmlNode.attributes) {
Object.entries(xmlNode.attributes).forEach(([key, value]) => {
if (value === null || value === void 0) {
attributes.set(key, "");
} else {
attributes.set(key, String(value));
}
});
}
const content = xmlNode.text !== void 0 ? String(xmlNode.text) : "";
const node = {};
Object.defineProperties(node, {
tagName: {
value: xmlNode.name,
writable: false,
enumerable: true,
configurable: false
},
attributes: {
value: attributes,
writable: false,
enumerable: true,
configurable: false
},
children: {
value: [],
writable: false,
enumerable: true,
configurable: false
},
content: {
value: content,
writable: false,
enumerable: true,
configurable: false
},
parent: {
value: null,
writable: false,
enumerable: true,
configurable: true
// 允许子节点重新配置该属性
},
sourceLocation: {
value: xmlNode.position ? this.createSourceLocation(xmlNode.position) : void 0,
writable: false,
enumerable: true,
configurable: false
}
});
return node;
}
/**
* 异步转换XML节点到DPML节点,针对大文件优化
* @param xmlNode XML节点
* @returns Promise<DPMLNode>
*/
async convertToDPMLAsyncOptimized(xmlNode) {
const rootDPMLNode = this.createDPMLNode(xmlNode);
const queue = [];
if (xmlNode.children && xmlNode.children.length > 0) {
xmlNode.children.forEach((childXml) => {
const childDPML = this.createDPMLNode(childXml);
rootDPMLNode.children.push(childDPML);
Object.defineProperty(childDPML, "parent", {
value: rootDPMLNode,
writable: false,
enumerable: true,
configurable: false
});
queue.push({
xmlNode: childXml,
dpmlNode: childDPML
});
});
}
const batchSize = 500;
while (queue.length > 0) {
const batch = queue.splice(0, Math.min(batchSize, queue.length));
for (const { xmlNode: currentXmlNode, dpmlNode: currentDPMLNode } of batch) {
if (currentXmlNode.children && currentXmlNode.children.length > 0) {
currentXmlNode.children.forEach((childXml) => {
const childDPML = this.createDPMLNode(childXml);
currentDPMLNode.children.push(childDPML);
Object.defineProperty(childDPML, "parent", {
value: currentDPMLNode,
writable: false,
enumerable: true,
configurable: false
});
queue.push({
xmlNode: childXml,
dpmlNode: childDPML
});
});
}
}
if (queue.length > 0) {
await new Promise((resolve) => setTimeout(resolve, 0));
}
}
return rootDPMLNode;
}
/**
* 将XML节点转换为DPML节点
* @param xmlNode XML节点
* @returns DPML节点
*/
convertToDPML(xmlNode) {
const dpmlNode = this.createDPMLNode(xmlNode);
if (xmlNode.children && xmlNode.children.length > 0) {
xmlNode.children.forEach((childXml) => {
const childDPML = this.convertToDPML(childXml);
dpmlNode.children.push(childDPML);
Object.defineProperty(childDPML, "parent", {
value: dpmlNode,
writable: false,
enumerable: true,
configurable: false
});
});
}
return dpmlNode;
}
/**
* 构建节点ID映射
* @param rootNode 根节点
* @returns 节点ID到节点的映射
*/
buildNodeMap(rootNode) {
const nodeMap = /* @__PURE__ */ new Map();
const traverseNode = /* @__PURE__ */ __name((node) => {
const nodeId = node.attributes.get("id");
if (nodeId) {
nodeMap.set(nodeId, node);
}
node.attributes.get("ref");
if (node.children && node.children.length > 0) {
node.children.forEach(traverseNode);
}
}, "traverseNode");
traverseNode(rootNode);
return nodeMap;
}
/**
* 验证节点引用完整性
* @param rootNode 根节点
* @param nodeMap 节点ID映射
*/
validateReferences(rootNode, nodeMap) {
if (this.options.xmlParserOptions?.validateReferences === false) {
return;
}
const checkReferences = /* @__PURE__ */ __name((node) => {
const nodeRef = node.attributes.get("ref");
if (nodeRef && !nodeMap.has(nodeRef)) {
throw new DPMLParseError(`\u5F15\u7528\u9519\u8BEF: \u627E\u4E0D\u5230ID\u4E3A"${nodeRef}"\u7684\u8282\u70B9`, ParseErrorCode.DPML_INVALID_ATTRIBUTE, node.sourceLocation, void 0);
}
if (node.children && node.children.length > 0) {
node.children.forEach(checkReferences);
}
}, "checkReferences");
checkReferences(rootNode);
}
/**
* 创建源代码位置信息
* @param position XML位置信息
* @returns DPML源代码位置信息
*/
createSourceLocation(position) {
return {
startLine: position.start.line,
startColumn: position.start.column,
endLine: position.end.line,
endColumn: position.end.column,
fileName: this.options.fileName
};
}
/**
* 验证XML解析结果
* @param xmlNode XML节点
* @param content 原始内容
*/
validateXMLResult(xmlNode, content) {
if (!xmlNode) {
throw new DPMLParseError("\u65E0\u6CD5\u89E3\u6790DPML\u5185\u5BB9", ParseErrorCode.DPML_INVALID_STRUCTURE, void 0, content.substring(0, 100));
}
if (!xmlNode.name) {
throw new DPMLParseError("\u7F3A\u5C11\u6839\u5143\u7D20", ParseErrorCode.DPML_MISSING_REQUIRED_TAG, void 0, content.substring(0, 100));
}
if (this.options.xmlParserOptions?.validateStructure) ;
}
/**
* 增强错误信息
* @param error 原始错误
* @param content 原始内容
* @returns 增强后的错误
*/
enhanceError(error, content) {
if (error instanceof ParseError) {
return error;
}
if (error instanceof XMLParseError) {
let locationInfo = void 0;
if (error.position) {
const pos = error.position;
locationInfo = {
startLine: pos.start.line,
startColumn: pos.start.column,
endLine: pos.end.line,
endColumn: pos.end.column,
fileName: this.options.fileName
};
}
return new DPMLParseError(error.message, ParseErrorCode.DPML_INVALID_STRUCTURE, locationInfo, error.source, error);
}
return new DPMLParseError(error instanceof Error ? error.message : String(error), ParseErrorCode.UNKNOWN_ERROR, void 0, content.substring(0, 100), error instanceof Error ? error : void 0);
}
};
__name(_DPMLAdapter, "DPMLAdapter");
var DPMLAdapter = _DPMLAdapter;
// src/core/parsing/XMLAdapter.ts
var _XMLAdapter = class _XMLAdapter {
/**
* 创建适配器并配置选项
* @param options 解析配置选项
* @param xmlParser XML解析器实例
*/
constructor(options, xmlParser) {
/**
* 底层XML解析器实例
*/
__publicField(this, "xmlParser");
/**
* 解析配置选项
*/
__publicField(this, "options");
this.options = options;
this.xmlParser = xmlParser;
this.configureParser();
}
/**
* 同步解析XML内容
* @param content XML内容字符串
* @returns 解析结果
* @throws {XMLParseError} 当解析失败时抛出
*/
parse(content) {
try {
if (this.shouldApplyLargeContentOptimization(content)) {
this.applyLargeContentOptimization();
}
const xmlNode = this.xmlParser.parse(content);
return this.processResult(xmlNode);
} catch (error) {
throw this.enhanceError(error, content);
}
}
/**
* 异步解析XML内容
* @param content XML内容字符串
* @returns 解析结果Promise
* @throws {XMLParseError} 当解析失败时抛出
*/
async parseAsync(content) {
try {
if (this.shouldApplyLargeContentOptimization(content)) {
this.applyLargeContentOptimization();
}
const xmlNode = await this.xmlParser.parseAsync(content);
return this.processResult(xmlNode);
} catch (error) {
throw this.enhanceError(error, content);
}
}
/**
* 检查是否应该应用大文件优化
* @param content XML内容
* @returns 是否应用优化
*/
shouldApplyLargeContentOptimization(content) {
const contentSizeThreshold = this.options.memoryOptimization?.largeFileThreshold || 1024 * 1024;
return content.length > contentSizeThreshold;
}
/**
* 应用大文件处理优化
*/
applyLargeContentOptimization() {
const optimizationOptions = {
// xml2js优化选项
explicitArray: true,
normalizeTags: false,
trim: true,
explicitRoot: true,
explicitChildren: true,
preserveChildrenOrder: true,
mergeAttrs: false,
charsAsChildren: false,
includeWhiteChars: false
};
if (this.options.memoryOptimization) {
const { batchSize, useStreaming } = this.options.memoryOptimization;
if (useStreaming) {
optimizationOptions.preserveChildrenOrder = false;
optimizationOptions.charsAsChildren = false;
}
}
this.xmlParser.configure(optimizationOptions);
if (typeof global !== "undefined" && global.gc) {
try {
global.gc();
} catch {
}
}
}
/**
* 配置底层解析器行为
*/
configureParser() {
const xmlOptions = {};
if (this.options.xmlParserOptions) {
const { preserveWhitespace, parseComments, enableNamespaces, maxDepth } = this.options.xmlParserOptions;
if (preserveWhitespace !== void 0) {
xmlOptions.trim = !preserveWhitespace;
xmlOptions.includeWhiteChars = preserveWhitespace;
}
if (parseComments !== void 0) {
xmlOptions.includeWhiteChars = parseComments;
}
if (enableNamespaces !== void 0) {
xmlOptions.xmlns = enableNamespaces;
}
}
this.xmlParser.configure(xmlOptions);
}
/**
* 处理解析结果
* @param xmlNode XML节点结果
* @returns 处理后的结果
*/
processResult(xmlNode) {
try {
this.validateNode(xmlNode);
const processedNode = this.postProcessNode(xmlNode);
return processedNode;
} catch (error) {
throw error instanceof Error ? error : new Error(String(error));
}
}
/**
* 验证XML节点
* @param node XML节点
*/
validateNode(node) {
if (!node) {
throw new Error("\u89E3\u6790\u7ED3\u679C\u4E3A\u7A7A");
}
if (node.type !== "element") {
throw new Error(`\u65E0\u6548\u7684XML\u8282\u70B9\u7C7B\u578B\uFF1A${node.type}`);
}
}
/**
* 后处理XML节点
* @param node XML节点
* @returns 处理后的节点
*/
postProcessNode(node) {
const clone = this.cloneNode(node);
this.normalizeAttributes(clone);
this.normalizeTextContent(clone);
return clone;
}
/**
* 深度克隆XML节点
* @param node 原始节点
* @returns 克隆的节点
*/
cloneNode(node) {
if (!node) return node;
const clone = {
type: node.type,
name: node.name,
attributes: {
...node.attributes
},
children: node.children ? node.children.map((child) => this.cloneNode(child)) : [],
text: node.text,
position: node.position ? {
start: {
...node.position.start
},
end: {
...node.position.end
}
} : void 0
};
return clone;
}
/**
* 规范化属性值
* @param node XML节点
*/
normalizeAttributes(node) {
if (!node.attributes) node.attributes = {};
Object.keys(node.attributes).forEach((key) => {
if (node.attributes[key] === null || node.attributes[key] === void 0) {
node.attributes[key] = "";
} else if (typeof node.attributes[key] !== "string") {
node.attributes[key] = String(node.attributes[key]);
}
});
if (node.children && node.children.length > 0) {
node.children.forEach((child) => this.normalizeAttributes(child));
}
}
/**
* 规范化文本内容
* @param node XML节点
*/
normalizeTextContent(node) {
if (node.text !== void 0 && node.text !== null && typeof node.text !== "string") {
node.text = String(node.text);
}
if (node.children && node.children.length > 0) {
node.children.forEach((child) => this.normalizeTextContent(child));
}
}
/**
* 增强错误信息
* @param error 原始错误
* @param content XML内容
* @returns 增强后的错误
*/
enhanceError(error, content) {
if (error instanceof XMLParseError) {
return error;
}
const enhancedError = XMLParseError.fromError(error, content, this.options.fileName);
if (content && content.length > 0) {
try {
let errorPosition = 0;
if (error instanceof Error) {
const posMatch = error.message.match(/line\s*(\d+)(?:,|\s+column\s+)(\d+)/i);
if (posMatch) {
const line = parseInt(posMatch[1], 10);
const column = parseInt(posMatch[2], 10);
const lines = content.split("\n");
let offset = 0;
for (let i = 0; i < Math.min(line - 1, lines.length); i++) {
offset += lines[i].length + 1;
}
errorPosition = offset + Math.min(column, lines[Math.min(line - 1, lines.length - 1)].length);
}
}
const start = Math.max(0, errorPosition - 40);
const end = Math.min(content.length, errorPosition + 40);
const snippet = content.substring(start, end);
enhancedError.contextFragment = snippet;
} catch {
}
}
return enhancedError;
}
};
__name(_XMLAdapter, "XMLAdapter");
var XMLAdapter = _XMLAdapter;
var _XMLParser = class _XMLParser {
/**
* 创建XML解析器
*/
constructor() {
/**
* 底层XML解析器实例
*/
__publicField(this, "parser");
/**
* 解析器选项
*/
__publicField(this, "parserOptions", {
explicitArray: true,
explicitChildren: false,
mergeAttrs: false,
attrkey: "$",
charkey: "_",
includeWhiteChars: false,
trim: true,
explicitRoot: true,
preserveChildrenOrder: true,
charsAsChildren: true,
normalizeTags: false,
normalize: true,
xmlns: false,
// @ts-expect-error - 类型定义中可能没有这个属性,但实际支持
emptyTag: null
});
this.parser = new xml2js.Parser(this.parserOptions);
}
/**
* 同步解析XML内容
* @param content XML内容字符串
* @returns 解析结果
*/
parse(content) {
try {
let result;
xml2js.parseString(content, this.parserOptions, (err, parsed) => {
if (err) throw err;
result = parsed;
});
if (!result) {
throw new Error("XML\u89E3\u6790\u5931\u8D25");
}
return this.transformToXMLNode(result, content);
} catch (error) {
throw this.enhanceError(error, content);
}
}
/**
* 异步解析XML内容
* @param content XML内容字符串
* @returns 解析结果Promise
*/
async parseAsync(content) {
try {
const result = await this.parser.parseStringPromise(content);
return this.transformToXMLNode(result, content);
} catch (error) {
throw this.enhanceError(error, content);
}
}
/**
* 配置解析器行为
* @param options 配置选项
*/
configure(options) {
const xml2jsOptions = {};
if (options.trimValues !== void 0) {
xml2jsOptions.trim = options.trimValues;
}
if (options.ignoreAttributes !== void 0) {
xml2jsOptions.ignoreAttrs = options.ignoreAttributes;
}
if (options.parseTagValue !== void 0) {
xml2jsOptions.explicitChildren = !options.parseTagValue;
}
if (options.processEntities !== void 0) {
xml2jsOptions.normalize = options.processEntities;
}
this.parserOptions = {
...this.parserOptions,
...xml2jsOptions
};
this.parser = new xml2js.Parser(this.parserOptions);
}
/**
* 将xml2js解析结果转换为统一的XMLNode格式
* @param parseResult xml2js解析结果
* @param originalContent 原始XML内容(用于位置计算)
* @returns XMLNode格式的解析结果
*/
transformToXMLNode(parseResult, originalContent) {
const rootTagName = Object.keys(parseResult)[0];
const rootContent = parseResult[rootTagName];
return this.processNode(rootTagName, rootContent, originalContent);
}
/**
* 处理单个节点及其子节点
* @param tagName 标签名
* @param nodeContent 节点内容
* @param originalContent 原始XML内容
* @returns 处理后的XMLNode
*/
processNode(tagName, nodeContent, originalContent) {
const attributes = {};
let text = "";
const children = [];
const content = Array.isArray(nodeContent) ? nodeContent[0] : nodeContent;
if (!content) {
return {
type: "element",
name: tagName,
attributes,
children: [],
text: "",
position: this.calculatePosition(tagName, originalContent)
};
}
if (content && typeof content === "object" && "$" in content) {
const attrs = content.$;
if (attrs && typeof attrs === "object") {
Object.entries(attrs).forEach(([key, value]) => {
attributes[key] = String(value);
});
}
}
if (content && typeof content === "object" && "_" in content) {
text = String(content._);
} else if (typeof content === "string") {
text = content;
}
if (!text && Array.isArray(content) && content.length > 0) {
const firstItem = content[0];
if (typeof firstItem === "string") {
text = firstItem;
} else if (firstItem && typeof firstItem === "object" && "_" in firstItem) {
text = String(firstItem._);
}
}
if (content && typeof content === "object") {
Object.keys(content).forEach((key) => {
if (key === "$" || key === "_") return;
const childItems = content[key];
if (Array.isArray(childItems)) {
childItems.forEach((childItem) => {
const childNode = this.processNode(key, [
childItem
], originalContent);
children.push(childNode);
});
}
});
}
return {
type: "element",
name: tagName,
attributes,
children,
text,
position: th