@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,23 +1,32 @@
1
- import { execFile, spawn } from 'node:child_process';
1
+ import { execFile } from 'node:child_process';
2
2
  import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
3
3
  import net from 'node:net';
4
4
  import { networkInterfaces } from 'node:os';
5
5
  import path from 'node:path';
6
6
  import { promisify } from 'node:util';
7
7
  import { getAstroArgs, runAstroInherit } from './lib/astro-command.mjs';
8
- import projectConfig from './lib/project-config.mjs';
9
8
  import { astroCacheDir, engineRoot, siteProjectRoot } from './lib/site-paths.mjs';
10
9
 
11
10
  const execFileAsync = promisify(execFile);
12
11
 
13
- const port = 4321;
12
+ const port = Number.parseInt(process.env.NORNA_DEV_PORT ?? '4321', 10);
13
+ if (!Number.isInteger(port) || port < 1 || port > 65_535) {
14
+ throw new Error('NORNA_DEV_PORT must be an integer from 1 through 65535.');
15
+ }
16
+ let projectConfig;
17
+ try {
18
+ ({ default: projectConfig } = await import('./lib/project-config.mjs'));
19
+ } catch (error) {
20
+ console.error(error instanceof Error ? error.message : String(error));
21
+ process.exit(1);
22
+ }
14
23
  const localHost = '127.0.0.1';
15
24
  const localUrl = `http://${localHost}:${port}${projectConfig.site.basePath}`;
16
25
  const probeUrls = [
17
26
  localUrl,
18
27
  `http://localhost:${port}${projectConfig.site.basePath}`,
19
28
  ];
20
- const skipOpen = process.env.WALDE_NO_OPEN === '1';
29
+ const skipOpen = process.env.NORNA_NO_OPEN === '1';
21
30
  const statePath = path.join(astroCacheDir, 'dev-local.json');
22
31
  const logPath = path.join(astroCacheDir, 'dev.log');
23
32
  const args = process.argv.slice(2);
@@ -42,19 +51,6 @@ const generateImages = async () => execFileAsync(process.execPath, [path.join(en
42
51
  maxBuffer: 1024 * 1024 * 10,
43
52
  });
44
53
 
45
- const getPortPids = async () => {
46
- try {
47
- const { stdout } = await execFileAsync('lsof', ['-nP', `-iTCP:${port}`, '-sTCP:LISTEN', '-t']);
48
- return [...new Set(stdout.trim().split(/\s+/).map(Number).filter(Number.isInteger))];
49
- } catch (error) {
50
- if (error.code === 1 || error.code === 'ENOENT') {
51
- return [];
52
- }
53
-
54
- throw error;
55
- }
56
- };
57
-
58
54
  const readState = async () => {
59
55
  try {
60
56
  return JSON.parse(await readFile(statePath, 'utf8'));
@@ -72,10 +68,9 @@ const getLanUrls = () => Object.values(networkInterfaces())
72
68
  .filter((network) => network?.family === 'IPv4' && !network.internal)
73
69
  .map((network) => `http://${network.address}:${port}${projectConfig.site.basePath}`);
74
70
 
75
- const writeState = async (pid, host) => {
71
+ const writeState = async (host) => {
76
72
  await mkdir(path.dirname(statePath), { recursive: true });
77
73
  await writeFile(statePath, `${JSON.stringify({
78
- pid,
79
74
  port,
80
75
  host,
81
76
  mode: host === '0.0.0.0' ? 'lan' : 'local',
@@ -88,6 +83,26 @@ const removeState = async () => {
88
83
  await rm(statePath, { force: true });
89
84
  };
90
85
 
86
+ const readDevLog = async () => {
87
+ try {
88
+ return await readFile(logPath, 'utf8');
89
+ } catch (error) {
90
+ if (error.code === 'ENOENT') return '';
91
+ throw error;
92
+ }
93
+ };
94
+
95
+ const getLogExcerpt = (source) => {
96
+ const lines = source.trim().split('\n');
97
+ if (lines.length === 1 && lines[0] === '') return '';
98
+
99
+ const structuredErrorIndex = lines.findLastIndex((line) => /^\[[^\]]*Error\]/u.test(line.trim()));
100
+ const genericErrorIndex = lines.findLastIndex((line) => /^Error(?::|\s+(?!reference\b))/u.test(line.trim()));
101
+ const errorIndex = structuredErrorIndex >= 0 ? structuredErrorIndex : genericErrorIndex;
102
+ const firstLine = errorIndex >= 0 ? errorIndex : Math.max(0, lines.length - 30);
103
+ return lines.slice(firstLine, firstLine + 30).join('\n');
104
+ };
105
+
91
106
  const isPortFreeOnHost = (loopbackHost) => new Promise((resolve, reject) => {
92
107
  const server = net.createServer();
93
108
 
@@ -110,14 +125,36 @@ const isPortFreeOnHost = (loopbackHost) => new Promise((resolve, reject) => {
110
125
  server.listen({ port, host: loopbackHost, ipv6Only: loopbackHost === '::1' });
111
126
  });
112
127
 
113
- const isPortFree = async () => {
114
- for (const loopbackHost of ['127.0.0.1']) {
115
- if (!(await isPortFreeOnHost(loopbackHost))) {
128
+ const isPortListeningOnHost = (host) => new Promise((resolve, reject) => {
129
+ const socket = net.createConnection({ port, host });
130
+ let settled = false;
131
+ const settle = (result) => {
132
+ if (settled) return;
133
+ settled = true;
134
+ socket.destroy();
135
+ resolve(result);
136
+ };
137
+
138
+ socket.once('connect', () => settle(true));
139
+ socket.once('error', (error) => {
140
+ if (['ECONNREFUSED', 'EHOSTUNREACH', 'ENETUNREACH', 'EADDRNOTAVAIL'].includes(error.code)) {
141
+ settle(false);
142
+ return;
143
+ }
144
+
145
+ if (!settled) reject(error);
146
+ });
147
+ socket.setTimeout(500, () => settle(false));
148
+ });
149
+
150
+ const isPortFree = async (host = localHost) => {
151
+ for (const probeHost of ['127.0.0.1', '::1']) {
152
+ if (await isPortListeningOnHost(probeHost)) {
116
153
  return false;
117
154
  }
118
155
  }
119
156
 
120
- return true;
157
+ return isPortFreeOnHost(host);
121
158
  };
122
159
 
123
160
  const sleep = (milliseconds) => new Promise((resolve) => {
@@ -153,12 +190,12 @@ const waitForServer = async () => {
153
190
  throw new Error(`Timed out waiting for ${localUrl}`);
154
191
  };
155
192
 
156
- const waitForPidToStopListening = async (pid) => {
193
+ const waitForPortToBeFree = async (host = localHost) => {
157
194
  const startedAt = Date.now();
158
195
  const timeoutMs = 5_000;
159
196
 
160
197
  while (Date.now() - startedAt < timeoutMs) {
161
- if (!(await getPortPids()).includes(pid)) {
198
+ if (await isPortFree(host)) {
162
199
  return true;
163
200
  }
164
201
 
@@ -168,32 +205,71 @@ const waitForPidToStopListening = async (pid) => {
168
205
  return false;
169
206
  };
170
207
 
171
- const killPortPids = async (pids) => {
208
+ const parseWindowsPortPids = (stdout) => [...new Set(
209
+ stdout
210
+ .trim()
211
+ .split(/\r?\n/u)
212
+ .map((line) => Number.parseInt(line.trim(), 10))
213
+ .filter(Number.isInteger),
214
+ )];
215
+
216
+ const getPortPids = async () => {
217
+ try {
218
+ if (process.platform === 'win32') {
219
+ const { stdout } = await execFileAsync('powershell.exe', [
220
+ '-NoProfile',
221
+ '-Command',
222
+ `(Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue).OwningProcess`,
223
+ ]);
224
+ return parseWindowsPortPids(stdout);
225
+ }
226
+
227
+ const { stdout } = await execFileAsync('lsof', [
228
+ '-nP',
229
+ `-iTCP:${port}`,
230
+ '-sTCP:LISTEN',
231
+ '-t',
232
+ ]);
233
+ return [...new Set(stdout.trim().split(/\s+/u).map(Number).filter(Number.isInteger))];
234
+ } catch (error) {
235
+ if (error.code === 1) return [];
236
+ if (error.code === 'ENOENT') {
237
+ const commandName = process.platform === 'win32' ? 'PowerShell' : 'lsof';
238
+ throw new Error(`Cannot use --kill because ${commandName} is not available. Stop the process on port ${port} manually, then rerun the command.`);
239
+ }
240
+
241
+ throw error;
242
+ }
243
+ };
244
+
245
+ const terminatePortProcesses = async (host) => {
246
+ const pids = await getPortPids();
247
+ if (pids.length === 0) {
248
+ throw new Error(`Port ${port} is occupied, but Norna could not identify its listening process. Stop that process manually, then rerun the command.`);
249
+ }
250
+
172
251
  for (const pid of pids) {
173
252
  console.log(`Stopping process ${pid} on port ${port}.`);
174
253
  try {
175
254
  process.kill(pid, 'SIGTERM');
176
255
  } catch (error) {
177
- if (error.code !== 'ESRCH') {
178
- throw error;
179
- }
256
+ if (error.code !== 'ESRCH') throw error;
180
257
  }
181
258
  }
182
259
 
183
- for (const pid of pids) {
184
- if (await waitForPidToStopListening(pid)) {
185
- continue;
186
- }
260
+ if (await waitForPortToBeFree(host)) return;
187
261
 
262
+ for (const pid of pids) {
188
263
  console.log(`Process ${pid} did not stop; sending SIGKILL.`);
189
264
  try {
190
265
  process.kill(pid, 'SIGKILL');
191
266
  } catch (error) {
192
- if (error.code !== 'ESRCH') {
193
- throw error;
194
- }
267
+ if (error.code !== 'ESRCH') throw error;
195
268
  }
196
- await waitForPidToStopListening(pid);
269
+ }
270
+
271
+ if (!(await waitForPortToBeFree(host))) {
272
+ throw new Error(`Port ${port} is still in use after stopping ${pids.join(', ')}.`);
197
273
  }
198
274
  };
199
275
 
@@ -218,65 +294,49 @@ const openBrowser = async () => {
218
294
 
219
295
  const stopServer = async ({ quiet = false } = {}) => {
220
296
  const state = await readState();
221
-
222
- await runAstro(['dev', 'stop']).catch(() => {});
223
-
224
- if (!state?.pid) {
225
- if (!quiet) {
226
- console.log('No dev:local server is tracked.');
227
- }
228
- return;
229
- }
230
-
231
- const listeningPids = await getPortPids();
232
-
233
- if (!listeningPids.includes(state.pid)) {
234
- await removeState();
235
- if (!quiet) {
236
- console.log('No tracked dev:local server is running.');
237
- }
238
- return;
239
- }
240
-
241
- process.kill(state.pid, 'SIGTERM');
242
-
243
- if (!(await waitForPidToStopListening(state.pid))) {
244
- process.kill(state.pid, 'SIGKILL');
245
- await waitForPidToStopListening(state.pid);
246
- }
247
-
297
+ const { stdout = '', stderr = '' } = await runAstro(['dev', 'stop']);
298
+ const stopped = `${stdout}\n${stderr}`.includes('Stopped dev server');
299
+ if (stopped) await waitForPortToBeFree(state?.host ?? localHost);
248
300
  await removeState();
249
301
 
250
302
  if (!quiet) {
251
- console.log(`Stopped dev server on ${localUrl}.`);
303
+ console.log(stopped
304
+ ? `Stopped dev server on ${localUrl}.`
305
+ : 'No dev server is tracked for this site.');
252
306
  }
253
307
  };
254
308
 
255
309
  const startServer = async ({ host = localHost, open = true, killBlockingPort = false } = {}) => {
256
310
  await stopServer({ quiet: true });
257
311
 
258
- let existingPids = await getPortPids();
259
- if (existingPids.length > 0 || !(await isPortFree())) {
260
- if (!killBlockingPort || existingPids.length === 0) {
261
- throw new Error(`Port ${port} is already in use. Stop the process using it, then rerun the dev command, or pass --kill.`);
312
+ if (!(await isPortFree(host))) {
313
+ if (!killBlockingPort) {
314
+ throw new Error(`Port ${port} is already in use. Stop the process using it, choose another port with NORNA_DEV_PORT, or rerun the command with --kill.`);
262
315
  }
263
316
 
264
- await killPortPids(existingPids);
265
- await removeState();
266
- existingPids = await getPortPids();
267
-
268
- if (existingPids.length > 0 || !(await isPortFree())) {
269
- throw new Error(`Port ${port} is still in use after trying to stop ${existingPids.join(', ')}.`);
270
- }
317
+ await terminatePortProcesses(host);
271
318
  }
272
319
 
273
320
  await syncSitePublic();
274
321
  await generateImages();
275
- await runAstroInherit(['dev', '--background', '--host', host, '--port', String(port)]);
322
+ const previousLog = await readDevLog();
323
+ try {
324
+ await runAstroInherit(['dev', '--background', '--host', host, '--port', String(port)]);
325
+ } catch (error) {
326
+ const currentLog = await readDevLog();
327
+ const newLog = currentLog.startsWith(previousLog)
328
+ ? currentLog.slice(previousLog.length)
329
+ : currentLog;
330
+ const excerpt = getLogExcerpt(newLog || currentLog);
331
+ throw new Error([
332
+ `Could not start the dev server at ${localUrl}.`,
333
+ excerpt ? `Astro reported:\n${excerpt}` : 'Astro did not write a detailed startup error.',
334
+ `Full log: ${logPath}`,
335
+ ].join('\n\n'), { cause: error });
336
+ }
276
337
  await waitForServer();
277
338
 
278
- const startedPids = await getPortPids();
279
- await writeState(startedPids[0] ?? null, host);
339
+ await writeState(host);
280
340
  if (open) {
281
341
  await openBrowser();
282
342
  } else {
@@ -295,13 +355,14 @@ const startServer = async ({ host = localHost, open = true, killBlockingPort = f
295
355
 
296
356
  const showStatus = async () => {
297
357
  const state = await readState();
298
- const listeningPids = await getPortPids();
358
+ const { stdout = '', stderr = '' } = await runAstro(['dev', 'status']);
359
+ const tracked = `${stdout}\n${stderr}`.includes('Dev server running at');
299
360
  const reachable = await isServerReachable();
300
361
 
301
- if (state?.pid && listeningPids.includes(state.pid)) {
302
- const reachability = reachable ? '' : ' The listener is active, but the URL probe did not respond.';
303
- console.log(`dev:${state.mode ?? 'local'} is running at ${localUrl} (pid ${state.pid}).${reachability}`);
304
- if (state.host === '0.0.0.0') {
362
+ if (tracked) {
363
+ const reachability = reachable ? '' : ' The server is tracked, but the site URL probe did not respond.';
364
+ console.log(`dev:${state?.mode ?? 'local'} is running at ${localUrl}.${reachability}`);
365
+ if (state?.host === '0.0.0.0') {
305
366
  const lanUrls = getLanUrls();
306
367
  if (lanUrls.length > 0) console.log(`On this local network: ${lanUrls.join(', ')}`);
307
368
  }
@@ -309,10 +370,7 @@ const showStatus = async () => {
309
370
  }
310
371
 
311
372
  if (reachable) {
312
- const detail = state?.pid
313
- ? `the tracked pid ${state.pid} is not listening`
314
- : 'no dev:local state file was found';
315
- console.log(`A server is responding at ${localUrl}, but ${detail}.`);
373
+ console.log(`A server is responding at ${localUrl}, but Astro does not track it for this site.`);
316
374
  return;
317
375
  }
318
376
 
@@ -325,11 +383,7 @@ const showStatus = async () => {
325
383
 
326
384
  const showLogs = async () => {
327
385
  if (shouldFollowLogs) {
328
- const tail = spawn('tail', ['-n', '80', '-f', logPath], { stdio: 'inherit' });
329
- await new Promise((resolve, reject) => {
330
- tail.once('exit', resolve);
331
- tail.once('error', reject);
332
- });
386
+ await runAstroInherit(['dev', 'logs', '--follow']);
333
387
  return;
334
388
  }
335
389
 
@@ -346,23 +400,32 @@ const showLogs = async () => {
346
400
  }
347
401
  };
348
402
 
349
- if (command === 'start') {
350
- await startServer({ open: !skipOpen, killBlockingPort: shouldKillBlockingPort });
351
- } else if (command === 'lan') {
352
- await startServer({ host: '0.0.0.0', open: !skipOpen, killBlockingPort: shouldKillBlockingPort });
353
- } else if (command === 'status') {
354
- await showStatus();
355
- } else if (command === 'logs') {
356
- await showLogs();
357
- } else if (command === 'restart') {
358
- const state = await readState();
359
- await startServer({
360
- host: state?.host === '0.0.0.0' ? '0.0.0.0' : localHost,
361
- open: false,
362
- killBlockingPort: shouldKillBlockingPort,
363
- });
364
- } else if (command === 'stop') {
365
- await stopServer();
366
- } else {
367
- throw new Error(`Unknown dev-local command: ${command}`);
403
+ const runCommand = async () => {
404
+ if (command === 'start') {
405
+ await startServer({ open: !skipOpen, killBlockingPort: shouldKillBlockingPort });
406
+ } else if (command === 'lan') {
407
+ await startServer({ host: '0.0.0.0', open: !skipOpen, killBlockingPort: shouldKillBlockingPort });
408
+ } else if (command === 'status') {
409
+ await showStatus();
410
+ } else if (command === 'logs') {
411
+ await showLogs();
412
+ } else if (command === 'restart') {
413
+ const state = await readState();
414
+ await startServer({
415
+ host: state?.host === '0.0.0.0' ? '0.0.0.0' : localHost,
416
+ open: false,
417
+ killBlockingPort: shouldKillBlockingPort,
418
+ });
419
+ } else if (command === 'stop') {
420
+ await stopServer();
421
+ } else {
422
+ throw new Error(`Unknown dev-local command: ${command}`);
423
+ }
424
+ };
425
+
426
+ try {
427
+ await runCommand();
428
+ } catch (error) {
429
+ console.error(error instanceof Error ? error.message : String(error));
430
+ process.exit(1);
368
431
  }
@@ -4,7 +4,6 @@ import { copyFile, mkdir, readdir, readFile, rm, stat, writeFile } from 'node:fs
4
4
  import path from 'node:path';
5
5
  import { promisify } from 'node:util';
6
6
  import {
7
- getBodySections,
8
7
  getContentFiles,
9
8
  readSiteFile,
10
9
  rasterImageExtensions,
@@ -13,10 +12,7 @@ import {
13
12
  toPosixPath,
14
13
  } from './lib/site-content.mjs';
15
14
  import { readImageDimensions } from './lib/image-dimensions.mjs';
16
- import {
17
- extractNornaMarkdownBlocks,
18
- getNornaBlockImageReferences,
19
- } from './lib/norna-markdown-blocks.mjs';
15
+ import { parsePageMarkdown } from './lib/page-markdown.mjs';
20
16
  import {
21
17
  astroPublicDir,
22
18
  generatedImagesDir,
@@ -105,18 +101,18 @@ const getImageSourceKey = (contentFile, image) => `pages/${contentFile.pageDirec
105
101
 
106
102
  const getReferencedImages = async (contentFile) => {
107
103
  const { body } = await readSiteFile(contentFile.contentPath, contentFile.contentLabel);
108
- const { sections } = await getBodySections(body);
104
+ const page = await parsePageMarkdown(body, { label: contentFile.contentLabel });
109
105
  const references = [];
110
106
 
111
- for (const section of sections) {
112
- const blocks = extractNornaMarkdownBlocks(section.text, { label: contentFile.contentLabel });
113
- for (const { image, line, blockDisplayType } of getNornaBlockImageReferences(blocks)) {
107
+ for (const region of page.regions) {
108
+ if (region.blockErrors.length > 0) throw new Error(region.blockErrors[0].message);
109
+ for (const { image, line, blockDisplayType } of region.managedImages) {
114
110
  references.push({
115
111
  contentFile,
116
112
  image,
117
113
  line,
118
114
  blockDisplayType,
119
- sectionLabel: section.id ?? 'page title',
115
+ sectionLabel: region.id ?? 'page title',
120
116
  sourceKey: getImageSourceKey(contentFile, image),
121
117
  });
122
118
  }
@@ -182,11 +178,11 @@ const validateCarouselOrientations = async (manifest) => {
182
178
 
183
179
  for (const contentFile of contentFiles) {
184
180
  const { body } = await readSiteFile(contentFile.contentPath, contentFile.contentLabel);
185
- const { sections } = await getBodySections(body);
181
+ const page = await parsePageMarkdown(body, { label: contentFile.contentLabel });
186
182
 
187
- for (const section of sections) {
188
- const blocks = extractNornaMarkdownBlocks(section.text, { label: contentFile.contentLabel });
189
- for (const block of blocks.filter((candidate) => candidate.type === 'image-carousel')) {
183
+ for (const region of page.regions) {
184
+ if (region.blockErrors.length > 0) throw new Error(region.blockErrors[0].message);
185
+ for (const block of region.blocks.filter((candidate) => candidate.type === 'image-carousel')) {
190
186
  const orientations = new Set(
191
187
  block.images
192
188
  .map((image) => manifest[getImageSourceKey(contentFile, image.image)])
@@ -198,7 +194,7 @@ const validateCarouselOrientations = async (manifest) => {
198
194
  orientations.delete('square');
199
195
  if (orientations.size > 1) {
200
196
  throw new Error(
201
- `Carousel in ${section.id ? `section "${section.id}"` : 'the page introduction'} on line ${block.line} mixes landscape and portrait images. Use landscape images with optional square images, or portrait images with optional square images.`,
197
+ `Carousel in ${region.id ? `section "${region.id}"` : 'the page introduction'} on line ${block.line} mixes landscape and portrait images. Use landscape images with optional square images, or portrait images with optional square images.`,
202
198
  );
203
199
  }
204
200
  }
@@ -3,6 +3,7 @@ import path from 'node:path';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { z } from 'astro/zod';
5
5
  import {
6
+ categorySchema,
6
7
  configSchema,
7
8
  pageThemeSchema,
8
9
  siteSchema,
@@ -14,6 +15,7 @@ import { applySchemaEditorMetadata } from './lib/schema-editor-metadata.mjs';
14
15
  const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
15
16
  const schemaDirectory = path.join(root, 'schemas');
16
17
  const definitions = [
18
+ ['category.schema.json', 'Norna page category', categorySchema],
17
19
  ['config.schema.json', 'Norna site configuration', configSchema],
18
20
  ['theme.schema.json', 'Norna visual theme', themeVisualSchema],
19
21
  ['page-theme.schema.json', 'Norna page theme', pageThemeSchema],
@@ -32,8 +34,9 @@ for (const [filename, title, schema] of definitions) {
32
34
 
33
35
  schemaFiles.set('manifest.json', `${JSON.stringify({
34
36
  editorApiVersion: 1,
35
- schemaVersion: 2,
37
+ schemaVersion: 3,
36
38
  files: {
39
+ category: 'category.schema.json',
37
40
  config: 'config.schema.json',
38
41
  contentFrontmatter: 'content-frontmatter.schema.json',
39
42
  sitewideContent: 'sitewide-content.schema.json',
@@ -9,6 +9,38 @@ import {
9
9
 
10
10
  const packageName = '@janga/norna';
11
11
  const cliExecutableName = 'norna';
12
+ const standaloneGitignore = `# build output
13
+ dist/
14
+
15
+ # legacy generated public output
16
+ /public/
17
+
18
+ # generated site state
19
+ **/.norna/public/
20
+ **/.norna/.astro/
21
+
22
+ # legacy Astro cache location
23
+ .astro/
24
+
25
+ # dependencies
26
+ node_modules/
27
+
28
+ # logs
29
+ npm-debug.log*
30
+ yarn-debug.log*
31
+ yarn-error.log*
32
+ pnpm-debug.log*
33
+
34
+ # environment variables
35
+ .env
36
+ .env.production
37
+
38
+ # macOS-specific files
39
+ .DS_Store
40
+ `;
41
+ const siteGitignore = `.norna/public/
42
+ .norna/.astro/
43
+ `;
12
44
 
13
45
  const usage = `
14
46
  Usage: norna init <target-dir> [--type standalone|embedded] [--site-dir <path>]
@@ -203,6 +235,8 @@ if (type === 'standalone') {
203
235
  if (siteDirectory !== 'site') targetPackageJson.scripts = {};
204
236
  addNornaScripts(targetPackageJson, nornaScripts, { includeStandaloneAliases: true });
205
237
  await writeFile(targetPackageJsonPath, `${JSON.stringify(targetPackageJson, null, 2)}\n`);
238
+ await writeFile(path.join(targetRoot, '.gitignore'), standaloneGitignore);
239
+ await writeFile(path.join(targetSiteDir, '.gitignore'), siteGitignore);
206
240
  } else {
207
241
  if (!existingEntries) {
208
242
  throw new Error(`Target directory must exist for --type embedded: ${targetRoot}`);
@@ -228,6 +262,7 @@ if (type === 'standalone') {
228
262
  filter: (source) => path.basename(source) !== '.DS_Store',
229
263
  recursive: true,
230
264
  });
265
+ await writeFile(path.join(targetSiteDir, '.gitignore'), siteGitignore);
231
266
  await writeFile(targetPackageJsonPath, `${JSON.stringify(targetPackageJson, null, 2)}\n`);
232
267
  }
233
268
 
@@ -1,6 +1,8 @@
1
1
  import path from 'node:path';
2
2
  import { createRequire } from 'node:module';
3
+ import { mkdirSync } from 'node:fs';
3
4
  import {
5
+ astroRootDir,
4
6
  engineRoot,
5
7
  siteProjectRoot,
6
8
  } from './site-paths.mjs';
@@ -11,18 +13,21 @@ const astroPackagePath = require.resolve('astro/package.json');
11
13
  const astroPackage = require(astroPackagePath);
12
14
 
13
15
  export const astroBinPath = path.join(path.dirname(astroPackagePath), astroPackage.bin.astro);
14
- export const astroConfigPath = path.relative(siteProjectRoot, path.join(engineRoot, 'astro.config.mjs'))
16
+ export const astroConfigPath = path.relative(astroRootDir, path.join(engineRoot, 'astro.config.mjs'))
15
17
  .split(path.sep)
16
18
  .join('/');
17
19
 
18
- export const getAstroArgs = (args) => [
19
- astroBinPath,
20
- '--root',
21
- siteProjectRoot,
22
- '--config',
23
- astroConfigPath,
24
- ...args,
25
- ];
20
+ export const getAstroArgs = (args) => {
21
+ mkdirSync(astroRootDir, { recursive: true });
22
+ return [
23
+ astroBinPath,
24
+ '--root',
25
+ astroRootDir,
26
+ '--config',
27
+ astroConfigPath,
28
+ ...args,
29
+ ];
30
+ };
26
31
 
27
32
  export const runAstroInherit = (args, options = {}) => runInherit(
28
33
  process.execPath,
@@ -0,0 +1,34 @@
1
+ import { mkdir, rename } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+
4
+ export const applyImageSyncPlan = async (
5
+ moves,
6
+ {
7
+ makeDirectory = (directoryPath) => mkdir(directoryPath, { recursive: true }),
8
+ moveFile = rename,
9
+ } = {},
10
+ ) => {
11
+ const completedMoves = [];
12
+
13
+ for (const [index, move] of moves.entries()) {
14
+ try {
15
+ await makeDirectory(path.dirname(move.to));
16
+ await moveFile(move.from, move.to);
17
+ completedMoves.push(move);
18
+ } catch (error) {
19
+ return {
20
+ completedMoves,
21
+ error,
22
+ failedMove: move,
23
+ remainingMoves: moves.slice(index),
24
+ };
25
+ }
26
+ }
27
+
28
+ return {
29
+ completedMoves,
30
+ error: null,
31
+ failedMove: null,
32
+ remainingMoves: [],
33
+ };
34
+ };