@brunoalz/smartgesti-site-editor 1.0.0 → 1.2.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 (219) hide show
  1. package/dist/editor/BlockSelector.d.ts.map +1 -1
  2. package/dist/editor/BlockSelector.js +60 -57
  3. package/dist/editor/BlockSelector.js.map +1 -1
  4. package/dist/editor/LandingPageEditor.d.ts.map +1 -1
  5. package/dist/editor/LandingPageEditor.js +145 -128
  6. package/dist/editor/LandingPageEditor.js.map +1 -1
  7. package/dist/editor/PageTabBar.d.ts +4 -1
  8. package/dist/editor/PageTabBar.d.ts.map +1 -1
  9. package/dist/editor/PageTabBar.js +179 -41
  10. package/dist/editor/PageTabBar.js.map +1 -1
  11. package/dist/editor/PropertyEditor/BlockPropertyEditor.d.ts +2 -0
  12. package/dist/editor/PropertyEditor/BlockPropertyEditor.d.ts.map +1 -1
  13. package/dist/editor/PropertyEditor/BlockPropertyEditor.js +53 -45
  14. package/dist/editor/PropertyEditor/BlockPropertyEditor.js.map +1 -1
  15. package/dist/editor/PropertyEditor/CollapsiblePropertyGroup.d.ts +2 -0
  16. package/dist/editor/PropertyEditor/CollapsiblePropertyGroup.d.ts.map +1 -1
  17. package/dist/editor/PropertyEditor/CollapsiblePropertyGroup.js +47 -33
  18. package/dist/editor/PropertyEditor/CollapsiblePropertyGroup.js.map +1 -1
  19. package/dist/editor/PropertyEditor/VariationSelector.d.ts.map +1 -1
  20. package/dist/editor/PropertyEditor/VariationSelector.js +10 -6
  21. package/dist/editor/PropertyEditor/VariationSelector.js.map +1 -1
  22. package/dist/editor/PropertyEditor/index.js +20 -18
  23. package/dist/editor/PropertyEditor/index.js.map +1 -1
  24. package/dist/editor/PropertyEditor/inputs/CarouselImagesInput.d.ts +16 -0
  25. package/dist/editor/PropertyEditor/inputs/CarouselImagesInput.d.ts.map +1 -0
  26. package/dist/editor/PropertyEditor/inputs/CarouselImagesInput.js +170 -0
  27. package/dist/editor/PropertyEditor/inputs/CarouselImagesInput.js.map +1 -0
  28. package/dist/editor/PropertyEditor/inputs/ImageGridInput.d.ts.map +1 -1
  29. package/dist/editor/PropertyEditor/inputs/ImageGridInput.js +148 -121
  30. package/dist/editor/PropertyEditor/inputs/ImageGridInput.js.map +1 -1
  31. package/dist/editor/PropertyEditor/inputs/index.d.ts +1 -0
  32. package/dist/editor/PropertyEditor/inputs/index.d.ts.map +1 -1
  33. package/dist/editor/PropertyEditor/renderPropertyInput.d.ts.map +1 -1
  34. package/dist/editor/PropertyEditor/renderPropertyInput.js +167 -139
  35. package/dist/editor/PropertyEditor/renderPropertyInput.js.map +1 -1
  36. package/dist/editor/components/CenterPanel.d.ts +9 -1
  37. package/dist/editor/components/CenterPanel.d.ts.map +1 -1
  38. package/dist/editor/components/CenterPanel.js +24 -14
  39. package/dist/editor/components/CenterPanel.js.map +1 -1
  40. package/dist/editor/components/RightPanel.d.ts +5 -0
  41. package/dist/editor/components/RightPanel.d.ts.map +1 -1
  42. package/dist/editor/components/RightPanel.js +18 -12
  43. package/dist/editor/components/RightPanel.js.map +1 -1
  44. package/dist/editor/components/Toolbar.d.ts +3 -0
  45. package/dist/editor/components/Toolbar.d.ts.map +1 -1
  46. package/dist/editor/components/Toolbar.js +54 -35
  47. package/dist/editor/components/Toolbar.js.map +1 -1
  48. package/dist/engine/export/exportHtml.d.ts.map +1 -1
  49. package/dist/engine/export/exportHtml.js +50 -50
  50. package/dist/engine/export/exportHtml.js.map +1 -1
  51. package/dist/engine/export/exporters/sections/BlogPostExporters.d.ts +6 -0
  52. package/dist/engine/export/exporters/sections/BlogPostExporters.d.ts.map +1 -0
  53. package/dist/engine/export/exporters/sections/BlogPostExporters.js +101 -0
  54. package/dist/engine/export/exporters/sections/BlogPostExporters.js.map +1 -0
  55. package/dist/engine/export/exporters/sections/FooterExporter.js +22 -22
  56. package/dist/engine/export/exporters/sections/FooterExporter.js.map +1 -1
  57. package/dist/engine/export/exporters/sections/HeroExporter.d.ts.map +1 -1
  58. package/dist/engine/export/exporters/sections/HeroExporter.js +222 -205
  59. package/dist/engine/export/exporters/sections/HeroExporter.js.map +1 -1
  60. package/dist/engine/export/exporters/sections/MarketingExporters.js +88 -88
  61. package/dist/engine/export/exporters/sections/MarketingExporters.js.map +1 -1
  62. package/dist/engine/export/exporters/sections/NavbarExporter.js +34 -34
  63. package/dist/engine/export/exporters/sections/NavbarExporter.js.map +1 -1
  64. package/dist/engine/export/exporters/sections/index.d.ts.map +1 -1
  65. package/dist/engine/export/exporters/sections/index.js +29 -22
  66. package/dist/engine/export/exporters/sections/index.js.map +1 -1
  67. package/dist/engine/index.d.ts +3 -0
  68. package/dist/engine/index.d.ts.map +1 -1
  69. package/dist/engine/index.js +99 -87
  70. package/dist/engine/index.js.map +1 -1
  71. package/dist/engine/plugins/builtin/blog/index.d.ts +3 -0
  72. package/dist/engine/plugins/builtin/blog/index.d.ts.map +1 -0
  73. package/dist/engine/plugins/builtin/blog/manifest.d.ts +3 -0
  74. package/dist/engine/plugins/builtin/blog/manifest.d.ts.map +1 -0
  75. package/dist/engine/plugins/builtin/blog/manifest.js +273 -0
  76. package/dist/engine/plugins/builtin/blog/manifest.js.map +1 -0
  77. package/dist/engine/plugins/builtin/blog/mockContentProvider.d.ts +7 -0
  78. package/dist/engine/plugins/builtin/blog/mockContentProvider.d.ts.map +1 -0
  79. package/dist/engine/plugins/builtin/blog/mockContentProvider.js +135 -0
  80. package/dist/engine/plugins/builtin/blog/mockContentProvider.js.map +1 -0
  81. package/dist/engine/plugins/contentHydration.d.ts +17 -0
  82. package/dist/engine/plugins/contentHydration.d.ts.map +1 -0
  83. package/dist/engine/plugins/contentHydration.js +121 -0
  84. package/dist/engine/plugins/contentHydration.js.map +1 -0
  85. package/dist/engine/plugins/dynamicPageResolver.d.ts +25 -0
  86. package/dist/engine/plugins/dynamicPageResolver.d.ts.map +1 -0
  87. package/dist/engine/plugins/dynamicPageResolver.js +32 -0
  88. package/dist/engine/plugins/dynamicPageResolver.js.map +1 -0
  89. package/dist/engine/plugins/index.d.ts +11 -0
  90. package/dist/engine/plugins/index.d.ts.map +1 -0
  91. package/dist/engine/plugins/pluginRegistry.d.ts +37 -0
  92. package/dist/engine/plugins/pluginRegistry.d.ts.map +1 -0
  93. package/dist/engine/plugins/pluginRegistry.js +134 -0
  94. package/dist/engine/plugins/pluginRegistry.js.map +1 -0
  95. package/dist/engine/plugins/types.d.ts +180 -0
  96. package/dist/engine/plugins/types.d.ts.map +1 -0
  97. package/dist/engine/presets/heroVariations.d.ts +5 -0
  98. package/dist/engine/presets/heroVariations.d.ts.map +1 -1
  99. package/dist/engine/presets/heroVariations.js +50 -6
  100. package/dist/engine/presets/heroVariations.js.map +1 -1
  101. package/dist/engine/preview/Preview.d.ts +6 -2
  102. package/dist/engine/preview/Preview.d.ts.map +1 -1
  103. package/dist/engine/preview/Preview.js +295 -125
  104. package/dist/engine/preview/Preview.js.map +1 -1
  105. package/dist/engine/registry/blocks/sections/blogPostCard.d.ts +3 -0
  106. package/dist/engine/registry/blocks/sections/blogPostCard.d.ts.map +1 -0
  107. package/dist/engine/registry/blocks/sections/blogPostCard.js +53 -0
  108. package/dist/engine/registry/blocks/sections/blogPostCard.js.map +1 -0
  109. package/dist/engine/registry/blocks/sections/blogPostDetail.d.ts +3 -0
  110. package/dist/engine/registry/blocks/sections/blogPostDetail.d.ts.map +1 -0
  111. package/dist/engine/registry/blocks/sections/blogPostDetail.js +49 -0
  112. package/dist/engine/registry/blocks/sections/blogPostDetail.js.map +1 -0
  113. package/dist/engine/registry/blocks/sections/blogPostGrid.d.ts +3 -0
  114. package/dist/engine/registry/blocks/sections/blogPostGrid.d.ts.map +1 -0
  115. package/dist/engine/registry/blocks/sections/blogPostGrid.js +89 -0
  116. package/dist/engine/registry/blocks/sections/blogPostGrid.js.map +1 -0
  117. package/dist/engine/registry/blocks/sections/hero.d.ts.map +1 -1
  118. package/dist/engine/registry/blocks/sections/hero.js +67 -14
  119. package/dist/engine/registry/blocks/sections/hero.js.map +1 -1
  120. package/dist/engine/registry/blocks/sections/index.d.ts +3 -0
  121. package/dist/engine/registry/blocks/sections/index.d.ts.map +1 -1
  122. package/dist/engine/registry/blocks/sections/navbar.d.ts.map +1 -1
  123. package/dist/engine/registry/blocks/sections/navbar.js +2 -1
  124. package/dist/engine/registry/blocks/sections/navbar.js.map +1 -1
  125. package/dist/engine/registry/registry.d.ts.map +1 -1
  126. package/dist/engine/registry/registry.js +16 -12
  127. package/dist/engine/registry/registry.js.map +1 -1
  128. package/dist/engine/registry/types.d.ts +10 -6
  129. package/dist/engine/registry/types.d.ts.map +1 -1
  130. package/dist/engine/render/renderers/sections/BlogPostCardRenderer.d.ts +3 -0
  131. package/dist/engine/render/renderers/sections/BlogPostCardRenderer.d.ts.map +1 -0
  132. package/dist/engine/render/renderers/sections/BlogPostCardRenderer.js +199 -0
  133. package/dist/engine/render/renderers/sections/BlogPostCardRenderer.js.map +1 -0
  134. package/dist/engine/render/renderers/sections/BlogPostDetailRenderer.d.ts +3 -0
  135. package/dist/engine/render/renderers/sections/BlogPostDetailRenderer.d.ts.map +1 -0
  136. package/dist/engine/render/renderers/sections/BlogPostDetailRenderer.js +293 -0
  137. package/dist/engine/render/renderers/sections/BlogPostDetailRenderer.js.map +1 -0
  138. package/dist/engine/render/renderers/sections/BlogPostGridRenderer.d.ts +3 -0
  139. package/dist/engine/render/renderers/sections/BlogPostGridRenderer.d.ts.map +1 -0
  140. package/dist/engine/render/renderers/sections/BlogPostGridRenderer.js +101 -0
  141. package/dist/engine/render/renderers/sections/BlogPostGridRenderer.js.map +1 -0
  142. package/dist/engine/render/renderers/sections/CtaRenderer.d.ts.map +1 -1
  143. package/dist/engine/render/renderers/sections/CtaRenderer.js +33 -31
  144. package/dist/engine/render/renderers/sections/CtaRenderer.js.map +1 -1
  145. package/dist/engine/render/renderers/sections/FaqItemRenderer.d.ts.map +1 -1
  146. package/dist/engine/render/renderers/sections/FaqItemRenderer.js +7 -6
  147. package/dist/engine/render/renderers/sections/FaqItemRenderer.js.map +1 -1
  148. package/dist/engine/render/renderers/sections/FaqRenderer.js +7 -7
  149. package/dist/engine/render/renderers/sections/FaqRenderer.js.map +1 -1
  150. package/dist/engine/render/renderers/sections/FeatureGridRenderer.d.ts.map +1 -1
  151. package/dist/engine/render/renderers/sections/FeatureGridRenderer.js +19 -18
  152. package/dist/engine/render/renderers/sections/FeatureGridRenderer.js.map +1 -1
  153. package/dist/engine/render/renderers/sections/FeatureRenderer.d.ts.map +1 -1
  154. package/dist/engine/render/renderers/sections/FeatureRenderer.js +5 -4
  155. package/dist/engine/render/renderers/sections/FeatureRenderer.js.map +1 -1
  156. package/dist/engine/render/renderers/sections/FooterRenderer.d.ts.map +1 -1
  157. package/dist/engine/render/renderers/sections/FooterRenderer.js +8 -7
  158. package/dist/engine/render/renderers/sections/FooterRenderer.js.map +1 -1
  159. package/dist/engine/render/renderers/sections/HeroRenderer.d.ts.map +1 -1
  160. package/dist/engine/render/renderers/sections/HeroRenderer.js +295 -218
  161. package/dist/engine/render/renderers/sections/HeroRenderer.js.map +1 -1
  162. package/dist/engine/render/renderers/sections/NavbarRenderer.d.ts.map +1 -1
  163. package/dist/engine/render/renderers/sections/NavbarRenderer.js +23 -22
  164. package/dist/engine/render/renderers/sections/NavbarRenderer.js.map +1 -1
  165. package/dist/engine/render/renderers/sections/PricingCardRenderer.d.ts.map +1 -1
  166. package/dist/engine/render/renderers/sections/PricingCardRenderer.js +7 -6
  167. package/dist/engine/render/renderers/sections/PricingCardRenderer.js.map +1 -1
  168. package/dist/engine/render/renderers/sections/PricingRenderer.js +9 -9
  169. package/dist/engine/render/renderers/sections/PricingRenderer.js.map +1 -1
  170. package/dist/engine/render/renderers/sections/TestimonialGridRenderer.d.ts.map +1 -1
  171. package/dist/engine/render/renderers/sections/TestimonialGridRenderer.js +17 -16
  172. package/dist/engine/render/renderers/sections/TestimonialGridRenderer.js.map +1 -1
  173. package/dist/engine/render/renderers/sections/TestimonialRenderer.d.ts.map +1 -1
  174. package/dist/engine/render/renderers/sections/TestimonialRenderer.js +11 -10
  175. package/dist/engine/render/renderers/sections/TestimonialRenderer.js.map +1 -1
  176. package/dist/engine/render/renderers/sections/index.js +24 -18
  177. package/dist/engine/render/renderers/sections/index.js.map +1 -1
  178. package/dist/engine/schema/siteDocument.d.ts +104 -3
  179. package/dist/engine/schema/siteDocument.d.ts.map +1 -1
  180. package/dist/engine/schema/siteDocument.js.map +1 -1
  181. package/dist/engine/shared/carouselAnimation.d.ts +20 -0
  182. package/dist/engine/shared/carouselAnimation.d.ts.map +1 -0
  183. package/dist/engine/shared/carouselAnimation.js +62 -0
  184. package/dist/engine/shared/carouselAnimation.js.map +1 -0
  185. package/dist/engine/shared/imageGrid/types.d.ts +2 -0
  186. package/dist/engine/shared/imageGrid/types.d.ts.map +1 -1
  187. package/dist/engine/shared/showWhen.d.ts +44 -0
  188. package/dist/engine/shared/showWhen.d.ts.map +1 -0
  189. package/dist/engine/shared/showWhen.js +33 -0
  190. package/dist/engine/shared/showWhen.js.map +1 -0
  191. package/dist/hooks/useEditorState.d.ts +3 -0
  192. package/dist/hooks/useEditorState.d.ts.map +1 -1
  193. package/dist/hooks/useEditorState.js +106 -84
  194. package/dist/hooks/useEditorState.js.map +1 -1
  195. package/dist/index.d.ts +13 -2
  196. package/dist/index.d.ts.map +1 -1
  197. package/dist/index.js +109 -93
  198. package/dist/index.js.map +1 -1
  199. package/dist/shared/templates/escola-blog.d.ts +3 -0
  200. package/dist/shared/templates/escola-blog.d.ts.map +1 -0
  201. package/dist/shared/templates/escola-blog.js +160 -0
  202. package/dist/shared/templates/escola-blog.js.map +1 -0
  203. package/dist/shared/templates/index.d.ts +2 -0
  204. package/dist/shared/templates/index.d.ts.map +1 -1
  205. package/dist/shared/templates/index.js +30 -12
  206. package/dist/shared/templates/index.js.map +1 -1
  207. package/dist/utils/changeDetector.d.ts +2 -1
  208. package/dist/utils/changeDetector.d.ts.map +1 -1
  209. package/dist/utils/changeDetector.js +39 -39
  210. package/dist/utils/changeDetector.js.map +1 -1
  211. package/dist/utils/sharedTemplateToEngine.d.ts +4 -5
  212. package/dist/utils/sharedTemplateToEngine.d.ts.map +1 -1
  213. package/dist/utils/sharedTemplateToEngine.js +14 -87
  214. package/dist/utils/sharedTemplateToEngine.js.map +1 -1
  215. package/dist/viewer/LandingPageViewer.d.ts +13 -6
  216. package/dist/viewer/LandingPageViewer.d.ts.map +1 -1
  217. package/dist/viewer/LandingPageViewer.js +220 -122
  218. package/dist/viewer/LandingPageViewer.js.map +1 -1
  219. package/package.json +3 -2
@@ -0,0 +1,135 @@
1
+ const s = [
2
+ {
3
+ id: "mock-post-1",
4
+ type: "blog-post",
5
+ slug: "bem-vindo-ao-nosso-blog",
6
+ data: {
7
+ title: "Bem-vindo ao nosso blog!",
8
+ excerpt: "Estamos animados em lançar nosso blog oficial. Acompanhe as novidades e dicas.",
9
+ content: "<p>Estamos animados em lançar nosso blog oficial. Aqui você encontrará notícias, tutoriais e dicas importantes.</p>",
10
+ featuredImage: "https://images.unsplash.com/photo-1499750310107-5fef28a66643?w=800&h=400&fit=crop",
11
+ category: "Novidades",
12
+ tags: ["lançamento", "novidades"],
13
+ authorName: "Equipe Editorial",
14
+ authorAvatar: "",
15
+ readingTime: 3
16
+ },
17
+ metadata: {
18
+ createdAt: "2025-01-15T10:00:00Z",
19
+ updatedAt: "2025-01-15T10:00:00Z",
20
+ publishedAt: "2025-01-15T10:00:00Z",
21
+ status: "published"
22
+ }
23
+ },
24
+ {
25
+ id: "mock-post-2",
26
+ type: "blog-post",
27
+ slug: "dicas-para-estudantes",
28
+ data: {
29
+ title: "5 Dicas para Estudantes de Sucesso",
30
+ excerpt: "Confira as melhores práticas para melhorar seus estudos e alcançar seus objetivos acadêmicos.",
31
+ content: "<p>Estudar de forma eficiente é uma habilidade que pode ser desenvolvida. Confira nossas dicas.</p>",
32
+ featuredImage: "https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=800&h=400&fit=crop",
33
+ category: "Educação",
34
+ tags: ["educação", "dicas", "estudos"],
35
+ authorName: "Prof. Maria Silva",
36
+ authorAvatar: "",
37
+ readingTime: 5
38
+ },
39
+ metadata: {
40
+ createdAt: "2025-01-20T14:30:00Z",
41
+ updatedAt: "2025-01-20T14:30:00Z",
42
+ publishedAt: "2025-01-20T14:30:00Z",
43
+ status: "published"
44
+ }
45
+ },
46
+ {
47
+ id: "mock-post-3",
48
+ type: "blog-post",
49
+ slug: "novidades-do-semestre",
50
+ data: {
51
+ title: "Novidades para o Próximo Semestre",
52
+ excerpt: "Novos cursos, eventos e melhorias que estão chegando. Saiba tudo sobre o que vem por aí.",
53
+ content: "<p>O próximo semestre traz muitas novidades. Novos cursos, eventos e oportunidades para todos.</p>",
54
+ featuredImage: "https://images.unsplash.com/photo-1524178232363-1fb2b075b655?w=800&h=400&fit=crop",
55
+ category: "Institucional",
56
+ tags: ["semestre", "novidades", "cursos"],
57
+ authorName: "Coordenação Acadêmica",
58
+ authorAvatar: "",
59
+ readingTime: 4
60
+ },
61
+ metadata: {
62
+ createdAt: "2025-02-01T09:00:00Z",
63
+ updatedAt: "2025-02-01T09:00:00Z",
64
+ publishedAt: "2025-02-01T09:00:00Z",
65
+ status: "published"
66
+ }
67
+ }
68
+ ];
69
+ function r(a) {
70
+ const e = a.data, t = a.metadata, o = t?.publishedAt ? new Date(t.publishedAt).toLocaleDateString("pt-BR", {
71
+ day: "2-digit",
72
+ month: "short",
73
+ year: "numeric"
74
+ }) : "";
75
+ return {
76
+ title: e.title || "",
77
+ excerpt: e.excerpt || "",
78
+ image: e.featuredImage || "",
79
+ date: o,
80
+ category: e.category || "",
81
+ authorName: e.authorName || "",
82
+ authorAvatar: e.authorAvatar || "",
83
+ readingTime: e.readingTime ? `${e.readingTime} min de leitura` : "",
84
+ linkHref: `/site/p/blog/${a.slug || a.id}`,
85
+ linkText: "Ler mais",
86
+ // Detail-specific props
87
+ content: e.content || "",
88
+ featuredImage: e.featuredImage || "",
89
+ tags: Array.isArray(e.tags) ? e.tags : []
90
+ };
91
+ }
92
+ const d = {
93
+ type: "blog-posts",
94
+ async fetchList(a) {
95
+ const e = a.limit ?? 10, t = a.page ?? 1, o = (t - 1) * e;
96
+ return {
97
+ items: s.slice(o, o + e),
98
+ total: s.length,
99
+ page: t,
100
+ limit: e,
101
+ hasMore: o + e < s.length
102
+ };
103
+ },
104
+ async fetchById(a) {
105
+ return s.find((e) => e.id === a || e.slug === a) ?? null;
106
+ },
107
+ getSchema() {
108
+ return {
109
+ type: "blog-post",
110
+ label: "Blog Post",
111
+ fields: [
112
+ { name: "title", type: "string", required: !0, label: "Título" },
113
+ { name: "slug", type: "string", required: !0, label: "Slug" },
114
+ { name: "excerpt", type: "string", label: "Resumo" },
115
+ {
116
+ name: "content",
117
+ type: "richtext",
118
+ required: !0,
119
+ label: "Conteúdo"
120
+ },
121
+ { name: "featuredImage", type: "image", label: "Imagem de Capa" },
122
+ { name: "category", type: "string", label: "Categoria" },
123
+ { name: "tags", type: "array", label: "Tags" },
124
+ { name: "authorName", type: "string", label: "Autor" },
125
+ { name: "authorAvatar", type: "image", label: "Avatar do Autor" },
126
+ { name: "readingTime", type: "number", label: "Tempo de Leitura" }
127
+ ]
128
+ };
129
+ },
130
+ toBlockProps: r
131
+ };
132
+ export {
133
+ d as mockBlogContentProvider
134
+ };
135
+ //# sourceMappingURL=mockContentProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockContentProvider.js","sources":["../../../../../src/engine/plugins/builtin/blog/mockContentProvider.ts"],"sourcesContent":["/**\n * Mock Blog Content Provider\n * Provides placeholder blog data for editor preview when no real\n * ContentProvider is registered by the consumer.\n */\n\nimport type {\n ContentProvider,\n ContentItem,\n ContentListParams,\n ContentListResult,\n DataSchema,\n} from \"../../types\";\n\nconst MOCK_POSTS: ContentItem[] = [\n {\n id: \"mock-post-1\",\n type: \"blog-post\",\n slug: \"bem-vindo-ao-nosso-blog\",\n data: {\n title: \"Bem-vindo ao nosso blog!\",\n excerpt:\n \"Estamos animados em lançar nosso blog oficial. Acompanhe as novidades e dicas.\",\n content:\n \"<p>Estamos animados em lançar nosso blog oficial. Aqui você encontrará notícias, tutoriais e dicas importantes.</p>\",\n featuredImage:\n \"https://images.unsplash.com/photo-1499750310107-5fef28a66643?w=800&h=400&fit=crop\",\n category: \"Novidades\",\n tags: [\"lançamento\", \"novidades\"],\n authorName: \"Equipe Editorial\",\n authorAvatar: \"\",\n readingTime: 3,\n },\n metadata: {\n createdAt: \"2025-01-15T10:00:00Z\",\n updatedAt: \"2025-01-15T10:00:00Z\",\n publishedAt: \"2025-01-15T10:00:00Z\",\n status: \"published\",\n },\n },\n {\n id: \"mock-post-2\",\n type: \"blog-post\",\n slug: \"dicas-para-estudantes\",\n data: {\n title: \"5 Dicas para Estudantes de Sucesso\",\n excerpt:\n \"Confira as melhores práticas para melhorar seus estudos e alcançar seus objetivos acadêmicos.\",\n content:\n \"<p>Estudar de forma eficiente é uma habilidade que pode ser desenvolvida. Confira nossas dicas.</p>\",\n featuredImage:\n \"https://images.unsplash.com/photo-1523050854058-8df90110c9f1?w=800&h=400&fit=crop\",\n category: \"Educação\",\n tags: [\"educação\", \"dicas\", \"estudos\"],\n authorName: \"Prof. Maria Silva\",\n authorAvatar: \"\",\n readingTime: 5,\n },\n metadata: {\n createdAt: \"2025-01-20T14:30:00Z\",\n updatedAt: \"2025-01-20T14:30:00Z\",\n publishedAt: \"2025-01-20T14:30:00Z\",\n status: \"published\",\n },\n },\n {\n id: \"mock-post-3\",\n type: \"blog-post\",\n slug: \"novidades-do-semestre\",\n data: {\n title: \"Novidades para o Próximo Semestre\",\n excerpt:\n \"Novos cursos, eventos e melhorias que estão chegando. Saiba tudo sobre o que vem por aí.\",\n content:\n \"<p>O próximo semestre traz muitas novidades. Novos cursos, eventos e oportunidades para todos.</p>\",\n featuredImage:\n \"https://images.unsplash.com/photo-1524178232363-1fb2b075b655?w=800&h=400&fit=crop\",\n category: \"Institucional\",\n tags: [\"semestre\", \"novidades\", \"cursos\"],\n authorName: \"Coordenação Acadêmica\",\n authorAvatar: \"\",\n readingTime: 4,\n },\n metadata: {\n createdAt: \"2025-02-01T09:00:00Z\",\n updatedAt: \"2025-02-01T09:00:00Z\",\n publishedAt: \"2025-02-01T09:00:00Z\",\n status: \"published\",\n },\n },\n];\n\n/**\n * Converts a ContentItem to blogPostCard block props\n */\nfunction toBlockProps(item: ContentItem): Record<string, unknown> {\n const d = item.data;\n const meta = item.metadata;\n\n const publishedDate = meta?.publishedAt\n ? new Date(meta.publishedAt).toLocaleDateString(\"pt-BR\", {\n day: \"2-digit\",\n month: \"short\",\n year: \"numeric\",\n })\n : \"\";\n\n return {\n title: d.title || \"\",\n excerpt: d.excerpt || \"\",\n image: d.featuredImage || \"\",\n date: publishedDate,\n category: d.category || \"\",\n authorName: d.authorName || \"\",\n authorAvatar: d.authorAvatar || \"\",\n readingTime: d.readingTime ? `${d.readingTime} min de leitura` : \"\",\n linkHref: `/site/p/blog/${item.slug || item.id}`,\n linkText: \"Ler mais\",\n // Detail-specific props\n content: d.content || \"\",\n featuredImage: d.featuredImage || \"\",\n tags: Array.isArray(d.tags) ? d.tags : [],\n };\n}\n\n/**\n * Mock ContentProvider for blog posts.\n * Returns placeholder data for editor preview.\n */\nexport const mockBlogContentProvider: ContentProvider = {\n type: \"blog-posts\",\n\n async fetchList(params: ContentListParams): Promise<ContentListResult> {\n const limit = params.limit ?? 10;\n const page = params.page ?? 1;\n const start = (page - 1) * limit;\n const items = MOCK_POSTS.slice(start, start + limit);\n\n return {\n items,\n total: MOCK_POSTS.length,\n page,\n limit,\n hasMore: start + limit < MOCK_POSTS.length,\n };\n },\n\n async fetchById(idOrSlug: string): Promise<ContentItem | null> {\n return (\n MOCK_POSTS.find((p) => p.id === idOrSlug || p.slug === idOrSlug) ?? null\n );\n },\n\n getSchema(): DataSchema {\n return {\n type: \"blog-post\",\n label: \"Blog Post\",\n fields: [\n { name: \"title\", type: \"string\", required: true, label: \"Título\" },\n { name: \"slug\", type: \"string\", required: true, label: \"Slug\" },\n { name: \"excerpt\", type: \"string\", label: \"Resumo\" },\n {\n name: \"content\",\n type: \"richtext\",\n required: true,\n label: \"Conteúdo\",\n },\n { name: \"featuredImage\", type: \"image\", label: \"Imagem de Capa\" },\n { name: \"category\", type: \"string\", label: \"Categoria\" },\n { name: \"tags\", type: \"array\", label: \"Tags\" },\n { name: \"authorName\", type: \"string\", label: \"Autor\" },\n { name: \"authorAvatar\", type: \"image\", label: \"Avatar do Autor\" },\n { name: \"readingTime\", type: \"number\", label: \"Tempo de Leitura\" },\n ],\n };\n },\n\n toBlockProps,\n};\n"],"names":["MOCK_POSTS","toBlockProps","item","d","meta","publishedDate","mockBlogContentProvider","params","limit","page","start","idOrSlug","p"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { SitePage } from '../schema/siteDocument';
2
+ import { ContentProvider, ContentListParams } from './types';
3
+ /**
4
+ * Map of provider type → ContentProvider instance
5
+ */
6
+ export type ContentProviderMap = Map<string, ContentProvider>;
7
+ /**
8
+ * Hydrates a page's blocks with data from ContentProviders.
9
+ *
10
+ * For pages with a dataSource:
11
+ * - mode "list": fetches list and populates grid blocks' `cards` prop
12
+ * - mode "single": fetches single item and spreads props onto detail blocks
13
+ *
14
+ * Returns a new page with hydrated block props (original page is not mutated).
15
+ */
16
+ export declare function hydratePageWithContent(page: SitePage, providers: ContentProviderMap, urlParams?: Record<string, string>, fetchParams?: ContentListParams): Promise<SitePage>;
17
+ //# sourceMappingURL=contentHydration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentHydration.d.ts","sourceRoot":"","sources":["../../../src/engine/plugins/contentHydration.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAS,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAe,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,kBAAkB,EAC7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,WAAW,CAAC,EAAE,iBAAiB,GAC9B,OAAO,CAAC,QAAQ,CAAC,CAsCnB"}
@@ -0,0 +1,121 @@
1
+ import { logger as c } from "../../utils/logger.js";
2
+ async function l(r, e, t, n) {
3
+ if (!r.dataSource)
4
+ return r;
5
+ const { provider: o, mode: s, paramMapping: a } = r.dataSource, i = e.get(o);
6
+ if (!i)
7
+ return c.warn(
8
+ `ContentProvider "${o}" not found for page "${r.id}". Rendering with static props.`
9
+ ), r;
10
+ try {
11
+ if (s === "list")
12
+ return await p(r, i, n);
13
+ if (s === "single") {
14
+ const u = m(a, t);
15
+ return u ? await h(r, i, u) : (c.warn(
16
+ `Could not resolve ID/slug for page "${r.id}" from URL params. Using static props.`
17
+ ), r);
18
+ }
19
+ return r;
20
+ } catch (u) {
21
+ return c.error(`Error hydrating page "${r.id}":`, u), r;
22
+ }
23
+ }
24
+ async function p(r, e, t) {
25
+ const n = {
26
+ limit: 12,
27
+ ...r.dataSource?.defaultParams,
28
+ ...t
29
+ }, o = await e.fetchList(n);
30
+ if (!o.items || o.items.length === 0)
31
+ return r;
32
+ const s = o.items.map((i) => e.toBlockProps(i)), a = r.structure.map(
33
+ (i) => d(i, s)
34
+ );
35
+ return {
36
+ ...r,
37
+ structure: a
38
+ };
39
+ }
40
+ function d(r, e) {
41
+ if (r.type === "blogPostGrid")
42
+ return {
43
+ ...r,
44
+ props: {
45
+ ...r.props,
46
+ cards: e
47
+ }
48
+ };
49
+ const t = r.props;
50
+ return t.children && Array.isArray(t.children) ? {
51
+ ...r,
52
+ props: {
53
+ ...t,
54
+ children: t.children.map(
55
+ (n) => d(n, e)
56
+ )
57
+ }
58
+ } : r;
59
+ }
60
+ async function h(r, e, t) {
61
+ const n = await e.fetchById(t);
62
+ if (!n)
63
+ return c.warn(`Content item "${t}" not found. Using static props.`), r;
64
+ const o = e.toBlockProps(n), s = r.structure.map(
65
+ (a) => f(a, o, n)
66
+ );
67
+ return {
68
+ ...r,
69
+ structure: s
70
+ };
71
+ }
72
+ function f(r, e, t) {
73
+ if (r.type === "blogPostDetail")
74
+ return {
75
+ ...r,
76
+ props: {
77
+ ...r.props,
78
+ ...e,
79
+ // Preserve metadata
80
+ _contentItemId: t.id,
81
+ _contentItemSlug: t.slug
82
+ }
83
+ };
84
+ if (r.type === "blogPostCard")
85
+ return {
86
+ ...r,
87
+ props: {
88
+ ...r.props,
89
+ ...e
90
+ }
91
+ };
92
+ const n = r.props;
93
+ return n.children && Array.isArray(n.children) ? {
94
+ ...r,
95
+ props: {
96
+ ...n,
97
+ children: n.children.map(
98
+ (o) => f(o, e, t)
99
+ )
100
+ }
101
+ } : r;
102
+ }
103
+ function m(r, e) {
104
+ if (!(!r || !e)) {
105
+ for (const t of ["slug", "id"]) {
106
+ const n = r[t];
107
+ if (n) {
108
+ const o = n.startsWith(":") ? n.slice(1) : n, s = e[o];
109
+ if (s) return s;
110
+ }
111
+ }
112
+ for (const t of Object.values(r)) {
113
+ const n = t.startsWith(":") ? t.slice(1) : t, o = e[n];
114
+ if (o) return o;
115
+ }
116
+ }
117
+ }
118
+ export {
119
+ l as hydratePageWithContent
120
+ };
121
+ //# sourceMappingURL=contentHydration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentHydration.js","sources":["../../../src/engine/plugins/contentHydration.ts"],"sourcesContent":["/**\n * Content Hydration\n * Hydrates page blocks with data from ContentProviders before rendering.\n *\n * This works at the data level, before either rendering pipeline\n * (React renderers or HTML exporters) processes the blocks.\n */\n\nimport { logger } from \"../../utils/logger\";\nimport type { SitePage, Block } from \"../schema/siteDocument\";\nimport type { ContentProvider, ContentItem, ContentListParams } from \"./types\";\n\n/**\n * Map of provider type → ContentProvider instance\n */\nexport type ContentProviderMap = Map<string, ContentProvider>;\n\n/**\n * Hydrates a page's blocks with data from ContentProviders.\n *\n * For pages with a dataSource:\n * - mode \"list\": fetches list and populates grid blocks' `cards` prop\n * - mode \"single\": fetches single item and spreads props onto detail blocks\n *\n * Returns a new page with hydrated block props (original page is not mutated).\n */\nexport async function hydratePageWithContent(\n page: SitePage,\n providers: ContentProviderMap,\n urlParams?: Record<string, string>,\n fetchParams?: ContentListParams,\n): Promise<SitePage> {\n // No dataSource → return page as-is\n if (!page.dataSource) {\n return page;\n }\n\n const { provider: providerType, mode, paramMapping } = page.dataSource;\n const provider = providers.get(providerType);\n\n if (!provider) {\n logger.warn(\n `ContentProvider \"${providerType}\" not found for page \"${page.id}\". Rendering with static props.`,\n );\n return page;\n }\n\n try {\n if (mode === \"list\") {\n return await hydrateListPage(page, provider, fetchParams);\n }\n\n if (mode === \"single\") {\n // Resolve the ID/slug from URL params\n const idOrSlug = resolveIdFromParams(paramMapping, urlParams);\n if (!idOrSlug) {\n logger.warn(\n `Could not resolve ID/slug for page \"${page.id}\" from URL params. Using static props.`,\n );\n return page;\n }\n return await hydrateSinglePage(page, provider, idOrSlug);\n }\n\n return page;\n } catch (error) {\n logger.error(`Error hydrating page \"${page.id}\":`, error);\n return page;\n }\n}\n\n/**\n * Hydrates a list-mode page: fetches items and populates grid blocks.\n */\nasync function hydrateListPage(\n page: SitePage,\n provider: ContentProvider,\n fetchParams?: ContentListParams,\n): Promise<SitePage> {\n const params: ContentListParams = {\n limit: 12,\n ...page.dataSource?.defaultParams,\n ...fetchParams,\n };\n\n const result = await provider.fetchList(params);\n\n if (!result.items || result.items.length === 0) {\n return page;\n }\n\n // Convert items to block props\n const cardProps = result.items.map((item) => provider.toBlockProps(item));\n\n // Hydrate all grid blocks on the page with the fetched cards\n const hydratedStructure = page.structure.map((block) =>\n hydrateGridBlock(block, cardProps),\n );\n\n return {\n ...page,\n structure: hydratedStructure,\n };\n}\n\n/**\n * Hydrates grid blocks (blogPostGrid, etc.) with card data.\n */\nfunction hydrateGridBlock(\n block: Block,\n cardProps: Record<string, unknown>[],\n): Block {\n // Direct match: blogPostGrid gets cards populated\n if (block.type === \"blogPostGrid\") {\n return {\n ...block,\n props: {\n ...block.props,\n cards: cardProps,\n },\n };\n }\n\n // Recurse into children for nested structures\n const props = block.props as Record<string, unknown>;\n if (props.children && Array.isArray(props.children)) {\n return {\n ...block,\n props: {\n ...props,\n children: (props.children as Block[]).map((child) =>\n hydrateGridBlock(child, cardProps),\n ),\n },\n };\n }\n\n return block;\n}\n\n/**\n * Hydrates a single-mode page: fetches one item and populates detail blocks.\n */\nasync function hydrateSinglePage(\n page: SitePage,\n provider: ContentProvider,\n idOrSlug: string,\n): Promise<SitePage> {\n const item = await provider.fetchById(idOrSlug);\n\n if (!item) {\n logger.warn(`Content item \"${idOrSlug}\" not found. Using static props.`);\n return page;\n }\n\n const blockProps = provider.toBlockProps(item);\n\n // Hydrate all detail blocks on the page\n const hydratedStructure = page.structure.map((block) =>\n hydrateDetailBlock(block, blockProps, item),\n );\n\n return {\n ...page,\n structure: hydratedStructure,\n };\n}\n\n/**\n * Hydrates detail blocks (blogPostDetail, etc.) with item data.\n */\nfunction hydrateDetailBlock(\n block: Block,\n blockProps: Record<string, unknown>,\n item: ContentItem,\n): Block {\n if (block.type === \"blogPostDetail\") {\n return {\n ...block,\n props: {\n ...block.props,\n ...blockProps,\n // Preserve metadata\n _contentItemId: item.id,\n _contentItemSlug: item.slug,\n },\n };\n }\n\n // Also hydrate blogPostCard blocks that reference the same item\n if (block.type === \"blogPostCard\") {\n return {\n ...block,\n props: {\n ...block.props,\n ...blockProps,\n },\n };\n }\n\n // Recurse into children\n const props = block.props as Record<string, unknown>;\n if (props.children && Array.isArray(props.children)) {\n return {\n ...block,\n props: {\n ...props,\n children: (props.children as Block[]).map((child) =>\n hydrateDetailBlock(child, blockProps, item),\n ),\n },\n };\n }\n\n return block;\n}\n\n/**\n * Resolves the item ID/slug from URL params using paramMapping.\n * e.g., paramMapping: { slug: \":slug\" }, urlParams: { slug: \"my-post\" } → \"my-post\"\n */\nfunction resolveIdFromParams(\n paramMapping?: Record<string, string>,\n urlParams?: Record<string, string>,\n): string | undefined {\n if (!paramMapping || !urlParams) return undefined;\n\n // Try slug first, then id\n for (const key of [\"slug\", \"id\"]) {\n const paramPattern = paramMapping[key];\n if (paramPattern) {\n // Extract param name from pattern (e.g., \":slug\" → \"slug\")\n const paramName = paramPattern.startsWith(\":\")\n ? paramPattern.slice(1)\n : paramPattern;\n const value = urlParams[paramName];\n if (value) return value;\n }\n }\n\n // Fallback: return first available param value\n for (const paramPattern of Object.values(paramMapping)) {\n const paramName = paramPattern.startsWith(\":\")\n ? paramPattern.slice(1)\n : paramPattern;\n const value = urlParams[paramName];\n if (value) return value;\n }\n\n return undefined;\n}\n"],"names":["hydratePageWithContent","page","providers","urlParams","fetchParams","providerType","mode","paramMapping","provider","logger","hydrateListPage","idOrSlug","resolveIdFromParams","hydrateSinglePage","error","params","result","cardProps","item","hydratedStructure","block","hydrateGridBlock","props","child","blockProps","hydrateDetailBlock","key","paramPattern","paramName","value"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { SitePage } from '../schema/siteDocument';
2
+ /**
3
+ * Result of matching a URL path against dynamic pages
4
+ */
5
+ export interface DynamicPageMatch {
6
+ /** The matched page */
7
+ page: SitePage;
8
+ /** Extracted URL parameters (e.g., { slug: "my-first-post" }) */
9
+ params: Record<string, string>;
10
+ }
11
+ /**
12
+ * Matches a URL path against pages, supporting dynamic segments.
13
+ *
14
+ * Priority:
15
+ * 1. Exact slug match (e.g., "blog" matches page with slug "blog")
16
+ * 2. Dynamic pattern match (e.g., "blog/my-post" matches "blog/:slug")
17
+ *
18
+ * Dynamic segments are prefixed with ":" (e.g., ":slug", ":id")
19
+ *
20
+ * @param pages - Available pages to match against
21
+ * @param urlPath - URL path to match (e.g., "blog/my-first-post")
22
+ * @returns Match result with page and extracted params, or null
23
+ */
24
+ export declare function matchDynamicPage(pages: SitePage[], urlPath: string): DynamicPageMatch | null;
25
+ //# sourceMappingURL=dynamicPageResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamicPageResolver.d.ts","sourceRoot":"","sources":["../../../src/engine/plugins/dynamicPageResolver.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,EAAE,MAAM,GACd,gBAAgB,GAAG,IAAI,CA4DzB"}
@@ -0,0 +1,32 @@
1
+ function d(l, h) {
2
+ const g = h.replace(/^\/+|\/+$/g, ""), o = g.split("/"), i = l.find((t) => (t.slug || "").replace(/^\/+|\/+$/g, "") === g);
3
+ if (i)
4
+ return { page: i, params: {} };
5
+ let r = null, p = -1;
6
+ for (const t of l) {
7
+ const n = (t.slug || "").replace(/^\/+|\/+$/g, "");
8
+ if (!n.includes(":")) continue;
9
+ const s = n.split("/");
10
+ if (s.length !== o.length) continue;
11
+ const u = {};
12
+ let f = !0, a = 0;
13
+ for (let e = 0; e < s.length; e++) {
14
+ const c = s[e], m = o[e];
15
+ if (c.startsWith(":")) {
16
+ const S = c.slice(1);
17
+ u[S] = decodeURIComponent(m);
18
+ } else if (c === m)
19
+ a++;
20
+ else {
21
+ f = !1;
22
+ break;
23
+ }
24
+ }
25
+ f && a > p && (r = { page: t, params: u }, p = a);
26
+ }
27
+ return r;
28
+ }
29
+ export {
30
+ d as matchDynamicPage
31
+ };
32
+ //# sourceMappingURL=dynamicPageResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamicPageResolver.js","sources":["../../../src/engine/plugins/dynamicPageResolver.ts"],"sourcesContent":["/**\n * Dynamic Page Resolver\n * Matches URL paths against dynamic page slugs (e.g., \"blog/:slug\")\n * and extracts URL parameters.\n */\n\nimport type { SitePage } from \"../schema/siteDocument\";\n\n/**\n * Result of matching a URL path against dynamic pages\n */\nexport interface DynamicPageMatch {\n /** The matched page */\n page: SitePage;\n /** Extracted URL parameters (e.g., { slug: \"my-first-post\" }) */\n params: Record<string, string>;\n}\n\n/**\n * Matches a URL path against pages, supporting dynamic segments.\n *\n * Priority:\n * 1. Exact slug match (e.g., \"blog\" matches page with slug \"blog\")\n * 2. Dynamic pattern match (e.g., \"blog/my-post\" matches \"blog/:slug\")\n *\n * Dynamic segments are prefixed with \":\" (e.g., \":slug\", \":id\")\n *\n * @param pages - Available pages to match against\n * @param urlPath - URL path to match (e.g., \"blog/my-first-post\")\n * @returns Match result with page and extracted params, or null\n */\nexport function matchDynamicPage(\n pages: SitePage[],\n urlPath: string,\n): DynamicPageMatch | null {\n // Normalize: remove leading/trailing slashes\n const normalizedPath = urlPath.replace(/^\\/+|\\/+$/g, \"\");\n const pathSegments = normalizedPath.split(\"/\");\n\n // 1. Try exact match first (highest priority)\n const exactMatch = pages.find((p) => {\n const pageSlug = (p.slug || \"\").replace(/^\\/+|\\/+$/g, \"\");\n return pageSlug === normalizedPath;\n });\n\n if (exactMatch) {\n return { page: exactMatch, params: {} };\n }\n\n // 2. Try dynamic pattern matches\n let bestMatch: DynamicPageMatch | null = null;\n let bestStaticSegments = -1;\n\n for (const page of pages) {\n const pageSlug = (page.slug || \"\").replace(/^\\/+|\\/+$/g, \"\");\n\n // Skip non-dynamic pages (already tried exact match)\n if (!pageSlug.includes(\":\")) continue;\n\n const slugSegments = pageSlug.split(\"/\");\n\n // Segment count must match\n if (slugSegments.length !== pathSegments.length) continue;\n\n const params: Record<string, string> = {};\n let isMatch = true;\n let staticSegments = 0;\n\n for (let i = 0; i < slugSegments.length; i++) {\n const slugPart = slugSegments[i];\n const pathPart = pathSegments[i];\n\n if (slugPart.startsWith(\":\")) {\n // Dynamic segment — extract param\n const paramName = slugPart.slice(1);\n params[paramName] = decodeURIComponent(pathPart);\n } else if (slugPart === pathPart) {\n // Static segment — must match exactly\n staticSegments++;\n } else {\n // No match\n isMatch = false;\n break;\n }\n }\n\n // Prefer matches with more static segments (more specific)\n if (isMatch && staticSegments > bestStaticSegments) {\n bestMatch = { page, params };\n bestStaticSegments = staticSegments;\n }\n }\n\n return bestMatch;\n}\n"],"names":["matchDynamicPage","pages","urlPath","normalizedPath","pathSegments","exactMatch","p","bestMatch","bestStaticSegments","page","pageSlug","slugSegments","params","isMatch","staticSegments","i","slugPart","pathPart","paramName"],"mappings":"AA+BO,SAASA,EACdC,GACAC,GACyB;AAEzB,QAAMC,IAAiBD,EAAQ,QAAQ,cAAc,EAAE,GACjDE,IAAeD,EAAe,MAAM,GAAG,GAGvCE,IAAaJ,EAAM,KAAK,CAACK,OACXA,EAAE,QAAQ,IAAI,QAAQ,cAAc,EAAE,MACpCH,CACrB;AAED,MAAIE;AACF,WAAO,EAAE,MAAMA,GAAY,QAAQ,CAAA,EAAC;AAItC,MAAIE,IAAqC,MACrCC,IAAqB;AAEzB,aAAWC,KAAQR,GAAO;AACxB,UAAMS,KAAYD,EAAK,QAAQ,IAAI,QAAQ,cAAc,EAAE;AAG3D,QAAI,CAACC,EAAS,SAAS,GAAG,EAAG;AAE7B,UAAMC,IAAeD,EAAS,MAAM,GAAG;AAGvC,QAAIC,EAAa,WAAWP,EAAa,OAAQ;AAEjD,UAAMQ,IAAiC,CAAA;AACvC,QAAIC,IAAU,IACVC,IAAiB;AAErB,aAASC,IAAI,GAAGA,IAAIJ,EAAa,QAAQI,KAAK;AAC5C,YAAMC,IAAWL,EAAaI,CAAC,GACzBE,IAAWb,EAAaW,CAAC;AAE/B,UAAIC,EAAS,WAAW,GAAG,GAAG;AAE5B,cAAME,IAAYF,EAAS,MAAM,CAAC;AAClC,QAAAJ,EAAOM,CAAS,IAAI,mBAAmBD,CAAQ;AAAA,MACjD,WAAWD,MAAaC;AAEtB,QAAAH;AAAA,WACK;AAEL,QAAAD,IAAU;AACV;AAAA,MACF;AAAA,IACF;AAGA,IAAIA,KAAWC,IAAiBN,MAC9BD,IAAY,EAAE,MAAAE,GAAM,QAAAG,EAAA,GACpBJ,IAAqBM;AAAA,EAEzB;AAEA,SAAOP;AACT;"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Plugin System — barrel export
3
+ */
4
+ export { pluginRegistry } from './pluginRegistry';
5
+ export type { PluginRegistry } from './pluginRegistry';
6
+ export { hydratePageWithContent } from './contentHydration';
7
+ export type { ContentProviderMap } from './contentHydration';
8
+ export { matchDynamicPage } from './dynamicPageResolver';
9
+ export type { DynamicPageMatch } from './dynamicPageResolver';
10
+ export type { DataSchemaField, DataSchema, ContentListParams, ContentItem, ContentListResult, ContentProvider, PageDataSource, PageEditRestrictions, PageTemplate, EditorRestriction, PluginManifest, PluginRegistration, SitePluginsConfig, } from './types';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/plugins/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,YAAY,EACV,eAAe,EACf,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,SAAS,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { BlockType, SiteDocument } from '../schema/siteDocument';
2
+ import { PluginRegistration, ContentProvider, EditorRestriction, PageTemplate, DataSchema } from './types';
3
+ export interface PluginRegistry {
4
+ /** Registra um plugin (manifest + hooks) */
5
+ register(plugin: PluginRegistration): void;
6
+ /** Retorna um plugin registrado por ID */
7
+ get(pluginId: string): PluginRegistration | undefined;
8
+ /** Retorna todos os plugins registrados */
9
+ getAll(): PluginRegistration[];
10
+ /** Retorna IDs dos plugins ativos num documento */
11
+ getActive(document: SiteDocument): string[];
12
+ /** Ativa um plugin num documento (retorna documento atualizado) */
13
+ activate(document: SiteDocument, pluginId: string): SiteDocument;
14
+ /** Desativa um plugin num documento (retorna documento atualizado) */
15
+ deactivate(document: SiteDocument, pluginId: string): SiteDocument;
16
+ /** Registra um content provider (implementado pelo consumer project) */
17
+ registerContentProvider(provider: ContentProvider): void;
18
+ /** Retorna um content provider por tipo */
19
+ getContentProvider(type: string): ContentProvider | undefined;
20
+ /** Retorna todos os content providers registrados */
21
+ getAllContentProviders(): ContentProvider[];
22
+ /** Retorna restrições de edição para um bloco num documento */
23
+ getEditorRestrictions(document: SiteDocument, blockType: BlockType): EditorRestriction | undefined;
24
+ /** Retorna todos os page templates disponíveis de plugins registrados */
25
+ getPageTemplates(): PageTemplate[];
26
+ /** Retorna page templates de um plugin específico */
27
+ getPageTemplatesForPlugin(pluginId: string): PageTemplate[];
28
+ /** Retorna todos os data schemas de plugins registrados */
29
+ getDataSchemas(): DataSchema[];
30
+ /** Verifica se um plugin tem dependências satisfeitas */
31
+ checkDependencies(pluginId: string): {
32
+ satisfied: boolean;
33
+ missing: string[];
34
+ };
35
+ }
36
+ export declare const pluginRegistry: PluginRegistry;
37
+ //# sourceMappingURL=pluginRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginRegistry.d.ts","sourceRoot":"","sources":["../../../src/engine/plugins/pluginRegistry.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtE,OAAO,KAAK,EAEV,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,UAAU,EAEX,MAAM,SAAS,CAAC;AAMjB,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAE3C,0CAA0C;IAC1C,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAEtD,2CAA2C;IAC3C,MAAM,IAAI,kBAAkB,EAAE,CAAC;IAE/B,mDAAmD;IACnD,SAAS,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,EAAE,CAAC;IAE5C,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC;IAEjE,sEAAsE;IACtE,UAAU,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC;IAEnE,wEAAwE;IACxE,uBAAuB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IAEzD,2CAA2C;IAC3C,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IAE9D,qDAAqD;IACrD,sBAAsB,IAAI,eAAe,EAAE,CAAC;IAE5C,+DAA+D;IAC/D,qBAAqB,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAC;IAEnG,yEAAyE;IACzE,gBAAgB,IAAI,YAAY,EAAE,CAAC;IAEnC,qDAAqD;IACrD,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IAE5D,2DAA2D;IAC3D,cAAc,IAAI,UAAU,EAAE,CAAC;IAE/B,yDAAyD;IACzD,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAChF;AA8OD,eAAO,MAAM,cAAc,EAAE,cAAyC,CAAC"}
@@ -0,0 +1,134 @@
1
+ import { logger as r } from "../../utils/logger.js";
2
+ import { componentRegistry as l } from "../registry/registry.js";
3
+ class c {
4
+ plugins = /* @__PURE__ */ new Map();
5
+ contentProviders = /* @__PURE__ */ new Map();
6
+ register(e) {
7
+ const { id: i } = e.manifest;
8
+ if (this.plugins.has(i) && r.warn(`Plugin "${i}" is already registered. Overwriting...`), this.plugins.set(i, e), e.getBlockDefinitions) {
9
+ const n = e.getBlockDefinitions();
10
+ for (const t of n)
11
+ l.register(t);
12
+ }
13
+ r.debug(`Plugin "${i}" v${e.manifest.version} registered`);
14
+ }
15
+ get(e) {
16
+ return this.plugins.get(e);
17
+ }
18
+ getAll() {
19
+ return Array.from(this.plugins.values());
20
+ }
21
+ getActive(e) {
22
+ return e.plugins?.active ?? [];
23
+ }
24
+ activate(e, i) {
25
+ const n = this.plugins.get(i);
26
+ if (!n)
27
+ return r.error(`Plugin "${i}" not found in registry`), e;
28
+ const t = this.checkDependencies(i);
29
+ if (!t.satisfied)
30
+ return r.error(
31
+ `Plugin "${i}" has unsatisfied dependencies: ${t.missing.join(", ")}`
32
+ ), e;
33
+ const a = e.plugins?.active ?? [];
34
+ if (a.includes(i))
35
+ return r.warn(`Plugin "${i}" is already active`), e;
36
+ const o = {
37
+ active: [...a, i],
38
+ config: e.plugins?.config ?? {}
39
+ };
40
+ n.manifest.defaultConfig && !o.config?.[i] && (o.config = {
41
+ ...o.config,
42
+ [i]: { ...n.manifest.defaultConfig }
43
+ });
44
+ let s = {
45
+ ...e,
46
+ plugins: o
47
+ };
48
+ return n.onActivate && (s = n.onActivate(s)), r.debug(`Plugin "${i}" activated`), s;
49
+ }
50
+ deactivate(e, i) {
51
+ const n = this.plugins.get(i);
52
+ if (!n)
53
+ return r.error(`Plugin "${i}" not found in registry`), e;
54
+ const t = e.plugins?.active ?? [];
55
+ if (!t.includes(i))
56
+ return r.warn(`Plugin "${i}" is not active`), e;
57
+ for (const s of t) {
58
+ if (s === i) continue;
59
+ if (this.plugins.get(s)?.manifest.dependencies?.includes(i))
60
+ return r.error(
61
+ `Cannot deactivate "${i}": plugin "${s}" depends on it`
62
+ ), e;
63
+ }
64
+ const a = {
65
+ active: t.filter((s) => s !== i),
66
+ config: e.plugins?.config ?? {}
67
+ };
68
+ let o = {
69
+ ...e,
70
+ plugins: a
71
+ };
72
+ return n.onDeactivate && (o = n.onDeactivate(o)), r.debug(`Plugin "${i}" deactivated`), o;
73
+ }
74
+ registerContentProvider(e) {
75
+ this.contentProviders.has(e.type) && r.warn(
76
+ `ContentProvider "${e.type}" is already registered. Overwriting...`
77
+ ), this.contentProviders.set(e.type, e), r.debug(`ContentProvider "${e.type}" registered`);
78
+ }
79
+ getContentProvider(e) {
80
+ return this.contentProviders.get(e);
81
+ }
82
+ getAllContentProviders() {
83
+ return Array.from(this.contentProviders.values());
84
+ }
85
+ getEditorRestrictions(e, i) {
86
+ const n = this.getActive(e);
87
+ let t;
88
+ for (const a of n) {
89
+ const o = this.plugins.get(a);
90
+ if (!o?.getEditorRestrictions) continue;
91
+ const s = o.getEditorRestrictions(i);
92
+ s && (t ? (s.lockedFields && (t.lockedFields = [
93
+ .../* @__PURE__ */ new Set([
94
+ ...t.lockedFields ?? [],
95
+ ...s.lockedFields
96
+ ])
97
+ ]), s.editableFields && (t.editableFields ? t.editableFields = t.editableFields.filter(
98
+ (g) => s.editableFields.includes(g)
99
+ ) : t.editableFields = [...s.editableFields])) : t = { ...s });
100
+ }
101
+ return t;
102
+ }
103
+ getPageTemplates() {
104
+ const e = [];
105
+ for (const i of this.plugins.values())
106
+ e.push(...i.manifest.capabilities.pageTemplates);
107
+ return e;
108
+ }
109
+ getPageTemplatesForPlugin(e) {
110
+ const i = this.plugins.get(e);
111
+ return i ? i.manifest.capabilities.pageTemplates : [];
112
+ }
113
+ getDataSchemas() {
114
+ const e = [];
115
+ for (const i of this.plugins.values())
116
+ e.push(...i.manifest.capabilities.dataSchemas);
117
+ return e;
118
+ }
119
+ checkDependencies(e) {
120
+ const i = this.plugins.get(e);
121
+ if (!i)
122
+ return { satisfied: !1, missing: [e] };
123
+ const t = (i.manifest.dependencies ?? []).filter((a) => !this.plugins.has(a));
124
+ return {
125
+ satisfied: t.length === 0,
126
+ missing: t
127
+ };
128
+ }
129
+ }
130
+ const p = new c();
131
+ export {
132
+ p as pluginRegistry
133
+ };
134
+ //# sourceMappingURL=pluginRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pluginRegistry.js","sources":["../../../src/engine/plugins/pluginRegistry.ts"],"sourcesContent":["/**\n * Plugin Registry\n * Registry centralizado para gerenciamento de plugins\n */\n\nimport { logger } from \"../../utils/logger\";\nimport type { BlockType, SiteDocument } from \"../schema/siteDocument\";\nimport type { BlockDefinition } from \"../registry/types\";\nimport { componentRegistry } from \"../registry/registry\";\nimport type {\n PluginManifest,\n PluginRegistration,\n ContentProvider,\n EditorRestriction,\n PageTemplate,\n DataSchema,\n SitePluginsConfig,\n} from \"./types\";\n\n// ============================================================================\n// Plugin Registry Interface\n// ============================================================================\n\nexport interface PluginRegistry {\n /** Registra um plugin (manifest + hooks) */\n register(plugin: PluginRegistration): void;\n\n /** Retorna um plugin registrado por ID */\n get(pluginId: string): PluginRegistration | undefined;\n\n /** Retorna todos os plugins registrados */\n getAll(): PluginRegistration[];\n\n /** Retorna IDs dos plugins ativos num documento */\n getActive(document: SiteDocument): string[];\n\n /** Ativa um plugin num documento (retorna documento atualizado) */\n activate(document: SiteDocument, pluginId: string): SiteDocument;\n\n /** Desativa um plugin num documento (retorna documento atualizado) */\n deactivate(document: SiteDocument, pluginId: string): SiteDocument;\n\n /** Registra um content provider (implementado pelo consumer project) */\n registerContentProvider(provider: ContentProvider): void;\n\n /** Retorna um content provider por tipo */\n getContentProvider(type: string): ContentProvider | undefined;\n\n /** Retorna todos os content providers registrados */\n getAllContentProviders(): ContentProvider[];\n\n /** Retorna restrições de edição para um bloco num documento */\n getEditorRestrictions(document: SiteDocument, blockType: BlockType): EditorRestriction | undefined;\n\n /** Retorna todos os page templates disponíveis de plugins registrados */\n getPageTemplates(): PageTemplate[];\n\n /** Retorna page templates de um plugin específico */\n getPageTemplatesForPlugin(pluginId: string): PageTemplate[];\n\n /** Retorna todos os data schemas de plugins registrados */\n getDataSchemas(): DataSchema[];\n\n /** Verifica se um plugin tem dependências satisfeitas */\n checkDependencies(pluginId: string): { satisfied: boolean; missing: string[] };\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\nclass PluginRegistryImpl implements PluginRegistry {\n private plugins: Map<string, PluginRegistration> = new Map();\n private contentProviders: Map<string, ContentProvider> = new Map();\n\n register(plugin: PluginRegistration): void {\n const { id } = plugin.manifest;\n if (this.plugins.has(id)) {\n logger.warn(`Plugin \"${id}\" is already registered. Overwriting...`);\n }\n this.plugins.set(id, plugin);\n\n // Registrar block definitions do plugin no componentRegistry\n if (plugin.getBlockDefinitions) {\n const definitions = plugin.getBlockDefinitions();\n for (const def of definitions) {\n componentRegistry.register(def);\n }\n }\n\n logger.debug(`Plugin \"${id}\" v${plugin.manifest.version} registered`);\n }\n\n get(pluginId: string): PluginRegistration | undefined {\n return this.plugins.get(pluginId);\n }\n\n getAll(): PluginRegistration[] {\n return Array.from(this.plugins.values());\n }\n\n getActive(document: SiteDocument): string[] {\n return document.plugins?.active ?? [];\n }\n\n activate(document: SiteDocument, pluginId: string): SiteDocument {\n const plugin = this.plugins.get(pluginId);\n if (!plugin) {\n logger.error(`Plugin \"${pluginId}\" not found in registry`);\n return document;\n }\n\n // Verificar dependências\n const deps = this.checkDependencies(pluginId);\n if (!deps.satisfied) {\n logger.error(\n `Plugin \"${pluginId}\" has unsatisfied dependencies: ${deps.missing.join(\", \")}`\n );\n return document;\n }\n\n // Verificar se já está ativo\n const activePlugins = document.plugins?.active ?? [];\n if (activePlugins.includes(pluginId)) {\n logger.warn(`Plugin \"${pluginId}\" is already active`);\n return document;\n }\n\n // Criar plugins config se não existir\n const pluginsConfig: SitePluginsConfig = {\n active: [...activePlugins, pluginId],\n config: document.plugins?.config ?? {},\n };\n\n // Aplicar config padrão se não existir\n if (plugin.manifest.defaultConfig && !pluginsConfig.config?.[pluginId]) {\n pluginsConfig.config = {\n ...pluginsConfig.config,\n [pluginId]: { ...plugin.manifest.defaultConfig },\n };\n }\n\n let updatedDocument: SiteDocument = {\n ...document,\n plugins: pluginsConfig,\n };\n\n // Chamar hook onActivate\n if (plugin.onActivate) {\n updatedDocument = plugin.onActivate(updatedDocument);\n }\n\n logger.debug(`Plugin \"${pluginId}\" activated`);\n return updatedDocument;\n }\n\n deactivate(document: SiteDocument, pluginId: string): SiteDocument {\n const plugin = this.plugins.get(pluginId);\n if (!plugin) {\n logger.error(`Plugin \"${pluginId}\" not found in registry`);\n return document;\n }\n\n const activePlugins = document.plugins?.active ?? [];\n if (!activePlugins.includes(pluginId)) {\n logger.warn(`Plugin \"${pluginId}\" is not active`);\n return document;\n }\n\n // Verificar se outros plugins dependem deste\n for (const active of activePlugins) {\n if (active === pluginId) continue;\n const activePlugin = this.plugins.get(active);\n if (activePlugin?.manifest.dependencies?.includes(pluginId)) {\n logger.error(\n `Cannot deactivate \"${pluginId}\": plugin \"${active}\" depends on it`\n );\n return document;\n }\n }\n\n const pluginsConfig: SitePluginsConfig = {\n active: activePlugins.filter((id) => id !== pluginId),\n config: document.plugins?.config ?? {},\n };\n\n let updatedDocument: SiteDocument = {\n ...document,\n plugins: pluginsConfig,\n };\n\n // Chamar hook onDeactivate\n if (plugin.onDeactivate) {\n updatedDocument = plugin.onDeactivate(updatedDocument);\n }\n\n logger.debug(`Plugin \"${pluginId}\" deactivated`);\n return updatedDocument;\n }\n\n registerContentProvider(provider: ContentProvider): void {\n if (this.contentProviders.has(provider.type)) {\n logger.warn(\n `ContentProvider \"${provider.type}\" is already registered. Overwriting...`\n );\n }\n this.contentProviders.set(provider.type, provider);\n logger.debug(`ContentProvider \"${provider.type}\" registered`);\n }\n\n getContentProvider(type: string): ContentProvider | undefined {\n return this.contentProviders.get(type);\n }\n\n getAllContentProviders(): ContentProvider[] {\n return Array.from(this.contentProviders.values());\n }\n\n getEditorRestrictions(\n document: SiteDocument,\n blockType: BlockType\n ): EditorRestriction | undefined {\n const activePlugins = this.getActive(document);\n\n // Merge restrictions from all active plugins\n let merged: EditorRestriction | undefined;\n\n for (const pluginId of activePlugins) {\n const plugin = this.plugins.get(pluginId);\n if (!plugin?.getEditorRestrictions) continue;\n\n const restriction = plugin.getEditorRestrictions(blockType);\n if (!restriction) continue;\n\n if (!merged) {\n merged = { ...restriction };\n } else {\n // Merge locked fields (union)\n if (restriction.lockedFields) {\n merged.lockedFields = [\n ...new Set([\n ...(merged.lockedFields ?? []),\n ...restriction.lockedFields,\n ]),\n ];\n }\n // Merge editable fields (intersection se ambos definem)\n if (restriction.editableFields) {\n if (merged.editableFields) {\n merged.editableFields = merged.editableFields.filter((f) =>\n restriction.editableFields!.includes(f)\n );\n } else {\n merged.editableFields = [...restriction.editableFields];\n }\n }\n }\n }\n\n return merged;\n }\n\n getPageTemplates(): PageTemplate[] {\n const templates: PageTemplate[] = [];\n for (const plugin of this.plugins.values()) {\n templates.push(...plugin.manifest.capabilities.pageTemplates);\n }\n return templates;\n }\n\n getPageTemplatesForPlugin(pluginId: string): PageTemplate[] {\n const plugin = this.plugins.get(pluginId);\n if (!plugin) return [];\n return plugin.manifest.capabilities.pageTemplates;\n }\n\n getDataSchemas(): DataSchema[] {\n const schemas: DataSchema[] = [];\n for (const plugin of this.plugins.values()) {\n schemas.push(...plugin.manifest.capabilities.dataSchemas);\n }\n return schemas;\n }\n\n checkDependencies(\n pluginId: string\n ): { satisfied: boolean; missing: string[] } {\n const plugin = this.plugins.get(pluginId);\n if (!plugin) {\n return { satisfied: false, missing: [pluginId] };\n }\n\n const deps = plugin.manifest.dependencies ?? [];\n const missing = deps.filter((dep) => !this.plugins.has(dep));\n\n return {\n satisfied: missing.length === 0,\n missing,\n };\n }\n}\n\n// Singleton instance\nexport const pluginRegistry: PluginRegistry = new PluginRegistryImpl();\n"],"names":["PluginRegistryImpl","plugin","id","logger","definitions","def","componentRegistry","pluginId","document","deps","activePlugins","pluginsConfig","updatedDocument","active","provider","type","blockType","merged","restriction","f","templates","schemas","missing","dep","pluginRegistry"],"mappings":"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"}