@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/lib/snackbar.ts CHANGED
@@ -1,149 +1,149 @@
1
- // The messages at the bottom of the screen (snackbars), the same in the editor (notify in App.tsx) and on
2
- // the site (a new version of a page, PageLayout.astro): in the middle, the newest lowest and the ones before
3
- // it moved up. Their look and place are the theme's Snackbar (.snackbar-stack and .snackbar in
4
- // packages/editor/theme/styles/ui.css). The editor's are drawn here, a text and links; the site's are drawn by
5
- // the theme's part (packages/editor/theme/ui/Snackbar.tsx, with its action and close button) and shown with
6
- // `element` (ui/snackbar.script.ts).
7
- //
8
- // A message goes away by itself after a few seconds (an error after a little longer; not while the
9
- // mouse or a finger is on it or a link in it has focus), when it is tapped, or when it is swiped left
10
- // or right: it follows the finger (or the mouse) sideways and fades; let go far enough (a third of its
11
- // width) or fast enough, and it slides out to that side, else it slides back. Up and down still
12
- // scroll the page. A swipe that started on a link does not also follow it.
13
- // One about something going on ("Gemmer…") stays until the next message replaces it; snackbar(null) only
14
- // takes that one away.
15
- import arrow from '@phosphor-icons/core/assets/regular/arrow-right.svg?raw';
16
-
17
- export type SnackbarLink = { text: string; href: string; onClick?: (e: MouseEvent) => void };
18
- export type SnackbarMessage = {
19
- text: string;
20
- error?: boolean;
21
- /** Links after the text, each with an arrow. */
22
- links?: SnackbarLink[];
23
- /** How long it stays, when longer than usual (e.g. with links to read). */
24
- ms?: number;
25
- /** The message as the site's theme draws it (its Snackbar part), shown in place of the text and links. */
26
- element?: HTMLElement;
27
- };
28
-
29
- const SNACKBAR_MS = 5000;
30
- const SNACKBAR_ERROR_MS = 8000;
31
-
32
- let stack: HTMLDivElement | undefined;
33
- const reduce = () => matchMedia('(prefers-reduced-motion: reduce)').matches;
34
- const working = (text: string) => text.endsWith('…');
35
-
36
- /** Shows a message at the bottom (or with null takes away the one about something going on). */
37
- export function snackbar(next: SnackbarMessage | null) {
38
- stack ??= Object.assign(document.createElement('div'), { className: 'snackbar-stack' });
39
- // A popover, so it is in front of an open sheet or dialog too (they are in the top layer).
40
- stack.popover = 'manual';
41
- if (!stack.isConnected) document.body.append(stack);
42
- for (const el of stack.querySelectorAll<HTMLElement>('.snackbar')) {
43
- if (working(el.dataset.text!) || el.dataset.text === next?.text) el.remove();
44
- }
45
- if (next) show(stack, next);
46
- if (!stack.childElementCount) return stack.remove();
47
- // Shown again for each message, so it comes in front of a sheet opened after the last one.
48
- if (stack.showPopover) {
49
- if (stack.matches(':popover-open')) stack.hidePopover();
50
- stack.showPopover();
51
- }
52
- }
53
-
54
- function show(stack: HTMLDivElement, { text, error, links = [], ms, element }: SnackbarMessage) {
55
- const el = element ?? document.createElement('p');
56
- el.dataset.text = text;
57
- if (!element) {
58
- el.className = 'snackbar';
59
- el.setAttribute('role', error ? 'alert' : 'status');
60
- el.append(text);
61
- }
62
- for (const link of element ? [] : links) {
63
- const a = document.createElement('a');
64
- a.className = 'snackbar-link';
65
- a.href = link.href;
66
- a.innerHTML = arrow.replace('<svg', '<svg width="14" height="14" fill="currentColor" aria-hidden="true"');
67
- a.prepend(link.text);
68
- if (link.onClick) a.addEventListener('click', link.onClick);
69
- el.append(' ', a);
70
- }
71
- stack.append(el);
72
-
73
- const remove = () => {
74
- clearTimeout(timer);
75
- el.remove();
76
- if (!stack.childElementCount) stack.remove();
77
- };
78
- // Goes by itself, but not while it is being read or swiped.
79
- const wait = working(text) ? 0 : (ms ?? (error ? SNACKBAR_ERROR_MS : SNACKBAR_MS));
80
- let timer = wait ? setTimeout(remove, wait) : undefined;
81
- const hold = () => clearTimeout(timer);
82
- const resume = () => {
83
- clearTimeout(timer);
84
- if (wait && el.isConnected && !el.matches(':hover, :focus-within')) timer = setTimeout(remove, wait / 2);
85
- };
86
- el.addEventListener('pointerenter', hold);
87
- el.addEventListener('pointerleave', resume);
88
- el.addEventListener('focusin', hold);
89
- el.addEventListener('focusout', resume);
90
- // The theme's (with a close button): Escape closes it too, while it has focus.
91
- if (element) el.addEventListener('keydown', (e) => e.key === 'Escape' && remove());
92
-
93
- // Swipe.
94
- let start: { x: number; y: number; t: number; id: number } | null = null;
95
- let dx = 0;
96
- let dragging = false;
97
- el.addEventListener('pointerdown', (e) => {
98
- if (e.button !== 0) return;
99
- start = { x: e.clientX, y: e.clientY, t: e.timeStamp, id: e.pointerId };
100
- dx = 0;
101
- dragging = false;
102
- hold();
103
- });
104
- el.addEventListener('pointermove', (e) => {
105
- if (!start || e.pointerId !== start.id) return;
106
- dx = e.clientX - start.x;
107
- if (!dragging) {
108
- if (Math.abs(dx) < 8 || Math.abs(dx) < Math.abs(e.clientY - start.y)) return;
109
- dragging = true;
110
- el.setPointerCapture(e.pointerId);
111
- el.getAnimations().forEach((a) => a.finish());
112
- }
113
- el.style.transform = `translateX(${dx}px)`;
114
- el.style.opacity = String(Math.max(0.2, 1 - Math.abs(dx) / el.offsetWidth));
115
- });
116
- const up = (e: PointerEvent) => {
117
- if (!start || e.pointerId !== start.id) return;
118
- const speed = Math.abs(dx) / Math.max(1, e.timeStamp - start.t);
119
- start = null;
120
- resume();
121
- if (!dragging) return;
122
- const from = { transform: el.style.transform, opacity: el.style.opacity };
123
- const duration = reduce() ? 0 : 200;
124
- if (e.type === 'pointerup' && (Math.abs(dx) > el.offsetWidth / 3 || speed > 0.6)) {
125
- const to = { transform: `translateX(${Math.sign(dx) * (el.offsetWidth + 32)}px)`, opacity: 0 };
126
- el.animate([from, to], { duration, easing: 'ease-out', fill: 'forwards' }).finished.then(remove);
127
- return;
128
- }
129
- el.animate([from, { transform: 'none', opacity: 1 }], { duration, easing: 'ease-out' });
130
- el.style.transform = '';
131
- el.style.opacity = '';
132
- };
133
- el.addEventListener('pointerup', up);
134
- el.addEventListener('pointercancel', up);
135
- // With the mouse, a link would otherwise be dragged instead of the message.
136
- el.addEventListener('dragstart', (e) => e.preventDefault());
137
- // A tap takes it away (a tap on a link or an action also follows it, and on the close button only takes it
138
- // away); the click at the end of a swipe does nothing.
139
- el.addEventListener(
140
- 'click',
141
- (e) => {
142
- if (!dragging) return remove();
143
- e.preventDefault();
144
- e.stopImmediatePropagation();
145
- dragging = false;
146
- },
147
- true,
148
- );
149
- }
1
+ // The messages at the bottom of the screen (snackbars), the same in the editor (notify in App.tsx) and on
2
+ // the site (a new version of a page, PageLayout.astro): in the middle, the newest lowest and the ones before
3
+ // it moved up. Their look and place are the theme's Snackbar (.snackbar-stack and .snackbar in
4
+ // packages/editor/theme/styles/ui.css). The editor's are drawn here, a text and links; the site's are drawn by
5
+ // the theme's part (packages/editor/theme/ui/Snackbar.tsx, with its action and close button) and shown with
6
+ // `element` (ui/snackbar.script.ts).
7
+ //
8
+ // A message goes away by itself after a few seconds (an error after a little longer; not while the
9
+ // mouse or a finger is on it or a link in it has focus), when it is tapped, or when it is swiped left
10
+ // or right: it follows the finger (or the mouse) sideways and fades; let go far enough (a third of its
11
+ // width) or fast enough, and it slides out to that side, else it slides back. Up and down still
12
+ // scroll the page. A swipe that started on a link does not also follow it.
13
+ // One about something going on ("Gemmer…") stays until the next message replaces it; snackbar(null) only
14
+ // takes that one away.
15
+ import arrow from '@phosphor-icons/core/assets/regular/arrow-right.svg?raw';
16
+
17
+ export type SnackbarLink = { text: string; href: string; onClick?: (e: MouseEvent) => void };
18
+ export type SnackbarMessage = {
19
+ text: string;
20
+ error?: boolean;
21
+ /** Links after the text, each with an arrow. */
22
+ links?: SnackbarLink[];
23
+ /** How long it stays, when longer than usual (e.g. with links to read). */
24
+ ms?: number;
25
+ /** The message as the site's theme draws it (its Snackbar part), shown in place of the text and links. */
26
+ element?: HTMLElement;
27
+ };
28
+
29
+ const SNACKBAR_MS = 5000;
30
+ const SNACKBAR_ERROR_MS = 8000;
31
+
32
+ let stack: HTMLDivElement | undefined;
33
+ const reduce = () => matchMedia('(prefers-reduced-motion: reduce)').matches;
34
+ const working = (text: string) => text.endsWith('…');
35
+
36
+ /** Shows a message at the bottom (or with null takes away the one about something going on). */
37
+ export function snackbar(next: SnackbarMessage | null) {
38
+ stack ??= Object.assign(document.createElement('div'), { className: 'snackbar-stack' });
39
+ // A popover, so it is in front of an open sheet or dialog too (they are in the top layer).
40
+ stack.popover = 'manual';
41
+ if (!stack.isConnected) document.body.append(stack);
42
+ for (const el of stack.querySelectorAll<HTMLElement>('.snackbar')) {
43
+ if (working(el.dataset.text!) || el.dataset.text === next?.text) el.remove();
44
+ }
45
+ if (next) show(stack, next);
46
+ if (!stack.childElementCount) return stack.remove();
47
+ // Shown again for each message, so it comes in front of a sheet opened after the last one.
48
+ if (stack.showPopover) {
49
+ if (stack.matches(':popover-open')) stack.hidePopover();
50
+ stack.showPopover();
51
+ }
52
+ }
53
+
54
+ function show(stack: HTMLDivElement, { text, error, links = [], ms, element }: SnackbarMessage) {
55
+ const el = element ?? document.createElement('p');
56
+ el.dataset.text = text;
57
+ if (!element) {
58
+ el.className = 'snackbar';
59
+ el.setAttribute('role', error ? 'alert' : 'status');
60
+ el.append(text);
61
+ }
62
+ for (const link of element ? [] : links) {
63
+ const a = document.createElement('a');
64
+ a.className = 'snackbar-link';
65
+ a.href = link.href;
66
+ a.innerHTML = arrow.replace('<svg', '<svg width="14" height="14" fill="currentColor" aria-hidden="true"');
67
+ a.prepend(link.text);
68
+ if (link.onClick) a.addEventListener('click', link.onClick);
69
+ el.append(' ', a);
70
+ }
71
+ stack.append(el);
72
+
73
+ const remove = () => {
74
+ clearTimeout(timer);
75
+ el.remove();
76
+ if (!stack.childElementCount) stack.remove();
77
+ };
78
+ // Goes by itself, but not while it is being read or swiped.
79
+ const wait = working(text) ? 0 : (ms ?? (error ? SNACKBAR_ERROR_MS : SNACKBAR_MS));
80
+ let timer = wait ? setTimeout(remove, wait) : undefined;
81
+ const hold = () => clearTimeout(timer);
82
+ const resume = () => {
83
+ clearTimeout(timer);
84
+ if (wait && el.isConnected && !el.matches(':hover, :focus-within')) timer = setTimeout(remove, wait / 2);
85
+ };
86
+ el.addEventListener('pointerenter', hold);
87
+ el.addEventListener('pointerleave', resume);
88
+ el.addEventListener('focusin', hold);
89
+ el.addEventListener('focusout', resume);
90
+ // The theme's (with a close button): Escape closes it too, while it has focus.
91
+ if (element) el.addEventListener('keydown', (e) => e.key === 'Escape' && remove());
92
+
93
+ // Swipe.
94
+ let start: { x: number; y: number; t: number; id: number } | null = null;
95
+ let dx = 0;
96
+ let dragging = false;
97
+ el.addEventListener('pointerdown', (e) => {
98
+ if (e.button !== 0) return;
99
+ start = { x: e.clientX, y: e.clientY, t: e.timeStamp, id: e.pointerId };
100
+ dx = 0;
101
+ dragging = false;
102
+ hold();
103
+ });
104
+ el.addEventListener('pointermove', (e) => {
105
+ if (!start || e.pointerId !== start.id) return;
106
+ dx = e.clientX - start.x;
107
+ if (!dragging) {
108
+ if (Math.abs(dx) < 8 || Math.abs(dx) < Math.abs(e.clientY - start.y)) return;
109
+ dragging = true;
110
+ el.setPointerCapture(e.pointerId);
111
+ el.getAnimations().forEach((a) => a.finish());
112
+ }
113
+ el.style.transform = `translateX(${dx}px)`;
114
+ el.style.opacity = String(Math.max(0.2, 1 - Math.abs(dx) / el.offsetWidth));
115
+ });
116
+ const up = (e: PointerEvent) => {
117
+ if (!start || e.pointerId !== start.id) return;
118
+ const speed = Math.abs(dx) / Math.max(1, e.timeStamp - start.t);
119
+ start = null;
120
+ resume();
121
+ if (!dragging) return;
122
+ const from = { transform: el.style.transform, opacity: el.style.opacity };
123
+ const duration = reduce() ? 0 : 200;
124
+ if (e.type === 'pointerup' && (Math.abs(dx) > el.offsetWidth / 3 || speed > 0.6)) {
125
+ const to = { transform: `translateX(${Math.sign(dx) * (el.offsetWidth + 32)}px)`, opacity: 0 };
126
+ el.animate([from, to], { duration, easing: 'ease-out', fill: 'forwards' }).finished.then(remove);
127
+ return;
128
+ }
129
+ el.animate([from, { transform: 'none', opacity: 1 }], { duration, easing: 'ease-out' });
130
+ el.style.transform = '';
131
+ el.style.opacity = '';
132
+ };
133
+ el.addEventListener('pointerup', up);
134
+ el.addEventListener('pointercancel', up);
135
+ // With the mouse, a link would otherwise be dragged instead of the message.
136
+ el.addEventListener('dragstart', (e) => e.preventDefault());
137
+ // A tap takes it away (a tap on a link or an action also follows it, and on the close button only takes it
138
+ // away); the click at the end of a swipe does nothing.
139
+ el.addEventListener(
140
+ 'click',
141
+ (e) => {
142
+ if (!dragging) return remove();
143
+ e.preventDefault();
144
+ e.stopImmediatePropagation();
145
+ dragging = false;
146
+ },
147
+ true,
148
+ );
149
+ }
package/lib/status.mjs CHANGED
@@ -1,18 +1,18 @@
1
- // The status of a page or blog post: `status` in its front matter, "Status" at the top of it in the
2
- // editor (packages/editor/defaults/collections.ts).
3
- // (none) Udgivet: on the site.
4
- // draft Kladde: not on the site (in dev, and on the editor's preview, it opens on its address).
5
- // unlisted Skjult: opens on its address, but is not on the blog, in the sitemap or in Google.
6
- // scheduled Planlagt: a draft until `publishAt` (Danish time, "2026-11-01T08:00"), then published.
7
- // A build after that time has it; each hour the site's Worker makes it Udgivet in the file
8
- // (packages/editor/worker/publish.js, packages/editor/lib/scheduled.mjs), which builds the site.
9
- // No dependencies, so the Worker can use it.
10
- import { isOver } from './notice.mjs';
11
-
12
- /** What a page or post is on a site built at `now`: 'published', 'draft' or 'unlisted'.
13
- * @param {{ status?: unknown; publishAt?: unknown }} data
14
- * @returns {'published' | 'draft' | 'unlisted'} */
15
- export function stateOf(data, now = Date.now()) {
16
- if (data.status === 'scheduled') return isOver(String(data.publishAt ?? ''), now) ? 'published' : 'draft';
17
- return data.status === 'draft' || data.status === 'unlisted' ? data.status : 'published';
18
- }
1
+ // The status of a page or blog post: `status` in its front matter, "Status" at the top of it in the
2
+ // editor (packages/editor/defaults/collections.ts).
3
+ // (none) Udgivet: on the site.
4
+ // draft Kladde: not on the site (in dev, and on the editor's preview, it opens on its address).
5
+ // unlisted Skjult: opens on its address, but is not on the blog, in the sitemap or in Google.
6
+ // scheduled Planlagt: a draft until `publishAt` (Danish time, "2026-11-01T08:00"), then published.
7
+ // A build after that time has it; each hour the site's Worker makes it Udgivet in the file
8
+ // (packages/editor/worker/publish.js, packages/editor/lib/scheduled.mjs), which builds the site.
9
+ // No dependencies, so the Worker can use it.
10
+ import { isOver } from './notice.mjs';
11
+
12
+ /** What a page or post is on a site built at `now`: 'published', 'draft' or 'unlisted'.
13
+ * @param {{ status?: unknown; publishAt?: unknown }} data
14
+ * @returns {'published' | 'draft' | 'unlisted'} */
15
+ export function stateOf(data, now = Date.now()) {
16
+ if (data.status === 'scheduled') return isOver(String(data.publishAt ?? ''), now) ? 'published' : 'draft';
17
+ return data.status === 'draft' || data.status === 'unlisted' ? data.status : 'published';
18
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @param {any} x
3
+ * @param {number} api
4
+ * @returns {boolean}
5
+ */
6
+ export function validApp(x: any, api: number): boolean;
7
+ /**
8
+ * @param {any} x
9
+ * @param {number} api
10
+ * @returns {boolean}
11
+ */
12
+ export function validTheme(x: any, api: number): boolean;
13
+ export function isText(v: unknown): v is string;
14
+ export function isPath(v: unknown): boolean;
15
+ export const ITEM_ID: RegExp;
16
+ export const REFUSED_APPS: string[];
17
+ export const STANDARD: "saturn";
18
+ export const RECORD: "store.json";
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Pure validation logic for store apps and themes.
3
+ * Exposes isText, isPath, ITEM_ID, REFUSED_APPS, STANDARD, RECORD, validApp, validTheme.
4
+ * No external dependencies.
5
+ */
6
+
7
+ /**
8
+ * @param {unknown} v
9
+ * @returns {v is string}
10
+ */
11
+ export const isText = (v) => typeof v === 'string' && v.trim() !== '';
12
+
13
+ /**
14
+ * @param {unknown} v
15
+ * @returns {boolean}
16
+ */
17
+ export const isPath = (v) => isText(v) && v.split('/').every((part) => part !== '' && part !== '.' && part !== '..');
18
+
19
+ export const ITEM_ID = /^[a-z0-9][a-z0-9-]*$/;
20
+ // The store's address before and a developer's page (STORE_BEFORE and DEVELOPER_ROUTE in src/store.ts)
21
+ export const REFUSED_APPS = ['butik', 'udvikler'];
22
+ // The standard theme, which every site has
23
+ export const STANDARD = 'saturn';
24
+ // The note in an installed folder of where it came from
25
+ export const RECORD = 'store.json';
26
+
27
+ const isAdd = (v) => isText(v?.label) && isText(v?.icon);
28
+ const isGoodFile = (f) => isText(f?.oid) && isPath(f?.path) && f.path !== RECORD;
29
+
30
+ /**
31
+ * @param {any} x
32
+ * @param {number} api
33
+ * @returns {boolean}
34
+ */
35
+ export function validApp(x, api) {
36
+ return (
37
+ ITEM_ID.test(x?.id ?? '') &&
38
+ !REFUSED_APPS.includes(x.id) &&
39
+ isText(x.version) &&
40
+ x.api === api &&
41
+ [x.label, x.publisher, x.icon, x.hint].every(isText) &&
42
+ Array.isArray(x.files) &&
43
+ x.files.length > 0 &&
44
+ x.files.every(isGoodFile) &&
45
+ ['blocks', 'lists', 'kinds'].every((k) => Array.isArray(x.adds?.[k]) && x.adds[k].every(isAdd))
46
+ );
47
+ }
48
+
49
+ /**
50
+ * @param {any} x
51
+ * @param {number} api
52
+ * @returns {boolean}
53
+ */
54
+ export function validTheme(x, api) {
55
+ return (
56
+ ITEM_ID.test(x?.id ?? '') &&
57
+ x.id !== STANDARD &&
58
+ x.api === api &&
59
+ [x.version, x.name, x.author, x.icon].every(isText) &&
60
+ Array.isArray(x.files) &&
61
+ x.files.length > 0 &&
62
+ x.files.every(isGoodFile)
63
+ );
64
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Tests for store entry validation logic (validApp, validTheme, isPath).
3
+ * Run with `node --test packages/editor/lib/*.test.mjs` (part of npm run check).
4
+ */
5
+ import { test } from 'node:test';
6
+ import assert from 'node:assert/strict';
7
+ import { validApp, validTheme, isPath } from './storeEntries.mjs';
8
+
9
+ const theme = () => ({
10
+ id: 'venus',
11
+ version: '1.0.0',
12
+ api: 4,
13
+ name: 'Venus',
14
+ author: 'Morpheme',
15
+ icon: 'palette',
16
+ files: [{ path: 'theme.json', oid: 'a'.repeat(40) }],
17
+ });
18
+ const app = () => ({
19
+ id: 'calendly',
20
+ version: '1.0.0',
21
+ api: 2,
22
+ label: 'Calendly',
23
+ publisher: 'Morpheme',
24
+ icon: 'event',
25
+ hint: 'Bookings',
26
+ files: [{ path: 'index.ts', oid: 'b'.repeat(40) }],
27
+ adds: { blocks: [{ label: 'Booking', icon: 'event' }], lists: [], kinds: [] },
28
+ });
29
+
30
+ test('valid theme', () => {
31
+ assert.equal(validTheme(theme(), 4), true);
32
+ });
33
+
34
+ test('valid theme wrong api', () => {
35
+ assert.equal(validTheme({ ...theme(), api: 3 }, 4), false);
36
+ });
37
+
38
+ test('valid theme standard id', () => {
39
+ assert.equal(validTheme({ ...theme(), id: 'saturn' }, 4), false);
40
+ });
41
+
42
+ test('valid theme bad path', () => {
43
+ assert.equal(validTheme({ ...theme(), files: [{ path: '../x', oid: 'a'.repeat(40) }] }, 4), false);
44
+ });
45
+
46
+ test('valid theme record path', () => {
47
+ assert.equal(validTheme({ ...theme(), files: [{ path: 'store.json', oid: 'a'.repeat(40) }] }, 4), false);
48
+ });
49
+
50
+ test('valid theme empty files', () => {
51
+ assert.equal(validTheme({ ...theme(), files: [] }, 4), false);
52
+ });
53
+
54
+ test('valid app', () => {
55
+ assert.equal(validApp(app(), 2), true);
56
+ });
57
+
58
+ test('valid app refused id', () => {
59
+ assert.equal(validApp({ ...app(), id: 'butik' }, 2), false);
60
+ });
61
+
62
+ test('valid app missing adds kinds', () => {
63
+ assert.equal(validApp({ ...app(), adds: { blocks: [], lists: [] } }, 2), false);
64
+ });
65
+
66
+ test('isPath cases', () => {
67
+ assert.equal(isPath('styles/global.css'), true);
68
+ assert.equal(isPath('a//b'), false);
69
+ assert.equal(isPath('./a'), false);
70
+ assert.equal(isPath(''), false);
71
+ });