fix: stabilize rule editor yaml roundtrip
This commit is contained in:
@@ -330,7 +330,7 @@ function normalizeBooleanText(value: string | boolean | undefined): boolean {
|
||||
}
|
||||
|
||||
function rewriteExtractNodes(fields: ExtractFieldSummary[]): Array<Record<string, unknown>> {
|
||||
const topLevelFields = fields.filter((field) => !field.name.includes('[*].'));
|
||||
const topLevelFields = fields.filter((field) => field.group !== '派生字段' && !field.name.includes('[*].'));
|
||||
return Array.from(groupBy(topLevelFields, (field) => field.group || '未分组').entries()).map(([group, items]) => ({
|
||||
group,
|
||||
fields: items.map((field) => ({
|
||||
@@ -343,6 +343,46 @@ function rewriteExtractNodes(fields: ExtractFieldSummary[]): Array<Record<string
|
||||
}));
|
||||
}
|
||||
|
||||
function rewriteDerivedFieldNodes(
|
||||
fields: ExtractFieldSummary[],
|
||||
existingNodes: unknown,
|
||||
): Array<Record<string, unknown>> {
|
||||
const derivedFields = fields.filter((field) => field.group === '派生字段');
|
||||
if (derivedFields.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const existingMap = new Map<string, Record<string, unknown>>();
|
||||
if (Array.isArray(existingNodes)) {
|
||||
existingNodes.forEach((node) => {
|
||||
if (!node || typeof node !== 'object') return;
|
||||
const record = deepClone(node as Record<string, unknown>);
|
||||
const name = String(record.name || '').trim();
|
||||
if (name) {
|
||||
existingMap.set(name, record);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return derivedFields.map((field) => {
|
||||
const existing = existingMap.get(field.name) || {};
|
||||
const nextNode: Record<string, unknown> = {
|
||||
...existing,
|
||||
name: field.name,
|
||||
type: field.type || String(existing.type || 'computed'),
|
||||
};
|
||||
const nextCompute = field.description && field.description !== '由其他字段计算得出'
|
||||
? field.description
|
||||
: String(existing.compute || '').trim();
|
||||
if (nextCompute) {
|
||||
nextNode.compute = nextCompute;
|
||||
} else {
|
||||
delete nextNode.compute;
|
||||
}
|
||||
return nextNode;
|
||||
});
|
||||
}
|
||||
|
||||
function rewriteSubDocumentNodes(subDocuments: SubDocumentSummary[]): Array<Record<string, unknown>> {
|
||||
return subDocuments.map((document) => ({
|
||||
id: document.id,
|
||||
@@ -474,7 +514,6 @@ function rewriteRuleNode(baseRule: Record<string, unknown> | undefined, rule: Ru
|
||||
}
|
||||
|
||||
delete nextRule.rules;
|
||||
delete nextRule.logic;
|
||||
|
||||
const existingStages = Array.isArray(nextRule.stages) ? (nextRule.stages as Array<Record<string, unknown>>) : [];
|
||||
const stages = existingStages.length > 0 ? deepClone(existingStages) : (buildMinimalRuleNode(rule).stages as Array<Record<string, unknown>>);
|
||||
@@ -494,6 +533,8 @@ function rewriteRuleNode(baseRule: Record<string, unknown> | undefined, rule: Ru
|
||||
}
|
||||
|
||||
nextRule.stages = stages;
|
||||
if (rule.logic?.trim()) nextRule.logic = rule.logic.trim();
|
||||
else if (typeof nextRule.logic === 'string' && !String(nextRule.logic).trim()) delete nextRule.logic;
|
||||
return nextRule;
|
||||
}
|
||||
|
||||
@@ -512,6 +553,7 @@ export function serializeEditableRuleConfig(config: EditableRuleConfig): string
|
||||
if (Array.isArray(config.metadata.inheritsFrom) && config.metadata.inheritsFrom.length > 0) metadata.inherits_from = [...config.metadata.inheritsFrom];
|
||||
root.metadata = metadata;
|
||||
root.extract = rewriteExtractNodes(config.fields);
|
||||
root.derived_fields = rewriteDerivedFieldNodes(config.fields, root.derived_fields);
|
||||
root.sub_documents = rewriteSubDocumentNodes(config.subDocuments);
|
||||
root.visual_elements = rewriteVisualElementNodes(config.visualElements);
|
||||
|
||||
|
||||
@@ -415,9 +415,9 @@ function parseRules(source: string): RuleSummary[] {
|
||||
group,
|
||||
risk: stripYamlValue(ruleBlock.match(/^\s+risk:\s*(.+)$/m)?.[1] || 'medium'),
|
||||
score: stripYamlValue(ruleBlock.match(/^\s+score:\s*(.+)$/m)?.[1] || '-'),
|
||||
type: stripYamlValue(ruleBlock.match(/^\s+type:\s*(.+)$/m)?.[1] || 'deterministic'),
|
||||
type: stripYamlValue(ruleBlock.match(/^\s{4}type:\s*(.+)$/m)?.[1] || 'deterministic'),
|
||||
checkTypes,
|
||||
logic: stripYamlValue(ruleBlock.match(/^\s+logic:\s*(.+)$/m)?.[1] || ''),
|
||||
logic: stripYamlValue(ruleBlock.match(/^\s{4}logic:\s*(.+)$/m)?.[1] || ''),
|
||||
subRules,
|
||||
subRuleIds: readList(ruleBlock, 'rules'),
|
||||
scope: scope.slice(0, 8),
|
||||
@@ -425,7 +425,7 @@ function parseRules(source: string): RuleSummary[] {
|
||||
stageCount: subRules.length,
|
||||
appliesIn: readFlexibleList(ruleBlock, 'applies_in'),
|
||||
prompt: prompts.join('\n\n'),
|
||||
description: stripYamlValue(ruleBlock.match(/^\s+desc:\s*(.+)$/m)?.[1] || '')
|
||||
description: stripYamlValue(ruleBlock.match(/^\s{4}desc:\s*(.+)$/m)?.[1] || '')
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user