meno-core 1.0.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.
Files changed (231) hide show
  1. package/bin/cli.ts +281 -0
  2. package/build-static.ts +298 -0
  3. package/bunfig.toml +39 -0
  4. package/entries/client-router.tsx +111 -0
  5. package/entries/server-router.tsx +71 -0
  6. package/lib/client/ClientInitializer.test.ts +9 -0
  7. package/lib/client/ClientInitializer.test.ts.skip +92 -0
  8. package/lib/client/ClientInitializer.ts +60 -0
  9. package/lib/client/ErrorBoundary.test.tsx +595 -0
  10. package/lib/client/ErrorBoundary.tsx +230 -0
  11. package/lib/client/componentRegistry.test.ts +165 -0
  12. package/lib/client/componentRegistry.ts +18 -0
  13. package/lib/client/contexts/ThemeContext.tsx +73 -0
  14. package/lib/client/core/ComponentBuilder.test.ts +677 -0
  15. package/lib/client/core/ComponentBuilder.ts +660 -0
  16. package/lib/client/core/ComponentRenderer.test.tsx +176 -0
  17. package/lib/client/core/ComponentRenderer.tsx +83 -0
  18. package/lib/client/core/cmsTemplateProcessor.ts +129 -0
  19. package/lib/client/elementRegistry.ts +81 -0
  20. package/lib/client/hmr/HMRManager.tsx +179 -0
  21. package/lib/client/hmr/index.ts +5 -0
  22. package/lib/client/hmrWebSocket.test.ts +9 -0
  23. package/lib/client/hmrWebSocket.ts +250 -0
  24. package/lib/client/hooks/useColorVariables.test.ts +166 -0
  25. package/lib/client/hooks/useColorVariables.ts +249 -0
  26. package/lib/client/hooks/usePropertyAutocomplete.test.ts +9 -0
  27. package/lib/client/hooks/usePropertyAutocomplete.ts +40 -0
  28. package/lib/client/hydration/HydrationUtils.test.ts +154 -0
  29. package/lib/client/hydration/HydrationUtils.ts +35 -0
  30. package/lib/client/i18nConfigService.test.ts +74 -0
  31. package/lib/client/i18nConfigService.ts +78 -0
  32. package/lib/client/index.ts +56 -0
  33. package/lib/client/navigation.test.ts +441 -0
  34. package/lib/client/navigation.ts +23 -0
  35. package/lib/client/responsiveStyleResolver.test.ts +491 -0
  36. package/lib/client/responsiveStyleResolver.ts +184 -0
  37. package/lib/client/routing/RouteLoader.test.ts +635 -0
  38. package/lib/client/routing/RouteLoader.ts +347 -0
  39. package/lib/client/routing/Router.tsx +382 -0
  40. package/lib/client/scripts/ScriptExecutor.test.ts +489 -0
  41. package/lib/client/scripts/ScriptExecutor.ts +171 -0
  42. package/lib/client/scripts/formHandler.ts +103 -0
  43. package/lib/client/styleProcessor.test.ts +126 -0
  44. package/lib/client/styleProcessor.ts +92 -0
  45. package/lib/client/styles/StyleInjector.test.ts +354 -0
  46. package/lib/client/styles/StyleInjector.ts +154 -0
  47. package/lib/client/templateEngine.test.ts +660 -0
  48. package/lib/client/templateEngine.ts +667 -0
  49. package/lib/client/theme.test.ts +173 -0
  50. package/lib/client/theme.ts +159 -0
  51. package/lib/client/utils/toast.ts +46 -0
  52. package/lib/server/createServer.ts +170 -0
  53. package/lib/server/cssGenerator.test.ts +172 -0
  54. package/lib/server/cssGenerator.ts +58 -0
  55. package/lib/server/fileWatcher.ts +134 -0
  56. package/lib/server/index.ts +55 -0
  57. package/lib/server/jsonLoader.test.ts +103 -0
  58. package/lib/server/jsonLoader.ts +350 -0
  59. package/lib/server/middleware/cors.test.ts +177 -0
  60. package/lib/server/middleware/cors.ts +69 -0
  61. package/lib/server/middleware/errorHandler.test.ts +208 -0
  62. package/lib/server/middleware/errorHandler.ts +63 -0
  63. package/lib/server/middleware/index.ts +9 -0
  64. package/lib/server/middleware/logger.test.ts +233 -0
  65. package/lib/server/middleware/logger.ts +99 -0
  66. package/lib/server/pageCache.test.ts +167 -0
  67. package/lib/server/pageCache.ts +97 -0
  68. package/lib/server/projectContext.ts +51 -0
  69. package/lib/server/providers/fileSystemCMSProvider.test.ts +292 -0
  70. package/lib/server/providers/fileSystemCMSProvider.ts +227 -0
  71. package/lib/server/providers/fileSystemPageProvider.ts +83 -0
  72. package/lib/server/routes/api/cms.test.ts +177 -0
  73. package/lib/server/routes/api/cms.ts +82 -0
  74. package/lib/server/routes/api/colors.ts +59 -0
  75. package/lib/server/routes/api/components.ts +70 -0
  76. package/lib/server/routes/api/config.test.ts +9 -0
  77. package/lib/server/routes/api/config.ts +28 -0
  78. package/lib/server/routes/api/core-routes.ts +182 -0
  79. package/lib/server/routes/api/functions.ts +170 -0
  80. package/lib/server/routes/api/index.ts +69 -0
  81. package/lib/server/routes/api/pages.ts +95 -0
  82. package/lib/server/routes/api/shared.test.ts +81 -0
  83. package/lib/server/routes/api/shared.ts +31 -0
  84. package/lib/server/routes/editor.test.ts +9 -0
  85. package/lib/server/routes/index.ts +104 -0
  86. package/lib/server/routes/pages.ts +161 -0
  87. package/lib/server/routes/static.ts +107 -0
  88. package/lib/server/services/ColorService.ts +193 -0
  89. package/lib/server/services/cmsService.test.ts +388 -0
  90. package/lib/server/services/cmsService.ts +296 -0
  91. package/lib/server/services/componentService.test.ts +276 -0
  92. package/lib/server/services/componentService.ts +346 -0
  93. package/lib/server/services/configService.ts +156 -0
  94. package/lib/server/services/fileWatcherService.ts +67 -0
  95. package/lib/server/services/index.ts +10 -0
  96. package/lib/server/services/pageService.test.ts +258 -0
  97. package/lib/server/services/pageService.ts +240 -0
  98. package/lib/server/ssrRenderer.test.ts +1005 -0
  99. package/lib/server/ssrRenderer.ts +878 -0
  100. package/lib/server/utilityClassGenerator.ts +11 -0
  101. package/lib/server/utils/index.ts +5 -0
  102. package/lib/server/utils/jsonLineMapper.test.ts +100 -0
  103. package/lib/server/utils/jsonLineMapper.ts +166 -0
  104. package/lib/server/validateStyleCoverage.test.ts +9 -0
  105. package/lib/server/validateStyleCoverage.ts +167 -0
  106. package/lib/server/websocketManager.test.ts +9 -0
  107. package/lib/server/websocketManager.ts +95 -0
  108. package/lib/shared/attributeNodeUtils.test.ts +152 -0
  109. package/lib/shared/attributeNodeUtils.ts +50 -0
  110. package/lib/shared/breakpoints.test.ts +166 -0
  111. package/lib/shared/breakpoints.ts +65 -0
  112. package/lib/shared/colorProperties.test.ts +111 -0
  113. package/lib/shared/colorProperties.ts +40 -0
  114. package/lib/shared/colorVariableUtils.test.ts +319 -0
  115. package/lib/shared/colorVariableUtils.ts +97 -0
  116. package/lib/shared/constants.test.ts +175 -0
  117. package/lib/shared/constants.ts +116 -0
  118. package/lib/shared/cssGeneration.ts +481 -0
  119. package/lib/shared/cssProperties.test.ts +252 -0
  120. package/lib/shared/cssProperties.ts +338 -0
  121. package/lib/shared/elementUtils.test.ts +245 -0
  122. package/lib/shared/elementUtils.ts +90 -0
  123. package/lib/shared/fontLoader.ts +97 -0
  124. package/lib/shared/i18n.test.ts +313 -0
  125. package/lib/shared/i18n.ts +286 -0
  126. package/lib/shared/index.ts +50 -0
  127. package/lib/shared/interfaces/contentProvider.test.ts +9 -0
  128. package/lib/shared/interfaces/contentProvider.ts +121 -0
  129. package/lib/shared/nodeUtils.test.ts +320 -0
  130. package/lib/shared/nodeUtils.ts +220 -0
  131. package/lib/shared/pathArrayUtils.test.ts +315 -0
  132. package/lib/shared/pathArrayUtils.ts +17 -0
  133. package/lib/shared/pathUtils.test.ts +260 -0
  134. package/lib/shared/pathUtils.ts +244 -0
  135. package/lib/shared/paths/Path.test.ts +74 -0
  136. package/lib/shared/paths/Path.ts +23 -0
  137. package/lib/shared/paths/PathConverter.test.ts +232 -0
  138. package/lib/shared/paths/PathConverter.ts +141 -0
  139. package/lib/shared/paths/PathUtils.ts +290 -0
  140. package/lib/shared/paths/PathValidator.test.ts +193 -0
  141. package/lib/shared/paths/PathValidator.ts +53 -0
  142. package/lib/shared/paths/index.ts +48 -0
  143. package/lib/shared/propResolver.test.ts +639 -0
  144. package/lib/shared/propResolver.ts +124 -0
  145. package/lib/shared/registry/BaseNodeTypeRegistry.test.ts +190 -0
  146. package/lib/shared/registry/BaseNodeTypeRegistry.ts +200 -0
  147. package/lib/shared/registry/ClientNodeTypeRegistry.ts +34 -0
  148. package/lib/shared/registry/ClientRegistry.test.ts +26 -0
  149. package/lib/shared/registry/ClientRegistry.ts +15 -0
  150. package/lib/shared/registry/ComponentRegistry.test.ts +293 -0
  151. package/lib/shared/registry/ComponentRegistry.ts +100 -0
  152. package/lib/shared/registry/NodeTypeDefinition.ts +198 -0
  153. package/lib/shared/registry/NodeTypeManager.ts +94 -0
  154. package/lib/shared/registry/RegistryManager.test.ts +58 -0
  155. package/lib/shared/registry/RegistryManager.ts +60 -0
  156. package/lib/shared/registry/SSRNodeTypeRegistry.ts +33 -0
  157. package/lib/shared/registry/SSRRegistry.test.ts +26 -0
  158. package/lib/shared/registry/SSRRegistry.ts +15 -0
  159. package/lib/shared/registry/createNodeType.ts +175 -0
  160. package/lib/shared/registry/defineNodeType.ts +73 -0
  161. package/lib/shared/registry/fieldPresets.ts +109 -0
  162. package/lib/shared/registry/index.ts +50 -0
  163. package/lib/shared/registry/nodeTypes/ComponentInstanceNodeType.ts +71 -0
  164. package/lib/shared/registry/nodeTypes/EmbedNodeType.ts +61 -0
  165. package/lib/shared/registry/nodeTypes/HtmlNodeType.ts +88 -0
  166. package/lib/shared/registry/nodeTypes/LocaleListNodeType.ts +66 -0
  167. package/lib/shared/registry/nodeTypes/ObjectLinkNodeType.ts +75 -0
  168. package/lib/shared/registry/nodeTypes/SlotMarkerType.ts +49 -0
  169. package/lib/shared/registry/nodeTypes/TextNodeType.ts +52 -0
  170. package/lib/shared/registry/nodeTypes/index.ts +75 -0
  171. package/lib/shared/responsiveScaling.test.ts +268 -0
  172. package/lib/shared/responsiveScaling.ts +194 -0
  173. package/lib/shared/responsiveStyleUtils.test.ts +300 -0
  174. package/lib/shared/responsiveStyleUtils.ts +139 -0
  175. package/lib/shared/slugTranslator.test.ts +325 -0
  176. package/lib/shared/slugTranslator.ts +177 -0
  177. package/lib/shared/styleNodeUtils.test.ts +132 -0
  178. package/lib/shared/styleNodeUtils.ts +102 -0
  179. package/lib/shared/styleUtils.test.ts +238 -0
  180. package/lib/shared/styleUtils.ts +63 -0
  181. package/lib/shared/themeDefaults.test.ts +113 -0
  182. package/lib/shared/themeDefaults.ts +103 -0
  183. package/lib/shared/tree/PathBuilder.ts +383 -0
  184. package/lib/shared/treePathUtils.test.ts +539 -0
  185. package/lib/shared/treePathUtils.ts +339 -0
  186. package/lib/shared/types/api.ts +58 -0
  187. package/lib/shared/types/cms.ts +95 -0
  188. package/lib/shared/types/colors.ts +45 -0
  189. package/lib/shared/types/components.ts +121 -0
  190. package/lib/shared/types/errors.test.ts +103 -0
  191. package/lib/shared/types/errors.ts +69 -0
  192. package/lib/shared/types/index.ts +96 -0
  193. package/lib/shared/types/nodes.ts +20 -0
  194. package/lib/shared/types/rendering.ts +61 -0
  195. package/lib/shared/types/styles.ts +38 -0
  196. package/lib/shared/types.ts +11 -0
  197. package/lib/shared/utilityClassConfig.ts +287 -0
  198. package/lib/shared/utilityClassMapper.test.ts +140 -0
  199. package/lib/shared/utilityClassMapper.ts +229 -0
  200. package/lib/shared/utils/fileUtils.test.ts +99 -0
  201. package/lib/shared/utils/fileUtils.ts +56 -0
  202. package/lib/shared/utils.test.ts +261 -0
  203. package/lib/shared/utils.ts +84 -0
  204. package/lib/shared/validation/index.ts +7 -0
  205. package/lib/shared/validation/propValidator.test.ts +178 -0
  206. package/lib/shared/validation/propValidator.ts +238 -0
  207. package/lib/shared/validation/schemas.test.ts +177 -0
  208. package/lib/shared/validation/schemas.ts +401 -0
  209. package/lib/shared/validation/validators.test.ts +109 -0
  210. package/lib/shared/validation/validators.ts +304 -0
  211. package/lib/test-utils/dom-setup.ts +55 -0
  212. package/lib/test-utils/factories/ConsoleMockFactory.ts +200 -0
  213. package/lib/test-utils/factories/DomMockFactory.ts +487 -0
  214. package/lib/test-utils/factories/EventMockFactory.ts +244 -0
  215. package/lib/test-utils/factories/FetchMockFactory.ts +210 -0
  216. package/lib/test-utils/factories/ServerMockFactory.ts +223 -0
  217. package/lib/test-utils/factories/StoreMockFactory.ts +370 -0
  218. package/lib/test-utils/factories/index.ts +11 -0
  219. package/lib/test-utils/fixtures.ts +134 -0
  220. package/lib/test-utils/helpers/asyncHelpers.test.ts +112 -0
  221. package/lib/test-utils/helpers/asyncHelpers.ts +196 -0
  222. package/lib/test-utils/helpers/index.ts +6 -0
  223. package/lib/test-utils/helpers.test.ts +73 -0
  224. package/lib/test-utils/helpers.ts +90 -0
  225. package/lib/test-utils/index.ts +17 -0
  226. package/lib/test-utils/mockFactories.ts +92 -0
  227. package/lib/test-utils/mocks.ts +341 -0
  228. package/package.json +38 -0
  229. package/templates/index-router.html +34 -0
  230. package/tsconfig.json +14 -0
  231. package/vite.config.ts +43 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Embed Node Type Definition
3
+ * Renders custom HTML/SVG content
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { createElement as h } from 'react';
8
+ import { StyleValueSchema } from '../../validation/schemas';
9
+ import { createNodeType } from '../createNodeType';
10
+ import { textareaField } from '../fieldPresets';
11
+
12
+ // Schema is the SINGLE source of truth
13
+ const EmbedNodeSchemaInternal = z.object({
14
+ type: z.literal('embed'),
15
+ html: z.string(),
16
+ style: StyleValueSchema.optional(),
17
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
18
+ }).passthrough();
19
+
20
+ // TypeScript type inferred from schema
21
+ export type EmbedNode = z.infer<typeof EmbedNodeSchemaInternal>;
22
+
23
+ // Export schema for validation/schemas.ts
24
+ export const EmbedNodeSchema = EmbedNodeSchemaInternal;
25
+
26
+ export const EmbedNodeType = createNodeType({
27
+ type: 'embed',
28
+ displayName: 'Embed',
29
+ category: 'content',
30
+ schema: EmbedNodeSchemaInternal,
31
+
32
+ defaultValues: {
33
+ html: '',
34
+ style: { base: {} },
35
+ },
36
+
37
+ treeDisplay: {
38
+ icon: 'HTML_ELEMENT',
39
+ getLabel: () => 'Embed',
40
+ },
41
+
42
+ editableFields: [
43
+ textareaField({ name: 'html', label: 'HTML Content', required: true, placeholder: '<svg>...</svg>' }),
44
+ ],
45
+
46
+ clientRenderer: (node, context) => {
47
+ return h('div', {
48
+ key: context.key,
49
+ dangerouslySetInnerHTML: { __html: node.html },
50
+ });
51
+ },
52
+
53
+ ssrRenderer: (node, _context) => {
54
+ return `<div>${node.html}</div>`;
55
+ },
56
+
57
+ capabilities: {
58
+ canHaveChildren: false,
59
+ requiresProps: ['html'],
60
+ },
61
+ });
@@ -0,0 +1,88 @@
1
+ /**
2
+ * HTML Node Type Definition
3
+ * HTML element nodes (div, span, header, etc.)
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { createElement as h } from 'react';
8
+ import { StyleValueSchema } from '../../validation/schemas';
9
+ import { createNodeType } from '../createNodeType';
10
+
11
+ // Forward reference for ComponentNode schema (recursive)
12
+ const ComponentNodeSchemaRef: z.ZodType<any> = z.lazy(() => z.any());
13
+
14
+ // Schema is the SINGLE source of truth
15
+ const HtmlNodeSchemaInternal = z.object({
16
+ type: z.literal('node'),
17
+ tag: z.string(),
18
+ style: StyleValueSchema.optional(),
19
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
20
+ props: z.record(z.string(), z.any()).optional(), // Backward compatibility
21
+ children: z.union([
22
+ z.array(z.union([ComponentNodeSchemaRef, z.string()])),
23
+ z.string(),
24
+ ]).optional(),
25
+ }).passthrough();
26
+
27
+ // TypeScript type inferred from schema
28
+ export type HtmlNode = z.infer<typeof HtmlNodeSchemaInternal>;
29
+
30
+ // Export schema for validation/schemas.ts
31
+ export const HtmlNodeSchema = HtmlNodeSchemaInternal;
32
+
33
+ export const HtmlNodeType = createNodeType({
34
+ type: 'node',
35
+ displayName: 'HTML Element',
36
+ category: 'core',
37
+ schema: HtmlNodeSchemaInternal,
38
+
39
+ defaultValues: {
40
+ tag: 'div',
41
+ style: { base: {} },
42
+ children: [],
43
+ },
44
+
45
+ treeDisplay: {
46
+ icon: 'HTML_ELEMENT',
47
+ getLabel: (node) => node.tag,
48
+ },
49
+
50
+ clientRenderer: (node, context) => {
51
+ const props: Record<string, any> = { key: context.key };
52
+
53
+ // Prevent form submission in editor
54
+ if (node.tag === 'form') {
55
+ props.onSubmit = (e: React.FormEvent) => e.preventDefault();
56
+ }
57
+
58
+ // Void elements cannot have children
59
+ const voidElements = ['img', 'br', 'hr', 'input', 'meta', 'link', 'area', 'base', 'col', 'embed', 'param', 'source', 'track', 'wbr'];
60
+ if (voidElements.includes(node.tag.toLowerCase())) {
61
+ return h(node.tag, props);
62
+ }
63
+
64
+ const children = context.buildChildren(
65
+ node.children as any,
66
+ context.elementPath,
67
+ context.parentComponentName,
68
+ context.componentContext
69
+ );
70
+
71
+ return h(node.tag, props, children);
72
+ },
73
+
74
+ ssrRenderer: (node, context) => {
75
+ const childrenHTML = context.renderChildren(node.children as any, context);
76
+ // Void elements don't have closing tags
77
+ const voidElements = ['img', 'br', 'hr', 'input', 'meta', 'link', 'area', 'base', 'col', 'embed', 'param', 'source', 'track', 'wbr'];
78
+ if (voidElements.includes(node.tag.toLowerCase())) {
79
+ return `<${node.tag} />`;
80
+ }
81
+ return `<${node.tag}>${childrenHTML}</${node.tag}>`;
82
+ },
83
+
84
+ capabilities: {
85
+ canHaveChildren: true,
86
+ requiresProps: ['tag'],
87
+ },
88
+ });
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Locale List Node Type Definition
3
+ * Renders locale switcher links
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { createElement as h } from 'react';
8
+ import { StyleValueSchema } from '../../validation/schemas';
9
+ import { createNodeType } from '../createNodeType';
10
+
11
+ // Schema is the SINGLE source of truth
12
+ const LocaleListNodeSchemaInternal = z.object({
13
+ type: z.literal('locale-list'),
14
+ style: StyleValueSchema.optional(),
15
+ itemStyle: StyleValueSchema.optional(),
16
+ activeItemStyle: StyleValueSchema.optional(),
17
+ separatorStyle: StyleValueSchema.optional(),
18
+ showCurrent: z.boolean().optional(),
19
+ showSeparator: z.boolean().optional(),
20
+ showFlag: z.boolean().optional(),
21
+ flagStyle: StyleValueSchema.optional(),
22
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
23
+ }).passthrough();
24
+
25
+ // TypeScript type inferred from schema
26
+ export type LocaleListNode = z.infer<typeof LocaleListNodeSchemaInternal>;
27
+
28
+ // Export schema for validation/schemas.ts
29
+ export const LocaleListNodeSchema = LocaleListNodeSchemaInternal;
30
+
31
+ export const LocaleListNodeType = createNodeType({
32
+ type: 'locale-list',
33
+ displayName: 'LocaleList',
34
+ category: 'special',
35
+ schema: LocaleListNodeSchemaInternal,
36
+
37
+ defaultValues: {
38
+ style: { base: {} },
39
+ showCurrent: true,
40
+ showSeparator: true,
41
+ showFlag: true,
42
+ },
43
+
44
+ treeDisplay: {
45
+ icon: 'HTML_ELEMENT',
46
+ getLabel: () => 'LocaleList',
47
+ },
48
+
49
+ clientRenderer: (_node, context) => {
50
+ // In editor, shows placeholder
51
+ return h('div', {
52
+ key: context.key,
53
+ 'data-locale-list': 'true',
54
+ }, '[Locale List]');
55
+ },
56
+
57
+ ssrRenderer: (_node, _context) => {
58
+ // Placeholder - full implementation renders actual locale links
59
+ return '<div class="locale-list">[Locale List]</div>';
60
+ },
61
+
62
+ capabilities: {
63
+ canHaveChildren: false,
64
+ requiresProps: [],
65
+ },
66
+ });
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Object Link Node Type Definition
3
+ * Renders as div in editor, <a> tag in SSR
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { createElement as h } from 'react';
8
+ import { StyleValueSchema, LinkMappingSchema } from '../../validation/schemas';
9
+ import { createNodeType } from '../createNodeType';
10
+ import { urlField } from '../fieldPresets';
11
+
12
+ // Forward reference for ComponentNode schema (recursive)
13
+ // This will be resolved when schemas.ts imports this and builds the union
14
+ const ComponentNodeSchemaRef: z.ZodType<any> = z.lazy(() => z.any());
15
+
16
+ // Schema is the SINGLE source of truth
17
+ const ObjectLinkNodeSchemaInternal = z.object({
18
+ type: z.literal('object-link'),
19
+ href: z.union([z.string(), LinkMappingSchema]),
20
+ style: StyleValueSchema.optional(),
21
+ attributes: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
22
+ children: z.union([
23
+ z.array(z.union([ComponentNodeSchemaRef, z.string()])),
24
+ z.string(),
25
+ ]).optional(),
26
+ }).passthrough();
27
+
28
+ // TypeScript type inferred from schema
29
+ export type ObjectLinkNode = z.infer<typeof ObjectLinkNodeSchemaInternal>;
30
+
31
+ // Export schema for validation/schemas.ts
32
+ export const ObjectLinkNodeSchema = ObjectLinkNodeSchemaInternal;
33
+
34
+ export const ObjectLinkNodeType = createNodeType({
35
+ type: 'object-link',
36
+ displayName: 'Link',
37
+ category: 'content',
38
+ schema: ObjectLinkNodeSchemaInternal,
39
+
40
+ defaultValues: {
41
+ href: '#',
42
+ style: { base: {} },
43
+ children: [],
44
+ },
45
+
46
+ treeDisplay: {
47
+ icon: 'HTML_ELEMENT',
48
+ getLabel: () => 'Link',
49
+ },
50
+
51
+ editableFields: [
52
+ urlField({ name: 'href', label: 'Link URL', required: true }),
53
+ ],
54
+
55
+ clientRenderer: (node, context) => {
56
+ const children = context.buildChildren(
57
+ node.children as any,
58
+ context.elementPath,
59
+ context.parentComponentName,
60
+ context.componentContext
61
+ );
62
+ return h('div', { key: context.key }, children);
63
+ },
64
+
65
+ ssrRenderer: (node, context) => {
66
+ const href = typeof node.href === 'string' ? node.href : '#';
67
+ const childrenHTML = context.renderChildren(node.children as any, context);
68
+ return `<a href="${context.escapeHtml(href)}" class="olink">${childrenHTML}</a>`;
69
+ },
70
+
71
+ capabilities: {
72
+ canHaveChildren: true,
73
+ requiresProps: ['href'],
74
+ },
75
+ });
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Slot Marker Node Type Definition
3
+ * Indicates where instance children should be placed in a component
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { createNodeType } from '../createNodeType';
8
+
9
+ // Schema is the SINGLE source of truth
10
+ const SlotMarkerSchemaInternal = z.object({
11
+ type: z.literal('slot'),
12
+ }).passthrough();
13
+
14
+ // TypeScript type inferred from schema
15
+ export type SlotMarker = z.infer<typeof SlotMarkerSchemaInternal>;
16
+
17
+ // Export schema for validation/schemas.ts
18
+ export const SlotMarkerSchema = SlotMarkerSchemaInternal;
19
+
20
+ export const SlotMarkerType = createNodeType({
21
+ type: 'slot',
22
+ displayName: 'Slot',
23
+ category: 'special',
24
+ schema: SlotMarkerSchemaInternal,
25
+
26
+ defaultValues: {},
27
+
28
+ treeDisplay: {
29
+ icon: 'SLOT_MARKER',
30
+ getLabel: () => 'slot',
31
+ },
32
+
33
+ clientRenderer: (_node, _context) => {
34
+ // Slot markers are replaced with instance children during component rendering
35
+ return null;
36
+ },
37
+
38
+ ssrRenderer: (_node, _context) => {
39
+ // Slot markers are replaced with instance children during component rendering
40
+ return '';
41
+ },
42
+
43
+ capabilities: {
44
+ canHaveChildren: false,
45
+ canHaveStyle: false,
46
+ canHaveAttributes: false,
47
+ requiresProps: [],
48
+ },
49
+ });
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Text Node Type Definition
3
+ * Static text content in component structures
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { createNodeType } from '../createNodeType';
8
+
9
+ // Schema is the SINGLE source of truth
10
+ const TextNodeSchemaInternal = z.object({
11
+ type: z.literal('text'),
12
+ value: z.string(),
13
+ }).passthrough();
14
+
15
+ // TypeScript type inferred from schema
16
+ export type TextNode = z.infer<typeof TextNodeSchemaInternal>;
17
+
18
+ // Export schema for validation/schemas.ts
19
+ export const TextNodeSchema = TextNodeSchemaInternal;
20
+
21
+ export const TextNodeType = createNodeType({
22
+ type: 'text',
23
+ displayName: 'Text',
24
+ category: 'content',
25
+ schema: TextNodeSchemaInternal,
26
+
27
+ defaultValues: {
28
+ value: '',
29
+ },
30
+
31
+ treeDisplay: {
32
+ icon: 'TEXT',
33
+ getLabel: (node) => `"${node.value.substring(0, 30)}${node.value.length > 30 ? '...' : ''}"`,
34
+ },
35
+
36
+ clientRenderer: (node, context) => {
37
+ // Text nodes render as simple text content
38
+ return context.processI18n(node.value) as any;
39
+ },
40
+
41
+ ssrRenderer: (node, context) => {
42
+ // Text nodes render as escaped text
43
+ return context.escapeHtml(context.processI18n(node.value));
44
+ },
45
+
46
+ capabilities: {
47
+ canHaveChildren: false,
48
+ canHaveStyle: false,
49
+ canHaveAttributes: false,
50
+ requiresProps: ['value'],
51
+ },
52
+ });
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Node Types Index
3
+ * Exports all built-in node type definitions, schemas, and types
4
+ *
5
+ * This is the single source of truth for node type definitions.
6
+ * Types are inferred from Zod schemas, eliminating duplication.
7
+ */
8
+
9
+ import { globalNodeTypeManager } from '../NodeTypeManager';
10
+ import type { NodeTypeDefinition } from '../NodeTypeDefinition';
11
+
12
+ // Import all node type definitions (each file exports type, schema, and definition)
13
+ import { HtmlNodeType, HtmlNodeSchema, type HtmlNode } from './HtmlNodeType';
14
+ import { ComponentInstanceNodeType, ComponentInstanceNodeSchema, type ComponentInstanceNode } from './ComponentInstanceNodeType';
15
+ import { SlotMarkerType, SlotMarkerSchema, type SlotMarker } from './SlotMarkerType';
16
+ import { EmbedNodeType, EmbedNodeSchema, type EmbedNode } from './EmbedNodeType';
17
+ import { ObjectLinkNodeType, ObjectLinkNodeSchema, type ObjectLinkNode } from './ObjectLinkNodeType';
18
+ import { LocaleListNodeType, LocaleListNodeSchema, type LocaleListNode } from './LocaleListNodeType';
19
+ import { TextNodeType, TextNodeSchema, type TextNode } from './TextNodeType';
20
+ /**
21
+ * All built-in node type definitions
22
+ * Type assertion needed because TypeScript sees each as a specific generic type
23
+ */
24
+ export const builtInNodeTypes: NodeTypeDefinition[] = [
25
+ HtmlNodeType as NodeTypeDefinition,
26
+ ComponentInstanceNodeType as NodeTypeDefinition,
27
+ SlotMarkerType as NodeTypeDefinition,
28
+ EmbedNodeType as NodeTypeDefinition,
29
+ ObjectLinkNodeType as NodeTypeDefinition,
30
+ LocaleListNodeType as NodeTypeDefinition,
31
+ TextNodeType as NodeTypeDefinition,
32
+ ];
33
+
34
+ /**
35
+ * Export all schemas for use in validation/schemas.ts
36
+ */
37
+ export const nodeSchemas = {
38
+ html: HtmlNodeSchema,
39
+ component: ComponentInstanceNodeSchema,
40
+ slot: SlotMarkerSchema,
41
+ embed: EmbedNodeSchema,
42
+ objectLink: ObjectLinkNodeSchema,
43
+ localeList: LocaleListNodeSchema,
44
+ text: TextNodeSchema,
45
+ };
46
+
47
+ /**
48
+ * Register all built-in node types with the global manager
49
+ * Call this early in app lifecycle (client and server entry points)
50
+ */
51
+ export function registerBuiltInNodeTypes(): void {
52
+ globalNodeTypeManager.registerAll(builtInNodeTypes);
53
+ }
54
+
55
+ // Re-export individual node types for direct access
56
+ export { HtmlNodeType, HtmlNodeSchema, type HtmlNode } from './HtmlNodeType';
57
+ export { ComponentInstanceNodeType, ComponentInstanceNodeSchema, type ComponentInstanceNode } from './ComponentInstanceNodeType';
58
+ export { SlotMarkerType, SlotMarkerSchema, type SlotMarker } from './SlotMarkerType';
59
+ export { EmbedNodeType, EmbedNodeSchema, type EmbedNode } from './EmbedNodeType';
60
+ export { ObjectLinkNodeType, ObjectLinkNodeSchema, type ObjectLinkNode } from './ObjectLinkNodeType';
61
+ export { LocaleListNodeType, LocaleListNodeSchema, type LocaleListNode } from './LocaleListNodeType';
62
+ export { TextNodeType, TextNodeSchema, type TextNode } from './TextNodeType';
63
+
64
+ /**
65
+ * Discriminated union of all component node types
66
+ * This is the single source of truth for ComponentNode type
67
+ */
68
+ export type ComponentNode =
69
+ | HtmlNode
70
+ | ComponentInstanceNode
71
+ | SlotMarker
72
+ | EmbedNode
73
+ | ObjectLinkNode
74
+ | LocaleListNode
75
+ | TextNode;