meno-core 1.0.2 → 1.0.4

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.
Files changed (94) hide show
  1. package/bin/cli.ts +63 -4
  2. package/build-static.ts +19 -3
  3. package/entries/server-router.tsx +0 -1
  4. package/lib/client/ErrorBoundary.test.tsx +3 -3
  5. package/lib/client/componentRegistry.test.ts +81 -35
  6. package/lib/client/core/ComponentBuilder.test.ts +12 -18
  7. package/lib/client/core/ComponentBuilder.ts +364 -768
  8. package/lib/client/core/ComponentRenderer.test.tsx +0 -1
  9. package/lib/client/core/builders/cmsListBuilder.ts +242 -0
  10. package/lib/client/core/builders/embedBuilder.ts +140 -0
  11. package/lib/client/core/builders/index.ts +26 -0
  12. package/lib/client/core/builders/linkBuilder.ts +136 -0
  13. package/lib/client/core/builders/localeListBuilder.ts +193 -0
  14. package/lib/client/core/builders/objectLinkBuilder.ts +138 -0
  15. package/lib/client/core/builders/types.ts +89 -0
  16. package/lib/client/core/cmsTemplateProcessor.ts +2 -2
  17. package/lib/client/hmrWebSocket.ts +6 -2
  18. package/lib/client/hydration/HydrationUtils.test.ts +1 -1
  19. package/lib/client/i18nConfigService.test.ts +6 -7
  20. package/lib/client/responsiveStyleResolver.test.ts +6 -6
  21. package/lib/client/routing/RouteLoader.test.ts +11 -11
  22. package/lib/client/routing/RouteLoader.ts +4 -2
  23. package/lib/client/routing/Router.tsx +21 -12
  24. package/lib/client/scripts/ScriptExecutor.test.ts +69 -70
  25. package/lib/client/scripts/ScriptExecutor.ts +81 -42
  26. package/lib/client/services/PrefetchService.test.ts +3 -3
  27. package/lib/client/styleProcessor.ts +4 -3
  28. package/lib/client/styles/StyleInjector.test.ts +6 -2
  29. package/lib/client/styles/StyleInjector.ts +7 -3
  30. package/lib/client/templateEngine.test.ts +6 -5
  31. package/lib/client/templateEngine.ts +20 -167
  32. package/lib/client/utils/toast.ts +19 -18
  33. package/lib/server/cssGenerator.test.ts +8 -8
  34. package/lib/server/errors.ts +65 -0
  35. package/lib/server/jsonLoader.test.ts +2 -2
  36. package/lib/server/jsonLoader.ts +5 -0
  37. package/lib/server/middleware/cors.ts +2 -2
  38. package/lib/server/middleware/logger.test.ts +9 -9
  39. package/lib/server/routes/api/pages.ts +1 -1
  40. package/lib/server/routes/pages.ts +2 -2
  41. package/lib/server/services/fileWatcherService.ts +3 -1
  42. package/lib/server/ssr/attributeBuilder.ts +78 -0
  43. package/lib/server/ssr/cmsSSRProcessor.ts +100 -0
  44. package/lib/server/ssr/cssCollector.ts +33 -0
  45. package/lib/server/ssr/htmlGenerator.ts +147 -0
  46. package/lib/server/ssr/imageMetadata.ts +117 -0
  47. package/lib/server/ssr/index.ts +33 -0
  48. package/lib/server/ssr/jsCollector.ts +89 -0
  49. package/lib/server/ssr/metaTagGenerator.ts +106 -0
  50. package/lib/server/ssr/ssrRenderer.ts +1133 -0
  51. package/lib/server/ssrRenderer.test.ts +11 -8
  52. package/lib/server/ssrRenderer.ts +7 -1527
  53. package/lib/server/validateStyleCoverage.ts +1 -1
  54. package/lib/shared/attributeNodeUtils.test.ts +7 -7
  55. package/lib/shared/constants.test.ts +1 -1
  56. package/lib/shared/constants.ts +1 -1
  57. package/lib/shared/cssGeneration.ts +1 -1
  58. package/lib/shared/errorLogger.test.ts +136 -0
  59. package/lib/shared/errorLogger.ts +87 -0
  60. package/lib/shared/errors.test.ts +99 -0
  61. package/lib/shared/errors.ts +50 -0
  62. package/lib/shared/expressionEvaluator.ts +161 -0
  63. package/lib/shared/fontLoader.ts +2 -2
  64. package/lib/shared/index.ts +43 -2
  65. package/lib/shared/itemTemplateUtils.test.ts +78 -0
  66. package/lib/shared/itemTemplateUtils.ts +66 -30
  67. package/lib/shared/nodeUtils.test.ts +3 -3
  68. package/lib/shared/propResolver.test.ts +232 -127
  69. package/lib/shared/propResolver.ts +8 -6
  70. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +5 -5
  71. package/lib/shared/registry/ClientRegistry.test.ts +1 -1
  72. package/lib/shared/registry/RegistryManager.test.ts +4 -4
  73. package/lib/shared/registry/SSRRegistry.test.ts +1 -1
  74. package/lib/shared/registry/index.ts +0 -1
  75. package/lib/shared/registry/nodeTypes/index.ts +0 -5
  76. package/lib/shared/responsiveScaling.ts +3 -2
  77. package/lib/shared/styleNodeUtils.test.ts +3 -3
  78. package/lib/shared/styleUtils.test.ts +7 -7
  79. package/lib/shared/styleUtils.ts +2 -2
  80. package/lib/shared/treePathUtils.test.ts +17 -17
  81. package/lib/shared/treePathUtils.ts +26 -20
  82. package/lib/shared/types/errors.ts +3 -3
  83. package/lib/shared/types/nodes.ts +0 -1
  84. package/lib/shared/types/rendering.ts +2 -1
  85. package/lib/shared/types/styles.ts +3 -1
  86. package/lib/shared/utilityClassMapper.ts +17 -5
  87. package/lib/shared/validation/propValidator.test.ts +51 -7
  88. package/lib/shared/validation/propValidator.ts +11 -6
  89. package/lib/shared/validation/schemas.ts +15 -9
  90. package/lib/shared/validation/validators.test.ts +2 -3
  91. package/lib/test-utils/factories/FetchMockFactory.ts +2 -2
  92. package/lib/test-utils/index.ts +2 -1
  93. package/package.json +1 -1
  94. package/lib/shared/registry/nodeTypes/TextNodeType.ts +0 -52
package/bin/cli.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import { resolve, join } from 'path';
8
- import { existsSync, mkdirSync, writeFileSync, cpSync } from 'fs';
8
+ import { existsSync, mkdirSync, writeFileSync, cpSync, readFileSync } from 'fs';
9
9
  import { setProjectRoot } from '../lib/server/projectContext';
10
10
 
11
11
  const args = process.argv.slice(2);
@@ -35,10 +35,66 @@ Examples:
35
35
  `);
36
36
  }
37
37
 
38
+ // Parse _headers file (Netlify/Cloudflare format)
39
+ function parseHeadersFile(distPath: string): Map<string, Record<string, string>> {
40
+ const headersPath = join(distPath, '_headers');
41
+ const headers = new Map<string, Record<string, string>>();
42
+
43
+ if (!existsSync(headersPath)) return headers;
44
+
45
+ const content = readFileSync(headersPath, 'utf-8');
46
+ let currentPath = '';
47
+
48
+ for (const line of content.split('\n')) {
49
+ const trimmed = line.trim();
50
+ if (!trimmed || trimmed.startsWith('#')) continue;
51
+
52
+ if (!line.startsWith(' ') && !line.startsWith('\t')) {
53
+ // Path line
54
+ currentPath = trimmed;
55
+ if (!headers.has(currentPath)) {
56
+ headers.set(currentPath, {});
57
+ }
58
+ } else if (currentPath && trimmed.includes(':')) {
59
+ // Header line
60
+ const colonIndex = trimmed.indexOf(':');
61
+ const name = trimmed.substring(0, colonIndex).trim();
62
+ const value = trimmed.substring(colonIndex + 1).trim();
63
+ headers.get(currentPath)![name] = value;
64
+ }
65
+ }
66
+
67
+ return headers;
68
+ }
69
+
70
+ // Get headers matching a pathname
71
+ function getMatchingHeaders(
72
+ pathname: string,
73
+ headersMap: Map<string, Record<string, string>>
74
+ ): Record<string, string> {
75
+ const result: Record<string, string> = {};
76
+
77
+ headersMap.forEach((headers, pattern) => {
78
+ if (pattern === pathname || pattern === '/*') {
79
+ Object.assign(result, headers);
80
+ } else if (pattern.endsWith('/*')) {
81
+ const prefix = pattern.slice(0, -1);
82
+ if (pathname.startsWith(prefix)) {
83
+ Object.assign(result, headers);
84
+ }
85
+ }
86
+ });
87
+
88
+ return result;
89
+ }
90
+
38
91
  // Start static file server on port 8080 (non-blocking)
39
92
  async function startStaticServer(distPath: string) {
40
93
  const { SERVE_PORT } = await import('../lib/shared/constants');
41
94
 
95
+ // Parse _headers file once on startup
96
+ const headersMap = parseHeadersFile(distPath);
97
+
42
98
  const server = Bun.serve({
43
99
  port: SERVE_PORT,
44
100
  async fetch(req: Request) {
@@ -50,6 +106,9 @@ async function startStaticServer(distPath: string) {
50
106
  pathname = '/index.html';
51
107
  }
52
108
 
109
+ // Get custom headers for this path
110
+ const customHeaders = getMatchingHeaders(pathname, headersMap);
111
+
53
112
  // Try to serve the file
54
113
  const filePath = join(distPath, pathname);
55
114
 
@@ -57,7 +116,7 @@ async function startStaticServer(distPath: string) {
57
116
  if (existsSync(filePath)) {
58
117
  const file = Bun.file(filePath);
59
118
  if (await file.exists()) {
60
- return new Response(file);
119
+ return new Response(file, { headers: customHeaders });
61
120
  }
62
121
  }
63
122
 
@@ -65,14 +124,14 @@ async function startStaticServer(distPath: string) {
65
124
  const htmlPath = filePath.endsWith('.html') ? filePath : `${filePath}.html`;
66
125
  if (existsSync(htmlPath)) {
67
126
  const file = Bun.file(htmlPath);
68
- return new Response(file);
127
+ return new Response(file, { headers: customHeaders });
69
128
  }
70
129
 
71
130
  // Try index.html in directory
72
131
  const indexPath = join(filePath, 'index.html');
73
132
  if (existsSync(indexPath)) {
74
133
  const file = Bun.file(indexPath);
75
- return new Response(file);
134
+ return new Response(file, { headers: customHeaders });
76
135
  }
77
136
 
78
137
  return new Response('Not Found', { status: 404 });
package/build-static.ts CHANGED
@@ -299,11 +299,27 @@ async function buildStaticPages(): Promise<void> {
299
299
  const functionsDir = projectPaths.functions();
300
300
  if (existsSync(functionsDir)) {
301
301
  copyDirectory(functionsDir, join(distDir, "functions"));
302
- console.log("✅ Assets and functions copied\n");
303
- } else {
304
- console.log("✅ Assets copied\n");
305
302
  }
306
303
 
304
+ // Copy _headers and _redirects files for static hosting (Netlify, Cloudflare Pages)
305
+ const hostingFiles: string[] = [];
306
+ const headersFile = join(projectPaths.project, '_headers');
307
+ const redirectsFile = join(projectPaths.project, '_redirects');
308
+
309
+ if (existsSync(headersFile)) {
310
+ copyFileSync(headersFile, join(distDir, '_headers'));
311
+ hostingFiles.push('_headers');
312
+ }
313
+ if (existsSync(redirectsFile)) {
314
+ copyFileSync(redirectsFile, join(distDir, '_redirects'));
315
+ hostingFiles.push('_redirects');
316
+ }
317
+
318
+ const parts = ['Assets'];
319
+ if (existsSync(functionsDir)) parts.push('functions');
320
+ if (hostingFiles.length > 0) parts.push(hostingFiles.join(', '));
321
+ console.log(`✅ ${parts.join(', ')} copied\n`);
322
+
307
323
  // Load all global components
308
324
  const components = await loadComponentDirectory(projectPaths.components());
309
325
  const globalComponents: Record<string, ComponentDefinition> = {};
@@ -66,7 +66,6 @@ const { server, port } = createServer({
66
66
  wsManager,
67
67
  cmsService,
68
68
  cmsProvider,
69
- enableEditor: true, // Full editor mode
70
69
  });
71
70
 
72
71
  console.log(`Server with routing and HMR running at http://localhost:${port}`);
@@ -1,6 +1,6 @@
1
1
  import { test, expect, describe, beforeEach, afterEach, mock } from "bun:test";
2
2
  import { ErrorBoundary, withErrorBoundary } from "./ErrorBoundary";
3
- import { createElement as h, Component, useState } from "react";
3
+ import React, { createElement as h, Component, useState } from "react";
4
4
  import { createRoot, Root } from "react-dom/client";
5
5
  import { flushPromises, wait } from "../test-utils/helpers/asyncHelpers";
6
6
 
@@ -33,7 +33,7 @@ function cleanupContainer(container: HTMLElement) {
33
33
  }
34
34
 
35
35
  // Component that throws an error when rendered
36
- function ThrowingComponent({ error }: { error: Error }) {
36
+ function ThrowingComponent({ error }: { error: Error }): React.ReactNode {
37
37
  throw error;
38
38
  }
39
39
 
@@ -124,7 +124,7 @@ describe("ErrorBoundary - Error catching", () => {
124
124
 
125
125
  // Verify onError callback was called with the error
126
126
  expect(onErrorMock).toHaveBeenCalled();
127
- const callArgs = onErrorMock.mock.calls[0];
127
+ const callArgs = (onErrorMock.mock.calls as unknown as [Error, unknown][])[0];
128
128
  expect(callArgs[0]).toBe(testError);
129
129
  } finally {
130
130
  root.unmount();
@@ -1,5 +1,21 @@
1
1
  import { test, expect, describe, beforeEach } from "bun:test";
2
2
  import { ComponentRegistry } from "./componentRegistry";
3
+ import type { ComponentDefinition, ComponentNode, PropDefinition } from "../shared/types";
4
+
5
+ /**
6
+ * Helper function to create a valid ComponentDefinition for tests
7
+ */
8
+ function createTestComponentDef(
9
+ structure?: ComponentNode,
10
+ componentInterface?: Record<string, PropDefinition>
11
+ ): ComponentDefinition {
12
+ return {
13
+ component: {
14
+ interface: componentInterface || {},
15
+ structure: structure || { type: "node" as const, tag: "div", children: [] }
16
+ }
17
+ };
18
+ }
3
19
 
4
20
  describe("ComponentRegistry", () => {
5
21
  let registry: ComponentRegistry;
@@ -10,10 +26,9 @@ describe("ComponentRegistry", () => {
10
26
 
11
27
  describe("register and get", () => {
12
28
  test("should register and retrieve a component", () => {
13
- const buttonDef = {
14
- type: "button",
15
- props: { className: "btn" }
16
- };
29
+ const buttonDef = createTestComponentDef(
30
+ { type: "node" as const, tag: "button", children: [], attributes: { className: "btn" } }
31
+ );
17
32
 
18
33
  registry.register("Button", buttonDef);
19
34
  const retrieved = registry.get("Button");
@@ -27,17 +42,25 @@ describe("ComponentRegistry", () => {
27
42
  });
28
43
 
29
44
  test("should overwrite existing component with same name", () => {
30
- registry.register("Button", { type: "button", props: { color: "red" } });
31
- registry.register("Button", { type: "button", props: { color: "blue" } });
45
+ registry.register("Button", createTestComponentDef(
46
+ { type: "node" as const, tag: "button", children: [], attributes: { color: "red" } }
47
+ ));
48
+ registry.register("Button", createTestComponentDef(
49
+ { type: "node" as const, tag: "button", children: [], attributes: { color: "blue" } }
50
+ ));
32
51
 
33
52
  const result = registry.get("Button");
34
- expect(result?.props.color).toBe("blue");
53
+ const structure = result?.component?.structure;
54
+ const attributes = structure && 'attributes' in structure ? structure.attributes as Record<string, unknown> : undefined;
55
+ expect(attributes?.color).toBe("blue");
35
56
  });
36
57
  });
37
58
 
38
59
  describe("has", () => {
39
60
  test("should return true for registered component", () => {
40
- registry.register("Card", { type: "div" });
61
+ registry.register("Card", createTestComponentDef(
62
+ { type: "node" as const, tag: "div", children: [] }
63
+ ));
41
64
  expect(registry.has("Card")).toBe(true);
42
65
  });
43
66
 
@@ -48,8 +71,12 @@ describe("ComponentRegistry", () => {
48
71
 
49
72
  describe("clear", () => {
50
73
  test("should clear all components", () => {
51
- registry.register("Button", { type: "button" });
52
- registry.register("Card", { type: "div" });
74
+ registry.register("Button", createTestComponentDef(
75
+ { type: "node" as const, tag: "button", children: [] }
76
+ ));
77
+ registry.register("Card", createTestComponentDef(
78
+ { type: "node" as const, tag: "div", children: [] }
79
+ ));
53
80
 
54
81
  expect(registry.getNames().length).toBe(2);
55
82
 
@@ -63,11 +90,13 @@ describe("ComponentRegistry", () => {
63
90
 
64
91
  describe("merge", () => {
65
92
  test("should merge multiple components", () => {
66
- registry.register("Button", { type: "button" });
93
+ registry.register("Button", createTestComponentDef(
94
+ { type: "node" as const, tag: "button", children: [] }
95
+ ));
67
96
 
68
97
  registry.merge({
69
- Card: { type: "div" },
70
- Link: { type: "a" }
98
+ Card: createTestComponentDef({ type: "node" as const, tag: "div", children: [] }),
99
+ Link: createTestComponentDef({ type: "node" as const, tag: "a", children: [] })
71
100
  });
72
101
 
73
102
  expect(registry.getNames().length).toBe(3);
@@ -77,21 +106,31 @@ describe("ComponentRegistry", () => {
77
106
  });
78
107
 
79
108
  test("should overwrite existing components when merging", () => {
80
- registry.register("Button", { type: "button", props: { color: "red" } });
109
+ registry.register("Button", createTestComponentDef(
110
+ { type: "node" as const, tag: "button", children: [], attributes: { color: "red" } }
111
+ ));
81
112
 
82
113
  registry.merge({
83
- Button: { type: "button", props: { color: "blue" } }
114
+ Button: createTestComponentDef(
115
+ { type: "node" as const, tag: "button", children: [], attributes: { color: "blue" } }
116
+ )
84
117
  });
85
118
 
86
119
  const button = registry.get("Button");
87
- expect(button?.props.color).toBe("blue");
120
+ const structure = button?.component?.structure;
121
+ const attributes = structure && 'attributes' in structure ? structure.attributes as Record<string, unknown> : undefined;
122
+ expect(attributes?.color).toBe("blue");
88
123
  });
89
124
  });
90
125
 
91
126
  describe("getAll", () => {
92
127
  test("should return all registered components", () => {
93
- registry.register("Button", { type: "button" });
94
- registry.register("Card", { type: "div" });
128
+ registry.register("Button", createTestComponentDef(
129
+ { type: "node" as const, tag: "button", children: [] }
130
+ ));
131
+ registry.register("Card", createTestComponentDef(
132
+ { type: "node" as const, tag: "div", children: [] }
133
+ ));
95
134
 
96
135
  const all = registry.getAll();
97
136
 
@@ -101,10 +140,14 @@ describe("ComponentRegistry", () => {
101
140
  });
102
141
 
103
142
  test("should return a copy, not the original registry", () => {
104
- registry.register("Button", { type: "button" });
143
+ registry.register("Button", createTestComponentDef(
144
+ { type: "node" as const, tag: "button", children: [] }
145
+ ));
105
146
 
106
147
  const all = registry.getAll();
107
- all.NewComponent = { type: "span" };
148
+ all.NewComponent = createTestComponentDef(
149
+ { type: "node" as const, tag: "span", children: [] }
150
+ );
108
151
 
109
152
  expect(registry.has("NewComponent")).toBe(false);
110
153
  });
@@ -112,8 +155,12 @@ describe("ComponentRegistry", () => {
112
155
 
113
156
  describe("getNames", () => {
114
157
  test("should return list of component names", () => {
115
- registry.register("Button", { type: "button" });
116
- registry.register("Card", { type: "div" });
158
+ registry.register("Button", createTestComponentDef(
159
+ { type: "node" as const, tag: "button", children: [] }
160
+ ));
161
+ registry.register("Card", createTestComponentDef(
162
+ { type: "node" as const, tag: "div", children: [] }
163
+ ));
117
164
 
118
165
  const names = registry.getNames();
119
166
 
@@ -128,7 +175,9 @@ describe("ComponentRegistry", () => {
128
175
 
129
176
  describe("remove", () => {
130
177
  test("should remove a component and return true", () => {
131
- registry.register("Button", { type: "button" });
178
+ registry.register("Button", createTestComponentDef(
179
+ { type: "node" as const, tag: "button", children: [] }
180
+ ));
132
181
 
133
182
  const result = registry.remove("Button");
134
183
 
@@ -142,23 +191,20 @@ describe("ComponentRegistry", () => {
142
191
  });
143
192
  });
144
193
 
145
- describe("component with variants", () => {
146
- test("should handle components with variant definitions", () => {
147
- const buttonDef = {
148
- type: "button",
149
- variants: {
150
- primary: { backgroundColor: "blue", color: "white" },
151
- secondary: { backgroundColor: "gray", color: "black" }
152
- },
153
- defaultVariant: "primary"
194
+ describe("component with category", () => {
195
+ test("should handle components with category definitions", () => {
196
+ const buttonDef: ComponentDefinition = {
197
+ component: {
198
+ interface: {},
199
+ structure: { type: "node" as const, tag: "button", children: [] },
200
+ category: "buttons"
201
+ }
154
202
  };
155
203
 
156
204
  registry.register("Button", buttonDef);
157
205
  const retrieved = registry.get("Button");
158
206
 
159
- expect(retrieved?.variants?.primary).toBeDefined();
160
- expect(retrieved?.variants?.primary?.backgroundColor).toBe("blue");
161
- expect(retrieved?.defaultVariant).toBe("primary");
207
+ expect(retrieved?.component?.category).toBe("buttons");
162
208
  });
163
209
  });
164
210
  });
@@ -3,22 +3,19 @@ import { ComponentBuilder } from "./ComponentBuilder";
3
3
  import { ComponentRegistry } from "../componentRegistry";
4
4
  import { ElementRegistry } from "../elementRegistry";
5
5
  import type { ComponentNode, CMSListNode, CMSItem } from "../../shared/types";
6
- import type { HighlightManager } from "../highlightManager";
7
6
  import { NODE_TYPE } from "../../shared/constants";
8
- import { createMockHighlightManager, createMockElementRegistry } from "../../test-utils/mocks";
7
+ import { createMockElementRegistry } from "../../test-utils/mocks";
9
8
 
10
9
  // Note: Using typed mocks from test-utils/mocks instead of inline 'as any' casts
11
10
 
12
11
  describe("ComponentBuilder", () => {
13
12
  let componentRegistry: ComponentRegistry;
14
- let hoverHighlightManager: HighlightManager;
15
13
  let elementRegistry: ElementRegistry;
16
14
  let builder: ComponentBuilder;
17
15
  let registeredPaths: Array<{ path: string; tag?: string }>;
18
16
 
19
17
  beforeEach(() => {
20
18
  componentRegistry = new ComponentRegistry();
21
- hoverHighlightManager = createMockHighlightManager();
22
19
  registeredPaths = [];
23
20
 
24
21
  // Create mock element registry with path tracking
@@ -31,7 +28,6 @@ describe("ComponentBuilder", () => {
31
28
 
32
29
  builder = new ComponentBuilder({
33
30
  componentRegistry,
34
- hoverHighlightManager,
35
31
  elementRegistry,
36
32
  });
37
33
  });
@@ -711,7 +707,7 @@ describe("ComponentBuilder", () => {
711
707
  ]);
712
708
 
713
709
  const result = builder.buildComponent({
714
- node,
710
+ node: node as unknown as ComponentNode,
715
711
  collectionItemsMap: { posts: items },
716
712
  });
717
713
 
@@ -730,7 +726,7 @@ describe("ComponentBuilder", () => {
730
726
  ]);
731
727
 
732
728
  const result = builder.buildComponent({
733
- node,
729
+ node: node as unknown as ComponentNode,
734
730
  collectionItemsMap: { posts: items },
735
731
  });
736
732
 
@@ -758,7 +754,7 @@ describe("ComponentBuilder", () => {
758
754
  ]);
759
755
 
760
756
  const result = builder.buildComponent({
761
- node,
757
+ node: node as unknown as ComponentNode,
762
758
  collectionItemsMap: { posts: items },
763
759
  });
764
760
 
@@ -774,7 +770,7 @@ describe("ComponentBuilder", () => {
774
770
  ]);
775
771
 
776
772
  const result = builder.buildComponent({
777
- node,
773
+ node: node as unknown as ComponentNode,
778
774
  collectionItemsMap: { posts: items },
779
775
  });
780
776
 
@@ -791,7 +787,7 @@ describe("ComponentBuilder", () => {
791
787
  ]);
792
788
 
793
789
  const result = builder.buildComponent({
794
- node,
790
+ node: node as unknown as ComponentNode,
795
791
  collectionItemsMap: { posts: [] },
796
792
  });
797
793
 
@@ -808,7 +804,7 @@ describe("ComponentBuilder", () => {
808
804
  ]);
809
805
 
810
806
  const result = builder.buildComponent({
811
- node,
807
+ node: node as unknown as ComponentNode,
812
808
  collectionItemsMap: {}, // No posts collection
813
809
  });
814
810
 
@@ -823,7 +819,7 @@ describe("ComponentBuilder", () => {
823
819
  ], { limit: 2 });
824
820
 
825
821
  const result = builder.buildComponent({
826
- node,
822
+ node: node as unknown as ComponentNode,
827
823
  collectionItemsMap: { posts: items },
828
824
  });
829
825
 
@@ -840,7 +836,7 @@ describe("ComponentBuilder", () => {
840
836
  ], { offset: 2 });
841
837
 
842
838
  const result = builder.buildComponent({
843
- node,
839
+ node: node as unknown as ComponentNode,
844
840
  collectionItemsMap: { posts: items },
845
841
  });
846
842
 
@@ -857,7 +853,7 @@ describe("ComponentBuilder", () => {
857
853
  ], { offset: 1, limit: 2 });
858
854
 
859
855
  const result = builder.buildComponent({
860
- node,
856
+ node: node as unknown as ComponentNode,
861
857
  collectionItemsMap: { posts: items },
862
858
  });
863
859
 
@@ -924,7 +920,6 @@ describe("ComponentBuilder", () => {
924
920
  // Create builder with page name getter
925
921
  const pageBuilder = new ComponentBuilder({
926
922
  componentRegistry,
927
- hoverHighlightManager,
928
923
  elementRegistry,
929
924
  getCurrentPageName: () => "about",
930
925
  getCurrentFileType: () => "page",
@@ -1005,7 +1000,7 @@ describe("ComponentBuilder", () => {
1005
1000
 
1006
1001
  const result1 = builder.buildComponent({
1007
1002
  node: node1,
1008
- path: [0],
1003
+ elementPath: [0],
1009
1004
  });
1010
1005
 
1011
1006
  expect(result1).not.toBeNull();
@@ -1013,7 +1008,7 @@ describe("ComponentBuilder", () => {
1013
1008
  // Second instance at page path [1, 2, 3]
1014
1009
  const result2 = builder.buildComponent({
1015
1010
  node: node1,
1016
- path: [1, 2, 3],
1011
+ elementPath: [1, 2, 3],
1017
1012
  });
1018
1013
 
1019
1014
  expect(result2).not.toBeNull();
@@ -1055,7 +1050,6 @@ describe("ComponentBuilder", () => {
1055
1050
  // Page element with same name
1056
1051
  const pageBuilder = new ComponentBuilder({
1057
1052
  componentRegistry,
1058
- hoverHighlightManager,
1059
1053
  elementRegistry,
1060
1054
  getCurrentPageName: () => "button",
1061
1055
  getCurrentFileType: () => "page",