@shapio/cms 0.3.0 → 0.3.1

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 (270) hide show
  1. package/dist/admin/apple-touch-icon.png +0 -0
  2. package/dist/admin/assets/{AssistError-BITJ_tpg.js → AssistError-BYR085vj.js} +2 -2
  3. package/dist/admin/assets/{AssistError-BITJ_tpg.js.map → AssistError-BYR085vj.js.map} +1 -1
  4. package/dist/admin/assets/{BlockMenuItems-CcluK965.js → BlockMenuItems-BnLF3Efc.js} +2 -2
  5. package/dist/admin/assets/{BlockMenuItems-CcluK965.js.map → BlockMenuItems-BnLF3Efc.js.map} +1 -1
  6. package/dist/admin/assets/{Body-BXa9DhtH.js → Body-CCOZq2q9.js} +2 -2
  7. package/dist/admin/assets/{Body-BXa9DhtH.js.map → Body-CCOZq2q9.js.map} +1 -1
  8. package/dist/admin/assets/{Builder-DcpRfXuc.js → Builder-BZy9mphs.js} +2 -2
  9. package/dist/admin/assets/{Builder-DcpRfXuc.js.map → Builder-BZy9mphs.js.map} +1 -1
  10. package/dist/admin/assets/{ConfirmDialog-B9nWhIIz.js → ConfirmDialog-Tu-gjEwm.js} +2 -2
  11. package/dist/admin/assets/{ConfirmDialog-B9nWhIIz.js.map → ConfirmDialog-Tu-gjEwm.js.map} +1 -1
  12. package/dist/admin/assets/{CopyButton-BoWb-xi1.js → CopyButton-BuBaIlCk.js} +2 -2
  13. package/dist/admin/assets/{CopyButton-BoWb-xi1.js.map → CopyButton-BuBaIlCk.js.map} +1 -1
  14. package/dist/admin/assets/{CursorPager-BnxmTk47.js → CursorPager-Bvu3CXpD.js} +2 -2
  15. package/dist/admin/assets/{CursorPager-BnxmTk47.js.map → CursorPager-Bvu3CXpD.js.map} +1 -1
  16. package/dist/admin/assets/{ExternalLink-Eeb9mONJ.js → ExternalLink-CCr5oRXI.js} +2 -2
  17. package/dist/admin/assets/{ExternalLink-Eeb9mONJ.js.map → ExternalLink-CCr5oRXI.js.map} +1 -1
  18. package/dist/admin/assets/Form-Doc0JEzF.js +2 -0
  19. package/dist/admin/assets/{Form-DZRLD3vH.js.map → Form-Doc0JEzF.js.map} +1 -1
  20. package/dist/admin/assets/{FormCheckboxGroup-uIC2XQIL.js → FormCheckboxGroup-eg39IJvf.js} +2 -2
  21. package/dist/admin/assets/{FormCheckboxGroup-uIC2XQIL.js.map → FormCheckboxGroup-eg39IJvf.js.map} +1 -1
  22. package/dist/admin/assets/{FormRadioGroup-hd95vPOu.js → FormRadioGroup-ZppSTZK6.js} +2 -2
  23. package/dist/admin/assets/{FormRadioGroup-hd95vPOu.js.map → FormRadioGroup-ZppSTZK6.js.map} +1 -1
  24. package/dist/admin/assets/{FormSelectField-D7VHmnx5.js → FormSelectField-Cosnxiz-.js} +2 -2
  25. package/dist/admin/assets/{FormSelectField-D7VHmnx5.js.map → FormSelectField-Cosnxiz-.js.map} +1 -1
  26. package/dist/admin/assets/{FormSwitchField-ft8Jbe6E.js → FormSwitchField-DsKQEZw6.js} +2 -2
  27. package/dist/admin/assets/{FormSwitchField-ft8Jbe6E.js.map → FormSwitchField-DsKQEZw6.js.map} +1 -1
  28. package/dist/admin/assets/{FormTextareaField-DzyOzfZb.js → FormTextareaField-BXidSgIE.js} +2 -2
  29. package/dist/admin/assets/{FormTextareaField-DzyOzfZb.js.map → FormTextareaField-BXidSgIE.js.map} +1 -1
  30. package/dist/admin/assets/{HintedLabel-CvC46uy_.js → HintedLabel-USQku9Yt.js} +2 -2
  31. package/dist/admin/assets/{HintedLabel-CvC46uy_.js.map → HintedLabel-USQku9Yt.js.map} +1 -1
  32. package/dist/admin/assets/{InfoHint-GJLRVumb.js → InfoHint-Bz_yvehr.js} +2 -2
  33. package/dist/admin/assets/{InfoHint-GJLRVumb.js.map → InfoHint-Bz_yvehr.js.map} +1 -1
  34. package/dist/admin/assets/{InsertMenuItem-D976G0Rj.js → InsertMenuItem-DJXglsEd.js} +2 -2
  35. package/dist/admin/assets/{InsertMenuItem-D976G0Rj.js.map → InsertMenuItem-DJXglsEd.js.map} +1 -1
  36. package/dist/admin/assets/{LinkTabs-BZSlA57U.js → LinkTabs-D4U-rJyK.js} +2 -2
  37. package/dist/admin/assets/{LinkTabs-BZSlA57U.js.map → LinkTabs-D4U-rJyK.js.map} +1 -1
  38. package/dist/admin/assets/{Match-DdxTHHM4.js → Match-UAw1Ss8a.js} +2 -2
  39. package/dist/admin/assets/{Match-DdxTHHM4.js.map → Match-UAw1Ss8a.js.map} +1 -1
  40. package/dist/admin/assets/{Panel-iIKjEURi.js → Panel-BdjqCkKs.js} +2 -2
  41. package/dist/admin/assets/{Panel-iIKjEURi.js.map → Panel-BdjqCkKs.js.map} +1 -1
  42. package/dist/admin/assets/{QueryView-D6aZQJRN.js → QueryView-Bkyizh1P.js} +2 -2
  43. package/dist/admin/assets/{QueryView-D6aZQJRN.js.map → QueryView-Bkyizh1P.js.map} +1 -1
  44. package/dist/admin/assets/{RadioTile-BpB79rIK.js → RadioTile-VHTPl88w.js} +2 -2
  45. package/dist/admin/assets/RadioTile-VHTPl88w.js.map +1 -0
  46. package/dist/admin/assets/{RichTextField-BuHCONPu.js → RichTextField-B21FqrT5.js} +4 -4
  47. package/dist/admin/assets/{RichTextField-BuHCONPu.js.map → RichTextField-B21FqrT5.js.map} +1 -1
  48. package/dist/admin/assets/{RowTitle--uFCpx8n.js → RowTitle-BD8QPs_v.js} +2 -2
  49. package/dist/admin/assets/{RowTitle--uFCpx8n.js.map → RowTitle-BD8QPs_v.js.map} +1 -1
  50. package/dist/admin/assets/{SecretReveal-DFpzeNE0.js → SecretReveal-BfJKUxXW.js} +2 -2
  51. package/dist/admin/assets/{SecretReveal-DFpzeNE0.js.map → SecretReveal-BfJKUxXW.js.map} +1 -1
  52. package/dist/admin/assets/{SharedGlyph-Cqkx30tn.js → SharedGlyph-DDPdvsm_.js} +2 -2
  53. package/dist/admin/assets/{SharedGlyph-Cqkx30tn.js.map → SharedGlyph-DDPdvsm_.js.map} +1 -1
  54. package/dist/admin/assets/{StepList-BY5MuJPJ.js → StepList-DKhkw1hN.js} +2 -2
  55. package/dist/admin/assets/{StepList-BY5MuJPJ.js.map → StepList-DKhkw1hN.js.map} +1 -1
  56. package/dist/admin/assets/Structure-C7dr00Bp.js +2 -0
  57. package/dist/admin/assets/{Structure-CqRa2t7z.js.map → Structure-C7dr00Bp.js.map} +1 -1
  58. package/dist/admin/assets/{SubNavLink-B2o4kSZ9.js → SubNavLink-BAF2-wuF.js} +2 -2
  59. package/dist/admin/assets/{SubNavLink-B2o4kSZ9.js.map → SubNavLink-BAF2-wuF.js.map} +1 -1
  60. package/dist/admin/assets/{SuggestAltButton-4rf2xhEJ.js → SuggestAltButton-DEsbHvs4.js} +2 -2
  61. package/dist/admin/assets/{SuggestAltButton-4rf2xhEJ.js.map → SuggestAltButton-DEsbHvs4.js.map} +1 -1
  62. package/dist/admin/assets/{TextLink-D15oyXlc.js → TextLink-CegO3jom.js} +2 -2
  63. package/dist/admin/assets/{TextLink-D15oyXlc.js.map → TextLink-CegO3jom.js.map} +1 -1
  64. package/dist/admin/assets/{Thumbnail-CP5mfgNY.js → Thumbnail-CTpKlrxR.js} +2 -2
  65. package/dist/admin/assets/{Thumbnail-CP5mfgNY.js.map → Thumbnail-CTpKlrxR.js.map} +1 -1
  66. package/dist/admin/assets/{UnsavedChangesGuard-DgOASh0p.js → UnsavedChangesGuard-Cbfg-Bgj.js} +2 -2
  67. package/dist/admin/assets/{UnsavedChangesGuard-DgOASh0p.js.map → UnsavedChangesGuard-Cbfg-Bgj.js.map} +1 -1
  68. package/dist/admin/assets/{UserAvatar-BocvNVL-.js → UserAvatar-CiZ00-cr.js} +2 -2
  69. package/dist/admin/assets/{UserAvatar-BocvNVL-.js.map → UserAvatar-CiZ00-cr.js.map} +1 -1
  70. package/dist/admin/assets/{arrow-up-gf_j6SVQ.js → arrow-up-DwMJqZVV.js} +2 -2
  71. package/dist/admin/assets/{arrow-up-gf_j6SVQ.js.map → arrow-up-DwMJqZVV.js.map} +1 -1
  72. package/dist/admin/assets/{auth-pcS9CCXu.js → auth-BaVAo0u_.js} +2 -2
  73. package/dist/admin/assets/{auth-pcS9CCXu.js.map → auth-BaVAo0u_.js.map} +1 -1
  74. package/dist/admin/assets/{badge-DD0mE96i.js → badge-IBeVOhKd.js} +2 -2
  75. package/dist/admin/assets/{badge-DD0mE96i.js.map → badge-IBeVOhKd.js.map} +1 -1
  76. package/dist/admin/assets/{boxes-DcK-kaSa.js → boxes-BH0MDegO.js} +2 -2
  77. package/dist/admin/assets/{boxes-DcK-kaSa.js.map → boxes-BH0MDegO.js.map} +1 -1
  78. package/dist/admin/assets/{calendar-clock-DEwACe0M.js → calendar-clock-DKUk-w81.js} +2 -2
  79. package/dist/admin/assets/{calendar-clock-DEwACe0M.js.map → calendar-clock-DKUk-w81.js.map} +1 -1
  80. package/dist/admin/assets/{changeSets-BjUEfYbj.js → changeSets-o_G67qPk.js} +2 -2
  81. package/dist/admin/assets/{changeSets-BjUEfYbj.js.map → changeSets-o_G67qPk.js.map} +1 -1
  82. package/dist/admin/assets/chevron-left-D259hWJn.js +2 -0
  83. package/dist/admin/assets/{chevron-left-BsQYDUEC.js.map → chevron-left-D259hWJn.js.map} +1 -1
  84. package/dist/admin/assets/{circle-check-Dq1owihe.js → circle-check-Cidzt1Ww.js} +2 -2
  85. package/dist/admin/assets/{circle-check-Dq1owihe.js.map → circle-check-Cidzt1Ww.js.map} +1 -1
  86. package/dist/admin/assets/{circle-x-Dx6zIZko.js → circle-x-c1RwmC6j.js} +2 -2
  87. package/dist/admin/assets/{circle-x-Dx6zIZko.js.map → circle-x-c1RwmC6j.js.map} +1 -1
  88. package/dist/admin/assets/{clock-DQvkffqQ.js → clock-BOtPNp9-.js} +2 -2
  89. package/dist/admin/assets/{clock-DQvkffqQ.js.map → clock-BOtPNp9-.js.map} +1 -1
  90. package/dist/admin/assets/cn-M4_WHiur.js +2 -0
  91. package/dist/admin/assets/cn-M4_WHiur.js.map +1 -0
  92. package/dist/admin/assets/coerce-DWI5sgLW.js +2 -0
  93. package/dist/admin/assets/{coerce-OsqQRj19.js.map → coerce-DWI5sgLW.js.map} +1 -1
  94. package/dist/admin/assets/{constants-SrImR6C3.js → constants-CgUdkWmf.js} +2 -2
  95. package/dist/admin/assets/{constants-SrImR6C3.js.map → constants-CgUdkWmf.js.map} +1 -1
  96. package/dist/admin/assets/content-D25ainqV.js +3 -0
  97. package/dist/admin/assets/{content-_SLbbnfX.js.map → content-D25ainqV.js.map} +1 -1
  98. package/dist/admin/assets/{contentCounts-Ch3uMXVU.js → contentCounts-T-LmvUf5.js} +2 -2
  99. package/dist/admin/assets/{contentCounts-Ch3uMXVU.js.map → contentCounts-T-LmvUf5.js.map} +1 -1
  100. package/dist/admin/assets/{contentTypes-BCOdUK_Z.js → contentTypes-BSlp81l1.js} +2 -2
  101. package/dist/admin/assets/{contentTypes-BCOdUK_Z.js.map → contentTypes-BSlp81l1.js.map} +1 -1
  102. package/dist/admin/assets/{copy-BDc3r0fO.js → copy-DT7dAzVm.js} +2 -2
  103. package/dist/admin/assets/{copy-BDc3r0fO.js.map → copy-DT7dAzVm.js.map} +1 -1
  104. package/dist/admin/assets/{dateTimeLocal-C92tyKwz.js → dateTimeLocal-DRq7DuYO.js} +2 -2
  105. package/dist/admin/assets/{dateTimeLocal-C92tyKwz.js.map → dateTimeLocal-DRq7DuYO.js.map} +1 -1
  106. package/dist/admin/assets/{develop-DS9TlDmv.js → develop-qF10t9tM.js} +6 -6
  107. package/dist/admin/assets/{develop-DS9TlDmv.js.map → develop-qF10t9tM.js.map} +1 -1
  108. package/dist/admin/assets/{dropdown-menu-gmP2Rp3n.js → dropdown-menu-Cl20LCvY.js} +2 -2
  109. package/dist/admin/assets/{dropdown-menu-gmP2Rp3n.js.map → dropdown-menu-Cl20LCvY.js.map} +1 -1
  110. package/dist/admin/assets/{ellipsis-NK0pWgqU.js → ellipsis-xDmHl1SK.js} +2 -2
  111. package/dist/admin/assets/{ellipsis-NK0pWgqU.js.map → ellipsis-xDmHl1SK.js.map} +1 -1
  112. package/dist/admin/assets/{external-link-D3Aoi2yX.js → external-link-DtJAaOWk.js} +2 -2
  113. package/dist/admin/assets/{external-link-D3Aoi2yX.js.map → external-link-DtJAaOWk.js.map} +1 -1
  114. package/dist/admin/assets/{file-text-DxXAmmxL.js → file-text-BJkQMeQO.js} +2 -2
  115. package/dist/admin/assets/{file-text-DxXAmmxL.js.map → file-text-BJkQMeQO.js.map} +1 -1
  116. package/dist/admin/assets/{fileRoute-C2tOrKhO.js → fileRoute-Buucm0CU.js} +2 -2
  117. package/dist/admin/assets/{fileRoute-C2tOrKhO.js.map → fileRoute-Buucm0CU.js.map} +1 -1
  118. package/dist/admin/assets/{followPlural-CN6cQfNk.js → followPlural-Cuocm4Sv.js} +2 -2
  119. package/dist/admin/assets/{followPlural-CN6cQfNk.js.map → followPlural-Cuocm4Sv.js.map} +1 -1
  120. package/dist/admin/assets/{globe-CuElSilX.js → globe-CAhrwBgv.js} +2 -2
  121. package/dist/admin/assets/{globe-CuElSilX.js.map → globe-CAhrwBgv.js.map} +1 -1
  122. package/dist/admin/assets/{image-CsH8dZve.js → image-CGN6ffEu.js} +2 -2
  123. package/dist/admin/assets/{image-CsH8dZve.js.map → image-CGN6ffEu.js.map} +1 -1
  124. package/dist/admin/assets/{image-off-B_uBCsYu.js → image-off-0zX_kODH.js} +2 -2
  125. package/dist/admin/assets/{image-off-B_uBCsYu.js.map → image-off-0zX_kODH.js.map} +1 -1
  126. package/dist/admin/assets/{inbox-DsuXNaKE.js → inbox-CWq1hHqK.js} +2 -2
  127. package/dist/admin/assets/{inbox-DsuXNaKE.js.map → inbox-CWq1hHqK.js.map} +1 -1
  128. package/dist/admin/assets/{inbox-3iAHL3pC.js → inbox-CukkApHK.js} +2 -2
  129. package/dist/admin/assets/{inbox-3iAHL3pC.js.map → inbox-CukkApHK.js.map} +1 -1
  130. package/dist/admin/assets/index-C9uJxg4J.js +4 -0
  131. package/dist/admin/assets/index-C9uJxg4J.js.map +1 -0
  132. package/dist/admin/assets/index-Cz3C-LxB.css +2 -0
  133. package/dist/admin/assets/{key-round-B17HiT3K.js → key-round-DnE-2gr0.js} +2 -2
  134. package/dist/admin/assets/{key-round-B17HiT3K.js.map → key-round-DnE-2gr0.js.map} +1 -1
  135. package/dist/admin/assets/{link-2-off-hWGS8LW6.js → link-2-off-Cbpvb3w4.js} +2 -2
  136. package/dist/admin/assets/{link-2-off-hWGS8LW6.js.map → link-2-off-Cbpvb3w4.js.map} +1 -1
  137. package/dist/admin/assets/{link-bhHmG4Tc.js → link-DPniuk00.js} +2 -2
  138. package/dist/admin/assets/{link-bhHmG4Tc.js.map → link-DPniuk00.js.map} +1 -1
  139. package/dist/admin/assets/{list-DRtRdjBC.js → list-CkHF_4xh.js} +2 -2
  140. package/dist/admin/assets/{list-DRtRdjBC.js.map → list-CkHF_4xh.js.map} +1 -1
  141. package/dist/admin/assets/{locales-BzPbz8FF.js → locales-DFLQ17ow.js} +2 -2
  142. package/dist/admin/assets/{locales-BzPbz8FF.js.map → locales-DFLQ17ow.js.map} +1 -1
  143. package/dist/admin/assets/{media-Xzot1ueY.js → media-CKTs3j83.js} +2 -2
  144. package/dist/admin/assets/{media-Xzot1ueY.js.map → media-CKTs3j83.js.map} +1 -1
  145. package/dist/admin/assets/{media-WLnWaL7U.js → media-CUfV74JZ.js} +2 -2
  146. package/dist/admin/assets/{media-WLnWaL7U.js.map → media-CUfV74JZ.js.map} +1 -1
  147. package/dist/admin/assets/{network-DHGqLwji.js → network-Fri1cjMt.js} +2 -2
  148. package/dist/admin/assets/{network-DHGqLwji.js.map → network-Fri1cjMt.js.map} +1 -1
  149. package/dist/admin/assets/{pencil-Bdp2z9D_.js → pencil-BqAgKC9v.js} +2 -2
  150. package/dist/admin/assets/{pencil-Bdp2z9D_.js.map → pencil-BqAgKC9v.js.map} +1 -1
  151. package/dist/admin/assets/{plus-BN_iSsnp.js → plus-DLRcpVhJ.js} +2 -2
  152. package/dist/admin/assets/{plus-BN_iSsnp.js.map → plus-DLRcpVhJ.js.map} +1 -1
  153. package/dist/admin/assets/{preload-helper-DAbCfXID.js → preload-helper-BHNBIF88.js} +2 -2
  154. package/dist/admin/assets/{preload-helper-DAbCfXID.js.map → preload-helper-BHNBIF88.js.map} +1 -1
  155. package/dist/admin/assets/{publishing-d9yhMwgA.js → publishing-DaaE8PaU.js} +2 -2
  156. package/dist/admin/assets/{publishing-d9yhMwgA.js.map → publishing-DaaE8PaU.js.map} +1 -1
  157. package/dist/admin/assets/{radio-group-DHIxK-IU.js → radio-group-CA3XlQcc.js} +2 -2
  158. package/dist/admin/assets/{radio-group-DHIxK-IU.js.map → radio-group-CA3XlQcc.js.map} +1 -1
  159. package/dist/admin/assets/{rotate-ccw-CBoZle-b.js → rotate-ccw-CfrkcgYa.js} +2 -2
  160. package/dist/admin/assets/{rotate-ccw-CBoZle-b.js.map → rotate-ccw-CfrkcgYa.js.map} +1 -1
  161. package/dist/admin/assets/{schedules-Dy89Nm6P.js → schedules-hJQkjEhN.js} +2 -2
  162. package/dist/admin/assets/{schedules-Dy89Nm6P.js.map → schedules-hJQkjEhN.js.map} +1 -1
  163. package/dist/admin/assets/{schema-B4smPFcR.js → schema--xSR7cf9.js} +2 -2
  164. package/dist/admin/assets/{schema-B4smPFcR.js.map → schema--xSR7cf9.js.map} +1 -1
  165. package/dist/admin/assets/{scroll-text-UbyzpWh-.js → scroll-text-BA9yh7Za.js} +2 -2
  166. package/dist/admin/assets/{scroll-text-UbyzpWh-.js.map → scroll-text-BA9yh7Za.js.map} +1 -1
  167. package/dist/admin/assets/{search-_YlNpPvU.js → search--71HzPvh.js} +2 -2
  168. package/dist/admin/assets/{search-_YlNpPvU.js.map → search--71HzPvh.js.map} +1 -1
  169. package/dist/admin/assets/{searchSchema-CvOhn4FV.js → searchSchema-Ypl6gq9g.js} +2 -2
  170. package/dist/admin/assets/{searchSchema-CvOhn4FV.js.map → searchSchema-Ypl6gq9g.js.map} +1 -1
  171. package/dist/admin/assets/{searchSchemas-BxRnxenn.js → searchSchemas-C-nQbyhd.js} +2 -2
  172. package/dist/admin/assets/{searchSchemas-BxRnxenn.js.map → searchSchemas-C-nQbyhd.js.map} +1 -1
  173. package/dist/admin/assets/sections-BBN2JErq.js +2 -0
  174. package/dist/admin/assets/sections-BBN2JErq.js.map +1 -0
  175. package/dist/admin/assets/{sections-Bb3Q4bcY.js → sections-D0OZozD2.js} +2 -2
  176. package/dist/admin/assets/{sections-Bb3Q4bcY.js.map → sections-D0OZozD2.js.map} +1 -1
  177. package/dist/admin/assets/{select-tHVWX85X.js → select-De48SQdZ.js} +2 -2
  178. package/dist/admin/assets/{select-tHVWX85X.js.map → select-De48SQdZ.js.map} +1 -1
  179. package/dist/admin/assets/{send-BqECHYi6.js → send-NuSmLVSD.js} +2 -2
  180. package/dist/admin/assets/{send-BqECHYi6.js.map → send-NuSmLVSD.js.map} +1 -1
  181. package/dist/admin/assets/settings-CYXU73dP.js +2 -0
  182. package/dist/admin/assets/settings-CYXU73dP.js.map +1 -0
  183. package/dist/admin/assets/skeleton-CCwdO9oq.js +42 -0
  184. package/dist/admin/assets/skeleton-CCwdO9oq.js.map +1 -0
  185. package/dist/admin/assets/{snapshots-BQrhsCmC.js → snapshots-BQeFK5cj.js} +2 -2
  186. package/dist/admin/assets/{snapshots-BQrhsCmC.js.map → snapshots-BQeFK5cj.js.map} +1 -1
  187. package/dist/admin/assets/{sparkles-BW4CbD6W.js → sparkles-B-0I44es.js} +2 -2
  188. package/dist/admin/assets/{sparkles-BW4CbD6W.js.map → sparkles-B-0I44es.js.map} +1 -1
  189. package/dist/admin/assets/{src-XaU0N8C-.js → src-CQu-YxUM.js} +2 -2
  190. package/dist/admin/assets/src-CQu-YxUM.js.map +1 -0
  191. package/dist/admin/assets/{stableId-C9Yq5iUw.js → stableId-rPnYVF-A.js} +2 -2
  192. package/dist/admin/assets/{stableId-C9Yq5iUw.js.map → stableId-rPnYVF-A.js.map} +1 -1
  193. package/dist/admin/assets/{store-BphwUzV5.js → store-Bqd9L9DK.js} +2 -2
  194. package/dist/admin/assets/{store-BphwUzV5.js.map → store-Bqd9L9DK.js.map} +1 -1
  195. package/dist/admin/assets/{switch-BVy02Vc8.js → switch-JmfyFAQG.js} +2 -2
  196. package/dist/admin/assets/{switch-BVy02Vc8.js.map → switch-JmfyFAQG.js.map} +1 -1
  197. package/dist/admin/assets/{table-CZYtdoHn.js → table-BEDv9IRM.js} +2 -2
  198. package/dist/admin/assets/{table-CZYtdoHn.js.map → table-BEDv9IRM.js.map} +1 -1
  199. package/dist/admin/assets/{tabs-quHbeVxA.js → tabs-DSS1c-Kf.js} +4 -4
  200. package/dist/admin/assets/{tabs-quHbeVxA.js.map → tabs-DSS1c-Kf.js.map} +1 -1
  201. package/dist/admin/assets/{textarea-B8Vl5gJ1.js → textarea-eatLAWE_.js} +2 -2
  202. package/dist/admin/assets/{textarea-B8Vl5gJ1.js.map → textarea-eatLAWE_.js.map} +1 -1
  203. package/dist/admin/assets/{titles-B2z5ckxG.js → titles-Bi2fWNN4.js} +2 -2
  204. package/dist/admin/assets/{titles-B2z5ckxG.js.map → titles-Bi2fWNN4.js.map} +1 -1
  205. package/dist/admin/assets/{tokens-Fh_OeIlf.js → tokens-C2E7swse.js} +2 -2
  206. package/dist/admin/assets/{tokens-Fh_OeIlf.js.map → tokens-C2E7swse.js.map} +1 -1
  207. package/dist/admin/assets/{tooltip-DwqM3opE.js → tooltip-Bji9fmSr.js} +2 -2
  208. package/dist/admin/assets/{tooltip-DwqM3opE.js.map → tooltip-Bji9fmSr.js.map} +1 -1
  209. package/dist/admin/assets/{undo-2-D4Fz4JMZ.js → undo-2-BU-uqm7e.js} +2 -2
  210. package/dist/admin/assets/{undo-2-D4Fz4JMZ.js.map → undo-2-BU-uqm7e.js.map} +1 -1
  211. package/dist/admin/assets/{useAuditLabels-DKrsrciQ.js → useAuditLabels-D5nmbXqN.js} +2 -2
  212. package/dist/admin/assets/{useAuditLabels-DKrsrciQ.js.map → useAuditLabels-D5nmbXqN.js.map} +1 -1
  213. package/dist/admin/assets/{useConfirmTarget-Dp8mCulm.js → useConfirmTarget-Y7_8kVX5.js} +2 -2
  214. package/dist/admin/assets/{useConfirmTarget-Dp8mCulm.js.map → useConfirmTarget-Y7_8kVX5.js.map} +1 -1
  215. package/dist/admin/assets/useContentSchema-DJTqjlUk.js +2 -0
  216. package/dist/admin/assets/{useContentSchema-Bv4_6VJR.js.map → useContentSchema-DJTqjlUk.js.map} +1 -1
  217. package/dist/admin/assets/{useCursorPager-B1upg5EU.js → useCursorPager-CiJroOo7.js} +2 -2
  218. package/dist/admin/assets/{useCursorPager-B1upg5EU.js.map → useCursorPager-CiJroOo7.js.map} +1 -1
  219. package/dist/admin/assets/{useDiscardGuard-34ynGJIk.js → useDiscardGuard-t_N3l9TQ.js} +2 -2
  220. package/dist/admin/assets/{useDiscardGuard-34ynGJIk.js.map → useDiscardGuard-t_N3l9TQ.js.map} +1 -1
  221. package/dist/admin/assets/{useMediaUploader-QXSjZStv.js → useMediaUploader-CLHmKCwq.js} +2 -2
  222. package/dist/admin/assets/{useMediaUploader-QXSjZStv.js.map → useMediaUploader-CLHmKCwq.js.map} +1 -1
  223. package/dist/admin/assets/{usePaletteItems-62-TZhy7.js → usePaletteItems-BVjWCdow.js} +2 -2
  224. package/dist/admin/assets/{usePaletteItems-62-TZhy7.js.map → usePaletteItems-BVjWCdow.js.map} +1 -1
  225. package/dist/admin/assets/{usePlaces-CY6f2DmI.js → usePlaces-CnSOZwtO.js} +2 -2
  226. package/dist/admin/assets/{usePlaces-CY6f2DmI.js.map → usePlaces-CnSOZwtO.js.map} +1 -1
  227. package/dist/admin/assets/{useQueries-BuKJBA0M.js → useQueries-BRolGUiw.js} +2 -2
  228. package/dist/admin/assets/{useQueries-BuKJBA0M.js.map → useQueries-BRolGUiw.js.map} +1 -1
  229. package/dist/admin/assets/{useSchemaScopeAccess-DUBeS9kU.js → useSchemaScopeAccess-bd8RQxuu.js} +2 -2
  230. package/dist/admin/assets/{useSchemaScopeAccess-DUBeS9kU.js.map → useSchemaScopeAccess-bd8RQxuu.js.map} +1 -1
  231. package/dist/admin/assets/{users-BOn2ohJQ.js → users-CbErtM7w.js} +2 -2
  232. package/dist/admin/assets/{users-BOn2ohJQ.js.map → users-CbErtM7w.js.map} +1 -1
  233. package/dist/admin/assets/{users-BkKc4MNB.js → users-bDGYpSXg.js} +2 -2
  234. package/dist/admin/assets/{users-BkKc4MNB.js.map → users-bDGYpSXg.js.map} +1 -1
  235. package/dist/admin/assets/{zod-BHAd1wTC.js → zod-Gtw4e0qi.js} +2 -2
  236. package/dist/admin/assets/{zod-BHAd1wTC.js.map → zod-Gtw4e0qi.js.map} +1 -1
  237. package/dist/admin/favicon-32.png +0 -0
  238. package/dist/admin/favicon.svg +2 -2
  239. package/dist/admin/index.html +60 -56
  240. package/dist/admin/theme-init.js +41 -9
  241. package/dist/cli.js +30 -6
  242. package/dist/cli.js.map +1 -1
  243. package/dist/config.d.ts +2 -2
  244. package/dist/config.js.map +1 -1
  245. package/dist/index.d.ts +11 -224
  246. package/dist/index.js +1 -1
  247. package/dist/{public-CGO8RBn3.d.ts → public-B7fFHMNr.d.ts} +251 -5
  248. package/dist/{worker-BLXy8aRW.js → worker-BAmQPoTJ.js} +574 -108
  249. package/dist/worker-BAmQPoTJ.js.map +1 -0
  250. package/package.json +5 -5
  251. package/dist/admin/assets/Form-DZRLD3vH.js +0 -2
  252. package/dist/admin/assets/RadioTile-BpB79rIK.js.map +0 -1
  253. package/dist/admin/assets/Structure-CqRa2t7z.js +0 -2
  254. package/dist/admin/assets/chevron-left-BsQYDUEC.js +0 -2
  255. package/dist/admin/assets/cn-BQ3voEft.js +0 -2
  256. package/dist/admin/assets/cn-BQ3voEft.js.map +0 -1
  257. package/dist/admin/assets/coerce-OsqQRj19.js +0 -2
  258. package/dist/admin/assets/content-_SLbbnfX.js +0 -3
  259. package/dist/admin/assets/index-BLYOgCKc.css +0 -2
  260. package/dist/admin/assets/index-BSzXA60W.js +0 -4
  261. package/dist/admin/assets/index-BSzXA60W.js.map +0 -1
  262. package/dist/admin/assets/sections-DiySZZHb.js +0 -2
  263. package/dist/admin/assets/sections-DiySZZHb.js.map +0 -1
  264. package/dist/admin/assets/settings-D-v8gL8F.js +0 -2
  265. package/dist/admin/assets/settings-D-v8gL8F.js.map +0 -1
  266. package/dist/admin/assets/skeleton-C3QLIh7W.js +0 -42
  267. package/dist/admin/assets/skeleton-C3QLIh7W.js.map +0 -1
  268. package/dist/admin/assets/src-XaU0N8C-.js.map +0 -1
  269. package/dist/admin/assets/useContentSchema-Bv4_6VJR.js +0 -2
  270. package/dist/worker-BLXy8aRW.js.map +0 -1
package/dist/config.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as ServiceFactoryContext, C as HookEvent, D as MediaUsage, E as MediaReferenceService, M as ShapioServices, N as defineConfig, O as ModelHooks, P as isHookError, S as HookError, T as JobHandlerContext, _ as ExtensionRoute, a as BeforeHookContext, b as ExtensionSite, c as ContentReadOptions, d as EXTENSION_CONTRACT_VERSION, f as EnqueueOptions, g as ExtensionJobService, h as ExtensionJobHandler, i as BeforeHook, j as ShapioConfig, k as ServiceFactory, l as ContentReadService, m as ExtensionHostConfig, n as AfterHookContext, o as BeforeHookEvent, p as EntryData, r as AfterHookEvent, s as ContentReadEntry, t as AfterHook, u as CustomServices, v as ExtensionRouteOptions, w as HookModel, x as HookEntry, y as ExtensionServices } from "./public-CGO8RBn3.js";
2
- export { AfterHook, AfterHookContext, AfterHookEvent, BeforeHook, BeforeHookContext, BeforeHookEvent, ContentReadEntry, ContentReadOptions, ContentReadService, CustomServices, EXTENSION_CONTRACT_VERSION, EnqueueOptions, EntryData, ExtensionHostConfig, ExtensionJobHandler, ExtensionJobService, ExtensionRoute, ExtensionRouteOptions, ExtensionServices, ExtensionSite, HookEntry, HookError, HookEvent, HookModel, JobHandlerContext, MediaReferenceService, MediaUsage, ModelHooks, ServiceFactory, ServiceFactoryContext, ShapioConfig, ShapioServices, defineConfig, isHookError };
1
+ import { A as ServiceFactoryContext, C as HookEvent, D as MediaUsage, E as MediaReferenceService, F as defineConfig, I as isHookError, M as ShapioServices, N as ThemeDefinition, O as ModelHooks, P as ThemeTokens, S as HookError, T as JobHandlerContext, _ as ExtensionRoute, a as BeforeHookContext, b as ExtensionSite, c as ContentReadOptions, d as EXTENSION_CONTRACT_VERSION, f as EnqueueOptions, g as ExtensionJobService, h as ExtensionJobHandler, i as BeforeHook, j as ShapioConfig, k as ServiceFactory, l as ContentReadService, m as ExtensionHostConfig, n as AfterHookContext, o as BeforeHookEvent, p as EntryData, r as AfterHookEvent, s as ContentReadEntry, t as AfterHook, u as CustomServices, v as ExtensionRouteOptions, w as HookModel, x as HookEntry, y as ExtensionServices } from "./public-B7fFHMNr.js";
2
+ export { AfterHook, AfterHookContext, AfterHookEvent, BeforeHook, BeforeHookContext, BeforeHookEvent, ContentReadEntry, ContentReadOptions, ContentReadService, CustomServices, EXTENSION_CONTRACT_VERSION, EnqueueOptions, EntryData, ExtensionHostConfig, ExtensionJobHandler, ExtensionJobService, ExtensionRoute, ExtensionRouteOptions, ExtensionServices, ExtensionSite, HookEntry, HookError, HookEvent, HookModel, JobHandlerContext, MediaReferenceService, MediaUsage, ModelHooks, ServiceFactory, ServiceFactoryContext, ShapioConfig, ShapioServices, ThemeDefinition, ThemeTokens, defineConfig, isHookError };
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../src/extensions/public.ts"],"sourcesContent":["import type { FastifyBaseLogger, FastifyPluginAsync, preHandlerAsyncHookHandler } from 'fastify';\nimport type { Kysely, Transaction } from 'kysely';\nimport type { DB } from '../db/types.js';\nimport type { PermissionEvaluator, Principal } from '../permissions/types.js';\nimport type { RouteAuditConfig } from '../plugins/auditDeclaration.js';\n\n// What Shapio adds to Fastify, repeated here so custom route code is typed without the server's internals.\ndeclare module 'fastify' {\n interface FastifyRequest {\n /** Who is calling. Anonymous unless a session cookie or API token resolved. Never null after onRequest. */\n principal: Principal;\n /**\n * The request's site on a site route (custom routes are site routes): the credential's site, else the\n * `Shapio-Site` header or `?site=`, else the primary site. Undefined on a route declaring\n * `config.site = 'network'`.\n */\n site: { id: string; key: string } | undefined;\n }\n interface FastifyContextConfig {\n /** Required on every mutating route: the audit action recorded on success, or `{ exempt: '<why>' }`. */\n audit?: RouteAuditConfig;\n /** `'network'` for a custom route that is about the whole instance rather than one site. */\n site?: 'site' | 'network';\n }\n}\n\n/**\n * The project extension contract (ADR 0009), imported by project authors from `@shapio/cms/config`:\n *\n * ```ts\n * import { defineConfig } from '@shapio/cms/config';\n * export const config = defineConfig({ hooks: { article: { beforePublish: (ctx) => { ... } } } });\n * ```\n *\n * Extensions are code: changing them needs a restart of Shapio (never a rebuild). Content models are never\n * configured here; they change live in the admin. This file has no runtime imports from the server, so a\n * config that imports it stays cheap to load.\n *\n * Stability: everything exported here follows semver with `EXTENSION_CONTRACT_VERSION`; Shapio's database\n * tables (reachable through `trx`) are internal and may change in any release.\n */\nexport const EXTENSION_CONTRACT_VERSION = 1;\n\nexport type BeforeHookEvent = 'beforeCreate' | 'beforeUpdate' | 'beforePublish' | 'beforeDelete';\nexport type AfterHookEvent = 'afterCreate' | 'afterUpdate' | 'afterPublish' | 'afterDelete';\nexport type HookEvent = BeforeHookEvent | AfterHookEvent;\n\n/** A site of a multi-site instance: its stable ID and its key (sites share the schema, not content). */\nexport type ExtensionSite = { id: string; key: string };\n\n/** Entry data keyed by field API key (the admin API's shape; media and relations are IDs). */\nexport type EntryData = Readonly<Record<string, unknown>>;\n\nexport type HookModel = {\n /** Stable model ID (never changes). */\n id: string;\n apiKey: string;\n label: string;\n kind: 'collection' | 'singleton';\n localized: boolean;\n draftAndPublish: boolean;\n};\n\nexport type HookEntry = {\n id: string;\n locale: string | null;\n /** Which head the change is about: the draft (create/update), the live version (publish), or a delete. */\n state: 'draft' | 'published' | 'deleted';\n};\n\nexport type ContentReadOptions = {\n locale?: string;\n /** Read as this principal (its permissions apply). Default: Shapio itself (everything). */\n principal?: Principal;\n};\n\nexport type ContentReadEntry = {\n id: string;\n locale: string;\n status: string;\n data: Record<string, unknown>;\n};\n\n/** Read-only access to content (drafts, as the admin API shows them). Reads committed data. */\nexport type ContentReadService = {\n get: (modelKey: string, id: string, options?: ContentReadOptions) => Promise<ContentReadEntry>;\n /** `query` is a delivery-style querystring, e.g. `filters[title][$contains]=a&pageSize=10`. */\n list: (\n modelKey: string,\n query?: string,\n options?: Omit<ContentReadOptions, 'locale'>,\n ) => Promise<{ items: ContentReadEntry[]; total: number }>;\n /** Number of (non-deleted) entries of a model. */\n count: (modelKey: string) => Promise<number>;\n /** The active content models (collections and singletons) of this site: shared ones and its own. */\n models: () => Promise<HookModel[]>;\n};\n\nexport type MediaUsage = {\n entryId: string;\n modelId: string;\n fieldId: string;\n locale: string;\n state: string;\n};\n\nexport type MediaReferenceService = {\n /** Where an asset is used (up to 100 references, plus the total). */\n usages: (assetId: string) => Promise<{ items: MediaUsage[]; total: number }>;\n};\n\nexport type EnqueueOptions = {\n runAt?: Date;\n /** Enqueueing the same key twice creates one job. */\n idempotencyKey?: string;\n maxAttempts?: number;\n};\n\nexport type ExtensionJobService = {\n /** Enqueues one of the project's own jobs (`jobs` in the config), by its name without the `ext.` prefix. */\n enqueue: (\n name: string,\n payload?: Record<string, unknown>,\n options?: EnqueueOptions,\n ) => Promise<{ id: string; created: boolean }>;\n};\n\n/**\n * What Shapio offers extensions. Deliberately small; everything else goes through `trx` or HTTP.\n *\n * Content and media are per site. The services handed to a hook read the hook's site; the services given to\n * routes, jobs and service factories read the primary site. Use `forSite` for another one (in a custom\n * route: `services.forSite(request.site)`).\n */\nexport type ShapioServices = {\n /** The site `content` and `media` read. */\n site: ExtensionSite;\n /** The same services reading another site. */\n forSite: (site: ExtensionSite) => ShapioServices;\n content: ContentReadService;\n media: MediaReferenceService;\n jobs: ExtensionJobService;\n logger: FastifyBaseLogger;\n};\n\n/**\n * Your own services, by name. Augment it for typed access everywhere services appear:\n *\n * ```ts\n * declare module '@shapio/cms/config' {\n * interface CustomServices { stats: StatsService }\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- augmented by projects\nexport interface CustomServices {}\n\nexport type ExtensionServices = ShapioServices & CustomServices;\n\ntype HookContextBase = {\n /** The site the entry belongs to; `services` read this site. */\n site: ExtensionSite;\n model: HookModel;\n entry: HookEntry;\n locale: string | null;\n /** The document after the change (absent for deletes). */\n data: EntryData | undefined;\n /** The document before the change: the previous draft (update) or the live version (publish). */\n before: EntryData | undefined;\n /** Who made the change (an admin, an API token, an app user, or Shapio itself for scheduled work). */\n principal: Principal;\n services: ExtensionServices;\n logger: FastifyBaseLogger;\n /** Aborted when Shapio shuts down. */\n signal: AbortSignal;\n};\n\n/**\n * `before*` hooks run INSIDE the write's transaction, before it commits. Throw `HookError` (or call\n * `reject`) to abort the write with 422 `HOOK_REJECTED`; nothing of the write is kept. Other errors abort it\n * too, as a 500. Database work through `trx` commits or rolls back with the write.\n */\nexport type BeforeHookContext = HookContextBase & {\n event: BeforeHookEvent;\n trx: Transaction<DB>;\n reject: (message: string, details?: Record<string, unknown>) => never;\n};\n\n/**\n * `after*` hooks run AFTER the write committed, as a job (retried with backoff on error, never rolling the\n * write back). Database work through `trx` is exactly once: it commits together with the record that the\n * hook ran. Other side effects (HTTP calls) are at least once: make them idempotent with `idempotencyKey`.\n */\nexport type AfterHookContext = HookContextBase & {\n event: AfterHookEvent;\n trx: Transaction<DB>;\n /** The outbox event the hook runs for. */\n eventId: string;\n /** `<eventId>:<hook name>`: stable across retries. */\n idempotencyKey: string;\n attempt: number;\n};\n\nexport type BeforeHook = (context: BeforeHookContext) => Promise<void> | void;\nexport type AfterHook = (context: AfterHookContext) => Promise<void> | void;\n\nexport type ModelHooks = { [E in BeforeHookEvent]?: BeforeHook } & { [E in AfterHookEvent]?: AfterHook };\n\nexport type ServiceFactoryContext = {\n /** Kysely on Shapio's database. Shapio's own tables are internal and may change between releases. */\n db: Kysely<DB>;\n config: ExtensionHostConfig;\n logger: FastifyBaseLogger;\n /** Shapio's services plus the custom services declared before this one. */\n services: ExtensionServices;\n};\n\nexport type ExtensionHostConfig = {\n nodeEnv: 'development' | 'production' | 'test';\n /** PUBLIC_URL origin, without a trailing slash. */\n publicUrl: string;\n basePath: string;\n /** The directory holding shapio.config and extensions/. */\n projectDir: string;\n};\n\nexport type ServiceFactory = (context: ServiceFactoryContext) => unknown;\n\n/** Options every custom route plugin receives (also available as `app.ext`). */\nexport type ExtensionRouteOptions = {\n services: ExtensionServices;\n /** Shapio's permission evaluator: `permissions.evaluate(request.principal, { action, modelId })`. */\n permissions: PermissionEvaluator;\n logger: FastifyBaseLogger;\n /** preHandler: 401/403 unless the caller is an admin user or an admin API token. */\n requireAdmin: preHandlerAsyncHookHandler;\n};\n\nexport type ExtensionRoute = {\n /** Mounted at `/api/ext/<prefix>` (under BASE_PATH). Lower-case letters, digits and dashes. */\n prefix: string;\n plugin: FastifyPluginAsync<ExtensionRouteOptions>;\n};\n\nexport type JobHandlerContext = {\n jobId: string;\n payload: Record<string, unknown>;\n attempt: number;\n maxAttempts: number;\n idempotencyKey: string | null;\n services: ExtensionServices;\n logger: FastifyBaseLogger;\n signal: AbortSignal;\n};\n\n/** Throw to retry with backoff; the return value (JSON) is stored as the job result. */\nexport type ExtensionJobHandler = (context: JobHandlerContext) => Promise<unknown>;\n\nexport type ShapioConfig = {\n /** Lifecycle hooks by model API ID (or stable model UUID); `*` runs for every model. */\n hooks?: Record<string, ModelHooks>;\n routes?: ExtensionRoute[];\n /** Constructed once at startup, in order, and shared by hooks, routes and jobs. */\n services?: Record<string, ServiceFactory>;\n /** Custom field editor modules: file names inside `extensions/editors/` (built ES modules). */\n editors?: string[];\n /** Job handlers by name; registered as `ext.<name>`. */\n jobs?: Record<string, ExtensionJobHandler>;\n};\n\n/** Identity helper for completion and type checking in `shapio.config.ts`. */\nexport const defineConfig = (config: ShapioConfig): ShapioConfig => config;\n\nconst HOOK_ERROR_BRAND = Symbol.for('shapio.HookError');\n\n/**\n * Thrown by a `before*` hook to reject a write: the API answers 422 with code `HOOK_REJECTED`, this message\n * and the details. Recognised by a brand, not `instanceof`, so a copy of this class loaded from another\n * path (a project's own `node_modules`) works the same.\n */\nexport class HookError extends Error {\n readonly details: Record<string, unknown> | undefined;\n readonly [HOOK_ERROR_BRAND] = true;\n\n constructor(message: string, details?: Record<string, unknown>) {\n super(message);\n this.name = 'HookError';\n this.details = details;\n }\n}\n\nexport const isHookError = (error: unknown): error is HookError =>\n typeof error === 'object' &&\n error !== null &&\n (error as Record<symbol, unknown>)[HOOK_ERROR_BRAND] === true;\n"],"mappings":";;;;;;;;;;;;;;;;AAyCA,MAAa,6BAA6B;;AAsO1C,MAAa,gBAAgB,WAAuC;AAEpE,MAAM,mBAAmB,OAAO,IAAI,kBAAkB;;;;;;AAOtD,IAAa,YAAb,cAA+B,MAAM;CACnC;CACA,CAAU,oBAAoB;CAE9B,YAAY,SAAiB,SAAmC;EAC9D,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,UAAU;CACjB;AACF;AAEA,MAAa,eAAe,UAC1B,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,sBAAsB"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../src/extensions/public.ts"],"sourcesContent":["import type { ThemeToken } from '@shapio/schema';\nimport type { FastifyBaseLogger, FastifyPluginAsync, preHandlerAsyncHookHandler } from 'fastify';\nimport type { Kysely, Transaction } from 'kysely';\nimport type { DB } from '../db/types.js';\nimport type { PermissionEvaluator, Principal } from '../permissions/types.js';\nimport type { RouteAuditConfig } from '../plugins/auditDeclaration.js';\n\n// What Shapio adds to Fastify, repeated here so custom route code is typed without the server's internals.\ndeclare module 'fastify' {\n interface FastifyRequest {\n /** Who is calling. Anonymous unless a session cookie or API token resolved. Never null after onRequest. */\n principal: Principal;\n /**\n * The request's site on a site route (custom routes are site routes): the credential's site, else the\n * `Shapio-Site` header or `?site=`, else the primary site. Undefined on a route declaring\n * `config.site = 'network'`.\n */\n site: { id: string; key: string } | undefined;\n }\n interface FastifyContextConfig {\n /** Required on every mutating route: the audit action recorded on success, or `{ exempt: '<why>' }`. */\n audit?: RouteAuditConfig;\n /** `'network'` for a custom route that is about the whole instance rather than one site. */\n site?: 'site' | 'network';\n }\n}\n\n/**\n * The project extension contract (ADR 0009), imported by project authors from `@shapio/cms/config`:\n *\n * ```ts\n * import { defineConfig } from '@shapio/cms/config';\n * export const config = defineConfig({ hooks: { article: { beforePublish: (ctx) => { ... } } } });\n * ```\n *\n * Extensions are code: changing them needs a restart of Shapio (never a rebuild). Content models are never\n * configured here; they change live in the admin. This file has no runtime imports from the server, so a\n * config that imports it stays cheap to load.\n *\n * Stability: everything exported here follows semver with `EXTENSION_CONTRACT_VERSION`; Shapio's database\n * tables (reachable through `trx`) are internal and may change in any release.\n */\nexport const EXTENSION_CONTRACT_VERSION = 1;\n\nexport type BeforeHookEvent = 'beforeCreate' | 'beforeUpdate' | 'beforePublish' | 'beforeDelete';\nexport type AfterHookEvent = 'afterCreate' | 'afterUpdate' | 'afterPublish' | 'afterDelete';\nexport type HookEvent = BeforeHookEvent | AfterHookEvent;\n\n/** A site of a multi-site instance: its stable ID and its key (sites share the schema, not content). */\nexport type ExtensionSite = { id: string; key: string };\n\n/** Entry data keyed by field API key (the admin API's shape; media and relations are IDs). */\nexport type EntryData = Readonly<Record<string, unknown>>;\n\nexport type HookModel = {\n /** Stable model ID (never changes). */\n id: string;\n apiKey: string;\n label: string;\n kind: 'collection' | 'singleton';\n localized: boolean;\n draftAndPublish: boolean;\n};\n\nexport type HookEntry = {\n id: string;\n locale: string | null;\n /** Which head the change is about: the draft (create/update), the live version (publish), or a delete. */\n state: 'draft' | 'published' | 'deleted';\n};\n\nexport type ContentReadOptions = {\n locale?: string;\n /** Read as this principal (its permissions apply). Default: Shapio itself (everything). */\n principal?: Principal;\n};\n\nexport type ContentReadEntry = {\n id: string;\n locale: string;\n status: string;\n data: Record<string, unknown>;\n};\n\n/** Read-only access to content (drafts, as the admin API shows them). Reads committed data. */\nexport type ContentReadService = {\n get: (modelKey: string, id: string, options?: ContentReadOptions) => Promise<ContentReadEntry>;\n /** `query` is a delivery-style querystring, e.g. `filters[title][$contains]=a&pageSize=10`. */\n list: (\n modelKey: string,\n query?: string,\n options?: Omit<ContentReadOptions, 'locale'>,\n ) => Promise<{ items: ContentReadEntry[]; total: number }>;\n /** Number of (non-deleted) entries of a model. */\n count: (modelKey: string) => Promise<number>;\n /** The active content models (collections and singletons) of this site: shared ones and its own. */\n models: () => Promise<HookModel[]>;\n};\n\nexport type MediaUsage = {\n entryId: string;\n modelId: string;\n fieldId: string;\n locale: string;\n state: string;\n};\n\nexport type MediaReferenceService = {\n /** Where an asset is used (up to 100 references, plus the total). */\n usages: (assetId: string) => Promise<{ items: MediaUsage[]; total: number }>;\n};\n\nexport type EnqueueOptions = {\n runAt?: Date;\n /** Enqueueing the same key twice creates one job. */\n idempotencyKey?: string;\n maxAttempts?: number;\n};\n\nexport type ExtensionJobService = {\n /** Enqueues one of the project's own jobs (`jobs` in the config), by its name without the `ext.` prefix. */\n enqueue: (\n name: string,\n payload?: Record<string, unknown>,\n options?: EnqueueOptions,\n ) => Promise<{ id: string; created: boolean }>;\n};\n\n/**\n * What Shapio offers extensions. Deliberately small; everything else goes through `trx` or HTTP.\n *\n * Content and media are per site. The services handed to a hook read the hook's site; the services given to\n * routes, jobs and service factories read the primary site. Use `forSite` for another one (in a custom\n * route: `services.forSite(request.site)`).\n */\nexport type ShapioServices = {\n /** The site `content` and `media` read. */\n site: ExtensionSite;\n /** The same services reading another site. */\n forSite: (site: ExtensionSite) => ShapioServices;\n content: ContentReadService;\n media: MediaReferenceService;\n jobs: ExtensionJobService;\n logger: FastifyBaseLogger;\n};\n\n/**\n * Your own services, by name. Augment it for typed access everywhere services appear:\n *\n * ```ts\n * declare module '@shapio/cms/config' {\n * interface CustomServices { stats: StatsService }\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type -- augmented by projects\nexport interface CustomServices {}\n\nexport type ExtensionServices = ShapioServices & CustomServices;\n\ntype HookContextBase = {\n /** The site the entry belongs to; `services` read this site. */\n site: ExtensionSite;\n model: HookModel;\n entry: HookEntry;\n locale: string | null;\n /** The document after the change (absent for deletes). */\n data: EntryData | undefined;\n /** The document before the change: the previous draft (update) or the live version (publish). */\n before: EntryData | undefined;\n /** Who made the change (an admin, an API token, an app user, or Shapio itself for scheduled work). */\n principal: Principal;\n services: ExtensionServices;\n logger: FastifyBaseLogger;\n /** Aborted when Shapio shuts down. */\n signal: AbortSignal;\n};\n\n/**\n * `before*` hooks run INSIDE the write's transaction, before it commits. Throw `HookError` (or call\n * `reject`) to abort the write with 422 `HOOK_REJECTED`; nothing of the write is kept. Other errors abort it\n * too, as a 500. Database work through `trx` commits or rolls back with the write.\n */\nexport type BeforeHookContext = HookContextBase & {\n event: BeforeHookEvent;\n trx: Transaction<DB>;\n reject: (message: string, details?: Record<string, unknown>) => never;\n};\n\n/**\n * `after*` hooks run AFTER the write committed, as a job (retried with backoff on error, never rolling the\n * write back). Database work through `trx` is exactly once: it commits together with the record that the\n * hook ran. Other side effects (HTTP calls) are at least once: make them idempotent with `idempotencyKey`.\n */\nexport type AfterHookContext = HookContextBase & {\n event: AfterHookEvent;\n trx: Transaction<DB>;\n /** The outbox event the hook runs for. */\n eventId: string;\n /** `<eventId>:<hook name>`: stable across retries. */\n idempotencyKey: string;\n attempt: number;\n};\n\nexport type BeforeHook = (context: BeforeHookContext) => Promise<void> | void;\nexport type AfterHook = (context: AfterHookContext) => Promise<void> | void;\n\nexport type ModelHooks = { [E in BeforeHookEvent]?: BeforeHook } & { [E in AfterHookEvent]?: AfterHook };\n\nexport type ServiceFactoryContext = {\n /** Kysely on Shapio's database. Shapio's own tables are internal and may change between releases. */\n db: Kysely<DB>;\n config: ExtensionHostConfig;\n logger: FastifyBaseLogger;\n /** Shapio's services plus the custom services declared before this one. */\n services: ExtensionServices;\n};\n\nexport type ExtensionHostConfig = {\n nodeEnv: 'development' | 'production' | 'test';\n /** PUBLIC_URL origin, without a trailing slash. */\n publicUrl: string;\n basePath: string;\n /** The directory holding shapio.config and extensions/. */\n projectDir: string;\n};\n\nexport type ServiceFactory = (context: ServiceFactoryContext) => unknown;\n\n/** Options every custom route plugin receives (also available as `app.ext`). */\nexport type ExtensionRouteOptions = {\n services: ExtensionServices;\n /** Shapio's permission evaluator: `permissions.evaluate(request.principal, { action, modelId })`. */\n permissions: PermissionEvaluator;\n logger: FastifyBaseLogger;\n /** preHandler: 401/403 unless the caller is an admin user or an admin API token. */\n requireAdmin: preHandlerAsyncHookHandler;\n};\n\nexport type ExtensionRoute = {\n /** Mounted at `/api/ext/<prefix>` (under BASE_PATH). Lower-case letters, digits and dashes. */\n prefix: string;\n plugin: FastifyPluginAsync<ExtensionRouteOptions>;\n};\n\nexport type JobHandlerContext = {\n jobId: string;\n payload: Record<string, unknown>;\n attempt: number;\n maxAttempts: number;\n idempotencyKey: string | null;\n services: ExtensionServices;\n logger: FastifyBaseLogger;\n signal: AbortSignal;\n};\n\n/** Throw to retry with backoff; the return value (JSON) is stored as the job result. */\nexport type ExtensionJobHandler = (context: JobHandlerContext) => Promise<unknown>;\n\n/**\n * A colour theme for the admin: token values for a light variant, a dark variant, or both. Every UI token is\n * required in a variant; the `brand-*` tokens may be left out (Shapio's are used). Values are `#rrggbb`\n * (contrast is checked by `shapio extensions check`), `#rgb`, `#rrggbbaa`, or `rgb()`, `hsl()`, `oklch()`,\n * `oklab()` with plain arguments.\n */\nexport type ThemeTokens = Partial<Record<ThemeToken, string>>;\n\nexport type ThemeDefinition = {\n /** Lower-case letters, digits and dashes; not a built-in theme's key. Saved in each browser's setting. */\n key: string;\n /** Shown in the theme menu (not translated). */\n name: string;\n description?: string;\n light?: ThemeTokens;\n dark?: ThemeTokens;\n};\n\nexport type ShapioConfig = {\n /** Lifecycle hooks by model API ID (or stable model UUID); `*` runs for every model. */\n hooks?: Record<string, ModelHooks>;\n routes?: ExtensionRoute[];\n /** Constructed once at startup, in order, and shared by hooks, routes and jobs. */\n services?: Record<string, ServiceFactory>;\n /** Custom field editor modules: file names inside `extensions/editors/` (built ES modules). */\n editors?: string[];\n /** Job handlers by name; registered as `ext.<name>`. */\n jobs?: Record<string, ExtensionJobHandler>;\n /** Admin colour themes, listed after the built-in ones in the theme menu. */\n themes?: ThemeDefinition[];\n};\n\n/** Identity helper for completion and type checking in `shapio.config.ts`. */\nexport const defineConfig = (config: ShapioConfig): ShapioConfig => config;\n\nconst HOOK_ERROR_BRAND = Symbol.for('shapio.HookError');\n\n/**\n * Thrown by a `before*` hook to reject a write: the API answers 422 with code `HOOK_REJECTED`, this message\n * and the details. Recognised by a brand, not `instanceof`, so a copy of this class loaded from another\n * path (a project's own `node_modules`) works the same.\n */\nexport class HookError extends Error {\n readonly details: Record<string, unknown> | undefined;\n readonly [HOOK_ERROR_BRAND] = true;\n\n constructor(message: string, details?: Record<string, unknown>) {\n super(message);\n this.name = 'HookError';\n this.details = details;\n }\n}\n\nexport const isHookError = (error: unknown): error is HookError =>\n typeof error === 'object' &&\n error !== null &&\n (error as Record<symbol, unknown>)[HOOK_ERROR_BRAND] === true;\n"],"mappings":";;;;;;;;;;;;;;;;AA0CA,MAAa,6BAA6B;;AA0P1C,MAAa,gBAAgB,WAAuC;AAEpE,MAAM,mBAAmB,OAAO,IAAI,kBAAkB;;;;;;AAOtD,IAAa,YAAb,cAA+B,MAAM;CACnC;CACA,CAAU,oBAAoB;CAE9B,YAAY,SAAiB,SAAmC;EAC9D,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,UAAU;CACjB;AACF;AAEA,MAAa,eAAe,UAC1B,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,sBAAsB"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as ServiceFactoryContext, C as HookEvent, D as MediaUsage, E as MediaReferenceService, F as PermissionEvaluator, I as Principal, L as DB, M as ShapioServices, N as defineConfig, O as ModelHooks, P as isHookError, R as OutboxEvents, S as HookError, T as JobHandlerContext, _ as ExtensionRoute, a as BeforeHookContext, b as ExtensionSite, c as ContentReadOptions, d as EXTENSION_CONTRACT_VERSION, f as EnqueueOptions, g as ExtensionJobService, h as ExtensionJobHandler, i as BeforeHook, j as ShapioConfig, k as ServiceFactory, l as ContentReadService, m as ExtensionHostConfig, n as AfterHookContext, o as BeforeHookEvent, p as EntryData, r as AfterHookEvent, s as ContentReadEntry, t as AfterHook, u as CustomServices, v as ExtensionRouteOptions, w as HookModel, x as HookEntry, y as ExtensionServices, z as ContentData } from "./public-CGO8RBn3.js";
1
+ import { A as ServiceFactoryContext, B as Database, C as HookEvent, D as MediaUsage, E as MediaReferenceService, F as defineConfig, G as DataType, H as OutboxEvents, I as isHookError, J as SchemaChange, K as JsonValue, L as PermissionEvaluator, M as ShapioServices, N as ThemeDefinition, O as ModelHooks, P as ThemeTokens, R as PermissionExecutor, S as HookError, T as JobHandlerContext, U as ContentData, V as DB, W as ComponentDefinition, _ as ExtensionRoute, a as BeforeHookContext, b as ExtensionSite, c as ContentReadOptions, d as EXTENSION_CONTRACT_VERSION, f as EnqueueOptions, g as ExtensionJobService, h as ExtensionJobHandler, i as BeforeHook, j as ShapioConfig, k as ServiceFactory, l as ContentReadService, m as ExtensionHostConfig, n as AfterHookContext, o as BeforeHookEvent, p as EntryData, q as ModelDefinition, r as AfterHookEvent, s as ContentReadEntry, t as AfterHook, u as CustomServices, v as ExtensionRouteOptions, w as HookModel, x as HookEntry, y as ExtensionServices, z as Principal } from "./public-B7fFHMNr.js";
2
2
  import { FastifyBaseLogger, FastifyInstance } from "fastify";
3
3
  import { Kysely, Selectable, Transaction } from "kysely";
4
4
  import { Static, Type } from "typebox";
@@ -35,6 +35,11 @@ declare const configSchema: Type.TObject<{
35
35
  HTTP_PORT: Type.TOptional<Type.TInteger>;
36
36
  DATABASE_URL: Type.TString;
37
37
  DATABASE_POOL_MAX: Type.TInteger;
38
+ /**
39
+ * How long a request waits for a free pooled connection (PostgreSQL and MySQL) before it fails with
40
+ * 503 `DATABASE_BUSY` and a logged error, instead of queueing forever. SQLite never waits for one.
41
+ */
42
+ DATABASE_POOL_ACQUIRE_TIMEOUT_MS: Type.TInteger;
38
43
  MIGRATE_ON_START: Type.TBoolean;
39
44
  /**
40
45
  * LISTEN for schema-change notifications to refresh caches early. Turn off where LISTEN does not work
@@ -343,6 +348,7 @@ type AppConfig = {
343
348
  database: {
344
349
  url: string;
345
350
  poolMax: number;
351
+ acquireTimeoutMs: number;
346
352
  migrateOnStart: boolean;
347
353
  };
348
354
  /** `listen`: use LISTEN/NOTIFY to refresh schema caches early (correctness never depends on it). */
@@ -420,222 +426,6 @@ type SiteRef = {
420
426
  key: string;
421
427
  };
422
428
  //#endregion
423
- //#region ../../packages/schema/dist/index.d.ts
424
- //#endregion
425
- //#region src/types/dataTypes.d.ts
426
- /** Every stored data type. A field's data type is separate from the editor that renders it (brief §2.5). */
427
- declare const DATA_TYPES: readonly ["string", "text", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"];
428
- type DataType = (typeof DATA_TYPES)[number];
429
- //#endregion
430
- //#region src/types/json.d.ts
431
- type JsonPrimitive = string | number | boolean | null;
432
- type JsonValue = JsonPrimitive | JsonValue[] | {
433
- [key: string]: JsonValue;
434
- };
435
- declare const SETTINGS_SCHEMAS: {
436
- string: Type.TObject<{
437
- pattern: Type.TOptional<Type.TString>;
438
- minLength: Type.TOptional<Type.TInteger>;
439
- maxLength: Type.TOptional<Type.TInteger>;
440
- }>;
441
- text: Type.TObject<{
442
- minLength: Type.TOptional<Type.TInteger>;
443
- maxLength: Type.TOptional<Type.TInteger>;
444
- }>;
445
- richtext: Type.TObject<{
446
- formatVersion: Type.TOptional<Type.TInteger>;
447
- maxLength: Type.TOptional<Type.TInteger>;
448
- }>;
449
- number: Type.TObject<{
450
- min: Type.TOptional<Type.TNumber>;
451
- max: Type.TOptional<Type.TNumber>;
452
- }>;
453
- integer: Type.TObject<{
454
- min: Type.TOptional<Type.TInteger>;
455
- max: Type.TOptional<Type.TInteger>;
456
- }>;
457
- decimal: Type.TObject<{
458
- precision: Type.TOptional<Type.TInteger>;
459
- scale: Type.TOptional<Type.TInteger>;
460
- min: Type.TOptional<Type.TString>;
461
- max: Type.TOptional<Type.TString>;
462
- }>;
463
- biginteger: Type.TObject<{
464
- min: Type.TOptional<Type.TString>;
465
- max: Type.TOptional<Type.TString>;
466
- }>;
467
- boolean: Type.TObject<{}>;
468
- date: Type.TObject<{
469
- min: Type.TOptional<Type.TString>;
470
- max: Type.TOptional<Type.TString>;
471
- }>;
472
- datetime: Type.TObject<{
473
- min: Type.TOptional<Type.TString>;
474
- max: Type.TOptional<Type.TString>;
475
- }>;
476
- time: Type.TObject<{
477
- min: Type.TOptional<Type.TString>;
478
- max: Type.TOptional<Type.TString>;
479
- }>;
480
- enum: Type.TObject<{
481
- values: Type.TArray<Type.TObject<{
482
- value: Type.TString;
483
- label: Type.TString;
484
- }>>;
485
- multiple: Type.TOptional<Type.TBoolean>;
486
- }>;
487
- json: Type.TObject<{}>;
488
- slug: Type.TObject<{
489
- sourceFieldId: Type.TOptional<Type.TString>;
490
- minLength: Type.TOptional<Type.TInteger>;
491
- maxLength: Type.TOptional<Type.TInteger>;
492
- }>;
493
- email: Type.TObject<{}>;
494
- url: Type.TObject<{
495
- protocols: Type.TOptional<Type.TArray<Type.TEnum<["http", "https", "mailto", "tel"]>>>;
496
- }>;
497
- uid: Type.TObject<{
498
- minLength: Type.TOptional<Type.TInteger>;
499
- maxLength: Type.TOptional<Type.TInteger>;
500
- }>;
501
- media: Type.TObject<{
502
- min: Type.TOptional<Type.TInteger>;
503
- max: Type.TOptional<Type.TInteger>;
504
- multiple: Type.TOptional<Type.TBoolean>;
505
- allowedKinds: Type.TOptional<Type.TArray<Type.TEnum<["image", "video", "audio", "document", "other"]>>>;
506
- }>;
507
- relation: Type.TObject<{
508
- min: Type.TOptional<Type.TInteger>;
509
- max: Type.TOptional<Type.TInteger>;
510
- target: Type.TString;
511
- cardinality: Type.TEnum<["one", "many"]>;
512
- }>;
513
- component: Type.TObject<{
514
- min: Type.TOptional<Type.TInteger>;
515
- max: Type.TOptional<Type.TInteger>;
516
- component: Type.TString;
517
- repeatable: Type.TOptional<Type.TBoolean>;
518
- }>;
519
- dynamiczone: Type.TObject<{
520
- min: Type.TOptional<Type.TInteger>;
521
- max: Type.TOptional<Type.TInteger>;
522
- components: Type.TArray<Type.TString>;
523
- }>;
524
- };
525
- type SettingsSchemas = typeof SETTINGS_SCHEMAS;
526
- /** Settings as authored (defaults may be missing). */
527
- type DataTypeSettingsInput = { [T in DataType]: Static<SettingsSchemas[T]>; };
528
- /** Settings after normalization: the defaulted keys are always present. */
529
- type DataTypeSettings = Omit<DataTypeSettingsInput, 'richtext' | 'enum' | 'media' | 'component'> & {
530
- richtext: DataTypeSettingsInput['richtext'] & {
531
- formatVersion: number;
532
- };
533
- enum: DataTypeSettingsInput['enum'] & {
534
- multiple: boolean;
535
- };
536
- media: DataTypeSettingsInput['media'] & {
537
- multiple: boolean;
538
- };
539
- component: DataTypeSettingsInput['component'] & {
540
- repeatable: boolean;
541
- };
542
- };
543
- //#endregion
544
- //#region src/types/definitions.d.ts
545
- declare const MODEL_KINDS: readonly ["collection", "singleton"];
546
- type ModelKind = (typeof MODEL_KINDS)[number];
547
- declare const SORT_DIRECTIONS: readonly ["asc", "desc"];
548
- type SortDirection = (typeof SORT_DIRECTIONS)[number];
549
- type EditorChoice = {
550
- id: string;
551
- options: Record<string, JsonValue>;
552
- };
553
- type FieldBase = {
554
- id: string;
555
- apiKey: string;
556
- label: string;
557
- description?: string;
558
- required: boolean;
559
- localized: boolean;
560
- public: boolean;
561
- unique: boolean;
562
- filterable: boolean;
563
- sortable: boolean;
564
- deprecated: boolean;
565
- defaultValue?: JsonValue;
566
- editor: EditorChoice;
567
- };
568
- /** A normalized field. Narrow on `type` to get typed `settings`. */
569
- type FieldDefinition<T extends DataType = DataType> = { [K in T]: FieldBase & {
570
- type: K;
571
- settings: DataTypeSettings[K];
572
- }; }[T];
573
- type FieldGroup = {
574
- id: string;
575
- label: string;
576
- fieldIds: string[];
577
- };
578
- type ModelDisplay = {
579
- titleFieldId?: string;
580
- listFieldIds?: string[];
581
- defaultSort?: {
582
- fieldId: string;
583
- direction: SortDirection;
584
- };
585
- groups?: FieldGroup[];
586
- canvasFieldIds?: string[];
587
- coverFieldId?: string;
588
- stripFieldIds?: string[];
589
- };
590
- type ComponentDisplay = {
591
- titleFieldId?: string;
592
- groups?: FieldGroup[];
593
- };
594
- type ModelDefinition = {
595
- id: string;
596
- kind: ModelKind;
597
- apiKey: string;
598
- /**
599
- * Present on collections (filled by normalizing), absent on singletons. Read it through `routeKeyOf`,
600
- * which also covers a stored definition that predates plural API IDs.
601
- */
602
- pluralApiKey?: string;
603
- label: string;
604
- description?: string;
605
- localized: boolean;
606
- draftAndPublish: boolean;
607
- fields: FieldDefinition[];
608
- display: ModelDisplay;
609
- };
610
- type ComponentDefinition = {
611
- id: string;
612
- kind: 'component';
613
- apiKey: string;
614
- label: string;
615
- description?: string;
616
- category?: string;
617
- icon?: string;
618
- fields: FieldDefinition[];
619
- display: ComponentDisplay;
620
- };
621
- //#endregion
622
- //#region src/diff/types.d.ts
623
- declare const CHANGE_KINDS: readonly ["definition.added", "definition.removed", "definition.apiKey", "definition.pluralApiKey", "definition.metadata", "model.kind", "model.localized", "model.draftAndPublish", "field.added", "field.removed", "field.order", "field.apiKey", "field.metadata", "field.editor", "field.type", "field.required", "field.localized", "field.public", "field.deprecated", "field.unique", "field.filterable", "field.sortable", "field.settings"];
624
- type ChangeKind = (typeof CHANGE_KINDS)[number];
625
- /**
626
- * One difference between two versions of a definition. `property` names the changed property for
627
- * `*.metadata` (`label`, `description`, ...) and `field.settings` (the settings key); `from`/`to` hold the
628
- * old and new values (absent when the side does not exist).
629
- */
630
- type SchemaChange = {
631
- kind: ChangeKind;
632
- definitionId: string;
633
- fieldId?: string;
634
- property?: string;
635
- from?: JsonValue;
636
- to?: JsonValue;
637
- };
638
- //#endregion
639
429
  //#region src/content/model.d.ts
640
430
  /** A collection or singleton resolved from a pinned snapshot, with what writes need to know about it. */
641
431
  type ContentModel = {
@@ -682,9 +472,6 @@ type ContentHooks = {
682
472
  run: (event: LifecycleEvent, context: LifecycleContext) => Promise<void>;
683
473
  };
684
474
  //#endregion
685
- //#region src/db/index.d.ts
686
- type Database = Kysely<DB>;
687
- //#endregion
688
475
  //#region src/extensions/editorManifest.d.ts
689
476
  /**
690
477
  * The custom field editors a project installs (ADR 0009): built ES modules in `extensions/editors/*.js`,
@@ -778,13 +565,13 @@ type ModelField = {
778
565
  * only name real models.
779
566
  */
780
567
  type FieldVisibilityLookup = {
781
- getModelFields: (modelId: string) => Promise<readonly ModelField[] | undefined>;
782
- hasModel: (modelId: string) => Promise<boolean>;
568
+ getModelFields: (modelId: string, executor?: PermissionExecutor) => Promise<readonly ModelField[] | undefined>;
569
+ hasModel: (modelId: string, executor?: PermissionExecutor) => Promise<boolean>;
783
570
  /**
784
571
  * The site a definition belongs to: null when it is shared (or unknown). Schema management of a site's
785
572
  * definition is granted by roles held on that site (plan site-schema, rule 4).
786
573
  */
787
- getModelSite: (modelId: string) => Promise<string | null>;
574
+ getModelSite: (modelId: string, executor?: PermissionExecutor) => Promise<string | null>;
788
575
  };
789
576
  //#endregion
790
577
  //#region src/publishing/outbound/ssrf.d.ts
@@ -1052,5 +839,5 @@ export declare const startDedicatedWorker: (config: AppConfig) => Promise<Worker
1052
839
  //#region src/constants/version.d.ts
1053
840
  export declare const SHAPIO_VERSION: string;
1054
841
  //#endregion
1055
- export { AfterHook, AfterHookContext, AfterHookEvent, type AppConfig, type AppDependencies, BeforeHook, BeforeHookContext, BeforeHookEvent, ContentReadEntry, ContentReadOptions, ContentReadService, CustomServices, EXTENSION_CONTRACT_VERSION, EnqueueOptions, EntryData, ExtensionHostConfig, ExtensionJobHandler, ExtensionJobService, ExtensionRoute, ExtensionRouteOptions, ExtensionServices, ExtensionSite, HookEntry, HookError, HookEvent, HookModel, JobHandlerContext, MediaReferenceService, MediaUsage, ModelHooks, type RunningServer, ServiceFactory, ServiceFactoryContext, ShapioConfig, ShapioServices, defineConfig, isHookError };
842
+ export { AfterHook, AfterHookContext, AfterHookEvent, type AppConfig, type AppDependencies, BeforeHook, BeforeHookContext, BeforeHookEvent, ContentReadEntry, ContentReadOptions, ContentReadService, CustomServices, EXTENSION_CONTRACT_VERSION, EnqueueOptions, EntryData, ExtensionHostConfig, ExtensionJobHandler, ExtensionJobService, ExtensionRoute, ExtensionRouteOptions, ExtensionServices, ExtensionSite, HookEntry, HookError, HookEvent, HookModel, JobHandlerContext, MediaReferenceService, MediaUsage, ModelHooks, type RunningServer, ServiceFactory, ServiceFactoryContext, ShapioConfig, ShapioServices, ThemeDefinition, ThemeTokens, defineConfig, isHookError };
1056
843
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as loadConfig, n as startServer, s as buildApp, t as startDedicatedWorker, u as SHAPIO_VERSION } from "./worker-BLXy8aRW.js";
1
+ import { a as loadConfig, n as startServer, s as buildApp, t as startDedicatedWorker, u as SHAPIO_VERSION } from "./worker-BAmQPoTJ.js";
2
2
  import { EXTENSION_CONTRACT_VERSION, HookError, defineConfig, isHookError } from "./config.js";
3
3
  export { EXTENSION_CONTRACT_VERSION, HookError, SHAPIO_VERSION, buildApp, defineConfig, isHookError, loadConfig, startDedicatedWorker, startServer };
@@ -1,5 +1,224 @@
1
1
  import { FastifyBaseLogger, FastifyInstance, FastifyPluginAsync, preHandlerAsyncHookHandler } from "fastify";
2
2
  import { ColumnType, Kysely, Transaction } from "kysely";
3
+ import { Static, Type } from "typebox";
4
+ //#region ../../packages/schema/dist/index.d.ts
5
+ //#endregion
6
+ //#region src/types/dataTypes.d.ts
7
+ /** Every stored data type. A field's data type is separate from the editor that renders it (brief §2.5). */
8
+ declare const DATA_TYPES: readonly ["string", "text", "richtext", "number", "integer", "decimal", "biginteger", "boolean", "date", "datetime", "time", "enum", "json", "slug", "email", "url", "uid", "media", "relation", "component", "dynamiczone"];
9
+ type DataType = (typeof DATA_TYPES)[number];
10
+ //#endregion
11
+ //#region src/types/json.d.ts
12
+ type JsonPrimitive$1 = string | number | boolean | null;
13
+ type JsonValue$1 = JsonPrimitive$1 | JsonValue$1[] | {
14
+ [key: string]: JsonValue$1;
15
+ };
16
+ declare const SETTINGS_SCHEMAS: {
17
+ string: Type.TObject<{
18
+ pattern: Type.TOptional<Type.TString>;
19
+ minLength: Type.TOptional<Type.TInteger>;
20
+ maxLength: Type.TOptional<Type.TInteger>;
21
+ }>;
22
+ text: Type.TObject<{
23
+ minLength: Type.TOptional<Type.TInteger>;
24
+ maxLength: Type.TOptional<Type.TInteger>;
25
+ }>;
26
+ richtext: Type.TObject<{
27
+ formatVersion: Type.TOptional<Type.TInteger>;
28
+ maxLength: Type.TOptional<Type.TInteger>;
29
+ }>;
30
+ number: Type.TObject<{
31
+ min: Type.TOptional<Type.TNumber>;
32
+ max: Type.TOptional<Type.TNumber>;
33
+ }>;
34
+ integer: Type.TObject<{
35
+ min: Type.TOptional<Type.TInteger>;
36
+ max: Type.TOptional<Type.TInteger>;
37
+ }>;
38
+ decimal: Type.TObject<{
39
+ precision: Type.TOptional<Type.TInteger>;
40
+ scale: Type.TOptional<Type.TInteger>;
41
+ min: Type.TOptional<Type.TString>;
42
+ max: Type.TOptional<Type.TString>;
43
+ }>;
44
+ biginteger: Type.TObject<{
45
+ min: Type.TOptional<Type.TString>;
46
+ max: Type.TOptional<Type.TString>;
47
+ }>;
48
+ boolean: Type.TObject<{}>;
49
+ date: Type.TObject<{
50
+ min: Type.TOptional<Type.TString>;
51
+ max: Type.TOptional<Type.TString>;
52
+ }>;
53
+ datetime: Type.TObject<{
54
+ min: Type.TOptional<Type.TString>;
55
+ max: Type.TOptional<Type.TString>;
56
+ }>;
57
+ time: Type.TObject<{
58
+ min: Type.TOptional<Type.TString>;
59
+ max: Type.TOptional<Type.TString>;
60
+ }>;
61
+ enum: Type.TObject<{
62
+ values: Type.TArray<Type.TObject<{
63
+ value: Type.TString;
64
+ label: Type.TString;
65
+ }>>;
66
+ multiple: Type.TOptional<Type.TBoolean>;
67
+ }>;
68
+ json: Type.TObject<{}>;
69
+ slug: Type.TObject<{
70
+ sourceFieldId: Type.TOptional<Type.TString>;
71
+ minLength: Type.TOptional<Type.TInteger>;
72
+ maxLength: Type.TOptional<Type.TInteger>;
73
+ }>;
74
+ email: Type.TObject<{}>;
75
+ url: Type.TObject<{
76
+ protocols: Type.TOptional<Type.TArray<Type.TEnum<["http", "https", "mailto", "tel"]>>>;
77
+ }>;
78
+ uid: Type.TObject<{
79
+ minLength: Type.TOptional<Type.TInteger>;
80
+ maxLength: Type.TOptional<Type.TInteger>;
81
+ }>;
82
+ media: Type.TObject<{
83
+ min: Type.TOptional<Type.TInteger>;
84
+ max: Type.TOptional<Type.TInteger>;
85
+ multiple: Type.TOptional<Type.TBoolean>;
86
+ allowedKinds: Type.TOptional<Type.TArray<Type.TEnum<["image", "video", "audio", "document", "other"]>>>;
87
+ }>;
88
+ relation: Type.TObject<{
89
+ min: Type.TOptional<Type.TInteger>;
90
+ max: Type.TOptional<Type.TInteger>;
91
+ target: Type.TString;
92
+ cardinality: Type.TEnum<["one", "many"]>;
93
+ }>;
94
+ component: Type.TObject<{
95
+ min: Type.TOptional<Type.TInteger>;
96
+ max: Type.TOptional<Type.TInteger>;
97
+ component: Type.TString;
98
+ repeatable: Type.TOptional<Type.TBoolean>;
99
+ }>;
100
+ dynamiczone: Type.TObject<{
101
+ min: Type.TOptional<Type.TInteger>;
102
+ max: Type.TOptional<Type.TInteger>;
103
+ components: Type.TArray<Type.TString>;
104
+ }>;
105
+ };
106
+ type SettingsSchemas = typeof SETTINGS_SCHEMAS;
107
+ /** Settings as authored (defaults may be missing). */
108
+ type DataTypeSettingsInput = { [T in DataType]: Static<SettingsSchemas[T]>; };
109
+ /** Settings after normalization: the defaulted keys are always present. */
110
+ type DataTypeSettings = Omit<DataTypeSettingsInput, 'richtext' | 'enum' | 'media' | 'component'> & {
111
+ richtext: DataTypeSettingsInput['richtext'] & {
112
+ formatVersion: number;
113
+ };
114
+ enum: DataTypeSettingsInput['enum'] & {
115
+ multiple: boolean;
116
+ };
117
+ media: DataTypeSettingsInput['media'] & {
118
+ multiple: boolean;
119
+ };
120
+ component: DataTypeSettingsInput['component'] & {
121
+ repeatable: boolean;
122
+ };
123
+ };
124
+ //#endregion
125
+ //#region src/types/definitions.d.ts
126
+ declare const MODEL_KINDS: readonly ["collection", "singleton"];
127
+ type ModelKind = (typeof MODEL_KINDS)[number];
128
+ declare const SORT_DIRECTIONS: readonly ["asc", "desc"];
129
+ type SortDirection = (typeof SORT_DIRECTIONS)[number];
130
+ type EditorChoice = {
131
+ id: string;
132
+ options: Record<string, JsonValue$1>;
133
+ };
134
+ type FieldBase = {
135
+ id: string;
136
+ apiKey: string;
137
+ label: string;
138
+ description?: string;
139
+ required: boolean;
140
+ localized: boolean;
141
+ public: boolean;
142
+ unique: boolean;
143
+ filterable: boolean;
144
+ sortable: boolean;
145
+ deprecated: boolean;
146
+ defaultValue?: JsonValue$1;
147
+ editor: EditorChoice;
148
+ };
149
+ /** A normalized field. Narrow on `type` to get typed `settings`. */
150
+ type FieldDefinition<T extends DataType = DataType> = { [K in T]: FieldBase & {
151
+ type: K;
152
+ settings: DataTypeSettings[K];
153
+ }; }[T];
154
+ type FieldGroup = {
155
+ id: string;
156
+ label: string;
157
+ fieldIds: string[];
158
+ };
159
+ type ModelDisplay = {
160
+ titleFieldId?: string;
161
+ listFieldIds?: string[];
162
+ defaultSort?: {
163
+ fieldId: string;
164
+ direction: SortDirection;
165
+ };
166
+ groups?: FieldGroup[];
167
+ canvasFieldIds?: string[];
168
+ coverFieldId?: string;
169
+ stripFieldIds?: string[];
170
+ };
171
+ type ComponentDisplay = {
172
+ titleFieldId?: string;
173
+ groups?: FieldGroup[];
174
+ };
175
+ type ModelDefinition = {
176
+ id: string;
177
+ kind: ModelKind;
178
+ apiKey: string;
179
+ /**
180
+ * Present on collections (filled by normalizing), absent on singletons. Read it through `routeKeyOf`,
181
+ * which also covers a stored definition that predates plural API IDs.
182
+ */
183
+ pluralApiKey?: string;
184
+ label: string;
185
+ description?: string;
186
+ localized: boolean;
187
+ draftAndPublish: boolean;
188
+ fields: FieldDefinition[];
189
+ display: ModelDisplay;
190
+ };
191
+ type ComponentDefinition = {
192
+ id: string;
193
+ kind: 'component';
194
+ apiKey: string;
195
+ label: string;
196
+ description?: string;
197
+ category?: string;
198
+ icon?: string;
199
+ fields: FieldDefinition[];
200
+ display: ComponentDisplay;
201
+ };
202
+ //#endregion
203
+ //#region src/diff/types.d.ts
204
+ declare const CHANGE_KINDS: readonly ["definition.added", "definition.removed", "definition.apiKey", "definition.pluralApiKey", "definition.metadata", "model.kind", "model.localized", "model.draftAndPublish", "field.added", "field.removed", "field.order", "field.apiKey", "field.metadata", "field.editor", "field.type", "field.required", "field.localized", "field.public", "field.deprecated", "field.unique", "field.filterable", "field.sortable", "field.settings"];
205
+ type ChangeKind = (typeof CHANGE_KINDS)[number];
206
+ /**
207
+ * One difference between two versions of a definition. `property` names the changed property for
208
+ * `*.metadata` (`label`, `description`, ...) and `field.settings` (the settings key); `from`/`to` hold the
209
+ * old and new values (absent when the side does not exist).
210
+ */
211
+ type SchemaChange = {
212
+ kind: ChangeKind;
213
+ definitionId: string;
214
+ fieldId?: string;
215
+ property?: string;
216
+ from?: JsonValue$1;
217
+ to?: JsonValue$1;
218
+ };
219
+ declare const THEME_TOKENS: readonly ["background", "foreground", "card", "card-foreground", "popover", "popover-foreground", "primary", "primary-foreground", "primary-hover", "secondary", "secondary-foreground", "muted", "muted-foreground", "accent", "accent-foreground", "destructive", "destructive-foreground", "destructive-muted", "success", "success-muted", "warning", "warning-muted", "info", "info-muted", "border", "input", "ring", "link", "overlay", "sidebar", "sidebar-foreground", "sidebar-primary", "sidebar-primary-foreground", "sidebar-accent", "sidebar-accent-foreground", "sidebar-border", "sidebar-ring", "brand-logo", "brand-logo-foreground", "brand-letters", "brand-panel-from", "brand-panel-to", "brand-panel-foreground", "brand-panel-mark"];
220
+ type ThemeToken = (typeof THEME_TOKENS)[number];
221
+ //#endregion
3
222
  //#region src/db/contentData.d.ts
4
223
  /**
5
224
  * User content values: JSONB keyed by stable field IDs. The shape is only known at runtime from the active
@@ -799,6 +1018,9 @@ interface DB {
799
1018
  webhooks: Webhooks;
800
1019
  }
801
1020
  //#endregion
1021
+ //#region src/db/index.d.ts
1022
+ type Database = Kysely<DB>;
1023
+ //#endregion
802
1024
  //#region src/permissions/types.d.ts
803
1025
  /**
804
1026
  * Principals and policies (ADR 0005). One evaluator serves admin users, app users, tokens and anonymous
@@ -898,15 +1120,21 @@ type PolicyRequest = {
898
1120
  action: ContentAction;
899
1121
  modelId: string;
900
1122
  };
1123
+ /**
1124
+ * Where a permission lookup reads its durable version checks (and any reload): the open transaction when
1125
+ * the caller is inside one, so the lookup never waits for a second pooled connection while it holds one
1126
+ * (an exhausted pool would then wait forever). Omitted: the pool.
1127
+ */
1128
+ type PermissionExecutor = Database;
901
1129
  type PermissionEvaluator = {
902
- evaluate: (principal: Principal, request: PolicyRequest) => Promise<Policy>;
903
- canPerform: (principal: Principal, action: GlobalAction) => Promise<boolean>;
1130
+ evaluate: (principal: Principal, request: PolicyRequest, executor?: PermissionExecutor) => Promise<Policy>;
1131
+ canPerform: (principal: Principal, action: GlobalAction, executor?: PermissionExecutor) => Promise<boolean>;
904
1132
  /**
905
1133
  * `canPerform` for the request's site: an action in `SITE_GRANTABLE_ACTIONS` also counts the roles that
906
1134
  * apply on `siteId` when the principal acts on that site (an admin narrowed to it, a site token of it, a
907
1135
  * network token). Any other action is `canPerform`.
908
1136
  */
909
- canPerformOnSite: (principal: Principal, action: GlobalAction, siteId: string) => Promise<boolean>;
1137
+ canPerformOnSite: (principal: Principal, action: GlobalAction, siteId: string, executor?: PermissionExecutor) => Promise<boolean>;
910
1138
  };
911
1139
  //#endregion
912
1140
  //#region src/plugins/auditDeclaration.d.ts
@@ -1155,6 +1383,22 @@ type JobHandlerContext = {
1155
1383
  };
1156
1384
  /** Throw to retry with backoff; the return value (JSON) is stored as the job result. */
1157
1385
  type ExtensionJobHandler = (context: JobHandlerContext) => Promise<unknown>;
1386
+ /**
1387
+ * A colour theme for the admin: token values for a light variant, a dark variant, or both. Every UI token is
1388
+ * required in a variant; the `brand-*` tokens may be left out (Shapio's are used). Values are `#rrggbb`
1389
+ * (contrast is checked by `shapio extensions check`), `#rgb`, `#rrggbbaa`, or `rgb()`, `hsl()`, `oklch()`,
1390
+ * `oklab()` with plain arguments.
1391
+ */
1392
+ type ThemeTokens = Partial<Record<ThemeToken, string>>;
1393
+ type ThemeDefinition = {
1394
+ /** Lower-case letters, digits and dashes; not a built-in theme's key. Saved in each browser's setting. */
1395
+ key: string;
1396
+ /** Shown in the theme menu (not translated). */
1397
+ name: string;
1398
+ description?: string;
1399
+ light?: ThemeTokens;
1400
+ dark?: ThemeTokens;
1401
+ };
1158
1402
  type ShapioConfig = {
1159
1403
  /** Lifecycle hooks by model API ID (or stable model UUID); `*` runs for every model. */
1160
1404
  hooks?: Record<string, ModelHooks>;
@@ -1165,6 +1409,8 @@ type ShapioConfig = {
1165
1409
  editors?: string[];
1166
1410
  /** Job handlers by name; registered as `ext.<name>`. */
1167
1411
  jobs?: Record<string, ExtensionJobHandler>;
1412
+ /** Admin colour themes, listed after the built-in ones in the theme menu. */
1413
+ themes?: ThemeDefinition[];
1168
1414
  };
1169
1415
  /** Identity helper for completion and type checking in `shapio.config.ts`. */
1170
1416
  declare const defineConfig: (config: ShapioConfig) => ShapioConfig;
@@ -1181,5 +1427,5 @@ declare class HookError extends Error {
1181
1427
  }
1182
1428
  declare const isHookError: (error: unknown) => error is HookError;
1183
1429
  //#endregion
1184
- export { ServiceFactoryContext as A, HookEvent as C, MediaUsage as D, MediaReferenceService as E, PermissionEvaluator as F, Principal as I, DB as L, ShapioServices as M, defineConfig as N, ModelHooks as O, isHookError as P, OutboxEvents as R, HookError as S, JobHandlerContext as T, ExtensionRoute as _, BeforeHookContext as a, ExtensionSite as b, ContentReadOptions as c, EXTENSION_CONTRACT_VERSION as d, EnqueueOptions as f, ExtensionJobService as g, ExtensionJobHandler as h, BeforeHook as i, ShapioConfig as j, ServiceFactory as k, ContentReadService as l, ExtensionHostConfig as m, AfterHookContext as n, BeforeHookEvent as o, EntryData as p, AfterHookEvent as r, ContentReadEntry as s, AfterHook as t, CustomServices as u, ExtensionRouteOptions as v, HookModel as w, HookEntry as x, ExtensionServices as y, ContentData as z };
1185
- //# sourceMappingURL=public-CGO8RBn3.d.ts.map
1430
+ export { ServiceFactoryContext as A, Database as B, HookEvent as C, MediaUsage as D, MediaReferenceService as E, defineConfig as F, DataType as G, OutboxEvents as H, isHookError as I, SchemaChange as J, JsonValue$1 as K, PermissionEvaluator as L, ShapioServices as M, ThemeDefinition as N, ModelHooks as O, ThemeTokens as P, PermissionExecutor as R, HookError as S, JobHandlerContext as T, ContentData as U, DB as V, ComponentDefinition as W, ExtensionRoute as _, BeforeHookContext as a, ExtensionSite as b, ContentReadOptions as c, EXTENSION_CONTRACT_VERSION as d, EnqueueOptions as f, ExtensionJobService as g, ExtensionJobHandler as h, BeforeHook as i, ShapioConfig as j, ServiceFactory as k, ContentReadService as l, ExtensionHostConfig as m, AfterHookContext as n, BeforeHookEvent as o, EntryData as p, ModelDefinition as q, AfterHookEvent as r, ContentReadEntry as s, AfterHook as t, CustomServices as u, ExtensionRouteOptions as v, HookModel as w, HookEntry as x, ExtensionServices as y, Principal as z };
1431
+ //# sourceMappingURL=public-B7fFHMNr.d.ts.map