@janga/norna 0.7.18 → 0.7.23

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 (615) hide show
  1. package/README.md +22 -12
  2. package/astro.config.mjs +25 -0
  3. package/bin/norna-cli.mjs +8 -2
  4. package/package.json +60 -13
  5. package/schemas/category.schema.json +20 -0
  6. package/schemas/config.schema.json +22 -14
  7. package/schemas/content-frontmatter.schema.json +25 -5
  8. package/schemas/manifest.json +2 -1
  9. package/schemas/page-theme.schema.json +58 -30
  10. package/schemas/sitewide-content.schema.json +20 -19
  11. package/schemas/theme.schema.json +542 -243
  12. package/scripts/add-site-node.mjs +251 -0
  13. package/scripts/check-config.mjs +32 -4
  14. package/scripts/deploy-site.mjs +5 -9
  15. package/scripts/dev-local.mjs +175 -112
  16. package/scripts/generate-images.mjs +11 -15
  17. package/scripts/generate-schemas.mjs +4 -1
  18. package/scripts/init-site.mjs +35 -0
  19. package/scripts/lib/astro-command.mjs +14 -9
  20. package/scripts/lib/content-sync-apply.mjs +34 -0
  21. package/scripts/lib/content-sync-plan.mjs +179 -0
  22. package/scripts/lib/editor-language-service.mjs +156 -177
  23. package/scripts/lib/heading-ids.mjs +4 -2
  24. package/scripts/lib/image-presentation.mjs +2 -0
  25. package/scripts/lib/markdown-links.mjs +182 -0
  26. package/scripts/lib/navigation-model.mjs +36 -19
  27. package/scripts/lib/norna-markdown-blocks.mjs +65 -145
  28. package/scripts/lib/norna-markdown-render-plugin.mjs +37 -0
  29. package/scripts/lib/object.mjs +28 -0
  30. package/scripts/lib/page-aliases.mjs +164 -0
  31. package/scripts/lib/page-markdown.mjs +332 -0
  32. package/scripts/lib/presentation-contract.mjs +266 -0
  33. package/scripts/lib/presentation-palette-metadata.mjs +51 -0
  34. package/scripts/lib/presentation.mjs +508 -79
  35. package/scripts/lib/project-config.mjs +78 -10
  36. package/scripts/lib/schema-definitions.mjs +67 -16
  37. package/scripts/lib/schema-editor-metadata.mjs +126 -24
  38. package/scripts/lib/schema-value-definitions.mjs +30 -12
  39. package/scripts/lib/site-content.mjs +46 -239
  40. package/scripts/lib/site-link-graph.mjs +326 -0
  41. package/scripts/lib/site-page-urls.mjs +10 -0
  42. package/scripts/lib/site-paths.mjs +2 -3
  43. package/scripts/lib/site-structure.mjs +189 -0
  44. package/scripts/lib/sitemap.mjs +34 -0
  45. package/scripts/lib/theme-presets.mjs +118 -119
  46. package/scripts/lib/theme-profiles.mjs +223 -0
  47. package/scripts/lib/typography.mjs +220 -35
  48. package/scripts/lib/yaml-config.mjs +50 -6
  49. package/scripts/lib/yaml-indentation.mjs +86 -0
  50. package/scripts/show-typography.mjs +2 -3
  51. package/scripts/sync-content-sections.mjs +158 -244
  52. package/scripts/sync-site-public.mjs +23 -2
  53. package/src/components/CodeBlockCopyScript.astro +92 -0
  54. package/src/components/DisplaySettings.astro +107 -0
  55. package/src/components/ImageCarousel.astro +38 -13
  56. package/src/components/NavigationPageTree.astro +103 -88
  57. package/src/components/PageAliasRedirect.astro +49 -0
  58. package/src/components/PageContentsNavigation.astro +21 -0
  59. package/src/components/SectionNavigationScript.astro +112 -2
  60. package/src/components/SiteBreadcrumbs.astro +15 -12
  61. package/src/components/SiteNavigation.astro +104 -41
  62. package/src/components/SitePage.astro +76 -40
  63. package/src/components/SiteSection.astro +40 -191
  64. package/src/components/SiteTreeNavigation.astro +10 -10
  65. package/src/content.config.ts +5 -2
  66. package/src/layouts/BaseLayout.astro +55 -9
  67. package/src/lib/generatedImages.ts +0 -7
  68. package/src/lib/readerPreferencesScript.mjs +141 -0
  69. package/src/lib/sectionContent.ts +119 -201
  70. package/src/lib/siteNavigation.ts +36 -18
  71. package/src/lib/sitePages.ts +92 -20
  72. package/src/pages/[...slug].astro +35 -8
  73. package/src/styles/content.css +494 -0
  74. package/src/styles/foundations.css +284 -0
  75. package/src/styles/global.css +6 -2047
  76. package/src/styles/media.css +523 -0
  77. package/src/styles/navigation.css +495 -0
  78. package/src/styles/page-layout.css +437 -0
  79. package/src/styles/responsive.css +525 -0
  80. package/starters/basic/README.md +3 -3
  81. package/docs/README.md +0 -137
  82. package/docs/assets/norna-dog-shelter.jpg +0 -0
  83. package/docs/commands.md +0 -189
  84. package/docs/configuration.md +0 -142
  85. package/docs/content.md +0 -351
  86. package/docs/design/command-organization.md +0 -414
  87. package/docs/design/navigation-and-theme-plan.md +0 -186
  88. package/docs/design/norna-diagram-design.md +0 -159
  89. package/docs/design/site-examples-structure.md +0 -119
  90. package/docs/engine-development.md +0 -215
  91. package/docs/getting-started.md +0 -206
  92. package/docs/how-to/embedded-site.md +0 -35
  93. package/docs/images-and-metadata.md +0 -188
  94. package/docs/local-development.md +0 -82
  95. package/docs/pages.md +0 -190
  96. package/docs/public-files.md +0 -118
  97. package/docs/publishing.md +0 -117
  98. package/docs/requirements.md +0 -54
  99. package/docs/site-files.md +0 -152
  100. package/docs/sitewide-content.md +0 -73
  101. package/docs/theme.md +0 -237
  102. package/docs/typography.md +0 -168
  103. package/examples/README.md +0 -49
  104. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/site.schema.json +0 -35
  105. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/sitewide.schema.json +0 -97
  106. package/examples/complete-sites/dog-shelter-multi-page/.astro/collections/theme.schema.json +0 -852
  107. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-assets.mjs +0 -4
  108. package/examples/complete-sites/dog-shelter-multi-page/.astro/content-modules.mjs +0 -1
  109. package/examples/complete-sites/dog-shelter-multi-page/.astro/content.d.ts +0 -183
  110. package/examples/complete-sites/dog-shelter-multi-page/.astro/data-store.json +0 -1
  111. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev-local.json +0 -8
  112. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.json +0 -13
  113. package/examples/complete-sites/dog-shelter-multi-page/.astro/dev.log +0 -36
  114. package/examples/complete-sites/dog-shelter-multi-page/.astro/settings.json +0 -5
  115. package/examples/complete-sites/dog-shelter-multi-page/.astro/types.d.ts +0 -2
  116. package/examples/complete-sites/dog-shelter-multi-page/README.md +0 -24
  117. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/_metadata.json +0 -74
  118. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  119. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  120. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  121. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  122. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  123. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  124. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  125. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  126. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  127. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  128. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  129. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  130. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  131. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  132. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  133. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  134. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/package.json +0 -3
  135. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  136. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  137. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  138. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  139. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  140. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  141. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  142. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  143. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  144. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  145. package/examples/complete-sites/dog-shelter-multi-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  146. package/examples/complete-sites/dog-shelter-multi-page/site/.norna/generated-images.json +0 -98
  147. package/examples/complete-sites/dog-shelter-multi-page/site/config.yaml +0 -1
  148. package/examples/complete-sites/dog-shelter-multi-page/site/pages/000-home/content.md +0 -23
  149. package/examples/complete-sites/dog-shelter-multi-page/site/pages/000-home/images/shelter-dog.jpg +0 -0
  150. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/content.md +0 -21
  151. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rex.jpg +0 -0
  152. package/examples/complete-sites/dog-shelter-multi-page/site/pages/010-dogs/images/rover.jpg +0 -0
  153. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/content.md +0 -22
  154. package/examples/complete-sites/dog-shelter-multi-page/site/pages/020-adopt/images/adoption-dog.jpg +0 -0
  155. package/examples/complete-sites/dog-shelter-multi-page/site/public/favicon.svg +0 -10
  156. package/examples/complete-sites/dog-shelter-multi-page/site/public/logo.svg +0 -9
  157. package/examples/complete-sites/dog-shelter-multi-page/site/public/robots.txt +0 -2
  158. package/examples/complete-sites/dog-shelter-multi-page/site/sitewide-content.yaml +0 -4
  159. package/examples/complete-sites/dog-shelter-multi-page/site/theme.yaml +0 -1
  160. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/site.schema.json +0 -35
  161. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/sitewide.schema.json +0 -97
  162. package/examples/complete-sites/dog-shelter-single-page/.astro/collections/theme.schema.json +0 -852
  163. package/examples/complete-sites/dog-shelter-single-page/.astro/content-assets.mjs +0 -4
  164. package/examples/complete-sites/dog-shelter-single-page/.astro/content-modules.mjs +0 -1
  165. package/examples/complete-sites/dog-shelter-single-page/.astro/content.d.ts +0 -183
  166. package/examples/complete-sites/dog-shelter-single-page/.astro/data-store.json +0 -1
  167. package/examples/complete-sites/dog-shelter-single-page/.astro/dev-local.json +0 -8
  168. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.json +0 -13
  169. package/examples/complete-sites/dog-shelter-single-page/.astro/dev.log +0 -18
  170. package/examples/complete-sites/dog-shelter-single-page/.astro/settings.json +0 -5
  171. package/examples/complete-sites/dog-shelter-single-page/.astro/types.d.ts +0 -2
  172. package/examples/complete-sites/dog-shelter-single-page/README.md +0 -24
  173. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/_metadata.json +0 -74
  174. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  175. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  176. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  177. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  178. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  179. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  180. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  181. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  182. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  183. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  184. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  185. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  186. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  187. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  188. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  189. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  190. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/package.json +0 -3
  191. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  192. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  193. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  194. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  195. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  196. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  197. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  198. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  199. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  200. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  201. package/examples/complete-sites/dog-shelter-single-page/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  202. package/examples/complete-sites/dog-shelter-single-page/site/.norna/generated-images.json +0 -50
  203. package/examples/complete-sites/dog-shelter-single-page/site/config.yaml +0 -1
  204. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/content.md +0 -37
  205. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/images/foster-dog.jpg +0 -0
  206. package/examples/complete-sites/dog-shelter-single-page/site/pages/000-home/images/rescue-dog.jpg +0 -0
  207. package/examples/complete-sites/dog-shelter-single-page/site/public/favicon.svg +0 -10
  208. package/examples/complete-sites/dog-shelter-single-page/site/public/logo.svg +0 -9
  209. package/examples/complete-sites/dog-shelter-single-page/site/public/robots.txt +0 -2
  210. package/examples/complete-sites/dog-shelter-single-page/site/sitewide-content.yaml +0 -4
  211. package/examples/complete-sites/dog-shelter-single-page/site/theme.yaml +0 -1
  212. package/examples/feature-demos/media-and-surfaces/.astro/collections/site.schema.json +0 -35
  213. package/examples/feature-demos/media-and-surfaces/.astro/collections/sitewide.schema.json +0 -97
  214. package/examples/feature-demos/media-and-surfaces/.astro/collections/theme.schema.json +0 -844
  215. package/examples/feature-demos/media-and-surfaces/.astro/content-assets.mjs +0 -4
  216. package/examples/feature-demos/media-and-surfaces/.astro/content-modules.mjs +0 -1
  217. package/examples/feature-demos/media-and-surfaces/.astro/content.d.ts +0 -183
  218. package/examples/feature-demos/media-and-surfaces/.astro/data-store.json +0 -1
  219. package/examples/feature-demos/media-and-surfaces/.astro/dev.log +0 -14
  220. package/examples/feature-demos/media-and-surfaces/.astro/settings.json +0 -5
  221. package/examples/feature-demos/media-and-surfaces/.astro/types.d.ts +0 -2
  222. package/examples/feature-demos/media-and-surfaces/README.md +0 -21
  223. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/_metadata.json +0 -80
  224. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  225. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  226. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  227. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  228. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  229. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  230. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  231. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  232. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  233. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  234. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  235. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  236. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js +0 -1389
  237. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  238. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  239. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  240. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  241. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  242. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/package.json +0 -3
  243. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  244. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  245. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  246. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  247. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  248. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  249. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  250. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  251. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  252. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  253. package/examples/feature-demos/media-and-surfaces/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  254. package/examples/feature-demos/media-and-surfaces/site/.norna/generated-images.json +0 -66
  255. package/examples/feature-demos/media-and-surfaces/site/config.yaml +0 -1
  256. package/examples/feature-demos/media-and-surfaces/site/pages/000-home/content.md +0 -15
  257. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/content.md +0 -71
  258. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-carousel.svg +0 -11
  259. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-stack.svg +0 -9
  260. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/card-surfaces.svg +0 -8
  261. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-one.svg +0 -8
  262. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-three.svg +0 -13
  263. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/carousel-two.svg +0 -8
  264. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-one.svg +0 -8
  265. package/examples/feature-demos/media-and-surfaces/site/pages/010-media/images/stack-two.svg +0 -9
  266. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/content.md +0 -42
  267. package/examples/feature-demos/media-and-surfaces/site/pages/020-surfaces/theme.yaml +0 -2
  268. package/examples/feature-demos/media-and-surfaces/site/public/robots.txt +0 -2
  269. package/examples/feature-demos/media-and-surfaces/site/sitewide-content.yaml +0 -2
  270. package/examples/feature-demos/media-and-surfaces/site/theme.yaml +0 -1
  271. package/examples/feature-demos/sitewide-content/.astro/collections/site.schema.json +0 -59
  272. package/examples/feature-demos/sitewide-content/.astro/collections/sitewide.schema.json +0 -138
  273. package/examples/feature-demos/sitewide-content/.astro/collections/theme.schema.json +0 -755
  274. package/examples/feature-demos/sitewide-content/.astro/content-assets.mjs +0 -1
  275. package/examples/feature-demos/sitewide-content/.astro/content-modules.mjs +0 -1
  276. package/examples/feature-demos/sitewide-content/.astro/content.d.ts +0 -183
  277. package/examples/feature-demos/sitewide-content/.astro/data-store.json +0 -1
  278. package/examples/feature-demos/sitewide-content/.astro/dev.json +0 -13
  279. package/examples/feature-demos/sitewide-content/.astro/dev.log +0 -18
  280. package/examples/feature-demos/sitewide-content/.astro/settings.json +0 -5
  281. package/examples/feature-demos/sitewide-content/.astro/types.d.ts +0 -2
  282. package/examples/feature-demos/sitewide-content/README.md +0 -26
  283. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/_metadata.json +0 -74
  284. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js +0 -434
  285. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro-B3JHJyiv.js.map +0 -1
  286. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  287. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  288. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  289. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  290. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  291. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  292. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  293. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  294. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js +0 -1534
  295. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/audit-C3SVr7dT.js.map +0 -1
  296. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js +0 -48
  297. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/highlight-BLtvqtzO.js.map +0 -1
  298. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js +0 -42
  299. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/icons-C92i61-2.js.map +0 -1
  300. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/package.json +0 -3
  301. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  302. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js +0 -190
  303. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/settings-v5GgKks_.js.map +0 -1
  304. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js +0 -458
  305. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/toolbar-BFvJVp26.js.map +0 -1
  306. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js +0 -1016
  307. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/ui-library-Cd35oAvo.js.map +0 -1
  308. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js +0 -32
  309. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/window-vo3A6TMn.js.map +0 -1
  310. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js +0 -111
  311. package/examples/feature-demos/sitewide-content/node_modules/.vite/deps/xray-DwhzGckb.js.map +0 -1
  312. package/examples/feature-demos/sitewide-content/site/.norna/generated-images.json +0 -1
  313. package/examples/feature-demos/sitewide-content/site/config.yaml +0 -1
  314. package/examples/feature-demos/sitewide-content/site/pages/000-home/content.md +0 -17
  315. package/examples/feature-demos/sitewide-content/site/pages/010-logo-and-navigation/content.md +0 -17
  316. package/examples/feature-demos/sitewide-content/site/pages/020-notices/content.md +0 -23
  317. package/examples/feature-demos/sitewide-content/site/pages/030-footer/content.md +0 -18
  318. package/examples/feature-demos/sitewide-content/site/public/logo.svg +0 -6
  319. package/examples/feature-demos/sitewide-content/site/public/robots.txt +0 -2
  320. package/examples/feature-demos/sitewide-content/site/sitewide-content.yaml +0 -14
  321. package/examples/feature-demos/sitewide-content/site/theme.yaml +0 -1
  322. package/examples/feature-demos/theme-preset-documentation/README.md +0 -16
  323. package/examples/feature-demos/theme-preset-documentation/site/.norna/generated-images.json +0 -74
  324. package/examples/feature-demos/theme-preset-documentation/site/config.yaml +0 -1
  325. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/content.md +0 -30
  326. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/black-schnauzer.jpg +0 -0
  327. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/retriever-portrait.jpg +0 -0
  328. package/examples/feature-demos/theme-preset-documentation/site/pages/000-home/images/schnauzer-portrait.jpg +0 -0
  329. package/examples/feature-demos/theme-preset-documentation/site/public/robots.txt +0 -2
  330. package/examples/feature-demos/theme-preset-documentation/site/sitewide-content.yaml +0 -3
  331. package/examples/feature-demos/theme-preset-documentation/site/theme.yaml +0 -1
  332. package/examples/feature-demos/theme-preset-portfolio/README.md +0 -16
  333. package/examples/feature-demos/theme-preset-portfolio/site/.norna/generated-images.json +0 -74
  334. package/examples/feature-demos/theme-preset-portfolio/site/config.yaml +0 -1
  335. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/content.md +0 -31
  336. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/puppy-portrait.jpg +0 -0
  337. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/shepherd-portrait.jpg +0 -0
  338. package/examples/feature-demos/theme-preset-portfolio/site/pages/000-home/images/white-puppy.jpg +0 -0
  339. package/examples/feature-demos/theme-preset-portfolio/site/public/robots.txt +0 -2
  340. package/examples/feature-demos/theme-preset-portfolio/site/sitewide-content.yaml +0 -3
  341. package/examples/feature-demos/theme-preset-portfolio/site/theme.yaml +0 -1
  342. package/examples/feature-demos/theme-preset-project/.astro/collections/routeTheme.schema.json +0 -746
  343. package/examples/feature-demos/theme-preset-project/.astro/collections/site.schema.json +0 -59
  344. package/examples/feature-demos/theme-preset-project/.astro/collections/sitewide.schema.json +0 -138
  345. package/examples/feature-demos/theme-preset-project/.astro/collections/theme.schema.json +0 -755
  346. package/examples/feature-demos/theme-preset-project/.astro/content-assets.mjs +0 -4
  347. package/examples/feature-demos/theme-preset-project/.astro/content-modules.mjs +0 -1
  348. package/examples/feature-demos/theme-preset-project/.astro/content.d.ts +0 -183
  349. package/examples/feature-demos/theme-preset-project/.astro/data-store.json +0 -1
  350. package/examples/feature-demos/theme-preset-project/.astro/dev-local.json +0 -8
  351. package/examples/feature-demos/theme-preset-project/.astro/dev.json +0 -15
  352. package/examples/feature-demos/theme-preset-project/.astro/dev.log +0 -164
  353. package/examples/feature-demos/theme-preset-project/.astro/settings.json +0 -5
  354. package/examples/feature-demos/theme-preset-project/.astro/types.d.ts +0 -2
  355. package/examples/feature-demos/theme-preset-project/README.md +0 -16
  356. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/_metadata.json +0 -80
  357. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  358. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  359. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  360. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  361. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  362. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  363. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  364. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  365. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  366. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  367. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  368. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  369. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/embla-carousel.js +0 -1389
  370. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  371. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  372. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  373. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  374. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  375. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/package.json +0 -3
  376. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  377. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  378. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  379. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  380. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  381. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  382. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  383. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  384. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  385. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  386. package/examples/feature-demos/theme-preset-project/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  387. package/examples/feature-demos/theme-preset-project/site/.norna/generated-images.json +0 -74
  388. package/examples/feature-demos/theme-preset-project/site/config.yaml +0 -1
  389. package/examples/feature-demos/theme-preset-project/site/pages/000-home/content.md +0 -31
  390. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/boxer-portrait.jpg +0 -0
  391. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/grass-puppy.jpg +0 -0
  392. package/examples/feature-demos/theme-preset-project/site/pages/000-home/images/grey-street-dog.jpg +0 -0
  393. package/examples/feature-demos/theme-preset-project/site/public/robots.txt +0 -2
  394. package/examples/feature-demos/theme-preset-project/site/sitewide-content.yaml +0 -3
  395. package/examples/feature-demos/theme-preset-project/site/theme.yaml +0 -1
  396. package/examples/feature-demos/theme-preset-statement/README.md +0 -16
  397. package/examples/feature-demos/theme-preset-statement/site/.norna/generated-images.json +0 -74
  398. package/examples/feature-demos/theme-preset-statement/site/config.yaml +0 -1
  399. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/content.md +0 -31
  400. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/black-pedigree.jpg +0 -0
  401. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/sheepdog-grass.jpg +0 -0
  402. package/examples/feature-demos/theme-preset-statement/site/pages/000-home/images/sheepdog-wide.jpg +0 -0
  403. package/examples/feature-demos/theme-preset-statement/site/public/robots.txt +0 -2
  404. package/examples/feature-demos/theme-preset-statement/site/sitewide-content.yaml +0 -3
  405. package/examples/feature-demos/theme-preset-statement/site/theme.yaml +0 -1
  406. package/fixtures/basic/site/.norna/generated-images.json +0 -1
  407. package/fixtures/basic/site/config.yaml +0 -1
  408. package/fixtures/basic/site/pages/000-home/content.md +0 -14
  409. package/fixtures/basic/site/pages/000-home/images/.gitkeep +0 -1
  410. package/fixtures/basic/site/public/robots.txt +0 -2
  411. package/fixtures/basic/site/sitewide-content.yaml +0 -3
  412. package/fixtures/basic/site/theme.yaml +0 -1
  413. package/fixtures/content-model-v2/.astro/collections/site.schema.json +0 -776
  414. package/fixtures/content-model-v2/.astro/collections/theme.schema.json +0 -668
  415. package/fixtures/content-model-v2/.astro/content-assets.mjs +0 -4
  416. package/fixtures/content-model-v2/.astro/content-modules.mjs +0 -1
  417. package/fixtures/content-model-v2/.astro/content.d.ts +0 -175
  418. package/fixtures/content-model-v2/.astro/data-store.json +0 -1
  419. package/fixtures/content-model-v2/.astro/dev-local.json +0 -8
  420. package/fixtures/content-model-v2/.astro/dev.json +0 -13
  421. package/fixtures/content-model-v2/.astro/dev.log +0 -231
  422. package/fixtures/content-model-v2/.astro/settings.json +0 -5
  423. package/fixtures/content-model-v2/.astro/types.d.ts +0 -2
  424. package/fixtures/content-model-v2/dist/_astro/GalleryGrid.astro_astro_type_script_index_0_lang.B0kxDyGz.js +0 -1
  425. package/fixtures/content-model-v2/dist/_astro/SitePage.BbfZub4g.css +0 -1
  426. package/fixtures/content-model-v2/dist/guide/index.html +0 -3
  427. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-480.webp +0 -0
  428. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-768.webp +0 -0
  429. package/fixtures/content-model-v2/dist/images/generated/intro/detail-27930b14-971.webp +0 -0
  430. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-480.webp +0 -0
  431. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-768.webp +0 -0
  432. package/fixtures/content-model-v2/dist/images/generated/intro/duplicate-49c98f6c-971.webp +0 -0
  433. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-480.webp +0 -0
  434. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-768.webp +0 -0
  435. package/fixtures/content-model-v2/dist/images/generated/intro/hero-6d588a83-971.webp +0 -0
  436. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1080.webp +0 -0
  437. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1440.webp +0 -0
  438. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-1600.webp +0 -0
  439. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-480.webp +0 -0
  440. package/fixtures/content-model-v2/dist/images/generated/plain/image-3770d763-768.webp +0 -0
  441. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-480.webp +0 -0
  442. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-768.webp +0 -0
  443. package/fixtures/content-model-v2/dist/images/generated/routes/010-guide/images/intro/duplicate-5cf614d2-960.webp +0 -0
  444. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1080.webp +0 -0
  445. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1440.webp +0 -0
  446. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-1600.webp +0 -0
  447. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-480.webp +0 -0
  448. package/fixtures/content-model-v2/dist/images/generated/timed/slide-one-3770d763-768.webp +0 -0
  449. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1080.webp +0 -0
  450. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1440.webp +0 -0
  451. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-1600.webp +0 -0
  452. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-480.webp +0 -0
  453. package/fixtures/content-model-v2/dist/images/generated/timed/slide-three-5bdec65e-768.webp +0 -0
  454. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1080.webp +0 -0
  455. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1440.webp +0 -0
  456. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-1600.webp +0 -0
  457. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-480.webp +0 -0
  458. package/fixtures/content-model-v2/dist/images/generated/timed/slide-two-26c08aee-768.webp +0 -0
  459. package/fixtures/content-model-v2/dist/index.html +0 -8
  460. package/fixtures/content-model-v2/node_modules/.vite/deps/_metadata.json +0 -80
  461. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  462. package/fixtures/content-model-v2/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  463. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  464. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  465. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  466. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  467. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  468. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  469. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  470. package/fixtures/content-model-v2/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  471. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  472. package/fixtures/content-model-v2/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  473. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js +0 -1389
  474. package/fixtures/content-model-v2/node_modules/.vite/deps/embla-carousel.js.map +0 -1
  475. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  476. package/fixtures/content-model-v2/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  477. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  478. package/fixtures/content-model-v2/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  479. package/fixtures/content-model-v2/node_modules/.vite/deps/package.json +0 -3
  480. package/fixtures/content-model-v2/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  481. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  482. package/fixtures/content-model-v2/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  483. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  484. package/fixtures/content-model-v2/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  485. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  486. package/fixtures/content-model-v2/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  487. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  488. package/fixtures/content-model-v2/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  489. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  490. package/fixtures/content-model-v2/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  491. package/fixtures/content-model-v2/site/.norna/generated-images.json +0 -210
  492. package/fixtures/content-model-v2/site/config.yaml +0 -1
  493. package/fixtures/content-model-v2/site/pages/000-home/content.md +0 -79
  494. package/fixtures/content-model-v2/site/pages/000-home/images/adopt.svg +0 -9
  495. package/fixtures/content-model-v2/site/pages/000-home/images/detail.jpg +0 -0
  496. package/fixtures/content-model-v2/site/pages/000-home/images/duplicate.jpg +0 -0
  497. package/fixtures/content-model-v2/site/pages/000-home/images/foster.svg +0 -12
  498. package/fixtures/content-model-v2/site/pages/000-home/images/hero.jpg +0 -0
  499. package/fixtures/content-model-v2/site/pages/000-home/images/image.jpg +0 -0
  500. package/fixtures/content-model-v2/site/pages/000-home/images/slide-one.jpg +0 -0
  501. package/fixtures/content-model-v2/site/pages/000-home/images/slide-three.jpg +0 -0
  502. package/fixtures/content-model-v2/site/pages/000-home/images/slide-two.jpg +0 -0
  503. package/fixtures/content-model-v2/site/pages/010-guide/content.md +0 -18
  504. package/fixtures/content-model-v2/site/pages/010-guide/images/duplicate.jpg +0 -0
  505. package/fixtures/content-model-v2/site/theme.yaml +0 -4
  506. package/fixtures/nested-pages/.astro/collections/site.schema.json +0 -35
  507. package/fixtures/nested-pages/.astro/collections/sitewide.schema.json +0 -97
  508. package/fixtures/nested-pages/.astro/collections/theme.schema.json +0 -844
  509. package/fixtures/nested-pages/.astro/content-assets.mjs +0 -4
  510. package/fixtures/nested-pages/.astro/content-modules.mjs +0 -1
  511. package/fixtures/nested-pages/.astro/content.d.ts +0 -183
  512. package/fixtures/nested-pages/.astro/data-store.json +0 -1
  513. package/fixtures/nested-pages/.astro/dev-local.json +0 -8
  514. package/fixtures/nested-pages/.astro/dev.log +0 -1128
  515. package/fixtures/nested-pages/.astro/settings.json +0 -5
  516. package/fixtures/nested-pages/.astro/types.d.ts +0 -2
  517. package/fixtures/nested-pages/node_modules/.vite/deps/_metadata.json +0 -74
  518. package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js +0 -434
  519. package/fixtures/nested-pages/node_modules/.vite/deps/astro-D_GIpJIE.js.map +0 -1
  520. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js +0 -6390
  521. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_aria-query.js.map +0 -1
  522. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js +0 -2702
  523. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_axobject-query.js.map +0 -1
  524. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js +0 -65
  525. package/fixtures/nested-pages/node_modules/.vite/deps/astro_n_html-escaper.js.map +0 -1
  526. package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js +0 -455
  527. package/fixtures/nested-pages/node_modules/.vite/deps/astro_runtime_client_dev-toolbar_entrypoint__js.js.map +0 -1
  528. package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js +0 -1534
  529. package/fixtures/nested-pages/node_modules/.vite/deps/audit-DM9Hkl5B.js.map +0 -1
  530. package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js +0 -48
  531. package/fixtures/nested-pages/node_modules/.vite/deps/highlight-DnZ1ULOL.js.map +0 -1
  532. package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js +0 -42
  533. package/fixtures/nested-pages/node_modules/.vite/deps/icons-RyebKi45.js.map +0 -1
  534. package/fixtures/nested-pages/node_modules/.vite/deps/package.json +0 -3
  535. package/fixtures/nested-pages/node_modules/.vite/deps/rolldown-runtime-BvCyGRYZ.js +0 -4
  536. package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js +0 -190
  537. package/fixtures/nested-pages/node_modules/.vite/deps/settings-DaU-gNnK.js.map +0 -1
  538. package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js +0 -458
  539. package/fixtures/nested-pages/node_modules/.vite/deps/toolbar-63PA619H.js.map +0 -1
  540. package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js +0 -1016
  541. package/fixtures/nested-pages/node_modules/.vite/deps/ui-library--bkcNSYz.js.map +0 -1
  542. package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js +0 -32
  543. package/fixtures/nested-pages/node_modules/.vite/deps/window-jPkpKVcy.js.map +0 -1
  544. package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js +0 -111
  545. package/fixtures/nested-pages/node_modules/.vite/deps/xray-BXCHpEJP.js.map +0 -1
  546. package/fixtures/nested-pages/site/.norna/generated-images.json +0 -10
  547. package/fixtures/nested-pages/site/config.yaml +0 -3
  548. package/fixtures/nested-pages/site/pages/000-home/content.md +0 -15
  549. package/fixtures/nested-pages/site/pages/010-guides/content.md +0 -15
  550. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/content.md +0 -21
  551. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/images/diagram.svg +0 -21
  552. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/pages/010-macos/content.md +0 -18
  553. package/fixtures/nested-pages/site/pages/010-guides/pages/010-installation/theme.yaml +0 -2
  554. package/fixtures/nested-pages/site/pages/010-guides/pages/020-workflows/content.md +0 -11
  555. package/fixtures/nested-pages/site/pages/010-guides/pages/030-release-notes/content.md +0 -9
  556. package/fixtures/nested-pages/site/pages/010-guides/pages/040-configuration/content.md +0 -3
  557. package/fixtures/nested-pages/site/pages/010-guides/pages/050-content/content.md +0 -3
  558. package/fixtures/nested-pages/site/pages/010-guides/pages/060-themes/content.md +0 -3
  559. package/fixtures/nested-pages/site/pages/010-guides/pages/070-images/content.md +0 -3
  560. package/fixtures/nested-pages/site/pages/010-guides/pages/080-cards/content.md +0 -3
  561. package/fixtures/nested-pages/site/pages/010-guides/pages/090-notes/content.md +0 -3
  562. package/fixtures/nested-pages/site/pages/010-guides/pages/100-validation/content.md +0 -3
  563. package/fixtures/nested-pages/site/pages/010-guides/pages/110-synchronization/content.md +0 -3
  564. package/fixtures/nested-pages/site/pages/010-guides/pages/120-building/content.md +0 -3
  565. package/fixtures/nested-pages/site/pages/010-guides/pages/130-publishing/content.md +0 -3
  566. package/fixtures/nested-pages/site/pages/010-guides/pages/140-troubleshooting/content.md +0 -3
  567. package/fixtures/nested-pages/site/pages/010-guides/pages/150-migration/content.md +0 -3
  568. package/fixtures/nested-pages/site/pages/010-guides/pages/160-accessibility/content.md +0 -3
  569. package/fixtures/nested-pages/site/pages/010-guides/pages/170-performance/content.md +0 -3
  570. package/fixtures/nested-pages/site/pages/010-guides/pages/180-security/content.md +0 -3
  571. package/fixtures/nested-pages/site/pages/010-guides/pages/190-localization/content.md +0 -3
  572. package/fixtures/nested-pages/site/pages/010-guides/pages/200-upgrading/content.md +0 -3
  573. package/fixtures/nested-pages/site/pages/010-guides/pages/210-faq/content.md +0 -3
  574. package/fixtures/nested-pages/site/pages/010-guides/theme.yaml +0 -7
  575. package/fixtures/nested-pages/site/pages/020-reference/content.md +0 -10
  576. package/fixtures/nested-pages/site/pages/020-reference/pages/010-installation/content.md +0 -11
  577. package/fixtures/nested-pages/site/theme.yaml +0 -1
  578. package/scripts/build-pages.mjs +0 -69
  579. package/scripts/lib/example-sites.mjs +0 -49
  580. package/scripts/lib/frontmatter-yaml.mjs +0 -113
  581. package/scripts/lib/git-status.mjs +0 -7
  582. package/scripts/release.mjs +0 -153
  583. package/scripts/test-banner-visibility.mjs +0 -80
  584. package/scripts/test-ci-lockfile.mjs +0 -65
  585. package/scripts/test-cli-discovery.mjs +0 -124
  586. package/scripts/test-client-javascript.mjs +0 -225
  587. package/scripts/test-content-check.mjs +0 -621
  588. package/scripts/test-content-model-v2.mjs +0 -1693
  589. package/scripts/test-documentation.mjs +0 -189
  590. package/scripts/test-editor-language-service.mjs +0 -305
  591. package/scripts/test-engine-commands.mjs +0 -204
  592. package/scripts/test-examples.mjs +0 -53
  593. package/scripts/test-heading-ids.mjs +0 -68
  594. package/scripts/test-navigation-model.mjs +0 -63
  595. package/scripts/test-navigation-preview.mjs +0 -108
  596. package/scripts/test-navigation.mjs +0 -157
  597. package/scripts/test-nested-pages.mjs +0 -125
  598. package/scripts/test-package-check.mjs +0 -500
  599. package/scripts/test-page-model.mjs +0 -108
  600. package/scripts/test-project-config.mjs +0 -139
  601. package/scripts/test-schemas.mjs +0 -169
  602. package/scripts/test-site-public.mjs +0 -85
  603. package/scripts/test-theme-presets.mjs +0 -188
  604. package/src/components/SiteNotesScript.astro +0 -43
  605. package/starters/project/.github/workflows/deploy.yml +0 -64
  606. package/starters/project/README.md +0 -84
  607. package/starters/project/package-lock.json +0 -4296
  608. package/starters/project/package.json +0 -37
  609. package/starters/project/site/config.yaml +0 -1
  610. package/starters/project/site/pages/000-home/content.md +0 -119
  611. package/starters/project/site/pages/010-guide/content.md +0 -80
  612. package/starters/project/site/public/robots.txt +0 -2
  613. package/starters/project/site/sitewide-content.yaml +0 -3
  614. package/starters/project/site/theme.yaml +0 -1
  615. package/tsconfig.json +0 -5
@@ -1,44 +1,40 @@
1
- import { execFile } from 'node:child_process';
2
- import { mkdir, rename, stat } from 'node:fs/promises';
3
1
  import { createInterface } from 'node:readline/promises';
4
2
  import { stdin as input, stdout as output } from 'node:process';
5
3
  import path from 'node:path';
6
- import { promisify } from 'node:util';
4
+ import { applyImageSyncPlan } from './lib/content-sync-apply.mjs';
7
5
  import {
8
- extractInlineNoteDiagnostics,
9
- extractMarkdownImageReferences,
10
- extractNornaMarkdownBlockDiagnostics,
11
- getNornaBlockImageReferences,
12
- } from './lib/norna-markdown-blocks.mjs';
6
+ createImageSyncPlan,
7
+ getExpectedImageLabel,
8
+ getImageCandidateLabel,
9
+ } from './lib/content-sync-plan.mjs';
13
10
  import {
14
- getBodySections,
15
- getContentFiles,
16
11
  getImageCandidatesByName,
17
12
  getDeprecatedInlineStyleReferences,
18
13
  readSiteFile,
19
14
  readThemeFile,
15
+ parseContentFrontmatter,
20
16
  toPosixPath,
21
17
  validateContentFrontmatterStructure,
22
18
  validateFrontmatterIndentation,
23
19
  validateThemeYamlStructure,
24
20
  } from './lib/site-content.mjs';
25
- import { getHeadingIdentifierIssues } from './lib/heading-ids.mjs';
21
+ import { getSiteStructure } from './lib/site-structure.mjs';
26
22
  import { readImageDimensions } from './lib/image-dimensions.mjs';
23
+ import { parsePageMarkdownSource } from './lib/page-markdown.mjs';
24
+ import {
25
+ createSiteLinkGraph,
26
+ getSitePublicFiles,
27
+ } from './lib/site-link-graph.mjs';
27
28
  import {
28
29
  siteThemeLabel,
29
30
  siteThemePath,
30
- siteProjectRoot,
31
31
  } from './lib/site-paths.mjs';
32
32
 
33
- const execFileAsync = promisify(execFile);
34
-
35
33
  const args = new Set(process.argv.slice(2));
36
34
  const shouldWrite = args.has('--write');
37
35
  const shouldCheck = args.has('--check') || !shouldWrite;
38
36
  const skipPrompt = args.has('--yes');
39
37
  const issues = [];
40
- const imageMoves = [];
41
- const referencedImagePaths = new Set();
42
38
 
43
39
  const addIssue = ({ severity, message, fix, sectionId, sectionLabel }) => {
44
40
  issues.push({ severity, message, fix, sectionId, sectionLabel });
@@ -46,7 +42,7 @@ const addIssue = ({ severity, message, fix, sectionId, sectionLabel }) => {
46
42
 
47
43
  const hasErrors = () => issues.some((issue) => issue.severity === 'error');
48
44
 
49
- const formatSectionLabel = (contentFile, section) => `${contentFile.contentLabel} [${section.id ?? section.heading}]`;
45
+ const formatSectionLabel = (contentFile, section) => `${contentFile.contentLabel} [${section.id ?? section.title}]`;
50
46
 
51
47
  const addContentIssue = (contentFile, issue) => addIssue({
52
48
  ...issue,
@@ -56,11 +52,18 @@ const addContentIssue = (contentFile, issue) => addIssue({
56
52
 
57
53
  const addSectionIssue = (contentFile, section, issue) => addIssue({
58
54
  ...issue,
59
- sectionId: issue.sectionId ?? `${contentFile.contentLabel}:${section.id ?? section.heading}`,
55
+ sectionId: issue.sectionId ?? `${contentFile.contentLabel}:${section.id ?? section.title}`,
60
56
  sectionLabel: issue.sectionLabel ?? formatSectionLabel(contentFile, section),
61
57
  });
62
58
 
63
- const promptForWrite = async () => {
59
+ const getMovePlanLines = (moves) => [
60
+ 'Planned image moves:',
61
+ ...moves.map((move) => `- ${getImageCandidateLabel({ contentFile: move.sourceContentFile, imagePath: move.from })} -> ${getExpectedImageLabel(move.contentFile, move.imageName)}`),
62
+ ];
63
+
64
+ const promptForWrite = async (moves) => {
65
+ console.log(getMovePlanLines(moves).join('\n'));
66
+
64
67
  if (skipPrompt) return true;
65
68
  if (!process.stdin.isTTY) return false;
66
69
 
@@ -171,185 +174,6 @@ const getAspectRatioLabel = ({ width, height }) => {
171
174
  return `${width / divisor}:${height / divisor}`;
172
175
  };
173
176
 
174
- const getExpectedImagePath = (contentFile, imageName) =>
175
- path.join(contentFile.imagesDir, imageName);
176
-
177
- const getExpectedImageLabel = (contentFile, imageName) =>
178
- `${contentFile.imagesLabel}/${imageName}`;
179
-
180
- const getGlobalImageCandidates = (globalImageCandidatesByName, imageName, expectedPath) =>
181
- (globalImageCandidatesByName.get(imageName) ?? []).filter(({ imagePath }) => imagePath !== expectedPath);
182
-
183
- const getReferenceLabel = (contentFile, section) => `${contentFile.contentLabel} [${section.id ?? 'page title'}]`;
184
-
185
- const getRootLabel = (contentFile) => contentFile.imagesLabel.replace(/\/images$/, '');
186
-
187
- const getCandidateLabel = ({ contentFile, imagePath }) =>
188
- `${contentFile.imagesLabel}/${toPosixPath(path.relative(contentFile.imagesDir, imagePath))}`;
189
-
190
- const addExpectedReference = (expectedReferencesByPath, expectedPath, expectedReference) => {
191
- if (!expectedReferencesByPath.has(expectedPath)) {
192
- expectedReferencesByPath.set(expectedPath, []);
193
- }
194
-
195
- expectedReferencesByPath.get(expectedPath).push(expectedReference);
196
- };
197
-
198
- const addGlobalImageCandidate = (globalImageCandidatesByName, imageName, candidate) => {
199
- if (!globalImageCandidatesByName.has(imageName)) {
200
- globalImageCandidatesByName.set(imageName, []);
201
- }
202
-
203
- globalImageCandidatesByName.get(imageName).push(candidate);
204
- };
205
-
206
- const assertCleanGitForCrossRootSync = async (moves) => {
207
- if (!moves.some((move) => move.crossRoot)) return;
208
-
209
- let stdout = '';
210
- try {
211
- ({ stdout } = await execFileAsync('git', ['status', '--short'], {
212
- cwd: siteProjectRoot,
213
- maxBuffer: 1024 * 1024,
214
- }));
215
- } catch (error) {
216
- addIssue({
217
- severity: 'error',
218
- message: 'Cross-page content sync requires a clean git working tree, but git status could not be checked.',
219
- fix: 'Run content:sync inside a Git worktree, or move cross-page image files manually.',
220
- });
221
- return;
222
- }
223
-
224
- if (!stdout.trim()) return;
225
-
226
- addIssue({
227
- severity: 'error',
228
- message: 'Cross-page content sync requires a clean git working tree before moving files between page image roots.',
229
- fix: `Commit or stash your current changes, then run content:sync again. Current changes:\n${stdout.trim()}`,
230
- });
231
- };
232
-
233
- const addConflictingMoveIssues = () => {
234
- const movesBySource = new Map();
235
- const movesByDestination = new Map();
236
-
237
- for (const move of imageMoves) {
238
- const sourceKey = move.from;
239
- const destinationKey = move.to;
240
-
241
- if (!movesBySource.has(sourceKey)) {
242
- movesBySource.set(sourceKey, []);
243
- }
244
- movesBySource.get(sourceKey).push(move);
245
-
246
- if (!movesByDestination.has(destinationKey)) {
247
- movesByDestination.set(destinationKey, []);
248
- }
249
- movesByDestination.get(destinationKey).push(move);
250
- }
251
-
252
- for (const moves of movesBySource.values()) {
253
- const destinations = new Set(moves.map((move) => move.to));
254
- if (destinations.size <= 1) continue;
255
-
256
- const firstMove = moves[0];
257
- addSectionIssue(firstMove.contentFile, firstMove.section, {
258
- severity: 'error',
259
- message: `Cannot relocate "${firstMove.imageName}" because the same source file is referenced from multiple destinations: ${moves.map((move) => getExpectedImageLabel(move.contentFile, move.imageName)).join(', ')}.`,
260
- fix: 'Duplicate the image manually or rename one of the image files so each move has a single destination.',
261
- });
262
- }
263
-
264
- for (const moves of movesByDestination.values()) {
265
- const sources = new Set(moves.map((move) => move.from));
266
- if (sources.size <= 1) continue;
267
-
268
- const firstMove = moves[0];
269
- addSectionIssue(firstMove.contentFile, firstMove.section, {
270
- severity: 'error',
271
- message: `Cannot relocate "${firstMove.imageName}" because multiple source files would move to ${getExpectedImageLabel(firstMove.contentFile, firstMove.imageName)}: ${moves.map((move) => getCandidateLabel(move.sourceContentFile ? { contentFile: move.sourceContentFile, imagePath: move.from } : move)).join(', ')}.`,
272
- fix: 'Move the intended file manually or rename files so the destination is unambiguous.',
273
- });
274
- }
275
- };
276
-
277
- const validateImageReference = async (
278
- contentFile,
279
- section,
280
- reference,
281
- globalImageCandidatesByName,
282
- expectedReferencesByPath,
283
- ) => {
284
- const imageName = reference.image;
285
- const expectedPath = getExpectedImagePath(contentFile, imageName);
286
- const expectedLabel = getExpectedImageLabel(contentFile, imageName);
287
- const expectedExists = await stat(expectedPath).then((entry) => entry.isFile()).catch(() => false);
288
-
289
- if (expectedExists) {
290
- referencedImagePaths.add(expectedPath);
291
- return expectedPath;
292
- }
293
-
294
- const candidates = getGlobalImageCandidates(globalImageCandidatesByName, imageName, expectedPath);
295
- if (candidates.length === 0) {
296
- addSectionIssue(contentFile, section, {
297
- severity: 'error',
298
- message: `Image "${imageName}" does not exist at ${expectedLabel} or anywhere under any page image root.`,
299
- fix: `Add the source image directly to ${contentFile.imagesLabel}/ or remove the Norna-managed image reference.`,
300
- });
301
- return null;
302
- }
303
-
304
- if (candidates.length > 1) {
305
- addSectionIssue(contentFile, section, {
306
- severity: 'error',
307
- message: `Cannot relocate "${imageName}". Multiple files with this filename were found: ${candidates.map(getCandidateLabel).join(', ')}.`,
308
- fix: 'Move the intended file manually or rename files so the move is unambiguous.',
309
- });
310
- return null;
311
- }
312
-
313
- const sourceCandidate = candidates[0];
314
- const sourcePath = sourceCandidate.imagePath;
315
- const referencesAtCurrentLocation = (expectedReferencesByPath.get(sourcePath) ?? [])
316
- .filter((expectedReference) => expectedReference.contentFile !== contentFile);
317
-
318
- if (referencesAtCurrentLocation.length > 0) {
319
- addSectionIssue(contentFile, section, {
320
- severity: 'error',
321
- message: `Cannot relocate "${imageName}" from ${getCandidateLabel(sourceCandidate)} because it is still referenced from ${referencesAtCurrentLocation.map((expectedReference) => getReferenceLabel(expectedReference.contentFile, expectedReference.section)).join(', ')}.`,
322
- fix: 'Remove the extra reference, duplicate the image file manually, or rename one of the image files so the intended move is unambiguous.',
323
- });
324
- return null;
325
- }
326
-
327
- if (!imageMoves.some((move) => move.from === sourcePath && move.to === expectedPath)) {
328
- imageMoves.push({
329
- imageName,
330
- from: sourcePath,
331
- to: expectedPath,
332
- contentFile,
333
- sourceContentFile: sourceCandidate.contentFile,
334
- section,
335
- crossRoot: sourceCandidate.contentFile !== contentFile,
336
- });
337
- }
338
- referencedImagePaths.add(sourcePath);
339
-
340
- if (!shouldWrite) {
341
- addSectionIssue(contentFile, section, {
342
- severity: 'error',
343
- message: `Image "${imageName}" is used here but is located in ${getCandidateLabel(sourceCandidate)}.`,
344
- fix: sourceCandidate.contentFile === contentFile
345
- ? 'Run norna content:sync to move it directly into the current page image root.'
346
- : `Run norna content:sync to move it from ${getRootLabel(sourceCandidate.contentFile)} to ${getRootLabel(contentFile)}. Cross-page sync requires a clean git working tree when files are moved.`,
347
- });
348
- }
349
-
350
- return sourcePath;
351
- };
352
-
353
177
  const warnAboutCarouselAspectRatios = async (contentFile, section, block, sourcePathsByImage) => {
354
178
  if (block.type !== 'image-carousel') return;
355
179
 
@@ -400,20 +224,48 @@ try {
400
224
  }
401
225
  }
402
226
 
403
- const contentFiles = await getContentFiles();
227
+ const siteStructure = await getSiteStructure();
228
+ const contentFiles = siteStructure.contentFiles;
229
+ for (const warning of siteStructure.warnings) {
230
+ addIssue({
231
+ severity: 'warning',
232
+ message: warning.message,
233
+ sectionId: warning.label,
234
+ sectionLabel: warning.label,
235
+ });
236
+ }
404
237
  const allImageFiles = [];
238
+ const managedImageReferences = [];
405
239
  const contentFileContexts = [];
406
- const globalImageCandidatesByName = new Map();
407
- const globalExpectedReferencesByPath = new Map();
408
240
 
409
241
  for (const contentFile of contentFiles) {
410
- const { frontmatter, body } = await readSiteFile(contentFile.contentPath, contentFile.contentLabel);
242
+ const { frontmatter, frontmatterBody, body, source } = await readSiteFile(contentFile.contentPath, contentFile.contentLabel);
411
243
  const bodyLineOffset = frontmatter.split(/\r?\n/).length - 1;
244
+ const issueCountBeforeFrontmatter = issues.length;
412
245
  validateFrontmatterIndentation(frontmatter, addIssue);
413
246
  validateContentFrontmatterStructure(frontmatter, addIssue);
247
+ let frontmatterData = {};
248
+ if (!issues.slice(issueCountBeforeFrontmatter).some(({ severity }) => severity === 'error')) {
249
+ try {
250
+ frontmatterData = parseContentFrontmatter(frontmatterBody, contentFile.contentLabel);
251
+ } catch (error) {
252
+ addContentIssue(contentFile, {
253
+ severity: 'error',
254
+ message: error instanceof Error ? error.message : String(error),
255
+ fix: 'Correct the page frontmatter using the content reference and project-local schema help.',
256
+ });
257
+ }
258
+ }
414
259
 
415
- const { headings, pageHeadings, prelude, sections } = await getBodySections(body);
416
- const headingIdentifierIssues = getHeadingIdentifierIssues(headings);
260
+ const page = await parsePageMarkdownSource(source, {
261
+ label: contentFile.contentLabel,
262
+ });
263
+ const {
264
+ headingIssues: headingIdentifierIssues,
265
+ pageHeadings,
266
+ prelude,
267
+ regions: sections,
268
+ } = page;
417
269
  const invalidHeadingLines = new Set();
418
270
  for (const issue of headingIdentifierIssues) {
419
271
  invalidHeadingLines.add(issue.heading.line);
@@ -437,9 +289,7 @@ for (const contentFile of contentFiles) {
437
289
 
438
290
  for (const [imageName, candidates] of imageCandidatesByName) {
439
291
  for (const imagePath of candidates) {
440
- const candidate = { contentFile, imagePath };
441
- allImageFiles.push(candidate);
442
- addGlobalImageCandidate(globalImageCandidatesByName, imageName, candidate);
292
+ allImageFiles.push({ contentFile, imageName, imagePath });
443
293
  }
444
294
  }
445
295
 
@@ -457,10 +307,10 @@ for (const contentFile of contentFiles) {
457
307
  });
458
308
  }
459
309
 
460
- if (sections[0] && !sections[0].isPageTitle) {
310
+ if (sections[0] && sections[0].kind !== 'page-intro') {
461
311
  addContentIssue(contentFile, {
462
312
  severity: 'error',
463
- message: `The first content heading is "${sections[0].heading}", but a Norna page must start with its H1 title.`,
313
+ message: `The first content heading is "${sections[0].title}", but a Norna page must start with its H1 title.`,
464
314
  fix: 'Add the page title first, for example "# About".',
465
315
  });
466
316
  }
@@ -474,18 +324,18 @@ for (const contentFile of contentFiles) {
474
324
  }
475
325
 
476
326
  for (const section of sections) {
477
- if (section.isPageTitle) {
327
+ if (section.kind === 'page-intro') {
478
328
  if (
479
329
  pageHeadings.length === 1
480
330
  && sections[0] === section
481
- && !invalidHeadingLines.has(section.line)
331
+ && !invalidHeadingLines.has(section.bodyLine)
482
332
  ) {
483
333
  validSections.add(section);
484
334
  }
485
335
  continue;
486
336
  }
487
337
 
488
- if (invalidHeadingLines.has(section.line) || !section.id) continue;
338
+ if (invalidHeadingLines.has(section.bodyLine) || !section.id) continue;
489
339
 
490
340
  if (sectionsById.has(section.id)) {
491
341
  addSectionIssue(contentFile, section, {
@@ -503,31 +353,25 @@ for (const contentFile of contentFiles) {
503
353
  for (const section of sections) {
504
354
  if (!validSections.has(section)) continue;
505
355
 
506
- const blockResults = extractNornaMarkdownBlockDiagnostics(section.text, {
507
- label: contentFile.contentLabel,
508
- lineOffset: bodyLineOffset + section.line - 1,
509
- });
356
+ const blockResults = { blocks: section.blocks, errors: section.blockErrors };
510
357
  blockResultsBySection.set(section, blockResults);
511
358
 
512
- const inlineNoteResults = extractInlineNoteDiagnostics(section.text, {
513
- label: contentFile.contentLabel,
514
- lineOffset: bodyLineOffset + section.line - 1,
515
- });
516
- for (const error of inlineNoteResults.errors) {
359
+ for (const error of section.noteErrors) {
517
360
  addSectionIssue(contentFile, section, {
518
361
  severity: 'error',
519
362
  message: error.message,
520
363
  });
521
364
  }
522
365
 
523
- for (const reference of getNornaBlockImageReferences(blockResults.blocks)) {
524
- const expectedPath = getExpectedImagePath(contentFile, reference.image);
525
- addExpectedReference(globalExpectedReferencesByPath, expectedPath, { contentFile, section, reference });
366
+ for (const reference of section.managedImages) {
367
+ managedImageReferences.push({ contentFile, section, reference });
526
368
  }
527
369
  }
528
370
 
529
371
  contentFileContexts.push({
530
372
  contentFile,
373
+ frontmatterData,
374
+ page,
531
375
  sections,
532
376
  validSections,
533
377
  blockResultsBySection,
@@ -535,6 +379,44 @@ for (const contentFile of contentFiles) {
535
379
  });
536
380
  }
537
381
 
382
+ const siteLinkGraph = createSiteLinkGraph({
383
+ pageDocuments: contentFileContexts.map(({ contentFile, frontmatterData, page }) => ({
384
+ contentFile,
385
+ data: frontmatterData,
386
+ document: page,
387
+ })),
388
+ publicFiles: await getSitePublicFiles(),
389
+ siteStructure,
390
+ });
391
+ for (const issue of siteLinkGraph.diagnostics) {
392
+ addContentIssue(issue.reference?.sourceContentFile ?? issue.contentFile, issue);
393
+ }
394
+
395
+ const imageSyncPlan = createImageSyncPlan({
396
+ imageCandidates: allImageFiles,
397
+ references: managedImageReferences,
398
+ reportMisplaced: !shouldWrite,
399
+ });
400
+ const {
401
+ moves: imageMoves,
402
+ referencedImagePaths,
403
+ resolvedPathByReference,
404
+ } = imageSyncPlan;
405
+ const plannerIssuesByReference = new Map();
406
+ const plannerConflictIssues = [];
407
+
408
+ for (const plannerIssue of imageSyncPlan.issues) {
409
+ if (plannerIssue.phase === 'conflict') {
410
+ plannerConflictIssues.push(plannerIssue);
411
+ continue;
412
+ }
413
+
414
+ if (!plannerIssuesByReference.has(plannerIssue.reference)) {
415
+ plannerIssuesByReference.set(plannerIssue.reference, []);
416
+ }
417
+ plannerIssuesByReference.get(plannerIssue.reference).push(plannerIssue);
418
+ }
419
+
538
420
  for (const context of contentFileContexts) {
539
421
  const {
540
422
  contentFile,
@@ -555,8 +437,7 @@ for (const context of contentFileContexts) {
555
437
  for (const section of sections) {
556
438
  if (!validSections.has(section)) continue;
557
439
 
558
- const markdownImages = extractMarkdownImageReferences(section.text);
559
- for (const reference of markdownImages) {
440
+ for (const reference of section.markdownImages) {
560
441
  addSectionIssue(contentFile, section, {
561
442
  severity: 'warning',
562
443
  message: `Markdown image "${reference.target}" references a local image that is not managed by Norna.`,
@@ -583,14 +464,12 @@ for (const context of contentFileContexts) {
583
464
  }
584
465
 
585
466
  const sourcePathsByImage = new Map();
586
- for (const reference of getNornaBlockImageReferences(blocks)) {
587
- const sourcePath = await validateImageReference(
588
- contentFile,
589
- section,
590
- reference,
591
- globalImageCandidatesByName,
592
- globalExpectedReferencesByPath,
593
- );
467
+ for (const reference of section.managedImages) {
468
+ for (const plannerIssue of plannerIssuesByReference.get(reference) ?? []) {
469
+ addSectionIssue(plannerIssue.contentFile, plannerIssue.section, plannerIssue.issue);
470
+ }
471
+
472
+ const sourcePath = resolvedPathByReference.get(reference);
594
473
  if (sourcePath) {
595
474
  sourcePathsByImage.set(reference.image, sourcePath);
596
475
  }
@@ -602,17 +481,15 @@ for (const context of contentFileContexts) {
602
481
  }
603
482
  }
604
483
 
484
+ for (const plannerIssue of plannerConflictIssues) {
485
+ addSectionIssue(plannerIssue.contentFile, plannerIssue.section, plannerIssue.issue);
486
+ }
487
+
605
488
  const unreferencedImages = allImageFiles
606
489
  .filter(({ imagePath }) => !referencedImagePaths.has(imagePath))
607
490
  .map(({ contentFile, imagePath }) => `${contentFile.imagesLabel}/${toPosixPath(path.relative(contentFile.imagesDir, imagePath))}`)
608
491
  .sort((left, right) => left.localeCompare(right, 'sv'));
609
492
 
610
- addConflictingMoveIssues();
611
-
612
- if (shouldWrite) {
613
- await assertCleanGitForCrossRootSync(imageMoves);
614
- }
615
-
616
493
  if (hasErrors()) {
617
494
  printReport(shouldWrite ? 'Content sync failed.' : 'Content check failed.', unreferencedImages);
618
495
  process.exit(1);
@@ -631,14 +508,51 @@ if (imageMoves.length === 0) {
631
508
  process.exit(0);
632
509
  }
633
510
 
634
- const canWrite = await promptForWrite();
511
+ const canWrite = await promptForWrite(imageMoves);
635
512
  if (!canWrite) {
636
513
  console.log('Aborted. No file was changed.');
637
514
  process.exit(1);
638
515
  }
639
516
 
640
- for (const move of imageMoves) {
641
- await mkdir(path.dirname(move.to), { recursive: true });
642
- await rename(move.from, move.to);
517
+ const applyResult = await applyImageSyncPlan(imageMoves);
518
+ for (const move of applyResult.completedMoves) {
643
519
  console.log(`Moved image "${move.imageName}" to ${move.contentFile.imagesLabel}/.`);
644
520
  }
521
+
522
+ if (applyResult.failedMove) {
523
+ const move = applyResult.failedMove;
524
+ const error = applyResult.error;
525
+ const sourceLabel = getImageCandidateLabel({ contentFile: move.sourceContentFile, imagePath: move.from });
526
+ const destinationLabel = getExpectedImageLabel(move.contentFile, move.imageName);
527
+ const lines = [
528
+ '',
529
+ `Content sync stopped after ${applyResult.completedMoves.length} of ${imageMoves.length} image moves.`,
530
+ ];
531
+
532
+ if (error?.code === 'EXDEV') {
533
+ lines.push(
534
+ `Cannot move "${move.imageName}" because the source and destination are on different filesystems.`,
535
+ `Move it manually from ${sourceLabel} to ${destinationLabel}.`,
536
+ );
537
+ } else {
538
+ lines.push(
539
+ `Could not move "${move.imageName}" from ${sourceLabel} to ${destinationLabel}.`,
540
+ `Filesystem error${error?.code ? ` (${error.code})` : ''}: ${error?.message ?? String(error)}`,
541
+ );
542
+ }
543
+
544
+ if (applyResult.completedMoves.length > 0) {
545
+ lines.push('', 'Completed moves:', ...getMovePlanLines(applyResult.completedMoves).slice(1));
546
+ }
547
+
548
+ lines.push(
549
+ '',
550
+ 'Remaining moves:',
551
+ ...getMovePlanLines(applyResult.remainingMoves).slice(1),
552
+ '',
553
+ 'Fix the reported filesystem problem, then run content:sync again. Already completed moves will be kept.',
554
+ );
555
+
556
+ console.error(lines.join('\n'));
557
+ process.exit(1);
558
+ }
@@ -1,11 +1,14 @@
1
- import { cp, mkdir, readdir, rm } from 'node:fs/promises';
1
+ import { cp, mkdir, readdir, rm, writeFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
+ import projectConfig from './lib/project-config.mjs';
4
+ import { createSitemapXml, sitemapFilename } from './lib/sitemap.mjs';
3
5
  import {
4
6
  astroPublicDir,
5
7
  astroPublicLabel,
6
8
  sitePublicDir,
7
9
  sitePublicLabel,
8
10
  } from './lib/site-paths.mjs';
11
+ import { getSiteStructure } from './lib/site-structure.mjs';
9
12
 
10
13
  const keepAstroPublicEntries = new Set(['images']);
11
14
 
@@ -21,6 +24,21 @@ const readDirectory = async (directory) => {
21
24
  }
22
25
  };
23
26
 
27
+ const sourceEntries = await readDirectory(sitePublicDir);
28
+ const sitemapConflict = sourceEntries.find(({ name }) => name.toLowerCase() === sitemapFilename);
29
+ if (sitemapConflict) {
30
+ throw new Error([
31
+ `${sitePublicLabel}/${sitemapConflict.name} conflicts with Norna's generated ${sitemapFilename}.`,
32
+ `Remove that source file. Norna generates ${sitemapFilename} from the public page tree and the URL in site/config.yaml.`,
33
+ ].join('\n'));
34
+ }
35
+
36
+ const siteStructure = await getSiteStructure();
37
+ const sitemapXml = createSitemapXml({
38
+ siteStructure,
39
+ siteUrl: projectConfig.site.url,
40
+ });
41
+
24
42
  await mkdir(astroPublicDir, { recursive: true });
25
43
 
26
44
  for (const entry of await readDirectory(astroPublicDir)) {
@@ -31,7 +49,7 @@ for (const entry of await readDirectory(astroPublicDir)) {
31
49
  await rm(path.join(astroPublicDir, entry.name), { force: true, recursive: true });
32
50
  }
33
51
 
34
- for (const entry of await readDirectory(sitePublicDir)) {
52
+ for (const entry of sourceEntries) {
35
53
  await cp(
36
54
  path.join(sitePublicDir, entry.name),
37
55
  path.join(astroPublicDir, entry.name),
@@ -39,4 +57,7 @@ for (const entry of await readDirectory(sitePublicDir)) {
39
57
  );
40
58
  }
41
59
 
60
+ await writeFile(path.join(astroPublicDir, sitemapFilename), sitemapXml);
61
+
42
62
  console.log(`Synced ${sitePublicLabel}/ to ${astroPublicLabel}/.`);
63
+ console.log(`Generated ${astroPublicLabel}/${sitemapFilename} for ${siteStructure.contentFiles.length} public page${siteStructure.contentFiles.length === 1 ? '' : 's'}.`);