ghost 6.54.1 → 6.56.0

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 (356) hide show
  1. package/components/tryghost-adapter-base-scheduling-0.2.0.tgz +0 -0
  2. package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
  3. package/components/tryghost-kg-default-nodes-2.1.4.tgz +0 -0
  4. package/components/tryghost-kg-default-transforms-1.3.3.tgz +0 -0
  5. package/components/tryghost-kg-html-to-lexical-1.3.3.tgz +0 -0
  6. package/components/tryghost-kg-lexical-html-renderer-1.4.3.tgz +0 -0
  7. package/components/tryghost-nql-string-0.0.0.tgz +0 -0
  8. package/core/boot.js +3 -6
  9. package/core/built/admin/assets/{Combination-CJG7Flp-.js → Combination-BCm9FL4o.js} +1 -1
  10. package/core/built/admin/assets/{PolarAngleAxis-BGjf7sBu.js → PolarAngleAxis-C4qtHy1B.js} +1 -1
  11. package/core/built/admin/assets/{RadialBarChart-zeFf9mBz.js → RadialBarChart-Bh09Stsj.js} +1 -1
  12. package/core/built/admin/assets/{account-migration-BklF2I_I.js → account-migration-D3O_yVck.js} +1 -1
  13. package/core/built/admin/assets/activitypub/{account-migration-CNovr6W-.js → account-migration-D8FbP-Z-.js} +7 -7
  14. package/core/built/admin/assets/activitypub/activitypub.js +6 -6
  15. package/core/built/admin/assets/activitypub/{avatar-B3DEDB1l.js → avatar-11EA1VSs.js} +2 -2
  16. package/core/built/admin/assets/activitypub/{avatar-flipboard-Cqrg0XMx.js → avatar-flipboard-jfbLG-xe.js} +2 -2
  17. package/core/built/admin/assets/activitypub/{bluesky-sharing-Ceslb1_M.js → bluesky-sharing-f1jTQe2P.js} +16 -16
  18. package/core/built/admin/assets/activitypub/{content-formatters-BpQARh28.js → content-formatters-nmTOPY9M.js} +3 -3
  19. package/core/built/admin/assets/activitypub/{copy-D9UWIAan.js → copy-BCwo9ep3.js} +2 -2
  20. package/core/built/admin/assets/activitypub/{dist-DHAjBcV3.js → dist-BEfX-0aW.js} +12 -12
  21. package/core/built/admin/assets/activitypub/{domain-C1qQvJ8C.js → domain-AaDlZlrA.js} +9 -9
  22. package/core/built/admin/assets/activitypub/{edit-profile-BcH-jEfM.js → edit-profile-DPi8Tl5M.js} +945 -945
  23. package/core/built/admin/assets/activitypub/{explore-AxwBh9dI.js → explore-CxTzjILQ.js} +8 -8
  24. package/core/built/admin/assets/activitypub/{feed-BaOlbh7a.js → feed-DPv5x2MX.js} +33 -33
  25. package/core/built/admin/assets/activitypub/{field-B7mYYQpN.js → field-DbgA8lat.js} +3 -3
  26. package/core/built/admin/assets/activitypub/{hash-BC9Q0N4c.js → hash-BWuZoYkA.js} +2 -2
  27. package/core/built/admin/assets/activitypub/{inbox-DQ4ZnC1m.js → inbox-35VDQ2K2.js} +2 -2
  28. package/core/built/admin/assets/activitypub/{inbox-vXez-5uJ.js → inbox-DSrF_i1O.js} +85 -85
  29. package/core/built/admin/assets/activitypub/{label-Chv5T8bw.js → label-CPjFBbo7.js} +3 -3
  30. package/core/built/admin/assets/activitypub/layout-CTgrezN7.js +1 -0
  31. package/core/built/admin/assets/activitypub/{moderation-DtSM2i1I.js → moderation-BkDC1XVZ.js} +11 -11
  32. package/core/built/admin/assets/activitypub/{note-Dckp4S-2.js → note-xEyH4xT-.js} +7 -7
  33. package/core/built/admin/assets/activitypub/{notifications-CG5T22vg.js → notifications-DClaL3ui.js} +9 -9
  34. package/core/built/admin/assets/activitypub/{preferences-D_799jdl.js → preferences-DpnOa-4Z.js} +20 -20
  35. package/core/built/admin/assets/activitypub/{profile-D2JfXBQl.js → profile-Dvi9mz-6.js} +237 -237
  36. package/core/built/admin/assets/activitypub/{reply-CpdMeAO5.js → reply-Cs9ySd6Z.js} +2 -2
  37. package/core/built/admin/assets/activitypub/{routes-CCHe2dQp.js → routes-DFBeTnfn.js} +1139 -1150
  38. package/core/built/admin/assets/activitypub/{separator-BI1FLsYM.js → separator-C5u_VjzY.js} +3 -3
  39. package/core/built/admin/assets/activitypub/{settings-kx-9Enkz.js → settings-CV2fFu6D.js} +13 -13
  40. package/core/built/admin/assets/activitypub/{site-x4_IjVJ0.js → site-_TgDd_EM.js} +81 -81
  41. package/core/built/admin/assets/activitypub/{step-1-DIDg4aHb.js → step-1-BfnNL2oF.js} +5 -5
  42. package/core/built/admin/assets/activitypub/{step-2-BfGe8BYt.js → step-2-DLndZkO-.js} +6 -6
  43. package/core/built/admin/assets/activitypub/{step-3-mE9spAqw.js → step-3-A-PZTtRE.js} +10 -10
  44. package/core/built/admin/assets/activitypub/{tabs-CyPRQQ1N.js → tabs-BUbz7tea.js} +321 -319
  45. package/core/built/admin/assets/activitypub/{topic-filter-DLHBZT93.js → topic-filter-BdX_xYYT.js} +3 -3
  46. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-VzbN99u_.js → use-activity-pub-queries-EwuRemHh.js} +2 -2
  47. package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-CAwXTmqH.js → use-navigate-with-base-path-cy4ACBc4.js} +92 -90
  48. package/core/built/admin/assets/activitypub/{use-reply-chain-data-BAB6fNGt.js → use-reply-chain-data-CyFcGfan.js} +5 -5
  49. package/core/built/admin/assets/activitypub/{x-C8tAnXly.js → x-7zk8mV2p.js} +2 -2
  50. package/core/built/admin/assets/audience-CkBb2LlO.js +1 -0
  51. package/core/built/admin/assets/{automated-emails-of1MvVsv.js → automated-emails-6t2bIRWf.js} +2 -2
  52. package/core/built/admin/assets/{automations-B7-y3dXt.js → automations-DhKeS_U5.js} +1 -1
  53. package/core/built/admin/assets/{automations-DRFjW5fw.js → automations-cMllU545.js} +1 -1
  54. package/core/built/admin/assets/{bluesky-sharing-BbbjWdzs.js → bluesky-sharing-DPGpyD-G.js} +1 -1
  55. package/core/built/admin/assets/{box-BWbhXh21.js → box-By_EgGtm.js} +1 -1
  56. package/core/built/admin/assets/{breadcrumb-B-M9Ip_2.js → breadcrumb-DIfcF5ow.js} +1 -1
  57. package/core/built/admin/assets/build-CsiH26uS.js +1 -0
  58. package/core/built/admin/assets/{card-DGoDJzrn.js → card-aUHX0hyR.js} +1 -1
  59. package/core/built/admin/assets/{chart-BuRT2Y6p.js → chart-BnXyfH11.js} +1 -1
  60. package/core/built/admin/assets/{chart-helpers-xiSsW8r0.js → chart-helpers-DV0FkdcD.js} +1 -1
  61. package/core/built/admin/assets/{checkbox-EhJKHFdZ.js → checkbox-BIl077a0.js} +1 -1
  62. package/core/built/admin/assets/{chunk.361.3cdb584b973959e52ccc.js → chunk.332.05991a101d67f732dec3.js} +16 -12
  63. package/core/built/admin/assets/chunk.524.87b52f4fada529df2c4c.js +25 -0
  64. package/core/built/admin/assets/chunk.582.340bcca873e806cbd4bb.js +27 -0
  65. package/core/built/admin/assets/{code-editor-view-CZtJFGhR.js → code-editor-view-C0aWNwdl.js} +1 -1
  66. package/core/built/admin/assets/comments-qwhIjH3c.js +1 -0
  67. package/core/built/admin/assets/{container-BYz2Ed39.js → container-LiZf3XdY.js} +1 -1
  68. package/core/built/admin/assets/{data-list-16rkJYYi.js → data-list-CupF7bjM.js} +1 -1
  69. package/core/built/admin/assets/{date-range-select-CTlyo8zW.js → date-range-select-dXc-GsVe.js} +1 -1
  70. package/core/built/admin/assets/{disabled-sources-indicator-qs2GfLvl.js → disabled-sources-indicator-DYAXW-6V.js} +1 -1
  71. package/core/built/admin/assets/dist-BUKmD51u.js +1 -0
  72. package/core/built/admin/assets/{dist-2Tnz2Yfq.js → dist-CNlMj7ML.js} +1 -1
  73. package/core/built/admin/assets/{dist-DGzPJ_bO.js → dist-Cb5RSHSg.js} +1 -1
  74. package/core/built/admin/assets/{dist-P_ohUlTi.js → dist-CqO2lWS0.js} +1 -1
  75. package/core/built/admin/assets/{domain-CPNXKVOV.js → domain-B5ogXUBa.js} +1 -1
  76. package/core/built/admin/assets/{dropzone-BmCXnw6J.js → dropzone-BnFG7dDP.js} +1 -1
  77. package/core/built/admin/assets/{edit-profile-SGrJve5M.js → edit-profile-B07jCZy9.js} +1 -1
  78. package/core/built/admin/assets/editor-DDYSOXGN.js +8 -0
  79. package/core/built/admin/assets/{empty-indicator-oX1u1Pkn.js → empty-indicator-WB1WgT9h.js} +1 -1
  80. package/core/built/admin/assets/{explore-CUYLv9G9.js → explore-Ca1y8HW_.js} +1 -1
  81. package/core/built/admin/assets/{feed-CPdJMttL.js → feed-x4iFMBP4.js} +1 -1
  82. package/core/built/admin/assets/field-ChCAabZg.js +1 -0
  83. package/core/built/admin/assets/filter-sources-LdtH1e-T.js +1 -0
  84. package/core/built/admin/assets/{filters-bXkkWro8.js → filters-CLehPo_D.js} +1 -1
  85. package/core/built/admin/assets/filters-CjVKRP8U.js +1 -0
  86. package/core/built/admin/assets/{ghost-05f9a7182ed56903dba05878a5b8422b.js → ghost-7f01131115186d1af84ead76e79646dd.js} +275 -255
  87. package/core/built/admin/assets/{ghost-3063eae29e6c9cc6d6e7131928a27da0.css → ghost-d38c30b866e59f2e06a357b5eb844fe5.css} +1 -1
  88. package/core/built/admin/assets/{ghost-dark-c8d0ab7f515b2010c173e23e9b32ea8a.css → ghost-dark-1bffd5099ba7a749303133efacf8480b.css} +1 -1
  89. package/core/built/admin/assets/gift-link-modal-Buqh2vXh.js +1 -0
  90. package/core/built/admin/assets/{gift-links-nBxJjZiQ.js → gift-links-CsUhefWG.js} +1 -1
  91. package/core/built/admin/assets/growth-DajOBdN0.js +1 -0
  92. package/core/built/admin/assets/growth-Dy2UOSay.js +3 -0
  93. package/core/built/admin/assets/{hooks-BApwwBE0.js → hooks-CixO01lL.js} +1 -1
  94. package/core/built/admin/assets/{inbox-Xx1CdnfO.js → inbox-BUOLDoji.js} +13 -13
  95. package/core/built/admin/assets/index-08n05-rc.js +67 -0
  96. package/core/built/admin/assets/index-DgUzgFvS.css +1 -0
  97. package/core/built/admin/assets/{inline-EMAm3okk.js → inline-Cw-gigDW.js} +1 -1
  98. package/core/built/admin/assets/input-group-uSK3XT7b.js +1 -0
  99. package/core/built/admin/assets/{input-surface-BpAjZXY5.js → input-surface-BdOe4KzO.js} +1 -1
  100. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +9132 -9087
  101. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +121 -121
  102. package/core/built/admin/assets/koenig-lexical/style.css +1 -1
  103. package/core/built/admin/assets/{koenig-lexical-B61IALf5.js → koenig-lexical-BFc4yFed.js} +82 -82
  104. package/core/built/admin/assets/{kpi-card-DCdlyaSS.js → kpi-card-BN-E6WYX.js} +1 -1
  105. package/core/built/admin/assets/{kpi-card-BlZaG1Lo.js → kpi-card-CCt-qeWD.js} +1 -1
  106. package/core/built/admin/assets/{kpi-helpers-DpAuS1Nb.js → kpi-helpers-DlxTbTs4.js} +1 -1
  107. package/core/built/admin/assets/{kpi-tabs-Dme44bQS.js → kpi-tabs-BlcUttpn.js} +1 -1
  108. package/core/built/admin/assets/{label-dSs5aepE.js → label-AVrxwmsz.js} +1 -1
  109. package/core/built/admin/assets/label-picker-DVnpu_IF.js +1 -0
  110. package/core/built/admin/assets/labels-DAIqKed7.js +1 -0
  111. package/core/built/admin/assets/layout-B0YLh7R9.js +1 -0
  112. package/core/built/admin/assets/link-helpers-D9LsDOkG.js +1 -0
  113. package/core/built/admin/assets/{list-page-B6ANtzkd.js → list-page-CdsnQR9N.js} +1 -1
  114. package/core/built/admin/assets/member-custom-fields-C8NpZYza.js +1 -0
  115. package/core/built/admin/assets/member-detail-CIVAdKXf.js +1 -0
  116. package/core/built/admin/assets/members-oLPiSkXD.js +10 -0
  117. package/core/built/admin/assets/modals-CB7v-k3T.js +31 -0
  118. package/core/built/admin/assets/moderation-CQ3urTFE.js +1 -0
  119. package/core/built/admin/assets/newsletter-rbeDX9Wk.js +1 -0
  120. package/core/built/admin/assets/{newsletters-D1jbtV-h.js → newsletters-BXJbJgA-.js} +1 -1
  121. package/core/built/admin/assets/newsletters-vt3Ni1Ov.js +1 -0
  122. package/core/built/admin/assets/note-Dk877BTv.js +1 -0
  123. package/core/built/admin/assets/notifications-CPlLjPxO.js +1 -0
  124. package/core/built/admin/assets/{offers-CrY6nSRR.js → offers-DEniVRD5.js} +1 -1
  125. package/core/built/admin/assets/onboarding-route-DdStOtjy.js +1 -0
  126. package/core/built/admin/assets/overview--4V-kx9c.js +1 -0
  127. package/core/built/admin/assets/overview-DSLv30oz.js +1 -0
  128. package/core/built/admin/assets/{page-header-op0eN36I.js → page-header-pp4dWmOS.js} +1 -1
  129. package/core/built/admin/assets/{pages-BbNWFcGj.js → pages-B4goRPUn.js} +1 -1
  130. package/core/built/admin/assets/{post-analytics-WwRDEnrV.js → post-analytics-BMJrI81R.js} +1 -1
  131. package/core/built/admin/assets/post-analytics-header-pU2m9ZuV.js +1 -0
  132. package/core/built/admin/assets/post-analytics-provider-Btml5vJI.js +1 -0
  133. package/core/built/admin/assets/{post-share-modal-Dx-MEjhI.js → post-share-modal-AcUZkbfL.js} +1 -1
  134. package/core/built/admin/assets/{posts-EWpZIjkr.js → posts-DhXE7b6r.js} +1 -1
  135. package/core/built/admin/assets/preferences-Ru4CRPHC.js +5 -0
  136. package/core/built/admin/assets/profile-BNb1oj7D.js +1 -0
  137. package/core/built/admin/assets/{referrers-BCfFYSHc.js → referrers-pmJT4k3-.js} +1 -1
  138. package/core/built/admin/assets/{router-provider-C1R4AZ2o.js → router-provider-BmEZf6c6.js} +1 -1
  139. package/core/built/admin/assets/select-B0HteHrp.js +1 -0
  140. package/core/built/admin/assets/settings-B1C9Q3wo.js +4 -0
  141. package/core/built/admin/assets/{settings-H6HxFgfI.js → settings-BGgk7oCI.js} +1 -1
  142. package/core/built/admin/assets/{shade-app-B3heOAfz-CGXQwWeO.js → shade-app-B3heOAfz-BhQXxNkT.js} +1 -1
  143. package/core/built/admin/assets/{share-modal-BJCadJyp.js → share-modal-BeuydaBf.js} +1 -1
  144. package/core/built/admin/assets/social-urls-DA2lXrhW.js +8 -0
  145. package/core/built/admin/assets/{sort-button-DyYlfYp7.js → sort-button-Df4t2AL8.js} +1 -1
  146. package/core/built/admin/assets/{source-icon-_ubRDbg_.js → source-icon-ajoaKb41.js} +1 -1
  147. package/core/built/admin/assets/{stack-xiN0eQ6Z.js → stack-CIfOAAVf.js} +1 -1
  148. package/core/built/admin/assets/{stats-BQZMGMvn.js → stats-C_lfxZAw.js} +1 -1
  149. package/core/built/admin/assets/{stats-view-Doei-qCX.js → stats-view-Cxot1iD8.js} +1 -1
  150. package/core/built/admin/assets/{step-1-IKiLBPoC.js → step-1-ogAA4lDr.js} +1 -1
  151. package/core/built/admin/assets/{step-2-jJ41PsDN.js → step-2-C5Xini-7.js} +1 -1
  152. package/core/built/admin/assets/{step-3-CaqFAEqf.js → step-3-CZv1FV81.js} +2 -2
  153. package/core/built/admin/assets/{switch-t-WyENU2.js → switch-CyQcwMAv.js} +1 -1
  154. package/core/built/admin/assets/{table-DxUL78jU.js → table-DFj1wiYv.js} +1 -1
  155. package/core/built/admin/assets/tabs-D4y1gqUd.js +1 -0
  156. package/core/built/admin/assets/{tags-CNujGwkT.js → tags-Dmft-Y4O.js} +1 -1
  157. package/core/built/admin/assets/{text-DwtjwGkh.js → text-DU9Hv33_.js} +1 -1
  158. package/core/built/admin/assets/textarea-d9qEkMOP.js +1 -0
  159. package/core/built/admin/assets/{tiers-BgYLWRJv.js → tiers-DYsa4DCo.js} +1 -1
  160. package/core/built/admin/assets/{toggle-group-BeEpQ69p.js → toggle-group-R2QMFvXW.js} +1 -1
  161. package/core/built/admin/assets/{topic-filter-Bb5MOD-1.js → topic-filter-DGDxDalo.js} +1 -1
  162. package/core/built/admin/assets/{use-analytics-data-Cds6XDjg.js → use-analytics-data-C76v4LIp.js} +1 -1
  163. package/core/built/admin/assets/use-filter-params-WrdhAISv.js +1 -0
  164. package/core/built/admin/assets/{use-growth-stats-D8uf98-G.js → use-growth-stats-aNXJOmQr.js} +1 -1
  165. package/core/built/admin/assets/{use-post-referrers-CRtgyuXB.js → use-post-referrers-CG0SZioj.js} +1 -1
  166. package/core/built/admin/assets/{use-reply-chain-data-DbKYX50v.js → use-reply-chain-data-RLdPKRmS.js} +1 -1
  167. package/core/built/admin/assets/{use-simple-pagination-DC01kpo0.js → use-simple-pagination-DgcF69KI.js} +1 -1
  168. package/core/built/admin/assets/{use-tinybird-query-C7bQRJWw.js → use-tinybird-query-C1R_Kbmy.js} +1 -1
  169. package/core/built/admin/assets/{use-tinybird-token-Az4tam7_.js → use-tinybird-token-C9fPjVM_.js} +1 -1
  170. package/core/built/admin/assets/{users-CcSCQFcQ.js → users-Dkv8NQZe.js} +1 -1
  171. package/core/built/admin/assets/{virtual-list-Dhuh9fGx.js → virtual-list-BmTUzeoF.js} +1 -1
  172. package/core/built/admin/assets/web-BqW0b0_C.js +1 -0
  173. package/core/built/admin/assets/web-Cy5GKMWM.js +2 -0
  174. package/core/built/admin/index.html +18 -18
  175. package/core/frontend/services/data/fetch-data.js +10 -5
  176. package/core/frontend/services/proxy.js +7 -8
  177. package/core/frontend/services/routing/api-adapter.js +115 -0
  178. package/core/frontend/services/routing/api-adapter.ts +157 -0
  179. package/core/frontend/services/routing/collection-router.js +5 -3
  180. package/core/frontend/services/routing/controllers/index.js +1 -1
  181. package/core/frontend/services/routing/controllers/rss.js +26 -31
  182. package/core/frontend/services/routing/controllers/rss.ts +66 -0
  183. package/core/frontend/services/routing/controllers/static.js +8 -7
  184. package/core/frontend/services/routing/parent-router.js +17 -4
  185. package/core/frontend/services/routing/permalink-adapter.js +26 -0
  186. package/core/frontend/services/routing/permalink-adapter.ts +23 -0
  187. package/core/frontend/services/routing/registry.js +59 -33
  188. package/core/frontend/services/routing/router-manager.js +14 -18
  189. package/core/frontend/services/routing/static-routes-router.js +11 -13
  190. package/core/frontend/services/routing/taxonomy-router.js +6 -2
  191. package/core/server/api/endpoints/automation-action-links.js +68 -0
  192. package/core/server/api/endpoints/automation-action-links.ts +46 -0
  193. package/core/server/api/endpoints/index.js +4 -0
  194. package/core/server/api/endpoints/settings.js +0 -2
  195. package/core/server/api/endpoints/utils/serializers/output/utils/url.js +11 -1
  196. package/core/server/data/migrations/versions/6.55/2026-07-27-11-25-44-add-to-hash-to-redirects.js +51 -0
  197. package/core/server/data/migrations/versions/6.55/2026-07-28-12-08-00-remove-routes-hash-from-settings.js +5 -0
  198. package/core/server/data/migrations/versions/6.56/2026-08-03-19-27-51-add-automation-run-step-id-to-automated-email-recipients.js +8 -0
  199. package/core/server/data/migrations/versions/6.56/2026-08-04-14-42-39-restrict-notification-add-permission-to-administrators.js +12 -0
  200. package/core/server/data/schema/commands.js +5 -0
  201. package/core/server/data/schema/default-settings/default-settings.json +0 -4
  202. package/core/server/data/schema/fixtures/fixtures.json +2 -2
  203. package/core/server/data/schema/schema.js +6 -1
  204. package/core/server/models/post.js +10 -1
  205. package/core/server/services/automations/automations-api.js +15 -0
  206. package/core/server/services/automations/automations-api.ts +19 -0
  207. package/core/server/services/automations/automations-repository.ts +20 -0
  208. package/core/server/services/automations/database-automations-repository.js +132 -30
  209. package/core/server/services/automations/database-automations-repository.ts +141 -12
  210. package/core/server/services/automations/database-date.js +10 -0
  211. package/core/server/services/automations/database-date.ts +5 -0
  212. package/core/server/services/automations/get-scheduler-idempotency-key.js +13 -0
  213. package/core/server/services/automations/get-scheduler-idempotency-key.ts +8 -0
  214. package/core/server/services/automations/poll.js +7 -2
  215. package/core/server/services/automations/poll.ts +10 -2
  216. package/core/server/services/automations/scheduler-poll-time.js +40 -0
  217. package/core/server/services/automations/scheduler-poll-time.ts +38 -0
  218. package/core/server/services/automations/service.js +19 -3
  219. package/core/server/services/automations/service.ts +20 -3
  220. package/core/server/services/comments/comments-service-emails.js +10 -7
  221. package/core/server/services/comments/comments-service.js +9 -4
  222. package/core/server/services/email-rendering/partials/email-wrapper.hbs +3 -1
  223. package/core/server/services/email-service/email-service-wrapper.js +6 -1
  224. package/core/server/services/email-service/email-templates/partials/styles.hbs +8 -0
  225. package/core/server/services/email-service/newsletter-email-event-storage.js +41 -10
  226. package/core/server/services/gift-links/CONTEXT.md +9 -0
  227. package/core/server/services/gifts/CONTEXT.md +55 -0
  228. package/core/server/services/gifts/README.md +28 -0
  229. package/core/server/services/gifts/gift-bookshelf-repository.js +65 -45
  230. package/core/server/services/gifts/gift-bookshelf-repository.ts +203 -74
  231. package/core/server/services/gifts/gift-checkout-adapter.js +59 -0
  232. package/core/server/services/gifts/gift-checkout-offer.js +74 -0
  233. package/core/server/services/gifts/gift-checkout-offer.ts +127 -0
  234. package/core/server/services/gifts/gift-codec.js +63 -0
  235. package/core/server/services/gifts/gift-codec.ts +62 -0
  236. package/core/server/services/gifts/gift-controller.js +6 -31
  237. package/core/server/services/gifts/gift-controller.ts +6 -69
  238. package/core/server/services/gifts/gift-email-service.ts +3 -2
  239. package/core/server/services/gifts/gift-schema.js +34 -0
  240. package/core/server/services/gifts/gift-schema.ts +39 -0
  241. package/core/server/services/gifts/gift-service-wrapper.js +13 -11
  242. package/core/server/services/gifts/gift-service.js +265 -52
  243. package/core/server/services/gifts/gift-service.ts +431 -97
  244. package/core/server/services/gifts/gift.ts +16 -39
  245. package/core/server/services/lib/dynamic-redirect-manager.js +12 -3
  246. package/core/server/services/link-redirection/link-redirect-repository.js +41 -4
  247. package/core/server/services/link-redirection/link-redirect.js +2 -0
  248. package/core/server/services/link-redirection/link-redirect.ts +3 -1
  249. package/core/server/services/link-redirection/link-redirects-service.js +38 -2
  250. package/core/server/services/link-tracking/click-event.js +3 -0
  251. package/core/server/services/link-tracking/index.js +38 -6
  252. package/core/server/services/link-tracking/link-click-repository.js +35 -9
  253. package/core/server/services/link-tracking/link-click-tracking-service.js +54 -4
  254. package/core/server/services/member-attribution/outbound-link-tagger.js +3 -1
  255. package/core/server/services/member-welcome-emails/member-welcome-email-renderer.js +20 -4
  256. package/core/server/services/member-welcome-emails/service.js +15 -3
  257. package/core/server/services/members/api.js +1 -2
  258. package/core/server/services/members/import-export/csv/formula.js +16 -0
  259. package/core/server/services/members/import-export/csv/formula.ts +14 -0
  260. package/core/server/services/members/import-export/csv/index.js +3 -1
  261. package/core/server/services/members/import-export/csv/index.ts +1 -0
  262. package/core/server/services/members/import-export/import/completion-email.js +22 -3
  263. package/core/server/services/members/import-export/import/completion-email.ts +29 -7
  264. package/core/server/services/members/import-export/import/importer.js +25 -4
  265. package/core/server/services/members/import-export/import/importer.ts +44 -5
  266. package/core/server/services/members/import-export/index.js +18 -1
  267. package/core/server/services/members/import-export/index.ts +32 -3
  268. package/core/server/services/members/members-api/controllers/router-controller.js +38 -36
  269. package/core/server/services/members/members-api/members-api.js +13 -7
  270. package/core/server/services/members/members-api/repositories/event-repository.js +4 -94
  271. package/core/server/services/members/members-api/services/member-bread-service.js +3 -3
  272. package/core/server/services/members/members-api/services/payments-service.js +6 -68
  273. package/core/server/services/members/service.js +8 -1
  274. package/core/server/services/members-custom-fields/schema.js +8 -1
  275. package/core/server/services/members-custom-fields/schema.ts +8 -0
  276. package/core/server/services/members-custom-fields/values-service.js +136 -8
  277. package/core/server/services/members-custom-fields/values-service.ts +152 -10
  278. package/core/server/services/mentions/service.js +5 -1
  279. package/core/server/services/oembed/oembed-service.js +44 -3
  280. package/core/server/services/posts/posts-service.js +11 -0
  281. package/core/server/services/route-settings/dynamic-routing-service.js +21 -52
  282. package/core/server/services/route-settings/index.js +1 -16
  283. package/core/server/services/route-settings/route-settings-parser.js +25 -25
  284. package/core/server/services/route-settings/route-settings-parser.ts +27 -27
  285. package/core/server/services/route-settings/validation-errors.js +68 -4
  286. package/core/server/services/route-settings/validation-errors.ts +79 -4
  287. package/core/server/services/settings/settings-service.js +0 -18
  288. package/core/server/services/stats/posts-stats-service.js +27 -23
  289. package/core/server/services/stripe/services/webhook/charge-refunded-event-service.js +1 -1
  290. package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +16 -4
  291. package/core/server/services/stripe/stripe-api.js +10 -0
  292. package/core/server/services/url/url-service-facade.js +1 -1
  293. package/core/server/services/url/url-service-facade.ts +8 -1
  294. package/core/server/web/api/endpoints/admin/routes.js +1 -0
  295. package/core/server/web/gift-preview/controller.js +10 -25
  296. package/core/shared/labs.js +2 -2
  297. package/package.json +8 -7
  298. package/pnpm-lock.yaml +28 -18
  299. package/pnpm-workspace.yaml +6 -4
  300. package/components/tryghost-kg-default-nodes-2.1.3.tgz +0 -0
  301. package/core/built/admin/assets/Growth-BTP1LthE.js +0 -3
  302. package/core/built/admin/assets/Newsletters-CSEX0myc.js +0 -1
  303. package/core/built/admin/assets/Overview-BjACEsJF.js +0 -1
  304. package/core/built/admin/assets/Web-CxxxjCcv.js +0 -2
  305. package/core/built/admin/assets/activitypub/layout-CziktJXo.js +0 -1
  306. package/core/built/admin/assets/audience-X_XsZivI.js +0 -1
  307. package/core/built/admin/assets/chunk.524.8365cd9280405c0f6216.js +0 -25
  308. package/core/built/admin/assets/chunk.582.61d078937e6102769f2c.js +0 -27
  309. package/core/built/admin/assets/comments-CvyXxOyN.js +0 -1
  310. package/core/built/admin/assets/constants-c-JNF9c2.js +0 -1
  311. package/core/built/admin/assets/dist-CjY-f5Z1.js +0 -1
  312. package/core/built/admin/assets/editor-BOG2YPUm.js +0 -8
  313. package/core/built/admin/assets/field-D0XISCK2.js +0 -1
  314. package/core/built/admin/assets/filter-sources-Bieps75g.js +0 -1
  315. package/core/built/admin/assets/filters-CuB-A7ma.js +0 -1
  316. package/core/built/admin/assets/gift-link-modal-su8MsRdg.js +0 -1
  317. package/core/built/admin/assets/growth-Ba6S5FQX.js +0 -1
  318. package/core/built/admin/assets/index-D8PbzuT9.css +0 -1
  319. package/core/built/admin/assets/index-ukW_0Uie.js +0 -67
  320. package/core/built/admin/assets/input-group-CGOXcy4l.js +0 -1
  321. package/core/built/admin/assets/label-picker-Uq91atex.js +0 -1
  322. package/core/built/admin/assets/labels-Cyayfd-e.js +0 -1
  323. package/core/built/admin/assets/layout-WUcz6tu1.js +0 -1
  324. package/core/built/admin/assets/link-helpers-tOlxmuH5.js +0 -1
  325. package/core/built/admin/assets/member-custom-fields-NCzrMuba.js +0 -1
  326. package/core/built/admin/assets/member-detail-DPWDtYnN.js +0 -1
  327. package/core/built/admin/assets/members-B9rO7qr4.js +0 -10
  328. package/core/built/admin/assets/modals-CxRaan1J.js +0 -31
  329. package/core/built/admin/assets/moderation-D8zon60E.js +0 -1
  330. package/core/built/admin/assets/multi-select-combobox-1wYm3nle.js +0 -1
  331. package/core/built/admin/assets/newsletter-DbYMRxRS.js +0 -1
  332. package/core/built/admin/assets/note-PiWPnnrh.js +0 -1
  333. package/core/built/admin/assets/notifications-DEgqqB9G.js +0 -1
  334. package/core/built/admin/assets/nql-BsgFMd93.js +0 -1
  335. package/core/built/admin/assets/onboarding-route-BzF6HeVn.js +0 -1
  336. package/core/built/admin/assets/overview-DixLeIqY.js +0 -1
  337. package/core/built/admin/assets/post-analytics-header-DsMoLx0R.js +0 -1
  338. package/core/built/admin/assets/post-analytics-provider-BJCPLMIb.js +0 -1
  339. package/core/built/admin/assets/preferences-D7-j6A4C.js +0 -5
  340. package/core/built/admin/assets/profile-Dl69QPp0.js +0 -1
  341. package/core/built/admin/assets/select-C1qDZnW4.js +0 -1
  342. package/core/built/admin/assets/settings-BbmC_Iqq.js +0 -4
  343. package/core/built/admin/assets/social-urls-BPL1nADp.js +0 -8
  344. package/core/built/admin/assets/tabs-BQcJQ1ke.js +0 -1
  345. package/core/built/admin/assets/textarea-Bjccvh_E.js +0 -1
  346. package/core/built/admin/assets/use-filter-params-DjXkhO54.js +0 -1
  347. package/core/built/admin/assets/web-LtHNiNBV.js +0 -1
  348. package/core/server/services/gifts/gift-repository.js +0 -2
  349. package/core/server/services/gifts/gift-repository.ts +0 -29
  350. package/core/server/services/route-settings/activation-bridge.js +0 -164
  351. package/core/server/services/route-settings/activation-bridge.ts +0 -210
  352. package/core/server/services/route-settings/default-settings-manager.js +0 -63
  353. package/core/server/services/route-settings/route-settings.js +0 -170
  354. package/core/server/services/route-settings/settings-loader.js +0 -60
  355. package/core/server/services/route-settings/settings-path-manager.js +0 -47
  356. package/core/server/services/route-settings/validate.js +0 -440
@@ -399,29 +399,33 @@ class PostsStatsService {
399
399
 
400
400
  async getGrowthStatsForPost(postId) {
401
401
  try {
402
- const freeMembers = await this.knex('members_created_events as mce')
403
- .countDistinct('mce.member_id as free_members')
404
- .leftJoin('members_subscription_created_events as msce', function () {
405
- this.on('mce.member_id', '=', 'msce.member_id')
406
- .andOn('mce.attribution_id', '=', 'msce.attribution_id');
407
- })
408
- .where('mce.attribution_id', postId)
409
- .whereIn('mce.attribution_type', ['post', 'page'])
410
- .where('msce.id', null);
411
-
412
- const paidMembers = await this.knex('members_subscription_created_events as msce')
413
- .countDistinct('msce.member_id as paid_members')
414
- .where('msce.attribution_id', postId)
415
- .whereIn('msce.attribution_type', ['post', 'page']);
416
-
417
- const mrr = await this.knex('members_subscription_created_events as msce')
418
- .sum('mpse.mrr_delta as mrr')
419
- .join('members_paid_subscription_events as mpse', function () {
420
- this.on('mpse.subscription_id', '=', 'msce.subscription_id');
421
- this.andOn('mpse.member_id', '=', 'msce.member_id');
422
- })
423
- .where('msce.attribution_id', postId)
424
- .whereIn('msce.attribution_type', ['post', 'page']);
402
+ // The three aggregates only depend on postId, so run them together:
403
+ // the wait becomes the slowest query instead of the sum of all three.
404
+ const [freeMembers, paidMembers, mrr] = await Promise.all([
405
+ this.knex('members_created_events as mce')
406
+ .countDistinct('mce.member_id as free_members')
407
+ .leftJoin('members_subscription_created_events as msce', function () {
408
+ this.on('mce.member_id', '=', 'msce.member_id')
409
+ .andOn('mce.attribution_id', '=', 'msce.attribution_id');
410
+ })
411
+ .where('mce.attribution_id', postId)
412
+ .whereIn('mce.attribution_type', ['post', 'page'])
413
+ .where('msce.id', null),
414
+
415
+ this.knex('members_subscription_created_events as msce')
416
+ .countDistinct('msce.member_id as paid_members')
417
+ .where('msce.attribution_id', postId)
418
+ .whereIn('msce.attribution_type', ['post', 'page']),
419
+
420
+ this.knex('members_subscription_created_events as msce')
421
+ .sum('mpse.mrr_delta as mrr')
422
+ .join('members_paid_subscription_events as mpse', function () {
423
+ this.on('mpse.subscription_id', '=', 'msce.subscription_id');
424
+ this.andOn('mpse.member_id', '=', 'msce.member_id');
425
+ })
426
+ .where('msce.attribution_id', postId)
427
+ .whereIn('msce.attribution_type', ['post', 'page'])
428
+ ]);
425
429
 
426
430
  return {
427
431
  data: [
@@ -50,7 +50,7 @@ module.exports = class ChargeRefundedEventService {
50
50
  * @private
51
51
  */
52
52
  async handleGiftRefundEvent(paymentIntentId) {
53
- const refunded = await this.deps.giftService.refund(paymentIntentId);
53
+ const refunded = await this.deps.giftService.handlePaymentRefund({paymentIntentId});
54
54
 
55
55
  if (!refunded) {
56
56
  logging.info(`charge.refunded: no gift found for payment_intent ${paymentIntentId}, skipping`);
@@ -18,6 +18,18 @@ function hasConflictingCheckoutFlowMetadata(metadata) {
18
18
  return hasStripeMetadataKey(metadata, 'ghost_donation') && hasStripeMetadataKey(metadata, 'ghost_gift');
19
19
  }
20
20
 
21
+ function getStripeResourceId(resource) {
22
+ if (typeof resource === 'string') {
23
+ return resource;
24
+ }
25
+
26
+ if (resource && typeof resource === 'object' && typeof resource.id === 'string') {
27
+ return resource.id;
28
+ }
29
+
30
+ return null;
31
+ }
32
+
21
33
  /**
22
34
  * Handles `checkout.session.completed` webhook events
23
35
  *
@@ -83,17 +95,17 @@ module.exports = class CheckoutSessionEventService {
83
95
  * @param {import('stripe').Stripe.Checkout.Session} session
84
96
  */
85
97
  async handleGiftEvent(session) {
86
- await this.deps.giftService.recordPurchase({
98
+ await this.deps.giftService.completePurchase({
87
99
  token: session.metadata?.gift_token,
88
100
  buyerEmail: session.customer_details?.email,
89
- stripeCustomerId: session.customer ?? null,
101
+ stripeCustomerId: getStripeResourceId(session.customer),
90
102
  tierId: session.metadata?.tier_id,
91
103
  cadence: session.metadata?.cadence,
92
- duration: session.metadata?.duration,
104
+ duration: Number(session.metadata?.duration),
93
105
  currency: session.currency,
94
106
  amount: session.amount_total,
95
107
  stripeCheckoutSessionId: session.id,
96
- stripePaymentIntentId: session.payment_intent
108
+ stripePaymentIntentId: getStripeResourceId(session.payment_intent)
97
109
  });
98
110
  }
99
111
 
@@ -23,6 +23,12 @@ const SEARCH_MODE_RATE_LIMIT = isTesting ? 10_000 : 100;
23
23
 
24
24
  const STRIPE_API_VERSION = '2020-08-27';
25
25
 
26
+ // Stripe's Managed Payments does not support Connect, and some Stripe
27
+ // accounts have it enabled by default for all Checkout Sessions.
28
+ // On those accounts, session creation fails with "Managed Payments cannot be
29
+ // used with Connect" unless it is explicitly disabled per session.
30
+ const MANAGED_PAYMENTS_DISABLED = {enabled: false};
31
+
26
32
  /**
27
33
  * @typedef {import('stripe').Stripe.Customer} ICustomer
28
34
  * @typedef {import('stripe').Stripe.DeletedCustomer} IDeletedCustomer
@@ -584,6 +590,7 @@ module.exports = class StripeAPI {
584
590
 
585
591
  let stripeSessionOptions = {
586
592
  payment_method_types: this.PAYMENT_METHOD_TYPES,
593
+ managed_payments: MANAGED_PAYMENTS_DISABLED,
587
594
  success_url: options.successUrl || this._config.checkoutSessionSuccessUrl,
588
595
  cancel_url: options.cancelUrl || this._config.checkoutSessionCancelUrl,
589
596
  // @ts-ignore - we need to update to latest stripe library to correctly use newer features
@@ -649,6 +656,7 @@ module.exports = class StripeAPI {
649
656
 
650
657
  const stripeSessionOptions = {
651
658
  mode: 'payment',
659
+ managed_payments: MANAGED_PAYMENTS_DISABLED,
652
660
  success_url: successUrl || this._config.checkoutSessionSuccessUrl,
653
661
  cancel_url: cancelUrl || this._config.checkoutSessionCancelUrl,
654
662
  automatic_tax: {
@@ -715,6 +723,7 @@ module.exports = class StripeAPI {
715
723
 
716
724
  const stripeSessionOptions = {
717
725
  mode: 'payment',
726
+ managed_payments: MANAGED_PAYMENTS_DISABLED,
718
727
  success_url: successUrl,
719
728
  cancel_url: cancelUrl,
720
729
  automatic_tax: {
@@ -761,6 +770,7 @@ module.exports = class StripeAPI {
761
770
  await this._rateLimitBucket.throttle();
762
771
  const session = await this._stripe.checkout.sessions.create({
763
772
  mode: 'setup',
773
+ managed_payments: MANAGED_PAYMENTS_DISABLED,
764
774
  payment_method_types: this.PAYMENT_METHOD_TYPES,
765
775
  success_url: options.successUrl || this._config.checkoutSetupSessionSuccessUrl,
766
776
  cancel_url: options.cancelUrl || this._config.checkoutSetupSessionCancelUrl,
@@ -49,7 +49,7 @@ class UrlServiceFacade {
49
49
  }
50
50
  const url = this.urlService.getUrlByResourceId(resource.id, options);
51
51
  if (this.isComparing() && !options?.skipComparison) {
52
- const context = this._compareContext(resource);
52
+ const context = this._compareContext(resource, options?.serializerContext ? { serializer: options.serializerContext } : {});
53
53
  // Snapshot: callers mutate the resource's nested objects in place
54
54
  // after this returns, but the comparison runs later via setImmediate.
55
55
  const snapshot = _.cloneDeep(resource);
@@ -43,6 +43,12 @@ export interface UrlOptions {
43
43
  // rows per rebuild would only capture stacks and recompute for nothing.
44
44
  // Dies with compare mode.
45
45
  skipComparison?: boolean;
46
+ // Diagnostic only: the producing api endpoint (docName/method/apiType),
47
+ // threaded from the output serializer so a compare mismatch or thin-resource
48
+ // throw names its producer in the logs. The compare-log caller stack
49
+ // truncates at the async api-framework boundary, so the stack alone can't.
50
+ // Ignored by both backends; only read into the compare context.
51
+ serializerContext?: {apiType?: string; docName?: string; method?: string};
46
52
  }
47
53
 
48
54
  /**
@@ -138,7 +144,8 @@ export class UrlServiceFacade {
138
144
  }
139
145
  const url = this.urlService.getUrlByResourceId(resource.id, options);
140
146
  if (this.isComparing() && !options?.skipComparison) {
141
- const context = this._compareContext(resource);
147
+ const context = this._compareContext(resource,
148
+ options?.serializerContext ? {serializer: options.serializerContext} : {});
142
149
  // Snapshot: callers mutate the resource's nested objects in place
143
150
  // after this returns, but the comparison runs later via setImmediate.
144
151
  const snapshot = _.cloneDeep(resource);
@@ -208,6 +208,7 @@ module.exports = function apiRoutes() {
208
208
 
209
209
  // ## Automations
210
210
  router.get('/automations', mw.authAdminApi, http(api.automations.browse));
211
+ router.get('/automations/:automation_id/actions/:action_id/links', mw.authAdminApi, http(api.automationActionLinks.browse));
211
212
  router.get('/automations/:id', mw.authAdminApi, http(api.automations.read));
212
213
  router.post('/automations/:id/email_preview', mw.authAdminApi, http(api.automationEmailPreviews.preview));
213
214
  router.post('/automations/:id/email_test', shared.middleware.brute.previewEmailLimiter, mw.authAdminApi, http(api.automationEmailPreviews.sendTestEmail));
@@ -39,7 +39,6 @@ function escapeHtml(str) {
39
39
 
40
40
  async function giftPreview(req, res) {
41
41
  const giftService = require('../../services/gifts').service;
42
- const tiersService = require('../../services/tiers');
43
42
  const urlUtils = require('../../../shared/url-utils').default;
44
43
  const settingsCache = require('../../../shared/settings-cache');
45
44
 
@@ -48,21 +47,14 @@ async function giftPreview(req, res) {
48
47
  const {token} = req.params;
49
48
  const siteTitle = settingsCache.get('title') || 'Ghost';
50
49
 
51
- let gift;
52
- let tier;
50
+ let preview;
53
51
 
54
52
  try {
55
- gift = await giftService.getByToken(token);
53
+ preview = await giftService.getPreview(token);
56
54
 
57
- if (!gift) {
55
+ if (!preview) {
58
56
  throw new errors.NotFoundError({message: `Gift not found for token`});
59
57
  }
60
-
61
- tier = await tiersService.api.read(gift.tierId);
62
-
63
- if (!tier) {
64
- throw new errors.NotFoundError({message: `Tier not found for gift: ${gift.id}`});
65
- }
66
58
  } catch (err) {
67
59
  logging.warn(`Gift preview: failed to load required gift data, redirecting to homepage`, err);
68
60
 
@@ -70,9 +62,9 @@ async function giftPreview(req, res) {
70
62
  }
71
63
 
72
64
  const ogTitle = getOgTitle({
73
- cadence: gift.cadence,
74
- duration: gift.duration,
75
- tierName: tier.name,
65
+ cadence: preview.cadence,
66
+ duration: preview.duration,
67
+ tierName: preview.tier.name,
76
68
  siteTitle
77
69
  });
78
70
  const ogDescription = t('Open this link to redeem your gift.');
@@ -120,33 +112,26 @@ async function giftPreview(req, res) {
120
112
  async function giftPreviewImage(req, res) {
121
113
  const giftService = require('../../services/gifts').service;
122
114
  const settingsCache = require('../../../shared/settings-cache');
123
- const tiersService = require('../../services/tiers');
124
115
 
125
116
  const accentColor = settingsCache.get('accent_color') || '#15171A';
126
117
  const siteTitle = settingsCache.get('title') || 'Ghost';
127
118
  const {token} = req.params;
128
119
 
129
120
  try {
130
- const gift = await giftService.getByToken(token);
121
+ const preview = await giftService.getPreview(token);
131
122
 
132
- if (!gift) {
123
+ if (!preview) {
133
124
  throw new errors.NotFoundError({message: `Gift not found for token`});
134
125
  }
135
126
 
136
- const tier = await tiersService.api.read(gift.tierId);
137
-
138
- if (!tier) {
139
- throw new errors.NotFoundError({message: `Tier not found for gift: ${gift.id}`});
140
- }
141
-
142
127
  const png = await generateGiftPreviewImage({
143
128
  accentColor,
144
129
  siteTitle,
145
130
  tierLabel: t('{tierName} membership', {
146
- tierName: tier.name,
131
+ tierName: preview.tier.name,
147
132
  interpolation: {escapeValue: false}
148
133
  }),
149
- cadenceLabel: getCadenceLabel(gift.cadence, gift.duration)
134
+ cadenceLabel: getCadenceLabel(preview.cadence, preview.duration)
150
135
  });
151
136
 
152
137
  res.set('Content-Type', 'image/png');
@@ -64,8 +64,8 @@ const PRIVATE_FEATURES = [
64
64
  'getHelperDeduplication',
65
65
  'memberDetailsReact',
66
66
  'membersCustomFields',
67
- 'previewByTier',
68
- 'paywallImprovements'
67
+ 'paywallImprovements',
68
+ 'giftSubCustomization'
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.54.1",
3
+ "version": "6.56.0",
4
4
  "description": "The professional publishing platform",
5
5
  "author": "Ghost Foundation",
6
6
  "homepage": "https://ghost.org",
@@ -193,21 +193,22 @@
193
193
  "xml": "1.0.1",
194
194
  "zod": "4.4.3",
195
195
  "@tryghost/adapter-base-cache": "file:components/tryghost-adapter-base-cache-0.2.0.tgz",
196
- "@tryghost/adapter-base-route-settings": "file:components/tryghost-adapter-base-route-settings-0.0.0.tgz",
197
196
  "@tryghost/adapter-base-redirects": "file:components/tryghost-adapter-base-redirects-0.0.0.tgz",
197
+ "@tryghost/adapter-base-route-settings": "file:components/tryghost-adapter-base-route-settings-0.0.0.tgz",
198
198
  "@tryghost/adapter-base-scheduling": "file:components/tryghost-adapter-base-scheduling-0.2.0.tgz",
199
199
  "@tryghost/adapter-base-sso": "file:components/tryghost-adapter-base-sso-0.1.1.tgz",
200
200
  "@tryghost/admin-api-schema": "file:components/tryghost-admin-api-schema-0.0.0.tgz",
201
- "@tryghost/custom-field-types": "file:components/tryghost-custom-field-types-0.0.0.tgz",
202
201
  "@tryghost/i18n": "file:components/tryghost-i18n-0.0.0.tgz",
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",
203
204
  "@tryghost/kg-default-cards": "file:components/tryghost-kg-default-cards-10.3.3.tgz",
204
- "@tryghost/kg-html-to-lexical": "file:components/tryghost-kg-html-to-lexical-1.3.3.tgz",
205
- "@tryghost/kg-default-nodes": "file:components/tryghost-kg-default-nodes-2.1.3.tgz",
205
+ "@tryghost/kg-default-nodes": "file:components/tryghost-kg-default-nodes-2.1.4.tgz",
206
206
  "@tryghost/kg-lexical-html-renderer": "file:components/tryghost-kg-lexical-html-renderer-1.4.3.tgz",
207
- "@tryghost/kg-card-factory": "file:components/tryghost-kg-card-factory-5.2.3.tgz",
207
+ "@tryghost/nql-string": "file:components/tryghost-nql-string-0.0.0.tgz",
208
208
  "@tryghost/parse-email-address": "file:components/tryghost-parse-email-address-0.0.0.tgz",
209
209
  "ghost-storage-base": "file:components/ghost-storage-base-3.0.0.tgz",
210
- "@tryghost/kg-converters": "file:components/tryghost-kg-converters-1.2.3.tgz"
210
+ "@tryghost/custom-field-types": "file:components/tryghost-custom-field-types-0.0.0.tgz",
211
+ "@tryghost/kg-html-to-lexical": "file:components/tryghost-kg-html-to-lexical-1.3.3.tgz"
211
212
  },
212
213
  "optionalDependencies": {
213
214
  "better-sqlite3": "12.11.1"
package/pnpm-lock.yaml CHANGED
@@ -60,22 +60,23 @@ overrides:
60
60
  '@xmldom/xmldom@<0.8.13': ^0.9.0
61
61
  perf-primitives: ^0.0.6
62
62
  '@tryghost/adapter-base-redirects': file:components/tryghost-adapter-base-redirects-0.0.0.tgz
63
- '@tryghost/adapter-base-cache': file:components/tryghost-adapter-base-cache-0.2.0.tgz
64
63
  '@tryghost/adapter-base-route-settings': file:components/tryghost-adapter-base-route-settings-0.0.0.tgz
64
+ '@tryghost/adapter-base-scheduling': file:components/tryghost-adapter-base-scheduling-0.2.0.tgz
65
+ '@tryghost/adapter-base-cache': file:components/tryghost-adapter-base-cache-0.2.0.tgz
65
66
  '@tryghost/adapter-base-sso': file:components/tryghost-adapter-base-sso-0.1.1.tgz
66
67
  '@tryghost/custom-field-types': file:components/tryghost-custom-field-types-0.0.0.tgz
67
- '@tryghost/adapter-base-scheduling': file:components/tryghost-adapter-base-scheduling-0.2.0.tgz
68
68
  '@tryghost/kg-card-factory': file:components/tryghost-kg-card-factory-5.2.3.tgz
69
69
  '@tryghost/admin-api-schema': file:components/tryghost-admin-api-schema-0.0.0.tgz
70
- '@tryghost/kg-utils': file:components/tryghost-kg-utils-1.1.3.tgz
71
70
  '@tryghost/kg-converters': file:components/tryghost-kg-converters-1.2.3.tgz
71
+ '@tryghost/kg-utils': file:components/tryghost-kg-utils-1.1.3.tgz
72
+ '@tryghost/nql-string': file:components/tryghost-nql-string-0.0.0.tgz
72
73
  '@tryghost/kg-clean-basic-html': file:components/tryghost-kg-clean-basic-html-4.3.3.tgz
73
74
  '@tryghost/parse-email-address': file:components/tryghost-parse-email-address-0.0.0.tgz
74
75
  ghost-storage-base: file:components/ghost-storage-base-3.0.0.tgz
75
76
  '@tryghost/i18n': file:components/tryghost-i18n-0.0.0.tgz
76
77
  '@tryghost/kg-markdown-html-renderer': file:components/tryghost-kg-markdown-html-renderer-7.2.3.tgz
77
78
  '@tryghost/kg-default-cards': file:components/tryghost-kg-default-cards-10.3.3.tgz
78
- '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.3.tgz
79
+ '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.4.tgz
79
80
  '@tryghost/kg-default-transforms': file:components/tryghost-kg-default-transforms-1.3.3.tgz
80
81
  '@tryghost/kg-html-to-lexical': file:components/tryghost-kg-html-to-lexical-1.3.3.tgz
81
82
  '@tryghost/kg-lexical-html-renderer': file:components/tryghost-kg-lexical-html-renderer-1.4.3.tgz
@@ -183,8 +184,8 @@ importers:
183
184
  specifier: file:components/tryghost-kg-default-cards-10.3.3.tgz
184
185
  version: file:components/tryghost-kg-default-cards-10.3.3.tgz(encoding@0.1.13)
185
186
  '@tryghost/kg-default-nodes':
186
- specifier: file:components/tryghost-kg-default-nodes-2.1.3.tgz
187
- version: file:components/tryghost-kg-default-nodes-2.1.3.tgz(@noble/hashes@1.8.0)
187
+ specifier: file:components/tryghost-kg-default-nodes-2.1.4.tgz
188
+ version: file:components/tryghost-kg-default-nodes-2.1.4.tgz(@noble/hashes@1.8.0)
188
189
  '@tryghost/kg-html-to-lexical':
189
190
  specifier: file:components/tryghost-kg-html-to-lexical-1.3.3.tgz
190
191
  version: file:components/tryghost-kg-html-to-lexical-1.3.3.tgz(@lexical/selection@0.13.1(lexical@0.13.1))(@lexical/utils@0.13.1(lexical@0.13.1))(@noble/hashes@1.8.0)
@@ -221,6 +222,9 @@ importers:
221
222
  '@tryghost/nql-lang':
222
223
  specifier: 0.6.6
223
224
  version: 0.6.6
225
+ '@tryghost/nql-string':
226
+ specifier: file:components/tryghost-nql-string-0.0.0.tgz
227
+ version: file:components/tryghost-nql-string-0.0.0.tgz
224
228
  '@tryghost/parse-email-address':
225
229
  specifier: file:components/tryghost-parse-email-address-0.0.0.tgz
226
230
  version: file:components/tryghost-parse-email-address-0.0.0.tgz
@@ -1304,7 +1308,7 @@ packages:
1304
1308
  version: 0.0.0
1305
1309
 
1306
1310
  '@tryghost/adapter-base-scheduling@file:components/tryghost-adapter-base-scheduling-0.2.0.tgz':
1307
- resolution: {integrity: sha512-GpXwbQLqrlzPBLUXoW0Bv4v47jjJ6sW3uanFHannFqYeOyJliBrG+IUz6PPQYt023AKTq6pkZnqnrKBr3FwD2w==, tarball: file:components/tryghost-adapter-base-scheduling-0.2.0.tgz}
1311
+ resolution: {integrity: sha512-i924QLy62EpWz9Spo332BOMh6peM14GsuNPoZH4i7eCDSCt5M8M+dytzNyeAxqMnsik2SWgdb7v3CoPaIyv8KA==, tarball: file:components/tryghost-adapter-base-scheduling-0.2.0.tgz}
1308
1312
  version: 0.2.0
1309
1313
 
1310
1314
  '@tryghost/adapter-base-sso@file:components/tryghost-adapter-base-sso-0.1.1.tgz':
@@ -1368,7 +1372,7 @@ packages:
1368
1372
  resolution: {integrity: sha512-fTAJPbBEOQgb7K2XXt3M9YDpfLrLPpbg/FrNZBOWoz6g4T/jtqPE11EnPVvIan/8dhgjC3uORcCh9kF/JuOmnA==}
1369
1373
 
1370
1374
  '@tryghost/custom-field-types@file:components/tryghost-custom-field-types-0.0.0.tgz':
1371
- resolution: {integrity: sha512-L/X2s5s6j9yEo/1Vpd0uLJdKCRVi3MVGe11OnSiMbd8j1msv0p2RQ3ZsRjbjouepwGHYM5hoTDxn4FTg9gF0Ng==, tarball: file:components/tryghost-custom-field-types-0.0.0.tgz}
1375
+ resolution: {integrity: sha512-Nrx7P7q+4YnIgpv1QiFfe5KRLNdCOH1IcaQXQu9sK3IpCefmCR0h0nmdJcB6gLTcQyCGyL6zf9PteLwY4M31rA==, tarball: file:components/tryghost-custom-field-types-0.0.0.tgz}
1372
1376
  version: 0.0.0
1373
1377
 
1374
1378
  '@tryghost/custom-fonts@1.0.11':
@@ -1448,21 +1452,21 @@ packages:
1448
1452
  version: 10.3.3
1449
1453
  engines: {node: ^22.13.1 || ^24.0.0}
1450
1454
 
1451
- '@tryghost/kg-default-nodes@file:components/tryghost-kg-default-nodes-2.1.3.tgz':
1452
- resolution: {integrity: sha512-R10lI/G/kHBeRgHg6z/0uraR4zJkMXnql6lhIU+pG1Yo5sJivKQ3yjNMR+yIsZ8ng8QK5Yd+CTOReQ7Mfk9rcg==, tarball: file:components/tryghost-kg-default-nodes-2.1.3.tgz}
1453
- version: 2.1.3
1455
+ '@tryghost/kg-default-nodes@file:components/tryghost-kg-default-nodes-2.1.4.tgz':
1456
+ resolution: {integrity: sha512-d6hwQiz3oumlEHLhVx/FQpUXXl8eNpSFEkLlb7YgODM6J5uUp0b3fLFVoU1xXBALjBplEFHb4Gn5YSKh6zEUAQ==, tarball: file:components/tryghost-kg-default-nodes-2.1.4.tgz}
1457
+ version: 2.1.4
1454
1458
  engines: {node: ^22.13.1 || ^24.0.0}
1455
1459
 
1456
1460
  '@tryghost/kg-default-transforms@file:components/tryghost-kg-default-transforms-1.3.3.tgz':
1457
- resolution: {integrity: sha512-LYu87pokySxbqoWRq2SY8SaGknTBsScLy1DDSp6+c6NXNOWUkRi4/XdV4hG49qvAKQQVohJIepbBwgFsvVusWA==, tarball: file:components/tryghost-kg-default-transforms-1.3.3.tgz}
1461
+ resolution: {integrity: sha512-1XkdffnYETy7ZXvHCdmyr/trM/wtUoju29FSF8PNKj65/YVdlb56BSdl38C6MD5TsYxAfjULe1BMn/OgEskhXQ==, tarball: file:components/tryghost-kg-default-transforms-1.3.3.tgz}
1458
1462
  version: 1.3.3
1459
1463
 
1460
1464
  '@tryghost/kg-html-to-lexical@file:components/tryghost-kg-html-to-lexical-1.3.3.tgz':
1461
- resolution: {integrity: sha512-r9wGwPDxJ2CUbZc+SsoBBUs7FnNiL6FHWU3UKlPxiuLHeBXXcpUEE5BdCMcvTGUwPo/T0zmhUtbp6rCBLw7D6Q==, tarball: file:components/tryghost-kg-html-to-lexical-1.3.3.tgz}
1465
+ resolution: {integrity: sha512-WfcWr11CFtT4tst1D9WP3tPSNE79F1U0NtPpqucEn+y1Slruxxw5kdnRY8HRYeyPwfXE2Rr1iVnqP9omSGSOeA==, tarball: file:components/tryghost-kg-html-to-lexical-1.3.3.tgz}
1462
1466
  version: 1.3.3
1463
1467
 
1464
1468
  '@tryghost/kg-lexical-html-renderer@file:components/tryghost-kg-lexical-html-renderer-1.4.3.tgz':
1465
- resolution: {integrity: sha512-u0UR00P2v2D98i7+MelmkxRtxfi3P3IcGrxbAUm/ijqn8iWhwQ8ikPO4wnRBvShed33xgXoSzeAYL6K8hfO0UA==, tarball: file:components/tryghost-kg-lexical-html-renderer-1.4.3.tgz}
1469
+ resolution: {integrity: sha512-AnyKgGOxkq8nxQixpgJwSWo24zIx0WB6ZIRTKYA+0RLQft7LZGoalKNUQfvONQy++m4Y9EAqy21df8VGQvsqIA==, tarball: file:components/tryghost-kg-lexical-html-renderer-1.4.3.tgz}
1466
1470
  version: 1.4.3
1467
1471
 
1468
1472
  '@tryghost/kg-markdown-html-renderer@file:components/tryghost-kg-markdown-html-renderer-7.2.3.tgz':
@@ -1501,6 +1505,10 @@ packages:
1501
1505
  '@tryghost/nql-lang@0.6.6':
1502
1506
  resolution: {integrity: sha512-ZWEUN92fVnxavf+matwASvi7pom0i1jhAtNCuoCN9f3ShtyrVm92m1SfvY+x/XuEvbefXAzCGzSEMcaQ4cqoXw==}
1503
1507
 
1508
+ '@tryghost/nql-string@file:components/tryghost-nql-string-0.0.0.tgz':
1509
+ resolution: {integrity: sha512-sbvE9JUjBRUHOOMMLQj9X+a2QjdCDbL6T9+/j07XA2mFSIi9kHNMcvTxP5KkxB07ANRYvSzLsxicFQFis2wu0w==, tarball: file:components/tryghost-nql-string-0.0.0.tgz}
1510
+ version: 0.0.0
1511
+
1504
1512
  '@tryghost/nql@0.13.1':
1505
1513
  resolution: {integrity: sha512-TQRDur1miWd2ORa3XOhtw8Na8AUj/8h+epNMDgiutOyAH/RTw+d+ksLndMnm/Z9MhnKg7kFy7398peKZ7nF8bQ==}
1506
1514
 
@@ -6490,7 +6498,7 @@ snapshots:
6490
6498
  transitivePeerDependencies:
6491
6499
  - encoding
6492
6500
 
6493
- '@tryghost/kg-default-nodes@file:components/tryghost-kg-default-nodes-2.1.3.tgz(@noble/hashes@1.8.0)':
6501
+ '@tryghost/kg-default-nodes@file:components/tryghost-kg-default-nodes-2.1.4.tgz(@noble/hashes@1.8.0)':
6494
6502
  dependencies:
6495
6503
  '@lexical/clipboard': 0.13.1(lexical@0.13.1)
6496
6504
  '@lexical/rich-text': 0.13.1(@lexical/clipboard@0.13.1(lexical@0.13.1))(@lexical/selection@0.13.1(lexical@0.13.1))(@lexical/utils@0.13.1(lexical@0.13.1))(lexical@0.13.1)
@@ -6515,7 +6523,7 @@ snapshots:
6515
6523
  '@lexical/list': 0.13.1(lexical@0.13.1)
6516
6524
  '@lexical/rich-text': 0.13.1(@lexical/clipboard@0.13.1(lexical@0.13.1))(@lexical/selection@0.13.1(lexical@0.13.1))(@lexical/utils@0.13.1(lexical@0.13.1))(lexical@0.13.1)
6517
6525
  '@lexical/utils': 0.13.1(lexical@0.13.1)
6518
- '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.3.tgz(@noble/hashes@1.8.0)
6526
+ '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.4.tgz(@noble/hashes@1.8.0)
6519
6527
  lexical: 0.13.1
6520
6528
  transitivePeerDependencies:
6521
6529
  - '@lexical/clipboard'
@@ -6531,7 +6539,7 @@ snapshots:
6531
6539
  '@lexical/link': 0.13.1(lexical@0.13.1)
6532
6540
  '@lexical/list': 0.13.1(lexical@0.13.1)
6533
6541
  '@lexical/rich-text': 0.13.1(@lexical/clipboard@0.13.1(lexical@0.13.1))(@lexical/selection@0.13.1(lexical@0.13.1))(@lexical/utils@0.13.1(lexical@0.13.1))(lexical@0.13.1)
6534
- '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.3.tgz(@noble/hashes@1.8.0)
6542
+ '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.4.tgz(@noble/hashes@1.8.0)
6535
6543
  '@tryghost/kg-default-transforms': file:components/tryghost-kg-default-transforms-1.3.3.tgz(@lexical/clipboard@0.13.1(lexical@0.13.1))(@lexical/selection@0.13.1(lexical@0.13.1))(@noble/hashes@1.8.0)
6536
6544
  jsdom: 29.1.1(@noble/hashes@1.8.0)
6537
6545
  lexical: 0.13.1
@@ -6548,7 +6556,7 @@ snapshots:
6548
6556
  '@lexical/link': 0.13.1(lexical@0.13.1)
6549
6557
  '@lexical/list': 0.13.1(lexical@0.13.1)
6550
6558
  '@lexical/rich-text': 0.13.1(@lexical/clipboard@0.13.1(lexical@0.13.1))(@lexical/selection@0.13.1(lexical@0.13.1))(@lexical/utils@0.13.1(lexical@0.13.1))(lexical@0.13.1)
6551
- '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.3.tgz(@noble/hashes@1.8.0)
6559
+ '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.4.tgz(@noble/hashes@1.8.0)
6552
6560
  '@tryghost/kg-default-transforms': file:components/tryghost-kg-default-transforms-1.3.3.tgz(@lexical/clipboard@0.13.1(lexical@0.13.1))(@lexical/selection@0.13.1(lexical@0.13.1))(@noble/hashes@1.8.0)
6553
6561
  '@tryghost/kg-utils': file:components/tryghost-kg-utils-1.1.3.tgz
6554
6562
  jsdom: 29.1.1(@noble/hashes@1.8.0)
@@ -6699,6 +6707,8 @@ snapshots:
6699
6707
  dependencies:
6700
6708
  date-fns: 2.30.0
6701
6709
 
6710
+ '@tryghost/nql-string@file:components/tryghost-nql-string-0.0.0.tgz': {}
6711
+
6702
6712
  '@tryghost/nql@0.13.1(supports-color@10.2.2)':
6703
6713
  dependencies:
6704
6714
  '@tryghost/mongo-knex': 0.10.1(supports-color@10.2.2)
@@ -137,6 +137,7 @@ catalog:
137
137
  '@dnd-kit/core': 6.3.1
138
138
  '@dnd-kit/sortable': 7.0.2
139
139
  '@dnd-kit/utilities': 3.2.2
140
+ shell-quote: 1.10.0
140
141
  catalogs:
141
142
  react17:
142
143
  react: 17.0.2
@@ -220,22 +221,23 @@ overrides:
220
221
  '@xmldom/xmldom@<0.8.13': ^0.9.0
221
222
  perf-primitives: ^0.0.6
222
223
  '@tryghost/adapter-base-redirects': file:components/tryghost-adapter-base-redirects-0.0.0.tgz
223
- '@tryghost/adapter-base-cache': file:components/tryghost-adapter-base-cache-0.2.0.tgz
224
224
  '@tryghost/adapter-base-route-settings': file:components/tryghost-adapter-base-route-settings-0.0.0.tgz
225
+ '@tryghost/adapter-base-scheduling': file:components/tryghost-adapter-base-scheduling-0.2.0.tgz
226
+ '@tryghost/adapter-base-cache': file:components/tryghost-adapter-base-cache-0.2.0.tgz
225
227
  '@tryghost/adapter-base-sso': file:components/tryghost-adapter-base-sso-0.1.1.tgz
226
228
  '@tryghost/custom-field-types': file:components/tryghost-custom-field-types-0.0.0.tgz
227
- '@tryghost/adapter-base-scheduling': file:components/tryghost-adapter-base-scheduling-0.2.0.tgz
228
229
  '@tryghost/kg-card-factory': file:components/tryghost-kg-card-factory-5.2.3.tgz
229
230
  '@tryghost/admin-api-schema': file:components/tryghost-admin-api-schema-0.0.0.tgz
230
- '@tryghost/kg-utils': file:components/tryghost-kg-utils-1.1.3.tgz
231
231
  '@tryghost/kg-converters': file:components/tryghost-kg-converters-1.2.3.tgz
232
+ '@tryghost/kg-utils': file:components/tryghost-kg-utils-1.1.3.tgz
233
+ '@tryghost/nql-string': file:components/tryghost-nql-string-0.0.0.tgz
232
234
  '@tryghost/kg-clean-basic-html': file:components/tryghost-kg-clean-basic-html-4.3.3.tgz
233
235
  '@tryghost/parse-email-address': file:components/tryghost-parse-email-address-0.0.0.tgz
234
236
  ghost-storage-base: file:components/ghost-storage-base-3.0.0.tgz
235
237
  '@tryghost/i18n': file:components/tryghost-i18n-0.0.0.tgz
236
238
  '@tryghost/kg-markdown-html-renderer': file:components/tryghost-kg-markdown-html-renderer-7.2.3.tgz
237
239
  '@tryghost/kg-default-cards': file:components/tryghost-kg-default-cards-10.3.3.tgz
238
- '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.3.tgz
240
+ '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.4.tgz
239
241
  '@tryghost/kg-default-transforms': file:components/tryghost-kg-default-transforms-1.3.3.tgz
240
242
  '@tryghost/kg-html-to-lexical': file:components/tryghost-kg-html-to-lexical-1.3.3.tgz
241
243
  '@tryghost/kg-lexical-html-renderer': file:components/tryghost-kg-lexical-html-renderer-1.4.3.tgz