ghost 6.64.0 → 6.65.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 (672) hide show
  1. package/bin/create-migration.js +15 -0
  2. package/components/tryghost-adapter-base-scheduling-0.2.4.tgz +0 -0
  3. package/components/tryghost-api-framework-0.0.0.tgz +0 -0
  4. package/components/tryghost-i18n-0.0.0.tgz +0 -0
  5. package/components/tryghost-kg-default-cards-10.3.6.tgz +0 -0
  6. package/components/tryghost-kg-lexical-html-renderer-1.5.1.tgz +0 -0
  7. package/components/tryghost-metafield-types-0.0.0.tgz +0 -0
  8. package/content/themes/casper/assets/built/casper.js +1 -1
  9. package/content/themes/casper/assets/built/screen.css +1 -1
  10. package/content/themes/casper/assets/css/screen.css +15 -2
  11. package/content/themes/casper/assets/js/init.js +37 -9
  12. package/content/themes/casper/package.json +8 -8
  13. package/content/themes/source/assets/built/screen.css +1 -1
  14. package/content/themes/source/assets/built/source.js +1 -1
  15. package/content/themes/source/assets/css/screen.css +14 -1
  16. package/content/themes/source/assets/js/main.js +24 -4
  17. package/content/themes/source/package.json +7 -7
  18. package/core/boot.js +22 -16
  19. package/core/bridge.js +1 -1
  20. package/core/built/admin/assets/Combination-DQ6f9A5P.js +41 -0
  21. package/core/built/admin/assets/{PolarAngleAxis-a81ieQUO.js → PolarAngleAxis-BBaU7PRV.js} +1 -1
  22. package/core/built/admin/assets/RadialBarChart-Bp20JPnA.js +1 -0
  23. package/core/built/admin/assets/{about-39CAfroa.js → about-Dp43j18M.js} +1 -1
  24. package/core/built/admin/assets/accordion-h62UzFhj.js +1 -0
  25. package/core/built/admin/assets/account-migration-CBTbtX6Q.js +1 -0
  26. package/core/built/admin/assets/action-list-DC9QpX-l.js +1 -0
  27. package/core/built/admin/assets/activitypub/{account-migration-KA6Jjf9L.js → account-migration-B1DUZS4Q.js} +8 -8
  28. package/core/built/admin/assets/activitypub/activitypub.js +24 -11
  29. package/core/built/admin/assets/activitypub/avatar-CRGud8yf.js +153 -0
  30. package/core/built/admin/assets/activitypub/{avatar-flipboard-csQaNeYK.js → avatar-flipboard-BZNFAXfm.js} +3 -3
  31. package/core/built/admin/assets/activitypub/{bluesky-sharing-C7nTDMvw.js → bluesky-sharing-Cg_v-LwS.js} +30 -31
  32. package/core/built/admin/assets/activitypub/{chunk-KS7C4IRE-Ck3O4oo2.js → chunk-KS7C4IRE-CTUL98Lc.js} +2498 -1885
  33. package/core/built/admin/assets/activitypub/{content-formatters-CLcjaBwV.js → content-formatters-D7GWP7nH.js} +23 -24
  34. package/core/built/admin/assets/activitypub/{copy-DcOh8kXw.js → copy-CgzTvoeR.js} +2 -2
  35. package/core/built/admin/assets/activitypub/{domain-fZ-X8i4-.js → domain-C3G_nkHU.js} +46 -46
  36. package/core/built/admin/assets/activitypub/{edit-profile-BqMLQV88.js → edit-profile-C8cCY-AK.js} +927 -928
  37. package/core/built/admin/assets/activitypub/{explore-B4yPoP8E.js → explore-NlDT4inq.js} +11 -11
  38. package/core/built/admin/assets/activitypub/{feed-BRC_mvAe.js → feed-DF22jCTV.js} +10 -10
  39. package/core/built/admin/assets/activitypub/{field-COacNgOt.js → field-95-iuTte.js} +4 -4
  40. package/core/built/admin/assets/activitypub/{hash-C7u-irQQ.js → hash-R7LMLnhY.js} +2 -2
  41. package/core/built/admin/assets/activitypub/{inbox-CbTTdDQ3.js → inbox-DUJUiV6x.js} +2 -2
  42. package/core/built/admin/assets/activitypub/{inbox-BW-yvUoN.js → inbox-DerExBzA.js} +416 -414
  43. package/core/built/admin/assets/activitypub/{label-kPMmYI7l.js → label-EwCn1QYc.js} +4 -4
  44. package/core/built/admin/assets/activitypub/layout-Dy6NnW1G.js +1 -0
  45. package/core/built/admin/assets/activitypub/{moderation-CuidJzc0.js → moderation-BSkfiVYo.js} +73 -75
  46. package/core/built/admin/assets/activitypub/{note-CAMRRSqD.js → note-DOnAJTXK.js} +9 -9
  47. package/core/built/admin/assets/activitypub/{notifications-BmNlXGgp.js → notifications-DZc6XTjG.js} +27 -27
  48. package/core/built/admin/assets/activitypub/{onboarding-Dmun9jr_.js → onboarding-8vEIwYTH.js} +3 -3
  49. package/core/built/admin/assets/activitypub/{onboarding-Bqg7fh_L.js → onboarding-DYVqbNmp.js} +2 -2
  50. package/core/built/admin/assets/activitypub/{preferences--oH19wf9.js → preferences-DDok6F2N.js} +1418 -1390
  51. package/core/built/admin/assets/activitypub/{profile-DH_tQx2D.js → profile-DjVa2hUk.js} +254 -255
  52. package/core/built/admin/assets/activitypub/{reply-Cap9PxSH.js → reply-DtXBpHxu.js} +2 -2
  53. package/core/built/admin/assets/activitypub/routes-Cw302e1c.js +4946 -0
  54. package/core/built/admin/assets/activitypub/{separator-CAxxu8VV.js → separator-FpRpVDd3.js} +8 -9
  55. package/core/built/admin/assets/activitypub/settings-yK-puALn.js +314 -0
  56. package/core/built/admin/assets/activitypub/{site-BYps63oh.js → site-CHw0R2PA.js} +2 -2
  57. package/core/built/admin/assets/activitypub/{step-1-CKjR2KAm.js → step-1-737bnvxk.js} +7 -7
  58. package/core/built/admin/assets/activitypub/{step-2-B6PKfOUQ.js → step-2-DBaIsAsM.js} +7 -7
  59. package/core/built/admin/assets/activitypub/{step-3-C-qBbcUo.js → step-3-BBmy9m9V.js} +23 -23
  60. package/core/built/admin/assets/activitypub/tabs-LQ2xirdm.js +1101 -0
  61. package/core/built/admin/assets/activitypub/{topic-filter-DsUOuu0k.js → topic-filter-75Nu0CKj.js} +4 -4
  62. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-CX9snsLs.js → use-activity-pub-queries-CYI2QJMs.js} +58 -58
  63. package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-DsJTGDSS.js → use-navigate-with-base-path-B4jZ8hyg.js} +3924 -1403
  64. package/core/built/admin/assets/activitypub/{use-reply-chain-data-AJi9zkzm.js → use-reply-chain-data-BHmFxc3U.js} +6 -6
  65. package/core/built/admin/assets/activitypub/users-CSjOwpT9.js +886 -0
  66. package/core/built/admin/assets/activitypub/{x-DR8AT3-4.js → x-B9ptWCds.js} +2 -2
  67. package/core/built/admin/assets/{add-integration-modal-B12oRifD.js → add-integration-modal-BwePhq95.js} +1 -1
  68. package/core/built/admin/assets/add-newsletter-modal-Zv0I7Msm.js +1 -0
  69. package/core/built/admin/assets/{add-recommendation-modal-CJf92edY.js → add-recommendation-modal-cdLv0wHy.js} +1 -1
  70. package/core/built/admin/assets/analytics-DY8_SaP7.js +1 -0
  71. package/core/built/admin/assets/announcement-bar-modal-C-2yWwag.js +1 -0
  72. package/core/built/admin/assets/api-keys-BHKATUqQ.js +1 -0
  73. package/core/built/admin/assets/{audience-6GXevic-.js → audience-wRcSN0jV.js} +1 -1
  74. package/core/built/admin/assets/{automated-emails-DJQ4uNZo.js → automated-emails-CzUa3v4d.js} +1 -1
  75. package/core/built/admin/assets/automations-DupSsSOr.js +1 -0
  76. package/core/built/admin/assets/badge-CI1Z0xyG.js +1 -0
  77. package/core/built/admin/assets/bluesky-sharing-B8PC1SBj.js +1 -0
  78. package/core/built/admin/assets/box-LUuYRT-1.js +1 -0
  79. package/core/built/admin/assets/brand-icon-CrmbX86T.js +1 -0
  80. package/core/built/admin/assets/breadcrumb-DDDpzLyo.js +1 -0
  81. package/core/built/admin/assets/button-D414TI3B.js +1 -0
  82. package/core/built/admin/assets/calendar-Cp_opo3i.js +1 -0
  83. package/core/built/admin/assets/card-C2dfd5u0.js +1 -0
  84. package/core/built/admin/assets/chart-B_UNLXse.js +63 -0
  85. package/core/built/admin/assets/chart-helpers-Czu_9QpJ.js +1 -0
  86. package/core/built/admin/assets/checkbox-CFFqf0Nh.js +1 -0
  87. package/core/built/admin/assets/{chunk.368.22ce1b732c0b40abd3f1.js → chunk.201.6961b57ed7a281ac193e.js} +23 -19
  88. package/core/built/admin/assets/chunk.524.0b850e72ec49a0fa3882.js +25 -0
  89. package/core/built/admin/assets/chunk.582.db2ae9e968256e8d58ac.js +27 -0
  90. package/core/built/admin/assets/code-editor-view-Bd_nnHKk.js +1 -0
  91. package/core/built/admin/assets/code-editor-view-BeU3Yf9M.js +1 -0
  92. package/core/built/admin/assets/color-picker-Bzm1V7qg.js +3 -0
  93. package/core/built/admin/assets/color-picker-field-DP0moHz9.js +1 -0
  94. package/core/built/admin/assets/combobox-6_ruuTuj.js +1 -0
  95. package/core/built/admin/assets/command-B5wfm6pd.js +1 -0
  96. package/core/built/admin/assets/comments-BB26dUSl.js +1 -0
  97. package/core/built/admin/assets/confirmation-context-znVJD4pX.js +1 -0
  98. package/core/built/admin/assets/container-CHHif8km.js +1 -0
  99. package/core/built/admin/assets/{content-api-modal-0ZjuLcQ8.js → content-api-modal-DOHwl0yZ.js} +1 -1
  100. package/core/built/admin/assets/context-menu-BpY46Dlb.js +1 -0
  101. package/core/built/admin/assets/copy-field-DRBx6Ady.js +1 -0
  102. package/core/built/admin/assets/create-ghost-browse-value-source-eIXo5Qws.js +1 -0
  103. package/core/built/admin/assets/custom-field-type-option-DrSlETOI.js +1 -0
  104. package/core/built/admin/assets/custom-integration-modal-Dgo425Ec.js +1 -0
  105. package/core/built/admin/assets/data-list-DM8yqpXi.js +1 -0
  106. package/core/built/admin/assets/date-range-select-DdC23c13.js +1 -0
  107. package/core/built/admin/assets/design-and-theme-modal-CbSu9IT4.js +2 -0
  108. package/core/built/admin/assets/detail-page-CN4NdhpV.js +1 -0
  109. package/core/built/admin/assets/dirty-confirm-dialog-BT_Vq9TD.js +1 -0
  110. package/core/built/admin/assets/{disabled-sources-indicator-CLZhMv8J.js → disabled-sources-indicator-C5xtW0Q2.js} +1 -1
  111. package/core/built/admin/assets/dist-B40T-RCQ.js +1 -0
  112. package/core/built/admin/assets/dist-CrlaEoaK.js +1 -0
  113. package/core/built/admin/assets/domain-BPReCZa8.js +1 -0
  114. package/core/built/admin/assets/dropzone-B2auMkf2.js +5 -0
  115. package/core/built/admin/assets/edit-profile-B7XTBzKe.js +1 -0
  116. package/core/built/admin/assets/editor-BcaC9dqm.js +8 -0
  117. package/core/built/admin/assets/editor-screen-FuMpItC8.js +27 -0
  118. package/core/built/admin/assets/email-sending-status-provider-9d81o1C2.js +1 -0
  119. package/core/built/admin/assets/embed-signup-form-modal-CbVbMsxl.js +8 -0
  120. package/core/built/admin/assets/empty-indicator-CSQts7GV.js +1 -0
  121. package/core/built/admin/assets/explore-DbSXFTJN.js +1 -0
  122. package/core/built/admin/assets/feature-image-placeholder-DFXA4vfJ.js +1 -0
  123. package/core/built/admin/assets/feed-W7RlF-Gp.js +1 -0
  124. package/core/built/admin/assets/field-BXEh3ptU.js +1 -0
  125. package/core/built/admin/assets/filter-sources-DHK2IoCk.js +1 -0
  126. package/core/built/admin/assets/filters-0SYNTqyQ.js +1 -0
  127. package/core/built/admin/assets/filters-DTtZKQyq.js +1 -0
  128. package/core/built/admin/assets/{first-promoter-modal-wr73Dldc.js → first-promoter-modal-DcoN_OXu.js} +1 -1
  129. package/core/built/admin/assets/{ghost-a1e6e172c6917e8ef8fa6b0007756d9b.js → ghost-25495154132af7305cb7b646fd83f48f.js} +562 -514
  130. package/core/built/admin/assets/gift-link-modal-BX-Q1TOk.js +1 -0
  131. package/core/built/admin/assets/grid-BEUIDQX7.js +1 -0
  132. package/core/built/admin/assets/growth-G6PLO4aF.js +1 -0
  133. package/core/built/admin/assets/growth-tkD-fBOY.js +3 -0
  134. package/core/built/admin/assets/heading-ih-fOVqF.js +1 -0
  135. package/core/built/admin/assets/history-modal-Ca-gStoq.js +1 -0
  136. package/core/built/admin/assets/html-field-B3CrKV9Y.js +1 -0
  137. package/core/built/admin/assets/images-H-BIm8OQ.js +1 -0
  138. package/core/built/admin/assets/{inbox-DgSZ6w2p.js → inbox-DBbDVMPz.js} +14 -14
  139. package/core/built/admin/assets/index-DOF2jDq0.js +4 -0
  140. package/core/built/admin/assets/index-JrrNchW1.css +2 -0
  141. package/core/built/admin/assets/input-group-CvH-3d3F.js +1 -0
  142. package/core/built/admin/assets/input-surface-CL23Mlh8.js +1 -0
  143. package/core/built/admin/assets/integration-header-C7GXGis_.js +1 -0
  144. package/core/built/admin/assets/invite-user-modal-EJ2_6RpV.js +1 -0
  145. package/core/built/admin/assets/isPlainObject-BzzgUf1E.js +1 -0
  146. package/core/built/admin/assets/{koenig-lexical-CXVgQFUk.js → koenig-lexical-Dkwee5FG.js} +1 -1
  147. package/core/built/admin/assets/koenig-loader-BzXCXHoA.js +2 -0
  148. package/core/built/admin/assets/kpi-card-iCDUTgOR.js +1 -0
  149. package/core/built/admin/assets/kpi-card-jTnpLKGr.js +1 -0
  150. package/core/built/admin/assets/kpi-helpers-Criu0YAf.js +1 -0
  151. package/core/built/admin/assets/kpi-tabs-DbOmmyOo.js +1 -0
  152. package/core/built/admin/assets/label-Du0yqMqL.js +1 -0
  153. package/core/built/admin/assets/label-picker-Bq1XXr1D.js +1 -0
  154. package/core/built/admin/assets/{labels-KMkFoRG6.js → labels-0x2NfLtC.js} +1 -1
  155. package/core/built/admin/assets/layout-Ckwzsnsu.js +1 -0
  156. package/core/built/admin/assets/lib-CCz2mjm8.js +2 -0
  157. package/core/built/admin/assets/link-helpers-o9GgBTni.js +1 -0
  158. package/core/built/admin/assets/{links-FwNCVyVe.js → links-Ctujreuh.js} +1 -1
  159. package/core/built/admin/assets/list-page-CH_wnDC3.js +1 -0
  160. package/core/built/admin/assets/member-activity-CsAh6MxK.js +1 -0
  161. package/core/built/admin/assets/member-activity-feed-0ytsQbtY.js +1 -0
  162. package/core/built/admin/assets/member-custom-fields-CTFGnnYv.js +1 -0
  163. package/core/built/admin/assets/member-detail-QU3vB1ML.js +1 -0
  164. package/core/built/admin/assets/members-CtMVO_AB.js +4 -0
  165. package/core/built/admin/assets/modal-page-8Ipfl51B.js +1 -0
  166. package/core/built/admin/assets/moderation-B8VtA-W0.js +1 -0
  167. package/core/built/admin/assets/multi-select-combobox-_9wEYmGv.js +1 -0
  168. package/core/built/admin/assets/navigation-modal-CGcjJvkc.js +1 -0
  169. package/core/built/admin/assets/newsletter-BpHjjqmq.js +1 -0
  170. package/core/built/admin/assets/newsletter-detail-modal-DzTbGOyo.js +1 -0
  171. package/core/built/admin/assets/newsletter-emails-BMKH4Osp.js +1 -0
  172. package/core/built/admin/assets/newsletters-BxC84_cL.js +1 -0
  173. package/core/built/admin/assets/note-BPtEzzZS.js +1 -0
  174. package/core/built/admin/assets/notifications-ng3ulEdp.js +1 -0
  175. package/core/built/admin/assets/offers-container-modal-CwqnRa3T.js +1 -0
  176. package/core/built/admin/assets/onboarding-route-CplZzd7F.js +1 -0
  177. package/core/built/admin/assets/overview-B0yD9OoX.js +1 -0
  178. package/core/built/admin/assets/overview-C4eJzQqi.js +1 -0
  179. package/core/built/admin/assets/page-header-CdCpekG9.js +1 -0
  180. package/core/built/admin/assets/pagemenu-CKQD9hoP.js +1 -0
  181. package/core/built/admin/assets/pages-route-CKsnxIvw.js +1 -0
  182. package/core/built/admin/assets/{pintura-modal-BljM7hf8.js → pintura-modal-C5jzeyGk.js} +1 -1
  183. package/core/built/admin/assets/portal-frame-DYo0bh0E.js +1 -0
  184. package/core/built/admin/assets/portal-modal-C0d8xjKa.js +1 -0
  185. package/core/built/admin/assets/post-analytics-C5C7IyAm.js +1 -0
  186. package/core/built/admin/assets/post-analytics-header-DKWHwoK2.js +1 -0
  187. package/core/built/admin/assets/{post-analytics-provider-CgreZDjS.js → post-analytics-provider-BqCPPxmW.js} +1 -1
  188. package/core/built/admin/assets/post-share-modal-wxmqbAv_.js +1 -0
  189. package/core/built/admin/assets/posts-list-screen-B978ZO0R.js +2 -0
  190. package/core/built/admin/assets/posts-route-CDqxKazl.js +1 -0
  191. package/core/built/admin/assets/preferences-CnejTRc4.js +5 -0
  192. package/core/built/admin/assets/preview-chrome-C7yZWVLZ.js +1 -0
  193. package/core/built/admin/assets/preview-modal-CFUxUGHp.js +1 -0
  194. package/core/built/admin/assets/profile-ClRGiOqA.js +1 -0
  195. package/core/built/admin/assets/radio-group-CTmLo0h9.js +1 -0
  196. package/core/built/admin/assets/router-provider-DDZvgS3V.js +1 -0
  197. package/core/built/admin/assets/select-D_4xWFYv.js +1 -0
  198. package/core/built/admin/assets/settings-BRl7-7a9.js +1 -0
  199. package/core/built/admin/assets/settings-BoQcPa-y.js +4 -0
  200. package/core/built/admin/assets/settings-breadcrumbs-C9Yxl81q.js +1 -0
  201. package/core/built/admin/assets/{dist-BXHrDV19.js → shade-scope-Cccj-c7I-D0XwkdKQ.js} +5 -3
  202. package/core/built/admin/assets/share-modal-DBqZobuR.js +1 -0
  203. package/core/built/admin/assets/simple-pagination-D5t_ox6x.js +1 -0
  204. package/core/built/admin/assets/skeleton-CPcTiTSX.js +1 -0
  205. package/core/built/admin/assets/{slack-modal-D7W_fNON.js → slack-modal-BF9ex8cd.js} +1 -1
  206. package/core/built/admin/assets/sort-button-C0EXGjnS.js +1 -0
  207. package/core/built/admin/assets/{source-icon-CQboPZQ3.js → source-icon-BzzftCQ2.js} +1 -1
  208. package/core/built/admin/assets/stats-view-CzpGoHzF.js +1 -0
  209. package/core/built/admin/assets/{step-1-BKhjy0PV.js → step-1-CBUYUPPF.js} +1 -1
  210. package/core/built/admin/assets/{step-2-PxA1OM7R.js → step-2-CEIXUwQa.js} +1 -1
  211. package/core/built/admin/assets/{step-3-BJbAiq16.js → step-3-C1HA5i1N.js} +2 -2
  212. package/core/built/admin/assets/stripe-button-DMFsLs80.js +1 -0
  213. package/core/built/admin/assets/stripe-connect-modal-CEvxCUTv.js +1 -0
  214. package/core/built/admin/assets/switch-DoOJF2yg.js +1 -0
  215. package/core/built/admin/assets/table-BDYbUHJz.js +1 -0
  216. package/core/built/admin/assets/tabs-BZyz4ZCH.js +1 -0
  217. package/core/built/admin/assets/tag-detail-CFzaz_9E.js +2 -0
  218. package/core/built/admin/assets/tag-picker-BKUCZuRc.js +1 -0
  219. package/core/built/admin/assets/tags-Bs1FiD7m.js +1 -0
  220. package/core/built/admin/assets/{testimonials-modal-Dkt6ODLW.js → testimonials-modal-CVm0_7E-.js} +1 -1
  221. package/core/built/admin/assets/text-BLI0C8Mc.js +1 -0
  222. package/core/built/admin/assets/textarea-C5qolByg.js +1 -0
  223. package/core/built/admin/assets/tier-detail-modal-Cmwzi-e7.js +1 -0
  224. package/core/built/admin/assets/toggle-group-BTL1QsWY.js +1 -0
  225. package/core/built/admin/assets/{topic-filter-DVOe3D-b.js → topic-filter-BMjhquv7.js} +1 -1
  226. package/core/built/admin/assets/transistor-modal-hMv53jF8.js +1 -0
  227. package/core/built/admin/assets/trend-badge-1w_HEzkG.js +1 -0
  228. package/core/built/admin/assets/{unsplash-modal-DXt7Brum.js → unsplash-modal-jzC8lEB2.js} +1 -1
  229. package/core/built/admin/assets/use-analytics-data-B3lGOxsC.js +1 -0
  230. package/core/built/admin/assets/use-availability-DnKqOyqd.js +1 -0
  231. package/core/built/admin/assets/{use-check-theme-limit-error-JD-J5aaZ.js → use-check-theme-limit-error-C1tc2P4N.js} +2 -2
  232. package/core/built/admin/assets/use-filter-params-DU-aiaTb.js +1 -0
  233. package/core/built/admin/assets/{use-filterable-api-CEMSAYPg.js → use-filterable-api-CxCrnPxG.js} +1 -1
  234. package/core/built/admin/assets/use-growth-stats-E13rMQUE.js +1 -0
  235. package/core/built/admin/assets/use-limiter-DlL7au90.js +19 -0
  236. package/core/built/admin/assets/{use-navigate-with-base-path-88EQpw2k.js → use-navigate-with-base-path-BzgNwMAx.js} +1 -1
  237. package/core/built/admin/assets/{use-pintura-config-BmU45Ruy.js → use-pintura-config-CtEV1JQY.js} +1 -1
  238. package/core/built/admin/assets/{use-pintura-editor-Bz2bZ4iT.js → use-pintura-editor-CaxE64kD.js} +1 -1
  239. package/core/built/admin/assets/use-reply-chain-data-BST2OgCM.js +1 -0
  240. package/core/built/admin/assets/use-sending-eta-DR9ueMH8.js +1 -0
  241. package/core/built/admin/assets/use-setting-group-ldtX1Vsk.js +1 -0
  242. package/core/built/admin/assets/use-settings-navigation-CzGU4sus.js +1 -0
  243. package/core/built/admin/assets/use-staff-users-DoeXaPsb.js +1 -0
  244. package/core/built/admin/assets/use-tinybird-query-BaBNCaj0.js +1 -0
  245. package/core/built/admin/assets/{use-tinybird-token-Lk1RSn0t.js → use-tinybird-token-CnZ19NDf.js} +1 -1
  246. package/core/built/admin/assets/{use-url-input-DpmbDppC.js → use-url-input-C5KHJw79.js} +1 -1
  247. package/core/built/admin/assets/user-detail-modal-Dm0KfPeR.js +1 -0
  248. package/core/built/admin/assets/{vendor-2dd263291938d407802568d3357ec69e.js → vendor-97e91ff8dd1457c668f9ef103ee1a77b.js} +2748 -2977
  249. package/core/built/admin/assets/virtual-list-tAuPUICw.js +1 -0
  250. package/core/built/admin/assets/web-BQlKcW2x.js +2 -0
  251. package/core/built/admin/assets/web-NTT5DkEz.js +1 -0
  252. package/core/built/admin/assets/{zapier-modal-BafLUO4R.js → zapier-modal-DsHG9Oev.js} +1 -1
  253. package/core/built/admin/index.html +22 -24
  254. package/core/frontend/apps/private-blogging/index.js +2 -2
  255. package/core/frontend/apps/private-blogging/lib/middleware.js +1 -1
  256. package/core/frontend/apps/private-blogging/lib/router.js +1 -1
  257. package/core/frontend/helpers/cancel_link.js +3 -3
  258. package/core/frontend/helpers/content.js +2 -2
  259. package/core/frontend/helpers/content_api_url.js +1 -1
  260. package/core/frontend/helpers/date.js +1 -1
  261. package/core/frontend/helpers/foreach.js +5 -5
  262. package/core/frontend/helpers/get.js +7 -4
  263. package/core/frontend/helpers/ghost_head.js +2 -2
  264. package/core/frontend/helpers/has.js +1 -3
  265. package/core/frontend/helpers/link.js +7 -7
  266. package/core/frontend/helpers/link_class.js +2 -2
  267. package/core/frontend/helpers/navigation.js +1 -2
  268. package/core/frontend/helpers/recommendations.js +5 -6
  269. package/core/frontend/helpers/tiers.js +1 -1
  270. package/core/frontend/helpers/total_members.js +1 -1
  271. package/core/frontend/helpers/total_paid_members.js +1 -1
  272. package/core/frontend/meta/author-url.js +1 -1
  273. package/core/frontend/meta/modified-date.js +1 -1
  274. package/core/frontend/meta/published-date.js +1 -1
  275. package/core/frontend/meta/schema.js +3 -8
  276. package/core/frontend/meta/structured-data.js +1 -2
  277. package/core/frontend/services/assets-minification/minifier.js +1 -1
  278. package/core/frontend/services/data/entry-lookup.js +1 -1
  279. package/core/frontend/services/data/fetch-data.js +2 -2
  280. package/core/frontend/services/rendering/format-response.js +1 -1
  281. package/core/frontend/services/rendering/renderer.js +3 -0
  282. package/core/frontend/services/rendering/templates.js +1 -1
  283. package/core/frontend/services/routing/controllers/static.js +1 -1
  284. package/core/frontend/services/routing/parent-router.js +1 -1
  285. package/core/frontend/services/routing/registry.js +1 -1
  286. package/core/frontend/services/sitemap/base-site-map-generator.js +68 -97
  287. package/core/frontend/services/sitemap/site-map-index-generator.js +16 -21
  288. package/core/frontend/services/sitemap/site-map-manager.js +82 -43
  289. package/core/frontend/services/sitemap/sitemap-xml.js +72 -0
  290. package/core/frontend/services/theme-engine/handlebars/utils.js +8 -8
  291. package/core/frontend/services/theme-engine/i18n/i18n.js +4 -5
  292. package/core/frontend/services/theme-engine/middleware/update-global-template-options.js +1 -1
  293. package/core/frontend/services/theme-engine/preview.js +1 -1
  294. package/core/frontend/utils/member-count.js +2 -2
  295. package/core/frontend/web/routers/serve-public-file.js +1 -1
  296. package/core/server/adapters/scheduling/README.md +4 -0
  297. package/core/server/adapters/scheduling/get-scheduler-idempotency-key.js +21 -0
  298. package/core/server/adapters/storage/LocalStorageBase.js +2 -1
  299. package/core/server/api/endpoints/automated-emails.js +8 -2
  300. package/core/server/api/endpoints/db.js +1 -1
  301. package/core/server/api/endpoints/emails.js +3 -3
  302. package/core/server/api/endpoints/mail.js +1 -1
  303. package/core/server/api/endpoints/member-signin-urls.js +1 -1
  304. package/core/server/api/endpoints/members.js +3 -3
  305. package/core/server/api/endpoints/oembed.js +1 -1
  306. package/core/server/api/endpoints/posts.js +1 -1
  307. package/core/server/api/endpoints/settings.js +2 -2
  308. package/core/server/api/endpoints/themes.js +5 -5
  309. package/core/server/api/endpoints/utils/serializers/input/pages.js +2 -2
  310. package/core/server/api/endpoints/utils/serializers/input/posts.js +2 -2
  311. package/core/server/api/endpoints/utils/serializers/input/tags.js +1 -1
  312. package/core/server/api/endpoints/utils/serializers/input/utils/slug-filter-order.js +4 -4
  313. package/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +8 -5
  314. package/core/server/api/endpoints/utils/serializers/output/mappers/posts.js +1 -1
  315. package/core/server/api/endpoints/utils/serializers/output/pages.js +4 -4
  316. package/core/server/api/endpoints/utils/serializers/output/posts.js +4 -4
  317. package/core/server/api/endpoints/utils/serializers/output/search-index.js +11 -11
  318. package/core/server/api/endpoints/utils/serializers/output/settings.js +1 -1
  319. package/core/server/api/endpoints/utils/serializers/output/utils/extra-attrs.js +3 -3
  320. package/core/server/api/endpoints/utils/validators/input/automated_emails.js +23 -33
  321. package/core/server/api/endpoints/utils/validators/input/settings.js +3 -3
  322. package/core/server/data/exporter/exporter.js +1 -2
  323. package/core/server/data/exporter/table-lists.js +1 -0
  324. package/core/server/data/importer/handlers/image.js +1 -2
  325. package/core/server/data/importer/handlers/json.js +1 -3
  326. package/core/server/data/importer/handlers/markdown.js +4 -8
  327. package/core/server/data/importer/import-manager.js +1 -1
  328. package/core/server/data/importer/importers/content-file-importer.js +4 -8
  329. package/core/server/data/importer/importers/data/base.js +10 -10
  330. package/core/server/data/importer/importers/data/custom-theme-settings-importer.js +1 -1
  331. package/core/server/data/importer/importers/data/data-importer.js +3 -4
  332. package/core/server/data/importer/importers/data/posts-importer.js +10 -10
  333. package/core/server/data/importer/importers/data/products-importer.js +3 -3
  334. package/core/server/data/importer/importers/data/settings-importer.js +2 -2
  335. package/core/server/data/importer/importers/data/stripe-prices-importer.js +1 -1
  336. package/core/server/data/importer/importers/data/stripe-products-importer.js +1 -1
  337. package/core/server/data/importer/importers/data/tags-importer.js +1 -1
  338. package/core/server/data/importer/importers/data/users-importer.js +2 -2
  339. package/core/server/data/importer/importers/json-to-html.js +12 -9
  340. package/core/server/data/migrations/versions/5.0/2022-05-11-13-12-rename-settings.js +1 -1
  341. package/core/server/data/migrations/versions/6.65/2026-09-16-15-35-26-add-members-metafield-change-events.js +17 -0
  342. package/core/server/data/schema/fixtures/fixture-manager.js +3 -3
  343. package/core/server/data/schema/index.js +1 -1
  344. package/core/server/data/schema/schema.js +26 -0
  345. package/core/server/data/schema/validator.js +96 -123
  346. package/core/server/data/seeders/importers/email-recipients-importer.js +2 -2
  347. package/core/server/data/seeders/importers/members-login-events-importer.js +1 -1
  348. package/core/server/data/seeders/importers/members-newsletters-importer.js +1 -1
  349. package/core/server/data/seeders/importers/members-paid-subscription-events-importer.js +1 -1
  350. package/core/server/data/seeders/importers/members-status-events-importer.js +1 -1
  351. package/core/server/data/seeders/importers/members-stripe-customers-importer.js +1 -1
  352. package/core/server/data/seeders/importers/members-stripe-customers-subscriptions-importer.js +1 -1
  353. package/core/server/data/seeders/importers/members-subscribe-events-importer.js +2 -2
  354. package/core/server/data/seeders/importers/members-subscription-created-events-importer.js +1 -1
  355. package/core/server/data/tinybird/pipes/mv_hits.pipe +25 -20
  356. package/core/server/data/tinybird/scripts/docker-analytics-manager.js +2 -2
  357. package/core/server/ghost-server.js +1 -19
  358. package/core/server/lib/image/image-size.js +1 -3
  359. package/core/server/lib/request-external.js +53 -117
  360. package/core/server/models/base/plugins/actions.js +2 -3
  361. package/core/server/models/base/plugins/crud.js +1 -2
  362. package/core/server/models/base/plugins/events.js +4 -4
  363. package/core/server/models/base/plugins/raw-knex.js +3 -3
  364. package/core/server/models/base/plugins/sanitize.js +1 -1
  365. package/core/server/models/benefit.js +1 -1
  366. package/core/server/models/collection.js +1 -1
  367. package/core/server/models/comment.js +3 -3
  368. package/core/server/models/invite.js +2 -5
  369. package/core/server/models/label.js +3 -6
  370. package/core/server/models/member.js +7 -10
  371. package/core/server/models/newsletter.js +1 -1
  372. package/core/server/models/permission.js +3 -6
  373. package/core/server/models/post.js +20 -23
  374. package/core/server/models/product.js +4 -1
  375. package/core/server/models/relations/authors.js +9 -12
  376. package/core/server/models/role.js +2 -5
  377. package/core/server/models/settings.js +3 -3
  378. package/core/server/models/tag.js +2 -5
  379. package/core/server/models/user.js +8 -10
  380. package/core/server/models/webhook.js +2 -4
  381. package/core/server/notify.js +2 -2
  382. package/core/server/services/adapter-manager/utils.js +6 -1
  383. package/core/server/services/api-version-compatibility/legacy-api-path-match.js +2 -2
  384. package/core/server/services/auth/api-key/admin.js +2 -2
  385. package/core/server/services/auth/api-key/content.js +1 -1
  386. package/core/server/services/auth/passwordreset.js +1 -1
  387. package/core/server/services/auth/setup.js +1 -3
  388. package/core/server/services/automations/README.md +19 -0
  389. package/core/server/services/automations/poll.js +3 -1
  390. package/core/server/services/automations/service.js +2 -2
  391. package/core/server/services/automations/welcome-email-automation-poll.js +199 -293
  392. package/core/server/services/comments/comments-controller.js +9 -30
  393. package/core/server/services/comments/comments-service-email-renderer.js +1 -1
  394. package/core/server/services/comments/comments-service-emails.js +1 -1
  395. package/core/server/services/comments/comments-service.js +27 -58
  396. package/core/server/services/comments/comments-stats-service.js +1 -1
  397. package/core/server/services/content-import/import/staged-file.js +9 -9
  398. package/core/server/services/content-import/index.js +1 -1
  399. package/core/server/services/custom-redirects/validation.js +1 -1
  400. package/core/server/services/email-analytics/email-analytics-service-wrapper.js +23 -55
  401. package/core/server/services/email-analytics/index.js +35 -19
  402. package/core/server/services/email-analytics/jobs/email-analytics-job-scheduler.js +31 -60
  403. package/core/server/services/email-service/README.md +35 -0
  404. package/core/server/services/email-service/batch-sending-service.js +13 -14
  405. package/core/server/services/email-service/email-renderer.js +50 -14
  406. package/core/server/services/email-service/email-service-wrapper.js +3 -2
  407. package/core/server/services/email-service/email-service.js +33 -8
  408. package/core/server/services/email-service/email-templates/partials/feedback-button.hbs +2 -1
  409. package/core/server/services/email-service/email-templates/partials/styles.hbs +0 -6
  410. package/core/server/services/email-service/email-templates/template.hbs +1 -1
  411. package/core/server/services/email-service/jobs/send-email-job.js +12 -0
  412. package/core/server/services/email-service/mailgun-email-provider.js +7 -2
  413. package/core/server/services/email-service/sending-service.js +1 -1
  414. package/core/server/services/gifts/gift-service.js +12 -3
  415. package/core/server/services/gifts/index.js +0 -2
  416. package/core/server/services/gifts/jobs/index.js +12 -24
  417. package/core/server/services/gifts/jobs/send-gift-reminders-job.js +6 -46
  418. package/core/server/services/invitations/accept.js +2 -2
  419. package/core/server/services/jobs/job-service.js +0 -28
  420. package/core/server/services/jobs-service/jobs-service.js +5 -0
  421. package/core/server/services/jobs-service/register-job-handlers.js +17 -1
  422. package/core/server/services/lib/mailgun-client.js +16 -1
  423. package/core/server/services/lib/mailgun-recipient-message-id.js +49 -0
  424. package/core/server/services/limits.js +1 -1
  425. package/core/server/services/mail/ghost-mailer.js +1 -1
  426. package/core/server/services/member-attribution/member-attribution-service.js +1 -1
  427. package/core/server/services/member-attribution/referrer-translator.js +1 -1
  428. package/core/server/services/members/account-service.js +3 -3
  429. package/core/server/services/members/api.js +1 -1
  430. package/core/server/services/members/import-export/import/importer.js +25 -16
  431. package/core/server/services/members/import-export/import/spool.js +11 -15
  432. package/core/server/services/members/import-export/index.js +6 -4
  433. package/core/server/services/members/jobs/index.js +1 -1
  434. package/core/server/services/members/jobs/members-import-job.js +18 -0
  435. package/core/server/services/members/member-avatar.js +18 -0
  436. package/core/server/services/members/members-api/controllers/member-controller.js +2 -2
  437. package/core/server/services/members/members-api/members-api.js +4 -4
  438. package/core/server/services/members/members-api/repositories/event-repository.js +36 -1
  439. package/core/server/services/members/members-api/repositories/member-repository.js +55 -17
  440. package/core/server/services/members/members-api/repositories/product-repository.js +1 -1
  441. package/core/server/services/members/members-api/services/member-bread-service.js +4 -7
  442. package/core/server/services/members/service.js +7 -2
  443. package/core/server/services/members/stats/members-stats.js +2 -2
  444. package/core/server/services/members-events/event-storage.js +2 -2
  445. package/core/server/services/members-metafields/actions.js +23 -2
  446. package/core/server/services/members-metafields/bindings-service.js +5 -5
  447. package/core/server/services/members-metafields/definitions-service.js +2 -7
  448. package/core/server/services/members-metafields/index.js +2 -1
  449. package/core/server/services/members-metafields/queries.js +7 -1
  450. package/core/server/services/members-metafields/schema.js +49 -1
  451. package/core/server/services/members-metafields/values-service.js +112 -10
  452. package/core/server/services/mentions/mention-sending-service.js +2 -2
  453. package/core/server/services/mentions/mention.js +3 -4
  454. package/core/server/services/mentions/mentions-api.js +4 -1
  455. package/core/server/services/mentions-jobs/job-service.js +0 -28
  456. package/core/server/services/milestones/milestones-service.js +1 -1
  457. package/core/server/services/newsletters/newsletters-service.js +1 -1
  458. package/core/server/services/notifications/notifications.js +3 -3
  459. package/core/server/services/oembed/oembed-service.js +79 -3
  460. package/core/server/services/permissions/can-this.js +1 -2
  461. package/core/server/services/post-scheduling/post-scheduling.js +8 -1
  462. package/core/server/services/posts/post-scheduling.js +7 -0
  463. package/core/server/services/settings/settings-bread-service.js +3 -3
  464. package/core/server/services/settings/settings-utils.js +1 -1
  465. package/core/server/services/settings-helpers/settings-helpers.js +1 -1
  466. package/core/server/services/staff/staff-service-emails.js +9 -9
  467. package/core/server/services/stats/posts-stats-service.js +10 -10
  468. package/core/server/services/stats/referrers-stats-service.js +1 -1
  469. package/core/server/services/stats/subscription-stats-service.js +3 -3
  470. package/core/server/services/stats/utils/tinybird.js +8 -1
  471. package/core/server/services/stripe/stripe-api.js +3 -3
  472. package/core/server/services/stripe/stripe-migrations.js +6 -6
  473. package/core/server/services/themes/storage.js +21 -26
  474. package/core/server/services/themes/theme-storage.js +2 -2
  475. package/core/server/services/tiers/tier.js +15 -15
  476. package/core/server/services/tinybird-sync/index.js +3 -0
  477. package/core/server/services/tinybird-sync/tinybird-sync-service.js +7 -2
  478. package/core/server/services/update-check/update-check-service.js +3 -3
  479. package/core/server/services/webhooks/serialize.js +1 -1
  480. package/core/server/web/api/app.js +0 -5
  481. package/core/server/web/api/middleware/upload.js +29 -2
  482. package/core/server/web/parent/middleware/index.js +1 -1
  483. package/core/server/web/parent/middleware/log-request.js +5 -0
  484. package/core/server/web/parent/middleware/queue-request.js +104 -59
  485. package/core/server/web/shared/middleware/api/spam-prevention.js +2 -2
  486. package/core/shared/config/defaults.json +6 -1
  487. package/core/shared/custom-theme-settings-cache/custom-theme-settings-service.js +1 -1
  488. package/core/shared/labs.js +3 -2
  489. package/core/shared/settings-cache/cache-manager.js +1 -1
  490. package/nodemon.json +1 -1
  491. package/package.json +6 -7
  492. package/pnpm-lock.yaml +126 -728
  493. package/pnpm-workspace.yaml +4 -7
  494. package/tsconfig.json +1 -1
  495. package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
  496. package/core/built/admin/assets/Combination-DWfJPcz9.js +0 -41
  497. package/core/built/admin/assets/RadialBarChart-CHRBhiBN.js +0 -1
  498. package/core/built/admin/assets/_baseAssignValue-DcPokYW8.js +0 -1
  499. package/core/built/admin/assets/accordion-CJmRaqK7.js +0 -1
  500. package/core/built/admin/assets/account-migration-DYf7skbb.js +0 -1
  501. package/core/built/admin/assets/action-list-Crnh-_UI.js +0 -1
  502. package/core/built/admin/assets/activitypub/avatar-DVJF5bxP.js +0 -261
  503. package/core/built/admin/assets/activitypub/layout-BL4_jtuV.js +0 -1
  504. package/core/built/admin/assets/activitypub/routes-DdyY9uFF.js +0 -7181
  505. package/core/built/admin/assets/activitypub/settings-B6EEcVkW.js +0 -315
  506. package/core/built/admin/assets/activitypub/tabs-DLhZtVde.js +0 -1083
  507. package/core/built/admin/assets/activitypub/users-inweyKL5.js +0 -1499
  508. package/core/built/admin/assets/add-newsletter-modal-CTvXiIqY.js +0 -1
  509. package/core/built/admin/assets/analytics-PHR1Fggi.js +0 -1
  510. package/core/built/admin/assets/announcement-bar-modal-Bql0CXdp.js +0 -1
  511. package/core/built/admin/assets/api-keys-CubH-7_H.js +0 -1
  512. package/core/built/admin/assets/automations-DcZSLFDU.js +0 -1
  513. package/core/built/admin/assets/badge-qP06OT7C.js +0 -1
  514. package/core/built/admin/assets/bluesky-sharing-CJw4d4Mf.js +0 -1
  515. package/core/built/admin/assets/box-CZ_LSVSy.js +0 -1
  516. package/core/built/admin/assets/brand-icon-D3ffDYaC.js +0 -1
  517. package/core/built/admin/assets/breadcrumb-Chn1Ip_q.js +0 -1
  518. package/core/built/admin/assets/button-DvIh2Bq-.js +0 -1
  519. package/core/built/admin/assets/calendar-1QGoStFM.js +0 -1
  520. package/core/built/admin/assets/card-FHQ4D10L.js +0 -1
  521. package/core/built/admin/assets/chart-helpers-CNpA7re_.js +0 -1
  522. package/core/built/admin/assets/chart-jVz9Nf9t.js +0 -63
  523. package/core/built/admin/assets/checkbox-DKht9xMl.js +0 -1
  524. package/core/built/admin/assets/chunk.524.cc9be98e44890cedc8c8.js +0 -25
  525. package/core/built/admin/assets/chunk.582.e6fe742b3217207b11a6.js +0 -27
  526. package/core/built/admin/assets/code-editor-view-BLQIV85-.js +0 -1
  527. package/core/built/admin/assets/code-editor-view-Cg5eJxcr.js +0 -1
  528. package/core/built/admin/assets/color-picker-DQoghc0t.js +0 -3
  529. package/core/built/admin/assets/color-picker-field-BbeK5RRs.js +0 -1
  530. package/core/built/admin/assets/combobox-weO4FBbv.js +0 -1
  531. package/core/built/admin/assets/command-DlLrCm9V.js +0 -1
  532. package/core/built/admin/assets/comments-BjTitLmP.js +0 -1
  533. package/core/built/admin/assets/confirmation-context-IyqoXVk-.js +0 -1
  534. package/core/built/admin/assets/container-DAimjOF_.js +0 -1
  535. package/core/built/admin/assets/context-menu-BtioYFrg.js +0 -1
  536. package/core/built/admin/assets/copy-field-C6ujqJlP.js +0 -1
  537. package/core/built/admin/assets/create-ghost-browse-value-source-DAZMWZNq.js +0 -1
  538. package/core/built/admin/assets/custom-integration-modal-Dm8QI_J4.js +0 -1
  539. package/core/built/admin/assets/data-list-C0CKkeWW.js +0 -1
  540. package/core/built/admin/assets/date-range-select-DrjHQdgz.js +0 -1
  541. package/core/built/admin/assets/design-and-theme-modal-CXVOzBWu.js +0 -2
  542. package/core/built/admin/assets/detail-page-QpLIL-EO.js +0 -1
  543. package/core/built/admin/assets/dirty-confirm-dialog-DWwxREGh.js +0 -1
  544. package/core/built/admin/assets/dist-Bf-HQtVL.js +0 -1
  545. package/core/built/admin/assets/dist-CUwte9v_.js +0 -1
  546. package/core/built/admin/assets/dist-FEQQAwTe.js +0 -1
  547. package/core/built/admin/assets/domain-DBrBic6q.js +0 -1
  548. package/core/built/admin/assets/dropzone-D61QVcEY.js +0 -5
  549. package/core/built/admin/assets/edit-profile-jCqJBxqw.js +0 -1
  550. package/core/built/admin/assets/editor-8Fm4UBEd.js +0 -8
  551. package/core/built/admin/assets/editor-screen-BSX_uC2B.js +0 -27
  552. package/core/built/admin/assets/email-sending-status-provider-DnNhlIvt.js +0 -1
  553. package/core/built/admin/assets/embed-signup-form-modal-DqtBs1WE.js +0 -8
  554. package/core/built/admin/assets/empty-indicator-L4Ql5Db7.js +0 -1
  555. package/core/built/admin/assets/en-Cx75dJv5.js +0 -1
  556. package/core/built/admin/assets/explore-DXhDCtKw.js +0 -1
  557. package/core/built/admin/assets/feature-image-placeholder-e2q6TcH6.js +0 -1
  558. package/core/built/admin/assets/feed-mmt4noNL.js +0 -1
  559. package/core/built/admin/assets/field-p7KnP98B.js +0 -1
  560. package/core/built/admin/assets/filter-bar-CiIKBg3D.js +0 -1
  561. package/core/built/admin/assets/filter-sources-I-dRaQxl.js +0 -1
  562. package/core/built/admin/assets/filters-1injvyxJ.js +0 -1
  563. package/core/built/admin/assets/filters-DnpO6GWX.js +0 -1
  564. package/core/built/admin/assets/gift-link-modal-C3H7YFXO.js +0 -1
  565. package/core/built/admin/assets/grid-5vplBYri.js +0 -1
  566. package/core/built/admin/assets/growth-B1og1kQp.js +0 -1
  567. package/core/built/admin/assets/growth-Bf6OHZlK.js +0 -3
  568. package/core/built/admin/assets/heading-BB21QAbb.js +0 -1
  569. package/core/built/admin/assets/history-modal-t_qEnxPx.js +0 -1
  570. package/core/built/admin/assets/html-field-COLQbV4r.js +0 -1
  571. package/core/built/admin/assets/images-4mvoc3lB.js +0 -1
  572. package/core/built/admin/assets/index-B3HZU2i8.css +0 -2
  573. package/core/built/admin/assets/index-DDd-zhNL.js +0 -4
  574. package/core/built/admin/assets/inline-B8H6NzIw.js +0 -1
  575. package/core/built/admin/assets/input-group-CLIN2ykI.js +0 -1
  576. package/core/built/admin/assets/input-surface-wSO5CRy5.js +0 -1
  577. package/core/built/admin/assets/integration-header-CKGrXNVP.js +0 -1
  578. package/core/built/admin/assets/invite-user-modal-BaN2mdhI.js +0 -1
  579. package/core/built/admin/assets/koenig-loader-B1XPPY5C.js +0 -2
  580. package/core/built/admin/assets/kpi-card-CRLPVlFW.js +0 -1
  581. package/core/built/admin/assets/kpi-card-CRPbW8NZ.js +0 -1
  582. package/core/built/admin/assets/kpi-helpers-D7zT96bp.js +0 -1
  583. package/core/built/admin/assets/kpi-tabs-DE_yh9Go.js +0 -1
  584. package/core/built/admin/assets/label-CgeBxy4o.js +0 -1
  585. package/core/built/admin/assets/label-picker-DGDp4Vwr.js +0 -1
  586. package/core/built/admin/assets/layout-DWnOMly4.js +0 -1
  587. package/core/built/admin/assets/lib-_QYaUU89.js +0 -2
  588. package/core/built/admin/assets/link-helpers-8J7ixADV.js +0 -1
  589. package/core/built/admin/assets/list-page-DLMP0PxC.js +0 -1
  590. package/core/built/admin/assets/member-activity-ClMWFyvN.js +0 -1
  591. package/core/built/admin/assets/member-activity-feed-BQY5Rwaj.js +0 -1
  592. package/core/built/admin/assets/member-custom-fields-Dd_ie1zG.js +0 -1
  593. package/core/built/admin/assets/member-detail-DjwkGVne.js +0 -1
  594. package/core/built/admin/assets/members--N9lhk1N.js +0 -4
  595. package/core/built/admin/assets/modal-page-Dz-9TP4E.js +0 -1
  596. package/core/built/admin/assets/moderation-DfYBKq9s.js +0 -1
  597. package/core/built/admin/assets/multi-select-combobox-BcBEzUW_.js +0 -1
  598. package/core/built/admin/assets/navigation-modal-Cd-scywg.js +0 -1
  599. package/core/built/admin/assets/newsletter-detail-modal-CFRY6vg_.js +0 -1
  600. package/core/built/admin/assets/newsletter-emails-4ntck1AC.js +0 -1
  601. package/core/built/admin/assets/newsletter-o6eCJtab.js +0 -1
  602. package/core/built/admin/assets/newsletters-Bmlv0edG.js +0 -1
  603. package/core/built/admin/assets/note-CWs3LF-0.js +0 -1
  604. package/core/built/admin/assets/notifications-BjSvTJqh.js +0 -1
  605. package/core/built/admin/assets/offers-container-modal-Bc9A196w.js +0 -1
  606. package/core/built/admin/assets/onboarding-route-Di1LJYEE.js +0 -1
  607. package/core/built/admin/assets/overview-DE7NHZQN.js +0 -1
  608. package/core/built/admin/assets/overview-DEF-ZY6x.js +0 -1
  609. package/core/built/admin/assets/page-header-B-G_g42C.js +0 -1
  610. package/core/built/admin/assets/pagemenu-CnkTDO71.js +0 -1
  611. package/core/built/admin/assets/pages-route-VT7r7YhG.js +0 -1
  612. package/core/built/admin/assets/portal-frame-D9V8iq5x.js +0 -1
  613. package/core/built/admin/assets/portal-modal-B5OOR9ZD.js +0 -1
  614. package/core/built/admin/assets/post-analytics-header-J0WciLx6.js +0 -1
  615. package/core/built/admin/assets/post-analytics-rGb-PgD-.js +0 -1
  616. package/core/built/admin/assets/post-share-modal-D0BbTo4W.js +0 -1
  617. package/core/built/admin/assets/posts-list-screen-CO5jAWoU.js +0 -2
  618. package/core/built/admin/assets/posts-route-DV-CXWK9.js +0 -1
  619. package/core/built/admin/assets/preferences-Tac29oG6.js +0 -5
  620. package/core/built/admin/assets/preview-chrome-C2lQgZBZ.js +0 -1
  621. package/core/built/admin/assets/preview-modal-CjRbBr8U.js +0 -1
  622. package/core/built/admin/assets/profile-yiM1f_Og.js +0 -1
  623. package/core/built/admin/assets/radio-group-CKROWsw4.js +0 -1
  624. package/core/built/admin/assets/router-provider-CU87qxXw.js +0 -1
  625. package/core/built/admin/assets/select-CKaC4ggu.js +0 -1
  626. package/core/built/admin/assets/settings-81kxUa28.js +0 -1
  627. package/core/built/admin/assets/settings-BVXFqBVK.js +0 -4
  628. package/core/built/admin/assets/settings-breadcrumbs-czGRx-iu.js +0 -1
  629. package/core/built/admin/assets/shade-app-CcS3f8MZ-D5BnfHck.js +0 -3
  630. package/core/built/admin/assets/share-modal-BL-16PiB.js +0 -1
  631. package/core/built/admin/assets/skeleton-DwCva0-b.js +0 -1
  632. package/core/built/admin/assets/sort-button-Dquc83jY.js +0 -1
  633. package/core/built/admin/assets/stack-BURz77VS.js +0 -1
  634. package/core/built/admin/assets/stats-view-NDja_g96.js +0 -1
  635. package/core/built/admin/assets/stripe-button-C3cfCAou.js +0 -1
  636. package/core/built/admin/assets/stripe-connect-modal-FyE3Ey2c.js +0 -1
  637. package/core/built/admin/assets/switch-zfUUy9Jh.js +0 -1
  638. package/core/built/admin/assets/table-dE4GTIRT.js +0 -1
  639. package/core/built/admin/assets/tabs-B3XK93sR.js +0 -1
  640. package/core/built/admin/assets/tag-detail-D4P-tZdM.js +0 -2
  641. package/core/built/admin/assets/tag-picker-BNSZ6Qxw.js +0 -1
  642. package/core/built/admin/assets/tags-BsZcaJ6h.js +0 -1
  643. package/core/built/admin/assets/text-DC-ot6u2.js +0 -1
  644. package/core/built/admin/assets/textarea-B4FffFmE.js +0 -1
  645. package/core/built/admin/assets/tier-detail-modal-a77Z2VMH.js +0 -1
  646. package/core/built/admin/assets/toggle-group-D2p4okmJ.js +0 -1
  647. package/core/built/admin/assets/transistor-modal-C8RMkhOD.js +0 -1
  648. package/core/built/admin/assets/trend-badge-B9v7kMF8.js +0 -1
  649. package/core/built/admin/assets/types-uYQ1HgqL.js +0 -1
  650. package/core/built/admin/assets/use-analytics-data-ChHqiZXv.js +0 -1
  651. package/core/built/admin/assets/use-availability-hPdeG76y.js +0 -1
  652. package/core/built/admin/assets/use-filter-params-BSFigDIn.js +0 -1
  653. package/core/built/admin/assets/use-growth-stats-CqqdnESN.js +0 -1
  654. package/core/built/admin/assets/use-limiter-DBGjYqu7.js +0 -19
  655. package/core/built/admin/assets/use-reply-chain-data-DmD2yX5D.js +0 -1
  656. package/core/built/admin/assets/use-sending-eta-CQeG6OP_.js +0 -1
  657. package/core/built/admin/assets/use-setting-group-Dza6bQ7W.js +0 -1
  658. package/core/built/admin/assets/use-settings-navigation-BIjI5mL3.js +0 -1
  659. package/core/built/admin/assets/use-simple-pagination-DwVxe-Lo.js +0 -1
  660. package/core/built/admin/assets/use-staff-users-i_Mq9OGR.js +0 -1
  661. package/core/built/admin/assets/use-tinybird-query-DXoF74NM.js +0 -1
  662. package/core/built/admin/assets/user-detail-modal-BU4QCHE7.js +0 -1
  663. package/core/built/admin/assets/virtual-list-DScLNuU8.js +0 -1
  664. package/core/built/admin/assets/web-BZS-t4H0.js +0 -1
  665. package/core/built/admin/assets/web-DxAUxnK3.js +0 -2
  666. package/core/frontend/services/sitemap/utils.js +0 -17
  667. package/core/server/services/automations/get-scheduler-idempotency-key.js +0 -13
  668. package/core/server/web/api/testmode/index.js +0 -1
  669. package/core/server/web/api/testmode/jobs/cpu-hog.js +0 -15
  670. package/core/server/web/api/testmode/jobs/graceful-job.js +0 -50
  671. package/core/server/web/api/testmode/jobs/say-hello.js +0 -17
  672. package/core/server/web/api/testmode/routes.js +0 -120
@@ -81,8 +81,8 @@ module.exports = class MentionSendingService {
81
81
  return;
82
82
  }
83
83
  // make sure we have something to parse before we create a job
84
- let html = post.get('status') === 'published' ? post.get('html') : null;
85
- let previousHtml = post.previous('status') === 'published' ? post.previous('html') : null;
84
+ const html = post.get('status') === 'published' ? post.get('html') : null;
85
+ const previousHtml = post.previous('status') === 'published' ? post.previous('html') : null;
86
86
  if (html || previousHtml) {
87
87
  // Capture the source URL now, from the event's data, rather than
88
88
  // deferring the model into the job.
@@ -309,12 +309,11 @@ module.exports = class Mention {
309
309
  timestamp = new Date();
310
310
  }
311
311
 
312
- let payload;
313
- payload = data.payload ? JSON.parse(JSON.stringify(data.payload)) : null;
312
+ const payload = data.payload ? JSON.parse(JSON.stringify(data.payload)) : null;
314
313
 
315
314
  /** @type boolean */
316
- let verified;
317
- verified = isNew ? false : !!data.verified;
315
+
316
+ const verified = isNew ? false : !!data.verified;
318
317
 
319
318
  /** @type {ObjectID | null} */
320
319
  let resourceId = null;
@@ -321,7 +321,10 @@ module.exports = class MentionsAPI {
321
321
  * @returns {Promise<Mention>}
322
322
  */
323
323
  async processWebmention(webmention) {
324
- let mention = await this.#repository.getBySourceAndTarget(webmention.source, webmention.target);
324
+ const mention = await this.#repository.getBySourceAndTarget(
325
+ webmention.source,
326
+ webmention.target,
327
+ );
325
328
 
326
329
  return await this.#updateWebmention(mention, webmention);
327
330
  }
@@ -20,33 +20,6 @@ const workerMessageHandler = ({ name, message }) => {
20
20
  }
21
21
  };
22
22
 
23
- const initTestMode = () => {
24
- // Output job queue length every 5 seconds
25
- setInterval(() => {
26
- logging.warn(
27
- `${jobManager.inlineQueue.length()} jobs in the queue. Idle: ${jobManager.inlineQueue.idle()}`,
28
- );
29
-
30
- const runningScheduledjobs = Object.keys(jobManager.bree.workers);
31
- if (Object.keys(jobManager.bree.workers).length) {
32
- logging.warn(
33
- `${Object.keys(jobManager.bree.workers).length} jobs running: ${runningScheduledjobs}`,
34
- );
35
- }
36
-
37
- const scheduledJobs = Object.keys(jobManager.bree.intervals);
38
- if (Object.keys(jobManager.bree.intervals).length) {
39
- logging.warn(
40
- `${Object.keys(jobManager.bree.intervals).length} scheduled jobs: ${scheduledJobs}`,
41
- );
42
- }
43
-
44
- if (runningScheduledjobs.length === 0 && scheduledJobs.length === 0) {
45
- logging.warn('No scheduled or running jobs');
46
- }
47
- }, 5000);
48
- };
49
-
50
23
  const jobManager = new JobManager({
51
24
  errorHandler,
52
25
  workerMessageHandler,
@@ -56,4 +29,3 @@ const jobManager = new JobManager({
56
29
  });
57
30
 
58
31
  module.exports = jobManager;
59
- module.exports.initTestMode = initTestMode;
@@ -300,7 +300,7 @@ module.exports = class MilestonesService {
300
300
  const membersMilestones = this.#milestonesConfig.members;
301
301
 
302
302
  // get the closest milestone we're over now
303
- let achievedMilestones = this.#getMatchedMilestones(membersMilestones, membersCount);
303
+ const achievedMilestones = this.#getMatchedMilestones(membersMilestones, membersCount);
304
304
 
305
305
  // check for previously achieved milestones. We do not send an email when no
306
306
  // previous milestones exist
@@ -391,7 +391,7 @@ class NewslettersService {
391
391
  if (process.env.NODE_ENV !== 'production') {
392
392
  logging.warn(message.text);
393
393
  }
394
- let msg = Object.assign(
394
+ const msg = Object.assign(
395
395
  {
396
396
  from: fromEmail,
397
397
  subject: 'Verify email address',
@@ -37,7 +37,7 @@ class Notifications {
37
37
  * @returns {Object[]} - all notifications
38
38
  */
39
39
  fetchAllNotifications() {
40
- let allNotifications = this.settingsCache.get('notifications');
40
+ const allNotifications = this.settingsCache.get('notifications');
41
41
 
42
42
  // @TODO: this check can be removed to improve read operation perf. It's here only because
43
43
  // reads are done often and this gives a possibility to self-heal any broken records.
@@ -67,7 +67,7 @@ class Notifications {
67
67
  * @returns {boolean}
68
68
  */
69
69
  areNotificationsValid(notifications) {
70
- if (!_.isArray(notifications)) {
70
+ if (!Array.isArray(notifications)) {
71
71
  return false;
72
72
  }
73
73
 
@@ -151,7 +151,7 @@ class Notifications {
151
151
  addedAt: moment().toDate(),
152
152
  };
153
153
 
154
- let notificationsToCheck = notifications;
154
+ const notificationsToCheck = notifications;
155
155
  let notificationsToAdd = [];
156
156
 
157
157
  const allNotifications = this.fetchAllNotifications();
@@ -90,15 +90,15 @@ const findUrlWithProvider = (url) => {
90
90
 
91
91
  // build up a list of URL variations to test against because the oembed
92
92
  // providers list is not always up to date with scheme or www vs non-www
93
- let baseUrl = url.replace(/^\/\/|^https?:\/\/(?:www\.)?/, '');
94
- let testUrls = [
93
+ const baseUrl = url.replace(/^\/\/|^https?:\/\/(?:www\.)?/, '');
94
+ const testUrls = [
95
95
  `https://${baseUrl}`,
96
96
  `https://www.${baseUrl}`,
97
97
  `http://${baseUrl}`,
98
98
  `http://www.${baseUrl}`,
99
99
  ];
100
100
 
101
- for (let testUrl of testUrls) {
101
+ for (const testUrl of testUrls) {
102
102
  provider = hasProvider(testUrl);
103
103
  if (provider) {
104
104
  url = testUrl;
@@ -394,6 +394,80 @@ class OEmbedService {
394
394
  };
395
395
  }
396
396
 
397
+ /**
398
+ * Requests a URL through this.externalRequest and resolves with the response
399
+ * and at most the first chunk of its body, aborting the rest of the download.
400
+ *
401
+ * @param {string} url
402
+ * @returns {Promise<{response: import('got').Response, chunk?: Buffer}>}
403
+ */
404
+ fetchFirstChunk(url) {
405
+ return new Promise((resolve, reject) => {
406
+ const stream = this.externalRequest.stream(url, {
407
+ headers: {
408
+ 'user-agent': USER_AGENT,
409
+ range: 'bytes=0-0',
410
+ },
411
+ timeout: {
412
+ request: DEFAULT_REQUEST_TIMEOUT,
413
+ },
414
+ decompress: false,
415
+ throwHttpErrors: false,
416
+ });
417
+ let response;
418
+
419
+ stream.on('response', (res) => {
420
+ response = res;
421
+ });
422
+ stream.once('data', (chunk) => {
423
+ stream.destroy();
424
+ resolve({ response, chunk });
425
+ });
426
+ stream.once('end', () => resolve({ response }));
427
+ stream.on('error', reject);
428
+ });
429
+ }
430
+
431
+ /**
432
+ * Checks that a favicon candidate is reachable and looks like an image.
433
+ *
434
+ * Replaces metascraper-logo-favicon's default resolver, which probes via
435
+ * reachable-url. reachable-url bundles got 11, which ignores the `dnsLookup`
436
+ * externalRequest installs to validate the resolved IP at connection time,
437
+ * leaving those probes open to DNS rebinding. Mirrors the default resolver's
438
+ * checks otherwise.
439
+ *
440
+ * @param {string} faviconUrl
441
+ * @param {Array<string|string[]>} [contentTypes] - allowed content types for the icon's extension
442
+ * @returns {Promise<{url: string} | undefined>}
443
+ */
444
+ async resolveFaviconUrl(faviconUrl, contentTypes) {
445
+ let result;
446
+ try {
447
+ result = await this.fetchFirstChunk(faviconUrl);
448
+ } catch {
449
+ return undefined;
450
+ }
451
+
452
+ const { response, chunk } = result;
453
+ if (!response || response.statusCode < 200 || response.statusCode >= 300) {
454
+ return undefined;
455
+ }
456
+
457
+ if (contentTypes) {
458
+ const contentType = response.headers['content-type']?.split(';')[0].toLowerCase();
459
+ if (!contentType || !contentTypes.some((ct) => contentType.includes(ct))) {
460
+ return undefined;
461
+ }
462
+ // An empty body or one starting with '<' (60) is markup, not an image
463
+ if (!chunk?.length || chunk[0] === 60) {
464
+ return undefined;
465
+ }
466
+ }
467
+
468
+ return { url: response.url };
469
+ }
470
+
397
471
  /**
398
472
  * @param {string} url
399
473
  * @param {string} html
@@ -477,6 +551,8 @@ class OEmbedService {
477
551
  require('metascraper-logo-favicon')({
478
552
  gotOpts,
479
553
  pickFn,
554
+ resolveFaviconUrl: (faviconUrl, contentTypes) =>
555
+ this.resolveFaviconUrl(faviconUrl, contentTypes),
480
556
  }),
481
557
  require('metascraper-logo')(),
482
558
  ];
@@ -132,7 +132,6 @@ class CanThisResult {
132
132
  const self = this;
133
133
  let userPermissionLoad;
134
134
  let apiKeyPermissionLoad;
135
- let permissionsLoad;
136
135
 
137
136
  // Get context.user, context.api_key and context.app
138
137
  context = parseContext(context);
@@ -158,7 +157,7 @@ class CanThisResult {
158
157
  }
159
158
 
160
159
  // Wait for both user and api key permissions to load
161
- permissionsLoad = Promise.all([userPermissionLoad, apiKeyPermissionLoad]).then(
160
+ const permissionsLoad = Promise.all([userPermissionLoad, apiKeyPermissionLoad]).then(
162
161
  function (result) {
163
162
  return {
164
163
  user: result[0],
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const moment_1 = __importDefault(require("moment"));
7
7
  const logging_1 = __importDefault(require("@tryghost/logging"));
8
8
  const build_signed_job_1 = require("../../adapters/scheduling/build-signed-job");
9
+ const get_scheduler_idempotency_key_1 = require("../../adapters/scheduling/get-scheduler-idempotency-key");
9
10
  // CJS-only modules — typed loosely below. models is the Bookshelf registry
10
11
  // without TS declarations; the rest are JS modules without types.
11
12
  const models = require('../../models');
@@ -111,14 +112,20 @@ class PostScheduling {
111
112
  const resource = `${resourceType}s`;
112
113
  const publishedAt = event === 'unscheduled' ? model.previous('published_at') : model.get('published_at');
113
114
  const previousPublishedAt = model.previous('published_at');
115
+ const time = (0, moment_1.default)(publishedAt).valueOf();
114
116
  return (0, build_signed_job_1.buildSignedJob)({
115
117
  apiUrl: this.#apiUrl,
116
118
  path: ['schedules', resource, `${model.get('id')}/`],
117
- time: (0, moment_1.default)(publishedAt).valueOf(),
119
+ time,
118
120
  key,
119
121
  extra: {
120
122
  oldTime: previousPublishedAt ? (0, moment_1.default)(previousPublishedAt).valueOf() : null,
121
123
  },
124
+ // The key identifies one job: the URL already carries the resource
125
+ // and a token signed for this fire time under the current signing key,
126
+ // so re-registering the same job (e.g. a boot rebuild) yields the same
127
+ // key, while a reschedule or key rotation yields a new one.
128
+ getIdempotencyKey: (url) => (0, get_scheduler_idempotency_key_1.getSchedulerIdempotencyKey)({ namespace: 'post-scheduling', date: new Date(time), url }),
122
129
  });
123
130
  }
124
131
  }
@@ -65,6 +65,13 @@ const publishNow = async (resourceType, id, force, options) => {
65
65
  throw err;
66
66
  }
67
67
 
68
+ // The read above is filtered to scheduled resources, so a resource that an
69
+ // earlier delivery has already published normally surfaces as NotFound.
70
+ // Keep an explicit check so the outcome doesn't depend on that filter.
71
+ if (preScheduledResource.status !== 'scheduled') {
72
+ return NO_OP;
73
+ }
74
+
68
75
  const publishedAtMoment = moment(preScheduledResource.published_at);
69
76
 
70
77
  if (publishedAtMoment.diff(moment(), 'minutes') > publishAPostBySchedulerToleranceInMinutes) {
@@ -128,7 +128,7 @@ class SettingsBREADService {
128
128
  * @returns
129
129
  */
130
130
  browse(context) {
131
- let settings = this.settingsCache.getAll();
131
+ const settings = this.settingsCache.getAll();
132
132
 
133
133
  return this._formatBrowse(settings, context);
134
134
  }
@@ -199,7 +199,7 @@ class SettingsBREADService {
199
199
  * @returns
200
200
  */
201
201
  async edit(settings, options, stripeConnectData) {
202
- let filteredSettings = settings.filter((setting) => {
202
+ const filteredSettings = settings.filter((setting) => {
203
203
  // The `stripe_connect_integration_token` "setting" is only used to set the `stripe_connect_*` settings.
204
204
  return (
205
205
  ![
@@ -488,7 +488,7 @@ class SettingsBREADService {
488
488
  if (process.env.NODE_ENV !== 'production') {
489
489
  logging.warn(message.text);
490
490
  }
491
- let msg = Object.assign(
491
+ const msg = Object.assign(
492
492
  {
493
493
  from: fromEmail,
494
494
  subject: 'Verify email address',
@@ -41,7 +41,7 @@ let SITE_UUID;
41
41
  function getOrGenerateSiteUuid() {
42
42
  if (!SITE_UUID) {
43
43
  try {
44
- let configuredSiteUuid = config.get('site_uuid');
44
+ const configuredSiteUuid = config.get('site_uuid');
45
45
  if (configuredSiteUuid && validator.isUUID(configuredSiteUuid)) {
46
46
  SITE_UUID = configuredSiteUuid.toLowerCase();
47
47
  logging.info(`Setting site_uuid to configured value: ${SITE_UUID}`);
@@ -125,7 +125,7 @@ class SettingsHelpers {
125
125
  }
126
126
 
127
127
  getMembersSupportAddress() {
128
- let supportAddress = this.settingsCache.get('members_support_address');
128
+ const supportAddress = this.settingsCache.get('members_support_address');
129
129
 
130
130
  if (!supportAddress) {
131
131
  // In the new flow, we make a difference between an empty setting (= use default) and a 'noreply' setting (=use noreply @ domain)
@@ -44,7 +44,7 @@ class StaffServiceEmails {
44
44
  attributionTitle = 'Homepage';
45
45
  }
46
46
 
47
- let staffUrl = this.urlUtils.urlJoin(
47
+ const staffUrl = this.urlUtils.urlJoin(
48
48
  this.urlUtils.urlFor('admin', true),
49
49
  '#',
50
50
  `/settings/staff/${user.slug}/email-notifications`,
@@ -101,7 +101,7 @@ class StaffServiceEmails {
101
101
  startedOn: this.getFormattedDate(subscription.startDate),
102
102
  };
103
103
 
104
- let offerData = this.getOfferData(offer);
104
+ const offerData = this.getOfferData(offer);
105
105
 
106
106
  if (!offerData && subscription?.trialEnd) {
107
107
  const trialEnd = moment(subscription.trialEnd);
@@ -118,7 +118,7 @@ class StaffServiceEmails {
118
118
  attributionTitle = 'Homepage';
119
119
  }
120
120
 
121
- let staffUrl = this.urlUtils.urlJoin(
121
+ const staffUrl = this.urlUtils.urlJoin(
122
122
  this.urlUtils.urlFor('admin', true),
123
123
  '#',
124
124
  `/settings/staff/${user.slug}/email-notifications`,
@@ -180,7 +180,7 @@ class StaffServiceEmails {
180
180
  cancellationReason: subscription.cancellationReason || '',
181
181
  };
182
182
 
183
- let staffUrl = this.urlUtils.urlJoin(
183
+ const staffUrl = this.urlUtils.urlJoin(
184
184
  this.urlUtils.urlFor('admin', true),
185
185
  '#',
186
186
  `/settings/staff/${user.slug}/email-notifications`,
@@ -217,7 +217,7 @@ class StaffServiceEmails {
217
217
  * @param {string} recipient.slug
218
218
  */
219
219
  async getSharedData(recipient) {
220
- let staffUrl = this.urlUtils.urlJoin(
220
+ const staffUrl = this.urlUtils.urlJoin(
221
221
  this.urlUtils.urlFor('admin', true),
222
222
  '#',
223
223
  `/settings/staff/${recipient.slug}/email-notifications`,
@@ -273,7 +273,7 @@ class StaffServiceEmails {
273
273
  for (const user of users) {
274
274
  const to = user.email;
275
275
 
276
- let staffUrl = this.urlUtils.urlJoin(
276
+ const staffUrl = this.urlUtils.urlJoin(
277
277
  this.urlUtils.urlFor('admin', true),
278
278
  '#',
279
279
  `/settings/staff/${user.slug}/email-notifications`,
@@ -442,7 +442,7 @@ class StaffServiceEmails {
442
442
  for (const user of users) {
443
443
  const to = user.email;
444
444
 
445
- let staffUrl = this.urlUtils.urlJoin(
445
+ const staffUrl = this.urlUtils.urlJoin(
446
446
  this.urlUtils.urlFor('admin', true),
447
447
  '#',
448
448
  `/settings/staff/${user.slug}/email-notifications`,
@@ -485,7 +485,7 @@ class StaffServiceEmails {
485
485
 
486
486
  /** @private */
487
487
  getMemberData(member) {
488
- let name = member?.name || member?.email;
488
+ const name = member?.name || member?.email;
489
489
  return {
490
490
  name,
491
491
  email: member?.email,
@@ -607,7 +607,7 @@ class StaffServiceEmails {
607
607
  this.logging.warn(message.text);
608
608
  }
609
609
 
610
- let msg = Object.assign(
610
+ const msg = Object.assign(
611
611
  {
612
612
  from: this.fromEmailAddress,
613
613
  forceTextContent: true,
@@ -355,7 +355,7 @@ class PostsStatsService {
355
355
  .groupBy('source');
356
356
 
357
357
  // Now join all the data
358
- let query = this.knex
358
+ const query = this.knex
359
359
  .with('free_referrers', freeReferrersCTE)
360
360
  .with('paid_referrers', paidReferrersCTE)
361
361
  .with('mrr_referrers', mrrReferrersCTE)
@@ -657,7 +657,7 @@ class PostsStatsService {
657
657
  const { dateFrom, dateTo } = getDateBoundaries(options);
658
658
 
659
659
  // Simpler approach mirroring _buildFreeMembersSubquery
660
- let subquery = knex('members_created_events as mce')
660
+ const subquery = knex('members_created_events as mce')
661
661
  .select('mce.referrer_source as source')
662
662
  .countDistinct('mce.member_id as free_members')
663
663
  .leftJoin('members_subscription_created_events as msce', function () {
@@ -686,7 +686,7 @@ class PostsStatsService {
686
686
  _buildPaidReferrersSubquery(postId, options) {
687
687
  const knex = this.knex;
688
688
  const { dateFrom, dateTo } = getDateBoundaries(options);
689
- let subquery = knex('members_subscription_created_events as msce')
689
+ const subquery = knex('members_subscription_created_events as msce')
690
690
  .select('msce.referrer_source as source')
691
691
  .countDistinct('msce.member_id as paid_members')
692
692
  .where('msce.attribution_id', postId)
@@ -708,7 +708,7 @@ class PostsStatsService {
708
708
  _buildMrrReferrersSubquery(postId, options) {
709
709
  const knex = this.knex;
710
710
  const { dateFrom, dateTo } = getDateBoundaries(options);
711
- let subquery = knex('members_subscription_created_events as msce')
711
+ const subquery = knex('members_subscription_created_events as msce')
712
712
  .select('msce.referrer_source as source')
713
713
  .sum('mpse.mrr_delta as mrr')
714
714
  .join('members_paid_subscription_events as mpse', function () {
@@ -744,7 +744,7 @@ class PostsStatsService {
744
744
  const { dateFrom, dateTo } = getDateBoundaries(options);
745
745
 
746
746
  // Parse order field and direction
747
- let [orderField, orderDirection = 'desc'] = order.split(' ');
747
+ const [orderField, orderDirection = 'desc'] = order.split(' ');
748
748
 
749
749
  // Map frontend order fields to database fields (simplified for ORDER BY)
750
750
  const orderFieldMap = {
@@ -834,7 +834,7 @@ class PostsStatsService {
834
834
  const { dateFrom, dateTo } = getDateBoundaries(options);
835
835
 
836
836
  // Parse order field and direction
837
- let [orderField, orderDirection = 'desc'] = order.split(' ');
837
+ const [orderField, orderDirection = 'desc'] = order.split(' ');
838
838
 
839
839
  // Map frontend order fields to database fields (simplified for ORDER BY)
840
840
  const orderFieldMap = {
@@ -1095,7 +1095,7 @@ class PostsStatsService {
1095
1095
  const { dateFrom, dateTo } = getDateBoundaries(options);
1096
1096
 
1097
1097
  // Build optimized deltas query - avoid expensive JOIN
1098
- let deltasQuery = this.knex('members_subscribe_events as mse')
1098
+ const deltasQuery = this.knex('members_subscribe_events as mse')
1099
1099
  .select(
1100
1100
  this.knex.raw(`DATE(mse.created_at) as date`),
1101
1101
  this.knex.raw(`SUM(CASE WHEN mse.subscribed = 1 THEN 1 ELSE -1 END) as value`),
@@ -1150,7 +1150,7 @@ class PostsStatsService {
1150
1150
  // Build complete time series with all dates
1151
1151
  const completeValues = [];
1152
1152
  let lastValue = startingValue; // Use provided starting value
1153
- let currentDate = rangeStart.clone();
1153
+ const currentDate = rangeStart.clone();
1154
1154
 
1155
1155
  while (currentDate.isSameOrBefore(rangeEnd)) {
1156
1156
  const dateKey = currentDate.format('YYYY-MM-DD');
@@ -1507,7 +1507,7 @@ class PostsStatsService {
1507
1507
  try {
1508
1508
  // Build free members query (modeled after _buildFreeMembersSubquery)
1509
1509
  // Members who signed up on post but paid elsewhere/never
1510
- let freeMembersQuery = this.knex('members_created_events as mce')
1510
+ const freeMembersQuery = this.knex('members_created_events as mce')
1511
1511
  .select('mce.attribution_id as post_id')
1512
1512
  .countDistinct('mce.member_id as free_members')
1513
1513
  .leftJoin('members_subscription_created_events as msce', function () {
@@ -1525,7 +1525,7 @@ class PostsStatsService {
1525
1525
 
1526
1526
  // Build paid members query (modeled after _buildPaidMembersSubquery)
1527
1527
  // Members whose paid conversion was attributed to this post
1528
- let paidMembersQuery = this.knex('members_subscription_created_events as msce')
1528
+ const paidMembersQuery = this.knex('members_subscription_created_events as msce')
1529
1529
  .select('msce.attribution_id as post_id')
1530
1530
  .countDistinct('msce.member_id as paid_members')
1531
1531
  .whereIn('msce.attribution_type', ['post', 'page'])
@@ -226,7 +226,7 @@ class ReferrersStatsService {
226
226
  const { dateFrom: startDateTime, dateTo: endDateTime } = getDateBoundaries(options);
227
227
 
228
228
  // Join subscription created events with paid subscription events to get MRR changes
229
- let query = knex('members_subscription_created_events as msce')
229
+ const query = knex('members_subscription_created_events as msce')
230
230
  .join('members_paid_subscription_events as mpse', function () {
231
231
  this.on('msce.member_id', '=', 'mpse.member_id').andOn(
232
232
  'msce.subscription_id',
@@ -25,12 +25,12 @@ class SubscriptionStatsService {
25
25
  });
26
26
 
27
27
  /** @type {SubscriptionHistoryEntry[]} */
28
- let subscriptionHistoryEntries = [];
28
+ const subscriptionHistoryEntries = [];
29
29
 
30
30
  /** @type {string[]} */
31
- let cadences = [];
31
+ const cadences = [];
32
32
  /** @type {string[]} */
33
- let tiers = [];
33
+ const tiers = [];
34
34
 
35
35
  for (let index = subscriptionDeltaEntries.length - 1; index >= 0; index -= 1) {
36
36
  const entry = subscriptionDeltaEntries[index];
@@ -82,6 +82,8 @@ const create = ({ config, request, settingsCache, tinybirdService }) => {
82
82
  }
83
83
  });
84
84
 
85
+ searchParams.ghost_client = 'server';
86
+
85
87
  // Convert searchParams to query string and append to URL
86
88
  const queryString = new URLSearchParams(searchParams).toString();
87
89
  const fullUrl = `${tinybirdUrl}?${queryString}`;
@@ -91,7 +93,12 @@ const create = ({ config, request, settingsCache, tinybirdService }) => {
91
93
  Authorization: `Bearer ${token}`,
92
94
  },
93
95
  timeout: {
94
- request: 10000,
96
+ // Allow Tinybird's 30-second query deadline to finish before timing out locally.
97
+ request: 35000,
98
+ },
99
+ retry: {
100
+ // A failed request may still be executing; avoid duplicating expensive queries.
101
+ limit: 0,
95
102
  },
96
103
  };
97
104
 
@@ -367,7 +367,7 @@ module.exports = class StripeAPI {
367
367
  let latestCustomer = customers[0];
368
368
  let latestSubscriptionTime = 0;
369
369
 
370
- for (let customer of customers) {
370
+ for (const customer of customers) {
371
371
  // skip customers with no subscriptions
372
372
  if (
373
373
  !customer.subscriptions ||
@@ -378,7 +378,7 @@ module.exports = class StripeAPI {
378
378
  }
379
379
 
380
380
  // find the customer with the most recent subscription
381
- for (let subscription of customer.subscriptions.data) {
381
+ for (const subscription of customer.subscriptions.data) {
382
382
  if (
383
383
  subscription.current_period_end &&
384
384
  subscription.current_period_end > latestSubscriptionTime
@@ -606,7 +606,7 @@ module.exports = class StripeAPI {
606
606
  subscriptionData.trial_period_days = options.trialDays;
607
607
  }
608
608
 
609
- let stripeSessionOptions = {
609
+ const stripeSessionOptions = {
610
610
  payment_method_types: this.PAYMENT_METHOD_TYPES,
611
611
  managed_payments: MANAGED_PAYMENTS_DISABLED,
612
612
  success_url: options.successUrl || this._config.checkoutSessionSuccessUrl,
@@ -69,7 +69,7 @@ module.exports = class StripeMigrations {
69
69
  logging.info(`Populating products and prices for existing stripe customers`);
70
70
  const uniquePlans = _.uniq(subscriptions.map((d) => _.get(d, 'plan.id')));
71
71
 
72
- let stripePrices = [];
72
+ const stripePrices = [];
73
73
  for (const plan of uniquePlans) {
74
74
  try {
75
75
  const stripePrice = await this.api.getPrice(plan, {
@@ -356,9 +356,9 @@ module.exports = class StripeMigrations {
356
356
 
357
357
  if (!monthlyPrice) {
358
358
  logging.info('Could not any active Monthly price - creating a new one');
359
- let defaultStripeProduct;
359
+
360
360
  const stripeProductsPage = await this.models.StripeProduct.findPage({ ...options, limit: 1 });
361
- defaultStripeProduct = stripeProductsPage.data[0];
361
+ const defaultStripeProduct = stripeProductsPage.data[0];
362
362
  const price = await this.api.createPrice({
363
363
  currency: 'usd',
364
364
  amount: 5000,
@@ -445,9 +445,9 @@ module.exports = class StripeMigrations {
445
445
 
446
446
  if (!yearlyPrice) {
447
447
  logging.info('Could not any active yearly price - creating a new one');
448
- let defaultStripeProduct;
448
+
449
449
  const stripeProductsPage = await this.models.StripeProduct.findPage({ ...options, limit: 1 });
450
- defaultStripeProduct = stripeProductsPage.data[0];
450
+ const defaultStripeProduct = stripeProductsPage.data[0];
451
451
  const price = await this.api.createPrice({
452
452
  currency: 'usd',
453
453
  amount: 500,
@@ -621,7 +621,7 @@ module.exports = class StripeMigrations {
621
621
  });
622
622
  if (invalidSubscriptions.length > 0) {
623
623
  logging.warn(`Deleting ${invalidSubscriptions.length} invalid subscription(s)`);
624
- for (let sub of invalidSubscriptions) {
624
+ for (const sub of invalidSubscriptions) {
625
625
  logging.warn(`Deleting subscription - ${sub.id} - no price found`);
626
626
  await sub.destroy(options);
627
627
  }