@morphemecms/cms 0.1.0 → 0.2.0-next-20261104150211

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 (908) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -21
  3. package/README.md +51 -51
  4. package/astro.mjs +162 -162
  5. package/bin/morpheme.mjs +38 -38
  6. package/client.d.ts +10 -10
  7. package/defaults/blockTexts.ts +33 -33
  8. package/defaults/collections.ts +774 -774
  9. package/defaults/colors.ts +125 -125
  10. package/defaults/company.ts +20 -20
  11. package/defaults/editor.ts +178 -178
  12. package/defaults/internalLinks.ts +30 -30
  13. package/defaults/opens.ts +18 -18
  14. package/defaults/popup.tsx +93 -93
  15. package/defaults/privacy.ts +79 -79
  16. package/defaults/rules.ts +450 -450
  17. package/defaults/schema.ts +16 -16
  18. package/defaults/sitedata.ts +129 -129
  19. package/defaults/standard.ts +106 -106
  20. package/defaults/standardPages.ts +87 -87
  21. package/defaults/texts.ts +481 -481
  22. package/demo/README.md +26 -26
  23. package/demo/src/content/blog/build-a-page-from-blocks.md +19 -19
  24. package/demo/src/content/blog/colors-everyone-can-read.md +19 -19
  25. package/demo/src/content/blog/edit-your-website-from-your-phone.md +21 -21
  26. package/demo/src/content/blog/every-save-is-a-version.md +21 -21
  27. package/demo/src/content/blog/schedule-a-post.md +17 -17
  28. package/demo/src/content/blog/secure-from-day-one.md +17 -17
  29. package/demo/src/content/blog/seo-without-the-guesswork.md +23 -23
  30. package/demo/src/content/blog/switch-themes-without-losing-anything.md +23 -23
  31. package/demo/src/content/blog/the-app-store.md +21 -21
  32. package/demo/src/content/pages/about.md +22 -22
  33. package/demo/src/content/pages/app-store.md +30 -30
  34. package/demo/src/content/pages/blocks.md +98 -98
  35. package/demo/src/content/pages/blog-page.md +11 -11
  36. package/demo/src/content/pages/contact.md +16 -16
  37. package/demo/src/content/pages/get-started.md +20 -20
  38. package/demo/src/content/pages/home.md +26 -26
  39. package/demo/src/content/pages/page-not-found.md +11 -11
  40. package/demo/src/content/pages/privacy-policy.md +24 -24
  41. package/demo/src/data/blocks.json +25 -25
  42. package/demo/src/data/booking.json +6 -6
  43. package/demo/src/data/categories/apps.json +6 -6
  44. package/demo/src/data/categories/design.json +6 -6
  45. package/demo/src/data/categories/editing.json +6 -6
  46. package/demo/src/data/categories/security.json +6 -6
  47. package/demo/src/data/categories/seo.json +6 -6
  48. package/demo/src/data/colors.json +75 -75
  49. package/demo/src/data/contact.json +8 -8
  50. package/demo/src/data/cookies.json +21 -21
  51. package/demo/src/data/footer.json +27 -27
  52. package/demo/src/data/menu.json +35 -35
  53. package/demo/src/data/mobile-menu.json +25 -25
  54. package/demo/src/data/popups/booking-bar.json +13 -13
  55. package/demo/src/data/popups/try-the-editor.json +16 -16
  56. package/demo/src/data/standard-pages.json +8 -8
  57. package/demo/src/data/testimonials/sample-bakery.json +10 -10
  58. package/demo/src/data/testimonials/sample-clinic.json +10 -10
  59. package/demo/src/data/testimonials/sample-studio.json +10 -10
  60. package/demo/src/site/colors.ts +11 -11
  61. package/demo/src/site/config.ts +19 -19
  62. package/icons/lucide/LICENSE +43 -43
  63. package/icons/lucide/address-book.svg +1 -1
  64. package/icons/lucide/app-window.svg +1 -1
  65. package/icons/lucide/arrow-counter-clockwise.svg +1 -1
  66. package/icons/lucide/arrow-down.svg +1 -1
  67. package/icons/lucide/arrow-left.svg +1 -1
  68. package/icons/lucide/arrow-right.svg +1 -1
  69. package/icons/lucide/arrow-square-out.svg +1 -1
  70. package/icons/lucide/arrow-u-up-left.svg +1 -1
  71. package/icons/lucide/arrow-u-up-right.svg +1 -1
  72. package/icons/lucide/arrow-up-right.svg +1 -1
  73. package/icons/lucide/arrow-up.svg +1 -1
  74. package/icons/lucide/arrows-down-up.svg +1 -1
  75. package/icons/lucide/arrows-in-line-horizontal.svg +1 -1
  76. package/icons/lucide/arrows-out-line-horizontal.svg +1 -1
  77. package/icons/lucide/article.svg +1 -1
  78. package/icons/lucide/bank.svg +1 -1
  79. package/icons/lucide/bell.svg +1 -1
  80. package/icons/lucide/bicycle.svg +1 -1
  81. package/icons/lucide/binoculars.svg +1 -1
  82. package/icons/lucide/book-open-text.svg +1 -1
  83. package/icons/lucide/book-open.svg +1 -1
  84. package/icons/lucide/browser.svg +1 -1
  85. package/icons/lucide/buildings.svg +1 -1
  86. package/icons/lucide/bus.svg +1 -1
  87. package/icons/lucide/calendar-blank.svg +1 -1
  88. package/icons/lucide/calendar-check.svg +1 -1
  89. package/icons/lucide/car.svg +1 -1
  90. package/icons/lucide/cards.svg +1 -1
  91. package/icons/lucide/caret-down.svg +1 -1
  92. package/icons/lucide/caret-left.svg +1 -1
  93. package/icons/lucide/caret-right.svg +1 -1
  94. package/icons/lucide/caret-up.svg +1 -1
  95. package/icons/lucide/certificate.svg +1 -1
  96. package/icons/lucide/chart-line-up.svg +1 -1
  97. package/icons/lucide/chats.svg +1 -1
  98. package/icons/lucide/check-circle.svg +1 -1
  99. package/icons/lucide/check.svg +1 -1
  100. package/icons/lucide/circle-half.svg +1 -1
  101. package/icons/lucide/circle.svg +1 -1
  102. package/icons/lucide/clock-counter-clockwise.svg +1 -1
  103. package/icons/lucide/clock.svg +1 -1
  104. package/icons/lucide/code.svg +1 -1
  105. package/icons/lucide/coffee.svg +1 -1
  106. package/icons/lucide/columns.svg +1 -1
  107. package/icons/lucide/cookie.svg +1 -1
  108. package/icons/lucide/copy.svg +1 -1
  109. package/icons/lucide/credit-card.svg +1 -1
  110. package/icons/lucide/currency-circle-dollar.svg +1 -1
  111. package/icons/lucide/cursor-click.svg +1 -1
  112. package/icons/lucide/database.svg +1 -1
  113. package/icons/lucide/desktop.svg +1 -1
  114. package/icons/lucide/device-mobile.svg +1 -1
  115. package/icons/lucide/door-open.svg +1 -1
  116. package/icons/lucide/download-simple.svg +1 -1
  117. package/icons/lucide/envelope-simple.svg +1 -1
  118. package/icons/lucide/eye-slash.svg +1 -1
  119. package/icons/lucide/eye.svg +1 -1
  120. package/icons/lucide/file-pdf.svg +1 -1
  121. package/icons/lucide/file-text.svg +1 -1
  122. package/icons/lucide/file-video.svg +1 -1
  123. package/icons/lucide/file-zip.svg +1 -1
  124. package/icons/lucide/flower-lotus.svg +1 -1
  125. package/icons/lucide/folder-simple.svg +1 -1
  126. package/icons/lucide/funnel.svg +1 -1
  127. package/icons/lucide/gauge.svg +1 -1
  128. package/icons/lucide/gear.svg +1 -1
  129. package/icons/lucide/github-logo.svg +1 -1
  130. package/icons/lucide/globe.svg +1 -1
  131. package/icons/lucide/google-logo.svg +1 -1
  132. package/icons/lucide/graduation-cap.svg +1 -1
  133. package/icons/lucide/hammer.svg +1 -1
  134. package/icons/lucide/hand-heart.svg +1 -1
  135. package/icons/lucide/handshake.svg +1 -1
  136. package/icons/lucide/hard-drives.svg +1 -1
  137. package/icons/lucide/heart.svg +1 -1
  138. package/icons/lucide/house.svg +1 -1
  139. package/icons/lucide/image-square.svg +1 -1
  140. package/icons/lucide/image.svg +1 -1
  141. package/icons/lucide/info.svg +1 -1
  142. package/icons/lucide/keyboard.svg +1 -1
  143. package/icons/lucide/leaf.svg +1 -1
  144. package/icons/lucide/lifebuoy.svg +1 -1
  145. package/icons/lucide/lightbulb.svg +1 -1
  146. package/icons/lucide/link-break.svg +1 -1
  147. package/icons/lucide/link-simple.svg +1 -1
  148. package/icons/lucide/list-bullets.svg +1 -1
  149. package/icons/lucide/list-checks.svg +1 -1
  150. package/icons/lucide/list-numbers.svg +1 -1
  151. package/icons/lucide/list.svg +1 -1
  152. package/icons/lucide/lock-simple-open.svg +1 -1
  153. package/icons/lucide/lock-simple.svg +1 -1
  154. package/icons/lucide/magnifying-glass.svg +1 -1
  155. package/icons/lucide/map-pin.svg +1 -1
  156. package/icons/lucide/map-trifold.svg +1 -1
  157. package/icons/lucide/medal.svg +1 -1
  158. package/icons/lucide/megaphone.svg +1 -1
  159. package/icons/lucide/minus.svg +1 -1
  160. package/icons/lucide/moon.svg +1 -1
  161. package/icons/lucide/newspaper.svg +1 -1
  162. package/icons/lucide/pack.json +23 -23
  163. package/icons/lucide/paint-brush-broad.svg +1 -1
  164. package/icons/lucide/palette.svg +1 -1
  165. package/icons/lucide/paper-plane-tilt.svg +1 -1
  166. package/icons/lucide/pencil-simple.svg +1 -1
  167. package/icons/lucide/phone.svg +1 -1
  168. package/icons/lucide/play-fill.svg +1 -1
  169. package/icons/lucide/plus.svg +1 -1
  170. package/icons/lucide/prohibit.svg +1 -1
  171. package/icons/lucide/puzzle-piece.svg +1 -1
  172. package/icons/lucide/question.svg +1 -1
  173. package/icons/lucide/quotes.svg +1 -1
  174. package/icons/lucide/rows.svg +1 -1
  175. package/icons/lucide/ruler.svg +1 -1
  176. package/icons/lucide/scan.svg +1 -1
  177. package/icons/lucide/shapes.svg +1 -1
  178. package/icons/lucide/share-network.svg +1 -1
  179. package/icons/lucide/shield-check.svg +1 -1
  180. package/icons/lucide/sidebar-simple.svg +1 -1
  181. package/icons/lucide/sign-out.svg +1 -1
  182. package/icons/lucide/signpost.svg +1 -1
  183. package/icons/lucide/sliders-horizontal.svg +1 -1
  184. package/icons/lucide/smiley.svg +1 -1
  185. package/icons/lucide/sparkle.svg +1 -1
  186. package/icons/lucide/square-half-bottom.svg +1 -1
  187. package/icons/lucide/square.svg +1 -1
  188. package/icons/lucide/squares-four.svg +1 -1
  189. package/icons/lucide/sticker.svg +1 -1
  190. package/icons/lucide/storefront.svg +1 -1
  191. package/icons/lucide/sun.svg +1 -1
  192. package/icons/lucide/swatches.svg +1 -1
  193. package/icons/lucide/tag.svg +1 -1
  194. package/icons/lucide/text-aa.svg +1 -1
  195. package/icons/lucide/text-align-left.svg +1 -1
  196. package/icons/lucide/text-b.svg +1 -1
  197. package/icons/lucide/text-h-one.svg +1 -1
  198. package/icons/lucide/text-h-three.svg +1 -1
  199. package/icons/lucide/text-h-two.svg +1 -1
  200. package/icons/lucide/text-italic.svg +1 -1
  201. package/icons/lucide/text-t.svg +1 -1
  202. package/icons/lucide/ticket.svg +1 -1
  203. package/icons/lucide/toggle-right.svg +1 -1
  204. package/icons/lucide/train.svg +1 -1
  205. package/icons/lucide/trash.svg +1 -1
  206. package/icons/lucide/upload-simple.svg +1 -1
  207. package/icons/lucide/user-circle.svg +1 -1
  208. package/icons/lucide/user.svg +1 -1
  209. package/icons/lucide/users-three.svg +1 -1
  210. package/icons/lucide/users.svg +1 -1
  211. package/icons/lucide/video-camera.svg +1 -1
  212. package/icons/lucide/warning-circle.svg +1 -1
  213. package/icons/lucide/warning.svg +1 -1
  214. package/icons/lucide/wave-sine.svg +1 -1
  215. package/icons/lucide/wheelchair.svg +1 -1
  216. package/icons/lucide/wrench.svg +1 -1
  217. package/icons/lucide/x.svg +1 -1
  218. package/icons/material-symbols/LICENSE +201 -201
  219. package/icons/material-symbols/address-book.svg +1 -1
  220. package/icons/material-symbols/app-window.svg +1 -1
  221. package/icons/material-symbols/arrow-counter-clockwise.svg +1 -1
  222. package/icons/material-symbols/arrow-down.svg +1 -1
  223. package/icons/material-symbols/arrow-left.svg +1 -1
  224. package/icons/material-symbols/arrow-right.svg +1 -1
  225. package/icons/material-symbols/arrow-square-out.svg +1 -1
  226. package/icons/material-symbols/arrow-u-up-left.svg +1 -1
  227. package/icons/material-symbols/arrow-u-up-right.svg +1 -1
  228. package/icons/material-symbols/arrow-up-right.svg +1 -1
  229. package/icons/material-symbols/arrow-up.svg +1 -1
  230. package/icons/material-symbols/arrows-down-up.svg +1 -1
  231. package/icons/material-symbols/arrows-in-line-horizontal.svg +1 -1
  232. package/icons/material-symbols/arrows-out-line-horizontal.svg +1 -1
  233. package/icons/material-symbols/article.svg +1 -1
  234. package/icons/material-symbols/bank.svg +1 -1
  235. package/icons/material-symbols/bell.svg +1 -1
  236. package/icons/material-symbols/bicycle.svg +1 -1
  237. package/icons/material-symbols/binoculars.svg +1 -1
  238. package/icons/material-symbols/book-open-text.svg +1 -1
  239. package/icons/material-symbols/book-open.svg +1 -1
  240. package/icons/material-symbols/browser.svg +1 -1
  241. package/icons/material-symbols/buildings.svg +1 -1
  242. package/icons/material-symbols/bus.svg +1 -1
  243. package/icons/material-symbols/calendar-blank.svg +1 -1
  244. package/icons/material-symbols/calendar-check.svg +1 -1
  245. package/icons/material-symbols/car.svg +1 -1
  246. package/icons/material-symbols/cards.svg +1 -1
  247. package/icons/material-symbols/caret-down.svg +1 -1
  248. package/icons/material-symbols/caret-left.svg +1 -1
  249. package/icons/material-symbols/caret-right.svg +1 -1
  250. package/icons/material-symbols/caret-up.svg +1 -1
  251. package/icons/material-symbols/certificate.svg +1 -1
  252. package/icons/material-symbols/chart-line-up.svg +1 -1
  253. package/icons/material-symbols/chats.svg +1 -1
  254. package/icons/material-symbols/check-circle.svg +1 -1
  255. package/icons/material-symbols/check.svg +1 -1
  256. package/icons/material-symbols/circle-half.svg +1 -1
  257. package/icons/material-symbols/circle.svg +1 -1
  258. package/icons/material-symbols/clock-counter-clockwise.svg +1 -1
  259. package/icons/material-symbols/clock.svg +1 -1
  260. package/icons/material-symbols/code.svg +1 -1
  261. package/icons/material-symbols/coffee.svg +1 -1
  262. package/icons/material-symbols/columns.svg +1 -1
  263. package/icons/material-symbols/cookie.svg +1 -1
  264. package/icons/material-symbols/copy.svg +1 -1
  265. package/icons/material-symbols/credit-card.svg +1 -1
  266. package/icons/material-symbols/currency-circle-dollar.svg +1 -1
  267. package/icons/material-symbols/cursor-click.svg +1 -1
  268. package/icons/material-symbols/database.svg +1 -1
  269. package/icons/material-symbols/desktop.svg +1 -1
  270. package/icons/material-symbols/device-mobile.svg +1 -1
  271. package/icons/material-symbols/door-open.svg +1 -1
  272. package/icons/material-symbols/download-simple.svg +1 -1
  273. package/icons/material-symbols/envelope-simple.svg +1 -1
  274. package/icons/material-symbols/eye-slash.svg +1 -1
  275. package/icons/material-symbols/eye.svg +1 -1
  276. package/icons/material-symbols/file-pdf.svg +1 -1
  277. package/icons/material-symbols/file-text.svg +1 -1
  278. package/icons/material-symbols/file-video.svg +1 -1
  279. package/icons/material-symbols/file-zip.svg +1 -1
  280. package/icons/material-symbols/flower-lotus.svg +1 -1
  281. package/icons/material-symbols/folder-simple.svg +1 -1
  282. package/icons/material-symbols/funnel.svg +1 -1
  283. package/icons/material-symbols/gauge.svg +1 -1
  284. package/icons/material-symbols/gear.svg +1 -1
  285. package/icons/material-symbols/github-logo.svg +1 -1
  286. package/icons/material-symbols/globe.svg +1 -1
  287. package/icons/material-symbols/google-logo.svg +1 -1
  288. package/icons/material-symbols/graduation-cap.svg +1 -1
  289. package/icons/material-symbols/hammer.svg +1 -1
  290. package/icons/material-symbols/hand-heart.svg +1 -1
  291. package/icons/material-symbols/handshake.svg +1 -1
  292. package/icons/material-symbols/hard-drives.svg +1 -1
  293. package/icons/material-symbols/heart.svg +1 -1
  294. package/icons/material-symbols/house.svg +1 -1
  295. package/icons/material-symbols/image-square.svg +1 -1
  296. package/icons/material-symbols/image.svg +1 -1
  297. package/icons/material-symbols/info.svg +1 -1
  298. package/icons/material-symbols/keyboard.svg +1 -1
  299. package/icons/material-symbols/leaf.svg +1 -1
  300. package/icons/material-symbols/lifebuoy.svg +1 -1
  301. package/icons/material-symbols/lightbulb.svg +1 -1
  302. package/icons/material-symbols/link-break.svg +1 -1
  303. package/icons/material-symbols/link-simple.svg +1 -1
  304. package/icons/material-symbols/list-bullets.svg +1 -1
  305. package/icons/material-symbols/list-checks.svg +1 -1
  306. package/icons/material-symbols/list-numbers.svg +1 -1
  307. package/icons/material-symbols/list.svg +1 -1
  308. package/icons/material-symbols/lock-simple-open.svg +1 -1
  309. package/icons/material-symbols/lock-simple.svg +1 -1
  310. package/icons/material-symbols/magnifying-glass.svg +1 -1
  311. package/icons/material-symbols/map-pin.svg +1 -1
  312. package/icons/material-symbols/map-trifold.svg +1 -1
  313. package/icons/material-symbols/medal.svg +1 -1
  314. package/icons/material-symbols/megaphone.svg +1 -1
  315. package/icons/material-symbols/minus.svg +1 -1
  316. package/icons/material-symbols/moon.svg +1 -1
  317. package/icons/material-symbols/newspaper.svg +1 -1
  318. package/icons/material-symbols/pack.json +29 -29
  319. package/icons/material-symbols/paint-brush-broad.svg +1 -1
  320. package/icons/material-symbols/palette.svg +1 -1
  321. package/icons/material-symbols/paper-plane-tilt.svg +1 -1
  322. package/icons/material-symbols/pencil-simple.svg +1 -1
  323. package/icons/material-symbols/phone.svg +1 -1
  324. package/icons/material-symbols/play-fill.svg +1 -1
  325. package/icons/material-symbols/plus.svg +1 -1
  326. package/icons/material-symbols/prohibit.svg +1 -1
  327. package/icons/material-symbols/puzzle-piece.svg +1 -1
  328. package/icons/material-symbols/question.svg +1 -1
  329. package/icons/material-symbols/quotes.svg +1 -1
  330. package/icons/material-symbols/rows.svg +1 -1
  331. package/icons/material-symbols/ruler.svg +1 -1
  332. package/icons/material-symbols/scan.svg +1 -1
  333. package/icons/material-symbols/shapes.svg +1 -1
  334. package/icons/material-symbols/share-network.svg +1 -1
  335. package/icons/material-symbols/shield-check.svg +1 -1
  336. package/icons/material-symbols/sidebar-simple.svg +1 -1
  337. package/icons/material-symbols/sign-out.svg +1 -1
  338. package/icons/material-symbols/signpost.svg +1 -1
  339. package/icons/material-symbols/sliders-horizontal.svg +1 -1
  340. package/icons/material-symbols/smiley.svg +1 -1
  341. package/icons/material-symbols/sparkle.svg +1 -1
  342. package/icons/material-symbols/square-half-bottom.svg +1 -1
  343. package/icons/material-symbols/square.svg +1 -1
  344. package/icons/material-symbols/squares-four.svg +1 -1
  345. package/icons/material-symbols/sticker.svg +1 -1
  346. package/icons/material-symbols/storefront.svg +1 -1
  347. package/icons/material-symbols/sun.svg +1 -1
  348. package/icons/material-symbols/swatches.svg +1 -1
  349. package/icons/material-symbols/tag.svg +1 -1
  350. package/icons/material-symbols/text-aa.svg +1 -1
  351. package/icons/material-symbols/text-align-left.svg +1 -1
  352. package/icons/material-symbols/text-b.svg +1 -1
  353. package/icons/material-symbols/text-h-one.svg +1 -1
  354. package/icons/material-symbols/text-h-three.svg +1 -1
  355. package/icons/material-symbols/text-h-two.svg +1 -1
  356. package/icons/material-symbols/text-italic.svg +1 -1
  357. package/icons/material-symbols/text-t.svg +1 -1
  358. package/icons/material-symbols/ticket.svg +1 -1
  359. package/icons/material-symbols/toggle-right.svg +1 -1
  360. package/icons/material-symbols/train.svg +1 -1
  361. package/icons/material-symbols/trash.svg +1 -1
  362. package/icons/material-symbols/upload-simple.svg +1 -1
  363. package/icons/material-symbols/user-circle.svg +1 -1
  364. package/icons/material-symbols/user.svg +1 -1
  365. package/icons/material-symbols/users-three.svg +1 -1
  366. package/icons/material-symbols/users.svg +1 -1
  367. package/icons/material-symbols/video-camera.svg +1 -1
  368. package/icons/material-symbols/warning-circle.svg +1 -1
  369. package/icons/material-symbols/warning.svg +1 -1
  370. package/icons/material-symbols/wave-sine.svg +1 -1
  371. package/icons/material-symbols/wheelchair.svg +1 -1
  372. package/icons/material-symbols/wrench.svg +1 -1
  373. package/icons/material-symbols/x.svg +1 -1
  374. package/icons/phosphor/pack.json +8 -8
  375. package/lib/apps.mjs +142 -139
  376. package/lib/apps.test.d.mts +1 -0
  377. package/lib/apps.test.mjs +50 -0
  378. package/lib/blocks.mjs +90 -90
  379. package/lib/caseCollisions.d.mts +4 -0
  380. package/lib/caseCollisions.mjs +62 -0
  381. package/lib/caseCollisions.test.d.mts +1 -0
  382. package/lib/caseCollisions.test.mjs +74 -0
  383. package/lib/colors.ts +86 -86
  384. package/lib/contactBar.ts +18 -18
  385. package/lib/contracts.d.mts +15 -0
  386. package/lib/contracts.mjs +17 -0
  387. package/lib/cookieCategories.mjs +28 -28
  388. package/lib/crop.mjs +83 -83
  389. package/lib/csp.mjs +130 -130
  390. package/lib/cspSources.mjs +60 -60
  391. package/lib/dynamic-colors.ts +426 -426
  392. package/lib/git.mjs +64 -64
  393. package/lib/hooks.ts +51 -51
  394. package/lib/inline.ts +20 -20
  395. package/lib/license-texts/Apache-2.0.txt +190 -190
  396. package/lib/license-texts/BSD-2-Clause.txt +24 -24
  397. package/lib/license-texts/BSD-3-Clause.txt +28 -28
  398. package/lib/license-texts/ISC.txt +15 -15
  399. package/lib/license-texts/MIT.txt +21 -21
  400. package/lib/licenses.d.mts +1 -1
  401. package/lib/licenses.mjs +683 -683
  402. package/lib/markdown.ts +42 -42
  403. package/lib/motion-schemes.mjs +5 -5
  404. package/lib/motion.ts +131 -131
  405. package/lib/notice.mjs +34 -34
  406. package/lib/scheduled.mjs +37 -37
  407. package/lib/snackbar.ts +149 -149
  408. package/lib/status.mjs +18 -18
  409. package/lib/storeEntries.d.mts +18 -0
  410. package/lib/storeEntries.mjs +64 -0
  411. package/lib/storeEntries.test.d.mts +1 -0
  412. package/lib/storeEntries.test.mjs +71 -0
  413. package/lib/svg.mjs +231 -231
  414. package/lib/text-colors.mjs +43 -43
  415. package/lib/video-id.mjs +72 -72
  416. package/lib/video.mjs +91 -91
  417. package/package.json +136 -131
  418. package/pages/404.astro +10 -10
  419. package/pages/[...slug].astro +51 -51
  420. package/pages/_headers.txt +31 -31
  421. package/pages/blog/index.astro +10 -10
  422. package/pages/blog/kategori/[category].astro +18 -18
  423. package/pages/editor/code-images.json.js +25 -25
  424. package/pages/editor/index.astro +75 -75
  425. package/pages/editor/manifest.webmanifest.js +23 -23
  426. package/pages/editor/sw.js +33 -33
  427. package/pages/editor/sw.js.js +4 -4
  428. package/pages/editor/thumbnails.json.js +21 -21
  429. package/pages/editor/version.json.js +22 -22
  430. package/pages/headers.js +4 -4
  431. package/pages/index.astro +10 -10
  432. package/pages/ny.astro +6 -6
  433. package/pages/robots.txt.js +3 -3
  434. package/pages/rss.xml.js +20 -20
  435. package/scripts/app-screenshots.mjs +164 -164
  436. package/scripts/app-workers.mjs +6 -6
  437. package/scripts/bin.mjs +12 -12
  438. package/scripts/built-site.mjs +134 -99
  439. package/scripts/check-consent.mjs +113 -113
  440. package/scripts/check-content.mjs +151 -149
  441. package/scripts/check-demo.mjs +24 -24
  442. package/scripts/check-store.mjs +160 -0
  443. package/scripts/check-themes.mjs +45 -45
  444. package/scripts/check-worker.mjs +569 -569
  445. package/scripts/compare-html.mjs +81 -81
  446. package/scripts/declarations.mjs +10 -0
  447. package/scripts/declarations.test.mjs +32 -0
  448. package/scripts/demo-site.mjs +42 -42
  449. package/scripts/editor-icons.mjs +56 -56
  450. package/scripts/editor-roundtrip.mjs +134 -134
  451. package/scripts/editor-screens.mjs +101 -101
  452. package/scripts/git-env.mjs +9 -9
  453. package/scripts/icon-packs.mjs +151 -151
  454. package/scripts/link-counts.mjs +22 -22
  455. package/scripts/page-colors.mjs +42 -42
  456. package/scripts/releases.mjs +80 -80
  457. package/scripts/responsive-images.mjs +94 -94
  458. package/scripts/scheduled-list.mjs +15 -15
  459. package/scripts/theme-screenshots.mjs +88 -88
  460. package/scripts/types.mjs +17 -21
  461. package/scripts/video-thumbnails.mjs +89 -89
  462. package/scripts/worker-modules.mjs +34 -34
  463. package/site/appCookies.mjs +74 -74
  464. package/site/apps.ts +21 -21
  465. package/site/autolinks.mjs +200 -200
  466. package/site/blockScripts.ts +31 -31
  467. package/site/categories.ts +16 -16
  468. package/site/consent.ts +26 -26
  469. package/site/content.config.ts +84 -84
  470. package/site/content.ts +104 -104
  471. package/site/cookieList.ts +17 -17
  472. package/site/defineSite.d.mts +2 -14
  473. package/site/defineSite.mjs +131 -136
  474. package/site/directives/interact.mjs +31 -31
  475. package/site/editor-version.mjs +26 -26
  476. package/site/fill.ts +13 -13
  477. package/site/format.ts +11 -11
  478. package/site/home.ts +66 -66
  479. package/site/iconPacks.mjs +43 -43
  480. package/site/icons.mjs +605 -605
  481. package/site/images.mjs +157 -157
  482. package/site/motion.ts +13 -13
  483. package/site/noindex.mjs +21 -21
  484. package/site/pageColors.ts +110 -110
  485. package/site/popups.ts +98 -98
  486. package/site/schema.ts +189 -189
  487. package/site/sections.ts +3 -3
  488. package/site/seo.ts +28 -28
  489. package/site/site.ts +76 -76
  490. package/site/siteConfig.mjs +8 -8
  491. package/site/siteCsp.mjs +75 -75
  492. package/site/siteModules.mjs +27 -27
  493. package/site/standardPages.ts +59 -59
  494. package/site/storeTheme.d.mts +6 -0
  495. package/site/storeTheme.mjs +29 -0
  496. package/site/storeTheme.test.d.mts +1 -0
  497. package/site/storeTheme.test.mjs +53 -0
  498. package/site/testimonials.ts +48 -48
  499. package/site/text.ts +43 -43
  500. package/site/theme.mjs +483 -472
  501. package/site/tracking.client.ts +225 -225
  502. package/site/tracking.ts +9 -9
  503. package/src/ActionParts.tsx +205 -205
  504. package/src/Advanced.tsx +152 -152
  505. package/src/App.tsx +901 -904
  506. package/src/AppList.tsx +1362 -1345
  507. package/src/BlockDialog.tsx +360 -360
  508. package/src/BlockParts.tsx +652 -652
  509. package/src/BlockSettings.tsx +533 -533
  510. package/src/BrandForm.tsx +164 -164
  511. package/src/Colors.tsx +476 -476
  512. package/src/CommunicationParts.tsx +199 -199
  513. package/src/CompanyForm.tsx +209 -209
  514. package/src/Consents.tsx +175 -175
  515. package/src/ContainmentParts.tsx +185 -185
  516. package/src/Crop.tsx +152 -152
  517. package/src/DataForm.tsx +434 -434
  518. package/src/Deleted.tsx +177 -177
  519. package/src/EntryForm.tsx +740 -740
  520. package/src/FileView.tsx +30 -30
  521. package/src/FormFrame.tsx +237 -237
  522. package/src/Keywords.tsx +225 -225
  523. package/src/Library.tsx +1563 -1563
  524. package/src/Licenses.tsx +336 -336
  525. package/src/LinkSheet.tsx +138 -138
  526. package/src/MarkdownEditor.tsx +1075 -1075
  527. package/src/Media.tsx +677 -677
  528. package/src/NavigationParts.tsx +350 -350
  529. package/src/NavigationRestParts.tsx +247 -247
  530. package/src/Notifications.tsx +59 -59
  531. package/src/PagePicker.tsx +136 -136
  532. package/src/Parts.tsx +991 -991
  533. package/src/PartsShown.tsx +168 -168
  534. package/src/PickerParts.tsx +183 -183
  535. package/src/Redirects.tsx +450 -450
  536. package/src/Screen.tsx +184 -184
  537. package/src/SectionsField.tsx +65 -65
  538. package/src/SelectionParts.tsx +134 -134
  539. package/src/SeoScores.tsx +184 -184
  540. package/src/Sheet.tsx +35 -35
  541. package/src/ThemeStore.tsx +376 -376
  542. package/src/Tokens.tsx +346 -346
  543. package/src/Versions.tsx +214 -214
  544. package/src/addresses.ts +75 -75
  545. package/src/allIcons.ts +7 -7
  546. package/src/appFiles.ts +29 -29
  547. package/src/apps.ts +281 -281
  548. package/src/ask.tsx +123 -123
  549. package/src/blocks.ts +251 -251
  550. package/src/brand.ts +153 -153
  551. package/src/cache.ts +42 -42
  552. package/src/check.ts +285 -285
  553. package/src/checkSite.ts +256 -256
  554. package/src/{consents.ts → consentData.ts} +26 -26
  555. package/src/cookieList.ts +70 -70
  556. package/src/countries.ts +59 -59
  557. package/src/deploy.ts +155 -155
  558. package/src/editor.css +602 -602
  559. package/src/examples.ts +85 -85
  560. package/src/fields.tsx +942 -942
  561. package/src/frontmatter.mjs +42 -42
  562. package/src/github.ts +376 -376
  563. package/src/i18n/da-DK/advanced.ts +28 -28
  564. package/src/i18n/da-DK/app.ts +71 -71
  565. package/src/i18n/da-DK/apps.ts +90 -90
  566. package/src/i18n/da-DK/blockSettings.ts +38 -38
  567. package/src/i18n/da-DK/blocks.ts +408 -408
  568. package/src/i18n/da-DK/check.ts +25 -25
  569. package/src/i18n/da-DK/colors.ts +64 -64
  570. package/src/i18n/da-DK/common.ts +118 -118
  571. package/src/i18n/da-DK/company.ts +24 -24
  572. package/src/i18n/da-DK/consents.ts +23 -23
  573. package/src/i18n/da-DK/forms.ts +116 -116
  574. package/src/i18n/da-DK/history.ts +35 -35
  575. package/src/i18n/da-DK/index.ts +49 -49
  576. package/src/i18n/da-DK/keywords.ts +19 -19
  577. package/src/i18n/da-DK/library.ts +135 -135
  578. package/src/i18n/da-DK/licenses.ts +25 -25
  579. package/src/i18n/da-DK/media.ts +79 -79
  580. package/src/i18n/da-DK/parts.ts +696 -696
  581. package/src/i18n/da-DK/preview.ts +13 -13
  582. package/src/i18n/da-DK/redirects.ts +51 -51
  583. package/src/i18n/da-DK/seo.ts +20 -20
  584. package/src/i18n/da-DK/text.ts +35 -35
  585. package/src/i18n/da-DK/theme.ts +41 -41
  586. package/src/i18n/en-US/advanced.ts +32 -32
  587. package/src/i18n/en-US/app.ts +84 -84
  588. package/src/i18n/en-US/apps.ts +134 -134
  589. package/src/i18n/en-US/blockSettings.ts +48 -48
  590. package/src/i18n/en-US/blocks.ts +441 -441
  591. package/src/i18n/en-US/check.ts +31 -31
  592. package/src/i18n/en-US/colors.ts +82 -82
  593. package/src/i18n/en-US/common.ts +144 -144
  594. package/src/i18n/en-US/company.ts +25 -25
  595. package/src/i18n/en-US/consents.ts +25 -25
  596. package/src/i18n/en-US/forms.ts +145 -145
  597. package/src/i18n/en-US/history.ts +43 -43
  598. package/src/i18n/en-US/index.ts +51 -51
  599. package/src/i18n/en-US/keywords.ts +24 -24
  600. package/src/i18n/en-US/library.ts +176 -176
  601. package/src/i18n/en-US/licenses.ts +36 -36
  602. package/src/i18n/en-US/media.ts +80 -80
  603. package/src/i18n/en-US/parts.ts +718 -718
  604. package/src/i18n/en-US/preview.ts +15 -15
  605. package/src/i18n/en-US/redirects.ts +66 -66
  606. package/src/i18n/en-US/seo.ts +26 -26
  607. package/src/i18n/en-US/text.ts +41 -41
  608. package/src/i18n/en-US/theme.ts +41 -41
  609. package/src/i18n/index.ts +124 -124
  610. package/src/icon.tsx +160 -160
  611. package/src/iconPacks.ts +89 -89
  612. package/src/images.ts +163 -163
  613. package/src/{licenses.ts → licenseData.ts} +79 -79
  614. package/src/markdown.mjs +204 -204
  615. package/src/nav.ts +68 -68
  616. package/src/notFound.ts +28 -28
  617. package/src/{notifications.ts → notificationData.ts} +223 -223
  618. package/src/pagePreview.tsx +204 -204
  619. package/src/r2Caching.ts +55 -55
  620. package/src/{redirects.ts → redirectData.ts} +149 -149
  621. package/src/registry.tsx +188 -188
  622. package/src/schema.ts +417 -417
  623. package/src/sections.mjs +303 -303
  624. package/src/seo.ts +333 -333
  625. package/src/shared.ts +44 -44
  626. package/src/sidebar.ts +31 -31
  627. package/src/site.ts +317 -317
  628. package/src/standard/Block.astro +19 -19
  629. package/src/standard/BlockSite.astro +18 -18
  630. package/src/standard/accordion/index.tsx +47 -47
  631. package/src/standard/accordion/load.ts +23 -23
  632. package/src/standard/accordion/shared.ts +15 -15
  633. package/src/standard/accordion/view.ts +32 -32
  634. package/src/standard/buttons/fields.ts +98 -98
  635. package/src/standard/buttons/index.tsx +23 -23
  636. package/src/standard/buttons/load.ts +34 -34
  637. package/src/standard/buttons/shared.ts +12 -12
  638. package/src/standard/buttons/view.ts +30 -30
  639. package/src/standard/cards/index.tsx +71 -71
  640. package/src/standard/cards/load.ts +17 -17
  641. package/src/standard/cards/shared.ts +27 -27
  642. package/src/standard/cards/view.ts +29 -29
  643. package/src/standard/checklist/index.tsx +27 -27
  644. package/src/standard/checklist/load.ts +5 -5
  645. package/src/standard/checklist/view.ts +13 -13
  646. package/src/standard/cookies/index.tsx +17 -17
  647. package/src/standard/cookies/list.ts +56 -56
  648. package/src/standard/cookies/load.ts +11 -11
  649. package/src/standard/cookies/shared.ts +20 -20
  650. package/src/standard/cookies/view.ts +28 -28
  651. package/src/standard/faq/index.tsx +29 -29
  652. package/src/standard/faq/load.ts +14 -14
  653. package/src/standard/faq/view.ts +21 -21
  654. package/src/standard/head.ts +23 -23
  655. package/src/standard/hero/fields.ts +48 -48
  656. package/src/standard/hero/index.tsx +57 -57
  657. package/src/standard/hero/load.ts +23 -23
  658. package/src/standard/hero/view.ts +38 -38
  659. package/src/standard/links/index.tsx +41 -41
  660. package/src/standard/links/load.ts +17 -17
  661. package/src/standard/links/view.ts +25 -25
  662. package/src/standard/list/index.tsx +50 -50
  663. package/src/standard/list/load.ts +5 -5
  664. package/src/standard/list/view.ts +18 -18
  665. package/src/standard/load.ts +7 -7
  666. package/src/standard/notice/index.tsx +30 -30
  667. package/src/standard/notice/load.ts +16 -16
  668. package/src/standard/notice/view.ts +10 -10
  669. package/src/standard/points/index.tsx +42 -42
  670. package/src/standard/points/load.ts +5 -5
  671. package/src/standard/points/view.ts +12 -12
  672. package/src/standard/posts/index.tsx +132 -132
  673. package/src/standard/posts/load.ts +36 -36
  674. package/src/standard/posts/shared.ts +21 -21
  675. package/src/standard/posts/view.ts +63 -63
  676. package/src/standard/pricecards/index.tsx +57 -57
  677. package/src/standard/pricecards/load.ts +11 -11
  678. package/src/standard/pricecards/view.ts +50 -50
  679. package/src/standard/sharedTexts.ts +6 -6
  680. package/src/standard/site.ts +124 -124
  681. package/src/standard/siteLooks.ts +19 -19
  682. package/src/standard/sites.ts +13 -13
  683. package/src/standard/steps/index.tsx +28 -28
  684. package/src/standard/steps/load.ts +5 -5
  685. package/src/standard/steps/view.ts +11 -11
  686. package/src/standard/testimonials/index.tsx +87 -87
  687. package/src/standard/testimonials/list.ts +43 -43
  688. package/src/standard/testimonials/load.ts +58 -58
  689. package/src/standard/testimonials/shared.ts +13 -13
  690. package/src/standard/testimonials/view.ts +76 -76
  691. package/src/standard/themeBlocks.ts +13 -13
  692. package/src/standard/video/index.tsx +23 -23
  693. package/src/standard/video/load.ts +10 -10
  694. package/src/standard/video/view.ts +42 -42
  695. package/src/standard/view.tsx +105 -105
  696. package/src/standard/views.ts +37 -37
  697. package/src/store.ts +479 -499
  698. package/src/theme.ts +90 -90
  699. package/src/themeUi.ts +97 -97
  700. package/src/themes.ts +91 -91
  701. package/src/ui.tsx +3402 -3402
  702. package/src/virtual.d.ts +5 -5
  703. package/src/when.ts +22 -22
  704. package/starter/.githooks/pre-push +4 -4
  705. package/starter/.nvmrc +1 -1
  706. package/starter/.prettierignore +11 -11
  707. package/starter/.prettierrc.json +7 -7
  708. package/starter/README.md +27 -26
  709. package/starter/astro.config.mjs +5 -5
  710. package/starter/package.json +67 -67
  711. package/starter/public/_redirects +1 -1
  712. package/starter/public/favicon.svg +1 -1
  713. package/starter/public/logo.svg +1 -1
  714. package/starter/src/content/pages/blog.md +8 -8
  715. package/starter/src/content/pages/forside.md +9 -9
  716. package/starter/src/content/pages/kontakt.md +7 -7
  717. package/starter/src/content/pages/privatlivspolitik.md +9 -9
  718. package/starter/src/content/pages/siden-findes-ikke.md +7 -7
  719. package/starter/src/content.config.ts +2 -2
  720. package/starter/src/data/apps.json +1 -1
  721. package/starter/src/data/block-settings.json +3 -3
  722. package/starter/src/data/blocks.json +1 -1
  723. package/starter/src/data/booking.json +6 -6
  724. package/starter/src/data/colors.json +70 -70
  725. package/starter/src/data/contact.json +8 -8
  726. package/starter/src/data/cookies.json +21 -21
  727. package/starter/src/data/csp.json +1 -1
  728. package/starter/src/data/footer.json +15 -15
  729. package/starter/src/data/internal-links.json +4 -4
  730. package/starter/src/data/menu.json +4 -4
  731. package/starter/src/data/mobile-menu.json +4 -4
  732. package/starter/src/data/old-addresses.json +1 -1
  733. package/starter/src/data/redirects.json +1 -1
  734. package/starter/src/data/standard-pages.json +8 -8
  735. package/starter/src/data/theme.json +1 -1
  736. package/starter/src/env.d.ts +2 -2
  737. package/starter/src/site/config.ts +13 -13
  738. package/starter/src/site/worker.js +14 -14
  739. package/starter/tsconfig.json +17 -17
  740. package/starter/worker/apps.js +6 -6
  741. package/starter/wrangler.jsonc +39 -39
  742. package/theme/LICENSE +21 -21
  743. package/theme/blocks/ArrowLink.tsx +14 -14
  744. package/theme/blocks/BlockHead.tsx +26 -26
  745. package/theme/blocks/Panel.tsx +32 -32
  746. package/theme/blocks/Person.tsx +26 -26
  747. package/theme/blocks/accordion/PageRow.tsx +25 -25
  748. package/theme/blocks/accordion/View.tsx +17 -17
  749. package/theme/blocks/buttons/Buttons.tsx +28 -28
  750. package/theme/blocks/buttons/View.tsx +12 -12
  751. package/theme/blocks/cards/LinkCards.tsx +72 -72
  752. package/theme/blocks/cards/View.tsx +20 -20
  753. package/theme/blocks/checklist/Checks.tsx +15 -15
  754. package/theme/blocks/checklist/View.tsx +14 -14
  755. package/theme/blocks/cookies/View.tsx +36 -36
  756. package/theme/blocks/faq/Accordion.tsx +34 -34
  757. package/theme/blocks/faq/View.tsx +16 -16
  758. package/theme/blocks/faq/script.ts +56 -56
  759. package/theme/blocks/hero/View.tsx +44 -44
  760. package/theme/blocks/links/LinkGroups.tsx +24 -24
  761. package/theme/blocks/links/View.tsx +17 -17
  762. package/theme/blocks/list/Rows.tsx +24 -24
  763. package/theme/blocks/list/View.tsx +14 -14
  764. package/theme/blocks/notice/View.tsx +13 -13
  765. package/theme/blocks/points/PointList.tsx +34 -34
  766. package/theme/blocks/points/View.tsx +14 -14
  767. package/theme/blocks/posts/View.tsx +26 -26
  768. package/theme/blocks/pricecards/View.tsx +40 -40
  769. package/theme/blocks/steps/StepList.tsx +23 -23
  770. package/theme/blocks/steps/View.tsx +14 -14
  771. package/theme/blocks/testimonials/List.tsx +46 -46
  772. package/theme/blocks/testimonials/Slider.tsx +44 -44
  773. package/theme/blocks/testimonials/Testimonial.tsx +124 -124
  774. package/theme/blocks/testimonials/View.tsx +21 -21
  775. package/theme/blocks/testimonials/script.ts +52 -52
  776. package/theme/blocks/video/View.tsx +41 -41
  777. package/theme/components/ActionBar.astro +63 -63
  778. package/theme/components/AppSlot.astro +21 -21
  779. package/theme/components/ArrowLink.tsx +21 -21
  780. package/theme/components/BlogIndex.astro +48 -48
  781. package/theme/components/BlogPosts.astro +18 -18
  782. package/theme/components/BlogPosts.tsx +45 -45
  783. package/theme/components/BookButton.tsx +22 -22
  784. package/theme/components/Container.astro +11 -11
  785. package/theme/components/CookieConsent.astro +121 -121
  786. package/theme/components/EndBlock.astro +21 -21
  787. package/theme/components/FontPreload.astro +6 -6
  788. package/theme/components/Footer.astro +85 -85
  789. package/theme/components/Header.astro +186 -186
  790. package/theme/components/Icon.astro +16 -16
  791. package/theme/components/Img.astro +29 -29
  792. package/theme/components/Img.tsx +33 -33
  793. package/theme/components/Inline.astro +11 -11
  794. package/theme/components/Logo.astro +23 -23
  795. package/theme/components/LogoMark.astro +10 -10
  796. package/theme/components/Markdown.astro +17 -17
  797. package/theme/components/MobileMenu.tsx +224 -224
  798. package/theme/components/MobileNav.astro +33 -33
  799. package/theme/components/PageHeader.astro +22 -22
  800. package/theme/components/PageSection.astro +24 -24
  801. package/theme/components/PhoneButton.tsx +11 -11
  802. package/theme/components/Popup.astro +145 -145
  803. package/theme/components/PopupButton.tsx +24 -24
  804. package/theme/components/PopupView.tsx +48 -48
  805. package/theme/components/PostList.tsx +58 -58
  806. package/theme/components/PostMeta.tsx +17 -17
  807. package/theme/components/RichText.astro +28 -28
  808. package/theme/components/Section.astro +29 -29
  809. package/theme/components/SectionHeading.tsx +8 -8
  810. package/theme/components/TextSection.astro +16 -16
  811. package/theme/components/home/PageBlock.astro +19 -19
  812. package/theme/components/home/Text.astro +13 -13
  813. package/theme/components/loadPopup.ts +22 -22
  814. package/theme/components/loadPosts.ts +16 -16
  815. package/theme/components/posts.ts +15 -15
  816. package/theme/editor/looks.mjs +7 -7
  817. package/theme/editor/previews.tsx +56 -56
  818. package/theme/layouts/Base.astro +273 -273
  819. package/theme/layouts/PageLayout.astro +126 -126
  820. package/theme/layouts/PostLayout.astro +137 -137
  821. package/theme/scripts/motion.ts +29 -29
  822. package/theme/styles/base.css +320 -320
  823. package/theme/styles/blocks.css +1808 -1808
  824. package/theme/styles/components.css +206 -206
  825. package/theme/styles/global.css +1302 -1302
  826. package/theme/styles/ui.css +6544 -6544
  827. package/theme/templates/Blog.astro +38 -38
  828. package/theme/templates/Category.astro +19 -19
  829. package/theme/templates/Home.astro +36 -36
  830. package/theme/templates/New.astro +68 -68
  831. package/theme/templates/NotFound.astro +117 -117
  832. package/theme/theme.json +28 -28
  833. package/theme/ui/Badge.tsx +45 -45
  834. package/theme/ui/BottomSheet.tsx +148 -148
  835. package/theme/ui/Button.tsx +79 -79
  836. package/theme/ui/ButtonGroup.tsx +31 -31
  837. package/theme/ui/Card.tsx +45 -45
  838. package/theme/ui/Carousel.tsx +124 -124
  839. package/theme/ui/Checkbox.tsx +59 -59
  840. package/theme/ui/Chip.tsx +101 -101
  841. package/theme/ui/ChipSet.tsx +27 -27
  842. package/theme/ui/DatePicker.tsx +149 -149
  843. package/theme/ui/DatePickerContainer.tsx +316 -316
  844. package/theme/ui/Dialog.tsx +100 -100
  845. package/theme/ui/Divider.tsx +27 -27
  846. package/theme/ui/ExposedDropdownMenu.tsx +77 -77
  847. package/theme/ui/Fab.tsx +88 -88
  848. package/theme/ui/FabMenu.tsx +67 -67
  849. package/theme/ui/IconButton.tsx +78 -78
  850. package/theme/ui/List.tsx +287 -287
  851. package/theme/ui/LoadingIndicator.tsx +29 -29
  852. package/theme/ui/Menu.tsx +278 -278
  853. package/theme/ui/NavigationBar.tsx +62 -62
  854. package/theme/ui/NavigationDrawer.tsx +80 -80
  855. package/theme/ui/NavigationRail.tsx +154 -154
  856. package/theme/ui/ProgressIndicator.tsx +162 -162
  857. package/theme/ui/RadioButton.tsx +50 -50
  858. package/theme/ui/Search.tsx +129 -129
  859. package/theme/ui/SegmentedButton.tsx +49 -49
  860. package/theme/ui/SideSheet.tsx +54 -54
  861. package/theme/ui/Slider.tsx +155 -155
  862. package/theme/ui/Snackbar.tsx +67 -67
  863. package/theme/ui/SplitButton.tsx +67 -67
  864. package/theme/ui/Switch.tsx +60 -60
  865. package/theme/ui/Tabs.tsx +114 -114
  866. package/theme/ui/TextField.tsx +278 -278
  867. package/theme/ui/TimePicker.tsx +128 -128
  868. package/theme/ui/TimePickerContainer.tsx +234 -234
  869. package/theme/ui/Toolbar.tsx +67 -67
  870. package/theme/ui/Tooltip.tsx +58 -58
  871. package/theme/ui/TopAppBar.tsx +77 -77
  872. package/theme/ui/bottomSheet.script.ts +8 -8
  873. package/theme/ui/{bottomSheet.ts → bottomSheetControl.ts} +211 -211
  874. package/theme/ui/carousel.script.ts +28 -28
  875. package/theme/ui/carouselLayout.ts +229 -229
  876. package/theme/ui/checkbox.script.ts +8 -8
  877. package/theme/ui/datePicker.script.ts +302 -302
  878. package/theme/ui/dates.ts +185 -185
  879. package/theme/ui/{dialog.ts → dialogControl.ts} +48 -48
  880. package/theme/ui/dropdownMenu.script.ts +166 -166
  881. package/theme/ui/fabMenu.script.ts +57 -57
  882. package/theme/ui/navigationRail.script.ts +47 -47
  883. package/theme/ui/ripple.script.ts +159 -159
  884. package/theme/ui/search.script.ts +92 -92
  885. package/theme/ui/{sideSheet.ts → sideSheetControl.ts} +48 -48
  886. package/theme/ui/slider.script.ts +12 -12
  887. package/theme/ui/sliderUpdate.ts +52 -52
  888. package/theme/ui/snackbar.script.ts +16 -16
  889. package/theme/ui/splitButton.script.ts +63 -63
  890. package/theme/ui/tabs.script.ts +48 -48
  891. package/theme/ui/textField.script.ts +17 -17
  892. package/theme/ui/textFieldUpdate.ts +44 -44
  893. package/theme/ui/timePicker.script.ts +248 -248
  894. package/theme/ui/toolbar.script.ts +43 -43
  895. package/theme/ui/tooltip.script.ts +68 -68
  896. package/worker/consent.js +141 -141
  897. package/worker/editor-github.js +167 -167
  898. package/worker/editor-host.js +74 -74
  899. package/worker/files.js +401 -401
  900. package/worker/github.js +36 -36
  901. package/worker/index.js +188 -184
  902. package/worker/not-found.js +97 -97
  903. package/worker/oauth.js +95 -95
  904. package/worker/publish.js +52 -52
  905. package/worker/push.js +270 -270
  906. package/worker/r2-status.js +50 -50
  907. package/worker/session.js +58 -58
  908. package/worker/store.js +46 -0
@@ -1,149 +1,151 @@
1
- // Checks the site's content by the editor's own rules before it is built (prebuild, and
2
- // `npm run check:content`): every block in the text of the pages and the data files the editor writes
3
- // (checkSite.ts in the editor, packages/editor/). Stops with what is wrong, so a broken page never goes
4
- // out; the site that is out stays as it is; among it every theme (themeProblems, with the icon packs it brings) and
5
- // the system's icon packs and the choice of one (iconPackProblems), and so an icon the site or the editor draws that a
6
- // pack has none for, and the choice of motion scheme (motionProblems). Says too which of the site's texts the
7
- // editor has no translation of (@site/texts, a block's texts.ts); that does not stop the build. The editor's
8
- // code is TypeScript and TSX, so it is loaded with Vite, as the site's own build does.
9
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
10
- import { join, relative } from 'node:path';
11
- import { fileURLToPath } from 'node:url';
12
- import { config } from '../site/siteConfig.mjs';
13
- import { createServer } from 'vite';
14
- import {
15
- aliases,
16
- blockProblems,
17
- iconPackProblems,
18
- motionProblems,
19
- installedThemes,
20
- themeFolder,
21
- themePlugin,
22
- themeProblems,
23
- } from '@morphemecms/cms/site/theme.mjs';
24
- import { appFoldersPlugin, appIds, appWorkersProblems } from '@morphemecms/cms/lib/apps.mjs';
25
- import { codePackageProblems, declarationProblems, ownerId } from '@morphemecms/cms/lib/licenses.mjs';
26
- import { notesOf, releaseProblems } from './releases.mjs';
27
-
28
- const root = `${process.cwd()}/`;
29
- // This package's own code, from the site's root (packages/editor/ or node_modules/@morphemecms/cms/).
30
- const own = relative(root, fileURLToPath(new URL('..', import.meta.url)));
31
- const { allowedCspProblems, appCspProblems } = await import('../site/siteCsp.mjs');
32
- const { appCookieProblems } = await import('../site/appCookies.mjs');
33
-
34
- // With the redirects' other two files (siteRedirects in src/site/config.ts): none may send on through another.
35
- const files = ['src/content', 'src/data']
36
- .filter((dir) => existsSync(dir))
37
- .flatMap((dir) =>
38
- readdirSync(dir, { recursive: true, withFileTypes: true })
39
- .filter((e) => e.isFile() && /\.(md|json)$/.test(e.name))
40
- .map((e) => join(e.parentPath, e.name)),
41
- )
42
- .concat([config.siteRedirects.rules, config.siteRedirects.map])
43
- .map((path) => ({ path, text: readFileSync(path, 'utf8') }));
44
-
45
- const server = await createServer({
46
- configFile: false,
47
- logLevel: 'error',
48
- appType: 'custom',
49
- // As in packages/editor/astro.mjs: the editor takes the site from src/site/ as @site, and the theme in use as @theme.
50
- plugins: [themePlugin(), appFoldersPlugin(process.cwd())],
51
- resolve: { alias: aliases() },
52
- server: { middlewareMode: true, hmr: false, ws: false },
53
- });
54
- let result, missing;
55
- // The licences ("Licenser" under "Indstillinger", @morphemecms/cms/lib/licenses.mjs): each app's own and those of the
56
- // third-party work it brings (its defineApp), installed or not, as each theme's (themeProblems), with the packages they
57
- // declare, which they give what a package lacks for.
58
- const licenses = [];
59
- const declared = new Set();
60
- // The apps and themes of the app store, against what the catalog has released of them (releases.mjs).
61
- let catalog = {};
62
- const releases = [];
63
- try {
64
- const { problemsOf, untranslated } = await server.ssrLoadModule('@morphemecms/cms/src/checkSite.ts');
65
- result = problemsOf(files);
66
- missing = untranslated();
67
- const { config } = await server.ssrLoadModule('/src/site/config.ts');
68
- if (config.store && existsSync(config.store.catalog)) catalog = JSON.parse(readFileSync(config.store.catalog, 'utf8'));
69
- for (const id of appIds(root)) {
70
- const app = (await server.ssrLoadModule(`/src/apps/${id}/index.ts`)).default;
71
- for (const x of app.thirdParty ?? []) if (x?.package) declared.add(x.package);
72
- if (app.version)
73
- releases.push(
74
- ...releaseProblems(catalog, {
75
- kind: 'apps',
76
- id,
77
- folder: `src/apps/${id}`,
78
- version: app.version,
79
- notes: notesOf(app.releaseNotes),
80
- where: `src/apps/${id}/index.ts`,
81
- }),
82
- );
83
- licenses.push(
84
- ...declarationProblems({
85
- license: app.license,
86
- thirdParty: app.thirdParty,
87
- folder: join(root, 'src/apps', id),
88
- where: `src/apps/${id}/index.ts`,
89
- what: `appen ${app.label}`,
90
- owner: ownerId('app', id),
91
- root,
92
- }),
93
- );
94
- }
95
- } finally {
96
- await server.close();
97
- }
98
-
99
- for (const [locale, files] of Object.entries(missing)) {
100
- for (const [file, texts] of Object.entries(files)) {
101
- console.warn(`\nEditoren viser ${texts.length} af sitets tekster uoversat på ${locale}. Skriv dem i ${file}:\n`);
102
- for (const text of texts) console.warn(` ${JSON.stringify(text)}`);
103
- }
104
- }
105
-
106
- // Every theme installed has what a theme must have (the standard theme all of it), so the owner can swap to any of them
107
- // on "Udseende".
108
- result.problems.push(...installedThemes().flatMap(themeProblems), ...iconPackProblems(), ...motionProblems());
109
- // Every block is drawn from its view, on the site and in the editor alike.
110
- result.problems.push(...blockProblems());
111
- // What each app loads from elsewhere is in its csp.json, so the pages' Content-Security-Policy lets it through.
112
- result.problems.push(...appCspProblems());
113
- // The addresses allowed in the editor after the policy stopped them are written as an app's csp.json.
114
- result.problems.push(...allowedCspProblems());
115
- // The cookies each app sets are in its cookies.json, for the cookie list in the cookie policy.
116
- result.problems.push(...appCookieProblems());
117
- // The Worker has the part of each app that has one (worker/apps.js).
118
- result.problems.push(...appWorkersProblems(root));
119
- // Every app and theme says what its licence is and what it brings (the icon packs say theirs, themeProblems), and
120
- // every package the site's and the editor's code imports, and those they depend on, has a licence the editor can show
121
- // under "Licenser" (more than the build ships, which stops on its own when something it ships has none).
122
- for (const theme of installedThemes())
123
- for (const x of JSON.parse(readFileSync(`${themeFolder(theme)}/theme.json`, 'utf8')).thirdParty ?? [])
124
- if (x?.package) declared.add(x.package);
125
- result.problems.push(...licenses, ...codePackageProblems(root, [join(own, 'src'), join(own, 'lib'), 'src'], declared));
126
- // What is changed in an app or a theme of the store since it was released has its next version, once, with its note.
127
- for (const theme of installedThemes()) {
128
- const manifest = JSON.parse(readFileSync(`${themeFolder(theme)}/theme.json`, 'utf8'));
129
- if (manifest.store === true)
130
- releases.push(
131
- ...releaseProblems(catalog, {
132
- kind: 'themes',
133
- id: theme,
134
- folder: themeFolder(theme),
135
- version: manifest.version,
136
- notes: notesOf(manifest.releaseNotes, true),
137
- where: `${themeFolder(theme)}/theme.json`,
138
- }),
139
- );
140
- }
141
- result.problems.push(...releases);
142
-
143
- if (result.problems.length) {
144
- console.error(`\nIndholdet følger ikke editorens regler (${result.problems.length}):\n`);
145
- for (const line of result.problems) console.error(` ${line}`);
146
- console.error('\nRet filerne (eller blokkens felter i src/apps/<app>/blocks/), så bygges sitet igen.\n');
147
- process.exit(1);
148
- }
149
- console.log(`${result.files} filer og ${result.blocks} blokke følger editorens regler.`);
1
+ // Checks the site's content by the editor's own rules before it is built (prebuild, and
2
+ // `npm run check:content`): every block in the text of the pages and the data files the editor writes
3
+ // (checkSite.ts in the editor, packages/editor/). Stops with what is wrong, so a broken page never goes
4
+ // out; the site that is out stays as it is; among it every theme (themeProblems, with the icon packs it brings) and
5
+ // the system's icon packs and the choice of one (iconPackProblems), and so an icon the site or the editor draws that a
6
+ // pack has none for, and the choice of motion scheme (motionProblems). Says too which of the site's texts the
7
+ // editor has no translation of (@site/texts, a block's texts.ts); that does not stop the build. The editor's
8
+ // code is TypeScript and TSX, so it is loaded with Vite, as the site's own build does.
9
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
10
+ import { join, relative } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { config } from '../site/siteConfig.mjs';
13
+ import { createServer } from 'vite';
14
+ import {
15
+ aliases,
16
+ blockProblems,
17
+ iconPackProblems,
18
+ motionProblems,
19
+ installedThemes,
20
+ themeFolder,
21
+ themePlugin,
22
+ themeProblems,
23
+ } from '@morphemecms/cms/site/theme.mjs';
24
+ import { appFoldersPlugin, appIds, appWorkersProblems } from '@morphemecms/cms/lib/apps.mjs';
25
+ import { caseCollisionProblems } from '@morphemecms/cms/lib/caseCollisions.mjs';
26
+ import { codePackageProblems, declarationProblems, ownerId } from '@morphemecms/cms/lib/licenses.mjs';
27
+ import { notesOf, releaseProblems } from './releases.mjs';
28
+
29
+ const root = `${process.cwd()}/`;
30
+ // This package's own code, from the site's root (packages/editor/ or node_modules/@morphemecms/cms/).
31
+ const own = relative(root, fileURLToPath(new URL('..', import.meta.url)));
32
+ const { allowedCspProblems, appCspProblems } = await import('../site/siteCsp.mjs');
33
+ const { appCookieProblems } = await import('../site/appCookies.mjs');
34
+
35
+ // With the redirects' other two files (siteRedirects in src/site/config.ts): none may send on through another.
36
+ const files = ['src/content', 'src/data']
37
+ .filter((dir) => existsSync(dir))
38
+ .flatMap((dir) =>
39
+ readdirSync(dir, { recursive: true, withFileTypes: true })
40
+ .filter((e) => e.isFile() && /\.(md|json)$/.test(e.name))
41
+ .map((e) => join(e.parentPath, e.name)),
42
+ )
43
+ .concat([config.siteRedirects.rules, config.siteRedirects.map])
44
+ .map((path) => ({ path, text: readFileSync(path, 'utf8') }));
45
+
46
+ const server = await createServer({
47
+ configFile: false,
48
+ logLevel: 'error',
49
+ appType: 'custom',
50
+ // As in packages/editor/astro.mjs: the editor takes the site from src/site/ as @site, and the theme in use as @theme.
51
+ plugins: [themePlugin(), appFoldersPlugin(process.cwd())],
52
+ resolve: { alias: aliases() },
53
+ server: { middlewareMode: true, hmr: false, ws: false },
54
+ });
55
+ let result, missing;
56
+ // The licences ("Licenser" under "Indstillinger", @morphemecms/cms/lib/licenses.mjs): each app's own and those of the
57
+ // third-party work it brings (its defineApp), installed or not, as each theme's (themeProblems), with the packages they
58
+ // declare, which they give what a package lacks for.
59
+ const licenses = [];
60
+ const declared = new Set();
61
+ // The apps and themes of the app store, against what the catalog has released of them (releases.mjs).
62
+ let catalog = {};
63
+ const releases = [];
64
+ try {
65
+ const { problemsOf, untranslated } = await server.ssrLoadModule('@morphemecms/cms/src/checkSite.ts');
66
+ result = problemsOf(files);
67
+ missing = untranslated();
68
+ if (existsSync('store/catalog.json')) catalog = JSON.parse(readFileSync('store/catalog.json', 'utf8'));
69
+ for (const id of appIds(root)) {
70
+ const app = (await server.ssrLoadModule(`/src/apps/${id}/index.ts`)).default;
71
+ for (const x of app.thirdParty ?? []) if (x?.package) declared.add(x.package);
72
+ if (app.version)
73
+ releases.push(
74
+ ...releaseProblems(catalog, {
75
+ kind: 'apps',
76
+ id,
77
+ folder: `src/apps/${id}`,
78
+ version: app.version,
79
+ notes: notesOf(app.releaseNotes),
80
+ where: `src/apps/${id}/index.ts`,
81
+ }),
82
+ );
83
+ licenses.push(
84
+ ...declarationProblems({
85
+ license: app.license,
86
+ thirdParty: app.thirdParty,
87
+ folder: join(root, 'src/apps', id),
88
+ where: `src/apps/${id}/index.ts`,
89
+ what: `appen ${app.label}`,
90
+ owner: ownerId('app', id),
91
+ root,
92
+ }),
93
+ );
94
+ }
95
+ } finally {
96
+ await server.close();
97
+ }
98
+
99
+ for (const [locale, files] of Object.entries(missing)) {
100
+ for (const [file, texts] of Object.entries(files)) {
101
+ console.warn(`\nEditoren viser ${texts.length} af sitets tekster uoversat på ${locale}. Skriv dem i ${file}:\n`);
102
+ for (const text of texts) console.warn(` ${JSON.stringify(text)}`);
103
+ }
104
+ }
105
+
106
+ // Every theme installed has what a theme must have (the standard theme all of it), so the owner can swap to any of them
107
+ // on "Udseende".
108
+ result.problems.push(...installedThemes().flatMap(themeProblems), ...iconPackProblems(), ...motionProblems());
109
+ // Every block is drawn from its view, on the site and in the editor alike.
110
+ result.problems.push(...blockProblems());
111
+ // What each app loads from elsewhere is in its csp.json, so the pages' Content-Security-Policy lets it through.
112
+ result.problems.push(...appCspProblems());
113
+ // The addresses allowed in the editor after the policy stopped them are written as an app's csp.json.
114
+ result.problems.push(...allowedCspProblems());
115
+ // The cookies each app sets are in its cookies.json, for the cookie list in the cookie policy.
116
+ result.problems.push(...appCookieProblems());
117
+ // The Worker has the part of each app that has one (worker/apps.js).
118
+ result.problems.push(...appWorkersProblems(root));
119
+ // No two files of the package or the site differ only by case (an import would find the wrong one on Windows).
120
+ result.problems.push(...caseCollisionProblems(root, [own, 'src']));
121
+ // Every app and theme says what its licence is and what it brings (the icon packs say theirs, themeProblems), and
122
+ // every package the site's and the editor's code imports, and those they depend on, has a licence the editor can show
123
+ // under "Licenser" (more than the build ships, which stops on its own when something it ships has none).
124
+ for (const theme of installedThemes())
125
+ for (const x of JSON.parse(readFileSync(`${themeFolder(theme)}/theme.json`, 'utf8')).thirdParty ?? [])
126
+ if (x?.package) declared.add(x.package);
127
+ result.problems.push(...licenses, ...codePackageProblems(root, [join(own, 'src'), join(own, 'lib'), 'src'], declared));
128
+ // What is changed in an app or a theme of the store since it was released has its next version, once, with its note.
129
+ for (const theme of installedThemes()) {
130
+ const manifest = JSON.parse(readFileSync(`${themeFolder(theme)}/theme.json`, 'utf8'));
131
+ if (manifest.store === true)
132
+ releases.push(
133
+ ...releaseProblems(catalog, {
134
+ kind: 'themes',
135
+ id: theme,
136
+ folder: themeFolder(theme),
137
+ version: manifest.version,
138
+ notes: notesOf(manifest.releaseNotes, true),
139
+ where: `${themeFolder(theme)}/theme.json`,
140
+ }),
141
+ );
142
+ }
143
+ result.problems.push(...releases);
144
+
145
+ if (result.problems.length) {
146
+ console.error(`\nIndholdet følger ikke editorens regler (${result.problems.length}):\n`);
147
+ for (const line of result.problems) console.error(` ${line}`);
148
+ console.error('\nRet filerne (eller blokkens felter i src/apps/<app>/blocks/), så bygges sitet igen.\n');
149
+ process.exit(1);
150
+ }
151
+ console.log(`${result.files} filer og ${result.blocks} blokke følger editorens regler.`);
@@ -1,24 +1,24 @@
1
- // The CMS's demo site (demo/, demo-site.mjs) still works with the CMS: its content checked by the editor's rules
2
- // (check-content.mjs), each file the same after a save in the editor (editor-roundtrip.mjs) and the site built, with the
3
- // standard theme, in a folder of its own. Run it when the CMS, the
4
- // standard theme or the demo has changed: npx morpheme check:demo.
5
- import { execFileSync } from 'node:child_process';
6
- import { rmSync } from 'node:fs';
7
- import { join } from 'node:path';
8
- import { fileURLToPath } from 'node:url';
9
- import { binOf } from './bin.mjs';
10
- import { demoSite } from './demo-site.mjs';
11
-
12
- const dir = demoSite();
13
- try {
14
- const run = (args) => execFileSync(process.execPath, args, { cwd: dir, stdio: 'inherit' });
15
- run([fileURLToPath(new URL('check-content.mjs', import.meta.url))]);
16
- run([fileURLToPath(new URL('editor-roundtrip.mjs', import.meta.url))]);
17
- run([binOf('astro'), 'build', '--outDir', join(dir, 'dist')]);
18
- console.log('\nDemoen virker med CMS’et.');
19
- } catch {
20
- console.error('\nDemoen virker ikke med CMS’et (se ovenfor).');
21
- process.exitCode = 1;
22
- } finally {
23
- rmSync(dir, { recursive: true, force: true });
24
- }
1
+ // The CMS's demo site (demo/, demo-site.mjs) still works with the CMS: its content checked by the editor's rules
2
+ // (check-content.mjs), each file the same after a save in the editor (editor-roundtrip.mjs) and the site built, with the
3
+ // standard theme, in a folder of its own. Run it when the CMS, the
4
+ // standard theme or the demo has changed: npx morpheme check:demo.
5
+ import { execFileSync } from 'node:child_process';
6
+ import { rmSync } from 'node:fs';
7
+ import { join } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+ import { binOf } from './bin.mjs';
10
+ import { demoSite } from './demo-site.mjs';
11
+
12
+ const dir = demoSite();
13
+ try {
14
+ const run = (args) => execFileSync(process.execPath, args, { cwd: dir, stdio: 'inherit' });
15
+ run([fileURLToPath(new URL('check-content.mjs', import.meta.url))]);
16
+ run([fileURLToPath(new URL('editor-roundtrip.mjs', import.meta.url))]);
17
+ run([binOf('astro'), 'build', '--outDir', join(dir, 'dist')]);
18
+ console.log('\nDemoen virker med CMS’et.');
19
+ } catch {
20
+ console.error('\nDemoen virker ikke med CMS’et (se ovenfor).');
21
+ process.exitCode = 1;
22
+ } finally {
23
+ rmSync(dir, { recursive: true, force: true });
24
+ }
@@ -0,0 +1,160 @@
1
+ // Checks the site's Worker's questions to the store (packages/editor/worker/store.js): /api/store/catalog and /api/store/files/<oid>,
2
+ // who may ask, what happens without a key, and the store's refusals and failures. GitHub and the store are played by a fake
3
+ // fetch that records each request; nothing goes to either.
4
+ // Run: npm run check:worker
5
+ import { APP_API, THEME_API } from '../lib/contracts.mjs';
6
+ import { workerModules } from './worker-modules.mjs';
7
+
8
+ const [{ handleStore, STORE_URL }] = await workerModules('store.js', 'session.js');
9
+
10
+ const problems = [];
11
+ const expect = (ok, what) => ok || problems.push(what);
12
+
13
+ const KEY = 'site-key-for-test';
14
+ const OID = 'a'.repeat(40);
15
+ const BYTES = new Uint8Array([1, 2, 3, 250]);
16
+
17
+ /** A fake fetch: GitHub says what `repoAccess` says for a token; the store answers with `store(url, init)`. `storeCalls` records the store's requests. */
18
+ function world({ repoAccess = { pull: true, push: false }, store = () => new Response('{}', { status: 200 }) } = {}) {
19
+ const storeCalls = [];
20
+ const ask = async (url, init = {}) => {
21
+ if (String(url).startsWith('https://api.github.com/')) return Response.json({ permissions: repoAccess });
22
+ storeCalls.push({ url: String(url), headers: init.headers ?? {} });
23
+ return store(String(url), init);
24
+ };
25
+ return { ask, storeCalls };
26
+ }
27
+
28
+ let n = 0;
29
+ /** A request from the editor's page; a fresh token each time (the Worker remembers what GitHub said about a token). */
30
+ const request = (path, { signedIn = true, method = 'GET' } = {}) =>
31
+ new Request(`https://editor.example/api/store/${path}`, {
32
+ method,
33
+ headers: { ...(signedIn ? { cookie: `editor_session=token-${++n}` } : {}), 'sec-fetch-site': 'same-origin' },
34
+ });
35
+ const call = async (w, path, env = { MORPHEME_STORE_KEY: KEY }, options) => {
36
+ const res = await handleStore(request(path, options), env, {}, w.ask);
37
+ const bytes = new Uint8Array(await res.clone().arrayBuffer());
38
+ return { res, bytes, text: new TextDecoder().decode(bytes) };
39
+ };
40
+
41
+ // Signed out: 401, and the store is not asked.
42
+ {
43
+ const w = world();
44
+ const { res } = await call(w, 'catalog', undefined, { signedIn: false });
45
+ expect(res.status === 401, `uden login var svaret ${res.status}, ikke 401`);
46
+ expect(w.storeCalls.length === 0, 'uden login blev butikken spurgt');
47
+ }
48
+
49
+ // Signed in without the right to read the repository: 403.
50
+ {
51
+ const w = world({ repoAccess: { pull: false, push: false } });
52
+ const { res } = await call(w, 'catalog');
53
+ expect(res.status === 403, `uden læseret var svaret ${res.status}, ikke 403`);
54
+ expect(w.storeCalls.length === 0, 'uden læseret blev butikken spurgt');
55
+ }
56
+
57
+ // Without a key: the catalog says "not connected" and files are not found; the store is not asked.
58
+ {
59
+ const w = world();
60
+ const catalog = await call(w, 'catalog', {});
61
+ expect(catalog.res.status === 200 && JSON.parse(catalog.text).connected === false, `uden nøgle var kataloget ${catalog.text}`);
62
+ const file = await call(w, `files/${OID}`, {});
63
+ expect(file.res.status === 404, `uden nøgle var en fil ${file.res.status}, ikke 404`);
64
+ expect(w.storeCalls.length === 0, 'uden nøgle blev butikken spurgt');
65
+ }
66
+
67
+ // With a key: one request to the catalog with the contract versions and the bearer, and the store's JSON back.
68
+ {
69
+ const w = world({ store: () => Response.json({ apps: [{ id: 'x' }] }) });
70
+ const { res, text } = await call(w, 'catalog');
71
+ expect(res.status === 200 && JSON.parse(text).apps?.[0]?.id === 'x', `kataloget var ${res.status} ${text}`);
72
+ expect(w.storeCalls.length === 1, `butikken blev spurgt ${w.storeCalls.length} gange, ikke 1`);
73
+ expect(w.storeCalls[0]?.url === `${STORE_URL}/store/catalog?app=${APP_API}&theme=${THEME_API}`, `adressen var ${w.storeCalls[0]?.url}`);
74
+ expect(w.storeCalls[0]?.headers.authorization === `Bearer ${KEY}`, 'kataloget blev spurgt uden nøglen som bearer');
75
+ expect(!text.includes(KEY), 'kataloget indeholdt nøglen');
76
+ }
77
+
78
+ // MORPHEME_STORE_URL is used when set.
79
+ {
80
+ const w = world();
81
+ await call(w, 'catalog', { MORPHEME_STORE_KEY: KEY, MORPHEME_STORE_URL: 'https://store.example' });
82
+ expect(
83
+ w.storeCalls[0]?.url === `https://store.example/store/catalog?app=${APP_API}&theme=${THEME_API}`,
84
+ `MORPHEME_STORE_URL blev ikke brugt: ${w.storeCalls[0]?.url}`,
85
+ );
86
+ }
87
+
88
+ // A file: only a 40-character oid; the bytes, content-type and cache-control go through.
89
+ {
90
+ const w = world();
91
+ const bad = await call(w, 'files/xyz');
92
+ expect(bad.res.status === 404, `oid xyz gav ${bad.res.status}, ikke 404`);
93
+ expect(w.storeCalls.length === 0, 'oid xyz blev spurgt om i butikken');
94
+ }
95
+ {
96
+ const w = world({
97
+ store: () =>
98
+ new Response(BYTES, {
99
+ status: 200,
100
+ headers: { 'content-type': 'image/png', 'cache-control': 'public, max-age=31536000, immutable' },
101
+ }),
102
+ });
103
+ const { res, bytes } = await call(w, `files/${OID}`);
104
+ expect(res.status === 200 && bytes.join() === BYTES.join(), `filens bytes var ${bytes.join()}`);
105
+ expect(
106
+ res.headers.get('cache-control') === 'public, max-age=31536000, immutable',
107
+ `cache-control var ${res.headers.get('cache-control')}`,
108
+ );
109
+ expect(res.headers.get('content-type') === 'image/png', `content-type var ${res.headers.get('content-type')}`);
110
+ expect(w.storeCalls[0]?.url === `${STORE_URL}/store/files/${OID}`, `filens adresse var ${w.storeCalls[0]?.url}`);
111
+ expect(w.storeCalls[0]?.headers.authorization === `Bearer ${KEY}`, 'filen blev spurgt uden nøglen som bearer');
112
+ }
113
+ {
114
+ const w = world({ store: () => new Response('no', { status: 404 }) });
115
+ const { res } = await call(w, `files/${OID}`);
116
+ expect(res.status === 404, `en fil butikken ikke har gav ${res.status}, ikke 404`);
117
+ }
118
+
119
+ // The store refuses or fails: 502, and never the key.
120
+ for (const [status, error] of [
121
+ [401, 'store refused'],
122
+ [403, 'store refused'],
123
+ [500, 'store failed'],
124
+ [400, 'store failed'],
125
+ [404, 'store failed'],
126
+ ]) {
127
+ for (const path of ['catalog', ...(status === 404 || status === 400 ? [] : [`files/${OID}`])]) {
128
+ const w = world({ store: () => new Response(`secret ${KEY}`, { status }) });
129
+ const { res, text } = await call(w, path);
130
+ expect(res.status === 502 && JSON.parse(text).error === error, `butikkens ${status} på ${path} gav ${res.status} ${text}`);
131
+ expect(
132
+ !text.includes(KEY) && ![...res.headers.values()].some((v) => v.includes(KEY)),
133
+ `svaret på butikkens ${status} indeholdt nøglen`,
134
+ );
135
+ }
136
+ }
137
+ {
138
+ const w = world({
139
+ store: () => {
140
+ throw new Error(`no network, ${KEY}`);
141
+ },
142
+ });
143
+ const { res, text } = await call(w, 'catalog');
144
+ expect(res.status === 502 && JSON.parse(text).error === 'store failed', `en netværksfejl gav ${res.status} ${text}`);
145
+ expect(!text.includes(KEY), 'svaret på en netværksfejl indeholdt nøglen');
146
+ }
147
+
148
+ // Other methods and addresses.
149
+ {
150
+ const w = world();
151
+ expect((await call(w, 'catalog', undefined, { method: 'POST' })).res.status === 405, 'POST gav ikke 405');
152
+ expect((await call(w, 'other')).res.status === 404, 'en ukendt adresse gav ikke 404');
153
+ expect(w.storeCalls.length === 0, 'en forkert metode eller adresse blev spurgt om i butikken');
154
+ }
155
+
156
+ if (problems.length) {
157
+ console.error(problems.map((p) => `- ${p}`).join('\n'));
158
+ process.exit(1);
159
+ }
160
+ console.log('Workerens spørgsmål til butikken er i orden.');
@@ -1,45 +1,45 @@
1
- // Every theme installed (src/themes/) works as the site's theme, so the owner can swap to any of them: with each of the
2
- // others than the one in use (src/data/theme.json), the editor's check of the content (check-content.mjs), the site
3
- // built (in a folder of its own, so dist/ stays the theme in use's) and every screen of the editor opened
4
- // (editor-screens.mjs). The theme in use is checked by the steps before (npm run build, npm run check:screens).
5
- // src/data/theme.json is the theme being checked while it runs, and as it was after.
6
- import { execFileSync } from 'node:child_process';
7
- import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
8
- import { tmpdir } from 'node:os';
9
- import { join } from 'node:path';
10
- import { fileURLToPath } from 'node:url';
11
- import { activeTheme, installedThemes } from '@morphemecms/cms/site/theme.mjs';
12
- import { binOf } from './bin.mjs';
13
-
14
- const ROOT = `${process.cwd()}/`;
15
- const file = join(ROOT, 'src/data/theme.json');
16
- const before = readFileSync(file, 'utf8');
17
- const others = installedThemes().filter((t) => t !== activeTheme());
18
- const run = (cmd, args) => execFileSync(cmd, args, { cwd: ROOT, stdio: 'inherit' });
19
-
20
- const failed = [];
21
- try {
22
- for (const theme of others) {
23
- console.log(`\nTemaet ${theme}:`);
24
- writeFileSync(file, `${JSON.stringify({ theme }, null, 2)}\n`);
25
- const out = mkdtempSync(join(tmpdir(), `theme-${theme}-`));
26
- try {
27
- run(process.execPath, [fileURLToPath(new URL('check-content.mjs', import.meta.url))]);
28
- run(process.execPath, [binOf('astro'), 'build', '--outDir', out]);
29
- run(process.execPath, [fileURLToPath(new URL('editor-screens.mjs', import.meta.url)), out]);
30
- } catch {
31
- failed.push(theme);
32
- } finally {
33
- rmSync(out, { recursive: true, force: true });
34
- }
35
- }
36
- } finally {
37
- writeFileSync(file, before);
38
- }
39
-
40
- if (failed.length) {
41
- console.error(`\nDet virker ikke med ${failed.length === 1 ? 'temaet' : 'temaerne'} ${failed.join(', ')} (se ovenfor).`);
42
- process.exit(1);
43
- }
44
- if (!others.length) console.log('Der er ingen andre temaer installeret i src/themes/.');
45
- else console.log(`\n${others.length === 1 ? 'Temaet' : 'Temaerne'} ${others.join(', ')} virker også som sitets tema.`);
1
+ // Every theme installed (src/themes/) works as the site's theme, so the owner can swap to any of them: with each of the
2
+ // others than the one in use (src/data/theme.json), the editor's check of the content (check-content.mjs), the site
3
+ // built (in a folder of its own, so dist/ stays the theme in use's) and every screen of the editor opened
4
+ // (editor-screens.mjs). The theme in use is checked by the steps before (npm run build, npm run check:screens).
5
+ // src/data/theme.json is the theme being checked while it runs, and as it was after.
6
+ import { execFileSync } from 'node:child_process';
7
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
8
+ import { tmpdir } from 'node:os';
9
+ import { join } from 'node:path';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { activeTheme, installedThemes } from '@morphemecms/cms/site/theme.mjs';
12
+ import { binOf } from './bin.mjs';
13
+
14
+ const ROOT = `${process.cwd()}/`;
15
+ const file = join(ROOT, 'src/data/theme.json');
16
+ const before = readFileSync(file, 'utf8');
17
+ const others = installedThemes().filter((t) => t !== activeTheme());
18
+ const run = (cmd, args) => execFileSync(cmd, args, { cwd: ROOT, stdio: 'inherit' });
19
+
20
+ const failed = [];
21
+ try {
22
+ for (const theme of others) {
23
+ console.log(`\nTemaet ${theme}:`);
24
+ writeFileSync(file, `${JSON.stringify({ theme }, null, 2)}\n`);
25
+ const out = mkdtempSync(join(tmpdir(), `theme-${theme}-`));
26
+ try {
27
+ run(process.execPath, [fileURLToPath(new URL('check-content.mjs', import.meta.url))]);
28
+ run(process.execPath, [binOf('astro'), 'build', '--outDir', out]);
29
+ run(process.execPath, [fileURLToPath(new URL('editor-screens.mjs', import.meta.url)), out]);
30
+ } catch {
31
+ failed.push(theme);
32
+ } finally {
33
+ rmSync(out, { recursive: true, force: true });
34
+ }
35
+ }
36
+ } finally {
37
+ writeFileSync(file, before);
38
+ }
39
+
40
+ if (failed.length) {
41
+ console.error(`\nDet virker ikke med ${failed.length === 1 ? 'temaet' : 'temaerne'} ${failed.join(', ')} (se ovenfor).`);
42
+ process.exit(1);
43
+ }
44
+ if (!others.length) console.log('Der er ingen andre temaer installeret i src/themes/.');
45
+ else console.log(`\n${others.length === 1 ? 'Temaet' : 'Temaerne'} ${others.join(', ')} virker også som sitets tema.`);