refactor(builder): consolidate buildNodeTree onto shared flattener; delete dead serializeTreeForCraft
buildNodeTree now delegates its structural walk (ColumnLayout linkedNodes,
SHELL_INNER wrapping, style:[]->{} normalization) to flattenTreeForCraft,
materializing each flat node into a real Craft.js Node via
query.parseFreshNode — except the synthetic SHELL_INNER wrapper, which is
still hand-built (parseFreshNode would merge in Container's default
craft.props and change its look). sanitizeAiTree now lives in craft-tree.ts
and is re-exported here for existing callers.
Delete the dead serializeTreeForCraft (only its own tests called it) and
its now-orphaned tests.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,63 +1,5 @@
|
||||
import { describe, test, expect, vi } from 'vitest';
|
||||
import { serializeTreeForCraft, sanitizeAiTree, __test } from './apply-ai-response';
|
||||
|
||||
describe('serializeTreeForCraft', () => {
|
||||
test('flattens nested tree', () => {
|
||||
const tree = {
|
||||
type: { resolvedName: 'Section' },
|
||||
props: { aiName: 'Hero', node_id: 'ai-hero-1' },
|
||||
nodes: [
|
||||
{
|
||||
type: { resolvedName: 'Heading' },
|
||||
props: { aiName: 'Title', node_id: 'ai-h-1', text: 'Welcome' },
|
||||
nodes: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
const out = serializeTreeForCraft(tree);
|
||||
expect(out.rootNodeId).toBe('ai-hero-1');
|
||||
expect((out.nodes['ai-hero-1'] as any).nodes).toEqual(['ai-h-1']);
|
||||
expect((out.nodes['ai-h-1'] as any).parent).toBe('ROOT');
|
||||
});
|
||||
|
||||
test('auto-generates ids when node_id is missing', () => {
|
||||
const tree = { type: { resolvedName: 'Heading' }, props: {}, nodes: [] };
|
||||
const out = serializeTreeForCraft(tree);
|
||||
expect(typeof out.rootNodeId).toBe('string');
|
||||
expect(out.nodes[out.rootNodeId]).toBeDefined();
|
||||
});
|
||||
|
||||
test('sets isCanvas true for layout components', () => {
|
||||
const tree = {
|
||||
type: { resolvedName: 'Container' },
|
||||
props: { node_id: 'c1' },
|
||||
nodes: [],
|
||||
};
|
||||
const out = serializeTreeForCraft(tree);
|
||||
expect((out.nodes['ROOT'] as any).isCanvas).toBe(true);
|
||||
});
|
||||
|
||||
test('sets isCanvas false for leaf components', () => {
|
||||
const tree = {
|
||||
type: { resolvedName: 'Heading' },
|
||||
props: { node_id: 'h1' },
|
||||
nodes: [],
|
||||
};
|
||||
const out = serializeTreeForCraft(tree);
|
||||
expect((out.nodes['ROOT'] as any).isCanvas).toBe(false);
|
||||
});
|
||||
|
||||
test('aliases root node to ROOT key', () => {
|
||||
const tree = {
|
||||
type: { resolvedName: 'Section' },
|
||||
props: { node_id: 'ai-section-1' },
|
||||
nodes: [],
|
||||
};
|
||||
const out = serializeTreeForCraft(tree);
|
||||
expect(out.nodes['ROOT']).toBeDefined();
|
||||
expect((out.nodes['ROOT'] as any).parent).toBeNull();
|
||||
});
|
||||
});
|
||||
import { sanitizeAiTree, __test } from './apply-ai-response';
|
||||
|
||||
describe('findNodeIdByAiNodeId', () => {
|
||||
const query = {
|
||||
|
||||
Reference in New Issue
Block a user