@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
package/src/apps.ts CHANGED
@@ -1,281 +1,281 @@
1
- // An app: more for the site, as a folder of its own in src/apps/<app>/ (registry.tsx finds them), installed
2
- // under "Indstillinger" › "Apps" (AppList.tsx): the site's own come with it in its code; those from the app store
3
- // (store.ts) are copied into it when they are installed, with a note of where they came from (store.json):
4
- // index.ts what the editor knows about it (defineApp): its name, who made it, its icon, what it does (in a
5
- // sentence, and more fully), the cookies it sets and its settings (settings.ts in the folder, with
6
- // defineSettings); in the store also its version, its category and the words it is found by;
7
- // screenshots/ the pictures it is shown with in the store, picked to give an idea of it (`screenshots` in
8
- // index.ts, packages/editor/scripts/app-screenshots.mjs), on its page;
9
- // texts.ts its texts in the editor's other languages, as a block's;
10
- // blocks/<type>/ the blocks it adds, each a folder like a standard block's (index.tsx, view.ts, load.ts,
11
- // View.tsx, texts.ts, evt. shared.ts and script.ts);
12
- // lists in index.ts the lists it brings (`lists`, a FolderCollection each, with its icon): under "Lister" while
13
- // it is installed, and on its page; the entries are files in the site's data (src/data/), so
14
- // they stay, as the rest of the content, when it is uninstalled;
15
- // <list>/ a kind of entry it adds to one of the site's lists (`kinds` in index.ts), e.g. popups/: a
16
- // pop-up with a signup form, chosen under "+" with the list's own kinds (FolderCollection
17
- // .kinds); its part (View.tsx, given its view by view.ts in the editor and load.ts on the site,
18
- // and script.ts for what it does in a browser) is drawn in the pop-up under its text, on the site
19
- // (Popup.astro finds them) and in the editor (`part` in index.ts, kindDraw);
20
- // slots/head.astro, slots/body-end.astro what it puts on every page of the site, in <head> or at the
21
- // end of <body> (AppSlot.astro), while it is installed;
22
- // hooks/<place>.ts how it changes something the site does itself, run by the site's build while it is installed
23
- // (@morphemecms/cms/lib/hooks.ts: hooks/page-colors.ts, the colours of a page);
24
- // page in index.ts what it shows on its page under its settings (AppPage), drawn with the editor's parts (ui.tsx),
25
- // asking its own addresses in the Worker (`api`);
26
- // screens in index.ts screens of its own under its page (#apps/<app>/<screen>, AppScreenPage), drawn as its page,
27
- // which links to them (Cookiescanner's "Blokeret adresse");
28
- // tabs in index.ts tabs it adds to the site's lists (#liste/<list>/<app>, after the list's own tab in the top app
29
- // bar, Library.tsx List), drawn as its page (Cookiescanner's "Problemer" on "Cookies");
30
- // notifications in index.ts the kinds of notifications it sends, each turned off under "Konto", and how it finds
31
- // them (`check`, with `api`; AppNotifications);
32
- // worker.js, build.mjs its part of the site's Worker (/api/<app>/…, each hour) and a step after the site is built
33
- // (packages/editor/lib/apps.mjs);
34
- // csp.json what it loads from elsewhere on the site (packages/editor/lib/csp.mjs).
35
- // An app that is not installed is not offered in the editor: its blocks are not under "Indsæt" nor
36
- // "Blokindstillinger", its kinds not under "+", its lists not under "Lister", its settings not on its page. What was made with it stays,
37
- // on the pages and on the site, and can still be edited. Installed, its blocks are under its name in "Blokindstillinger". The
38
- // apps installed are in the site's file of apps (config.apps.installed), each app's settings in a file of
39
- // its own in config.apps.settings. The site's build reads the settings, so settings.ts imports nothing
40
- // that needs a browser.
41
- import type { Icon } from '@phosphor-icons/react';
42
- import type { ComponentType, ReactNode } from 'react';
43
- import type { BlockData } from './blocks';
44
- import type { Field, FolderCollection, KindPart, Opens, OwnedList, PreviewVariant } from './schema';
45
- import type { ConsentCategory } from '../lib/cookieCategories.mjs';
46
- import type { AppCategory, AppCookie, AppNeeds, AppShot, StoreRecord } from './store';
47
- import type { ThirdParty } from './licenses';
48
- import { config } from '@site/config';
49
-
50
- /** An app's settings, on its page once it is installed (#apps/<app>, AppList.tsx). */
51
- export type AppSettings = {
52
- fields: Field[];
53
- /** The settings before any are saved, in the site's language. */
54
- values: Record<string, unknown>;
55
- /** Made-up settings over `values`, which its blocks and kinds are drawn with under "Dele" (exampleData in
56
- * examples.ts), where the site's own are never shown (MobilePay's number). */
57
- example?: Record<string, unknown>;
58
- };
59
- export const defineSettings = (settings: AppSettings) => settings;
60
-
61
- /** A kind of entry an app adds to one of the site's lists (its value is the app's id): its name and
62
- * icon where one is picked under "+", what it is, and fields of its own, shown only for it. `omit`: the
63
- * list's own fields it does not have (a bar at the bottom of the screen has no picture or heading); the
64
- * fields that depend on one of them go with it (Field.only), and they must not depend on another
65
- * themselves. `draw`: how one looks on the site, by the form of an entry of it (DataForm.tsx), once for each
66
- * of `variants` (its states, e.g. before and after a signup), under its name, with its props over the entry's; or
67
- * `part`, its part in the list's own drawing (FolderCollection.drawPart, kindDraw). `opens`: what a button can
68
- * open of one (a button's "Åbn promovering", the list's FolderCollection.opens), without it nothing. */
69
- export type AppKind = {
70
- label: string;
71
- hint?: string;
72
- icon: Icon;
73
- fields?: Field[];
74
- omit?: string[];
75
- draw?: (props: Record<string, any>, data: BlockData) => ReactNode;
76
- /** Its part in the list's own drawing instead of a drawing of its own (a pop-up's signup form, KindPart). */
77
- part?: KindPart;
78
- variants?: PreviewVariant[];
79
- opens?: Opens;
80
- };
81
-
82
- /** How an entry of an app's kind looks on the site, beside its form and under "Dele": its own drawing, or its part in the
83
- * list's own drawing (`collection`: the list it is a kind of). */
84
- export function kindDraw(kind: AppKind, collection?: { drawPart?: FolderCollection['drawPart'] }): AppKind['draw'] {
85
- if (kind.draw) return kind.draw;
86
- const { part } = kind;
87
- const drawPart = collection?.drawPart;
88
- return part && drawPart ? (props, data) => drawPart(props, data, part) : undefined;
89
- }
90
-
91
- /** What an app's page is given for what it shows (AppDefinition.page): `api` asks the app's own addresses in the site's
92
- * Worker (/api/<app>/<path>, its worker.js), signed in with GitHub as the editor is. */
93
- export type AppPageProps = { api: (path?: string, init?: RequestInit) => Promise<Response> };
94
-
95
- /** A screen of an app's own under its page (AppDefinition.screens): its title (in the site's language, shown with
96
- * siteText), and what it shows, drawn as the app's page with the editor's parts and given the same `api`. */
97
- export type AppScreen = { title: string; page: ComponentType<AppPageProps> };
98
-
99
- /** A tab an app adds to one of the site's lists (AppDefinition.tabs): its name (in the site's language, shown with
100
- * siteText) and icon in the list's top app bar, after the list's own, and what it shows, drawn as the app's page with
101
- * the editor's parts and given the same `api`. */
102
- export type AppTab = { label: string; icon: Icon; page: ComponentType<AppPageProps> };
103
-
104
- /** The notifications an app sends ("Notifikationer", notifications.ts). `types`: each kind it sends, by its id, with its
105
- * name (in the site's language, shown with siteText), under "Konto" › "Notifikationer", where each can be turned off; it
106
- * sends no other. `check`: what it has to say now, asked with its `api` when the editor opens and every 15 minutes while
107
- * it is open; each comes once (by its `id`). */
108
- export type AppNotifications = {
109
- types: Record<string, string>;
110
- check: (props: AppPageProps) => Promise<AppNotification[]>;
111
- };
112
- /** A notification from an app: its type (one of `types`), an id it comes once by, the text (in the site's language, with
113
- * siteText), whether it is about something wrong, and evt. the screen it leads to (`to`: a route, as `apps/<app>`) with
114
- * the text of the link to it (`link`, in the site's language; without it, the app's name). */
115
- export type AppNotification = { type: string; id: string; text: string; error?: boolean; to?: string; link?: string };
116
-
117
- /** A list an app brings, as the site's own lists (packages/editor/defaults/collections.ts), with its icon under "Lister". */
118
- export type AppList = OwnedList;
119
-
120
- export type AppDefinition = {
121
- label: string;
122
- /** Who made it, under its name on its page. */
123
- publisher: string;
124
- /** Its own licence: an SPDX expression ("MIT", with its text in LICENSE in its folder), or "UNLICENSED" when all
125
- * rights are reserved. Under "Licenser" and on its page, also in the store. */
126
- license: string;
127
- /** The third-party work it brings (fonts, icons, code, pictures), each with its licence (ThirdParty): every package
128
- * its code imports that is not the editor's (npm run check:content says which are missing), or a work with its
129
- * licence file in its folder; [] when it brings none. Under "Licenser" and on its page, also in the store. */
130
- thirdParty: ThirdParty[];
131
- icon: Icon;
132
- /** What it does, in a short sentence, on its page and in the list of apps. */
133
- hint: string;
134
- /** What it does and how, more fully, on its page under "Om appen": a paragraph for each blank line. */
135
- description?: string;
136
- /** The pictures it is shown with on its page (as a theme's), a few picked to give an idea of it, each with what it
137
- * shows and what it says under it (AppShot); taken by packages/editor/scripts/app-screenshots.mjs with made-up content only. */
138
- screenshots?: AppShot[];
139
- /** The cookies it sets, on its page under "Cookies"; without any, it sets none. What the cookie banner asks about
140
- * first is `cookies`. */
141
- cookieList?: AppCookie[];
142
- settings?: AppSettings;
143
- /** The kinds it adds to the site's lists, by the list's id (a FolderCollection with `kinds`). */
144
- kinds?: Record<string, AppKind>;
145
- /** The lists it brings ("Priser"), under "Lister" while it is installed. */
146
- lists?: AppList[];
147
- /** In the app store (store.ts): its version, X.Y.Z ("1.2.1"): X for a major release, Y for new features, Z for fixes
148
- * or fitting a theme, the numbers after the one raised back to 0; without it, it is the site's own. X is raised only
149
- * when the app itself changes something a site that has it can break on (a block, field or setting gone or changed),
150
- * never for a new contract on its own: which editor it runs in is its `api` (APP_API), and fitting it to a new one is
151
- * Z (Y with new features), since a major release is not updated to on its own. */
152
- version?: string;
153
- /** In the app store: what is new in each version, by the version ("1.1.0"), shown before it is updated to it; every
154
- * version after the first has one: the next after the one released, given once until it is released, with all that
155
- * is new since in its note (packages/editor/scripts/releases.mjs). */
156
- releaseNotes?: Record<string, string>;
157
- /** In the app store: what kind of app it is (a filter in the store) and words it is found by, besides its name and
158
- * what it does ("nyhedsbrev"). The kind also says where its settings are: under "Indstillinger" on the site's screen
159
- * with it (PartScreen.apps in partScreens: "analytics" on "Analytics"), or on a part of "Virksomheden" with it
160
- * (Part.apps in companyParts: "payment" on "Betaling"), so they are where they are used and not on its page under
161
- * "Apps", which only installs it; without such a screen, on a screen of their own (#apps/<id>/indstillinger). */
162
- category?: AppCategory;
163
- keywords?: string[];
164
- /** The categories of cookies (lib/cookieCategories.mjs) of what it loads that sets cookies (a tag), with these
165
- * settings (its saved ones over settings.ts); none when it loads nothing that does. The cookie banner asks about each
166
- * of them (packages/editor/site/consent.ts), and it starts only after a yes to one of them (afterConsent in
167
- * src/scripts/tracking.ts). */
168
- cookies?: (values: Record<string, unknown>) => ConsentCategory[];
169
- /** What it shows on its page under its settings while it is installed (Cookiescanner's last scan), drawn with the
170
- * editor's parts (ui.tsx), its texts with siteText. */
171
- page?: ComponentType<AppPageProps>;
172
- /** Screens of its own under its page while it is installed, by the last part of their address (#apps/<id>/<key>; not
173
- * "indstillinger"), each linked to from its page. */
174
- screens?: Record<string, AppScreen>;
175
- /** Tabs it adds to the site's lists while it is installed, by the list's id, each at #liste/<list>/<app>. */
176
- tabs?: Record<string, AppTab>;
177
- notifications?: AppNotifications;
178
- };
179
- export const defineApp = (app: AppDefinition) => app;
180
-
181
- /** An app with its id, the name of its folder (src/apps/<id>/), the types of the blocks it adds, what it needs of the
182
- * site (needsOf, from its folder), the addresses of its pictures with what each says under it, and where it came from when it was installed from the
183
- * app store (its store.json; the site's own have none). */
184
- export type SiteApp = AppDefinition & {
185
- id: string;
186
- blocks: string[];
187
- needs: AppNeeds;
188
- pictures: { src: string; label: string }[];
189
- store?: StoreRecord;
190
- };
191
-
192
- /** A list with the kinds the apps add to it: each an option of its field of kinds (`kinds`, a select),
193
- * and its fields after the list's own, shown only for it; the list's own fields a kind leaves out (the
194
- * app's `omit`, or the list's own for its own kinds) are shown only for the others. All apps', installed or not, so an entry made with an app
195
- * stays one; only those of the apps installed, and not turned off, are offered under "+" (kindsOffered). */
196
- export function withKinds<C extends { id: string; kind: string; fields?: Field[]; kinds?: string; omit?: Record<string, string[]> }>(
197
- collection: C,
198
- apps: SiteApp[],
199
- ): C {
200
- const name = collection.kinds;
201
- const added = apps.flatMap((a) => (a.kinds?.[collection.id] ? [{ app: a, kind: a.kinds[collection.id] }] : []));
202
- if (!name || !collection.fields || (!added.length && !collection.omit)) return collection;
203
- const all = [...(collection.fields.find((f) => f.name === name)?.options ?? []).map((o) => o.value), ...added.map(({ app }) => app.id)];
204
- // The kinds that have a field of the list's own: all but those that leave it out.
205
- const omitted = (k: string) => [...(collection.omit?.[k] ?? []), ...(added.find(({ app }) => app.id === k)?.kind.omit ?? [])];
206
- const having = (field: string) => all.filter((k) => !omitted(k).includes(field));
207
- return {
208
- ...collection,
209
- fields: [
210
- ...collection.fields.map((f) =>
211
- f.name === name
212
- ? {
213
- ...f,
214
- options: [
215
- ...(f.options ?? []),
216
- ...added.map(({ app, kind }) => ({ value: app.id, label: kind.label, hint: kind.hint, icon: kind.icon })),
217
- ],
218
- }
219
- : having(f.name).length < all.length
220
- ? { ...f, only: { field: name, is: having(f.name) } }
221
- : f,
222
- ),
223
- ...added.flatMap(({ app, kind }) => (kind.fields ?? []).map((f) => ({ ...f, only: { field: name, is: [app.id] } }))),
224
- ],
225
- };
226
- }
227
-
228
- /** An app's kind of a list as it is turned off under "Blokindstillinger", among the blocks turned off ("popups/mailchimp",
229
- * as its address under "+", #ny/popups/mailchimp). */
230
- export const kindKey = (list: string, app: string) => `${list}/${app}`;
231
-
232
- /** The kinds a new entry of a list can be, under its "+": its own, and those of the apps installed and not turned off
233
- * under "Blokindstillinger" (`off`, offBlocks). */
234
- export function kindsOffered(
235
- collection: { id: string; fields?: Field[]; kinds?: string },
236
- apps: SiteApp[],
237
- installed: string[],
238
- off: string[],
239
- ) {
240
- const field = collection.fields?.find((f) => f.name === collection.kinds);
241
- return (field?.options ?? []).filter(
242
- (o) => !apps.some((a) => a.id === o.value) || (installed.includes(o.value) && !off.includes(kindKey(collection.id, o.value))),
243
- );
244
- }
245
-
246
- /** The tabs the apps installed add to a list (AppDefinition.tabs), each with its app, in the order of the apps. */
247
- export const tabsOf = (list: string, apps: SiteApp[], installed: string[]) =>
248
- apps.flatMap((app) => (installed.includes(app.id) && app.tabs?.[list] ? [{ app, tab: app.tabs[list] }] : []));
249
-
250
- /** The id of an app from the path of a file in its folder ("/src/apps/mailchimp/index.ts": "mailchimp",
251
- * also ".../apps/mailchimp/popups/View.tsx"). */
252
- export const appIdOf = (path: string) => path.split('/apps/')[1].split('/')[0];
253
-
254
- /** The file of an app's settings (config.apps.settings/<id>.json). */
255
- export const settingsFile = (id: string) => `${config.apps.settings}/${id}.json`;
256
-
257
- /** The apps installed, by their ids, from the site's file of apps. */
258
- export function installedApps(files: { path: string; text: string }[]): string[] {
259
- try {
260
- const installed = JSON.parse(files.find((f) => f.path === config.apps.installed)?.text ?? '{}').installed;
261
- return Array.isArray(installed) ? installed.map(String) : [];
262
- } catch {
263
- return [];
264
- }
265
- }
266
-
267
- /** Each app's settings as the files have them now, by its id, over those it starts with (`values`). */
268
- export function appSettings(
269
- files: { path: string; text: string }[],
270
- apps: { id: string; settings?: AppSettings }[],
271
- ): Record<string, Record<string, any>> {
272
- return Object.fromEntries(
273
- apps.map((a) => {
274
- let saved = {};
275
- try {
276
- saved = JSON.parse(files.find((f) => f.path === settingsFile(a.id))?.text ?? '{}');
277
- } catch {}
278
- return [a.id, { ...a.settings?.values, ...saved }];
279
- }),
280
- );
281
- }
1
+ // An app: more for the site, as a folder of its own in src/apps/<app>/ (registry.tsx finds them), installed
2
+ // under "Indstillinger" › "Apps" (AppList.tsx): the site's own come with it in its code; those from the app store
3
+ // (store.ts) are copied into it when they are installed, with a note of where they came from (store.json):
4
+ // index.ts what the editor knows about it (defineApp): its name, who made it, its icon, what it does (in a
5
+ // sentence, and more fully), the cookies it sets and its settings (settings.ts in the folder, with
6
+ // defineSettings); in the store also its version, its category and the words it is found by;
7
+ // screenshots/ the pictures it is shown with in the store, picked to give an idea of it (`screenshots` in
8
+ // index.ts, packages/editor/scripts/app-screenshots.mjs), on its page;
9
+ // texts.ts its texts in the editor's other languages, as a block's;
10
+ // blocks/<type>/ the blocks it adds, each a folder like a standard block's (index.tsx, view.ts, load.ts,
11
+ // View.tsx, texts.ts, evt. shared.ts and script.ts);
12
+ // lists in index.ts the lists it brings (`lists`, a FolderCollection each, with its icon): under "Lister" while
13
+ // it is installed, and on its page; the entries are files in the site's data (src/data/), so
14
+ // they stay, as the rest of the content, when it is uninstalled;
15
+ // <list>/ a kind of entry it adds to one of the site's lists (`kinds` in index.ts), e.g. popups/: a
16
+ // pop-up with a signup form, chosen under "+" with the list's own kinds (FolderCollection
17
+ // .kinds); its part (View.tsx, given its view by view.ts in the editor and load.ts on the site,
18
+ // and script.ts for what it does in a browser) is drawn in the pop-up under its text, on the site
19
+ // (Popup.astro finds them) and in the editor (`part` in index.ts, kindDraw);
20
+ // slots/head.astro, slots/body-end.astro what it puts on every page of the site, in <head> or at the
21
+ // end of <body> (AppSlot.astro), while it is installed;
22
+ // hooks/<place>.ts how it changes something the site does itself, run by the site's build while it is installed
23
+ // (@morphemecms/cms/lib/hooks.ts: hooks/page-colors.ts, the colours of a page);
24
+ // page in index.ts what it shows on its page under its settings (AppPage), drawn with the editor's parts (ui.tsx),
25
+ // asking its own addresses in the Worker (`api`);
26
+ // screens in index.ts screens of its own under its page (#apps/<app>/<screen>, AppScreenPage), drawn as its page,
27
+ // which links to them (Cookiescanner's "Blokeret adresse");
28
+ // tabs in index.ts tabs it adds to the site's lists (#liste/<list>/<app>, after the list's own tab in the top app
29
+ // bar, Library.tsx List), drawn as its page (Cookiescanner's "Problemer" on "Cookies");
30
+ // notifications in index.ts the kinds of notifications it sends, each turned off under "Konto", and how it finds
31
+ // them (`check`, with `api`; AppNotifications);
32
+ // worker.js, build.mjs its part of the site's Worker (/api/<app>/…, each hour) and a step after the site is built
33
+ // (packages/editor/lib/apps.mjs);
34
+ // csp.json what it loads from elsewhere on the site (packages/editor/lib/csp.mjs).
35
+ // An app that is not installed is not offered in the editor: its blocks are not under "Indsæt" nor
36
+ // "Blokindstillinger", its kinds not under "+", its lists not under "Lister", its settings not on its page. What was made with it stays,
37
+ // on the pages and on the site, and can still be edited. Installed, its blocks are under its name in "Blokindstillinger". The
38
+ // apps installed are in the site's file of apps (config.apps.installed), each app's settings in a file of
39
+ // its own in config.apps.settings. The site's build reads the settings, so settings.ts imports nothing
40
+ // that needs a browser.
41
+ import type { Icon } from '@phosphor-icons/react';
42
+ import type { ComponentType, ReactNode } from 'react';
43
+ import type { BlockData } from './blocks';
44
+ import type { Field, FolderCollection, KindPart, Opens, OwnedList, PreviewVariant } from './schema';
45
+ import type { ConsentCategory } from '../lib/cookieCategories.mjs';
46
+ import type { AppCategory, AppCookie, AppNeeds, AppShot, StoreRecord } from './store';
47
+ import type { ThirdParty } from './licenseData';
48
+ import { config } from '@site/config';
49
+
50
+ /** An app's settings, on its page once it is installed (#apps/<app>, AppList.tsx). */
51
+ export type AppSettings = {
52
+ fields: Field[];
53
+ /** The settings before any are saved, in the site's language. */
54
+ values: Record<string, unknown>;
55
+ /** Made-up settings over `values`, which its blocks and kinds are drawn with under "Dele" (exampleData in
56
+ * examples.ts), where the site's own are never shown (MobilePay's number). */
57
+ example?: Record<string, unknown>;
58
+ };
59
+ export const defineSettings = (settings: AppSettings) => settings;
60
+
61
+ /** A kind of entry an app adds to one of the site's lists (its value is the app's id): its name and
62
+ * icon where one is picked under "+", what it is, and fields of its own, shown only for it. `omit`: the
63
+ * list's own fields it does not have (a bar at the bottom of the screen has no picture or heading); the
64
+ * fields that depend on one of them go with it (Field.only), and they must not depend on another
65
+ * themselves. `draw`: how one looks on the site, by the form of an entry of it (DataForm.tsx), once for each
66
+ * of `variants` (its states, e.g. before and after a signup), under its name, with its props over the entry's; or
67
+ * `part`, its part in the list's own drawing (FolderCollection.drawPart, kindDraw). `opens`: what a button can
68
+ * open of one (a button's "Åbn promovering", the list's FolderCollection.opens), without it nothing. */
69
+ export type AppKind = {
70
+ label: string;
71
+ hint?: string;
72
+ icon: Icon;
73
+ fields?: Field[];
74
+ omit?: string[];
75
+ draw?: (props: Record<string, any>, data: BlockData) => ReactNode;
76
+ /** Its part in the list's own drawing instead of a drawing of its own (a pop-up's signup form, KindPart). */
77
+ part?: KindPart;
78
+ variants?: PreviewVariant[];
79
+ opens?: Opens;
80
+ };
81
+
82
+ /** How an entry of an app's kind looks on the site, beside its form and under "Dele": its own drawing, or its part in the
83
+ * list's own drawing (`collection`: the list it is a kind of). */
84
+ export function kindDraw(kind: AppKind, collection?: { drawPart?: FolderCollection['drawPart'] }): AppKind['draw'] {
85
+ if (kind.draw) return kind.draw;
86
+ const { part } = kind;
87
+ const drawPart = collection?.drawPart;
88
+ return part && drawPart ? (props, data) => drawPart(props, data, part) : undefined;
89
+ }
90
+
91
+ /** What an app's page is given for what it shows (AppDefinition.page): `api` asks the app's own addresses in the site's
92
+ * Worker (/api/<app>/<path>, its worker.js), signed in with GitHub as the editor is. */
93
+ export type AppPageProps = { api: (path?: string, init?: RequestInit) => Promise<Response> };
94
+
95
+ /** A screen of an app's own under its page (AppDefinition.screens): its title (in the site's language, shown with
96
+ * siteText), and what it shows, drawn as the app's page with the editor's parts and given the same `api`. */
97
+ export type AppScreen = { title: string; page: ComponentType<AppPageProps> };
98
+
99
+ /** A tab an app adds to one of the site's lists (AppDefinition.tabs): its name (in the site's language, shown with
100
+ * siteText) and icon in the list's top app bar, after the list's own, and what it shows, drawn as the app's page with
101
+ * the editor's parts and given the same `api`. */
102
+ export type AppTab = { label: string; icon: Icon; page: ComponentType<AppPageProps> };
103
+
104
+ /** The notifications an app sends ("Notifikationer", notificationData.ts). `types`: each kind it sends, by its id, with its
105
+ * name (in the site's language, shown with siteText), under "Konto" › "Notifikationer", where each can be turned off; it
106
+ * sends no other. `check`: what it has to say now, asked with its `api` when the editor opens and every 15 minutes while
107
+ * it is open; each comes once (by its `id`). */
108
+ export type AppNotifications = {
109
+ types: Record<string, string>;
110
+ check: (props: AppPageProps) => Promise<AppNotification[]>;
111
+ };
112
+ /** A notification from an app: its type (one of `types`), an id it comes once by, the text (in the site's language, with
113
+ * siteText), whether it is about something wrong, and evt. the screen it leads to (`to`: a route, as `apps/<app>`) with
114
+ * the text of the link to it (`link`, in the site's language; without it, the app's name). */
115
+ export type AppNotification = { type: string; id: string; text: string; error?: boolean; to?: string; link?: string };
116
+
117
+ /** A list an app brings, as the site's own lists (packages/editor/defaults/collections.ts), with its icon under "Lister". */
118
+ export type AppList = OwnedList;
119
+
120
+ export type AppDefinition = {
121
+ label: string;
122
+ /** Who made it, under its name on its page. */
123
+ publisher: string;
124
+ /** Its own licence: an SPDX expression ("MIT", with its text in LICENSE in its folder), or "UNLICENSED" when all
125
+ * rights are reserved. Under "Licenser" and on its page, also in the store. */
126
+ license: string;
127
+ /** The third-party work it brings (fonts, icons, code, pictures), each with its licence (ThirdParty): every package
128
+ * its code imports that is not the editor's (npm run check:content says which are missing), or a work with its
129
+ * licence file in its folder; [] when it brings none. Under "Licenser" and on its page, also in the store. */
130
+ thirdParty: ThirdParty[];
131
+ icon: Icon;
132
+ /** What it does, in a short sentence, on its page and in the list of apps. */
133
+ hint: string;
134
+ /** What it does and how, more fully, on its page under "Om appen": a paragraph for each blank line. */
135
+ description?: string;
136
+ /** The pictures it is shown with on its page (as a theme's), a few picked to give an idea of it, each with what it
137
+ * shows and what it says under it (AppShot); taken by packages/editor/scripts/app-screenshots.mjs with made-up content only. */
138
+ screenshots?: AppShot[];
139
+ /** The cookies it sets, on its page under "Cookies"; without any, it sets none. What the cookie banner asks about
140
+ * first is `cookies`. */
141
+ cookieList?: AppCookie[];
142
+ settings?: AppSettings;
143
+ /** The kinds it adds to the site's lists, by the list's id (a FolderCollection with `kinds`). */
144
+ kinds?: Record<string, AppKind>;
145
+ /** The lists it brings ("Priser"), under "Lister" while it is installed. */
146
+ lists?: AppList[];
147
+ /** In the app store (store.ts): its version, X.Y.Z ("1.2.1"): X for a major release, Y for new features, Z for fixes
148
+ * or fitting a theme, the numbers after the one raised back to 0; without it, it is the site's own. X is raised only
149
+ * when the app itself changes something a site that has it can break on (a block, field or setting gone or changed),
150
+ * never for a new contract on its own: which editor it runs in is its `api` (APP_API), and fitting it to a new one is
151
+ * Z (Y with new features), since a major release is not updated to on its own. */
152
+ version?: string;
153
+ /** In the app store: what is new in each version, by the version ("1.1.0"), shown before it is updated to it; every
154
+ * version after the first has one: the next after the one released, given once until it is released, with all that
155
+ * is new since in its note (packages/editor/scripts/releases.mjs). */
156
+ releaseNotes?: Record<string, string>;
157
+ /** In the app store: what kind of app it is (a filter in the store) and words it is found by, besides its name and
158
+ * what it does ("nyhedsbrev"). The kind also says where its settings are: under "Indstillinger" on the site's screen
159
+ * with it (PartScreen.apps in partScreens: "analytics" on "Analytics"), or on a part of "Virksomheden" with it
160
+ * (Part.apps in companyParts: "payment" on "Betaling"), so they are where they are used and not on its page under
161
+ * "Apps", which only installs it; without such a screen, on a screen of their own (#apps/<id>/indstillinger). */
162
+ category?: AppCategory;
163
+ keywords?: string[];
164
+ /** The categories of cookies (lib/cookieCategories.mjs) of what it loads that sets cookies (a tag), with these
165
+ * settings (its saved ones over settings.ts); none when it loads nothing that does. The cookie banner asks about each
166
+ * of them (packages/editor/site/consent.ts), and it starts only after a yes to one of them (afterConsent in
167
+ * src/scripts/tracking.ts). */
168
+ cookies?: (values: Record<string, unknown>) => ConsentCategory[];
169
+ /** What it shows on its page under its settings while it is installed (Cookiescanner's last scan), drawn with the
170
+ * editor's parts (ui.tsx), its texts with siteText. */
171
+ page?: ComponentType<AppPageProps>;
172
+ /** Screens of its own under its page while it is installed, by the last part of their address (#apps/<id>/<key>; not
173
+ * "indstillinger"), each linked to from its page. */
174
+ screens?: Record<string, AppScreen>;
175
+ /** Tabs it adds to the site's lists while it is installed, by the list's id, each at #liste/<list>/<app>. */
176
+ tabs?: Record<string, AppTab>;
177
+ notifications?: AppNotifications;
178
+ };
179
+ export const defineApp = (app: AppDefinition) => app;
180
+
181
+ /** An app with its id, the name of its folder (src/apps/<id>/), the types of the blocks it adds, what it needs of the
182
+ * site (needsOf, from its folder), the addresses of its pictures with what each says under it, and where it came from when it was installed from the
183
+ * app store (its store.json; the site's own have none). */
184
+ export type SiteApp = AppDefinition & {
185
+ id: string;
186
+ blocks: string[];
187
+ needs: AppNeeds;
188
+ pictures: { src: string; label: string }[];
189
+ store?: StoreRecord;
190
+ };
191
+
192
+ /** A list with the kinds the apps add to it: each an option of its field of kinds (`kinds`, a select),
193
+ * and its fields after the list's own, shown only for it; the list's own fields a kind leaves out (the
194
+ * app's `omit`, or the list's own for its own kinds) are shown only for the others. All apps', installed or not, so an entry made with an app
195
+ * stays one; only those of the apps installed, and not turned off, are offered under "+" (kindsOffered). */
196
+ export function withKinds<C extends { id: string; kind: string; fields?: Field[]; kinds?: string; omit?: Record<string, string[]> }>(
197
+ collection: C,
198
+ apps: SiteApp[],
199
+ ): C {
200
+ const name = collection.kinds;
201
+ const added = apps.flatMap((a) => (a.kinds?.[collection.id] ? [{ app: a, kind: a.kinds[collection.id] }] : []));
202
+ if (!name || !collection.fields || (!added.length && !collection.omit)) return collection;
203
+ const all = [...(collection.fields.find((f) => f.name === name)?.options ?? []).map((o) => o.value), ...added.map(({ app }) => app.id)];
204
+ // The kinds that have a field of the list's own: all but those that leave it out.
205
+ const omitted = (k: string) => [...(collection.omit?.[k] ?? []), ...(added.find(({ app }) => app.id === k)?.kind.omit ?? [])];
206
+ const having = (field: string) => all.filter((k) => !omitted(k).includes(field));
207
+ return {
208
+ ...collection,
209
+ fields: [
210
+ ...collection.fields.map((f) =>
211
+ f.name === name
212
+ ? {
213
+ ...f,
214
+ options: [
215
+ ...(f.options ?? []),
216
+ ...added.map(({ app, kind }) => ({ value: app.id, label: kind.label, hint: kind.hint, icon: kind.icon })),
217
+ ],
218
+ }
219
+ : having(f.name).length < all.length
220
+ ? { ...f, only: { field: name, is: having(f.name) } }
221
+ : f,
222
+ ),
223
+ ...added.flatMap(({ app, kind }) => (kind.fields ?? []).map((f) => ({ ...f, only: { field: name, is: [app.id] } }))),
224
+ ],
225
+ };
226
+ }
227
+
228
+ /** An app's kind of a list as it is turned off under "Blokindstillinger", among the blocks turned off ("popups/mailchimp",
229
+ * as its address under "+", #ny/popups/mailchimp). */
230
+ export const kindKey = (list: string, app: string) => `${list}/${app}`;
231
+
232
+ /** The kinds a new entry of a list can be, under its "+": its own, and those of the apps installed and not turned off
233
+ * under "Blokindstillinger" (`off`, offBlocks). */
234
+ export function kindsOffered(
235
+ collection: { id: string; fields?: Field[]; kinds?: string },
236
+ apps: SiteApp[],
237
+ installed: string[],
238
+ off: string[],
239
+ ) {
240
+ const field = collection.fields?.find((f) => f.name === collection.kinds);
241
+ return (field?.options ?? []).filter(
242
+ (o) => !apps.some((a) => a.id === o.value) || (installed.includes(o.value) && !off.includes(kindKey(collection.id, o.value))),
243
+ );
244
+ }
245
+
246
+ /** The tabs the apps installed add to a list (AppDefinition.tabs), each with its app, in the order of the apps. */
247
+ export const tabsOf = (list: string, apps: SiteApp[], installed: string[]) =>
248
+ apps.flatMap((app) => (installed.includes(app.id) && app.tabs?.[list] ? [{ app, tab: app.tabs[list] }] : []));
249
+
250
+ /** The id of an app from the path of a file in its folder ("/src/apps/mailchimp/index.ts": "mailchimp",
251
+ * also ".../apps/mailchimp/popups/View.tsx"). */
252
+ export const appIdOf = (path: string) => path.split('/apps/')[1].split('/')[0];
253
+
254
+ /** The file of an app's settings (config.apps.settings/<id>.json). */
255
+ export const settingsFile = (id: string) => `${config.apps.settings}/${id}.json`;
256
+
257
+ /** The apps installed, by their ids, from the site's file of apps. */
258
+ export function installedApps(files: { path: string; text: string }[]): string[] {
259
+ try {
260
+ const installed = JSON.parse(files.find((f) => f.path === config.apps.installed)?.text ?? '{}').installed;
261
+ return Array.isArray(installed) ? installed.map(String) : [];
262
+ } catch {
263
+ return [];
264
+ }
265
+ }
266
+
267
+ /** Each app's settings as the files have them now, by its id, over those it starts with (`values`). */
268
+ export function appSettings(
269
+ files: { path: string; text: string }[],
270
+ apps: { id: string; settings?: AppSettings }[],
271
+ ): Record<string, Record<string, any>> {
272
+ return Object.fromEntries(
273
+ apps.map((a) => {
274
+ let saved = {};
275
+ try {
276
+ saved = JSON.parse(files.find((f) => f.path === settingsFile(a.id))?.text ?? '{}');
277
+ } catch {}
278
+ return [a.id, { ...a.settings?.values, ...saved }];
279
+ }),
280
+ );
281
+ }