mcp-dndgrid 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/PROJECT_SUMMARY.md +482 -0
- package/QUICKSTART.md +223 -0
- package/README.md +365 -0
- package/STATUS.md +315 -0
- package/USAGE_GUIDE.md +547 -0
- package/dist/chunk-CMGEAPA5.js +157 -0
- package/dist/chunk-CMGEAPA5.js.map +1 -0
- package/dist/chunk-QZHBI6ZI.js +5281 -0
- package/dist/chunk-QZHBI6ZI.js.map +1 -0
- package/dist/chunk-SEGVTWSK.js +44 -0
- package/dist/chunk-SEGVTWSK.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +248012 -0
- package/dist/index.js.map +1 -0
- package/dist/stdio-FWYJXSU7.js +101 -0
- package/dist/stdio-FWYJXSU7.js.map +1 -0
- package/dist/template-JDMAVVX7.js +9 -0
- package/dist/template-JDMAVVX7.js.map +1 -0
- package/examples/claude_desktop_config.example.json +12 -0
- package/examples/example-complex-editor.tsx +107 -0
- package/examples/example-dashboard.tsx +65 -0
- package/examples/example-ide-layout.tsx +53 -0
- package/examples/test-generator.ts +37 -0
- package/examples/test-parser.ts +121 -0
- package/examples/test-scenarios.md +496 -0
- package/package.json +42 -0
- package/src/index.ts +16 -0
- package/src/server.ts +314 -0
- package/src/tools/analyze-layout.ts +193 -0
- package/src/tools/apply-template.ts +125 -0
- package/src/tools/generate-layout.ts +235 -0
- package/src/tools/interactive-builder.ts +100 -0
- package/src/tools/validate-layout.ts +113 -0
- package/src/types/layout.ts +48 -0
- package/src/types/template.ts +181 -0
- package/src/utils/ast-parser.ts +264 -0
- package/src/utils/code-generator.ts +123 -0
- package/src/utils/layout-analyzer.ts +105 -0
- package/src/utils/layout-builder.ts +127 -0
- package/src/utils/validator.ts +263 -0
- package/stderr.log +1 -0
- package/stdout.log +0 -0
- package/test-mcp.js +27 -0
- package/tsconfig.json +29 -0
- package/tsup.config.ts +16 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
JSONRPCMessageSchema
|
|
4
|
+
} from "./chunk-QZHBI6ZI.js";
|
|
5
|
+
import "./chunk-SEGVTWSK.js";
|
|
6
|
+
|
|
7
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
8
|
+
import process from "process";
|
|
9
|
+
|
|
10
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
11
|
+
var ReadBuffer = class {
|
|
12
|
+
append(chunk) {
|
|
13
|
+
this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
|
|
14
|
+
}
|
|
15
|
+
readMessage() {
|
|
16
|
+
if (!this._buffer) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const index = this._buffer.indexOf("\n");
|
|
20
|
+
if (index === -1) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const line = this._buffer.toString("utf8", 0, index).replace(/\r$/, "");
|
|
24
|
+
this._buffer = this._buffer.subarray(index + 1);
|
|
25
|
+
return deserializeMessage(line);
|
|
26
|
+
}
|
|
27
|
+
clear() {
|
|
28
|
+
this._buffer = void 0;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
function deserializeMessage(line) {
|
|
32
|
+
return JSONRPCMessageSchema.parse(JSON.parse(line));
|
|
33
|
+
}
|
|
34
|
+
function serializeMessage(message) {
|
|
35
|
+
return JSON.stringify(message) + "\n";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
39
|
+
var StdioServerTransport = class {
|
|
40
|
+
constructor(_stdin = process.stdin, _stdout = process.stdout) {
|
|
41
|
+
this._stdin = _stdin;
|
|
42
|
+
this._stdout = _stdout;
|
|
43
|
+
this._readBuffer = new ReadBuffer();
|
|
44
|
+
this._started = false;
|
|
45
|
+
this._ondata = (chunk) => {
|
|
46
|
+
this._readBuffer.append(chunk);
|
|
47
|
+
this.processReadBuffer();
|
|
48
|
+
};
|
|
49
|
+
this._onerror = (error) => {
|
|
50
|
+
this.onerror?.(error);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Starts listening for messages on stdin.
|
|
55
|
+
*/
|
|
56
|
+
async start() {
|
|
57
|
+
if (this._started) {
|
|
58
|
+
throw new Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");
|
|
59
|
+
}
|
|
60
|
+
this._started = true;
|
|
61
|
+
this._stdin.on("data", this._ondata);
|
|
62
|
+
this._stdin.on("error", this._onerror);
|
|
63
|
+
}
|
|
64
|
+
processReadBuffer() {
|
|
65
|
+
while (true) {
|
|
66
|
+
try {
|
|
67
|
+
const message = this._readBuffer.readMessage();
|
|
68
|
+
if (message === null) {
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
this.onmessage?.(message);
|
|
72
|
+
} catch (error) {
|
|
73
|
+
this.onerror?.(error);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async close() {
|
|
78
|
+
this._stdin.off("data", this._ondata);
|
|
79
|
+
this._stdin.off("error", this._onerror);
|
|
80
|
+
const remainingDataListeners = this._stdin.listenerCount("data");
|
|
81
|
+
if (remainingDataListeners === 0) {
|
|
82
|
+
this._stdin.pause();
|
|
83
|
+
}
|
|
84
|
+
this._readBuffer.clear();
|
|
85
|
+
this.onclose?.();
|
|
86
|
+
}
|
|
87
|
+
send(message) {
|
|
88
|
+
return new Promise((resolve) => {
|
|
89
|
+
const json = serializeMessage(message);
|
|
90
|
+
if (this._stdout.write(json)) {
|
|
91
|
+
resolve();
|
|
92
|
+
} else {
|
|
93
|
+
this._stdout.once("drain", resolve);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
export {
|
|
99
|
+
StdioServerTransport
|
|
100
|
+
};
|
|
101
|
+
//# sourceMappingURL=stdio-FWYJXSU7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../node_modules/@modelcontextprotocol/sdk/src/server/stdio.ts","../node_modules/@modelcontextprotocol/sdk/src/shared/stdio.ts"],"sourcesContent":[null,null],"mappings":";;;;;;;AAAA,OAAO,aAAa;;;ACKd,IAAO,aAAP,MAAiB;EAGnB,OAAO,OAAa;AAChB,SAAK,UAAU,KAAK,UAAU,OAAO,OAAO,CAAC,KAAK,SAAS,KAAK,CAAC,IAAI;EACzE;EAEA,cAAW;AACP,QAAI,CAAC,KAAK,SAAS;AACf,aAAO;IACX;AAEA,UAAM,QAAQ,KAAK,QAAQ,QAAQ,IAAI;AACvC,QAAI,UAAU,IAAI;AACd,aAAO;IACX;AAEA,UAAM,OAAO,KAAK,QAAQ,SAAS,QAAQ,GAAG,KAAK,EAAE,QAAQ,OAAO,EAAE;AACtE,SAAK,UAAU,KAAK,QAAQ,SAAS,QAAQ,CAAC;AAC9C,WAAO,mBAAmB,IAAI;EAClC;EAEA,QAAK;AACD,SAAK,UAAU;EACnB;;AAGE,SAAU,mBAAmB,MAAY;AAC3C,SAAO,qBAAqB,MAAM,KAAK,MAAM,IAAI,CAAC;AACtD;AAEM,SAAU,iBAAiB,SAAuB;AACpD,SAAO,KAAK,UAAU,OAAO,IAAI;AACrC;;;AD3BM,IAAO,uBAAP,MAA2B;EAI7B,YACY,SAAmB,QAAQ,OAC3B,UAAoB,QAAQ,QAAM;AADlC,SAAA,SAAA;AACA,SAAA,UAAA;AALJ,SAAA,cAA0B,IAAI,WAAU;AACxC,SAAA,WAAW;AAYnB,SAAA,UAAU,CAAC,UAAiB;AACxB,WAAK,YAAY,OAAO,KAAK;AAC7B,WAAK,kBAAiB;IAC1B;AACA,SAAA,WAAW,CAAC,UAAgB;AACxB,WAAK,UAAU,KAAK;IACxB;EAbG;;;;EAkBH,MAAM,QAAK;AACP,QAAI,KAAK,UAAU;AACf,YAAM,IAAI,MACN,+GAA+G;IAEvH;AAEA,SAAK,WAAW;AAChB,SAAK,OAAO,GAAG,QAAQ,KAAK,OAAO;AACnC,SAAK,OAAO,GAAG,SAAS,KAAK,QAAQ;EACzC;EAEQ,oBAAiB;AACrB,WAAO,MAAM;AACT,UAAI;AACA,cAAM,UAAU,KAAK,YAAY,YAAW;AAC5C,YAAI,YAAY,MAAM;AAClB;QACJ;AAEA,aAAK,YAAY,OAAO;MAC5B,SAAS,OAAO;AACZ,aAAK,UAAU,KAAc;MACjC;IACJ;EACJ;EAEA,MAAM,QAAK;AAEP,SAAK,OAAO,IAAI,QAAQ,KAAK,OAAO;AACpC,SAAK,OAAO,IAAI,SAAS,KAAK,QAAQ;AAGtC,UAAM,yBAAyB,KAAK,OAAO,cAAc,MAAM;AAC/D,QAAI,2BAA2B,GAAG;AAG9B,WAAK,OAAO,MAAK;IACrB;AAGA,SAAK,YAAY,MAAK;AACtB,SAAK,UAAS;EAClB;EAEA,KAAK,SAAuB;AACxB,WAAO,IAAI,QAAQ,aAAU;AACzB,YAAM,OAAO,iBAAiB,OAAO;AACrC,UAAI,KAAK,QAAQ,MAAM,IAAI,GAAG;AAC1B,gBAAO;MACX,OAAO;AACH,aAAK,QAAQ,KAAK,SAAS,OAAO;MACtC;IACJ,CAAC;EACL;;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Complex Editor Layout
|
|
3
|
+
*
|
|
4
|
+
* Generated using: generate-layout
|
|
5
|
+
* Description: Complex IDE with multiple nested panels
|
|
6
|
+
* Components: Navigation, FileTree, Editor, Preview, Console, Terminal, Properties
|
|
7
|
+
*
|
|
8
|
+
* This demonstrates a complex editor layout with:
|
|
9
|
+
* - Top navigation bar (8%)
|
|
10
|
+
* - Left sidebar (15%): File tree
|
|
11
|
+
* - Center (50%): Editor with preview (60/40 split)
|
|
12
|
+
* - Right sidebar (15%): Properties panel
|
|
13
|
+
* - Bottom panel (12%): Console and terminal (50/50 split)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
"use client";
|
|
17
|
+
|
|
18
|
+
import { DndGridContainer, DndGridSplit, DndGridItem } from 'zerojin/components';
|
|
19
|
+
import { Navigation } from './components/Navigation';
|
|
20
|
+
import { FileTree } from './components/FileTree';
|
|
21
|
+
import { Editor } from './components/Editor';
|
|
22
|
+
import { Preview } from './components/Preview';
|
|
23
|
+
import { Console } from './components/Console';
|
|
24
|
+
import { Terminal } from './components/Terminal';
|
|
25
|
+
import { Properties } from './components/Properties';
|
|
26
|
+
|
|
27
|
+
export default function ComplexEditorLayout() {
|
|
28
|
+
return (
|
|
29
|
+
<DndGridContainer width={1920} height={1080}>
|
|
30
|
+
{/* Top: Navigation */}
|
|
31
|
+
<DndGridSplit direction="horizontal" ratio={0.08}>
|
|
32
|
+
<DndGridItem>
|
|
33
|
+
<Navigation />
|
|
34
|
+
</DndGridItem>
|
|
35
|
+
|
|
36
|
+
{/* Main content area */}
|
|
37
|
+
<DndGridSplit direction="vertical" ratio={0.15}>
|
|
38
|
+
{/* Left: File tree */}
|
|
39
|
+
<DndGridItem>
|
|
40
|
+
<FileTree />
|
|
41
|
+
</DndGridItem>
|
|
42
|
+
|
|
43
|
+
{/* Center + Right + Bottom */}
|
|
44
|
+
<DndGridSplit direction="vertical" ratio={0.77}>
|
|
45
|
+
{/* Center + Right */}
|
|
46
|
+
<DndGridSplit direction="horizontal" ratio={0.88}>
|
|
47
|
+
{/* Center: Editor + Preview */}
|
|
48
|
+
<DndGridSplit direction="vertical" ratio={0.6}>
|
|
49
|
+
<DndGridItem>
|
|
50
|
+
<Editor />
|
|
51
|
+
</DndGridItem>
|
|
52
|
+
<DndGridItem>
|
|
53
|
+
<Preview />
|
|
54
|
+
</DndGridItem>
|
|
55
|
+
</DndGridSplit>
|
|
56
|
+
|
|
57
|
+
{/* Bottom: Console + Terminal */}
|
|
58
|
+
<DndGridSplit direction="vertical" ratio={0.5}>
|
|
59
|
+
<DndGridItem>
|
|
60
|
+
<Console />
|
|
61
|
+
</DndGridItem>
|
|
62
|
+
<DndGridItem>
|
|
63
|
+
<Terminal />
|
|
64
|
+
</DndGridItem>
|
|
65
|
+
</DndGridSplit>
|
|
66
|
+
</DndGridSplit>
|
|
67
|
+
|
|
68
|
+
{/* Right: Properties */}
|
|
69
|
+
<DndGridItem>
|
|
70
|
+
<Properties />
|
|
71
|
+
</DndGridItem>
|
|
72
|
+
</DndGridSplit>
|
|
73
|
+
</DndGridSplit>
|
|
74
|
+
</DndGridSplit>
|
|
75
|
+
</DndGridContainer>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Performance Metrics:
|
|
81
|
+
* - Items: 7
|
|
82
|
+
* - Splits: 6
|
|
83
|
+
* - Max Depth: 4
|
|
84
|
+
* - Estimated Performance: Good
|
|
85
|
+
*
|
|
86
|
+
* Complexity Analysis:
|
|
87
|
+
* ⚠️ Approaching recommended depth limit (4 levels)
|
|
88
|
+
* ✅ Item count well within limits (< 20)
|
|
89
|
+
* ⚠️ Complex nesting - consider simplifying if adding more panels
|
|
90
|
+
*
|
|
91
|
+
* Refactoring Opportunities:
|
|
92
|
+
* - Consider extracting bottom panel into separate component
|
|
93
|
+
* - Could use composition for editor+preview section
|
|
94
|
+
* - May benefit from lazy loading for heavy components
|
|
95
|
+
*
|
|
96
|
+
* Best Practices Followed:
|
|
97
|
+
* ✅ "use client" directive
|
|
98
|
+
* ✅ Descriptive component names
|
|
99
|
+
* ✅ Logical grouping of related panels
|
|
100
|
+
* ✅ Ratios within usable ranges
|
|
101
|
+
*
|
|
102
|
+
* Usage Notes:
|
|
103
|
+
* - This is near the upper complexity limit
|
|
104
|
+
* - Adding more panels may impact performance
|
|
105
|
+
* - Consider user feedback on panel sizes
|
|
106
|
+
* - Test drag-and-drop performance with actual data
|
|
107
|
+
*/
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: Dashboard 2x2 Grid
|
|
3
|
+
*
|
|
4
|
+
* Generated using: apply-template
|
|
5
|
+
* Template: dashboard-2x2
|
|
6
|
+
* Components: UserStats, RevenueChart, ActivityLog, QuickActions
|
|
7
|
+
*
|
|
8
|
+
* This demonstrates a 2x2 dashboard grid layout:
|
|
9
|
+
* - Top-left: User statistics
|
|
10
|
+
* - Top-right: Revenue chart
|
|
11
|
+
* - Bottom-left: Activity log
|
|
12
|
+
* - Bottom-right: Quick actions
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
"use client";
|
|
16
|
+
|
|
17
|
+
import { DndGridContainer, DndGridSplit, DndGridItem } from 'zerojin/components';
|
|
18
|
+
import { UserStats } from './components/UserStats';
|
|
19
|
+
import { RevenueChart } from './components/RevenueChart';
|
|
20
|
+
import { ActivityLog } from './components/ActivityLog';
|
|
21
|
+
import { QuickActions } from './components/QuickActions';
|
|
22
|
+
|
|
23
|
+
export default function Dashboard() {
|
|
24
|
+
return (
|
|
25
|
+
<DndGridContainer width={1400} height={900}>
|
|
26
|
+
<DndGridSplit direction="horizontal" ratio={0.5}>
|
|
27
|
+
<DndGridSplit direction="vertical" ratio={0.5}>
|
|
28
|
+
<DndGridItem>
|
|
29
|
+
<UserStats />
|
|
30
|
+
</DndGridItem>
|
|
31
|
+
<DndGridItem>
|
|
32
|
+
<RevenueChart />
|
|
33
|
+
</DndGridItem>
|
|
34
|
+
</DndGridSplit>
|
|
35
|
+
<DndGridSplit direction="vertical" ratio={0.5}>
|
|
36
|
+
<DndGridItem>
|
|
37
|
+
<ActivityLog />
|
|
38
|
+
</DndGridItem>
|
|
39
|
+
<DndGridItem>
|
|
40
|
+
<QuickActions />
|
|
41
|
+
</DndGridItem>
|
|
42
|
+
</DndGridSplit>
|
|
43
|
+
</DndGridSplit>
|
|
44
|
+
</DndGridContainer>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Performance Metrics:
|
|
50
|
+
* - Items: 4
|
|
51
|
+
* - Splits: 3
|
|
52
|
+
* - Max Depth: 2
|
|
53
|
+
* - Estimated Performance: Excellent
|
|
54
|
+
*
|
|
55
|
+
* Best Practices:
|
|
56
|
+
* ✅ Equal ratios (0.5) for balanced grid
|
|
57
|
+
* ✅ Symmetrical structure
|
|
58
|
+
* ✅ Low complexity
|
|
59
|
+
* ✅ Easy to rearrange via drag-and-drop
|
|
60
|
+
*
|
|
61
|
+
* Usage Tips:
|
|
62
|
+
* - Perfect for admin dashboards
|
|
63
|
+
* - Can easily expand to 2x3 or 3x3 by adding more splits
|
|
64
|
+
* - Each widget is independently draggable
|
|
65
|
+
*/
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example: IDE Layout
|
|
3
|
+
*
|
|
4
|
+
* Generated using: apply-template
|
|
5
|
+
* Template: ide-layout
|
|
6
|
+
* Components: FileExplorer, CodeEditor, Terminal
|
|
7
|
+
*
|
|
8
|
+
* This demonstrates a typical 3-panel IDE layout:
|
|
9
|
+
* - Left sidebar (20%): File explorer
|
|
10
|
+
* - Right top (56%): Code editor
|
|
11
|
+
* - Right bottom (24%): Terminal
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
"use client";
|
|
15
|
+
|
|
16
|
+
import { DndGridContainer, DndGridSplit, DndGridItem } from 'zerojin/components';
|
|
17
|
+
import { FileExplorer } from './components/FileExplorer';
|
|
18
|
+
import { CodeEditor } from './components/CodeEditor';
|
|
19
|
+
import { Terminal } from './components/Terminal';
|
|
20
|
+
|
|
21
|
+
export default function IDELayout() {
|
|
22
|
+
return (
|
|
23
|
+
<DndGridContainer width={1600} height={900}>
|
|
24
|
+
<DndGridSplit direction="vertical" ratio={0.2}>
|
|
25
|
+
<DndGridItem>
|
|
26
|
+
<FileExplorer />
|
|
27
|
+
</DndGridItem>
|
|
28
|
+
<DndGridSplit direction="horizontal" ratio={0.7}>
|
|
29
|
+
<DndGridItem>
|
|
30
|
+
<CodeEditor />
|
|
31
|
+
</DndGridItem>
|
|
32
|
+
<DndGridItem>
|
|
33
|
+
<Terminal />
|
|
34
|
+
</DndGridItem>
|
|
35
|
+
</DndGridSplit>
|
|
36
|
+
</DndGridSplit>
|
|
37
|
+
</DndGridContainer>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Performance Metrics:
|
|
43
|
+
* - Items: 3
|
|
44
|
+
* - Splits: 2
|
|
45
|
+
* - Max Depth: 2
|
|
46
|
+
* - Estimated Performance: Excellent
|
|
47
|
+
*
|
|
48
|
+
* Best Practices:
|
|
49
|
+
* ✅ "use client" directive for Next.js App Router
|
|
50
|
+
* ✅ Ratios within recommended range (0.2-0.8)
|
|
51
|
+
* ✅ Low item count (< 20)
|
|
52
|
+
* ✅ Shallow nesting (< 4 levels)
|
|
53
|
+
*/
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { LayoutBuilder, L } from '../src/utils/layout-builder.js';
|
|
2
|
+
import { CodeGenerator } from '../src/utils/code-generator.js';
|
|
3
|
+
import { LayoutAnalyzer } from '../src/utils/layout-analyzer.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Test the code generator with a simple IDE layout
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
// Build an IDE layout
|
|
10
|
+
const ideLayout = new LayoutBuilder(1200, 800)
|
|
11
|
+
.setRoot(
|
|
12
|
+
L.v(
|
|
13
|
+
0.2,
|
|
14
|
+
L.item('Sidebar'),
|
|
15
|
+
L.h(0.7, L.item('CodeEditor'), L.item('Terminal'))
|
|
16
|
+
)
|
|
17
|
+
)
|
|
18
|
+
.build();
|
|
19
|
+
|
|
20
|
+
console.log('=== IDE Layout Tree ===');
|
|
21
|
+
console.log(JSON.stringify(ideLayout, null, 2));
|
|
22
|
+
|
|
23
|
+
// Analyze the layout
|
|
24
|
+
const metadata = LayoutAnalyzer.calculateMetadata(ideLayout);
|
|
25
|
+
console.log('\n=== Layout Metadata ===');
|
|
26
|
+
console.log(metadata);
|
|
27
|
+
|
|
28
|
+
// Generate code
|
|
29
|
+
const generator = new CodeGenerator({
|
|
30
|
+
framework: 'nextjs-app',
|
|
31
|
+
width: ideLayout.width,
|
|
32
|
+
height: ideLayout.height,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const code = generator.generate(ideLayout);
|
|
36
|
+
console.log('\n=== Generated Code ===');
|
|
37
|
+
console.log(code);
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { ASTParser } from '../src/utils/ast-parser.js';
|
|
2
|
+
import { Validator } from '../src/utils/validator.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Test AST parser and validator
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const sampleCode = `
|
|
9
|
+
"use client";
|
|
10
|
+
|
|
11
|
+
import { DndGridContainer, DndGridSplit, DndGridItem } from 'zerojin/components';
|
|
12
|
+
|
|
13
|
+
export default function Layout() {
|
|
14
|
+
return (
|
|
15
|
+
<DndGridContainer width={1200} height={800}>
|
|
16
|
+
<DndGridSplit direction="vertical" ratio={0.2}>
|
|
17
|
+
<DndGridItem>
|
|
18
|
+
<Sidebar />
|
|
19
|
+
</DndGridItem>
|
|
20
|
+
<DndGridSplit direction="horizontal" ratio={0.7}>
|
|
21
|
+
<DndGridItem>
|
|
22
|
+
<CodeEditor />
|
|
23
|
+
</DndGridItem>
|
|
24
|
+
<DndGridItem>
|
|
25
|
+
<Terminal />
|
|
26
|
+
</DndGridItem>
|
|
27
|
+
</DndGridSplit>
|
|
28
|
+
</DndGridSplit>
|
|
29
|
+
</DndGridContainer>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
|
|
34
|
+
console.log('=== Testing AST Parser ===\n');
|
|
35
|
+
|
|
36
|
+
// Parse the code
|
|
37
|
+
const parser = new ASTParser();
|
|
38
|
+
const layout = parser.parse(sampleCode);
|
|
39
|
+
|
|
40
|
+
if (layout) {
|
|
41
|
+
console.log('✅ Successfully parsed layout tree:');
|
|
42
|
+
console.log(JSON.stringify(layout, null, 2));
|
|
43
|
+
} else {
|
|
44
|
+
console.log('❌ Failed to parse layout');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log('\n=== Testing Validator ===\n');
|
|
48
|
+
|
|
49
|
+
// Validate the code
|
|
50
|
+
const validator = new Validator();
|
|
51
|
+
const codeValidation = validator.validateCode(sampleCode, false);
|
|
52
|
+
|
|
53
|
+
console.log('Code Validation:');
|
|
54
|
+
console.log(`Valid: ${codeValidation.valid}`);
|
|
55
|
+
console.log(`Errors: ${codeValidation.errors.length}`);
|
|
56
|
+
console.log(`Warnings: ${codeValidation.warnings.length}`);
|
|
57
|
+
|
|
58
|
+
if (codeValidation.errors.length > 0) {
|
|
59
|
+
console.log('\nErrors:');
|
|
60
|
+
codeValidation.errors.forEach((err, i) => {
|
|
61
|
+
console.log(` ${i + 1}. [${err.type}] ${err.message}`);
|
|
62
|
+
if (err.fix) console.log(` Fix: ${err.fix}`);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (codeValidation.warnings.length > 0) {
|
|
67
|
+
console.log('\nWarnings:');
|
|
68
|
+
codeValidation.warnings.forEach((warn, i) => {
|
|
69
|
+
console.log(` ${i + 1}. ${warn.message}`);
|
|
70
|
+
if (warn.suggestion) console.log(` Suggestion: ${warn.suggestion}`);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Validate the parsed layout tree
|
|
75
|
+
if (layout) {
|
|
76
|
+
console.log('\n=== Validating Layout Tree ===\n');
|
|
77
|
+
const treeValidation = validator.validate(layout, true);
|
|
78
|
+
|
|
79
|
+
console.log(`Valid: ${treeValidation.valid}`);
|
|
80
|
+
console.log(`Errors: ${treeValidation.errors.length}`);
|
|
81
|
+
console.log(`Warnings: ${treeValidation.warnings.length}`);
|
|
82
|
+
console.log(`Suggestions: ${treeValidation.suggestions.length}`);
|
|
83
|
+
|
|
84
|
+
if (treeValidation.warnings.length > 0) {
|
|
85
|
+
console.log('\nWarnings:');
|
|
86
|
+
treeValidation.warnings.forEach((warn, i) => {
|
|
87
|
+
console.log(` ${i + 1}. ${warn.message}`);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (treeValidation.suggestions.length > 0) {
|
|
92
|
+
console.log('\nSuggestions:');
|
|
93
|
+
treeValidation.suggestions.forEach((sugg, i) => {
|
|
94
|
+
console.log(` ${i + 1}. ${sugg}`);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Test with invalid code
|
|
100
|
+
console.log('\n=== Testing Invalid Code ===\n');
|
|
101
|
+
|
|
102
|
+
const invalidCode = `
|
|
103
|
+
<DndGridContainer width={1200} height={800}>
|
|
104
|
+
<DndGridSplit direction="vertical" ratio={1.5}>
|
|
105
|
+
<DndGridItem>
|
|
106
|
+
<ComponentA />
|
|
107
|
+
</DndGridItem>
|
|
108
|
+
</DndGridSplit>
|
|
109
|
+
</DndGridContainer>
|
|
110
|
+
`;
|
|
111
|
+
|
|
112
|
+
const invalidValidation = validator.validateCode(invalidCode, false);
|
|
113
|
+
console.log(`Valid: ${invalidValidation.valid}`);
|
|
114
|
+
console.log(`Errors: ${invalidValidation.errors.length}`);
|
|
115
|
+
|
|
116
|
+
if (invalidValidation.errors.length > 0) {
|
|
117
|
+
console.log('\nErrors found:');
|
|
118
|
+
invalidValidation.errors.forEach((err, i) => {
|
|
119
|
+
console.log(` ${i + 1}. [${err.type}] ${err.message}`);
|
|
120
|
+
});
|
|
121
|
+
}
|