@shapio/cms 0.5.9 → 0.5.10

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 (192) hide show
  1. package/dist/admin/assets/{AssetTile-Da76KsyX.js → AssetTile-DecaDqjj.js} +2 -2
  2. package/dist/admin/assets/{AssetTile-Da76KsyX.js.map → AssetTile-DecaDqjj.js.map} +1 -1
  3. package/dist/admin/assets/{AssistError-Wr62cDj3.js → AssistError-rslPtgWB.js} +2 -2
  4. package/dist/admin/assets/{AssistError-Wr62cDj3.js.map → AssistError-rslPtgWB.js.map} +1 -1
  5. package/dist/admin/assets/{BlockMenuItems-BMiEVCIT.js → BlockMenuItems-JHFue7Qt.js} +2 -2
  6. package/dist/admin/assets/{BlockMenuItems-BMiEVCIT.js.map → BlockMenuItems-JHFue7Qt.js.map} +1 -1
  7. package/dist/admin/assets/{Body-BEW1sAAB.js → Body-7NgJl9Pi.js} +2 -2
  8. package/dist/admin/assets/Body-7NgJl9Pi.js.map +1 -0
  9. package/dist/admin/assets/Builder-DmlYcgiP.js +2 -0
  10. package/dist/admin/assets/Builder-DmlYcgiP.js.map +1 -0
  11. package/dist/admin/assets/{CodeEditor-Ck7ggv6w.js → CodeEditor-Dv1FtkvI.js} +2 -2
  12. package/dist/admin/assets/{CodeEditor-Ck7ggv6w.js.map → CodeEditor-Dv1FtkvI.js.map} +1 -1
  13. package/dist/admin/assets/{CopyButton-WMWuSVsk.js → CopyButton-Brnpfqe0.js} +2 -2
  14. package/dist/admin/assets/{CopyButton-WMWuSVsk.js.map → CopyButton-Brnpfqe0.js.map} +1 -1
  15. package/dist/admin/assets/{CursorPager-CsnzX1P8.js → CursorPager-C7cAK5Qe.js} +2 -2
  16. package/dist/admin/assets/{CursorPager-CsnzX1P8.js.map → CursorPager-C7cAK5Qe.js.map} +1 -1
  17. package/dist/admin/assets/{FocalPoint-CstZuVmt.js → FocalPoint-Bhtb1gUa.js} +2 -2
  18. package/dist/admin/assets/{FocalPoint-CstZuVmt.js.map → FocalPoint-Bhtb1gUa.js.map} +1 -1
  19. package/dist/admin/assets/{Form-CEOW2OFF.js → Form-Cf1ephPH.js} +2 -2
  20. package/dist/admin/assets/{Form-CEOW2OFF.js.map → Form-Cf1ephPH.js.map} +1 -1
  21. package/dist/admin/assets/FormCheckboxGroup-BzVZFR3W.js +2 -0
  22. package/dist/admin/assets/FormCheckboxGroup-BzVZFR3W.js.map +1 -0
  23. package/dist/admin/assets/{FormRadioGroup-BQurJa8M.js → FormRadioGroup-BzmLzRnI.js} +2 -2
  24. package/dist/admin/assets/{FormRadioGroup-BQurJa8M.js.map → FormRadioGroup-BzmLzRnI.js.map} +1 -1
  25. package/dist/admin/assets/{FormSelectField-B4sjP-pj.js → FormSelectField-Cl7EjXc3.js} +2 -2
  26. package/dist/admin/assets/{FormSelectField-B4sjP-pj.js.map → FormSelectField-Cl7EjXc3.js.map} +1 -1
  27. package/dist/admin/assets/{FormSheet-V99zdfQe.js → FormSheet-CLZpd_7B.js} +2 -2
  28. package/dist/admin/assets/FormSheet-CLZpd_7B.js.map +1 -0
  29. package/dist/admin/assets/{FormSwitchField-RZgoP--n.js → FormSwitchField-BbqQ3tx_.js} +2 -2
  30. package/dist/admin/assets/{FormSwitchField-RZgoP--n.js.map → FormSwitchField-BbqQ3tx_.js.map} +1 -1
  31. package/dist/admin/assets/{FormTextareaField-CzXgoQzf.js → FormTextareaField-9RN5Pt3B.js} +2 -2
  32. package/dist/admin/assets/{FormTextareaField-CzXgoQzf.js.map → FormTextareaField-9RN5Pt3B.js.map} +1 -1
  33. package/dist/admin/assets/{HintedLabel-Cd9nuSqV.js → HintedLabel-D9IVF0EE.js} +2 -2
  34. package/dist/admin/assets/{HintedLabel-Cd9nuSqV.js.map → HintedLabel-D9IVF0EE.js.map} +1 -1
  35. package/dist/admin/assets/{InfoHint-ymRmHKMr.js → InfoHint-tlSeZB9U.js} +2 -2
  36. package/dist/admin/assets/{InfoHint-ymRmHKMr.js.map → InfoHint-tlSeZB9U.js.map} +1 -1
  37. package/dist/admin/assets/{InlineConfirm-A4IqkrGp.js → InlineConfirm-Kj9AOIFO.js} +2 -2
  38. package/dist/admin/assets/{InlineConfirm-A4IqkrGp.js.map → InlineConfirm-Kj9AOIFO.js.map} +1 -1
  39. package/dist/admin/assets/{InsertMenuItem-Bf7S7qbm.js → InsertMenuItem-CHAp2tH7.js} +2 -2
  40. package/dist/admin/assets/{InsertMenuItem-Bf7S7qbm.js.map → InsertMenuItem-CHAp2tH7.js.map} +1 -1
  41. package/dist/admin/assets/{Match-DJq8wn3e.js → Match-BfNRwPfR.js} +2 -2
  42. package/dist/admin/assets/{Match-DJq8wn3e.js.map → Match-BfNRwPfR.js.map} +1 -1
  43. package/dist/admin/assets/{NoAccess-CZufdbPI.js → NoAccess-DnEpYj9l.js} +2 -2
  44. package/dist/admin/assets/{NoAccess-CZufdbPI.js.map → NoAccess-DnEpYj9l.js.map} +1 -1
  45. package/dist/admin/assets/Panel-Bcl09TtM.js.map +1 -1
  46. package/dist/admin/assets/{QueryView-DO9TFWYE.js → QueryView-B86NcRt5.js} +2 -2
  47. package/dist/admin/assets/{QueryView-DO9TFWYE.js.map → QueryView-B86NcRt5.js.map} +1 -1
  48. package/dist/admin/assets/{RadioTile-DmKBFkpy.js → RadioTile-Bwd2Pmlk.js} +2 -2
  49. package/dist/admin/assets/RadioTile-Bwd2Pmlk.js.map +1 -0
  50. package/dist/admin/assets/{RichTextField-BpxyusP4.js → RichTextField-Dou79MHF.js} +2 -2
  51. package/dist/admin/assets/RichTextField-Dou79MHF.js.map +1 -0
  52. package/dist/admin/assets/{RowTitle-DVOfgxOd.js → RowTitle-DH9OZs3g.js} +2 -2
  53. package/dist/admin/assets/{RowTitle-DVOfgxOd.js.map → RowTitle-DH9OZs3g.js.map} +1 -1
  54. package/dist/admin/assets/{SecretReveal-DRCqVEFF.js → SecretReveal-D95oACLj.js} +2 -2
  55. package/dist/admin/assets/{SecretReveal-DRCqVEFF.js.map → SecretReveal-D95oACLj.js.map} +1 -1
  56. package/dist/admin/assets/{SharedGlyph-nsXJPCew.js → SharedGlyph-Chwb1EIS.js} +2 -2
  57. package/dist/admin/assets/{SharedGlyph-nsXJPCew.js.map → SharedGlyph-Chwb1EIS.js.map} +1 -1
  58. package/dist/admin/assets/{StepList-CDZPRd3-.js → StepList-D9iHsUZJ.js} +2 -2
  59. package/dist/admin/assets/StepList-D9iHsUZJ.js.map +1 -0
  60. package/dist/admin/assets/Structure-CewJL1b3.js +2 -0
  61. package/dist/admin/assets/{Structure-CL51Bvbm.js.map → Structure-CewJL1b3.js.map} +1 -1
  62. package/dist/admin/assets/SubNavLink-7Cs1LqMv.js.map +1 -1
  63. package/dist/admin/assets/{SuggestAltButton-4SaZQOJu.js → SuggestAltButton-BK1uo4yC.js} +2 -2
  64. package/dist/admin/assets/{SuggestAltButton-4SaZQOJu.js.map → SuggestAltButton-BK1uo4yC.js.map} +1 -1
  65. package/dist/admin/assets/{Thumbnail-DauHAkh8.js → Thumbnail-C2A_Ub77.js} +2 -2
  66. package/dist/admin/assets/{Thumbnail-DauHAkh8.js.map → Thumbnail-C2A_Ub77.js.map} +1 -1
  67. package/dist/admin/assets/{Trans-B3UWiZaU.js → Trans-CPoNNUK1.js} +2 -2
  68. package/dist/admin/assets/{Trans-B3UWiZaU.js.map → Trans-CPoNNUK1.js.map} +1 -1
  69. package/dist/admin/assets/{UnsavedChangesGuard-DPgih7BX.js → UnsavedChangesGuard-BsEyn9oH.js} +2 -2
  70. package/dist/admin/assets/{UnsavedChangesGuard-DPgih7BX.js.map → UnsavedChangesGuard-BsEyn9oH.js.map} +1 -1
  71. package/dist/admin/assets/{UserAvatar-If-zlQNY.js → UserAvatar-CgGKOFfP.js} +2 -2
  72. package/dist/admin/assets/{UserAvatar-If-zlQNY.js.map → UserAvatar-CgGKOFfP.js.map} +1 -1
  73. package/dist/admin/assets/{badge-DEe9tqLS.js → badge-DGqA_yr_.js} +2 -2
  74. package/dist/admin/assets/{badge-DEe9tqLS.js.map → badge-DGqA_yr_.js.map} +1 -1
  75. package/dist/admin/assets/baseExtensions-TVKN1UwW.js.map +1 -1
  76. package/dist/admin/assets/{changeSets-D5i2SgFV.js → changeSets-B6HxCJ4A.js} +2 -2
  77. package/dist/admin/assets/{changeSets-D5i2SgFV.js.map → changeSets-B6HxCJ4A.js.map} +1 -1
  78. package/dist/admin/assets/cn-DVhJ55Mo.js.map +1 -1
  79. package/dist/admin/assets/{constants-FKg_ke3y.js → constants-DY3YJAKH.js} +2 -2
  80. package/dist/admin/assets/{constants-FKg_ke3y.js.map → constants-DY3YJAKH.js.map} +1 -1
  81. package/dist/admin/assets/content-BNZF26Ve.js +3 -0
  82. package/dist/admin/assets/content-BNZF26Ve.js.map +1 -0
  83. package/dist/admin/assets/{contentTypes-B5taZv3y.js → contentTypes-Bz2xpqGf.js} +2 -2
  84. package/dist/admin/assets/{contentTypes-B5taZv3y.js.map → contentTypes-Bz2xpqGf.js.map} +1 -1
  85. package/dist/admin/assets/createLucideIcon-BOsNKleB.js.map +1 -1
  86. package/dist/admin/assets/{develop-CFlv7IdP.js → develop-D6CtwuYj.js} +2 -2
  87. package/dist/admin/assets/develop-D6CtwuYj.js.map +1 -0
  88. package/dist/admin/assets/{dropdown-menu-B7dJyA8h.js → dropdown-menu-Bz7CLcRK.js} +2 -2
  89. package/dist/admin/assets/{dropdown-menu-B7dJyA8h.js.map → dropdown-menu-Bz7CLcRK.js.map} +1 -1
  90. package/dist/admin/assets/es2015-Cv57ynE1.js +42 -0
  91. package/dist/admin/assets/es2015-Cv57ynE1.js.map +1 -0
  92. package/dist/admin/assets/{field-BDCHXkZE.js → field-D-xWW2E7.js} +2 -2
  93. package/dist/admin/assets/{field-BDCHXkZE.js.map → field-D-xWW2E7.js.map} +1 -1
  94. package/dist/admin/assets/{fileRoute-c9UMUr9b.js → fileRoute-DMal-zYL.js} +2 -2
  95. package/dist/admin/assets/{fileRoute-c9UMUr9b.js.map → fileRoute-DMal-zYL.js.map} +1 -1
  96. package/dist/admin/assets/{followPlural-CHpz-yo4.js → followPlural-CsgeALTW.js} +2 -2
  97. package/dist/admin/assets/{followPlural-CHpz-yo4.js.map → followPlural-CsgeALTW.js.map} +1 -1
  98. package/dist/admin/assets/{inbox-Daw10v5C.js → inbox-C0PVc6UI.js} +2 -2
  99. package/dist/admin/assets/{inbox-Daw10v5C.js.map → inbox-C0PVc6UI.js.map} +1 -1
  100. package/dist/admin/assets/{index-BRx5mel0.js → index-BqtCXB0u.js} +4 -4
  101. package/dist/admin/assets/{index-BRx5mel0.js.map → index-BqtCXB0u.js.map} +1 -1
  102. package/dist/admin/assets/{labels-B83cEX9w.js → labels-BtktCNGw.js} +2 -2
  103. package/dist/admin/assets/{labels-B83cEX9w.js.map → labels-BtktCNGw.js.map} +1 -1
  104. package/dist/admin/assets/{media-CgxriwNL.js → media-CeZGDGh7.js} +2 -2
  105. package/dist/admin/assets/{media-CgxriwNL.js.map → media-CeZGDGh7.js.map} +1 -1
  106. package/dist/admin/assets/{network-Cc1TAyal.js → network-BflLSKFO.js} +2 -2
  107. package/dist/admin/assets/{network-Cc1TAyal.js.map → network-BflLSKFO.js.map} +1 -1
  108. package/dist/admin/assets/publishing-BkxBplUZ.js +2 -0
  109. package/dist/admin/assets/publishing-BkxBplUZ.js.map +1 -0
  110. package/dist/admin/assets/{radio-group-Btmx7dlD.js → radio-group-CRuWQnuV.js} +2 -2
  111. package/dist/admin/assets/{radio-group-Btmx7dlD.js.map → radio-group-CRuWQnuV.js.map} +1 -1
  112. package/dist/admin/assets/schema-6eUoC8fJ.js +2 -0
  113. package/dist/admin/assets/schema-6eUoC8fJ.js.map +1 -0
  114. package/dist/admin/assets/{searchSchemas-fO_49fDI.js → searchSchemas-DAnwh3I3.js} +2 -2
  115. package/dist/admin/assets/{searchSchemas-fO_49fDI.js.map → searchSchemas-DAnwh3I3.js.map} +1 -1
  116. package/dist/admin/assets/{sections-SX-oiQoE.js → sections-CWL-XD6m.js} +2 -2
  117. package/dist/admin/assets/sections-CWL-XD6m.js.map +1 -0
  118. package/dist/admin/assets/{select-JB2Vv7ep.js → select-DVrPV1b3.js} +2 -2
  119. package/dist/admin/assets/{select-JB2Vv7ep.js.map → select-DVrPV1b3.js.map} +1 -1
  120. package/dist/admin/assets/{settings-CrRFxhSo.js → settings-CqnrPmzR.js} +2 -2
  121. package/dist/admin/assets/{settings-CrRFxhSo.js.map → settings-CqnrPmzR.js.map} +1 -1
  122. package/dist/admin/assets/{shapes-EMjfYsXV.js → shapes-ZAkMBB-Z.js} +4 -4
  123. package/dist/admin/assets/shapes-ZAkMBB-Z.js.map +1 -0
  124. package/dist/admin/assets/{skeleton-Dk-qdg0z.js → skeleton-CiX26LnL.js} +2 -2
  125. package/dist/admin/assets/{skeleton-Dk-qdg0z.js.map → skeleton-CiX26LnL.js.map} +1 -1
  126. package/dist/admin/assets/src-CMor9izq.js.map +1 -1
  127. package/dist/admin/assets/{switch-DyCRGDs7.js → switch-CiVf05NF.js} +2 -2
  128. package/dist/admin/assets/{switch-DyCRGDs7.js.map → switch-CiVf05NF.js.map} +1 -1
  129. package/dist/admin/assets/theme-Cv-MfOv8.js.map +1 -1
  130. package/dist/admin/assets/{tooltip-CCOeMqiL.js → tooltip-Bqf3oyqC.js} +2 -2
  131. package/dist/admin/assets/{tooltip-CCOeMqiL.js.map → tooltip-Bqf3oyqC.js.map} +1 -1
  132. package/dist/admin/assets/{useContentSchema-uXOfT985.js → useContentSchema-B_q1rMrG.js} +2 -2
  133. package/dist/admin/assets/{useContentSchema-uXOfT985.js.map → useContentSchema-B_q1rMrG.js.map} +1 -1
  134. package/dist/admin/assets/useCursorPager-BHYqHb3M.js.map +1 -1
  135. package/dist/admin/assets/{useDiscardGuard-DvBI3VIz.js → useDiscardGuard-C4QTfiU4.js} +2 -2
  136. package/dist/admin/assets/{useDiscardGuard-DvBI3VIz.js.map → useDiscardGuard-C4QTfiU4.js.map} +1 -1
  137. package/dist/admin/assets/{useMediaPickerDialog-CehOsykG.js → useMediaPickerDialog-BLrVV1Kn.js} +2 -2
  138. package/dist/admin/assets/{useMediaPickerDialog-CehOsykG.js.map → useMediaPickerDialog-BLrVV1Kn.js.map} +1 -1
  139. package/dist/admin/assets/{useMediaUploader-DvtxYXxD.js → useMediaUploader-CFy6lasO.js} +2 -2
  140. package/dist/admin/assets/useMediaUploader-CFy6lasO.js.map +1 -0
  141. package/dist/admin/assets/{useModelIndex-D8Q0oM4M.js → useModelIndex-NU-WlHQY.js} +2 -2
  142. package/dist/admin/assets/{useModelIndex-D8Q0oM4M.js.map → useModelIndex-NU-WlHQY.js.map} +1 -1
  143. package/dist/admin/assets/{usePlaces-CySN2Vwz.js → usePlaces-BA4x6503.js} +2 -2
  144. package/dist/admin/assets/{usePlaces-CySN2Vwz.js.map → usePlaces-BA4x6503.js.map} +1 -1
  145. package/dist/admin/assets/{useResolvedDefinitions-C279ueCH.js → useResolvedDefinitions-30lnwFQ1.js} +2 -2
  146. package/dist/admin/assets/{useResolvedDefinitions-C279ueCH.js.map → useResolvedDefinitions-30lnwFQ1.js.map} +1 -1
  147. package/dist/admin/assets/{useResolvedScheme-DEq7P4R5.js → useResolvedScheme-BVM4qLct.js} +2 -2
  148. package/dist/admin/assets/{useResolvedScheme-DEq7P4R5.js.map → useResolvedScheme-BVM4qLct.js.map} +1 -1
  149. package/dist/admin/assets/{zod-vPzaNsuW.js → zod-ZaQjjiAq.js} +2 -2
  150. package/dist/admin/assets/{zod-vPzaNsuW.js.map → zod-ZaQjjiAq.js.map} +1 -1
  151. package/dist/admin/index.html +29 -29
  152. package/dist/cli.js +1 -1
  153. package/dist/{cliMain-DzBXO7Oa.js → cliMain-CTntiVc2.js} +11 -11
  154. package/dist/cliMain-CTntiVc2.js.map +1 -0
  155. package/dist/config.d.ts +1 -1
  156. package/dist/config.js +1 -1
  157. package/dist/{contentDisposition-DOL2Xt0l.js → contentDisposition-DzhPhncr.js} +2 -2
  158. package/dist/{contentDisposition-DOL2Xt0l.js.map → contentDisposition-DzhPhncr.js.map} +1 -1
  159. package/dist/index.d.ts +2 -2
  160. package/dist/index.js +2 -2
  161. package/dist/{public-jttKsns_.d.ts → public-CMFaGDyf.d.ts} +4 -4
  162. package/dist/{public-B57h4F7Y.js → public-sJCQaNaP.js} +2 -2
  163. package/dist/{public-B57h4F7Y.js.map → public-sJCQaNaP.js.map} +1 -1
  164. package/dist/{s3Adapter-U01iEAcK.js → s3Adapter-CZcCl0sy.js} +2 -2
  165. package/dist/{s3Adapter-U01iEAcK.js.map → s3Adapter-CZcCl0sy.js.map} +1 -1
  166. package/dist/{worker-6ru1tYBs.js → worker-DHm2JwMZ.js} +353 -232
  167. package/dist/worker-DHm2JwMZ.js.map +1 -0
  168. package/package.json +5 -5
  169. package/dist/admin/assets/Body-BEW1sAAB.js.map +0 -1
  170. package/dist/admin/assets/Builder-Tk_5Orrl.js +0 -2
  171. package/dist/admin/assets/Builder-Tk_5Orrl.js.map +0 -1
  172. package/dist/admin/assets/FormCheckboxGroup-VjWVMiF3.js +0 -2
  173. package/dist/admin/assets/FormCheckboxGroup-VjWVMiF3.js.map +0 -1
  174. package/dist/admin/assets/FormSheet-V99zdfQe.js.map +0 -1
  175. package/dist/admin/assets/RadioTile-DmKBFkpy.js.map +0 -1
  176. package/dist/admin/assets/RichTextField-BpxyusP4.js.map +0 -1
  177. package/dist/admin/assets/StepList-CDZPRd3-.js.map +0 -1
  178. package/dist/admin/assets/Structure-CL51Bvbm.js +0 -2
  179. package/dist/admin/assets/content-DKT2ziPH.js +0 -3
  180. package/dist/admin/assets/content-DKT2ziPH.js.map +0 -1
  181. package/dist/admin/assets/develop-CFlv7IdP.js.map +0 -1
  182. package/dist/admin/assets/es2015-1nJWBurR.js +0 -42
  183. package/dist/admin/assets/es2015-1nJWBurR.js.map +0 -1
  184. package/dist/admin/assets/publishing-RQUj-CyN.js +0 -2
  185. package/dist/admin/assets/publishing-RQUj-CyN.js.map +0 -1
  186. package/dist/admin/assets/schema-BMQEabwO.js +0 -2
  187. package/dist/admin/assets/schema-BMQEabwO.js.map +0 -1
  188. package/dist/admin/assets/sections-SX-oiQoE.js.map +0 -1
  189. package/dist/admin/assets/shapes-EMjfYsXV.js.map +0 -1
  190. package/dist/admin/assets/useMediaUploader-DvtxYXxD.js.map +0 -1
  191. package/dist/cliMain-DzBXO7Oa.js.map +0 -1
  192. package/dist/worker-6ru1tYBs.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { a as buildAssetKey, c as isValidStorageKey, d as withVisibility, i as ObjectNotFoundError, l as sanitizeFilename, n as contentDisposition, o as buildVariantKey, r as InvalidStorageKeyError, s as encodeKeyPath, u as visibilityOfKey } from "./contentDisposition-DOL2Xt0l.js";
2
- import { i as isHookError, n as HookError } from "./public-B57h4F7Y.js";
1
+ import { a as buildAssetKey, c as isValidStorageKey, d as withVisibility, i as ObjectNotFoundError, l as sanitizeFilename, n as contentDisposition, o as buildVariantKey, r as InvalidStorageKeyError, s as encodeKeyPath, u as visibilityOfKey } from "./contentDisposition-DzhPhncr.js";
2
+ import { i as isHookError, n as HookError } from "./public-sJCQaNaP.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { createCipheriv, createDecipheriv, createHash, createHmac, hkdfSync, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
5
5
  import { closeSync, createReadStream, createWriteStream, existsSync, openSync, readFileSync, statSync } from "node:fs";
@@ -2065,7 +2065,7 @@ const REFUSES_UPDATES = /* @__PURE__ */ new Set(["content_revisions", "schema_re
2065
2065
  const targetOf = (conflict) => conflict.columns?.map((column) => column.column.name);
2066
2066
  /**
2067
2067
  * `ON CONFLICT … DO UPDATE` as `ON DUPLICATE KEY UPDATE`, and `ON CONFLICT … DO NOTHING` without RETURNING
2068
- * as `ON DUPLICATE KEY UPDATE <key> = <key>` (a no-op), when MySQL's any-key behaviour equals the target's
2068
+ * as `ON DUPLICATE KEY UPDATE <key> = <key>` (a no-op), when MySQL's any-key behavior equals the target's
2069
2069
  * (`duplicateKeyMatchesTarget`). Any other conflict clause (another unique key could fire, a `WHERE` on the
2070
2070
  * update, RETURNING) is left for the compiler's plan: each row inserted under a savepoint, and a duplicate
2071
2071
  * on the target either skipped or turned into an UPDATE of the row it found.
@@ -2277,7 +2277,7 @@ const insertPlan = (node, compile) => {
2277
2277
  /**
2278
2278
  * Subquery shapes MySQL rejects, rewritten (ADR 0001, "MySQL"): `IN (… LIMIT n)` (error 1235) and a subquery
2279
2279
  * reading the table an UPDATE, DELETE or INSERT writes (error 1093) read a derived table instead, which MySQL
2280
- * materialises first; PostgreSQL's `UPDATE … FROM` becomes a multi-table UPDATE.
2280
+ * materializes first; PostgreSQL's `UPDATE … FROM` becomes a multi-table UPDATE.
2281
2281
  */
2282
2282
  /** The alias of a derived table wrapped around a subquery. */
2283
2283
  const DERIVED_ALIAS = "shapio_derived";
@@ -2287,7 +2287,7 @@ const tableNameOf$1 = (node) => node && TableNode.is(node) ? node.table.identifi
2287
2287
  * reads `table`, the target of the enclosing UPDATE, DELETE or INSERT (error 1093).
2288
2288
  */
2289
2289
  const needsDerivedTable = (node, table) => node.limit !== void 0 || table !== void 0 && ((node.from?.froms ?? []).some((item) => tableNameOf$1(AliasNode.is(item) ? item.node : item) === table) || (node.joins ?? []).some((join) => tableNameOf$1(AliasNode.is(join.table) ? join.table.node : join.table) === table));
2290
- /** `(select * from (<subquery>) as shapio_derived)`: MySQL materialises it first. */
2290
+ /** `(select * from (<subquery>) as shapio_derived)`: MySQL materializes it first. */
2291
2291
  const derived = (node) => Object.freeze({
2292
2292
  ...SelectQueryNode.createFrom([AliasNode.create(node, IdentifierNode.create(DERIVED_ALIAS))]),
2293
2293
  selections: [SelectionNode.create(SelectAllNode.create())]
@@ -2317,7 +2317,7 @@ var DerivedTableWrapper = class extends OperationNodeTransformer {
2317
2317
  const wrapSubqueries = (where, table) => where ? new DerivedTableWrapper(table).transformNode(where) : where;
2318
2318
  /**
2319
2319
  * An INSERT whose VALUES read the target table in a scalar subquery (`coalesce(max(position) + 1, 0)`):
2320
- * MySQL rejects that (error 1093) unless the subquery reads a derived table, which it materialises first.
2320
+ * MySQL rejects that (error 1093) unless the subquery reads a derived table, which it materializes first.
2321
2321
  */
2322
2322
  const withDerivedValueSubqueries = (node) => {
2323
2323
  const table = node.into?.table.identifier.name;
@@ -2494,7 +2494,7 @@ var ShapioMysqlQueryCompiler = class ShapioMysqlQueryCompiler extends MysqlQuery
2494
2494
  //#endregion
2495
2495
  //#region src/db/notifyHub.ts
2496
2496
  /**
2497
- * In-process notification delivery (ADR 0002 notes notifications are an optimisation; consumers also check
2497
+ * In-process notification delivery (ADR 0002 notes notifications are an optimization; consumers also check
2498
2498
  * a durable version): an event bus per database. Every handle on the same database in this process shares
2499
2499
  * one bus, so two app instances in one test process still hear each other.
2500
2500
  * - SQLite: the only delivery (SQLite deployments are single-process).
@@ -2880,7 +2880,7 @@ var MysqlDriver = class {
2880
2880
  this.#pool = pool;
2881
2881
  }
2882
2882
  #pooled() {
2883
- if (!this.#pool) throw new Error("The MySQL driver is not initialised");
2883
+ if (!this.#pool) throw new Error("The MySQL driver is not initialized");
2884
2884
  return this.#pool;
2885
2885
  }
2886
2886
  /**
@@ -3044,7 +3044,7 @@ const ISO_TIMESTAMP = /^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}/;
3044
3044
  */
3045
3045
  const timestampText = (value) => typeof value === "string" && ISO_TIMESTAMP.test(value) ? toDatetimeText(value) : value;
3046
3046
  const isTimestampColumn = (table, column) => table !== void 0 && (tableInfo(table)?.timestamps ?? []).includes(column);
3047
- /** A value node (or primitive list) bound to a timestamp column, with ISO text normalised. */
3047
+ /** A value node (or primitive list) bound to a timestamp column, with ISO text normalized. */
3048
3048
  const timestampValue = (node) => {
3049
3049
  if (ValueNode.is(node)) {
3050
3050
  const value = timestampText(node.value);
@@ -3053,7 +3053,7 @@ const timestampValue = (node) => {
3053
3053
  if (PrimitiveValueListNode.is(node)) return PrimitiveValueListNode.create(node.values.map(timestampText));
3054
3054
  return node;
3055
3055
  };
3056
- /** Insert rows with ISO text for timestamp columns normalised. */
3056
+ /** Insert rows with ISO text for timestamp columns normalized. */
3057
3057
  const withTimestampValues = (node) => {
3058
3058
  const table = node.into?.table.identifier.name;
3059
3059
  const positions = (node.columns?.map((column) => column.column.name) ?? []).flatMap((column, index) => isTimestampColumn(table, column) ? [index] : []);
@@ -3172,7 +3172,7 @@ const decodeRow = (row, markers) => {
3172
3172
  * Adapts Kysely queries written for PostgreSQL to MySQL (dialect boundary, ADR 0001, "MySQL"). Rewrites that
3173
3173
  * stay one statement happen here; statements MySQL cannot run as one (`RETURNING`, most `ON CONFLICT`) are
3174
3174
  * planned by the compiler (`plans.ts`). This plugin:
3175
- * - fills the columns PostgreSQL defaults that MySQL cannot, and normalises ISO text bound to timestamp
3175
+ * - fills the columns PostgreSQL defaults that MySQL cannot, and normalizes ISO text bound to timestamp
3176
3176
  * columns (`insertValues.ts`);
3177
3177
  * - spells casts MySQL's way (`text` → `char`, `bigint`/`integer` → `signed`) and maps row locks MySQL lacks;
3178
3178
  * - keeps PostgreSQL's NULL placement in ORDER BY (`nullOrdering.ts`);
@@ -3393,7 +3393,7 @@ const currentTimestamp = () => {
3393
3393
  };
3394
3394
  /**
3395
3395
  * A bound value read as a timestamp (ISO-8601 text or a Date; null stays null).
3396
- * PostgreSQL: `cast($1 as timestamptz)`. SQLite: the value normalised by `toStoredTimestamp` and bound.
3396
+ * PostgreSQL: `cast($1 as timestamptz)`. SQLite: the value normalized by `toStoredTimestamp` and bound.
3397
3397
  * MySQL: `cast($1 as datetime(6))` with UTC `DATETIME` text (ISO text keeps its microseconds).
3398
3398
  * Contract: compares and sorts against timestamp columns as an instant, at the precision the text carries
3399
3399
  * (microseconds from `timestampCursorText` on PostgreSQL, milliseconds on SQLite).
@@ -3918,7 +3918,7 @@ const indexExpressionSql = (index) => index.columns.map((column) => index.nullab
3918
3918
  const nullsNotDistinctIndexFor = (table, columns) => NULLS_NOT_DISTINCT_INDEXES.find((index) => index.table === table && index.columns.length === columns.length && index.columns.every((column) => columns.includes(column)));
3919
3919
  //#endregion
3920
3920
  //#region src/db/sqlite/plugin.ts
3921
- /** Row-lock modifiers PostgreSQL needs and SQLite rejects; its write transactions are already serialised. */
3921
+ /** Row-lock modifiers PostgreSQL needs and SQLite rejects; its write transactions are already serialized. */
3922
3922
  const ROW_LOCKS = /* @__PURE__ */ new Set([
3923
3923
  "ForUpdate",
3924
3924
  "ForNoKeyUpdate",
@@ -4102,7 +4102,7 @@ const OPTIMIZE = {
4102
4102
  };
4103
4103
  /**
4104
4104
  * A Kysely driver over Node's built-in `node:sqlite` (no native dependency). One writer connection runs
4105
- * every write, serialised by an in-process lock (`writeLock.ts`, `BEGIN IMMEDIATE`); reader connections
4105
+ * every write, serialized by an in-process lock (`writeLock.ts`, `BEGIN IMMEDIATE`); reader connections
4106
4106
  * serve read-only transactions and autocommit reads concurrently (WAL). An in-memory database has the
4107
4107
  * writer only, and every statement takes the lock.
4108
4108
  */
@@ -4331,7 +4331,7 @@ var SqliteSession = class {
4331
4331
  //#region src/db/sqlite/index.ts
4332
4332
  /**
4333
4333
  * SQLite runs DDL inside transactions, so each migration commits or rolls back whole. The driver handles
4334
- * concurrency itself (one writer, several readers), so Kysely must not serialise connections on top.
4334
+ * concurrency itself (one writer, several readers), so Kysely must not serialize connections on top.
4335
4335
  */
4336
4336
  var ShapioSqliteAdapter = class extends SqliteAdapter {
4337
4337
  get supportsTransactionalDdl() {
@@ -5260,11 +5260,11 @@ const richTextMediaIds = (document) => {
5260
5260
  return [...ids];
5261
5261
  };
5262
5262
  //#endregion
5263
- //#region ../../packages/schema/dist/resolve-viddCEYd.js
5263
+ //#region ../../packages/schema/dist/resolve-Csjpkpue.js
5264
5264
  /**
5265
5265
  * The built-in SEO component (plan seo-fields). It is ordinary schema data, created through the change planner
5266
5266
  * and always shared with every site; what makes it "the" SEO component is its stable ID, never its API ID, so
5267
- * a renamed or extended copy is still recognised and an unrelated `seo` component (an import) never is.
5267
+ * a renamed or extended copy is still recognized and an unrelated `seo` component (an import) never is.
5268
5268
  */
5269
5269
  const SEO_COMPONENT_ID = "f3905a00-d2a3-4c62-899a-c894bfd6cb9b";
5270
5270
  /** Stable field IDs of the built-in's fields. Resolver and admin look fields up by these. */
@@ -6297,7 +6297,7 @@ const entries = [
6297
6297
  optionsSchema: Type.Object({ collapsed: Type.Optional(Type.Boolean()) }, closed$1$1)
6298
6298
  }
6299
6299
  ];
6300
- const EDITOR_CATALOGUE = new Map(entries.map((entry) => [entry.id, entry]));
6300
+ const EDITOR_CATALOG = new Map(entries.map((entry) => [entry.id, entry]));
6301
6301
  /** The editor a field gets when its definition names none. */
6302
6302
  const DEFAULT_EDITORS = {
6303
6303
  string: "textInput",
@@ -7167,7 +7167,7 @@ const checkFlags = (field, path, isComponent) => {
7167
7167
  const checkEditor = (field, path) => {
7168
7168
  const { id, options } = field.editor;
7169
7169
  if (isCustomEditorId(id)) return [];
7170
- const entry = EDITOR_CATALOGUE.get(id);
7170
+ const entry = EDITOR_CATALOG.get(id);
7171
7171
  if (!entry) return [issue$1(`${path}/editor/id`, "UNKNOWN_EDITOR", `"${id}" is not a built-in editor (custom editors use a vendor.name ID)`)];
7172
7172
  if (!entry.dataTypes.includes(field.type) || !(entry.supports?.(field) ?? true)) return [issue$1(`${path}/editor/id`, "INCOMPATIBLE_EDITOR", `the ${id} editor cannot edit this ${field.type} field`)];
7173
7173
  return collectSchemaErrors(entry.optionsSchema, options, `${path}/editor/options`).map((error) => issue$1(error.path, "INVALID_EDITOR_OPTIONS", error.message));
@@ -8544,11 +8544,11 @@ const BUILT_IN_THEME_KEYS = [
8544
8544
  "butter"
8545
8545
  ];
8546
8546
  /**
8547
- * A token value an extension may use: a hex colour or a colour function whose arguments are numbers, units
8547
+ * A token value an extension may use: a hex color or a color function whose arguments are numbers, units
8548
8548
  * and separators only (no `;`, quotes, braces or nested functions such as `url()` or `var()`), so a value
8549
8549
  * can never escape its declaration.
8550
8550
  */
8551
- const THEME_COLOUR_PATTERN = /^(?:#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|(?:rgba?|hsla?|oklch|oklab)\([0-9a-z.,%\s/+-]{1,80}\))$/;
8551
+ const THEME_COLOR_PATTERN = /^(?:#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|(?:rgba?|hsla?|oklch|oklab)\([0-9a-z.,%\s/+-]{1,80}\))$/;
8552
8552
  const SURFACES = [
8553
8553
  "background",
8554
8554
  "card",
@@ -8631,7 +8631,7 @@ const luminance = (hex) => {
8631
8631
  ].map((index) => channel(parseInt(hex.slice(index, index + 2), 16)));
8632
8632
  return .2126 * (r ?? 0) + .7152 * (g ?? 0) + .0722 * (b ?? 0);
8633
8633
  };
8634
- /** The WCAG contrast ratio of two `#rrggbb` colours. */
8634
+ /** The WCAG contrast ratio of two `#rrggbb` colors. */
8635
8635
  const contrastRatio = (a, b) => {
8636
8636
  const [high = 0, low = 0] = [luminance(a), luminance(b)].sort((x, y) => y - x);
8637
8637
  return (high + .05) / (low + .05);
@@ -8844,7 +8844,7 @@ const purgeDeletedEntriesOfModels = async (modelIds, trx) => {
8844
8844
  /**
8845
8845
  * The publication sequence and log behind `?snapshot=N` (ADR 0001). The sequence is one row incremented
8846
8846
  * inside each publishing transaction: its row lock orders publications by commit, so a reader that sees N
8847
- * also sees every publication before N. Take it as late as possible in the transaction (it serialises every
8847
+ * also sees every publication before N. Take it as late as possible in the transaction (it serializes every
8848
8848
  * publication instance-wide until commit), and never ahead of the transaction that uses it.
8849
8849
  *
8850
8850
  * Every number also gets a `publication_snapshots` ledger row (why, who, the schema version live with it),
@@ -9032,7 +9032,7 @@ const purgeDefinitions = async (ids, trx = db) => {
9032
9032
  await trx.deleteFrom("models").where("id", "in", ids).execute();
9033
9033
  };
9034
9034
  /**
9035
- * Keeps the denormalised kind, API key and scope in step with the active revision; also undeletes. The scope
9035
+ * Keeps the denormalized kind, API key and scope in step with the active revision; also undeletes. The scope
9036
9036
  * only differs from the stored one for a scope change (`ActivationItem.moveScope`).
9037
9037
  */
9038
9038
  const markModelActive = (model, trx = db) => trx.updateTable("models").set({
@@ -9305,7 +9305,7 @@ const sleep = (ms, signal) => new Promise((resolve) => {
9305
9305
  //#region src/db/sqlite/keyedMutex.ts
9306
9306
  /**
9307
9307
  * An in-process mutex per key: SQLite's stand-in for PostgreSQL session advisory locks (migrations, index
9308
- * builds). It serialises holders inside one process only; SQLite deployments are single-process.
9308
+ * builds). It serializes holders inside one process only; SQLite deployments are single-process.
9309
9309
  */
9310
9310
  const TAILS = /* @__PURE__ */ new Map();
9311
9311
  /** Runs `fn` while holding the lock for `key`; waiters run in arrival order. */
@@ -9417,10 +9417,10 @@ const acquireXactLockShared = async (trx, namespace, key) => {
9417
9417
  //#endregion
9418
9418
  //#region src/schema/planner/locks.ts
9419
9419
  /**
9420
- * Serialises every schema activation (and the start of every planned change) instance-wide. Activations are
9420
+ * Serializes every schema activation (and the start of every planned change) instance-wide. Activations are
9421
9421
  * rare, and holding this lock while re-validating the whole schema closes races between changes to
9422
9422
  * *different* definitions (e.g. two renames to colliding GraphQL names). It lives in the model namespace;
9423
- * a collision with a model's hash only costs extra serialisation.
9423
+ * a collision with a model's hash only costs extra serialization.
9424
9424
  */
9425
9425
  const SCHEMA_ACTIVATION_LOCK_KEY = lockKeyFromId("shapio:schema-activation");
9426
9426
  /**
@@ -10879,7 +10879,7 @@ const MEDIA_PROCESS_JOB = "media.process";
10879
10879
  const MEDIA_PURGE_JOB = "media.purge";
10880
10880
  const MEDIA_RELOCATE_JOB = "media.relocate";
10881
10881
  const MEDIA_GRANT_EXPIRE_JOB = "media.grant.expire";
10882
- /** Outbox event types (webhook catalogue `media.*`, package H). */
10882
+ /** Outbox event types (webhook catalog `media.*`, package H). */
10883
10883
  const MEDIA_EVENTS = {
10884
10884
  created: "media.created",
10885
10885
  updated: "media.updated",
@@ -12884,7 +12884,7 @@ const getOwnerRoleId = async (trx) => {
12884
12884
  const isOwnerActor = (actor, ownerRoleId) => actor.kind === "system" || actor.kind === "admin" && actor.networkRoleIds.includes(ownerRoleId);
12885
12885
  /**
12886
12886
  * Inserts an admin user with role assignments (`roleIds`: those roles on every site). Shared by setup,
12887
- * invitations and `shapio admin create`; the caller owns the transaction, validation, authorisation and
12887
+ * invitations and `shapio admin create`; the caller owns the transaction, validation, authorization and
12888
12888
  * audit.
12889
12889
  */
12890
12890
  const insertAdminUser = async (input, trx) => {
@@ -12909,7 +12909,7 @@ const getAdminUser = async (id) => {
12909
12909
  if (!row) throw notFound$7();
12910
12910
  return toAdminUserView(row);
12911
12911
  };
12912
- /** Fails when no active owner other than `exceptUserId` would remain. Locks owners to serialise checks. */
12912
+ /** Fails when no active owner other than `exceptUserId` would remain. Locks owners to serialize checks. */
12913
12913
  const assertAnotherOwnerRemains = async (exceptUserId, trx) => {
12914
12914
  if (!(await lockActiveHoldersOfRoleKey(SYSTEM_ROLE_KEYS.owner, trx)).some((owner) => owner.id !== exceptUserId)) throw new AppError(409, "LAST_OWNER", "Shapio needs at least one active owner");
12915
12915
  };
@@ -14817,7 +14817,7 @@ const groupByRole = (grants) => {
14817
14817
  * Every role's grants, held in memory and reloaded when `system_versions.permissions_version` moves.
14818
14818
  * The version is checked on every lookup: read here, or read once by the request (`versions`, see
14819
14819
  * `KnownVersions`). That durable check is what makes a permission change visible to every instance from the
14820
- * next request (NOTIFY would only be an optimisation). Lookups on the pool share one reload; a
14820
+ * next request (NOTIFY would only be an optimization). Lookups on the pool share one reload; a
14821
14821
  * lookup inside a transaction reads (and, when stale, reloads) through that transaction alone, never
14822
14822
  * through a reload running on another request's transaction.
14823
14823
  */
@@ -15414,7 +15414,7 @@ const findNamingProblems = (config) => {
15414
15414
  return [...problems, ...findThemeProblems(config.themes)];
15415
15415
  };
15416
15416
  const BUILT_IN_THEMES = new Set(BUILT_IN_THEME_KEYS);
15417
- /** Theme keys (pattern, built-in, unique), at least one variant, and colour values (no CSS injection). */
15417
+ /** Theme keys (pattern, built-in, unique), at least one variant, and color values (no CSS injection). */
15418
15418
  const findThemeProblems = (themes) => {
15419
15419
  const problems = [];
15420
15420
  const keys = /* @__PURE__ */ new Set();
@@ -15442,9 +15442,9 @@ const findThemeProblems = (themes) => {
15442
15442
  });
15443
15443
  for (const variant of THEME_VARIANTS) {
15444
15444
  const tokens = theme[variant];
15445
- for (const [token, value] of Object.entries(isRecord$6(tokens) ? tokens : {})) if (typeof value === "string" && !THEME_COLOUR_PATTERN.test(value)) problems.push({
15445
+ for (const [token, value] of Object.entries(isRecord$6(tokens) ? tokens : {})) if (typeof value === "string" && !THEME_COLOR_PATTERN.test(value)) problems.push({
15446
15446
  path: `${path}/${variant}/${token}`,
15447
- message: `"${value}" is not a colour: use #rrggbb, rgb(), hsl(), oklch() or oklab()`
15447
+ message: `"${value}" is not a color: use #rrggbb, rgb(), hsl(), oklch() or oklab()`
15448
15448
  });
15449
15449
  }
15450
15450
  });
@@ -17625,7 +17625,7 @@ const themeCss = (theme) => {
17625
17625
  return block(selector, tokens);
17626
17626
  }).join("\n");
17627
17627
  };
17628
- const buildThemeCatalogue = (themes) => ({
17628
+ const buildThemeCatalog = (themes) => ({
17629
17629
  items: themes.map((theme) => ({
17630
17630
  key: theme.key,
17631
17631
  name: theme.name,
@@ -17835,7 +17835,7 @@ const resolveMediaOrigins = async (storage) => {
17835
17835
  const base = originOf(storage.publicBaseUrl);
17836
17836
  if (base) origins.add(base);
17837
17837
  if (storage.s3) {
17838
- const { createS3Adapter } = await import("./s3Adapter-U01iEAcK.js");
17838
+ const { createS3Adapter } = await import("./s3Adapter-CZcCl0sy.js");
17839
17839
  const adapter = createS3Adapter({
17840
17840
  config: storage.s3,
17841
17841
  publicBaseUrl: void 0
@@ -17939,7 +17939,7 @@ const LAST_SEEN_WRITE_INTERVAL_MS = 6e4;
17939
17939
  const CSRF_HEADER = "x-csrf-token";
17940
17940
  const INVITATION_TTL_MS = 6048e5;
17941
17941
  const PASSWORD_RESET_TTL_MS = 36e5;
17942
- /** API tokens carry a recognisable prefix (secret scanners, and telling them apart from app-user JWTs). */
17942
+ /** API tokens carry a recognizable prefix (secret scanners, and telling them apart from app-user JWTs). */
17943
17943
  const API_TOKEN_PREFIX = "shp_";
17944
17944
  /** Rate limits for unauthenticated credential endpoints. Per IP via @fastify/rate-limit route config. */
17945
17945
  const CREDENTIAL_RATE_LIMIT_PER_IP = {
@@ -18044,7 +18044,7 @@ const isSetupRequired = async (database = db) => await countAll(database) === 0;
18044
18044
  /**
18045
18045
  * At boot, while no admin exists: supersedes any earlier setup token and issues a new one. Returns the
18046
18046
  * token for the caller to show exactly once (it is stored only as a hash), or undefined when setup is done.
18047
- * Serialised with setup itself by the setup advisory lock.
18047
+ * Serialized with setup itself by the setup advisory lock.
18048
18048
  */
18049
18049
  const issueSetupToken = async (database) => database.transaction().execute(async (trx) => {
18050
18050
  await acquireXactLock(trx, LOCK_NAMESPACE.setup, 1);
@@ -18206,7 +18206,7 @@ const findSummaryByIdInSite = (id, siteId, trx = db) => summaries(trx).where("ap
18206
18206
  const findByEmailWithHash = (siteId, email, trx = db) => trx.selectFrom("app_users").selectAll().where("site_id", "=", siteId).where((eb) => eb(eb.fn("lower", ["email"]), "=", email.toLowerCase())).where("deleted_at", "is", null).executeTakeFirst();
18207
18207
  /** Includes the password hash: for credential checks only. Live (not deleted) accounts only. */
18208
18208
  const findByIdWithHash = (id, trx = db) => trx.selectFrom("app_users").selectAll().where("id", "=", id).where("deleted_at", "is", null).executeTakeFirst();
18209
- /** Locks the live account row (status changes, deletion and credential changes serialise on it). */
18209
+ /** Locks the live account row (status changes, deletion and credential changes serialize on it). */
18210
18210
  const lockById$2 = (id, trx) => trx.selectFrom("app_users").selectAll().where("id", "=", id).where("deleted_at", "is", null).forUpdate().executeTakeFirst();
18211
18211
  /** Locks the live account row of one site (another site's account reads as not found). */
18212
18212
  const lockByIdInSite = (id, siteId, trx) => trx.selectFrom("app_users").selectAll().where("id", "=", id).where("site_id", "=", siteId).where("deleted_at", "is", null).forUpdate().executeTakeFirst();
@@ -19831,11 +19831,11 @@ const jsonInstruction = (request) => request.json ? `\n\nAnswer with one JSON ob
19831
19831
  * Chat Completions (`POST {AI_BASE_URL}/chat/completions`). `openai` uses `response_format` with the
19832
19832
  * schema; `openai-compatible` (Ollama, LM Studio, vLLM) gets the schema in the prompt.
19833
19833
  */
19834
- const createChatCompletionsProvider = (transport, flavour) => ({
19835
- id: flavour,
19834
+ const createChatCompletionsProvider = (transport, flavor) => ({
19835
+ id: flavor,
19836
19836
  model: transport.config.model,
19837
19837
  complete: async (request) => {
19838
- const native = flavour === "openai";
19838
+ const native = flavor === "openai";
19839
19839
  const system = native ? request.system : `${request.system}${jsonInstruction(request)}`;
19840
19840
  const responseFormat = request.json && native ? {
19841
19841
  type: "json_schema",
@@ -20785,9 +20785,9 @@ const createMysqlNotificationListener = (options) => {
20785
20785
  //#endregion
20786
20786
  //#region src/db/notifications.ts
20787
20787
  /**
20788
- * LISTEN/NOTIFY primitives (ADR 0002). Notifications are an optimisation only: a listener can miss
20788
+ * LISTEN/NOTIFY primitives (ADR 0002). Notifications are an optimization only: a listener can miss
20789
20789
  * messages while disconnected, so every consumer must also check a durable version. Callers get an
20790
- * `onConnect` callback after every (re)connect to resynchronise for anything missed in between.
20790
+ * `onConnect` callback after every (re)connect to resynchronize for anything missed in between.
20791
20791
  *
20792
20792
  * SQLite: `shapio_notify()` queues on the connection and an in-process bus delivers on commit
20793
20793
  * (`notifyHub.ts`); only listeners in the same process hear it.
@@ -21742,9 +21742,9 @@ const THEMED = [
21742
21742
  ];
21743
21743
  const themed = (theme) => THEMED.map((selector) => `body.graphiql-${theme} ${selector}`).join(",\n");
21744
21744
  /**
21745
- * Page layout, and GraphiQL's palette adjusted to WCAG AA: every text colour (syntax highlighting, links,
21745
+ * Page layout, and GraphiQL's palette adjusted to WCAG AA: every text color (syntax highlighting, links,
21746
21746
  * secondary text) reaches 4.5:1 on the backgrounds it is drawn on, in both themes (GraphiQL's own light
21747
- * palette is 2.3–4.3:1 there), and links in the docs are underlined so they don't rely on colour alone.
21747
+ * palette is 2.3–4.3:1 there), and links in the docs are underlined so they don't rely on color alone.
21748
21748
  */
21749
21749
  const STYLE$1 = `html, body, #graphiql { height: 100%; margin: 0; }
21750
21750
  ${themed("light")} {
@@ -24681,7 +24681,7 @@ const createMediaStorage = async (config, deps) => {
24681
24681
  publicBaseUrl: config.publicBaseUrl
24682
24682
  }));
24683
24683
  if (config.s3) {
24684
- const { createS3Adapter } = await import("./s3Adapter-U01iEAcK.js");
24684
+ const { createS3Adapter } = await import("./s3Adapter-CZcCl0sy.js");
24685
24685
  adapters.set("s3", createS3Adapter({
24686
24686
  config: config.s3,
24687
24687
  publicBaseUrl: config.publicBaseUrl
@@ -24858,7 +24858,7 @@ const CORS_METHODS = [
24858
24858
  /**
24859
24859
  * Baseline HTTP hardening: security headers, CORS (off unless origins are configured; the admin and API
24860
24860
  * share one origin, so CORS is only for the user's own sites and apps), a global rate limit keyed by the
24861
- * client IP (which honours TRUST_PROXY), and @fastify/sensible's httpErrors.
24861
+ * client IP (which honors TRUST_PROXY), and @fastify/sensible's httpErrors.
24862
24862
  * The rate-limit store is in memory, so with several instances each counts on its own (documented: put a
24863
24863
  * shared limiter in front for strict limits; ADR 0008).
24864
24864
  */
@@ -24925,11 +24925,11 @@ const textInputPlugin = fp(async (app) => {
24925
24925
  });
24926
24926
  }, { name: "shapio-text-input" });
24927
24927
  //#endregion
24928
- //#region src/plugins/themeCatalogue.ts
24929
- /** The catalogue is built from the project config by the app (extensions/themeStylesheet.ts). */
24930
- const themeCataloguePlugin = fp(async (app, { catalogue }) => {
24931
- app.decorate("themeCatalogue", catalogue);
24932
- }, { name: "shapio-theme-catalogue" });
24928
+ //#region src/plugins/themeCatalog.ts
24929
+ /** The catalog is built from the project config by the app (extensions/themeStylesheet.ts). */
24930
+ const themeCatalogPlugin = fp(async (app, { catalog }) => {
24931
+ app.decorate("themeCatalog", catalog);
24932
+ }, { name: "shapio-theme-catalog" });
24933
24933
  //#endregion
24934
24934
  //#region src/repositories/usage.ts
24935
24935
  const upsertFieldReads = async (rows, trx = db) => {
@@ -25441,7 +25441,7 @@ const PUBLISHING_JOBS = {
25441
25441
  deploymentTrigger: "deployment.trigger",
25442
25442
  deploymentPoll: "deployment.poll"
25443
25443
  };
25444
- /** Change set events (also in the webhook catalogue). `shipped` carries the snapshot it went live in. */
25444
+ /** Change set events (also in the webhook catalog). `shipped` carries the snapshot it went live in. */
25445
25445
  const CHANGE_SET_EVENTS = {
25446
25446
  scheduled: "change_set.scheduled",
25447
25447
  shipping: "change_set.shipping",
@@ -28479,13 +28479,13 @@ const RevisionSummarySchema = Type.Object({
28479
28479
  });
28480
28480
  /** A revision in a definition's history: whether its change went live, and whether it is the active one. */
28481
28481
  const RevisionListItemSchema = Type.Intersect([RevisionSummarySchema, Type.Object({
28482
- /** The change that wrote it: `failed` and `cancelled` revisions never went live. */
28482
+ /** The change that wrote it: `failed` and `canceled` revisions never went live. */
28483
28483
  status: Type.Union([
28484
28484
  Type.Literal("pending"),
28485
28485
  Type.Literal("running"),
28486
28486
  Type.Literal("activated"),
28487
28487
  Type.Literal("failed"),
28488
- Type.Literal("cancelled")
28488
+ Type.Literal("canceled")
28489
28489
  ]),
28490
28490
  active: Type.Boolean()
28491
28491
  })]);
@@ -29374,7 +29374,7 @@ const activateDefinitions = async (db, request) => {
29374
29374
  * with the schema version it activated. The ledger row of the change set's own site is `change_set`; other
29375
29375
  * sites' rows are `conversion` and name the change set; without a change set every row is `schema`. Each
29376
29376
  * site's number is taken on first use (a change set's publications, an entry-level conversion) or at the
29377
- * end, under the schema lock, and that site's deferred work then runs with it. Activations are serialised
29377
+ * end, under the schema lock, and that site's deferred work then runs with it. Activations are serialized
29378
29378
  * by the schema lock and every other publisher holds one site's sequence row at most, so taking several
29379
29379
  * sites' rows in first-use order cannot deadlock. A metadata-only activation (a label rename) takes no
29380
29380
  * number anywhere: live content and every API response stay exactly as they were (brief §10).
@@ -30668,7 +30668,7 @@ const markFailed$2 = (id, error, now, trx = db) => trx.updateTable("scheduled_pu
30668
30668
  }).where("id", "=", id).where("status", "in", ["scheduled", "failed"]).execute();
30669
30669
  /** Cancels a schedule that has not run yet; returns the row when it changed. */
30670
30670
  const cancel = (id, now, trx = db) => trx.updateTable("scheduled_publications").set({
30671
- status: "cancelled",
30671
+ status: "canceled",
30672
30672
  updated_at: now
30673
30673
  }).where("id", "=", id).where("status", "in", ["scheduled", "failed"]).returningAll().executeTakeFirst();
30674
30674
  /** Whether the entry has a publication still scheduled (change kind waits for it). */
@@ -31143,9 +31143,9 @@ const getEditorFile = async (request, reply) => {
31143
31143
  return reply.type("text/javascript; charset=utf-8").header("cache-control", "private, max-age=31536000, immutable").send(await readFile(entry.path));
31144
31144
  };
31145
31145
  //#endregion
31146
- //#region src/controllers/themeCatalogue.ts
31146
+ //#region src/controllers/themeCatalog.ts
31147
31147
  /** The project's extension themes, for the admin's theme menu. */
31148
- const listThemes = async (request) => ({ items: request.server.themeCatalogue.items });
31148
+ const listThemes = async (request) => ({ items: request.server.themeCatalog.items });
31149
31149
  let stylesheetEtag;
31150
31150
  const etagOf = (stylesheet) => {
31151
31151
  if (stylesheetEtag?.stylesheet !== stylesheet) stylesheetEtag = {
@@ -31156,11 +31156,11 @@ const etagOf = (stylesheet) => {
31156
31156
  };
31157
31157
  /**
31158
31158
  * Their CSS, linked render-blocking from the admin's index.html (empty without extension themes). Public:
31159
- * it holds colours only, and the signed-out screens render in the chosen theme too. Revalidated on each
31159
+ * it holds colors only, and the signed-out screens render in the chosen theme too. Revalidated on each
31160
31160
  * load (it changes only with a restart), so a changed theme shows without a stale cache.
31161
31161
  */
31162
31162
  const getThemeStylesheet = async (request, reply) => {
31163
- const { stylesheet } = request.server.themeCatalogue;
31163
+ const { stylesheet } = request.server.themeCatalog;
31164
31164
  const etag = etagOf(stylesheet);
31165
31165
  reply.header("etag", etag).header("cache-control", "no-cache").type("text/css; charset=utf-8");
31166
31166
  if (request.headers["if-none-match"] === etag) return reply.code(304).send();
@@ -31190,7 +31190,7 @@ const listThemesSchema = { response: { 200: Type.Object({ items: Type.Array(Type
31190
31190
  //#endregion
31191
31191
  //#region src/routes/admin/extensions/index.ts
31192
31192
  /**
31193
- * /api/admin/extensions: what the project installed for the admin (custom field editors, ADR 0009; colour
31193
+ * /api/admin/extensions: what the project installed for the admin (custom field editors, ADR 0009; color
31194
31194
  * themes, docs/plans/themes.md).
31195
31195
  */
31196
31196
  const adminExtensionsRoutes = async (app) => {
@@ -33925,7 +33925,7 @@ const createReplaceGrant = async (context, assetId, input) => {
33925
33925
  const goneGrant = () => new AppError(404, "UPLOAD_GRANT_INVALID", "This upload grant is unknown, used or expired");
33926
33926
  /**
33927
33927
  * Local driver only: receives the bytes of a grant (the S3 driver's browser uploads go to the bucket).
33928
- * Authorised by the grant's signature, not by a session. `readUpload` parses the request with the grant's
33928
+ * Authorized by the grant's signature, not by a session. `readUpload` parses the request with the grant's
33929
33929
  * size limit; the bytes stream to disk and are re-checked on confirm.
33930
33930
  */
33931
33931
  const receiveLocalUpload = async (context, grantId, readUpload) => {
@@ -34445,7 +34445,7 @@ const confirmUploadSchema = {
34445
34445
  };
34446
34446
  //#endregion
34447
34447
  //#region src/routes/admin/media/index.ts
34448
- const NOT_AUDITED = "media library organisation (folders, metadata, moves) is recorded by media.* outbox events, not audited";
34448
+ const NOT_AUDITED = "media library organization (folders, metadata, moves) is recorded by media.* outbox events, not audited";
34449
34449
  const GRANT_ONLY = "issues an upload grant only; the change is audited on confirm (media.upload / media.replace)";
34450
34450
  /** /api/admin/media: the media library (folders, assets, uploads, usage). */
34451
34451
  const adminMediaRoutes = async (app) => {
@@ -35557,7 +35557,7 @@ const summarizeItem = (component, item, lookups) => {
35557
35557
  }
35558
35558
  return "";
35559
35559
  };
35560
- const labelled = (label, summary) => summary ? `${label} (${summary})` : label;
35560
+ const labeled = (label, summary) => summary ? `${label} (${summary})` : label;
35561
35561
  const componentSummary = (field, value, lookups) => {
35562
35562
  const component = lookups.component(field.settings.component);
35563
35563
  const items = listOf(value);
@@ -35572,7 +35572,7 @@ const zoneSummary = (value, lookups) => {
35572
35572
  const blocks = value.map((item) => {
35573
35573
  const id = item[COMPONENT_KEY];
35574
35574
  const component = typeof id === "string" ? lookups.component(id) : void 0;
35575
- return component ? labelled(component.label, summarizeItem(component, item, lookups)) : String(id);
35575
+ return component ? labeled(component.label, summarizeItem(component, item, lookups)) : String(id);
35576
35576
  });
35577
35577
  return `${plural(value.length, "block", "blocks")}: ${blocks.join(", ")}`;
35578
35578
  };
@@ -40250,12 +40250,12 @@ const markDeliveryDead = (id, error, now, trx = db) => trx.updateTable("webhook_
40250
40250
  updated_at: now
40251
40251
  }).where("id", "=", id).where("status", "in", ["pending", "retrying"]).execute();
40252
40252
  //#endregion
40253
- //#region src/webhooks/catalogue.ts
40253
+ //#region src/webhooks/catalog.ts
40254
40254
  const group = (name, types) => types.map((type) => ({
40255
40255
  type,
40256
40256
  group: name
40257
40257
  }));
40258
- const WEBHOOK_EVENT_CATALOGUE = [
40258
+ const WEBHOOK_EVENT_CATALOG = [
40259
40259
  ...group("entry", [
40260
40260
  "entry.created",
40261
40261
  "entry.updated",
@@ -40279,8 +40279,8 @@ const WEBHOOK_EVENT_CATALOGUE = [
40279
40279
  ];
40280
40280
  /** Sent by "Send test"; never produced by the outbox. */
40281
40281
  const WEBHOOK_TEST_EVENT = "webhook.test";
40282
- const TYPES = new Set(WEBHOOK_EVENT_CATALOGUE.map((event) => event.type));
40283
- const GROUPS = new Set(WEBHOOK_EVENT_CATALOGUE.map((event) => event.group));
40282
+ const TYPES = new Set(WEBHOOK_EVENT_CATALOG.map((event) => event.type));
40283
+ const GROUPS = new Set(WEBHOOK_EVENT_CATALOG.map((event) => event.group));
40284
40284
  const isValidEventPattern = (pattern) => TYPES.has(pattern) || pattern.endsWith(".*") && GROUPS.has(pattern.slice(0, -2));
40285
40285
  const matchesEvent = (patterns, type) => patterns.some((pattern) => pattern === type || pattern.endsWith(".*") && type.startsWith(pattern.slice(0, -1)));
40286
40286
  //#endregion
@@ -40356,7 +40356,7 @@ const assertEvents = (events) => {
40356
40356
  const invalid = events.filter((event) => !isValidEventPattern(event));
40357
40357
  if (invalid.length > 0) throw new AppError(400, "INVALID_EVENTS", `Unknown events: ${invalid.join(", ")}`, { invalid });
40358
40358
  };
40359
- const listEventTypes$1 = () => WEBHOOK_EVENT_CATALOGUE;
40359
+ const listEventTypes$1 = () => WEBHOOK_EVENT_CATALOG;
40360
40360
  const listWebhooks$2 = async (runtime, site) => (await list$1(site.id, runtime.db)).map((row) => toView(runtime, row));
40361
40361
  const getWebhook$1 = async (runtime, site, id) => {
40362
40362
  const row = await findSummaryVisible(site.id, id, runtime.db);
@@ -41029,7 +41029,7 @@ const cancelSchedule$1 = async (context, id) => {
41029
41029
  if (!existing) throw scheduleNotFound(id);
41030
41030
  if (modelKey) await modelWithPolicy(context, modelKey, "publish");
41031
41031
  await context.db.transaction().execute(async (trx) => {
41032
- if (!await cancel(id, /* @__PURE__ */ new Date(), trx)) throw new AppError(409, "SCHEDULE_NOT_PENDING", "Only schedules that have not run can be cancelled", {
41032
+ if (!await cancel(id, /* @__PURE__ */ new Date(), trx)) throw new AppError(409, "SCHEDULE_NOT_PENDING", "Only schedules that have not run can be canceled", {
41033
41033
  id,
41034
41034
  status: existing.status
41035
41035
  });
@@ -41090,7 +41090,7 @@ const ScheduleStatusSchema = Type.Enum([
41090
41090
  "scheduled",
41091
41091
  "done",
41092
41092
  "failed",
41093
- "cancelled"
41093
+ "canceled"
41094
41094
  ]);
41095
41095
  const ScheduleSchema = Type.Object({
41096
41096
  id: UuidSchema,
@@ -41145,7 +41145,7 @@ const cancelScheduleSchema = {
41145
41145
  //#endregion
41146
41146
  //#region src/routes/admin/publishing/schedules/index.ts
41147
41147
  /**
41148
- * /api/admin/publishing/schedules: publish-at / unpublish-at per entry and locale. Creating and cancelling
41148
+ * /api/admin/publishing/schedules: publish-at / unpublish-at per entry and locale. Creating and canceling
41149
41149
  * need publish permission on the model (checked by the service through the evaluator); listing everything
41150
41150
  * needs `publishing.manage`, listing one entry's schedules needs read permission on its model.
41151
41151
  */
@@ -42921,7 +42921,7 @@ const openStoredBundle = (storage, stored) => storage.get(stored.driver).getStre
42921
42921
  const removeStoredBundle = (storage, stored) => storage.get(stored.driver).delete(stored.key);
42922
42922
  //#endregion
42923
42923
  //#region src/constants/version.ts
42924
- const SHAPIO_VERSION = "0.5.9";
42924
+ const SHAPIO_VERSION = "0.5.10";
42925
42925
  //#endregion
42926
42926
  //#region src/repositories/transferExport.ts
42927
42927
  /**
@@ -43612,7 +43612,7 @@ const readPayload = (payload) => {
43612
43612
  pendingChangeIds: value.pendingChangeIds ?? []
43613
43613
  };
43614
43614
  };
43615
- /** The import acts as Shapio itself: the request that started it was authorised as an instance admin. */
43615
+ /** The import acts as Shapio itself: the request that started it was authorized as an instance admin. */
43616
43616
  const SYSTEM_ACTOR = {
43617
43617
  kind: "system",
43618
43618
  component: "transfer"
@@ -43653,7 +43653,7 @@ const forEachBatch = async (run, type, handle) => {
43653
43653
  };
43654
43654
  const waitForSchema = async (run) => {
43655
43655
  const changes = await findSchemaChangeStatuses(run.payload.pendingChangeIds);
43656
- const failed = changes.find((change) => change.status === "failed" || change.status === "cancelled");
43656
+ const failed = changes.find((change) => change.status === "failed" || change.status === "canceled");
43657
43657
  if (failed) throw new PermanentJobError(`Schema change ${failed.id} failed: ${JSON.stringify(failed.error)}`);
43658
43658
  if (changes.some((change) => change.status !== "activated")) throw new Error("Waiting for the imported schema changes to activate");
43659
43659
  };
@@ -44163,7 +44163,7 @@ const putMediaFileSchema = {
44163
44163
  /**
44164
44164
  * /api/admin/transfer: content export and import (`shapio export` / `shapio import`). Bundles and media
44165
44165
  * files travel as raw streams (never buffered whole), so this scope passes those bodies through unparsed.
44166
- * The service authorises every call as an instance administrator.
44166
+ * The service authorizes every call as an instance administrator.
44167
44167
  */
44168
44168
  const adminTransferRoutes = async (app) => {
44169
44169
  declareSiteScope(app, "site");
@@ -46442,14 +46442,14 @@ const docsRoutes = async (app) => {
46442
46442
  //#endregion
46443
46443
  //#region src/db/migrations/20261001120000_create_platform_tables.ts
46444
46444
  var _20261001120000_create_platform_tables_exports = /* @__PURE__ */ __exportAll({
46445
- down: () => down$34,
46446
- up: () => up$34
46445
+ down: () => down$37,
46446
+ up: () => up$37
46447
46447
  });
46448
46448
  /**
46449
46449
  * Foundation tables shared by every package: durable versions, the job queue, the transactional outbox
46450
46450
  * and the audit log. Statuses are text with CHECK constraints so new states need only a constraint change.
46451
46451
  */
46452
- const up$34 = async (db) => {
46452
+ const up$37 = async (db) => {
46453
46453
  await db.schema.createTable("system_versions").addColumn("id", "boolean", (col) => col.primaryKey().defaultTo(true).check(sql`id`)).addColumn("schema_version", "integer", (col) => col.notNull().defaultTo(0)).addColumn("permissions_version", "integer", (col) => col.notNull().defaultTo(0)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
46454
46454
  await sql`insert into system_versions default values`.execute(db);
46455
46455
  await db.schema.createTable("jobs").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("type", "text", (col) => col.notNull()).addColumn("payload", "jsonb", (col) => col.notNull().defaultTo(sql`'{}'::jsonb`)).addColumn("status", "text", (col) => col.notNull().defaultTo("pending").check(sql`status in ('pending', 'running', 'succeeded', 'dead')`)).addColumn("priority", "integer", (col) => col.notNull().defaultTo(0)).addColumn("run_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("attempts", "integer", (col) => col.notNull().defaultTo(0)).addColumn("max_attempts", "integer", (col) => col.notNull().defaultTo(10).check(sql`max_attempts > 0`)).addColumn("idempotency_key", "text").addColumn("locked_by", "text").addColumn("locked_until", "timestamptz").addColumn("checkpoint", "jsonb").addColumn("result", "jsonb").addColumn("last_error", "text").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("finished_at", "timestamptz").execute();
@@ -46471,7 +46471,7 @@ const up$34 = async (db) => {
46471
46471
  "occurred_at desc"
46472
46472
  ]).execute();
46473
46473
  };
46474
- const down$34 = async (db) => {
46474
+ const down$37 = async (db) => {
46475
46475
  await db.schema.dropTable("audit_events").execute();
46476
46476
  await db.schema.dropTable("outbox_events").execute();
46477
46477
  await db.schema.dropTable("jobs").execute();
@@ -46480,8 +46480,8 @@ const down$34 = async (db) => {
46480
46480
  //#endregion
46481
46481
  //#region src/db/migrations/20261001130000_create_admin_identity.ts
46482
46482
  var _20261001130000_create_admin_identity_exports = /* @__PURE__ */ __exportAll({
46483
- down: () => down$33,
46484
- up: () => up$33
46483
+ down: () => down$36,
46484
+ up: () => up$36
46485
46485
  });
46486
46486
  /**
46487
46487
  * Admin identity (package B, ADR 0005): admin users, roles and their permission grants, server-side
@@ -46490,7 +46490,7 @@ var _20261001130000_create_admin_identity_exports = /* @__PURE__ */ __exportAll(
46490
46490
  */
46491
46491
  const withTimestamps$3 = (table) => table.addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`));
46492
46492
  const uuidPrimaryKey$3 = (table) => table.addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`));
46493
- const up$33 = async (db) => {
46493
+ const up$36 = async (db) => {
46494
46494
  await withTimestamps$3(uuidPrimaryKey$3(db.schema.createTable("admin_users")).addColumn("email", "text", (col) => col.notNull().unique()).addColumn("name", "text", (col) => col.notNull().defaultTo("")).addColumn("password_hash", "text", (col) => col.notNull()).addColumn("status", "text", (col) => col.notNull().defaultTo("active").check(sql`status in ('active', 'disabled')`)).addColumn("last_login_at", "timestamptz").addColumn("password_changed_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`))).execute();
46495
46495
  await withTimestamps$3(uuidPrimaryKey$3(db.schema.createTable("admin_roles")).addColumn("key", "text", (col) => col.notNull().unique().check(sql`key ~ '^[a-z][a-z0-9-]{0,62}$'`)).addColumn("name", "text", (col) => col.notNull()).addColumn("description", "text", (col) => col.notNull().defaultTo("")).addColumn("kind", "text", (col) => col.notNull().defaultTo("admin").check(sql`kind in ('admin', 'delivery')`)).addColumn("is_system", "boolean", (col) => col.notNull().defaultTo(false)).addColumn("version", "integer", (col) => col.notNull().defaultTo(1))).execute();
46496
46496
  await withTimestamps$3(uuidPrimaryKey$3(db.schema.createTable("admin_role_permissions")).addColumn("role_id", "uuid", (col) => col.notNull().references("admin_roles.id").onDelete("cascade")).addColumn("action", "text", (col) => col.notNull()).addColumn("model_id", "text").addColumn("condition", "text", (col) => col.check(sql`condition in ('ownedByPrincipal')`)).addColumn("field_ids", sql`text[]`).addUniqueConstraint("admin_role_permissions_grant_uq", [
@@ -46510,7 +46510,7 @@ const up$33 = async (db) => {
46510
46510
  await withTimestamps$3(uuidPrimaryKey$3(db.schema.createTable("api_tokens")).addColumn("name", "text", (col) => col.notNull()).addColumn("token_hash", "text", (col) => col.notNull().unique()).addColumn("token_prefix", "text", (col) => col.notNull()).addColumn("role_id", "uuid", (col) => col.notNull().references("admin_roles.id").onDelete("restrict")).addColumn("created_by", "uuid", (col) => col.references("admin_users.id").onDelete("set null")).addColumn("expires_at", "timestamptz").addColumn("last_used_at", "timestamptz").addColumn("revoked_at", "timestamptz")).execute();
46511
46511
  await db.schema.createIndex("api_tokens_role_idx").on("api_tokens").column("role_id").execute();
46512
46512
  };
46513
- const down$33 = async (db) => {
46513
+ const down$36 = async (db) => {
46514
46514
  await db.schema.dropTable("api_tokens").execute();
46515
46515
  await db.schema.dropTable("setup_tokens").execute();
46516
46516
  await db.schema.dropTable("password_resets").execute();
@@ -46524,31 +46524,31 @@ const down$33 = async (db) => {
46524
46524
  //#endregion
46525
46525
  //#region src/db/migrations/20261001130500_create_system_settings.ts
46526
46526
  var _20261001130500_create_system_settings_exports = /* @__PURE__ */ __exportAll({
46527
- down: () => down$32,
46528
- up: () => up$32
46527
+ down: () => down$35,
46528
+ up: () => up$35
46529
46529
  });
46530
46530
  /**
46531
46531
  * Instance-wide key/value settings that must survive restarts and be shared by every instance, e.g. the
46532
46532
  * generated signing secret. General purpose: later packages add keys, not tables.
46533
46533
  */
46534
- const up$32 = async (db) => {
46534
+ const up$35 = async (db) => {
46535
46535
  await db.schema.createTable("system_settings").addColumn("key", "text", (col) => col.primaryKey()).addColumn("value", "text", (col) => col.notNull()).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
46536
46536
  };
46537
- const down$32 = async (db) => {
46537
+ const down$35 = async (db) => {
46538
46538
  await db.schema.dropTable("system_settings").execute();
46539
46539
  };
46540
46540
  //#endregion
46541
46541
  //#region src/db/migrations/20261001140000_create_schema_tables.ts
46542
46542
  var _20261001140000_create_schema_tables_exports = /* @__PURE__ */ __exportAll({
46543
- down: () => down$31,
46544
- up: () => up$31
46543
+ down: () => down$34,
46544
+ up: () => up$34
46545
46545
  });
46546
46546
  /**
46547
46547
  * Schema registry (package D, ADR 0002): models and components (one table, `kind` discriminator), immutable
46548
46548
  * schema revisions, the per-model active pointer, schema change jobs, locales and schema settings.
46549
46549
  * Model definitions are data: creating or changing a model never runs DDL (CONTRIBUTING.md rule 1).
46550
46550
  */
46551
- const up$31 = async (db) => {
46551
+ const up$34 = async (db) => {
46552
46552
  await db.schema.createTable("models").addColumn("id", "uuid", (col) => col.primaryKey()).addColumn("kind", "text", (col) => col.notNull().check(sql`kind in ('collection', 'singleton', 'component')`)).addColumn("api_key", "text", (col) => col.notNull()).addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("deleted_at", "timestamptz").execute();
46553
46553
  await sql`create unique index models_api_key_uq on models (lower(api_key)) where deleted_at is null`.execute(db);
46554
46554
  await db.schema.createTable("schema_revisions").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("model_id", "uuid", (col) => col.notNull().references("models.id").onDelete("restrict")).addColumn("version", "integer", (col) => col.notNull().check(sql`version > 0`)).addColumn("definition", "jsonb", (col) => col.notNull()).addColumn("hash", "text", (col) => col.notNull()).addColumn("parent_revision_id", "uuid", (col) => col.references("schema_revisions.id")).addColumn("created_by_type", "text", (col) => col.notNull()).addColumn("created_by_id", "text").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addUniqueConstraint("schema_revisions_model_version_uq", ["model_id", "version"]).execute();
@@ -46576,7 +46576,7 @@ const up$31 = async (db) => {
46576
46576
  await db.schema.createTable("schema_settings").addColumn("id", "boolean", (col) => col.primaryKey().defaultTo(true).check(sql`id`)).addColumn("read_only", "boolean", (col) => col.notNull().defaultTo(false)).addColumn("read_only_reason", "text").addColumn("updated_by_type", "text").addColumn("updated_by_id", "text").addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
46577
46577
  await sql`insert into schema_settings default values`.execute(db);
46578
46578
  };
46579
- const down$31 = async (db) => {
46579
+ const down$34 = async (db) => {
46580
46580
  await db.schema.dropTable("schema_settings").execute();
46581
46581
  await db.schema.dropTable("locales").execute();
46582
46582
  await db.schema.dropTable("schema_change_jobs").execute();
@@ -46588,8 +46588,8 @@ const down$31 = async (db) => {
46588
46588
  //#endregion
46589
46589
  //#region src/db/migrations/20261001150000_create_content_tables.ts
46590
46590
  var _20261001150000_create_content_tables_exports = /* @__PURE__ */ __exportAll({
46591
- down: () => down$30,
46592
- up: () => up$30
46591
+ down: () => down$33,
46592
+ up: () => up$33
46593
46593
  });
46594
46594
  /**
46595
46595
  * Content storage (package E, ADR 0001): entries, immutable content revisions, mutable heads (one per
@@ -46597,7 +46597,7 @@ var _20261001150000_create_content_tables_exports = /* @__PURE__ */ __exportAll(
46597
46597
  * and the publication log behind `?snapshot=N`. User content models never get tables of their own
46598
46598
  * (CONTRIBUTING.md rule 1): their values are JSONB keyed by stable field IDs.
46599
46599
  */
46600
- const up$30 = async (db) => {
46600
+ const up$33 = async (db) => {
46601
46601
  await db.schema.createTable("entries").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("model_id", "uuid", (col) => col.notNull().references("models.id").onDelete("restrict")).addColumn("owner_app_user_id", "uuid").addColumn("created_by_admin_id", "uuid", (col) => col.references("admin_users.id").onDelete("set null")).addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("updated_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("deleted_at", "timestamptz").execute();
46602
46602
  await sql`create index entries_model_idx on entries (model_id, created_at) where deleted_at is null`.execute(db);
46603
46603
  await sql`create index entries_owner_idx on entries (owner_app_user_id) where owner_app_user_id is not null`.execute(db);
@@ -46661,7 +46661,7 @@ const up$30 = async (db) => {
46661
46661
  await sql`create unique index publication_log_open_uq on publication_log (entry_id, locale) where to_seq is null`.execute(db);
46662
46662
  await db.schema.createIndex("publication_log_model_seq_idx").on("publication_log").columns(["model_id", "from_seq"]).execute();
46663
46663
  };
46664
- const down$30 = async (db) => {
46664
+ const down$33 = async (db) => {
46665
46665
  await db.schema.dropTable("publication_log").execute();
46666
46666
  await db.schema.dropTable("publication_state").execute();
46667
46667
  await db.schema.dropTable("unique_values").execute();
@@ -46674,8 +46674,8 @@ const down$30 = async (db) => {
46674
46674
  //#endregion
46675
46675
  //#region src/db/migrations/20261001160000_create_media_tables.ts
46676
46676
  var _20261001160000_create_media_tables_exports = /* @__PURE__ */ __exportAll({
46677
- down: () => down$29,
46678
- up: () => up$29
46677
+ down: () => down$32,
46678
+ up: () => up$32
46679
46679
  });
46680
46680
  /**
46681
46681
  * Media library (package G): folders, assets, image variants, references from content and upload grants.
@@ -46686,7 +46686,7 @@ const withTimestamps$2 = (table) => table.addColumn("created_at", "timestamptz",
46686
46686
  const uuidPrimaryKey$2 = (table) => table.addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`));
46687
46687
  const STORAGE_DRIVER_CHECK = sql`storage_driver in ('local', 's3')`;
46688
46688
  const VISIBILITY_CHECK = sql`visibility in ('public', 'private')`;
46689
- const up$29 = async (db) => {
46689
+ const up$32 = async (db) => {
46690
46690
  await withTimestamps$2(uuidPrimaryKey$2(db.schema.createTable("media_folders")).addColumn("parent_id", "uuid", (col) => col.references("media_folders.id").onDelete("restrict")).addColumn("name", "text", (col) => col.notNull().check(sql`length(name) between 1 and 255`)).addColumn("created_by", "uuid", (col) => col.references("admin_users.id").onDelete("set null")).addColumn("version", "integer", (col) => col.notNull().defaultTo(1))).execute();
46691
46691
  await sql`create unique index media_folders_sibling_name_uq on media_folders
46692
46692
  (coalesce(parent_id, '00000000-0000-0000-0000-000000000000'::uuid), lower(name))`.execute(db);
@@ -46715,7 +46715,7 @@ const up$29 = async (db) => {
46715
46715
  ]).execute();
46716
46716
  await db.schema.createTable("media_upload_grants").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("asset_id", "uuid", (col) => col.notNull()).addColumn("kind", "text", (col) => col.notNull().check(sql`kind in ('create', 'replace')`)).addColumn("storage_driver", "text", (col) => col.notNull().check(STORAGE_DRIVER_CHECK)).addColumn("storage_key", "text", (col) => col.notNull().unique()).addColumn("original_filename", "text", (col) => col.notNull()).addColumn("declared_mime_type", "text", (col) => col.notNull()).addColumn("max_size_bytes", "bigint", (col) => col.notNull()).addColumn("folder_id", "uuid").addColumn("visibility", "text", (col) => col.notNull().check(VISIBILITY_CHECK)).addColumn("created_by", "uuid", (col) => col.references("admin_users.id").onDelete("set null")).addColumn("created_by_principal", "text", (col) => col.notNull()).addColumn("status", "text", (col) => col.notNull().defaultTo("pending").check(sql`status in ('pending', 'consumed', 'rejected', 'expired')`)).addColumn("expires_at", "timestamptz", (col) => col.notNull()).addColumn("consumed_at", "timestamptz").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
46717
46717
  };
46718
- const down$29 = async (db) => {
46718
+ const down$32 = async (db) => {
46719
46719
  await db.schema.dropTable("media_upload_grants").execute();
46720
46720
  await db.schema.dropTable("media_references").execute();
46721
46721
  await db.schema.dropTable("media_variants").execute();
@@ -46725,8 +46725,8 @@ const down$29 = async (db) => {
46725
46725
  //#endregion
46726
46726
  //#region src/db/migrations/20261001170000_create_publishing_tables.ts
46727
46727
  var _20261001170000_create_publishing_tables_exports = /* @__PURE__ */ __exportAll({
46728
- down: () => down$28,
46729
- up: () => up$28
46728
+ down: () => down$31,
46729
+ up: () => up$31
46730
46730
  });
46731
46731
  /**
46732
46732
  * Publishing (package H): scheduled publications, releases, webhooks and their delivery log, deployment
@@ -46765,13 +46765,13 @@ const createPreviewTables = async (db) => {
46765
46765
  await uuidPrimaryKey$1(db.schema.createTable("preview_tokens")).addColumn("token_hash", "text", (col) => col.notNull().unique()).addColumn("token_prefix", "text", (col) => col.notNull()).addColumn("model_id", "uuid", (col) => col.notNull()).addColumn("entry_id", "uuid", (col) => col.references("entries.id").onDelete("cascade")).addColumn("locale", "text").addColumn("connection_id", "uuid", (col) => col.references("deployment_connections.id").onDelete("set null")).addColumn("delivery_role_id", "uuid", (col) => col.references("admin_roles.id").onDelete("set null")).addColumn("created_by", "uuid", (col) => col.notNull().references("admin_users.id").onDelete("cascade")).addColumn("expires_at", "timestamptz", (col) => col.notNull()).addColumn("revoked_at", "timestamptz").addColumn("last_used_at", "timestamptz").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
46766
46766
  await db.schema.createIndex("preview_tokens_entry_idx").on("preview_tokens").columns(["entry_id", "created_at desc"]).execute();
46767
46767
  };
46768
- const up$28 = async (db) => {
46768
+ const up$31 = async (db) => {
46769
46769
  await createSchedulingTables(db);
46770
46770
  await createWebhookTables(db);
46771
46771
  await createDeploymentTables(db);
46772
46772
  await createPreviewTables(db);
46773
46773
  };
46774
- const down$28 = async (db) => {
46774
+ const down$31 = async (db) => {
46775
46775
  await db.schema.dropTable("preview_tokens").execute();
46776
46776
  await db.schema.dropTable("deployment_runs").execute();
46777
46777
  await db.schema.dropTable("deployment_connections").execute();
@@ -46784,8 +46784,8 @@ const down$28 = async (db) => {
46784
46784
  //#endregion
46785
46785
  //#region src/db/migrations/20261001180000_create_app_users.ts
46786
46786
  var _20261001180000_create_app_users_exports = /* @__PURE__ */ __exportAll({
46787
- down: () => down$27,
46788
- up: () => up$27
46787
+ down: () => down$30,
46788
+ up: () => up$30
46789
46789
  });
46790
46790
  /**
46791
46791
  * App users (package I, ADR 0005): the end users of sites and apps built on Shapio, with their own roles
@@ -46836,7 +46836,7 @@ const createCredentials = async (db) => {
46836
46836
  }
46837
46837
  await db.schema.createTable("app_login_codes").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("app_user_id", "uuid", (col) => col.notNull().references("app_users.id").onDelete("cascade")).addColumn("code_hash", "text", (col) => col.notNull().unique()).addColumn("expires_at", "timestamptz", (col) => col.notNull()).addColumn("used_at", "timestamptz").addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).execute();
46838
46838
  };
46839
- const up$27 = async (db) => {
46839
+ const up$30 = async (db) => {
46840
46840
  await createUsers(db);
46841
46841
  await createRoles(db);
46842
46842
  await createCredentials(db);
@@ -46846,7 +46846,7 @@ const up$27 = async (db) => {
46846
46846
  foreign key (owner_app_user_id) references app_users (id) on delete set null
46847
46847
  `.execute(db);
46848
46848
  };
46849
- const down$27 = async (db) => {
46849
+ const down$30 = async (db) => {
46850
46850
  await sql`alter table entries drop constraint if exists entries_owner_app_user_fk`.execute(db);
46851
46851
  await db.schema.dropTable("app_login_codes").execute();
46852
46852
  await db.schema.dropTable("app_password_resets").execute();
@@ -46861,8 +46861,8 @@ const down$27 = async (db) => {
46861
46861
  //#endregion
46862
46862
  //#region src/db/migrations/20261002120000_create_extension_hook_runs.ts
46863
46863
  var _20261002120000_create_extension_hook_runs_exports = /* @__PURE__ */ __exportAll({
46864
- down: () => down$26,
46865
- up: () => up$26
46864
+ down: () => down$29,
46865
+ up: () => up$29
46866
46866
  });
46867
46867
  /**
46868
46868
  * Extension points (package K, ADR 0009): the ledger of post-commit lifecycle hooks (`afterCreate`,
@@ -46870,17 +46870,17 @@ var _20261002120000_create_extension_hook_runs_exports = /* @__PURE__ */ __expor
46870
46870
  * as the hook's own database work, so a hook re-run after a worker crash finds its row and is skipped:
46871
46871
  * exactly once for everything the hook does through its transaction.
46872
46872
  */
46873
- const up$26 = async (db) => {
46873
+ const up$29 = async (db) => {
46874
46874
  await db.schema.createTable("extension_hook_runs").addColumn("event_id", "uuid", (col) => col.notNull()).addColumn("hook", "text", (col) => col.notNull()).addColumn("job_id", "uuid").addColumn("completed_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addPrimaryKeyConstraint("extension_hook_runs_pkey", ["event_id", "hook"]).execute();
46875
46875
  };
46876
- const down$26 = async (db) => {
46876
+ const down$29 = async (db) => {
46877
46877
  await db.schema.dropTable("extension_hook_runs").execute();
46878
46878
  };
46879
46879
  //#endregion
46880
46880
  //#region src/db/migrations/20261002130000_app_auth_token_version_and_login_code_pkce.ts
46881
46881
  var _20261002130000_app_auth_token_version_and_login_code_pkce_exports = /* @__PURE__ */ __exportAll({
46882
- down: () => down$25,
46883
- up: () => up$25
46882
+ down: () => down$28,
46883
+ up: () => up$28
46884
46884
  });
46885
46885
  /**
46886
46886
  * App users (ADR 0005):
@@ -46891,20 +46891,20 @@ var _20261002130000_app_auth_token_version_and_login_code_pkce_exports = /* @__P
46891
46891
  * sign-in; the one-time login code is only exchanged with the matching verifier. Codes live a minute, so
46892
46892
  * any pending ones (issued without a challenge) are dropped rather than given a placeholder.
46893
46893
  */
46894
- const up$25 = async (db) => {
46894
+ const up$28 = async (db) => {
46895
46895
  await db.schema.alterTable("app_users").addColumn("token_version", "integer", (col) => col.notNull().defaultTo(0)).execute();
46896
46896
  await sql`delete from app_login_codes`.execute(db);
46897
46897
  await db.schema.alterTable("app_login_codes").addColumn("code_challenge", "text", (col) => col.notNull()).execute();
46898
46898
  };
46899
- const down$25 = async (db) => {
46899
+ const down$28 = async (db) => {
46900
46900
  await db.schema.alterTable("app_login_codes").dropColumn("code_challenge").execute();
46901
46901
  await db.schema.alterTable("app_users").dropColumn("token_version").execute();
46902
46902
  };
46903
46903
  //#endregion
46904
46904
  //#region src/db/migrations/20261002180000_add_publication_log_diff_indexes.ts
46905
46905
  var _20261002180000_add_publication_log_diff_indexes_exports = /* @__PURE__ */ __exportAll({
46906
- down: () => down$24,
46907
- up: () => up$24
46906
+ down: () => down$27,
46907
+ up: () => up$27
46908
46908
  });
46909
46909
  /**
46910
46910
  * The snapshot diff (repositories/snapshotDiff.ts) finds the (entry, locale) pairs whose live period opened
@@ -46913,7 +46913,7 @@ var _20261002180000_add_publication_log_diff_indexes_exports = /* @__PURE__ */ _
46913
46913
  * - `(entry_id, locale, from_seq)`: "the row live at seq N" is the latest row starting at or before N.
46914
46914
  * Periods that opened in the range use the existing `(model_id, from_seq)` index.
46915
46915
  */
46916
- const up$24 = async (db) => {
46916
+ const up$27 = async (db) => {
46917
46917
  await sql`create index publication_log_to_seq_idx on publication_log (to_seq) where to_seq is not null`.execute(db);
46918
46918
  await db.schema.createIndex("publication_log_entry_locale_from_idx").on("publication_log").columns([
46919
46919
  "entry_id",
@@ -46921,15 +46921,15 @@ const up$24 = async (db) => {
46921
46921
  "from_seq"
46922
46922
  ]).execute();
46923
46923
  };
46924
- const down$24 = async (db) => {
46924
+ const down$27 = async (db) => {
46925
46925
  await db.schema.dropIndex("publication_log_entry_locale_from_idx").execute();
46926
46926
  await db.schema.dropIndex("publication_log_to_seq_idx").execute();
46927
46927
  };
46928
46928
  //#endregion
46929
46929
  //#region src/db/migrations/20261002180100_create_usage_tables.ts
46930
46930
  var _20261002180100_create_usage_tables_exports = /* @__PURE__ */ __exportAll({
46931
- down: () => down$23,
46932
- up: () => up$23
46931
+ down: () => down$26,
46932
+ up: () => up$26
46933
46933
  });
46934
46934
  /**
46935
46935
  * Field usage from delivery traffic (plan developer-face §5): daily counters written by the in-memory
@@ -46937,7 +46937,7 @@ var _20261002180100_create_usage_tables_exports = /* @__PURE__ */ __exportAll({
46937
46937
  * payloads. `principal_key` is `token:<id>`, `app_users` or `anonymous`. Pruned by the retention job
46938
46938
  * after USAGE_RETENTION_DAYS.
46939
46939
  */
46940
- const up$23 = async (db) => {
46940
+ const up$26 = async (db) => {
46941
46941
  await db.schema.createTable("field_reads").addColumn("day", "date", (col) => col.notNull()).addColumn("model_id", "uuid", (col) => col.notNull()).addColumn("field_path", "text", (col) => col.notNull()).addColumn("principal_key", "text", (col) => col.notNull()).addColumn("selection", "text", (col) => col.notNull().check(sql`selection in ('explicit', 'implicit')`)).addColumn("reads", "bigint", (col) => col.notNull().defaultTo(0)).addColumn("last_read_at", "timestamptz", (col) => col.notNull()).addPrimaryKeyConstraint("field_reads_pkey", [
46942
46942
  "day",
46943
46943
  "model_id",
@@ -46948,15 +46948,15 @@ const up$23 = async (db) => {
46948
46948
  await db.schema.createIndex("field_reads_model_day_idx").on("field_reads").columns(["model_id", "day"]).execute();
46949
46949
  await db.schema.createTable("token_reads").addColumn("day", "date", (col) => col.notNull()).addColumn("principal_key", "text", (col) => col.notNull()).addColumn("requests", "bigint", (col) => col.notNull().defaultTo(0)).addColumn("last_snapshot", "bigint").addColumn("last_read_at", "timestamptz", (col) => col.notNull()).addPrimaryKeyConstraint("token_reads_pkey", ["day", "principal_key"]).execute();
46950
46950
  };
46951
- const down$23 = async (db) => {
46951
+ const down$26 = async (db) => {
46952
46952
  await db.schema.dropTable("token_reads").execute();
46953
46953
  await db.schema.dropTable("field_reads").execute();
46954
46954
  };
46955
46955
  //#endregion
46956
46956
  //#region src/db/migrations/20261002180200_create_change_sets.ts
46957
46957
  var _20261002180200_create_change_sets_exports = /* @__PURE__ */ __exportAll({
46958
- down: () => down$22,
46959
- up: () => up$22
46958
+ down: () => down$25,
46959
+ up: () => up$25
46960
46960
  });
46961
46961
  /**
46962
46962
  * Change sets (developer-face plan §5, ADR 0010): schema drafts and entry publications that ship as ONE
@@ -47135,7 +47135,7 @@ const migrateReleases = async (db) => {
47135
47135
  await sql`drop table release_items`.execute(db);
47136
47136
  await sql`drop table releases`.execute(db);
47137
47137
  };
47138
- const up$22 = async (db) => {
47138
+ const up$25 = async (db) => {
47139
47139
  await createTables(db);
47140
47140
  await linkExecutionRecords(db);
47141
47141
  await allowConversionRevisions(db);
@@ -47207,7 +47207,7 @@ const restoreReleases = async (db) => {
47207
47207
  await sql`update webhooks set events = array_remove(array_remove(events, 'change_set.shipping'),
47208
47208
  'change_set.discarded')`.execute(db);
47209
47209
  };
47210
- const down$22 = async (db) => {
47210
+ const down$25 = async (db) => {
47211
47211
  await restoreReleases(db);
47212
47212
  await sql`alter table content_revisions drop constraint content_revisions_reason_check`.execute(db);
47213
47213
  await sql`alter table content_revisions add constraint content_revisions_reason_check
@@ -47228,8 +47228,8 @@ const down$22 = async (db) => {
47228
47228
  //#endregion
47229
47229
  //#region src/db/migrations/20261002190000_create_editor_presence_and_content_health.ts
47230
47230
  var _20261002190000_create_editor_presence_and_content_health_exports = /* @__PURE__ */ __exportAll({
47231
- down: () => down$21,
47232
- up: () => up$21
47231
+ down: () => down$24,
47232
+ up: () => up$24
47233
47233
  });
47234
47234
  /**
47235
47235
  * Editor experience (plan editor-experience §9):
@@ -47240,7 +47240,7 @@ var _20261002190000_create_editor_presence_and_content_health_exports = /* @__PU
47240
47240
  * - `content_health_findings`: open and recently resolved findings of the health rules per entry and
47241
47241
  * locale (`*` for the entry as a whole). An evaluation upserts what it found and resolves the rest.
47242
47242
  */
47243
- const up$21 = async (db) => {
47243
+ const up$24 = async (db) => {
47244
47244
  await sql`
47245
47245
  create unlogged table editor_presence (
47246
47246
  entry_id uuid not null,
@@ -47277,15 +47277,15 @@ const up$21 = async (db) => {
47277
47277
  await sql`create index content_health_findings_resolved_idx on content_health_findings (resolved_at)
47278
47278
  where resolved_at is not null`.execute(db);
47279
47279
  };
47280
- const down$21 = async (db) => {
47280
+ const down$24 = async (db) => {
47281
47281
  await sql`drop table content_health_findings`.execute(db);
47282
47282
  await sql`drop table editor_presence`.execute(db);
47283
47283
  };
47284
47284
  //#endregion
47285
47285
  //#region src/db/migrations/20261003120000_add_changes_ship_permission.ts
47286
47286
  var _20261003120000_add_changes_ship_permission_exports = /* @__PURE__ */ __exportAll({
47287
- down: () => down$20,
47288
- up: () => up$20
47287
+ down: () => down$23,
47288
+ up: () => up$23
47289
47289
  });
47290
47290
  /**
47291
47291
  * `changes.ship` (agentic plan §I): shipping a change set (and scheduling a ship) becomes its own global
@@ -47293,7 +47293,7 @@ var _20261003120000_add_changes_ship_permission_exports = /* @__PURE__ */ __expo
47293
47293
  * live. Every role that holds `changes.manage` today keeps what it could do: it gets `changes.ship` too.
47294
47294
  * The permissions version moves only when grants changed, so running instances reload exactly then.
47295
47295
  */
47296
- const up$20 = async (db) => {
47296
+ const up$23 = async (db) => {
47297
47297
  await sql`
47298
47298
  with granted as (
47299
47299
  insert into admin_role_permissions (role_id, action, model_id, condition, field_ids)
@@ -47307,7 +47307,7 @@ const up$20 = async (db) => {
47307
47307
  where exists (select 1 from granted)
47308
47308
  `.execute(db);
47309
47309
  };
47310
- const down$20 = async (db) => {
47310
+ const down$23 = async (db) => {
47311
47311
  await sql`
47312
47312
  with revoked as (
47313
47313
  delete from admin_role_permissions where action = 'changes.ship' returning 1
@@ -47319,8 +47319,8 @@ const down$20 = async (db) => {
47319
47319
  //#endregion
47320
47320
  //#region src/db/migrations/20261003130000_create_sites.ts
47321
47321
  var _20261003130000_create_sites_exports = /* @__PURE__ */ __exportAll({
47322
- down: () => down$19,
47323
- up: () => up$19
47322
+ down: () => down$22,
47323
+ up: () => up$22
47324
47324
  });
47325
47325
  /**
47326
47326
  * Sites (plan agentic-ecosystem §H, ADR 0011): one instance hosts many sites with one schema and one login.
@@ -47508,7 +47508,7 @@ const siteRoleAssignments = async (db) => {
47508
47508
  `.execute(db);
47509
47509
  await sql`alter table admin_invitations drop column role_ids`.execute(db);
47510
47510
  };
47511
- const up$19 = async (db) => {
47511
+ const up$22 = async (db) => {
47512
47512
  await createSites(db);
47513
47513
  await addSiteColumns(db);
47514
47514
  await tieCopiesToEntries(db);
@@ -47521,7 +47521,7 @@ const assertSingleSite = async (db) => {
47521
47521
  const { rows } = await sql`select count(*)::text as count from sites`.execute(db);
47522
47522
  if (Number(rows[0]?.count ?? 0) > 1) throw new Error("Cannot roll back sites while more than one site exists: merging them would merge their snapshot ledgers and uniqueness and widen role assignments. Delete the other sites first.");
47523
47523
  };
47524
- const down$19 = async (db) => {
47524
+ const down$22 = async (db) => {
47525
47525
  await assertSingleSite(db);
47526
47526
  await sql`alter table admin_invitations add column role_ids uuid[] not null default '{}'::uuid[]`.execute(db);
47527
47527
  await sql`
@@ -47592,8 +47592,8 @@ const down$19 = async (db) => {
47592
47592
  //#endregion
47593
47593
  //#region src/db/migrations/20261003140200_enqueue_field_index_layout.ts
47594
47594
  var _20261003140200_enqueue_field_index_layout_exports = /* @__PURE__ */ __exportAll({
47595
- down: () => down$18,
47596
- up: () => up$18
47595
+ down: () => down$21,
47596
+ up: () => up$21
47597
47597
  });
47598
47598
  /**
47599
47599
  * Field index layout v2 (sites plan §H): per-field expression indexes on `entry_heads` lead with `site_id`,
@@ -47605,7 +47605,7 @@ var _20261003140200_enqueue_field_index_layout_exports = /* @__PURE__ */ __expor
47605
47605
  */
47606
47606
  const JOB_TYPE$1 = "schema.fieldIndexLayout";
47607
47607
  const IDEMPOTENCY_KEY$1 = "schema.fieldIndexLayout:v2";
47608
- const up$18 = async (db) => {
47608
+ const up$21 = async (db) => {
47609
47609
  await sql`
47610
47610
  insert into jobs (type, payload, max_attempts, idempotency_key)
47611
47611
  select ${JOB_TYPE$1}, '{}'::jsonb, 5, ${IDEMPOTENCY_KEY$1}
@@ -47618,14 +47618,14 @@ const up$18 = async (db) => {
47618
47618
  `.execute(db);
47619
47619
  };
47620
47620
  /** The layout job is idempotent; rolling back only forgets it if it has not run yet. */
47621
- const down$18 = async (db) => {
47621
+ const down$21 = async (db) => {
47622
47622
  await sql`delete from jobs where idempotency_key = ${IDEMPOTENCY_KEY$1} and status = 'pending'`.execute(db);
47623
47623
  };
47624
47624
  //#endregion
47625
47625
  //#region src/db/migrations/20261003140500_change_set_items_site_and_preview_entry.ts
47626
47626
  var _20261003140500_change_set_items_site_and_preview_entry_exports = /* @__PURE__ */ __exportAll({
47627
- down: () => down$17,
47628
- up: () => up$17
47627
+ down: () => down$20,
47628
+ up: () => up$20
47629
47629
  });
47630
47630
  /**
47631
47631
  * Sites, publishing (plan agentic-ecosystem §H, package G5).
@@ -47636,7 +47636,7 @@ var _20261003140500_change_set_items_site_and_preview_entry_exports = /* @__PURE
47636
47636
  * - `preview_tokens.entry_id` becomes required: a preview token previews one entry of one site. Model-wide
47637
47637
  * tokens (short-lived by design) are deleted; whoever needs one opens the entry's preview again.
47638
47638
  */
47639
- const up$17 = async (db) => {
47639
+ const up$20 = async (db) => {
47640
47640
  await sql`alter table change_sets add constraint change_sets_id_site_uq unique (id, site_id)`.execute(db);
47641
47641
  await sql`alter table change_set_items add column site_id uuid`.execute(db);
47642
47642
  await sql`
@@ -47652,7 +47652,7 @@ const up$17 = async (db) => {
47652
47652
  await sql`delete from preview_tokens where entry_id is null`.execute(db);
47653
47653
  await sql`alter table preview_tokens alter column entry_id set not null`.execute(db);
47654
47654
  };
47655
- const down$17 = async (db) => {
47655
+ const down$20 = async (db) => {
47656
47656
  await sql`alter table preview_tokens alter column entry_id drop not null`.execute(db);
47657
47657
  await sql`alter table change_set_items drop constraint change_set_items_entry_site_fk`.execute(db);
47658
47658
  await sql`alter table change_set_items drop constraint change_set_items_set_site_fk`.execute(db);
@@ -47662,8 +47662,8 @@ const down$17 = async (db) => {
47662
47662
  //#endregion
47663
47663
  //#region src/db/migrations/20261003150000_widen_deployment_providers.ts
47664
47664
  var _20261003150000_widen_deployment_providers_exports = /* @__PURE__ */ __exportAll({
47665
- down: () => down$16,
47666
- up: () => up$16
47665
+ down: () => down$19,
47666
+ up: () => up$19
47667
47667
  });
47668
47668
  /**
47669
47669
  * Deploy adapters (plan agentic-ecosystem §B2): deployment connections may use the Vercel and Netlify
@@ -47678,11 +47678,11 @@ const replaceCheck = async (db, check) => {
47678
47678
  check (${check}) not valid`.execute(db);
47679
47679
  await sql`alter table deployment_connections validate constraint deployment_connections_provider_check`.execute(db);
47680
47680
  };
47681
- const up$16 = async (db) => {
47681
+ const up$19 = async (db) => {
47682
47682
  await replaceCheck(db, WIDENED);
47683
47683
  };
47684
47684
  /** Refuses while Vercel or Netlify connections exist: a down migration never deletes user data. */
47685
- const down$16 = async (db) => {
47685
+ const down$19 = async (db) => {
47686
47686
  const { rows } = await sql`
47687
47687
  select count(*)::text as count from deployment_connections where provider in ('vercel', 'netlify')
47688
47688
  `.execute(db);
@@ -47693,8 +47693,8 @@ const down$16 = async (db) => {
47693
47693
  //#endregion
47694
47694
  //#region src/db/migrations/20261003160000_create_assist_runs.ts
47695
47695
  var _20261003160000_create_assist_runs_exports = /* @__PURE__ */ __exportAll({
47696
- down: () => down$15,
47697
- up: () => up$15
47696
+ down: () => down$18,
47697
+ up: () => up$18
47698
47698
  });
47699
47699
  /**
47700
47700
  * Editor assists (plan agentic-ecosystem §A0, §I): one `assist_runs` row per assist request (who, which
@@ -47710,14 +47710,14 @@ const replaceSourceCheck = async (db, check) => {
47710
47710
  await sql`alter table change_sets add constraint change_sets_source_check check (${check}) not valid`.execute(db);
47711
47711
  await sql`alter table change_sets validate constraint change_sets_source_check`.execute(db);
47712
47712
  };
47713
- const up$15 = async (db) => {
47713
+ const up$18 = async (db) => {
47714
47714
  await db.schema.createTable("assist_runs").addColumn("id", "uuid", (col) => col.primaryKey().defaultTo(sql`gen_random_uuid()`)).addColumn("site_id", "uuid", (col) => col.notNull().references("sites.id").onDelete("cascade")).addColumn("actor_type", "text", (col) => col.notNull()).addColumn("actor_id", "text", (col) => col.notNull()).addColumn("action", "text", (col) => col.notNull().check(ACTIONS)).addColumn("rule", "text").addColumn("provider", "text", (col) => col.notNull()).addColumn("model", "text", (col) => col.notNull()).addColumn("input_tokens", "integer", (col) => col.notNull().defaultTo(0)).addColumn("output_tokens", "integer", (col) => col.notNull().defaultTo(0)).addColumn("duration_ms", "integer", (col) => col.notNull().defaultTo(0)).addColumn("status", "text", (col) => col.notNull().check(sql`status in ('queued', 'running', 'succeeded', 'failed')`)).addColumn("error_code", "text").addColumn("job_id", "uuid", (col) => col.references("jobs.id").onDelete("set null")).addColumn("created_at", "timestamptz", (col) => col.notNull().defaultTo(sql`now()`)).addColumn("finished_at", "timestamptz").execute();
47715
47715
  await db.schema.createIndex("assist_runs_site_created_idx").on("assist_runs").columns(["site_id", "created_at"]).execute();
47716
47716
  await db.schema.createIndex("assist_runs_created_idx").on("assist_runs").column("created_at").execute();
47717
47717
  await replaceSourceCheck(db, SOURCES_WIDENED);
47718
47718
  };
47719
47719
  /** Refuses while change sets opened by assist exist: a down migration never deletes user data. */
47720
- const down$15 = async (db) => {
47720
+ const down$18 = async (db) => {
47721
47721
  const { rows } = await sql`
47722
47722
  select count(*)::text as count from change_sets where source = 'assist'
47723
47723
  `.execute(db);
@@ -47729,8 +47729,8 @@ const down$15 = async (db) => {
47729
47729
  //#endregion
47730
47730
  //#region src/db/migrations/20261003170000_audit_events_seq.ts
47731
47731
  var _20261003170000_audit_events_seq_exports$2 = /* @__PURE__ */ __exportAll({
47732
- down: () => down$14,
47733
- up: () => up$14
47732
+ down: () => down$17,
47733
+ up: () => up$17
47734
47734
  });
47735
47735
  /**
47736
47736
  * `audit_events.seq`: a monotonic tiebreaker after `occurred_at`, so events written in the same instant (one
@@ -47739,17 +47739,17 @@ var _20261003170000_audit_events_seq_exports$2 = /* @__PURE__ */ __exportAll({
47739
47739
  * are numbered in the order the rewrite reads them. No index: the audit queries filter and sort by
47740
47740
  * `occurred_at` first, and `seq` only breaks ties.
47741
47741
  */
47742
- const up$14 = async (db) => {
47742
+ const up$17 = async (db) => {
47743
47743
  await db.schema.alterTable("audit_events").addColumn("seq", "bigint", (col) => col.notNull().generatedAlwaysAsIdentity()).execute();
47744
47744
  };
47745
- const down$14 = async (db) => {
47745
+ const down$17 = async (db) => {
47746
47746
  await db.schema.alterTable("audit_events").dropColumn("seq").execute();
47747
47747
  };
47748
47748
  //#endregion
47749
47749
  //#region src/db/migrations/20261004120000_models_site_scope.ts
47750
47750
  var _20261004120000_models_site_scope_exports$2 = /* @__PURE__ */ __exportAll({
47751
- down: () => down$13,
47752
- up: () => up$13
47751
+ down: () => down$16,
47752
+ up: () => up$16
47753
47753
  });
47754
47754
  /**
47755
47755
  * Per-site schema (plan site-schema): a definition belongs to one site (`models.site_id`) or is shared by every
@@ -47762,7 +47762,7 @@ var _20261004120000_models_site_scope_exports$2 = /* @__PURE__ */ __exportAll({
47762
47762
  * over `lower(api_key)` cannot hold. Share or delete them first; then `down` is lossless.
47763
47763
  */
47764
47764
  const NIL_UUID$1 = "00000000-0000-0000-0000-000000000000";
47765
- const up$13 = async (db) => {
47765
+ const up$16 = async (db) => {
47766
47766
  await sql`alter table models add column site_id uuid references sites (id)`.execute(db);
47767
47767
  await sql`create index models_site_idx on models (site_id)`.execute(db);
47768
47768
  await sql`drop index models_api_key_uq`.execute(db);
@@ -47772,7 +47772,7 @@ const up$13 = async (db) => {
47772
47772
  `.execute(db);
47773
47773
  await sql`alter table schema_drafts add column shared boolean not null default false`.execute(db);
47774
47774
  };
47775
- const down$13 = async (db) => {
47775
+ const down$16 = async (db) => {
47776
47776
  const { rows } = await sql`select count(*)::text as count from models where site_id is not null`.execute(db);
47777
47777
  if (Number(rows[0]?.count ?? 0) > 0) throw new Error("Cannot roll back per-site schema while definitions belong to a site: two sites may share an API ID. Share or delete the site definitions first.");
47778
47778
  await sql`alter table schema_drafts drop column shared`.execute(db);
@@ -47784,8 +47784,8 @@ const down$13 = async (db) => {
47784
47784
  //#endregion
47785
47785
  //#region src/db/migrations/20261004130000_site_seo_settings.ts
47786
47786
  var _20261004130000_site_seo_settings_exports$2 = /* @__PURE__ */ __exportAll({
47787
- down: () => down$12,
47788
- up: () => up$12
47787
+ down: () => down$15,
47788
+ up: () => up$15
47789
47789
  });
47790
47790
  /**
47791
47791
  * SEO defaults per site (plan seo-fields): `sites.seo_defaults` holds the site's default texts per locale, its
@@ -47796,7 +47796,7 @@ var _20261004130000_site_seo_settings_exports$2 = /* @__PURE__ */ __exportAll({
47796
47796
  * about what a site publishes) gets it; the built-in owner and admin roles get it from `ensureSystemRoles`.
47797
47797
  * The permissions version moves only when grants changed, so running instances reload exactly then.
47798
47798
  */
47799
- const up$12 = async (db) => {
47799
+ const up$15 = async (db) => {
47800
47800
  await sql`alter table sites add column seo_defaults jsonb`.execute(db);
47801
47801
  await sql`
47802
47802
  with granted as (
@@ -47811,7 +47811,7 @@ const up$12 = async (db) => {
47811
47811
  where exists (select 1 from granted)
47812
47812
  `.execute(db);
47813
47813
  };
47814
- const down$12 = async (db) => {
47814
+ const down$15 = async (db) => {
47815
47815
  await sql`
47816
47816
  with revoked as (
47817
47817
  delete from admin_role_permissions where action = 'site.settings' returning 1
@@ -47824,8 +47824,8 @@ const down$12 = async (db) => {
47824
47824
  //#endregion
47825
47825
  //#region src/db/migrations/20261005120000_entry_heads_entry_created_at.ts
47826
47826
  var _20261005120000_entry_heads_entry_created_at_exports$2 = /* @__PURE__ */ __exportAll({
47827
- down: () => down$11,
47828
- up: () => up$11
47827
+ down: () => down$14,
47828
+ up: () => up$14
47829
47829
  });
47830
47830
  /**
47831
47831
  * Delivery perf 2 (ADR 0001 amendment): the entry's `created_at` on each head (`entry_created_at`), so a list
@@ -47842,7 +47842,7 @@ const INDEX$2 = "entry_heads_entry_order_idx";
47842
47842
  const JOB_TYPE = "schema.entryOrderIndex";
47843
47843
  const IDEMPOTENCY_KEY = "schema.entryOrderIndex:v1";
47844
47844
  const BATCH$1 = 5e3;
47845
- const up$11 = async (db) => {
47845
+ const up$14 = async (db) => {
47846
47846
  await sql`alter table entry_heads add column entry_created_at timestamptz`.execute(db);
47847
47847
  for (;;) {
47848
47848
  const result = await sql`
@@ -47867,7 +47867,7 @@ const up$11 = async (db) => {
47867
47867
  create index ${sql.id(INDEX$2)} on entry_heads (site_id, model_id, state, entry_created_at desc, entry_id)
47868
47868
  `.execute(db);
47869
47869
  };
47870
- const down$11 = async (db) => {
47870
+ const down$14 = async (db) => {
47871
47871
  await sql`delete from jobs where idempotency_key = ${IDEMPOTENCY_KEY} and status = 'pending'`.execute(db);
47872
47872
  await sql`drop index if exists ${sql.id(INDEX$2)}`.execute(db);
47873
47873
  await sql`alter table entry_heads drop column entry_created_at`.execute(db);
@@ -47876,20 +47876,58 @@ const down$11 = async (db) => {
47876
47876
  //#region src/db/migrations/20261006120000_system_versions_release.ts
47877
47877
  var _20261006120000_system_versions_release_exports = /* @__PURE__ */ __exportAll({
47878
47878
  dialectNeutral: () => true,
47879
- down: () => down$10,
47880
- up: () => up$10
47879
+ down: () => down$13,
47880
+ up: () => up$13
47881
47881
  });
47882
- const up$10 = async (db) => {
47882
+ const up$13 = async (db) => {
47883
47883
  await db.schema.alterTable("system_versions").addColumn("release", "text").execute();
47884
47884
  };
47885
- const down$10 = async (db) => {
47885
+ const down$13 = async (db) => {
47886
47886
  await db.schema.alterTable("system_versions").dropColumn("release").execute();
47887
47887
  };
47888
47888
  //#endregion
47889
+ //#region src/db/migrations/20261014120000_canceled_status.ts
47890
+ var _20261014120000_canceled_status_exports$2 = /* @__PURE__ */ __exportAll({
47891
+ down: () => down$12,
47892
+ up: () => up$12
47893
+ });
47894
+ /**
47895
+ * The `cancelled` status of schema change jobs and scheduled publications becomes `canceled`. Rows are
47896
+ * rewritten and the check constraints swapped. MySQL has its own twin; SQLite rebuilds the two tables
47897
+ * (`./sqlite/20261014120000_canceled_status.ts`).
47898
+ */
47899
+ const TABLES$4 = [{
47900
+ table: "schema_change_jobs",
47901
+ values: [
47902
+ "pending",
47903
+ "running",
47904
+ "activated",
47905
+ "failed"
47906
+ ]
47907
+ }, {
47908
+ table: "scheduled_publications",
47909
+ values: [
47910
+ "scheduled",
47911
+ "done",
47912
+ "failed"
47913
+ ]
47914
+ }];
47915
+ const swap$1 = async (db, from, to) => {
47916
+ for (const { table, values } of TABLES$4) {
47917
+ const constraint = `${table}_status_check`;
47918
+ await sql`alter table ${sql.table(table)} drop constraint ${sql.id(constraint)}`.execute(db);
47919
+ await sql`update ${sql.table(table)} set status = ${to} where status = ${from}`.execute(db);
47920
+ const allowed = sql.join([...values, to].map((value) => sql.lit(value)));
47921
+ await sql`alter table ${sql.table(table)} add constraint ${sql.id(constraint)} check (status in (${allowed}))`.execute(db);
47922
+ }
47923
+ };
47924
+ const up$12 = (db) => swap$1(db, "cancelled", "canceled");
47925
+ const down$12 = (db) => swap$1(db, "canceled", "cancelled");
47926
+ //#endregion
47889
47927
  //#region src/db/migrations/mysql/0001_baseline.ts
47890
47928
  var _0001_baseline_exports$1 = /* @__PURE__ */ __exportAll({
47891
- down: () => down$9,
47892
- up: () => up$9
47929
+ down: () => down$11,
47930
+ up: () => up$11
47893
47931
  });
47894
47932
  /**
47895
47933
  * MySQL baseline: Shapio's whole system schema as of PostgreSQL migration
@@ -48999,7 +49037,7 @@ const STATEMENTS$1 = [
48999
49037
  ('00000000-0000-4000-b000-000000000001', 'public', '00000000-0000-4000-a000-000000000001'),
49000
49038
  ('00000000-0000-4000-b000-000000000001', 'authenticated', '00000000-0000-4000-a000-000000000002')`
49001
49039
  ];
49002
- const TABLES$1 = [
49040
+ const TABLES$3 = [
49003
49041
  "system_versions",
49004
49042
  "jobs",
49005
49043
  "outbox_events",
@@ -49072,13 +49110,13 @@ const withoutForeignKeyChecks = async (db, statements) => db.connection().execut
49072
49110
  await sql`set foreign_key_checks = 1`.execute(connection);
49073
49111
  }
49074
49112
  });
49075
- const up$9 = async (db) => withoutForeignKeyChecks(db, STATEMENTS$1);
49076
- const down$9 = async (db) => withoutForeignKeyChecks(db, [...TABLES$1].reverse().map((table) => `drop table if exists \`${table}\``));
49113
+ const up$11 = async (db) => withoutForeignKeyChecks(db, STATEMENTS$1);
49114
+ const down$11 = async (db) => withoutForeignKeyChecks(db, [...TABLES$3].reverse().map((table) => `drop table if exists \`${table}\``));
49077
49115
  //#endregion
49078
49116
  //#region src/db/migrations/mysql/20261003170000_audit_events_seq.ts
49079
49117
  var _20261003170000_audit_events_seq_exports$1 = /* @__PURE__ */ __exportAll({
49080
- down: () => down$8,
49081
- up: () => up$8
49118
+ down: () => down$10,
49119
+ up: () => up$10
49082
49120
  });
49083
49121
  /**
49084
49122
  * MySQL twin of `../20261003170000_audit_events_seq.ts`: `seq` is `AUTO_INCREMENT`, which InnoDB only allows
@@ -49086,26 +49124,26 @@ var _20261003170000_audit_events_seq_exports$1 = /* @__PURE__ */ __exportAll({
49086
49124
  * tiebreaker). Existing rows are numbered in primary-key order. `db/mysql/tables.ts` lists `seq` as the
49087
49125
  * table's identity, so an insert's emulated RETURNING finds its row by `LAST_INSERT_ID()`.
49088
49126
  */
49089
- const up$8 = async (db) => {
49127
+ const up$10 = async (db) => {
49090
49128
  await sql`alter table \`audit_events\`
49091
49129
  add column \`seq\` bigint not null auto_increment,
49092
49130
  add unique key \`audit_events_seq_key\` (\`seq\`)`.execute(db);
49093
49131
  };
49094
- const down$8 = async (db) => {
49132
+ const down$10 = async (db) => {
49095
49133
  await sql`alter table \`audit_events\` drop column \`seq\``.execute(db);
49096
49134
  };
49097
49135
  //#endregion
49098
49136
  //#region src/db/migrations/mysql/20261004120000_models_site_scope.ts
49099
49137
  var _20261004120000_models_site_scope_exports$1 = /* @__PURE__ */ __exportAll({
49100
- down: () => down$7,
49101
- up: () => up$7
49138
+ down: () => down$9,
49139
+ up: () => up$9
49102
49140
  });
49103
49141
  /**
49104
49142
  * MySQL twin of `../20261004120000_models_site_scope.ts`. The per-scope API ID key uses functional key parts,
49105
49143
  * like the baseline: `coalesce(site_id, '')` for the scope (MySQL has no `NULLS NOT DISTINCT`) and the
49106
49144
  * case-folded API ID of live rows only (a deleted row's part is NULL, and NULLs never collide).
49107
49145
  */
49108
- const up$7 = async (db) => {
49146
+ const up$9 = async (db) => {
49109
49147
  await sql`alter table \`models\` add column \`site_id\` char(36) character set ascii collate ascii_general_ci`.execute(db);
49110
49148
  await sql`create index \`models_site_idx\` on \`models\` (\`site_id\`)`.execute(db);
49111
49149
  await sql`alter table \`models\` add constraint \`models_site_id_fkey\` foreign key (\`site_id\`) references \`sites\` (\`id\`)`.execute(db);
@@ -49114,7 +49152,7 @@ const up$7 = async (db) => {
49114
49152
  ((coalesce(\`site_id\`, '')), (case when (\`deleted_at\` IS NULL) then lower(\`api_key\`) end))`.execute(db);
49115
49153
  await sql`alter table \`schema_drafts\` add column \`shared\` tinyint(1) not null default 0`.execute(db);
49116
49154
  };
49117
- const down$7 = async (db) => {
49155
+ const down$9 = async (db) => {
49118
49156
  const { rows } = await sql`select count(*) as count from \`models\` where \`site_id\` is not null`.execute(db);
49119
49157
  if (Number(rows[0]?.count ?? 0) > 0) throw new Error("Cannot roll back per-site schema while definitions belong to a site: two sites may share an API ID. Share or delete the site definitions first.");
49120
49158
  await sql`alter table \`schema_drafts\` drop column \`shared\``.execute(db);
@@ -49128,8 +49166,8 @@ const down$7 = async (db) => {
49128
49166
  //#endregion
49129
49167
  //#region src/db/migrations/mysql/20261004130000_site_seo_settings.ts
49130
49168
  var _20261004130000_site_seo_settings_exports$1 = /* @__PURE__ */ __exportAll({
49131
- down: () => down$6,
49132
- up: () => up$6
49169
+ down: () => down$8,
49170
+ up: () => up$8
49133
49171
  });
49134
49172
  /**
49135
49173
  * MySQL twin of `../20261004130000_site_seo_settings.ts`. `insert ignore` stands in for `on conflict do
@@ -49137,7 +49175,7 @@ var _20261004130000_site_seo_settings_exports$1 = /* @__PURE__ */ __exportAll({
49137
49175
  */
49138
49176
  const bumpPermissionsVersion$1 = (db) => sql`update \`system_versions\` set \`permissions_version\` = \`permissions_version\` + 1,
49139
49177
  \`updated_at\` = current_timestamp(6)`.execute(db);
49140
- const up$6 = async (db) => {
49178
+ const up$8 = async (db) => {
49141
49179
  await sql`alter table \`sites\` add column \`seo_defaults\` json`.execute(db);
49142
49180
  const granted = await sql`
49143
49181
  insert ignore into \`admin_role_permissions\` (\`id\`, \`role_id\`, \`action\`, \`model_id\`, \`condition\`, \`field_ids\`)
@@ -49147,7 +49185,7 @@ const up$6 = async (db) => {
49147
49185
  `.execute(db);
49148
49186
  if (Number(granted.numAffectedRows ?? 0) > 0) await bumpPermissionsVersion$1(db);
49149
49187
  };
49150
- const down$6 = async (db) => {
49188
+ const down$8 = async (db) => {
49151
49189
  const revoked = await sql`delete from \`admin_role_permissions\` where \`action\` = 'site.settings'`.execute(db);
49152
49190
  if (Number(revoked.numAffectedRows ?? 0) > 0) await bumpPermissionsVersion$1(db);
49153
49191
  await sql`alter table \`sites\` drop column \`seo_defaults\``.execute(db);
@@ -49155,8 +49193,8 @@ const down$6 = async (db) => {
49155
49193
  //#endregion
49156
49194
  //#region src/db/migrations/mysql/20261005120000_entry_heads_entry_created_at.ts
49157
49195
  var _20261005120000_entry_heads_entry_created_at_exports$1 = /* @__PURE__ */ __exportAll({
49158
- down: () => down$5,
49159
- up: () => up$5
49196
+ down: () => down$7,
49197
+ up: () => up$7
49160
49198
  });
49161
49199
  /**
49162
49200
  * MySQL twin of `../20261005120000_entry_heads_entry_created_at.ts`. The column is added `ALGORITHM=INSTANT`
@@ -49165,7 +49203,7 @@ var _20261005120000_entry_heads_entry_created_at_exports$1 = /* @__PURE__ */ __e
49165
49203
  */
49166
49204
  const INDEX$1 = "entry_heads_entry_order_idx";
49167
49205
  const BATCH = 5e3;
49168
- const up$5 = async (db) => {
49206
+ const up$7 = async (db) => {
49169
49207
  await sql`alter table \`entry_heads\` add column \`entry_created_at\` datetime(6), algorithm=instant`.execute(db);
49170
49208
  for (;;) {
49171
49209
  const result = await sql`update \`entry_heads\` set \`entry_created_at\` = (
@@ -49176,11 +49214,48 @@ const up$5 = async (db) => {
49176
49214
  await sql`create index ${sql.id(INDEX$1)} on \`entry_heads\`
49177
49215
  (\`site_id\`, \`model_id\`, \`state\`, \`entry_created_at\` desc, \`entry_id\`) algorithm=inplace lock=none`.execute(db);
49178
49216
  };
49179
- const down$5 = async (db) => {
49217
+ const down$7 = async (db) => {
49180
49218
  await sql`drop index ${sql.id(INDEX$1)} on \`entry_heads\``.execute(db);
49181
49219
  await sql`alter table \`entry_heads\` drop column \`entry_created_at\``.execute(db);
49182
49220
  };
49183
49221
  //#endregion
49222
+ //#region src/db/migrations/mysql/20261014120000_canceled_status.ts
49223
+ var _20261014120000_canceled_status_exports$1 = /* @__PURE__ */ __exportAll({
49224
+ down: () => down$6,
49225
+ up: () => up$6
49226
+ });
49227
+ /**
49228
+ * MySQL twin of `../20261014120000_canceled_status.ts`: MySQL 8.4 drops a check constraint with
49229
+ * `drop check`, not `drop constraint`.
49230
+ */
49231
+ const TABLES$2 = [{
49232
+ table: "schema_change_jobs",
49233
+ values: [
49234
+ "pending",
49235
+ "running",
49236
+ "activated",
49237
+ "failed"
49238
+ ]
49239
+ }, {
49240
+ table: "scheduled_publications",
49241
+ values: [
49242
+ "scheduled",
49243
+ "done",
49244
+ "failed"
49245
+ ]
49246
+ }];
49247
+ const swap = async (db, from, to) => {
49248
+ for (const { table, values } of TABLES$2) {
49249
+ const constraint = `${table}_status_check`;
49250
+ await sql`alter table ${sql.table(table)} drop check ${sql.id(constraint)}`.execute(db);
49251
+ await sql`update ${sql.table(table)} set status = ${to} where status = ${from}`.execute(db);
49252
+ const allowed = sql.join([...values, to].map((value) => sql.lit(value)));
49253
+ await sql`alter table ${sql.table(table)} add constraint ${sql.id(constraint)} check (status in (${allowed}))`.execute(db);
49254
+ }
49255
+ };
49256
+ const up$6 = (db) => swap(db, "cancelled", "canceled");
49257
+ const down$6 = (db) => swap(db, "canceled", "cancelled");
49258
+ //#endregion
49184
49259
  //#region src/db/migrations/mysql/index.ts
49185
49260
  const MYSQL_MIGRATIONS = {
49186
49261
  "0001_baseline": _0001_baseline_exports$1,
@@ -49188,13 +49263,14 @@ const MYSQL_MIGRATIONS = {
49188
49263
  "20261004120000_models_site_scope": _20261004120000_models_site_scope_exports$1,
49189
49264
  "20261004130000_site_seo_settings": _20261004130000_site_seo_settings_exports$1,
49190
49265
  "20261005120000_entry_heads_entry_created_at": _20261005120000_entry_heads_entry_created_at_exports$1,
49191
- "20261006120000_system_versions_release": _20261006120000_system_versions_release_exports
49266
+ "20261006120000_system_versions_release": _20261006120000_system_versions_release_exports,
49267
+ "20261014120000_canceled_status": _20261014120000_canceled_status_exports$1
49192
49268
  };
49193
49269
  //#endregion
49194
49270
  //#region src/db/migrations/sqlite/0001_baseline.ts
49195
49271
  var _0001_baseline_exports = /* @__PURE__ */ __exportAll({
49196
- down: () => down$4,
49197
- up: () => up$4
49272
+ down: () => down$5,
49273
+ up: () => up$5
49198
49274
  });
49199
49275
  /**
49200
49276
  * SQLite baseline: Shapio's whole system schema as of PostgreSQL migration
@@ -50277,7 +50353,7 @@ const STATEMENTS = [
50277
50353
  ('00000000-0000-4000-b000-000000000001', 'public', '00000000-0000-4000-a000-000000000001'),
50278
50354
  ('00000000-0000-4000-b000-000000000001', 'authenticated', '00000000-0000-4000-a000-000000000002')`
50279
50355
  ];
50280
- const TABLES = [
50356
+ const TABLES$1 = [
50281
50357
  "system_versions",
50282
50358
  "jobs",
50283
50359
  "outbox_events",
@@ -50339,18 +50415,18 @@ const TABLES = [
50339
50415
  "assist_runs",
50340
50416
  "sequences"
50341
50417
  ];
50342
- const up$4 = async (db) => {
50418
+ const up$5 = async (db) => {
50343
50419
  for (const statement of STATEMENTS) await sql.raw(statement).execute(db);
50344
50420
  };
50345
- const down$4 = async (db) => {
50421
+ const down$5 = async (db) => {
50346
50422
  await sql`pragma defer_foreign_keys = on`.execute(db);
50347
- for (const table of [...TABLES].reverse()) await sql.raw(`drop table if exists "${table}"`).execute(db);
50423
+ for (const table of [...TABLES$1].reverse()) await sql.raw(`drop table if exists "${table}"`).execute(db);
50348
50424
  };
50349
50425
  //#endregion
50350
50426
  //#region src/db/migrations/sqlite/20261003170000_audit_events_seq.ts
50351
50427
  var _20261003170000_audit_events_seq_exports = /* @__PURE__ */ __exportAll({
50352
- down: () => down$3,
50353
- up: () => up$3
50428
+ down: () => down$4,
50429
+ up: () => up$4
50354
50430
  });
50355
50431
  /**
50356
50432
  * SQLite twin of `../20261003170000_audit_events_seq.ts`. SQLite cannot add a column whose default calls a
@@ -50377,7 +50453,7 @@ const INDEXES = [
50377
50453
  `create index "audit_events_occurred_at_idx" on "audit_events" (occurred_at DESC)`,
50378
50454
  `create index "audit_events_target_idx" on "audit_events" (target_type, target_id, occurred_at DESC)`
50379
50455
  ];
50380
- const up$3 = async (db) => {
50456
+ const up$4 = async (db) => {
50381
50457
  await sql`insert into "sequences" (name, value) values ('audit_events_seq', 0)`.execute(db);
50382
50458
  await sql`alter table "audit_events" rename to "audit_events_before_seq"`.execute(db);
50383
50459
  await sql`create table "audit_events" (
@@ -50405,15 +50481,15 @@ const up$3 = async (db) => {
50405
50481
  await sql`drop table "audit_events_before_seq"`.execute(db);
50406
50482
  for (const statement of INDEXES) await sql.raw(statement).execute(db);
50407
50483
  };
50408
- const down$3 = async (db) => {
50484
+ const down$4 = async (db) => {
50409
50485
  await sql`alter table "audit_events" drop column "seq"`.execute(db);
50410
50486
  await sql`delete from "sequences" where name = 'audit_events_seq'`.execute(db);
50411
50487
  };
50412
50488
  //#endregion
50413
50489
  //#region src/db/migrations/sqlite/20261004120000_models_site_scope.ts
50414
50490
  var _20261004120000_models_site_scope_exports = /* @__PURE__ */ __exportAll({
50415
- down: () => down$2,
50416
- up: () => up$2
50491
+ down: () => down$3,
50492
+ up: () => up$3
50417
50493
  });
50418
50494
  /**
50419
50495
  * SQLite twin of `../20261004120000_models_site_scope.ts`. `down` rebuilds `models` without `site_id`
@@ -50423,7 +50499,7 @@ var _20261004120000_models_site_scope_exports = /* @__PURE__ */ __exportAll({
50423
50499
  * deletes nothing they reference.
50424
50500
  */
50425
50501
  const NIL_UUID = "00000000-0000-0000-0000-000000000000";
50426
- const up$2 = async (db) => {
50502
+ const up$3 = async (db) => {
50427
50503
  await sql`alter table "models" add column "site_id" text_uuid references sites (id)`.execute(db);
50428
50504
  await sql`create index "models_site_idx" on "models" (site_id)`.execute(db);
50429
50505
  await sql`drop index "models_api_key_uq"`.execute(db);
@@ -50433,7 +50509,7 @@ const up$2 = async (db) => {
50433
50509
  `.execute(db);
50434
50510
  await sql`alter table "schema_drafts" add column "shared" integer_boolean not null default 0`.execute(db);
50435
50511
  };
50436
- const down$2 = async (db) => {
50512
+ const down$3 = async (db) => {
50437
50513
  const { rows } = await sql`select count(*) as count from "models" where site_id is not null`.execute(db);
50438
50514
  if (Number(rows[0]?.count ?? 0) > 0) throw new Error("Cannot roll back per-site schema while definitions belong to a site: two sites may share an API ID. Share or delete the site definitions first.");
50439
50515
  await sql`alter table "schema_drafts" drop column "shared"`.execute(db);
@@ -50458,15 +50534,15 @@ const down$2 = async (db) => {
50458
50534
  //#endregion
50459
50535
  //#region src/db/migrations/sqlite/20261004130000_site_seo_settings.ts
50460
50536
  var _20261004130000_site_seo_settings_exports = /* @__PURE__ */ __exportAll({
50461
- down: () => down$1,
50462
- up: () => up$1
50537
+ down: () => down$2,
50538
+ up: () => up$2
50463
50539
  });
50464
50540
  /**
50465
50541
  * SQLite twin of `../20261004130000_site_seo_settings.ts`. `insert or ignore` stands in for `on conflict do
50466
50542
  * nothing` (the grant's unique index); the permissions version moves only when a grant was added or removed.
50467
50543
  */
50468
50544
  const bumpPermissionsVersion = (db) => sql`update "system_versions" set permissions_version = permissions_version + 1, updated_at = shapio_now()`.execute(db);
50469
- const up$1 = async (db) => {
50545
+ const up$2 = async (db) => {
50470
50546
  await sql`alter table "sites" add column "seo_defaults" text_jsonb`.execute(db);
50471
50547
  const granted = await sql`
50472
50548
  insert or ignore into "admin_role_permissions" (role_id, action, model_id, condition, field_ids)
@@ -50476,7 +50552,7 @@ const up$1 = async (db) => {
50476
50552
  `.execute(db);
50477
50553
  if (Number(granted.numAffectedRows ?? 0) > 0) await bumpPermissionsVersion(db);
50478
50554
  };
50479
- const down$1 = async (db) => {
50555
+ const down$2 = async (db) => {
50480
50556
  const revoked = await sql`delete from "admin_role_permissions" where action = 'site.settings'`.execute(db);
50481
50557
  if (Number(revoked.numAffectedRows ?? 0) > 0) await bumpPermissionsVersion(db);
50482
50558
  await sql`alter table "sites" drop column "seo_defaults"`.execute(db);
@@ -50484,8 +50560,8 @@ const down$1 = async (db) => {
50484
50560
  //#endregion
50485
50561
  //#region src/db/migrations/sqlite/20261005120000_entry_heads_entry_created_at.ts
50486
50562
  var _20261005120000_entry_heads_entry_created_at_exports = /* @__PURE__ */ __exportAll({
50487
- down: () => down,
50488
- up: () => up
50563
+ down: () => down$1,
50564
+ up: () => up$1
50489
50565
  });
50490
50566
  /**
50491
50567
  * SQLite twin of `../20261005120000_entry_heads_entry_created_at.ts`. One process holds the write lock, so
@@ -50493,18 +50569,61 @@ var _20261005120000_entry_heads_entry_created_at_exports = /* @__PURE__ */ __exp
50493
50569
  * documented single-process limitation of ADR 0001, "D2: as built").
50494
50570
  */
50495
50571
  const INDEX = "entry_heads_entry_order_idx";
50496
- const up = async (db) => {
50572
+ const up$1 = async (db) => {
50497
50573
  await sql`alter table "entry_heads" add column "entry_created_at" text_timestamptz`.execute(db);
50498
50574
  await sql`update "entry_heads" set entry_created_at = (
50499
50575
  select e.created_at from "entries" e where e.id = "entry_heads".entry_id
50500
50576
  ) where entry_created_at is null`.execute(db);
50501
50577
  await sql`create index ${sql.id(INDEX)} on "entry_heads" (site_id, model_id, state, entry_created_at desc, entry_id)`.execute(db);
50502
50578
  };
50503
- const down = async (db) => {
50579
+ const down$1 = async (db) => {
50504
50580
  await sql`drop index if exists ${sql.id(INDEX)}`.execute(db);
50505
50581
  await sql`alter table "entry_heads" drop column "entry_created_at"`.execute(db);
50506
50582
  };
50507
50583
  //#endregion
50584
+ //#region src/db/migrations/sqlite/20261014120000_canceled_status.ts
50585
+ var _20261014120000_canceled_status_exports = /* @__PURE__ */ __exportAll({
50586
+ down: () => down,
50587
+ up: () => up
50588
+ });
50589
+ /**
50590
+ * SQLite twin of `../20261014120000_canceled_status.ts`. SQLite cannot change a check constraint, so each
50591
+ * table is rebuilt from its own stored `create table` statement with the one value swapped: renamed aside
50592
+ * (with `legacy_alter_table` on, so references to the name keep pointing at it), recreated, refilled with the
50593
+ * status rewritten, and its indexes recreated from `sqlite_master`. Nothing references either table.
50594
+ */
50595
+ const TABLES = ["schema_change_jobs", "scheduled_publications"];
50596
+ const rebuild = async (db, table, from, to) => {
50597
+ const { rows: created } = await sql`
50598
+ select sql from sqlite_master where type = 'table' and name = ${table}
50599
+ `.execute(db);
50600
+ const { rows: indexes } = await sql`
50601
+ select sql from sqlite_master where type = 'index' and tbl_name = ${table} and sql is not null
50602
+ `.execute(db);
50603
+ const definition = created[0]?.sql;
50604
+ if (!definition || !definition.includes(`'${from}'`)) throw new Error(`${table}: expected a status check allowing '${from}'`);
50605
+ const repaired = definition.replace(/references\s+("?)(\w+?)_before_\w+\1/gi, (_, quote, base) => `references ${quote}${base}${quote}`);
50606
+ const aside = `${table}_before_${to}`;
50607
+ await sql`pragma legacy_alter_table = on`.execute(db);
50608
+ await sql`alter table ${sql.table(table)} rename to ${sql.table(aside)}`.execute(db);
50609
+ await sql.raw(repaired.replace(`'${from}'`, `'${to}'`)).execute(db);
50610
+ const { rows: columns } = await sql`
50611
+ select name from pragma_table_info(${aside}) order by cid
50612
+ `.execute(db);
50613
+ const names = columns.map(({ name }) => sql.id(name));
50614
+ const values = columns.map(({ name }) => name === "status" ? sql`case when status = ${from} then ${to} else status end` : sql.id(name));
50615
+ await sql`insert into ${sql.table(table)} (${sql.join(names)}) select ${sql.join(values)} from ${sql.table(aside)}`.execute(db);
50616
+ await sql`drop table ${sql.table(aside)}`.execute(db);
50617
+ await sql`pragma legacy_alter_table = off`.execute(db);
50618
+ for (const { sql: index } of indexes) await sql.raw(index).execute(db);
50619
+ };
50620
+ const up = async (db) => {
50621
+ for (const table of TABLES) await rebuild(db, table, "cancelled", "canceled");
50622
+ };
50623
+ const down = async (db) => {
50624
+ for (const table of TABLES) await rebuild(db, table, "canceled", "cancelled");
50625
+ };
50626
+ //#endregion
50508
50627
  //#region src/db/migrations/sqlite/index.ts
50509
50628
  const SQLITE_MIGRATIONS = {
50510
50629
  "0001_baseline": _0001_baseline_exports,
@@ -50512,7 +50631,8 @@ const SQLITE_MIGRATIONS = {
50512
50631
  "20261004120000_models_site_scope": _20261004120000_models_site_scope_exports,
50513
50632
  "20261004130000_site_seo_settings": _20261004130000_site_seo_settings_exports,
50514
50633
  "20261005120000_entry_heads_entry_created_at": _20261005120000_entry_heads_entry_created_at_exports,
50515
- "20261006120000_system_versions_release": _20261006120000_system_versions_release_exports
50634
+ "20261006120000_system_versions_release": _20261006120000_system_versions_release_exports,
50635
+ "20261014120000_canceled_status": _20261014120000_canceled_status_exports
50516
50636
  };
50517
50637
  //#endregion
50518
50638
  //#region src/db/migrations/index.ts
@@ -50546,7 +50666,8 @@ const MIGRATIONS = {
50546
50666
  "20261004120000_models_site_scope": _20261004120000_models_site_scope_exports$2,
50547
50667
  "20261004130000_site_seo_settings": _20261004130000_site_seo_settings_exports$2,
50548
50668
  "20261005120000_entry_heads_entry_created_at": _20261005120000_entry_heads_entry_created_at_exports$2,
50549
- "20261006120000_system_versions_release": _20261006120000_system_versions_release_exports
50669
+ "20261006120000_system_versions_release": _20261006120000_system_versions_release_exports,
50670
+ "20261014120000_canceled_status": _20261014120000_canceled_status_exports$2
50550
50671
  };
50551
50672
  const PROVIDERS = {
50552
50673
  postgres: { getMigrations: () => Promise.resolve({ ...MIGRATIONS }) },
@@ -51016,7 +51137,7 @@ const mediaFilesRoutes = async (app) => {
51016
51137
  //#region src/services/previewContent.ts
51017
51138
  /**
51018
51139
  * `/api/preview/content/:modelKey[/:id]` (brief §7): DRAFT content for a site's preview, in the delivery
51019
- * shape, authorised by a preview token. Reads are evaluated with the token creator's CURRENT permissions
51140
+ * shape, authorized by a preview token. Reads are evaluated with the token creator's CURRENT permissions
51020
51141
  * (so revoking their role ends the preview), limited to read, to the token's model, entry and locale, and to
51021
51142
  * fields a delivery reader would see (`public` fields within the creator's read mask), so a shared preview
51022
51143
  * link never shows more than the published site would.
@@ -51207,7 +51328,7 @@ const getPreview = async (request, reply) => send(reply, await getPreview$1(requ
51207
51328
  //#region src/routes/preview/index.ts
51208
51329
  /**
51209
51330
  * /api/preview/content/:modelKey[/:id]: draft content for site previews, addressed by route key like
51210
- * delivery (plural API ID of a collection), authorised by a preview token in
51331
+ * delivery (plural API ID of a collection), authorized by a preview token in
51211
51332
  * `Authorization: Bearer shpv_…` (never a query parameter, so tokens stay out of access logs).
51212
51333
  */
51213
51334
  const previewRoutes = async (app) => {
@@ -51452,7 +51573,7 @@ const buildApp = async (config, deps) => {
51452
51573
  await app.register(contentHooksPlugin, { hooks: deps.contentHooks ?? extensions.hooks });
51453
51574
  await app.register(adminContentRoutes, { prefix: urls.withBasePath("/api/admin/content") });
51454
51575
  await app.register(editorManifestPlugin, { manifest: deps.editorManifest ?? buildEditorManifest(extensions.loaded.projectDir, extensions.loaded.config.editors ?? [], app.log.child({ component: "extensions" })) });
51455
- await app.register(themeCataloguePlugin, { catalogue: buildThemeCatalogue(extensions.loaded.config.themes ?? []) });
51576
+ await app.register(themeCatalogPlugin, { catalog: buildThemeCatalog(extensions.loaded.config.themes ?? []) });
51456
51577
  await app.register(adminExtensionsRoutes, { prefix: urls.withBasePath("/api/admin/extensions") });
51457
51578
  await app.register(deliveryRoutes, { prefix: urls.withBasePath("/api/content") });
51458
51579
  await app.register(siteRoutes, { prefix: urls.withBasePath("/api/site") });
@@ -52397,7 +52518,7 @@ const EXPIRING_CREDENTIAL_TABLES = [
52397
52518
  "admin_invitations"
52398
52519
  ];
52399
52520
  /**
52400
- * Credentials that expired before the cutoff: they no longer authorise anything, and the retention period
52521
+ * Credentials that expired before the cutoff: they no longer authorize anything, and the retention period
52401
52522
  * keeps recently expired ones for looking into an incident.
52402
52523
  */
52403
52524
  const pruneExpiredCredentials$1 = (table) => async (before, limit, trx = db) => deleted(await trx.deleteFrom(table).where("id", "in", (eb) => eb.selectFrom(table).select("id").where("expires_at", "<", before).limit(limit)).executeTakeFirstOrThrow());
@@ -52884,7 +53005,7 @@ var AssetBusyError = class extends Error {
52884
53005
  /**
52885
53006
  * The `media.relocate` job: after a visibility change, copies the original and its variants under the
52886
53007
  * new visibility prefix (verified by checksum), points the rows at them, and purges the old objects.
52887
- * Shapio's own routes honour the new visibility before this runs; the move matters for a CDN or bucket
53008
+ * Shapio's own routes honor the new visibility before this runs; the move matters for a CDN or bucket
52888
53009
  * policy that exposes only `public/`.
52889
53010
  */
52890
53011
  const relocateAsset = async (deps, payload) => {
@@ -53022,7 +53143,7 @@ const summarizeResponse = (response) => {
53022
53143
  * network errors are retried by the queue with exponential backoff up to the webhook's max attempts; then
53023
53144
  * the delivery is dead (dead-lettered). A destination refused by the network policy, or a signing secret that
53024
53145
  * can no longer be decrypted (SESSION_SECRET changed; rotate it to repair), is dead at once.
53025
- * Every attempt is summarised in the delivery log, with the signature redacted and the body truncated.
53146
+ * Every attempt is summarized in the delivery log, with the signature redacted and the body truncated.
53026
53147
  */
53027
53148
  const createWebhookDeliveryHandler = (runtime) => async (job) => {
53028
53149
  const { deliveryId } = job.payload;
@@ -53781,4 +53902,4 @@ const startDedicatedWorker = async (config) => {
53781
53902
  //#endregion
53782
53903
  export { parseLockFile as $, listForAssets as A, SCHEMA_KIND_DIRECTORIES as B, SITE_KEY_PATTERN as C, EXTENSION_JOB_PREFIX as D, BEFORE_EVENTS as E, describeError as F, foldApiKey as G, THEME_VARIANTS as H, LOCK_FILE_PATH as I, isDataType as J, generatedNames as K, RESERVED_DEFINITION_API_KEYS as L, listLiveByDriver as M, lockById$5 as N, EXTENSION_ROUTE_ROOT as O, update$8 as P, parseDefinition as Q, RESERVED_FIELD_API_KEYS as R, loopbackUrl as S, AFTER_EVENTS as T, checkThemeContrast as U, SITES_DIRECTORY as V, createDefinitionIndex as W, lockEntriesForSite as X, lockCoversSite as Y, mergePulledLock as Z, createAdminDirect as _, loadConfig as a, suggestPlural as at, createLogger as b, getPendingMigrations as c, upgradeLockFile as ct, EmailSchema as d, RICHTEXT_FORMAT as dt, routeKeyOf as et, PasswordSchema as f, SAFE_LINK_PATTERN as ft, listAllSites as g, sqliteDriverOf as gt, createSite$1 as h, createDb as ht, assertDatabaseReachable as i, serializeLockFile as it, STORAGE_DRIVERS$1 as j, buildEditorManifest as k, migrateToLatest as l, validateSchema as lt, createMediaStorage as m, validateRichText as mt, startServer as n, scopeDirectory as nt, loadEnvFileIfPresent as o, toTypeName as ot, PersonNameSchema as p, createStableId as pt, hashDefinition as q, copyObjectVerified as r, serializeDefinition as rt, buildApp as s, typeChangeDropsValues as st, startDedicatedWorker as t, schemaFilePath as tt, SHAPIO_VERSION as u, withSiteCovered as ut, SYSTEM_CLI_ACTOR as v, loadProjectConfig as w, createUrlBuilder as x, generateToken as y, RESERVED_TYPE_NAMES as z };
53783
53904
 
53784
- //# sourceMappingURL=worker-6ru1tYBs.js.map
53905
+ //# sourceMappingURL=worker-DHm2JwMZ.js.map