ghost 6.56.0 → 6.57.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. package/bin/validate-adapters.js +74 -0
  2. package/bin/validate-adapters.ts +87 -0
  3. package/bin/warm-compile-cache.sh +60 -0
  4. package/components/tryghost-adapter-base-scheduling-0.2.1.tgz +0 -0
  5. package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
  6. package/components/tryghost-kg-converters-1.2.4.tgz +0 -0
  7. package/components/tryghost-kg-default-cards-10.3.4.tgz +0 -0
  8. package/components/tryghost-kg-default-nodes-2.1.5.tgz +0 -0
  9. package/components/tryghost-kg-default-transforms-1.3.3.tgz +0 -0
  10. package/components/tryghost-kg-html-to-lexical-1.3.3.tgz +0 -0
  11. package/components/tryghost-kg-lexical-html-renderer-1.4.3.tgz +0 -0
  12. package/components/tryghost-parse-email-address-0.0.0.tgz +0 -0
  13. package/core/app.js +1 -1
  14. package/core/boot.js +21 -25
  15. package/core/bridge.js +10 -12
  16. package/core/built/admin/assets/Combination-BDvCdg1t.js +41 -0
  17. package/core/built/admin/assets/about-BNojRaxf.js +1 -0
  18. package/core/built/admin/assets/{account-migration-D3O_yVck.js → account-migration-DMS8JsM-.js} +1 -1
  19. package/core/built/admin/assets/action-list-lGzZLHc8.js +1 -0
  20. package/core/built/admin/assets/activitypub/{account-migration-D8FbP-Z-.js → account-migration-DHFbePl6.js} +7 -7
  21. package/core/built/admin/assets/activitypub/activitypub.js +3 -3
  22. package/core/built/admin/assets/activitypub/{avatar-11EA1VSs.js → avatar-CT4tS2_S.js} +2 -2
  23. package/core/built/admin/assets/activitypub/{avatar-flipboard-jfbLG-xe.js → avatar-flipboard-ByYWKipo.js} +2 -2
  24. package/core/built/admin/assets/activitypub/{bluesky-sharing-f1jTQe2P.js → bluesky-sharing-srVnSHDz.js} +8 -8
  25. package/core/built/admin/assets/activitypub/{content-formatters-nmTOPY9M.js → content-formatters-C2sos5Ht.js} +3 -3
  26. package/core/built/admin/assets/activitypub/{copy-BCwo9ep3.js → copy-B1UBTOoZ.js} +2 -2
  27. package/core/built/admin/assets/activitypub/{dist-BEfX-0aW.js → dist-MPsb2WZ1.js} +4 -4
  28. package/core/built/admin/assets/activitypub/{domain-AaDlZlrA.js → domain-DzcM9Dzo.js} +9 -9
  29. package/core/built/admin/assets/activitypub/{edit-profile-DPi8Tl5M.js → edit-profile-CsQ_4xAk.js} +5 -5
  30. package/core/built/admin/assets/activitypub/{explore-CxTzjILQ.js → explore-CJe0DZBK.js} +8 -8
  31. package/core/built/admin/assets/activitypub/{feed-DPv5x2MX.js → feed-CKV3qWON.js} +9 -9
  32. package/core/built/admin/assets/activitypub/{field-DbgA8lat.js → field-DckHfDJf.js} +3 -3
  33. package/core/built/admin/assets/activitypub/{hash-BWuZoYkA.js → hash-Dlp8RM55.js} +2 -2
  34. package/core/built/admin/assets/activitypub/{inbox-35VDQ2K2.js → inbox-CsPy4R0M.js} +2 -2
  35. package/core/built/admin/assets/activitypub/{inbox-DSrF_i1O.js → inbox-DAsjzUUe.js} +10 -10
  36. package/core/built/admin/assets/activitypub/{label-CPjFBbo7.js → label-DWyo9E5T.js} +3 -3
  37. package/core/built/admin/assets/activitypub/layout-DM_3pqsU.js +1 -0
  38. package/core/built/admin/assets/activitypub/{moderation-BkDC1XVZ.js → moderation-B0Inc03M.js} +7 -7
  39. package/core/built/admin/assets/activitypub/{note-xEyH4xT-.js → note-CSE54lER.js} +7 -7
  40. package/core/built/admin/assets/activitypub/{notifications-DClaL3ui.js → notifications-RSwbKqdh.js} +9 -9
  41. package/core/built/admin/assets/activitypub/{preferences-DpnOa-4Z.js → preferences-CE231n2_.js} +11 -11
  42. package/core/built/admin/assets/activitypub/{profile-Dvi9mz-6.js → profile-aaQ1j1Eo.js} +13 -13
  43. package/core/built/admin/assets/activitypub/{reply-Cs9ySd6Z.js → reply-Cjb0Vs3m.js} +2 -2
  44. package/core/built/admin/assets/activitypub/{routes-DFBeTnfn.js → routes-Djb0mc9k.js} +26 -26
  45. package/core/built/admin/assets/activitypub/{separator-C5u_VjzY.js → separator-D8pROI5n.js} +3 -3
  46. package/core/built/admin/assets/activitypub/{settings-CV2fFu6D.js → settings-DMc32IQl.js} +5 -5
  47. package/core/built/admin/assets/activitypub/{site-_TgDd_EM.js → site-DVIcsohX.js} +4 -4
  48. package/core/built/admin/assets/activitypub/{step-1-BfnNL2oF.js → step-1-9Yey9usF.js} +5 -5
  49. package/core/built/admin/assets/activitypub/{step-2-DLndZkO-.js → step-2-DdYmKRXV.js} +6 -6
  50. package/core/built/admin/assets/activitypub/{step-3-A-PZTtRE.js → step-3-hdSkcjZU.js} +10 -10
  51. package/core/built/admin/assets/activitypub/{tabs-BUbz7tea.js → tabs-CUqseYzQ.js} +6 -6
  52. package/core/built/admin/assets/activitypub/{topic-filter-BdX_xYYT.js → topic-filter-Coni6OXM.js} +3 -3
  53. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-EwuRemHh.js → use-activity-pub-queries-MeHTPMQv.js} +2 -2
  54. package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-cy4ACBc4.js → use-navigate-with-base-path-B046AM38.js} +24 -7
  55. package/core/built/admin/assets/activitypub/{use-reply-chain-data-CyFcGfan.js → use-reply-chain-data-1AO-Xob6.js} +5 -5
  56. package/core/built/admin/assets/activitypub/{x-7zk8mV2p.js → x-BRfRYd16.js} +2 -2
  57. package/core/built/admin/assets/add-integration-modal-DU9ghGLS.js +1 -0
  58. package/core/built/admin/assets/add-newsletter-modal-DFxuQrYu.js +1 -0
  59. package/core/built/admin/assets/add-recommendation-modal-D-3LOrdd.js +1 -0
  60. package/core/built/admin/assets/analytics-DTIMRhWw.js +1 -0
  61. package/core/built/admin/assets/announcement-bar-modal-DGCcezB6.js +1 -0
  62. package/core/built/admin/assets/api-keys-Dx4NeNpK.js +1 -0
  63. package/core/built/admin/assets/api-keys-_iCT4dxr.js +1 -0
  64. package/core/built/admin/assets/{audience-CkBb2LlO.js → audience-DkknNqhZ.js} +1 -1
  65. package/core/built/admin/assets/automated-emails-PayPCT8L.js +1 -0
  66. package/core/built/admin/assets/{automations-DhKeS_U5.js → automations-162q5HjL.js} +1 -1
  67. package/core/built/admin/assets/{automations-cMllU545.js → automations-DvSU7QhW.js} +1 -1
  68. package/core/built/admin/assets/{bluesky-sharing-DPGpyD-G.js → bluesky-sharing-yZ9A_jL8.js} +1 -1
  69. package/core/built/admin/assets/brand-icon-09YqFZjV.js +1 -0
  70. package/core/built/admin/assets/{breadcrumb-DIfcF5ow.js → breadcrumb-CjOH7LCU.js} +1 -1
  71. package/core/built/admin/assets/{chart-helpers-DV0FkdcD.js → chart-helpers-DGxvWnBT.js} +1 -1
  72. package/core/built/admin/assets/checkbox-BSUcnNq_.js +1 -0
  73. package/core/built/admin/assets/{chunk.332.05991a101d67f732dec3.js → chunk.424.4a27628efdade15c2dab.js} +28 -27
  74. package/core/built/admin/assets/chunk.524.dce1c51e0bc30fb2718e.js +25 -0
  75. package/core/built/admin/assets/{chunk.211.6f7328d63c41536451b3.js → chunk.571.40f093ed6d883993714e.js} +5 -5
  76. package/core/built/admin/assets/chunk.582.3a430d5c6a744fd475b6.js +27 -0
  77. package/core/built/admin/assets/code-editor-view-BcyKABrG.js +1 -0
  78. package/core/built/admin/assets/color-picker-field-8NoSnhNI.js +1 -0
  79. package/core/built/admin/assets/color-utils-Dzeeuj1F.js +1 -0
  80. package/core/built/admin/assets/combobox-5rdgDrDV.js +1 -0
  81. package/core/built/admin/assets/command-BOYMbZa_.js +1 -0
  82. package/core/built/admin/assets/comments-BhNM5CYl.js +1 -0
  83. package/core/built/admin/assets/components-CwL6a6As-B0E0-NBJ.js +1 -0
  84. package/core/built/admin/assets/confirmation-modal-CYD7x3UQ.js +1 -0
  85. package/core/built/admin/assets/content-api-modal-BtW4Z1-1.js +1 -0
  86. package/core/built/admin/assets/copy-field-CEp_XieW.js +1 -0
  87. package/core/built/admin/assets/currency-Dy4Tc2R2.js +1 -0
  88. package/core/built/admin/assets/custom-integration-modal-bk3lNEuQ.js +1 -0
  89. package/core/built/admin/assets/{date-range-select-dXc-GsVe.js → date-range-select-B3Ij1Rqg.js} +1 -1
  90. package/core/built/admin/assets/debounce-Cx5B_9OI.js +3 -0
  91. package/core/built/admin/assets/design-and-theme-modal-B2xYKS1I.js +23 -0
  92. package/core/built/admin/assets/dirty-confirm-dialog-YE9L21gY.js +1 -0
  93. package/core/built/admin/assets/disabled-sources-indicator-uIzbWL7K.js +1 -0
  94. package/core/built/admin/assets/{dist-pHiOxyxa.js → dist-ARN6XTcR.js} +1 -1
  95. package/core/built/admin/assets/dist-B2PvRwLn.js +1 -0
  96. package/core/built/admin/assets/{dist-DyViJwIy.js → dist-Bg8bSvLA.js} +3 -3
  97. package/core/built/admin/assets/dist-CsvXCJSe.js +23 -0
  98. package/core/built/admin/assets/dist-DlCyLrOC.js +1 -0
  99. package/core/built/admin/assets/dist-j1xxxnY8.js +1 -0
  100. package/core/built/admin/assets/dist-myQaY0ka.js +1 -0
  101. package/core/built/admin/assets/{domain-B5ogXUBa.js → domain-DzrOAPY8.js} +1 -1
  102. package/core/built/admin/assets/{dropzone-BnFG7dDP.js → dropzone-CzhP33wa.js} +1 -1
  103. package/core/built/admin/assets/{edit-profile-B07jCZy9.js → edit-profile-oufs4R4n.js} +1 -1
  104. package/core/built/admin/assets/editor-BBKrunMK.js +8 -0
  105. package/core/built/admin/assets/embed-signup-form-modal-Ch3s6lqA.js +9 -0
  106. package/core/built/admin/assets/{explore-Ca1y8HW_.js → explore-CA-R01Br.js} +1 -1
  107. package/core/built/admin/assets/{feed-x4iFMBP4.js → feed-ClC8_Gld.js} +1 -1
  108. package/core/built/admin/assets/{field-ChCAabZg.js → field-B3OPenbP.js} +1 -1
  109. package/core/built/admin/assets/{filter-sources-LdtH1e-T.js → filter-sources-CiPLnG9A.js} +1 -1
  110. package/core/built/admin/assets/filters-Bz0HsRie.js +1 -0
  111. package/core/built/admin/assets/{filters-CjVKRP8U.js → filters-yFvybRMe.js} +1 -1
  112. package/core/built/admin/assets/first-promoter-modal-BC0UpYCD.js +1 -0
  113. package/core/built/admin/assets/format-url-C-t8G6Qd.js +1 -0
  114. package/core/built/admin/assets/{ghost-7f01131115186d1af84ead76e79646dd.js → ghost-d683fbeb945b13155ea669caa5d8db41.js} +300 -298
  115. package/core/built/admin/assets/{gift-link-modal-Buqh2vXh.js → gift-link-modal-BKRuqo-k.js} +1 -1
  116. package/core/built/admin/assets/{gift-links-CsUhefWG.js → gift-links-CVuqLhsZ.js} +1 -1
  117. package/core/built/admin/assets/global-data-provider-RzW6Bnlf.js +1 -0
  118. package/core/built/admin/assets/grid-CUciBfjf.js +1 -0
  119. package/core/built/admin/assets/{growth-DajOBdN0.js → growth-ClNAldfL.js} +1 -1
  120. package/core/built/admin/assets/{growth-Dy2UOSay.js → growth-Dz8OSG06.js} +2 -2
  121. package/core/built/admin/assets/history-modal-DIVuQ5Ct.js +1 -0
  122. package/core/built/admin/assets/{hooks-CixO01lL.js → hooks-D6EE7BIt.js} +2 -2
  123. package/core/built/admin/assets/html-field-CVZ2sMxw.js +1 -0
  124. package/core/built/admin/assets/iframe-buffering-e8vH4-Qn.js +1 -0
  125. package/core/built/admin/assets/images-Ok8FFJ3A.js +1 -0
  126. package/core/built/admin/assets/{inbox-BUOLDoji.js → inbox-CMUVI6qb.js} +13 -13
  127. package/core/built/admin/assets/index-DUXM0NlS.js +67 -0
  128. package/core/built/admin/assets/index-Ds2iUoF6.css +1 -0
  129. package/core/built/admin/assets/index.es-B9tvf-t4.js +1 -0
  130. package/core/built/admin/assets/{input-group-uSK3XT7b.js → input-group-2XU-iuh_.js} +1 -1
  131. package/core/built/admin/assets/integration-header-B4DyXV06.js +1 -0
  132. package/core/built/admin/assets/integrations-BT6_iJvu.js +1 -0
  133. package/core/built/admin/assets/invite-user-modal-DrZ7xxrZ.js +1 -0
  134. package/core/built/admin/assets/isEmail-BOfC647y.js +1 -0
  135. package/core/built/admin/assets/koenig-editor-base-BPj4S760.js +1 -0
  136. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +9254 -9251
  137. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +124 -124
  138. package/core/built/admin/assets/{koenig-lexical-BFc4yFed.js → koenig-lexical-Cdjv-m3_.js} +98 -98
  139. package/core/built/admin/assets/{kpi-card-CCt-qeWD.js → kpi-card-J8Mj1sDX.js} +1 -1
  140. package/core/built/admin/assets/{kpi-card-BN-E6WYX.js → kpi-card-awos0BMH.js} +1 -1
  141. package/core/built/admin/assets/{kpi-helpers-DlxTbTs4.js → kpi-helpers-SEhvH-8E.js} +1 -1
  142. package/core/built/admin/assets/{kpi-tabs-BlcUttpn.js → kpi-tabs-R6BjsKhd.js} +1 -1
  143. package/core/built/admin/assets/{label-AVrxwmsz.js → label-BMC3dzLI.js} +1 -1
  144. package/core/built/admin/assets/label-picker-Bnlru5tO.js +1 -0
  145. package/core/built/admin/assets/{labels-DAIqKed7.js → labels-DAPjKPy2.js} +1 -1
  146. package/core/built/admin/assets/layout-yR9rlvEw.js +1 -0
  147. package/core/built/admin/assets/limit-modal-COmLevuY.js +1 -0
  148. package/core/built/admin/assets/{link-helpers-D9LsDOkG.js → link-helpers-Bzkk68GD.js} +1 -1
  149. package/core/built/admin/assets/member-custom-fields-BvFKEpxJ.js +1 -0
  150. package/core/built/admin/assets/member-detail-CWdPAe3p.js +1 -0
  151. package/core/built/admin/assets/members-Bnt0ih2R.js +11 -0
  152. package/core/built/admin/assets/modal-page-BMTzFHVO.js +1 -0
  153. package/core/built/admin/assets/{moderation-CQ3urTFE.js → moderation-mPjYHgZW.js} +1 -1
  154. package/core/built/admin/assets/multi-select-combobox-CsoyHAiX.js +1 -0
  155. package/core/built/admin/assets/navigation-modal-D_c0badj.js +1 -0
  156. package/core/built/admin/assets/newsletter-DR49NyGS.js +1 -0
  157. package/core/built/admin/assets/newsletter-detail-modal-B45pL1pb.js +1 -0
  158. package/core/built/admin/assets/newsletter-emails-B-OLfrvr.js +1 -0
  159. package/core/built/admin/assets/{newsletters-vt3Ni1Ov.js → newsletters-DGs5BaKH.js} +1 -1
  160. package/core/built/admin/assets/{newsletters-BXJbJgA-.js → newsletters-Du0lzskS.js} +1 -1
  161. package/core/built/admin/assets/{note-Dk877BTv.js → note-CSVsUKBm.js} +1 -1
  162. package/core/built/admin/assets/{notifications-CPlLjPxO.js → notifications-DV9FRtDw.js} +1 -1
  163. package/core/built/admin/assets/{offers-DEniVRD5.js → offers-Um6ab71O.js} +1 -1
  164. package/core/built/admin/assets/offers-container-modal-B0hFS8nk.js +1 -0
  165. package/core/built/admin/assets/{onboarding-route-DdStOtjy.js → onboarding-route--jL5KLPD.js} +1 -1
  166. package/core/built/admin/assets/overview-B-ZPNqMo.js +1 -0
  167. package/core/built/admin/assets/overview-D96iwoJi.js +1 -0
  168. package/core/built/admin/assets/{page-header-pp4dWmOS.js → page-header-DAvDYKO9.js} +1 -1
  169. package/core/built/admin/assets/{pages-B4goRPUn.js → pages-BVMnpI2O.js} +1 -1
  170. package/core/built/admin/assets/pintura-modal-jiUCxX0Q.js +1 -0
  171. package/core/built/admin/assets/portal-frame-D4D4nEO6.js +1 -0
  172. package/core/built/admin/assets/portal-modal-BLFdYeDH.js +1 -0
  173. package/core/built/admin/assets/{post-analytics-BMJrI81R.js → post-analytics-BhAtiFJp.js} +1 -1
  174. package/core/built/admin/assets/post-analytics-header-DK27VjJm.js +1 -0
  175. package/core/built/admin/assets/{post-analytics-provider-Btml5vJI.js → post-analytics-provider-DGg0FUqs.js} +1 -1
  176. package/core/built/admin/assets/{post-share-modal-AcUZkbfL.js → post-share-modal-DtFAC132.js} +1 -1
  177. package/core/built/admin/assets/{posts-DhXE7b6r.js → posts-CxG7v0-M.js} +1 -1
  178. package/core/built/admin/assets/preferences-CuWLISHa.js +5 -0
  179. package/core/built/admin/assets/preview-chrome-BOVO6_PE.js +1 -0
  180. package/core/built/admin/assets/preview-modal-DctYx20m.js +1 -0
  181. package/core/built/admin/assets/profile-BsKYYtuL.js +1 -0
  182. package/core/built/admin/assets/radio-group-CI5_Kf_d.js +1 -0
  183. package/core/built/admin/assets/{referrers-pmJT4k3-.js → referrers-B9QDAfYm.js} +1 -1
  184. package/core/built/admin/assets/{router-provider-BmEZf6c6.js → router-provider-DSQfprxH.js} +1 -1
  185. package/core/built/admin/assets/select-CkXqNJDJ.js +1 -0
  186. package/core/built/admin/assets/settings-B4vM-rgV.js +4 -0
  187. package/core/built/admin/assets/{settings-BGgk7oCI.js → settings-ZCj-W56o.js} +1 -1
  188. package/core/built/admin/assets/settings-breadcrumbs-DIq31FwA.js +1 -0
  189. package/core/built/admin/assets/{share-modal-BeuydaBf.js → share-modal-BNj14g79.js} +1 -1
  190. package/core/built/admin/assets/slack-modal-C6SpMQ-q.js +1 -0
  191. package/core/built/admin/assets/social-urls-CHQ9cTAK.js +1 -0
  192. package/core/built/admin/assets/{sort-button-Df4t2AL8.js → sort-button-B-k54ow2.js} +1 -1
  193. package/core/built/admin/assets/{source-icon-ajoaKb41.js → source-icon-Cej3sZM6.js} +1 -1
  194. package/core/built/admin/assets/{stats-C_lfxZAw.js → stats-B2KW8E2y.js} +1 -1
  195. package/core/built/admin/assets/{stats-view-Cxot1iD8.js → stats-view-CVzU2-p5.js} +1 -1
  196. package/core/built/admin/assets/{step-1-ogAA4lDr.js → step-1-Dbn1iIMU.js} +1 -1
  197. package/core/built/admin/assets/{step-2-C5Xini-7.js → step-2-BahnSuN6.js} +1 -1
  198. package/core/built/admin/assets/{step-3-CZv1FV81.js → step-3-CW04e2ZJ.js} +2 -2
  199. package/core/built/admin/assets/stripe-button-BkBZqaGG.js +1 -0
  200. package/core/built/admin/assets/stripe-connect-modal-CYDDrSJm.js +1 -0
  201. package/core/built/admin/assets/switch-CE2NuMn-.js +1 -0
  202. package/core/built/admin/assets/{table-DFj1wiYv.js → table-BtLcEi1M.js} +1 -1
  203. package/core/built/admin/assets/tabs-BaWRfg8j.js +1 -0
  204. package/core/built/admin/assets/tag-detail-CmqiC32L.js +1 -0
  205. package/core/built/admin/assets/tags-BbygUvNB.js +1 -0
  206. package/core/built/admin/assets/tags-BwCgmr5v.js +1 -0
  207. package/core/built/admin/assets/testimonials-modal--bdzppyh.js +1 -0
  208. package/core/built/admin/assets/tier-detail-modal-BZmAsIy4.js +1 -0
  209. package/core/built/admin/assets/{tiers-DYsa4DCo.js → tiers-Da6kxHQP.js} +1 -1
  210. package/core/built/admin/assets/toggle-group-CVl-Xigr.js +1 -0
  211. package/core/built/admin/assets/{topic-filter-DGDxDalo.js → topic-filter-BoRHRbL1.js} +1 -1
  212. package/core/built/admin/assets/transistor-modal-CBPDqEGy.js +1 -0
  213. package/core/built/admin/assets/unsplash-modal-CixoRAO2.js +1 -0
  214. package/core/built/admin/assets/{use-analytics-data-C76v4LIp.js → use-analytics-data-BiWvcf1u.js} +1 -1
  215. package/core/built/admin/assets/use-check-theme-limit-error-B14lZukR.js +2 -0
  216. package/core/built/admin/assets/use-feature-flag-BmJoc5WN.js +1 -0
  217. package/core/built/admin/assets/use-filter-params-ChoV72Hw.js +1 -0
  218. package/core/built/admin/assets/use-filterable-api-iMpDZBxD.js +1 -0
  219. package/core/built/admin/assets/use-form-vRjI0Kwk.js +1 -0
  220. package/core/built/admin/assets/{use-growth-stats-aNXJOmQr.js → use-growth-stats-Dom8xVzo.js} +1 -1
  221. package/core/built/admin/assets/use-hash-link-navigation-guard-B9j6HIrV.js +1 -0
  222. package/core/built/admin/assets/use-limiter-Dwg8ivgQ.js +2 -0
  223. package/core/built/admin/assets/use-pintura-config-Bj4QmiVk.js +1 -0
  224. package/core/built/admin/assets/use-pintura-editor-DvrslmPE.js +1 -0
  225. package/core/built/admin/assets/{use-post-referrers-CG0SZioj.js → use-post-referrers-pxIHTXFs.js} +1 -1
  226. package/core/built/admin/assets/use-query-params-DHhhu8wi.js +1 -0
  227. package/core/built/admin/assets/{use-reply-chain-data-RLdPKRmS.js → use-reply-chain-data-CmFe0N6F.js} +1 -1
  228. package/core/built/admin/assets/use-setting-group-Cmp_sy-d.js +1 -0
  229. package/core/built/admin/assets/use-settings-navigation-BmROPrls.js +1 -0
  230. package/core/built/admin/assets/{use-simple-pagination-DgcF69KI.js → use-simple-pagination-D5rL3YwO.js} +1 -1
  231. package/core/built/admin/assets/{use-tinybird-query-C1R_Kbmy.js → use-tinybird-query-DP2dMaq7.js} +1 -1
  232. package/core/built/admin/assets/{use-tinybird-token-C9fPjVM_.js → use-tinybird-token-DrK_skPQ.js} +1 -1
  233. package/core/built/admin/assets/use-url-input-ChrUZBFf.js +5 -0
  234. package/core/built/admin/assets/user-detail-modal-XODpOqNC.js +1 -0
  235. package/core/built/admin/assets/{users-Dkv8NQZe.js → users-B6hIds6n.js} +1 -1
  236. package/core/built/admin/assets/validator-Cr0sMKuW.js +7 -0
  237. package/core/built/admin/assets/{virtual-list-BmTUzeoF.js → virtual-list-Dnoafqbk.js} +1 -1
  238. package/core/built/admin/assets/web-D71mjB2r.js +1 -0
  239. package/core/built/admin/assets/web-z71lA1Y3.js +2 -0
  240. package/core/built/admin/assets/zapier-modal-Bp507Um7.js +1 -0
  241. package/core/built/admin/index.html +16 -14
  242. package/core/frontend/helpers/authors.js +1 -1
  243. package/core/frontend/helpers/link.js +3 -8
  244. package/core/frontend/helpers/tags.js +1 -1
  245. package/core/frontend/meta/author-url.js +2 -2
  246. package/core/frontend/meta/url.js +4 -4
  247. package/core/frontend/services/proxy.js +1 -1
  248. package/core/frontend/services/routing/events.js +20 -6
  249. package/core/frontend/services/routing/permalink-adapter.js +0 -13
  250. package/core/frontend/services/routing/permalink-adapter.ts +0 -13
  251. package/core/frontend/services/routing/router-manager.js +15 -9
  252. package/core/frontend/services/sitemap/base-site-map-generator.js +1 -28
  253. package/core/frontend/services/sitemap/site-map-manager.js +22 -57
  254. package/core/frontend/web/middleware/admin-toolbar.js +1 -1
  255. package/core/frontend/web/middleware/serve-indexnow-key.js +1 -7
  256. package/core/server/adapters/route-settings/utils.js +10 -2
  257. package/core/server/adapters/route-settings/utils.ts +12 -2
  258. package/core/server/api/endpoints/email-post.js +1 -1
  259. package/core/server/api/endpoints/index.js +2 -2
  260. package/core/server/api/endpoints/previews.js +1 -1
  261. package/core/server/api/endpoints/search-index-public.js +3 -3
  262. package/core/server/api/endpoints/search-index.js +4 -4
  263. package/core/server/api/endpoints/themes.js +6 -1
  264. package/core/server/api/endpoints/utils/serializers/input/authors.js +2 -2
  265. package/core/server/api/endpoints/utils/serializers/input/comments.js +1 -1
  266. package/core/server/api/endpoints/utils/serializers/input/pages.js +3 -3
  267. package/core/server/api/endpoints/utils/serializers/input/posts.js +3 -3
  268. package/core/server/api/endpoints/utils/serializers/input/tags.js +1 -1
  269. package/core/server/api/endpoints/utils/serializers/input/users.js +2 -2
  270. package/core/server/api/endpoints/utils/serializers/input/utils/url.js +31 -13
  271. package/core/server/api/endpoints/utils/serializers/output/mappers/posts.js +2 -2
  272. package/core/server/api/endpoints/utils/serializers/output/mappers/tags.js +2 -2
  273. package/core/server/api/endpoints/utils/serializers/output/mappers/users.js +8 -0
  274. package/core/server/api/endpoints/utils/serializers/output/utils/url.js +18 -11
  275. package/core/server/data/migrations/versions/6.57/2026-08-04-18-00-00-store-custom-field-values-as-leaf-rows.js +74 -0
  276. package/core/server/data/migrations/versions/6.57/2026-08-04-18-54-14-reset-automation-email-analytics.js +25 -0
  277. package/core/server/data/schema/commands.js +21 -5
  278. package/core/server/data/schema/schema.js +24 -5
  279. package/core/server/lib/common/to-plain.ts +1 -1
  280. package/core/server/models/base/plugins/overrides.js +7 -5
  281. package/core/server/models/post.js +2 -2
  282. package/core/server/services/adapter-manager/adapter-manager.js +1 -45
  283. package/core/server/services/adapter-manager/adapter-manager.ts +2 -48
  284. package/core/server/services/adapter-manager/adapter-paths.js +28 -0
  285. package/core/server/services/adapter-manager/adapter-paths.ts +26 -0
  286. package/core/server/services/adapter-manager/base-classes.js +22 -0
  287. package/core/server/services/adapter-manager/base-classes.ts +22 -0
  288. package/core/server/services/adapter-manager/index.js +4 -27
  289. package/core/server/services/adapter-manager/index.ts +4 -31
  290. package/core/server/services/adapter-manager/utils.js +50 -0
  291. package/core/server/services/adapter-manager/utils.ts +57 -0
  292. package/core/server/services/audience-feedback/audience-feedback-controller.js +11 -2
  293. package/core/server/services/audience-feedback/audience-feedback-service.js +2 -2
  294. package/core/server/services/audience-feedback/feedback-repository.js +4 -1
  295. package/core/server/services/auth/session/session-service.js +18 -3
  296. package/core/server/services/automations/database-automations-repository.js +5 -5
  297. package/core/server/services/automations/database-automations-repository.ts +12 -12
  298. package/core/server/services/automations/database-date.js +52 -3
  299. package/core/server/services/automations/database-date.ts +23 -2
  300. package/core/server/services/automations/service.js +2 -2
  301. package/core/server/services/automations/service.ts +2 -2
  302. package/core/server/services/comments/comments-service-emails.js +1 -1
  303. package/core/server/services/comments/comments-service.js +1 -1
  304. package/core/server/services/email-analytics/email-analytics-service-wrapper.js +12 -3
  305. package/core/server/services/email-analytics/email-analytics-service.js +4 -3
  306. package/core/server/services/email-analytics/index.js +2 -3
  307. package/core/server/services/email-analytics/index.ts +1 -2
  308. package/core/server/services/email-analytics/lib/queries.js +91 -124
  309. package/core/server/services/email-analytics/lib/queries.ts +341 -0
  310. package/core/server/services/email-service/email-service-wrapper.js +2 -1
  311. package/core/server/services/email-service/mailgun-email-provider.js +15 -0
  312. package/core/server/services/indexnow-ping/index.js +0 -2
  313. package/core/server/services/indexnow-ping/index.ts +0 -2
  314. package/core/server/services/indexnow-ping/indexnow-ping-service.js +6 -8
  315. package/core/server/services/indexnow-ping/indexnow-ping-service.ts +9 -17
  316. package/core/server/services/lib/mailgun-client.js +3 -3
  317. package/core/server/services/media-inliner/external-media-inliner.js +12 -8
  318. package/core/server/services/member-attribution/url-translator.js +5 -7
  319. package/core/server/services/member-welcome-emails/service.js +72 -12
  320. package/core/server/services/members/api.js +1 -1
  321. package/core/server/services/members/import-export/import/completion-email.js +8 -4
  322. package/core/server/services/members/import-export/import/completion-email.ts +9 -4
  323. package/core/server/services/members/import-export/import/importer.js +25 -4
  324. package/core/server/services/members/import-export/import/importer.ts +26 -6
  325. package/core/server/services/members/import-export/import/row.ts +5 -1
  326. package/core/server/services/members/import-export/index.js +1 -5
  327. package/core/server/services/members/import-export/index.ts +2 -6
  328. package/core/server/services/members/members-api/repositories/member-repository.js +51 -0
  329. package/core/server/services/members-custom-fields/queries.js +4 -13
  330. package/core/server/services/members-custom-fields/queries.ts +4 -13
  331. package/core/server/services/members-custom-fields/schema.js +18 -27
  332. package/core/server/services/members-custom-fields/schema.ts +17 -27
  333. package/core/server/services/members-custom-fields/storage.js +94 -27
  334. package/core/server/services/members-custom-fields/storage.ts +114 -39
  335. package/core/server/services/members-custom-fields/values-service.js +98 -219
  336. package/core/server/services/members-custom-fields/values-service.ts +110 -238
  337. package/core/server/services/mentions/resource-service.js +1 -1
  338. package/core/server/services/mentions/service.js +2 -2
  339. package/core/server/services/route-settings/dynamic-routing-service.js +9 -59
  340. package/core/server/services/slack-notifications/slack-notifications.js +2 -2
  341. package/core/server/services/slack-ping/index.js +1 -1
  342. package/core/server/services/slack-ping/index.ts +1 -1
  343. package/core/server/services/slack-ping/slack-ping-service.js +3 -2
  344. package/core/server/services/slack-ping/slack-ping-service.ts +4 -5
  345. package/core/server/services/stats/content-stats-service.js +3 -3
  346. package/core/server/services/stats/members-stats-service.js +0 -7
  347. package/core/server/services/stats/posts-stats-service.js +2 -2
  348. package/core/server/services/themes/storage.js +19 -2
  349. package/core/server/services/url/config.js +90 -135
  350. package/core/server/services/url/index.js +6 -49
  351. package/core/server/services/url/lazy-find-resource.js +14 -11
  352. package/core/server/services/url/lazy-find-resource.ts +14 -11
  353. package/core/server/services/url/lazy-url-service.js +174 -94
  354. package/core/server/services/url/lazy-url-service.ts +233 -97
  355. package/core/server/services/url/routable-resources.js +62 -71
  356. package/core/server/services/url/router-filter.js +12 -4
  357. package/core/server/services/url/router-filter.ts +12 -4
  358. package/core/server/services/webhooks/index.js +1 -1
  359. package/core/server/services/webhooks/serialize.js +12 -2
  360. package/core/server/web/api/endpoints/admin/routes.js +2 -2
  361. package/core/shared/config/env/config.testing-mysql.json +1 -2
  362. package/core/shared/config/env/config.testing.json +1 -2
  363. package/core/shared/custom-theme-settings-cache/custom-theme-settings-bread-service.js +4 -0
  364. package/core/shared/custom-theme-settings-cache/custom-theme-settings-service.js +39 -0
  365. package/core/shared/events/index.js +1 -2
  366. package/core/shared/labs.js +4 -4
  367. package/package.json +10 -11
  368. package/pnpm-lock.yaml +44 -47
  369. package/pnpm-workspace.yaml +19 -19
  370. package/tsconfig.json +1 -0
  371. package/components/tryghost-adapter-base-scheduling-0.2.0.tgz +0 -0
  372. package/components/tryghost-kg-converters-1.2.3.tgz +0 -0
  373. package/components/tryghost-kg-default-cards-10.3.3.tgz +0 -0
  374. package/components/tryghost-kg-default-nodes-2.1.4.tgz +0 -0
  375. package/core/built/admin/assets/Combination-BCm9FL4o.js +0 -41
  376. package/core/built/admin/assets/activitypub/layout-CTgrezN7.js +0 -1
  377. package/core/built/admin/assets/automated-emails-6t2bIRWf.js +0 -7
  378. package/core/built/admin/assets/checkbox-BIl077a0.js +0 -1
  379. package/core/built/admin/assets/chunk.524.87b52f4fada529df2c4c.js +0 -25
  380. package/core/built/admin/assets/chunk.582.340bcca873e806cbd4bb.js +0 -27
  381. package/core/built/admin/assets/code-editor-view-C0aWNwdl.js +0 -1
  382. package/core/built/admin/assets/comments-qwhIjH3c.js +0 -1
  383. package/core/built/admin/assets/disabled-sources-indicator-DYAXW-6V.js +0 -1
  384. package/core/built/admin/assets/dist-BUKmD51u.js +0 -1
  385. package/core/built/admin/assets/dist-CNlMj7ML.js +0 -1
  386. package/core/built/admin/assets/dist-DDY6GRVz.js +0 -1
  387. package/core/built/admin/assets/dist-DG78yroX.js +0 -23
  388. package/core/built/admin/assets/editor-DDYSOXGN.js +0 -8
  389. package/core/built/admin/assets/esm-CFX93H5M.js +0 -2
  390. package/core/built/admin/assets/filters-CLehPo_D.js +0 -1
  391. package/core/built/admin/assets/index-08n05-rc.js +0 -67
  392. package/core/built/admin/assets/index-DgUzgFvS.css +0 -1
  393. package/core/built/admin/assets/label-picker-DVnpu_IF.js +0 -1
  394. package/core/built/admin/assets/layout-B0YLh7R9.js +0 -1
  395. package/core/built/admin/assets/member-custom-fields-C8NpZYza.js +0 -1
  396. package/core/built/admin/assets/member-detail-CIVAdKXf.js +0 -1
  397. package/core/built/admin/assets/members-oLPiSkXD.js +0 -10
  398. package/core/built/admin/assets/modals-CB7v-k3T.js +0 -31
  399. package/core/built/admin/assets/newsletter-rbeDX9Wk.js +0 -1
  400. package/core/built/admin/assets/overview--4V-kx9c.js +0 -1
  401. package/core/built/admin/assets/overview-DSLv30oz.js +0 -1
  402. package/core/built/admin/assets/post-analytics-header-pU2m9ZuV.js +0 -1
  403. package/core/built/admin/assets/preferences-Ru4CRPHC.js +0 -5
  404. package/core/built/admin/assets/profile-BNb1oj7D.js +0 -1
  405. package/core/built/admin/assets/select-B0HteHrp.js +0 -1
  406. package/core/built/admin/assets/settings-B1C9Q3wo.js +0 -4
  407. package/core/built/admin/assets/social-urls-DA2lXrhW.js +0 -8
  408. package/core/built/admin/assets/switch-CyQcwMAv.js +0 -1
  409. package/core/built/admin/assets/tabs-D4y1gqUd.js +0 -1
  410. package/core/built/admin/assets/tags-Dmft-Y4O.js +0 -1
  411. package/core/built/admin/assets/toggle-group-R2QMFvXW.js +0 -1
  412. package/core/built/admin/assets/use-filter-params-WrdhAISv.js +0 -1
  413. package/core/built/admin/assets/web-BqW0b0_C.js +0 -1
  414. package/core/built/admin/assets/web-Cy5GKMWM.js +0 -2
  415. package/core/server/services/email-analytics/jobs/update-member-email-analytics/index.js +0 -14
  416. package/core/server/services/url/local-file-cache.js +0 -75
  417. package/core/server/services/url/queue.js +0 -260
  418. package/core/server/services/url/resource.js +0 -102
  419. package/core/server/services/url/resources.js +0 -480
  420. package/core/server/services/url/url-generator.js +0 -276
  421. package/core/server/services/url/url-service-facade.js +0 -366
  422. package/core/server/services/url/url-service-facade.ts +0 -519
  423. package/core/server/services/url/url-service.js +0 -387
  424. package/core/server/services/url/urls.js +0 -140
  425. package/core/shared/events/url-resource-updated-event.js +0 -33
  426. /package/core/built/admin/assets/{chunk.211.6f7328d63c41536451b3.js.LICENSE.txt → chunk.571.40f093ed6d883993714e.js.LICENSE.txt} +0 -0
  427. /package/core/built/admin/assets/{dist-CqO2lWS0.js → dist-CqO2lWS02.js} +0 -0
  428. /package/core/server/api/endpoints/{gift-reminders.js → gifts.js} +0 -0
@@ -1,22 +1,21 @@
1
1
  const errors = require('@tryghost/errors');
2
2
 
3
3
  /**
4
- * Enumerates the routable resources of a type: the rows the lazy URL service
5
- * would produce a URL for. This is the lazy counterpart of the eager
6
- * service's boot walk — same raw-knex fast path, same public-visibility
7
- * gates — computed on demand instead of held in memory.
4
+ * Enumerates the routable resources of a type: the rows the URL service would
5
+ * produce a URL for. Computed on demand rather than held in memory.
8
6
  *
9
- * Callers name the extra columns they want back; everything else stays out
10
- * of memory. The columns URL computation needs (permalink fields, filter
11
- * columns, relations) come from the lazy service itself, so rows are never
12
- * thin for the active routing config.
7
+ * Callers name the extra columns they want back; everything else stays out of
8
+ * memory. The columns URL computation itself needs (permalink fields, filter
9
+ * columns, relations) are passed in by the URL service, which is the source of
10
+ * truth for what the active routing config reads — so rows are never thin for
11
+ * it.
13
12
  */
14
13
 
15
14
  // Which rows of each type are routable. visibility:public alone is not
16
15
  // enough for tags and authors: without the has-posts join, empty tags and
17
16
  // staff user accounts would be routable/listable.
18
17
  const TYPE_CONFIG = {
19
- posts: {modelName: 'Post', table: 'posts', filter: 'status:published+type:post'},
18
+ posts: {modelName: 'Post', table: 'posts', filter: 'status:published+type:post', canCarryRelations: true},
20
19
  pages: {modelName: 'Post', table: 'posts', filter: 'status:published+type:page'},
21
20
  tags: {
22
21
  modelName: 'Tag',
@@ -37,80 +36,72 @@ const RELATION_FIELDS = {
37
36
  authors: ['users.id', 'users.slug']
38
37
  };
39
38
 
40
- // Keeps each SQLite query under the bound-variable limit (#5810) — the same
41
- // strategy as the eager boot walk (services/url/resources.js).
39
+ // Keeps each SQLite query under the bound-variable limit (#5810).
42
40
  const SQLITE_BATCH_SIZE = 999;
43
41
 
44
42
  /**
45
- * @param {Object} deps
46
- * @param {Object} deps.lazyUrlService - source of truth for the columns and
47
- * relations the active routing config reads
48
- * @returns {(type: string, options?: {columns?: string[]}) => Promise<Object[]>}
43
+ * @param {string} type
44
+ * @param {Object} [options]
45
+ * @param {string[]} [options.columns] - extra columns the caller wants back
46
+ * @param {string[]} [options.requiredFields] - columns URL computation reads
47
+ * @param {string[]} [options.requiredRelations] - relations URL computation
48
+ * reads; ignored for types that carry none
49
+ * @returns {Promise<Object[]>}
49
50
  */
50
- function createFetchRoutableResources({lazyUrlService}) {
51
- if (!lazyUrlService) {
51
+ async function fetchRoutableResources(type, {columns = [], requiredFields = [], requiredRelations = []} = {}) {
52
+ const typeConfig = TYPE_CONFIG[type];
53
+ if (!typeConfig) {
52
54
  throw new errors.IncorrectUsageError({
53
- message: 'fetchRoutableResources requires a lazy URL service backend'
55
+ message: `Unknown routable resource type: ${type}`
54
56
  });
55
57
  }
56
58
 
57
- return async function fetchRoutableResources(type, {columns = []} = {}) {
58
- const typeConfig = TYPE_CONFIG[type];
59
- if (!typeConfig) {
60
- throw new errors.IncorrectUsageError({
61
- message: `Unknown routable resource type: ${type}`
62
- });
63
- }
64
-
65
- // Lazy requires: the model layer must not load before boot wires it.
66
- const models = require('../../models');
67
- const schema = require('../../data/schema');
68
- const DatabaseInfo = require('@tryghost/database-info');
59
+ // Required here rather than at the top so this module can be loaded
60
+ // for its shape without pulling in the model layer.
61
+ const models = require('../../models');
62
+ const schema = require('../../data/schema');
63
+ const DatabaseInfo = require('@tryghost/database-info');
69
64
 
70
- // Callers speak include; raw_knex only speaks exclude, so translate
71
- // against the table schema here, once.
72
- const include = new Set(['id', ...columns, ...lazyUrlService.getRequiredFields(type)]);
73
- const options = {
74
- modelName: typeConfig.modelName,
75
- filter: typeConfig.filter,
76
- exclude: Object.keys(schema.tables[typeConfig.table]).filter(column => !include.has(column))
77
- };
78
- if (typeConfig.shouldHavePosts) {
79
- options.shouldHavePosts = typeConfig.shouldHavePosts;
80
- }
65
+ // Callers speak include; raw_knex only speaks exclude, so translate
66
+ // against the table schema here, once.
67
+ const include = new Set(['id', ...columns, ...requiredFields]);
68
+ const options = {
69
+ modelName: typeConfig.modelName,
70
+ filter: typeConfig.filter,
71
+ exclude: Object.keys(schema.tables[typeConfig.table]).filter(column => !include.has(column))
72
+ };
73
+ if (typeConfig.shouldHavePosts) {
74
+ options.shouldHavePosts = typeConfig.shouldHavePosts;
75
+ }
81
76
 
82
- // Relations only when the active routing config reads them (e.g.
83
- // /:primary_tag/:slug/ permalinks, tag-filtered collections). Pages
84
- // never carry relations, mirroring the eager resource config.
85
- if (type === 'posts') {
86
- const relations = lazyUrlService.getRequiredRelations();
87
- if (relations.length) {
88
- options.withRelated = relations;
89
- options.withRelatedFields = {};
90
- for (const relation of relations) {
91
- options.withRelatedFields[relation] = RELATION_FIELDS[relation];
92
- }
93
- }
77
+ // Relations only when the active routing config reads them (e.g.
78
+ // /:primary_tag/:slug/ permalinks, tag-filtered collections), and only for
79
+ // the types that have any see canCarryRelations above.
80
+ if (typeConfig.canCarryRelations && requiredRelations.length) {
81
+ options.withRelated = requiredRelations;
82
+ options.withRelatedFields = {};
83
+ for (const relation of requiredRelations) {
84
+ options.withRelatedFields[relation] = RELATION_FIELDS[relation];
94
85
  }
86
+ }
95
87
 
96
- let rows;
97
- if (!DatabaseInfo.isSQLite(models.Base.knex)) {
98
- rows = await models.Base.Model.raw_knex.fetchAll(options);
99
- } else {
100
- rows = [];
101
- let offset = 0;
102
- let batch;
103
- do {
104
- // orderBy makes the pagination deterministic; without it the
105
- // row order between batches is unspecified.
106
- batch = await models.Base.Model.raw_knex.fetchAll({...options, orderBy: 'id', offset, limit: SQLITE_BATCH_SIZE});
107
- rows.push(...batch);
108
- offset += SQLITE_BATCH_SIZE;
109
- } while (batch.length);
110
- }
88
+ let rows;
89
+ if (!DatabaseInfo.isSQLite(models.Base.knex)) {
90
+ rows = await models.Base.Model.raw_knex.fetchAll(options);
91
+ } else {
92
+ rows = [];
93
+ let offset = 0;
94
+ let batch;
95
+ do {
96
+ // orderBy makes the pagination deterministic; without it the
97
+ // row order between batches is unspecified.
98
+ batch = await models.Base.Model.raw_knex.fetchAll({...options, orderBy: 'id', offset, limit: SQLITE_BATCH_SIZE});
99
+ rows.push(...batch);
100
+ offset += SQLITE_BATCH_SIZE;
101
+ } while (batch.length);
102
+ }
111
103
 
112
- return rows;
113
- };
104
+ return rows;
114
105
  }
115
106
 
116
- module.exports = {createFetchRoutableResources};
107
+ module.exports = {fetchRoutableResources};
@@ -6,8 +6,9 @@ exports.buildFilter = buildFilter;
6
6
  exports.filterMatches = filterMatches;
7
7
  const nql = require('@tryghost/nql');
8
8
  const logging = require('@tryghost/logging');
9
- // A deliberate copy of the eager UrlGenerator's NQL semantics: while both
10
- // services run side by side, eager is the parity oracle and must stay separate.
9
+ // NQL evaluation for routes.yaml collection filters, kept in one place so the
10
+ // forward lookup, ownership check and reverse lookup all decide membership the
11
+ // same way.
11
12
  exports.EXPANSIONS = [
12
13
  { key: 'author', replacement: 'authors.slug' },
13
14
  { key: 'tags', replacement: 'tags.slug' },
@@ -46,8 +47,15 @@ function buildFilter(filter) {
46
47
  }
47
48
  return nql(filter, { expansions: exports.EXPANSIONS, transformer: PAGE_TRANSFORMER });
48
49
  }
49
- // A null filter always matches; a filter that throws is a non-match, not an
50
- // error, mirroring the eager generator's try/catch.
50
+ // A null filter always matches; anything that throws is a non-match, not an
51
+ // error.
52
+ //
53
+ // That covers malformed filters as well as odd records, because NQL parses
54
+ // lazily: `buildFilter` returns happily for a filter like `((`, and the parse
55
+ // error surfaces here on the first `queryJSON`. So this catch is the only
56
+ // thing standing between a bad routes.yaml filter and a site that cannot
57
+ // route — do not narrow it on the assumption that compilation already
58
+ // failed somewhere upstream. Pinned in router-filter.test.js.
51
59
  function filterMatches(compiledFilter, record) {
52
60
  if (!compiledFilter) {
53
61
  return true;
@@ -1,8 +1,9 @@
1
1
  const nql = require('@tryghost/nql');
2
2
  const logging = require('@tryghost/logging');
3
3
 
4
- // A deliberate copy of the eager UrlGenerator's NQL semantics: while both
5
- // services run side by side, eager is the parity oracle and must stay separate.
4
+ // NQL evaluation for routes.yaml collection filters, kept in one place so the
5
+ // forward lookup, ownership check and reverse lookup all decide membership the
6
+ // same way.
6
7
  export const EXPANSIONS = [
7
8
  {key: 'author', replacement: 'authors.slug'},
8
9
  {key: 'tags', replacement: 'tags.slug'},
@@ -50,8 +51,15 @@ export function buildFilter(filter: string | null | undefined): CompiledFilter |
50
51
  return nql(filter, {expansions: EXPANSIONS, transformer: PAGE_TRANSFORMER});
51
52
  }
52
53
 
53
- // A null filter always matches; a filter that throws is a non-match, not an
54
- // error, mirroring the eager generator's try/catch.
54
+ // A null filter always matches; anything that throws is a non-match, not an
55
+ // error.
56
+ //
57
+ // That covers malformed filters as well as odd records, because NQL parses
58
+ // lazily: `buildFilter` returns happily for a filter like `((`, and the parse
59
+ // error surfaces here on the first `queryJSON`. So this catch is the only
60
+ // thing standing between a bad routes.yaml filter and a site that cannot
61
+ // route — do not narrow it on the assumption that compilation already
62
+ // failed somewhere upstream. Pinned in router-filter.test.js.
55
63
  export function filterMatches(compiledFilter: CompiledFilter | null, record: Record<string, unknown>): boolean {
56
64
  if (!compiledFilter) {
57
65
  return true;
@@ -7,7 +7,7 @@ module.exports = {
7
7
  const models = require('../../models');
8
8
  const limitService = require('../../services/limits');
9
9
  const events = require('../../lib/common/events');
10
- const urlService = require('../url').facade;
10
+ const urlService = require('../url');
11
11
  const createSerialize = require('./serialize');
12
12
  const createPayload = require('./payload');
13
13
  const WebhookTrigger = require('./webhook-trigger');
@@ -3,7 +3,17 @@
3
3
  // routing an under-loaded post 404s. Ask the URL service which relations it
4
4
  // needs and load only the ones missing — reloading a relation the event
5
5
  // already carries (e.g. authors) would strip its nested roles from the
6
- // payload. Returns [] under eager routing, which resolves URLs by id.
6
+ // payload. `getRequiredRelations()` is [] when the routing config reads
7
+ // none, so this is a no-op on a default routes.yaml.
8
+ // `model._changed` carries raw model keys, but `previous` is picked off the
9
+ // API-serialized payload, where some keys are renamed (members `products` → `tiers`).
10
+ const SERIALIZED_KEYS = {
11
+ members: {
12
+ products: 'tiers',
13
+ stripeSubscriptions: 'subscriptions'
14
+ }
15
+ };
16
+
7
17
  const loadRequiredUrlRelations = async (model, urlService) => {
8
18
  const required = urlService.getRequiredRelations();
9
19
  const missing = required.filter(relation => !model.relations[relation]);
@@ -79,7 +89,7 @@ module.exports = ({urlService}) => async (event, model) => {
79
89
  .serializers
80
90
  .handle
81
91
  .output(model, {docName: docName, method: 'read'}, api.serializers.output, frame);
82
- previous = _.pick(frame.response[docName][0], changed);
92
+ previous = _.pick(frame.response[docName][0], changed.map(key => SERIALIZED_KEYS[docName]?.[key] ?? key));
83
93
  }
84
94
 
85
95
 
@@ -85,8 +85,8 @@ module.exports = function apiRoutes() {
85
85
  // ## Schedules
86
86
  router.put('/schedules/:resource/:id', mw.authAdminApiWithUrl, http(api.schedules.publish));
87
87
 
88
- // ## Gift Reminders
89
- router.put('/gifts/flush_reminders', mw.authAdminApiWithUrl, http(api.giftReminders.flushReminders));
88
+ // ## Gifts
89
+ router.put('/gifts/flush_reminders', mw.authAdminApiWithUrl, http(api.gifts.flushReminders));
90
90
 
91
91
  // ## Settings
92
92
  router.get('/settings/routes/yaml', mw.authAdminApi, http(api.settings.download));
@@ -115,7 +115,6 @@
115
115
  "useMinFiles": false,
116
116
  "paths": {
117
117
  "fixtures": "test/utils/fixtures/fixtures",
118
- "defaultSettings": "test/utils/fixtures/default-settings.json",
119
- "urlCache": "test/utils/fixtures/urls"
118
+ "defaultSettings": "test/utils/fixtures/default-settings.json"
120
119
  }
121
120
  }
@@ -111,7 +111,6 @@
111
111
  "useMinFiles": false,
112
112
  "paths": {
113
113
  "fixtures": "test/utils/fixtures/fixtures",
114
- "defaultSettings": "test/utils/fixtures/default-settings.json",
115
- "urlCache": "test/utils/fixtures/urls"
114
+ "defaultSettings": "test/utils/fixtures/default-settings.json"
116
115
  }
117
116
  }
@@ -26,4 +26,8 @@ module.exports = class CustomThemeSettingsBREADService {
26
26
  async destroy(data, options = {}) {
27
27
  return this.Model.destroy(data, options);
28
28
  }
29
+
30
+ async transaction(fn) {
31
+ return this.Model.transaction(fn);
32
+ }
29
33
  };
@@ -164,6 +164,45 @@ module.exports = class CustomThemeSettingsService {
164
164
  return settingsObjects;
165
165
  }
166
166
 
167
+ /**
168
+ * Duplicate stored settings from one theme to another, e.g. when a theme
169
+ * is saved as a copy under a new name.
170
+ *
171
+ * No-ops if the destination theme already has stored settings so existing
172
+ * customisations are never overwritten. Values are copied verbatim - they
173
+ * are reconciled against the destination theme's settings definition by
174
+ * the sync that runs when that theme is activated.
175
+ *
176
+ * @param {string} fromThemeName
177
+ * @param {string} toThemeName
178
+ */
179
+ async copySettingsBetweenThemes(fromThemeName, toThemeName) {
180
+ const sourceCollection = await this._repository.browse({filter: `theme:'${fromThemeName}'`});
181
+
182
+ // single transaction so a failure part-way leaves no partial copy
183
+ // behind that would make later attempts skip the copy. The
184
+ // destination check locks inside the same transaction so concurrent
185
+ // copies can't both see an empty destination and insert duplicates
186
+ await this._repository.transaction(async (transacting) => {
187
+ const destinationCollection = await this._repository.browse({filter: `theme:'${toThemeName}'`, transacting, forUpdate: true});
188
+
189
+ if (destinationCollection.toJSON().length > 0) {
190
+ debug(`Skipping copy of custom theme settings from '${fromThemeName}' to '${toThemeName}' - destination already has settings`);
191
+ return;
192
+ }
193
+
194
+ for (const setting of sourceCollection.toJSON()) {
195
+ debug(`Copying custom theme setting '${fromThemeName}.${setting.key}' to '${toThemeName}'`);
196
+ await this._repository.add({
197
+ theme: toThemeName,
198
+ key: setting.key,
199
+ type: setting.type,
200
+ value: setting.value
201
+ }, {transacting});
202
+ }
203
+ });
204
+ }
205
+
167
206
  // Private -----------------------------------------------------------------
168
207
 
169
208
  /**
@@ -12,6 +12,5 @@ module.exports = {
12
12
  OfferRedemptionEvent: require('./offer-redemption-event'),
13
13
  SubscriptionActivatedEvent: require('./subscription-activated-event'),
14
14
  SubscriptionCancelledEvent: require('./subscription-cancelled-event'),
15
- SubscriptionCreatedEvent: require('./subscription-created-event'),
16
- URLResourceUpdatedEvent: require('./url-resource-updated-event')
15
+ SubscriptionCreatedEvent: require('./subscription-created-event')
17
16
  };
@@ -27,13 +27,13 @@ const messages = {
27
27
 
28
28
  // flags in this list always return `true`, allows quick global enable prior to full flag removal
29
29
  const GA_FEATURES = [
30
+ 'automationAnalytics',
30
31
  'customFonts',
31
32
  'explore',
32
33
  'commentsThreads',
33
34
  'commentsPinning',
34
35
  'featurebaseFeedback',
35
36
  'dangerZoneResetAuth',
36
- 'indexnow',
37
37
  'llmsTxt'
38
38
  ];
39
39
 
@@ -48,11 +48,10 @@ const PUBLIC_BETA_FEATURES = [
48
48
  // Which is only visible if the developer experiments flag is enabled
49
49
  const PRIVATE_FEATURES = [
50
50
  'automations',
51
- 'automationAnalytics',
51
+ 'automationRunAnalytics',
52
52
  'stripeAutomaticTax',
53
53
  'importMemberTier',
54
54
  'csvContentImporter',
55
- 'urlCache',
56
55
  'lexicalIndicators',
57
56
  'adminUIRefresh',
58
57
  'emailCustomization',
@@ -65,7 +64,8 @@ const PRIVATE_FEATURES = [
65
64
  'memberDetailsReact',
66
65
  'membersCustomFields',
67
66
  'paywallImprovements',
68
- 'giftSubCustomization'
67
+ 'giftSubCustomization',
68
+ 'tagDetailsReact'
69
69
  ];
70
70
 
71
71
  module.exports.GA_KEYS = [...GA_FEATURES];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghost",
3
- "version": "6.56.0",
3
+ "version": "6.57.1",
4
4
  "description": "The professional publishing platform",
5
5
  "author": "Ghost Foundation",
6
6
  "homepage": "https://ghost.org",
@@ -56,7 +56,7 @@
56
56
  "@tryghost/api-framework": "3.3.5",
57
57
  "@tryghost/bookshelf-plugins": "2.3.2",
58
58
  "@tryghost/brute-knex": "3.2.1",
59
- "@tryghost/color-utils": "0.2.19",
59
+ "@tryghost/color-utils": "0.2.20",
60
60
  "@tryghost/config-url-helpers": "1.0.27",
61
61
  "@tryghost/custom-fonts": "1.0.11",
62
62
  "@tryghost/database-info": "2.3.2",
@@ -111,7 +111,6 @@
111
111
  "countries-and-timezones": "3.9.0",
112
112
  "csso": "5.0.5",
113
113
  "csv-writer": "1.6.0",
114
- "date-fns": "2.30.0",
115
114
  "dequal": "2.0.3",
116
115
  "dompurify": "3.4.11",
117
116
  "downsize-cjs": "1.1.2",
@@ -192,22 +191,22 @@
192
191
  "ua-parser-js": "1.0.41",
193
192
  "xml": "1.0.1",
194
193
  "zod": "4.4.3",
195
- "@tryghost/adapter-base-cache": "file:components/tryghost-adapter-base-cache-0.2.0.tgz",
196
- "@tryghost/adapter-base-redirects": "file:components/tryghost-adapter-base-redirects-0.0.0.tgz",
197
194
  "@tryghost/adapter-base-route-settings": "file:components/tryghost-adapter-base-route-settings-0.0.0.tgz",
198
- "@tryghost/adapter-base-scheduling": "file:components/tryghost-adapter-base-scheduling-0.2.0.tgz",
195
+ "@tryghost/adapter-base-redirects": "file:components/tryghost-adapter-base-redirects-0.0.0.tgz",
199
196
  "@tryghost/adapter-base-sso": "file:components/tryghost-adapter-base-sso-0.1.1.tgz",
200
197
  "@tryghost/admin-api-schema": "file:components/tryghost-admin-api-schema-0.0.0.tgz",
198
+ "@tryghost/custom-field-types": "file:components/tryghost-custom-field-types-0.0.0.tgz",
199
+ "@tryghost/adapter-base-scheduling": "file:components/tryghost-adapter-base-scheduling-0.2.1.tgz",
200
+ "@tryghost/adapter-base-cache": "file:components/tryghost-adapter-base-cache-0.2.0.tgz",
201
201
  "@tryghost/i18n": "file:components/tryghost-i18n-0.0.0.tgz",
202
202
  "@tryghost/kg-card-factory": "file:components/tryghost-kg-card-factory-5.2.3.tgz",
203
- "@tryghost/kg-converters": "file:components/tryghost-kg-converters-1.2.3.tgz",
204
- "@tryghost/kg-default-cards": "file:components/tryghost-kg-default-cards-10.3.3.tgz",
205
- "@tryghost/kg-default-nodes": "file:components/tryghost-kg-default-nodes-2.1.4.tgz",
203
+ "@tryghost/kg-converters": "file:components/tryghost-kg-converters-1.2.4.tgz",
204
+ "@tryghost/kg-default-cards": "file:components/tryghost-kg-default-cards-10.3.4.tgz",
206
205
  "@tryghost/kg-lexical-html-renderer": "file:components/tryghost-kg-lexical-html-renderer-1.4.3.tgz",
207
- "@tryghost/nql-string": "file:components/tryghost-nql-string-0.0.0.tgz",
208
206
  "@tryghost/parse-email-address": "file:components/tryghost-parse-email-address-0.0.0.tgz",
207
+ "@tryghost/kg-default-nodes": "file:components/tryghost-kg-default-nodes-2.1.5.tgz",
208
+ "@tryghost/nql-string": "file:components/tryghost-nql-string-0.0.0.tgz",
209
209
  "ghost-storage-base": "file:components/ghost-storage-base-3.0.0.tgz",
210
- "@tryghost/custom-field-types": "file:components/tryghost-custom-field-types-0.0.0.tgz",
211
210
  "@tryghost/kg-html-to-lexical": "file:components/tryghost-kg-html-to-lexical-1.3.3.tgz"
212
211
  },
213
212
  "optionalDependencies": {