ghost 6.57.1 → 6.58.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 (747) hide show
  1. package/LICENSE +22 -0
  2. package/bin/validate-adapters.js +1 -5
  3. package/components/ghost-storage-base-3.0.0.tgz +0 -0
  4. package/components/tryghost-adapter-base-cache-0.2.0.tgz +0 -0
  5. package/components/tryghost-adapter-base-jobs-0.0.0.tgz +0 -0
  6. package/components/tryghost-adapter-base-redirects-0.0.0.tgz +0 -0
  7. package/components/tryghost-adapter-base-route-settings-0.0.0.tgz +0 -0
  8. package/components/tryghost-adapter-base-scheduling-0.2.2.tgz +0 -0
  9. package/components/tryghost-adapter-base-sso-0.1.2.tgz +0 -0
  10. package/components/tryghost-admin-api-schema-0.0.0.tgz +0 -0
  11. package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
  12. package/components/tryghost-i18n-0.0.0.tgz +0 -0
  13. package/components/tryghost-kg-card-factory-5.2.4.tgz +0 -0
  14. package/components/tryghost-kg-clean-basic-html-4.3.4.tgz +0 -0
  15. package/components/tryghost-kg-converters-1.2.5.tgz +0 -0
  16. package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
  17. package/components/tryghost-kg-default-nodes-2.2.0.tgz +0 -0
  18. package/components/tryghost-kg-default-transforms-1.3.4.tgz +0 -0
  19. package/components/tryghost-kg-html-to-lexical-1.4.0.tgz +0 -0
  20. package/components/tryghost-kg-lexical-html-renderer-1.5.0.tgz +0 -0
  21. package/components/tryghost-kg-markdown-html-renderer-7.2.4.tgz +0 -0
  22. package/components/tryghost-kg-utils-1.1.4.tgz +0 -0
  23. package/components/tryghost-nql-string-0.0.0.tgz +0 -0
  24. package/components/tryghost-parse-email-address-0.0.0.tgz +0 -0
  25. package/core/boot.js +35 -3
  26. package/core/built/admin/assets/{about-BNojRaxf.js → about-B_BvSyLF.js} +1 -1
  27. package/core/built/admin/assets/{account-migration-DMS8JsM-.js → account-migration-oJUGxnzT.js} +1 -1
  28. package/core/built/admin/assets/activitypub/{account-migration-DHFbePl6.js → account-migration-BpDeIF3G.js} +8 -8
  29. package/core/built/admin/assets/activitypub/activitypub.js +4 -4
  30. package/core/built/admin/assets/activitypub/{avatar-CT4tS2_S.js → avatar-B0SpBPVL.js} +3 -3
  31. package/core/built/admin/assets/activitypub/{avatar-flipboard-ByYWKipo.js → avatar-flipboard-DKt1LGcE.js} +3 -3
  32. package/core/built/admin/assets/activitypub/{bluesky-sharing-srVnSHDz.js → bluesky-sharing-aPMtrS3L.js} +10 -10
  33. package/core/built/admin/assets/activitypub/{chunk-KS7C4IRE-D4HEcEwi.js → chunk-KS7C4IRE-CnTrsgmM.js} +26 -15
  34. package/core/built/admin/assets/activitypub/{content-formatters-C2sos5Ht.js → content-formatters-BORfuA9G.js} +318 -284
  35. package/core/built/admin/assets/activitypub/{copy-B1UBTOoZ.js → copy-D-YvNi2E.js} +2 -2
  36. package/core/built/admin/assets/activitypub/{dist-MPsb2WZ1.js → dist-Dqggkccr.js} +5 -5
  37. package/core/built/admin/assets/activitypub/{domain-DzcM9Dzo.js → domain-CPdiB27_.js} +10 -10
  38. package/core/built/admin/assets/activitypub/{edit-profile-CsQ_4xAk.js → edit-profile-BY2PawIe.js} +7 -7
  39. package/core/built/admin/assets/activitypub/{explore-CJe0DZBK.js → explore-Sp9bgAwq.js} +11 -11
  40. package/core/built/admin/assets/activitypub/{feed-CKV3qWON.js → feed-BjtF4ohL.js} +10 -10
  41. package/core/built/admin/assets/activitypub/{field-DckHfDJf.js → field-BDOYVTg6.js} +4 -4
  42. package/core/built/admin/assets/activitypub/{hash-Dlp8RM55.js → hash-DqXYHgzG.js} +2 -2
  43. package/core/built/admin/assets/activitypub/{inbox-CsPy4R0M.js → inbox-CZ7IOAMn.js} +2 -2
  44. package/core/built/admin/assets/activitypub/{inbox-DAsjzUUe.js → inbox-z1o2j1Tb.js} +11 -11
  45. package/core/built/admin/assets/activitypub/{label-DWyo9E5T.js → label-1jhN-qhD.js} +4 -4
  46. package/core/built/admin/assets/activitypub/layout-BRMezuty.js +1 -0
  47. package/core/built/admin/assets/activitypub/{moderation-B0Inc03M.js → moderation-CZudJi8N.js} +9 -9
  48. package/core/built/admin/assets/activitypub/{note-CSE54lER.js → note-nr_m_5yb.js} +8 -8
  49. package/core/built/admin/assets/activitypub/{notifications-RSwbKqdh.js → notifications-BdcyivbT.js} +10 -10
  50. package/core/built/admin/assets/activitypub/{onboarding-BFDkzeR2.js → onboarding-B4kwav9u.js} +2 -2
  51. package/core/built/admin/assets/activitypub/{onboarding-D6rcBdPe.js → onboarding-DZNElJYP.js} +3 -3
  52. package/core/built/admin/assets/activitypub/{preferences-CE231n2_.js → preferences-CNqy1x9C.js} +13 -13
  53. package/core/built/admin/assets/activitypub/{profile-aaQ1j1Eo.js → profile-DlY4rhbO.js} +15 -15
  54. package/core/built/admin/assets/activitypub/{reply-Cjb0Vs3m.js → reply-DASIN0Ec.js} +2 -2
  55. package/core/built/admin/assets/activitypub/{routes-Djb0mc9k.js → routes-CEHdEZzS.js} +31 -31
  56. package/core/built/admin/assets/activitypub/{separator-D8pROI5n.js → separator-B3k35sUV.js} +4 -4
  57. package/core/built/admin/assets/activitypub/{settings-DMc32IQl.js → settings-CrSV1cux.js} +6 -6
  58. package/core/built/admin/assets/activitypub/{site-DVIcsohX.js → site-CtBUCPBz.js} +6 -6
  59. package/core/built/admin/assets/activitypub/{step-1-9Yey9usF.js → step-1-D9jGWyAy.js} +7 -7
  60. package/core/built/admin/assets/activitypub/{step-2-DdYmKRXV.js → step-2-Jz_enuo9.js} +7 -7
  61. package/core/built/admin/assets/activitypub/{step-3-hdSkcjZU.js → step-3-KpUqpGWi.js} +12 -12
  62. package/core/built/admin/assets/activitypub/{tabs-CUqseYzQ.js → tabs-DvlsxTCI.js} +7 -7
  63. package/core/built/admin/assets/activitypub/{topic-filter-Coni6OXM.js → topic-filter-CIN1E2jg.js} +4 -4
  64. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-MeHTPMQv.js → use-activity-pub-queries-CATFd6YV.js} +4 -4
  65. package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-B046AM38.js → use-navigate-with-base-path-iCkcbMGk.js} +2 -2
  66. package/core/built/admin/assets/activitypub/{use-reply-chain-data-1AO-Xob6.js → use-reply-chain-data-DJ0vhA8V.js} +6 -6
  67. package/core/built/admin/assets/activitypub/{users-BLeiOTHc.js → users-sgJ6GNZX.js} +12 -11
  68. package/core/built/admin/assets/activitypub/{x-BRfRYd16.js → x-Cy2jUiYM.js} +2 -2
  69. package/core/built/admin/assets/add-integration-modal-BW23PDYs.js +1 -0
  70. package/core/built/admin/assets/add-newsletter-modal-M0ls8BKO.js +1 -0
  71. package/core/built/admin/assets/{add-recommendation-modal-D-3LOrdd.js → add-recommendation-modal-B0NeBMzl.js} +1 -1
  72. package/core/built/admin/assets/{analytics-DTIMRhWw.js → analytics-BC2oR8ay.js} +1 -1
  73. package/core/built/admin/assets/announcement-bar-modal-pXBqjQE_.js +1 -0
  74. package/core/built/admin/assets/{api-keys-_iCT4dxr.js → api-keys-BgKr003d.js} +1 -1
  75. package/core/built/admin/assets/{api-keys-Dx4NeNpK.js → api-keys-Df6uv1dT.js} +1 -1
  76. package/core/built/admin/assets/{audience-DkknNqhZ.js → audience-BY8od8If.js} +1 -1
  77. package/core/built/admin/assets/{automated-emails-PayPCT8L.js → automated-emails-28c2Lbb3.js} +1 -1
  78. package/core/built/admin/assets/{automations-DvSU7QhW.js → automations-DCs6Wady.js} +1 -1
  79. package/core/built/admin/assets/{automations-162q5HjL.js → automations-Dzp_QnON.js} +1 -1
  80. package/core/built/admin/assets/{bluesky-sharing-yZ9A_jL8.js → bluesky-sharing-D0P42Cws.js} +1 -1
  81. package/core/built/admin/assets/{breadcrumb-CjOH7LCU.js → breadcrumb-MTj_cKLb.js} +1 -1
  82. package/core/built/admin/assets/card-CiiE7QfM.js +1 -0
  83. package/core/built/admin/assets/{chart-helpers-DGxvWnBT.js → chart-helpers-DcO3k_vA.js} +1 -1
  84. package/core/built/admin/assets/{checkbox-BSUcnNq_.js → checkbox-LmClhqcS.js} +1 -1
  85. package/core/built/admin/assets/{chunk.424.4a27628efdade15c2dab.js → chunk.408.1a258af360eb8d905508.js} +40 -37
  86. package/core/built/admin/assets/{chunk.571.40f093ed6d883993714e.js → chunk.492.a9da46ca956b10116774.js} +1342 -1342
  87. package/core/built/admin/assets/{chunk.571.40f093ed6d883993714e.js.LICENSE.txt → chunk.492.a9da46ca956b10116774.js.LICENSE.txt} +1 -1
  88. package/core/built/admin/assets/chunk.524.4c693c3a00ac91df34fa.js +25 -0
  89. package/core/built/admin/assets/chunk.582.20b600e329e58d12d7c2.js +27 -0
  90. package/core/built/admin/assets/code-editor-view-DqTOUnbM.js +1 -0
  91. package/core/built/admin/assets/code-editor-view-bA0lfxUL.js +1 -0
  92. package/core/built/admin/assets/{debounce-Cx5B_9OI.js → color-picker-CBlJMv3y.js} +2 -2
  93. package/core/built/admin/assets/color-picker-field-Cv9GOJQZ.js +1 -0
  94. package/core/built/admin/assets/{combobox-5rdgDrDV.js → combobox-BbPJzjCp.js} +1 -1
  95. package/core/built/admin/assets/command-BrhXIlDr.js +1 -0
  96. package/core/built/admin/assets/comments-Cu4rD1aJ.js +1 -0
  97. package/core/built/admin/assets/confirmation-provider-BEdrnHns.js +1 -0
  98. package/core/built/admin/assets/{content-api-modal-BtW4Z1-1.js → content-api-modal-BOFWRUkC.js} +1 -1
  99. package/core/built/admin/assets/{copy-field-CEp_XieW.js → copy-field-8biQvNMD.js} +1 -1
  100. package/core/built/admin/assets/custom-field-type-option-CNhAgHbJ.js +1 -0
  101. package/core/built/admin/assets/custom-integration-modal-CrGOI8IB.js +1 -0
  102. package/core/built/admin/assets/{date-range-select-B3Ij1Rqg.js → date-range-select-Bsh4gIek.js} +1 -1
  103. package/core/built/admin/assets/debounce-pscB46sW.js +1 -0
  104. package/core/built/admin/assets/design-and-theme-modal-DWZguwWX.js +23 -0
  105. package/core/built/admin/assets/{dirty-confirm-dialog-YE9L21gY.js → dirty-confirm-dialog-DmdMpgyN.js} +1 -1
  106. package/core/built/admin/assets/{disabled-sources-indicator-uIzbWL7K.js → disabled-sources-indicator-BLnmyWgt.js} +1 -1
  107. package/core/built/admin/assets/dist-4m6pHdc0.js +23 -0
  108. package/core/built/admin/assets/{dist-DCk0UkGx.js → dist-B6bJuxL3.js} +1 -1
  109. package/core/built/admin/assets/{dist-CbHbGtQ-.js → dist-BtaTA7Ii.js} +1 -1
  110. package/core/built/admin/assets/{dist-Q1p9iXwH.js → dist-CZgIBXQN.js} +1 -1
  111. package/core/built/admin/assets/dist-CiHx7vA5.js +6 -0
  112. package/core/built/admin/assets/{dist-ARN6XTcR.js → dist-ECAUrdGc.js} +1 -1
  113. package/core/built/admin/assets/dist-Z97pCNqS.js +11 -0
  114. package/core/built/admin/assets/{dist-t6AXpf_4.js → dist-zwwGt8Yf.js} +1 -1
  115. package/core/built/admin/assets/{domain-DzrOAPY8.js → domain-Dp9TRrFp.js} +1 -1
  116. package/core/built/admin/assets/{dropzone-CzhP33wa.js → dropzone-B21Entqz.js} +1 -1
  117. package/core/built/admin/assets/{edit-profile-oufs4R4n.js → edit-profile-DG6lpMsr.js} +1 -1
  118. package/core/built/admin/assets/editor-CPQOrhrn.js +8 -0
  119. package/core/built/admin/assets/{editor-DtxX27Jz.css → editor-DLioOiRN.css} +1 -1
  120. package/core/built/admin/assets/{embed-signup-form-modal-Ch3s6lqA.js → embed-signup-form-modal-CgWniDha.js} +2 -2
  121. package/core/built/admin/assets/esm-CXo5SEPy.js +2 -0
  122. package/core/built/admin/assets/{explore-CA-R01Br.js → explore-C3rzONJv.js} +1 -1
  123. package/core/built/admin/assets/{feed-ClC8_Gld.js → feed-DpUwS1cU.js} +1 -1
  124. package/core/built/admin/assets/{field-B3OPenbP.js → field-BQqLTgHM.js} +1 -1
  125. package/core/built/admin/assets/{filter-sources-CiPLnG9A.js → filter-sources-FgqoUIL7.js} +1 -1
  126. package/core/built/admin/assets/{filters-yFvybRMe.js → filters-D0uIMD8n.js} +1 -1
  127. package/core/built/admin/assets/filters-DZJT29GW.js +1 -0
  128. package/core/built/admin/assets/{first-promoter-modal-BC0UpYCD.js → first-promoter-modal-DJhQQheG.js} +1 -1
  129. package/core/built/admin/assets/framework-provider-CFLwK5uS.js +4 -0
  130. package/core/built/admin/assets/{ghost-d38c30b866e59f2e06a357b5eb844fe5.css → ghost-68f447a1796b93a1f128b649bac8506d.css} +1 -1
  131. package/core/built/admin/assets/{ghost-d683fbeb945b13155ea669caa5d8db41.js → ghost-ba408063a5922b458b4a8f216cf23251.js} +124 -342
  132. package/core/built/admin/assets/{ghost-dark-1bffd5099ba7a749303133efacf8480b.css → ghost-dark-28ae4899c92022857f3584694bcb50ef.css} +1 -1
  133. package/core/built/admin/assets/{gift-link-modal-BKRuqo-k.js → gift-link-modal-sdFLjND9.js} +1 -1
  134. package/core/built/admin/assets/{gift-links-CVuqLhsZ.js → gift-links-D7BJ9qfe.js} +1 -1
  135. package/core/built/admin/assets/{global-data-provider-RzW6Bnlf.js → global-data-provider-CixmTX00.js} +1 -1
  136. package/core/built/admin/assets/{growth-ClNAldfL.js → growth-0YYkBEeS.js} +1 -1
  137. package/core/built/admin/assets/{growth-Dz8OSG06.js → growth-DpjAPeQT.js} +2 -2
  138. package/core/built/admin/assets/{history-modal-DIVuQ5Ct.js → history-modal-BWJ4-cJ0.js} +1 -1
  139. package/core/built/admin/assets/{hooks-D6EE7BIt.js → hooks-CJepWnbB.js} +1 -1
  140. package/core/built/admin/assets/{html-field-CVZ2sMxw.js → html-field-C-oa5DEl.js} +1 -1
  141. package/core/built/admin/assets/{iframe-buffering-e8vH4-Qn.js → iframe-buffering-Ba9sDpi2.js} +1 -1
  142. package/core/built/admin/assets/{images-Ok8FFJ3A.js → images-3cQgwfTD.js} +1 -1
  143. package/core/built/admin/assets/{inbox-CMUVI6qb.js → inbox-Dz_JblyJ.js} +6 -6
  144. package/core/built/admin/assets/index-BOJzlYiz.js +67 -0
  145. package/core/built/admin/assets/index-Bid6LAyc.css +1 -0
  146. package/core/built/admin/assets/{input-group-2XU-iuh_.js → input-group-DpogNUIt.js} +1 -1
  147. package/core/built/admin/assets/{integrations-BT6_iJvu.js → integrations-B9yYgci5.js} +1 -1
  148. package/core/built/admin/assets/{invite-user-modal-DrZ7xxrZ.js → invite-user-modal-DCiQSiuD.js} +1 -1
  149. package/core/built/admin/assets/{koenig-editor-base-BPj4S760.js → koenig-editor-base-BApy8Q7C.js} +1 -1
  150. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +8328 -8294
  151. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +84 -84
  152. package/core/built/admin/assets/{koenig-lexical-Cdjv-m3_.js → koenig-lexical-2KuqRwZI.js} +33 -33
  153. package/core/built/admin/assets/{kpi-card-J8Mj1sDX.js → kpi-card-Ck3tT2Wg.js} +1 -1
  154. package/core/built/admin/assets/{kpi-card-awos0BMH.js → kpi-card-DDIxptaS.js} +1 -1
  155. package/core/built/admin/assets/{kpi-helpers-SEhvH-8E.js → kpi-helpers-ssbuy-hD.js} +1 -1
  156. package/core/built/admin/assets/{kpi-tabs-R6BjsKhd.js → kpi-tabs-BqoIM6bI.js} +1 -1
  157. package/core/built/admin/assets/{label-BMC3dzLI.js → label-DodDsMzn.js} +1 -1
  158. package/core/built/admin/assets/label-picker-Cvvbmzb5.js +1 -0
  159. package/core/built/admin/assets/{labels-DAPjKPy2.js → labels-DqvSR6JF.js} +1 -1
  160. package/core/built/admin/assets/layout-DkkGyev2.js +1 -0
  161. package/core/built/admin/assets/limit-service-BhiEvqcP.js +20 -0
  162. package/core/built/admin/assets/{link-helpers-Bzkk68GD.js → link-helpers-kpbU8TWh.js} +1 -1
  163. package/core/built/admin/assets/luxon-D1RVjjpq.js +1 -0
  164. package/core/built/admin/assets/member-custom-fields-CvGcpaiW.js +1 -0
  165. package/core/built/admin/assets/member-detail-CMCMZ47_.js +1 -0
  166. package/core/built/admin/assets/members-sRl6fNfq.js +11 -0
  167. package/core/built/admin/assets/{moderation-mPjYHgZW.js → moderation-KhKwGqI1.js} +1 -1
  168. package/core/built/admin/assets/{multi-select-combobox-CsoyHAiX.js → multi-select-combobox-nhCff0_K.js} +1 -1
  169. package/core/built/admin/assets/{navigation-modal-D_c0badj.js → navigation-modal-MDJExWDJ.js} +1 -1
  170. package/core/built/admin/assets/newsletter-BIBHumfV.js +1 -0
  171. package/core/built/admin/assets/newsletter-detail-modal-CfjBMH3v.js +1 -0
  172. package/core/built/admin/assets/{newsletter-emails-B-OLfrvr.js → newsletter-emails-ClDL-7dA.js} +1 -1
  173. package/core/built/admin/assets/newsletters-CBe-IPzK.js +1 -0
  174. package/core/built/admin/assets/{newsletters-Du0lzskS.js → newsletters-ILsexy-5.js} +1 -1
  175. package/core/built/admin/assets/{note-CSVsUKBm.js → note-HnNUOt4d.js} +1 -1
  176. package/core/built/admin/assets/{notifications-DV9FRtDw.js → notifications-Cj5e-258.js} +1 -1
  177. package/core/built/admin/assets/nql-lang-CaWrLesS.js +19 -0
  178. package/core/built/admin/assets/{offers-Um6ab71O.js → offers-DMxebaoK.js} +1 -1
  179. package/core/built/admin/assets/offers-container-modal-BHwHtixC.js +1 -0
  180. package/core/built/admin/assets/{onboarding-route--jL5KLPD.js → onboarding-route-D_4jp7Nq.js} +1 -1
  181. package/core/built/admin/assets/overview-CezDdg-F.js +1 -0
  182. package/core/built/admin/assets/overview-D5mM51Lj.js +1 -0
  183. package/core/built/admin/assets/{page-header-DAvDYKO9.js → page-header-VLPJfj_d.js} +1 -1
  184. package/core/built/admin/assets/{pages-BVMnpI2O.js → pages-Gchxp5c7.js} +1 -1
  185. package/core/built/admin/assets/{pintura-modal-jiUCxX0Q.js → pintura-modal-BXXJ8Iaa.js} +1 -1
  186. package/core/built/admin/assets/{portal-frame-D4D4nEO6.js → portal-frame-BLCvF8f-.js} +1 -1
  187. package/core/built/admin/assets/portal-modal-DN80tAcy.js +1 -0
  188. package/core/built/admin/assets/{post-analytics-BhAtiFJp.js → post-analytics-Gv81eN_g.js} +1 -1
  189. package/core/built/admin/assets/post-analytics-header-_ydSY8qO.js +1 -0
  190. package/core/built/admin/assets/{post-analytics-provider-DGg0FUqs.js → post-analytics-provider-O2YjZMhN.js} +1 -1
  191. package/core/built/admin/assets/{post-share-modal-DtFAC132.js → post-share-modal-CzYak_a5.js} +1 -1
  192. package/core/built/admin/assets/{posts-CxG7v0-M.js → posts-DgcUi2rc.js} +1 -1
  193. package/core/built/admin/assets/preferences-gneLb6LV.js +5 -0
  194. package/core/built/admin/assets/{preview-modal-DctYx20m.js → preview-modal-Bkq-tgVm.js} +1 -1
  195. package/core/built/admin/assets/profile-CzXmCNTC.js +1 -0
  196. package/core/built/admin/assets/{radio-group-CI5_Kf_d.js → radio-group-Dsq5ZEbV.js} +1 -1
  197. package/core/built/admin/assets/{referrers-B9QDAfYm.js → referrers-C3a2K8qB.js} +1 -1
  198. package/core/built/admin/assets/{router-provider-DSQfprxH.js → router-provider-CkB_ArLF.js} +1 -1
  199. package/core/built/admin/assets/{select-CkXqNJDJ.js → select-xuZAuDyS.js} +1 -1
  200. package/core/built/admin/assets/{settings-ZCj-W56o.js → settings-Ct8pabhr.js} +1 -1
  201. package/core/built/admin/assets/settings-KSWWQanQ.js +4 -0
  202. package/core/built/admin/assets/{settings-breadcrumbs-DIq31FwA.js → settings-breadcrumbs-DbPGu-Tu.js} +1 -1
  203. package/core/built/admin/assets/{share-modal-BNj14g79.js → share-modal-CdiUx9WM.js} +1 -1
  204. package/core/built/admin/assets/{slack-modal-C6SpMQ-q.js → slack-modal-BP--Z3jE.js} +1 -1
  205. package/core/built/admin/assets/{sort-button-B-k54ow2.js → sort-button-CjfKdlsL.js} +1 -1
  206. package/core/built/admin/assets/{source-icon-Cej3sZM6.js → source-icon-DHj1h6Ts.js} +1 -1
  207. package/core/built/admin/assets/{stats-B2KW8E2y.js → stats-C615kulJ.js} +1 -1
  208. package/core/built/admin/assets/{stats-view-CVzU2-p5.js → stats-view-BSMRdYiN.js} +1 -1
  209. package/core/built/admin/assets/{step-1-Dbn1iIMU.js → step-1-pSdGYtIF.js} +1 -1
  210. package/core/built/admin/assets/{step-2-BahnSuN6.js → step-2-T9Uy4eBD.js} +1 -1
  211. package/core/built/admin/assets/{step-3-CW04e2ZJ.js → step-3-D4uXe_XG.js} +2 -2
  212. package/core/built/admin/assets/{stripe-button-BkBZqaGG.js → stripe-button-Bh4p6Wud.js} +1 -1
  213. package/core/built/admin/assets/stripe-connect-modal-C2vTvepi.js +1 -0
  214. package/core/built/admin/assets/{table-BtLcEi1M.js → table-DghJxZMH.js} +1 -1
  215. package/core/built/admin/assets/{tabs-BaWRfg8j.js → tabs-l9c7FjzI.js} +1 -1
  216. package/core/built/admin/assets/tag-detail-DBw_M2-p.js +2 -0
  217. package/core/built/admin/assets/{tags-BbygUvNB.js → tags-DoWsAG6l.js} +1 -1
  218. package/core/built/admin/assets/{tags-BwCgmr5v.js → tags-EmEvJN75.js} +1 -1
  219. package/core/built/admin/assets/{testimonials-modal--bdzppyh.js → testimonials-modal-BZKePE2T.js} +1 -1
  220. package/core/built/admin/assets/tier-detail-modal-D65pVWsN.js +1 -0
  221. package/core/built/admin/assets/{tiers-Da6kxHQP.js → tiers-8iTFjJWg.js} +1 -1
  222. package/core/built/admin/assets/{toggle-group-CVl-Xigr.js → toggle-group-uJnl42w3.js} +1 -1
  223. package/core/built/admin/assets/{topic-filter-BoRHRbL1.js → topic-filter-BM7hz0kW.js} +1 -1
  224. package/core/built/admin/assets/transistor-modal-VZOGN3od.js +1 -0
  225. package/core/built/admin/assets/{unsplash-modal-CixoRAO2.js → unsplash-modal-CKGfACxF.js} +1 -1
  226. package/core/built/admin/assets/{use-analytics-data-BiWvcf1u.js → use-analytics-data-IxJcSjc9.js} +1 -1
  227. package/core/built/admin/assets/use-check-theme-limit-error-CGp3CGT5.js +1 -0
  228. package/core/built/admin/assets/use-feature-flag-CSq2Lwzt.js +1 -0
  229. package/core/built/admin/assets/use-filter-params-0hcJJuEJ.js +1 -0
  230. package/core/built/admin/assets/{use-filterable-api-iMpDZBxD.js → use-filterable-api-CQBtVG-l.js} +1 -1
  231. package/core/built/admin/assets/{use-growth-stats-Dom8xVzo.js → use-growth-stats-1NW-8eEZ.js} +1 -1
  232. package/core/built/admin/assets/use-limiter-ffwpsZPp.js +2 -0
  233. package/core/built/admin/assets/{use-pintura-config-Bj4QmiVk.js → use-pintura-config-BjFChXV1.js} +1 -1
  234. package/core/built/admin/assets/{use-pintura-editor-DvrslmPE.js → use-pintura-editor-Cb41oJyL.js} +1 -1
  235. package/core/built/admin/assets/{use-post-referrers-pxIHTXFs.js → use-post-referrers-Dp1BnTAK.js} +1 -1
  236. package/core/built/admin/assets/{use-reply-chain-data-CmFe0N6F.js → use-reply-chain-data-C0ZUTkfk.js} +1 -1
  237. package/core/built/admin/assets/{use-setting-group-Cmp_sy-d.js → use-setting-group-Bx8M6FL2.js} +1 -1
  238. package/core/built/admin/assets/{use-settings-navigation-BmROPrls.js → use-settings-navigation-BOZcat_V.js} +1 -1
  239. package/core/built/admin/assets/{use-simple-pagination-D5rL3YwO.js → use-simple-pagination-DsEGSJhe.js} +1 -1
  240. package/core/built/admin/assets/{use-tinybird-query-DP2dMaq7.js → use-tinybird-query-Ci_DiPkX.js} +1 -1
  241. package/core/built/admin/assets/{use-tinybird-token-DrK_skPQ.js → use-tinybird-token-CsUwc722.js} +1 -1
  242. package/core/built/admin/assets/use-upgrade-route-B3_DUiuT.js +1 -0
  243. package/core/built/admin/assets/{use-url-input-ChrUZBFf.js → use-url-input-BEZJpVgN.js} +2 -2
  244. package/core/built/admin/assets/user-detail-modal-595z1N5r.js +1 -0
  245. package/core/built/admin/assets/{users-B6hIds6n.js → users-DmGMPfw7.js} +1 -1
  246. package/core/built/admin/assets/virtual-list-D5ugXyZY.js +1 -0
  247. package/core/built/admin/assets/{web-D71mjB2r.js → web-CAta3lRE.js} +1 -1
  248. package/core/built/admin/assets/web-Ds9_wWJK.js +2 -0
  249. package/core/built/admin/assets/zapier-modal-CcfDZY53.js +1 -0
  250. package/core/built/admin/index.html +12 -12
  251. package/core/frontend/apps/private-blogging/lib/middleware.js +5 -58
  252. package/core/frontend/helpers/ghost_head.js +52 -0
  253. package/core/frontend/meta/asset-url.js +20 -9
  254. package/core/frontend/public/cards.manifest.json +1 -0
  255. package/core/frontend/public/ghost-stats.min.js +1 -1
  256. package/core/frontend/services/assets-minification/card-assets.js +121 -46
  257. package/core/frontend/services/assets-minification/index.js +13 -4
  258. package/core/frontend/services/data/fetch-data.js +7 -14
  259. package/core/frontend/services/llms/service.js +27 -6
  260. package/core/frontend/services/proxy.js +1 -0
  261. package/core/frontend/services/routing/api-adapter.js +11 -5
  262. package/core/frontend/services/routing/collection-router.js +1 -2
  263. package/core/frontend/services/routing/controllers/entry/markdown.js +63 -5
  264. package/core/frontend/services/routing/controllers/entry.js +1 -1
  265. package/core/frontend/services/routing/controllers/previews.js +0 -3
  266. package/core/frontend/services/routing/events.js +2 -1
  267. package/core/frontend/services/routing/parent-router.js +0 -22
  268. package/core/frontend/services/routing/router-manager.js +2 -2
  269. package/core/frontend/services/routing/static-pages-router.js +0 -1
  270. package/core/frontend/services/sitemap/handler.js +3 -4
  271. package/core/frontend/services/sitemap/site-map-manager.js +1 -2
  272. package/core/frontend/services/theme-engine/i18n/i18n.js +0 -33
  273. package/core/frontend/web/middleware/llms-discovery.js +2 -2
  274. package/core/frontend/web/routers/serve-public-file.js +33 -3
  275. package/core/frontend/web/site.js +5 -4
  276. package/core/server/adapters/jobs/InMemoryJobsBackend.js +113 -0
  277. package/core/server/adapters/redirects/S3RedirectsStore.js +33 -13
  278. package/core/server/adapters/route-settings/S3RouteSettingsStore.js +33 -13
  279. package/core/server/adapters/scheduling/scheduling-default.js +6 -7
  280. package/core/server/adapters/storage/LocalStorageBase.js +1 -3
  281. package/core/server/api/endpoints/index.js +0 -4
  282. package/core/server/api/endpoints/member-custom-fields.js +15 -4
  283. package/core/server/api/endpoints/pages.js +3 -11
  284. package/core/server/api/endpoints/posts.js +3 -11
  285. package/core/server/api/endpoints/utils/api-filter-utils.js +15 -1
  286. package/core/server/api/endpoints/utils/serializers/input/settings.js +4 -0
  287. package/core/server/api/endpoints/utils/serializers/output/index.js +0 -4
  288. package/core/server/api/endpoints/utils/serializers/output/mappers/email-batches.js +1 -1
  289. package/core/server/api/endpoints/utils/serializers/output/mappers/snippets.js +0 -1
  290. package/core/server/api/endpoints/utils/serializers/output/member-custom-fields.js +1 -0
  291. package/core/server/data/exporter/table-lists.js +4 -1
  292. package/core/server/data/migrations/utils/schema.js +5 -3
  293. package/core/server/data/migrations/versions/6.57/2026-08-04-18-00-00-store-custom-field-values-as-leaf-rows.js +19 -7
  294. package/core/server/data/migrations/versions/6.58/2026-08-10-08-20-50-add-machine-payments-settings.js +41 -0
  295. package/core/server/data/migrations/versions/6.58/2026-08-10-08-21-00-add-machine-payment-events-table.js +18 -0
  296. package/core/server/data/migrations/versions/6.58/2026-08-10-15-24-09-reset-custom-field-definitions-for-underscored-keys.js +66 -0
  297. package/core/server/data/migrations/versions/6.58/2026-08-11-10-00-00-swap-custom-field-values-to-key-fk.js +65 -0
  298. package/core/server/data/migrations/versions/6.58/2026-08-11-10-34-25-remove-legacy-explore-integration.js +131 -0
  299. package/core/server/data/migrations/versions/6.58/2026-08-11-16-00-00-add-sort-order-to-members-custom-fields.js +13 -0
  300. package/core/server/data/migrations/versions/6.58/2026-08-11-21-22-48-rename-email-batches-provider-id.js +8 -0
  301. package/core/server/data/migrations/versions/6.58/2026-08-13-16-07-33-add-automation-runs-automation-id-created-at-index.js +28 -0
  302. package/core/server/data/schema/README.md +87 -0
  303. package/core/server/data/schema/commands.js +5 -2
  304. package/core/server/data/schema/default-settings/default-settings.json +27 -0
  305. package/core/server/data/schema/fixtures/fixtures.json +0 -21
  306. package/core/server/data/schema/schema.js +37 -9
  307. package/core/server/data/seeders/data-generator.js +3 -1
  308. package/core/server/data/seeders/importers/automation-action-edges-importer.js +38 -0
  309. package/core/server/data/seeders/importers/automation-action-revisions-importer.js +139 -0
  310. package/core/server/data/seeders/importers/automation-actions-importer.js +84 -0
  311. package/core/server/data/seeders/importers/automation-run-steps-importer.js +134 -0
  312. package/core/server/data/seeders/importers/automation-runs-importer.js +97 -0
  313. package/core/server/data/seeders/importers/automations-importer.js +78 -0
  314. package/core/server/data/seeders/importers/benefits-importer.js +1 -1
  315. package/core/server/data/seeders/importers/comment-reports-importer.js +5 -5
  316. package/core/server/data/seeders/importers/comments-importer.js +6 -6
  317. package/core/server/data/seeders/importers/email-batches-importer.js +9 -8
  318. package/core/server/data/seeders/importers/email-recipient-failures-importer.js +1 -1
  319. package/core/server/data/seeders/importers/email-recipients-importer.js +12 -12
  320. package/core/server/data/seeders/importers/emails-importer.js +7 -7
  321. package/core/server/data/seeders/importers/index.js +6 -0
  322. package/core/server/data/seeders/importers/labels-importer.js +4 -4
  323. package/core/server/data/seeders/importers/members-click-events-importer.js +4 -4
  324. package/core/server/data/seeders/importers/members-created-events-importer.js +5 -5
  325. package/core/server/data/seeders/importers/members-feedback-importer.js +7 -7
  326. package/core/server/data/seeders/importers/members-importer.js +5 -5
  327. package/core/server/data/seeders/importers/members-labels-importer.js +1 -1
  328. package/core/server/data/seeders/importers/members-login-events-importer.js +4 -4
  329. package/core/server/data/seeders/importers/members-newsletters-importer.js +1 -1
  330. package/core/server/data/seeders/importers/members-paid-subscription-events-importer.js +1 -1
  331. package/core/server/data/seeders/importers/members-products-importer.js +3 -3
  332. package/core/server/data/seeders/importers/members-status-events-importer.js +4 -4
  333. package/core/server/data/seeders/importers/members-stripe-customers-importer.js +3 -3
  334. package/core/server/data/seeders/importers/members-stripe-customers-subscriptions-importer.js +8 -8
  335. package/core/server/data/seeders/importers/members-subscribe-events-importer.js +3 -3
  336. package/core/server/data/seeders/importers/members-subscription-created-events-importer.js +4 -4
  337. package/core/server/data/seeders/importers/newsletters-importer.js +1 -1
  338. package/core/server/data/seeders/importers/offer-redemptions-importer.js +6 -6
  339. package/core/server/data/seeders/importers/offers-importer.js +4 -4
  340. package/core/server/data/seeders/importers/posts-authors-importer.js +1 -1
  341. package/core/server/data/seeders/importers/posts-importer.js +5 -5
  342. package/core/server/data/seeders/importers/posts-products-importer.js +1 -1
  343. package/core/server/data/seeders/importers/posts-tags-importer.js +1 -1
  344. package/core/server/data/seeders/importers/products-benefits-importer.js +1 -1
  345. package/core/server/data/seeders/importers/products-importer.js +1 -1
  346. package/core/server/data/seeders/importers/recommendation-click-events-importer.js +1 -1
  347. package/core/server/data/seeders/importers/recommendation-subscribe-events-importer.js +1 -1
  348. package/core/server/data/seeders/importers/recommendations-importer.js +1 -1
  349. package/core/server/data/seeders/importers/redirects-importer.js +1 -1
  350. package/core/server/data/seeders/importers/roles-users-importer.js +1 -1
  351. package/core/server/data/seeders/importers/stripe-prices-importer.js +1 -1
  352. package/core/server/data/seeders/importers/stripe-products-importer.js +1 -1
  353. package/core/server/data/seeders/importers/table-importer.js +92 -91
  354. package/core/server/data/seeders/importers/tags-importer.js +3 -3
  355. package/core/server/data/seeders/importers/users-importer.js +3 -3
  356. package/core/server/data/seeders/importers/web-mentions-importer.js +3 -3
  357. package/core/server/data/seeders/utils/database-date.js +14 -18
  358. package/core/server/data/seeders/utils/json-importer.js +1 -1
  359. package/core/server/data/seeders/utils/random.js +8 -7
  360. package/core/server/data/seeders/utils/topological-sort.js +5 -3
  361. package/core/server/data/tinybird/ARCHITECTURE.md +1 -2
  362. package/core/server/models/base/plugins/crud.js +0 -5
  363. package/core/server/models/index.js +2 -0
  364. package/core/server/models/machine-payment-event.js +18 -0
  365. package/core/server/models/member.js +24 -0
  366. package/core/server/models/settings.js +32 -3
  367. package/core/server/models/user.js +1 -1
  368. package/core/server/services/README.md +30 -0
  369. package/core/server/services/activitypub/activity-pub-service.js +2 -3
  370. package/core/server/services/adapter-manager/base-classes.js +3 -1
  371. package/core/server/services/auth/passwordreset.js +47 -51
  372. package/core/server/services/automations/database-automations-repository.js +19 -3
  373. package/core/server/services/automations/poll.js +2 -8
  374. package/core/server/services/comments/comments-service.js +4 -16
  375. package/core/server/services/comments/index.js +1 -3
  376. package/core/server/services/email-analytics/email-analytics-service-wrapper.js +68 -119
  377. package/core/server/services/email-analytics/email-analytics-service.js +73 -229
  378. package/core/server/services/email-analytics/event-processing-result.js +0 -10
  379. package/core/server/services/email-analytics/fetch-mailgun-events.js +25 -0
  380. package/core/server/services/email-analytics/index.js +35 -67
  381. package/core/server/services/email-analytics/lib/queries.js +88 -51
  382. package/core/server/services/email-analytics/newsletter-email-analytics-batch-processor.js +4 -1
  383. package/core/server/services/email-service/batch-sending-service.js +1 -1
  384. package/core/server/services/email-service/email-event-processor.js +12 -12
  385. package/core/server/services/email-service/events/email-bounced-event.js +8 -46
  386. package/core/server/services/email-service/events/email-delivered-event.js +8 -36
  387. package/core/server/services/email-service/events/email-opened-event.js +8 -36
  388. package/core/server/services/email-service/events/email-temporary-bounced-event.js +8 -46
  389. package/core/server/services/email-service/events/email-unsubscribed-event.js +8 -31
  390. package/core/server/services/email-service/events/spam-complaint-event.js +8 -31
  391. package/core/server/services/email-service/newsletter-email-event-storage.js +8 -7
  392. package/core/server/services/email-service/sending-service.js +1 -1
  393. package/core/server/services/email-suppression-list/mailgun-email-suppression-list.js +2 -2
  394. package/core/server/services/email-suppression-list/service.js +1 -3
  395. package/core/server/services/explore-ping/explore-ping-service.js +1 -6
  396. package/core/server/services/explore-ping/index.js +0 -2
  397. package/core/server/services/gifts/index.js +109 -3
  398. package/core/server/services/gifts/jobs/clean-gifts-job.js +1 -1
  399. package/core/server/services/gifts/jobs/send-gift-reminders-job.js +1 -1
  400. package/core/server/services/jobs-service/index.js +36 -0
  401. package/core/server/services/jobs-service/job.js +6 -0
  402. package/core/server/services/jobs-service/jobs-service.js +91 -0
  403. package/core/server/services/jobs-service/register-job-handlers.js +6 -0
  404. package/core/server/services/lib/mailgun-client.js +1 -1
  405. package/core/server/services/machine-payments/README.md +23 -0
  406. package/core/server/services/machine-payments/adapters/mpp-adapter.js +195 -0
  407. package/core/server/services/machine-payments/content-loader.js +89 -0
  408. package/core/server/services/machine-payments/eligibility.js +6 -0
  409. package/core/server/services/machine-payments/events/machine-payment-event-repository.js +58 -0
  410. package/core/server/services/machine-payments/events/machine-payment-event.js +46 -0
  411. package/core/server/services/machine-payments/index.js +87 -0
  412. package/core/server/services/machine-payments/pricing.js +54 -0
  413. package/core/server/services/machine-payments/service.js +275 -0
  414. package/core/server/services/machine-payments/stripe/deposit-address-store.js +157 -0
  415. package/core/server/services/machine-payments/stripe/payment-recorder.js +85 -0
  416. package/core/server/services/machine-payments/stripe/stripe-client-options.js +25 -0
  417. package/core/server/services/machine-payments/types.js +2 -0
  418. package/core/server/services/members/import-export/csv/parse.js +9 -1
  419. package/core/server/services/members/import-export/import/completion-email.js +61 -27
  420. package/core/server/services/members/import-export/import/email-template.js +28 -15
  421. package/core/server/services/members/import-export/import/importer.js +99 -51
  422. package/core/server/services/members/import-export/import/spool.js +1 -1
  423. package/core/server/services/members/import-export/index.js +24 -1
  424. package/core/server/services/members/members-api/services/member-bread-service.js +2 -2
  425. package/core/server/services/members/members-config-provider.js +12 -2
  426. package/core/server/services/members-custom-fields/actions.js +2 -1
  427. package/core/server/services/members-custom-fields/definitions-service.js +109 -27
  428. package/core/server/services/members-custom-fields/filter.js +199 -0
  429. package/core/server/services/members-custom-fields/key.js +37 -0
  430. package/core/server/services/members-custom-fields/queries.js +15 -0
  431. package/core/server/services/members-custom-fields/schema.js +1 -1
  432. package/core/server/services/members-custom-fields/values-service.js +18 -14
  433. package/core/server/services/members-events/last-seen-at-updater.js +1 -1
  434. package/core/server/services/oembed/oembed-service.js +8 -2
  435. package/core/server/services/permissions/can-this.js +4 -1
  436. package/core/server/services/posts/posts-service.js +18 -16
  437. package/core/server/services/public-config/config.js +1 -1
  438. package/core/server/services/route-settings/dynamic-routing-service.js +2 -0
  439. package/core/server/services/settings-helpers/settings-helpers.js +0 -1
  440. package/core/server/services/stats/posts-stats-service.js +0 -2
  441. package/core/server/services/stripe/stripe-api.js +2 -9
  442. package/core/server/web/api/endpoints/admin/middleware.js +0 -1
  443. package/core/server/web/api/endpoints/admin/routes.js +2 -3
  444. package/core/server/web/comments/routes.js +31 -8
  445. package/core/shared/config/defaults.json +17 -2
  446. package/core/shared/config/loader.js +11 -2
  447. package/core/shared/config/overrides.json +2 -0
  448. package/core/shared/config/secrets.js +71 -0
  449. package/core/shared/labs.js +4 -13
  450. package/core/shared/machine-payments.js +30 -0
  451. package/core/shared/private-site-access/index.js +68 -0
  452. package/package.json +48 -43
  453. package/pnpm-lock.yaml +1412 -1583
  454. package/pnpm-workspace.yaml +85 -48
  455. package/bin/validate-adapters.ts +0 -87
  456. package/components/tryghost-adapter-base-scheduling-0.2.1.tgz +0 -0
  457. package/components/tryghost-adapter-base-sso-0.1.1.tgz +0 -0
  458. package/components/tryghost-kg-card-factory-5.2.3.tgz +0 -0
  459. package/components/tryghost-kg-clean-basic-html-4.3.3.tgz +0 -0
  460. package/components/tryghost-kg-converters-1.2.4.tgz +0 -0
  461. package/components/tryghost-kg-default-cards-10.3.4.tgz +0 -0
  462. package/components/tryghost-kg-default-nodes-2.1.5.tgz +0 -0
  463. package/components/tryghost-kg-default-transforms-1.3.3.tgz +0 -0
  464. package/components/tryghost-kg-html-to-lexical-1.3.3.tgz +0 -0
  465. package/components/tryghost-kg-lexical-html-renderer-1.4.3.tgz +0 -0
  466. package/components/tryghost-kg-markdown-html-renderer-7.2.3.tgz +0 -0
  467. package/components/tryghost-kg-utils-1.1.3.tgz +0 -0
  468. package/content/themes/casper/assets/built/casper.js.map +0 -1
  469. package/content/themes/casper/assets/built/global.css.map +0 -1
  470. package/content/themes/casper/assets/built/screen.css.map +0 -1
  471. package/content/themes/source/assets/built/screen.css.map +0 -1
  472. package/content/themes/source/assets/built/source.js.map +0 -1
  473. package/core/built/admin/assets/activitypub/layout-DM_3pqsU.js +0 -1
  474. package/core/built/admin/assets/add-integration-modal-DU9ghGLS.js +0 -1
  475. package/core/built/admin/assets/add-newsletter-modal-DFxuQrYu.js +0 -1
  476. package/core/built/admin/assets/announcement-bar-modal-DGCcezB6.js +0 -1
  477. package/core/built/admin/assets/card-aUHX0hyR.js +0 -1
  478. package/core/built/admin/assets/chunk.524.dce1c51e0bc30fb2718e.js +0 -25
  479. package/core/built/admin/assets/chunk.582.3a430d5c6a744fd475b6.js +0 -27
  480. package/core/built/admin/assets/code-editor-view-BcyKABrG.js +0 -1
  481. package/core/built/admin/assets/color-picker-field-8NoSnhNI.js +0 -1
  482. package/core/built/admin/assets/command-BOYMbZa_.js +0 -1
  483. package/core/built/admin/assets/comments-BhNM5CYl.js +0 -1
  484. package/core/built/admin/assets/confirmation-modal-CYD7x3UQ.js +0 -1
  485. package/core/built/admin/assets/custom-integration-modal-bk3lNEuQ.js +0 -1
  486. package/core/built/admin/assets/design-and-theme-modal-B2xYKS1I.js +0 -23
  487. package/core/built/admin/assets/dist-Bg8bSvLA.js +0 -6
  488. package/core/built/admin/assets/dist-BnFdlebk.js +0 -11
  489. package/core/built/admin/assets/dist-CsvXCJSe.js +0 -23
  490. package/core/built/admin/assets/editor-BBKrunMK.js +0 -8
  491. package/core/built/admin/assets/filters-Bz0HsRie.js +0 -1
  492. package/core/built/admin/assets/framework-provider-CmtnPXIT.js +0 -4
  493. package/core/built/admin/assets/index-DUXM0NlS.js +0 -67
  494. package/core/built/admin/assets/index-Ds2iUoF6.css +0 -1
  495. package/core/built/admin/assets/label-picker-Bnlru5tO.js +0 -1
  496. package/core/built/admin/assets/layout-yR9rlvEw.js +0 -1
  497. package/core/built/admin/assets/limit-modal-COmLevuY.js +0 -1
  498. package/core/built/admin/assets/limit-service-9fwD33lU.js +0 -20
  499. package/core/built/admin/assets/member-custom-fields-BvFKEpxJ.js +0 -1
  500. package/core/built/admin/assets/member-detail-CWdPAe3p.js +0 -1
  501. package/core/built/admin/assets/members-Bnt0ih2R.js +0 -11
  502. package/core/built/admin/assets/newsletter-DR49NyGS.js +0 -1
  503. package/core/built/admin/assets/newsletter-detail-modal-B45pL1pb.js +0 -1
  504. package/core/built/admin/assets/newsletters-DGs5BaKH.js +0 -1
  505. package/core/built/admin/assets/nql-lang-B7faUf8D.js +0 -19
  506. package/core/built/admin/assets/offers-container-modal-B0hFS8nk.js +0 -1
  507. package/core/built/admin/assets/overview-B-ZPNqMo.js +0 -1
  508. package/core/built/admin/assets/overview-D96iwoJi.js +0 -1
  509. package/core/built/admin/assets/portal-modal-BLFdYeDH.js +0 -1
  510. package/core/built/admin/assets/post-analytics-header-DK27VjJm.js +0 -1
  511. package/core/built/admin/assets/preferences-CuWLISHa.js +0 -5
  512. package/core/built/admin/assets/profile-BsKYYtuL.js +0 -1
  513. package/core/built/admin/assets/settings-B4vM-rgV.js +0 -4
  514. package/core/built/admin/assets/stripe-connect-modal-CYDDrSJm.js +0 -1
  515. package/core/built/admin/assets/tag-detail-CmqiC32L.js +0 -1
  516. package/core/built/admin/assets/tier-detail-modal-BZmAsIy4.js +0 -1
  517. package/core/built/admin/assets/transistor-modal-CBPDqEGy.js +0 -1
  518. package/core/built/admin/assets/use-check-theme-limit-error-B14lZukR.js +0 -2
  519. package/core/built/admin/assets/use-feature-flag-BmJoc5WN.js +0 -1
  520. package/core/built/admin/assets/use-filter-params-ChoV72Hw.js +0 -1
  521. package/core/built/admin/assets/use-limiter-Dwg8ivgQ.js +0 -2
  522. package/core/built/admin/assets/user-detail-modal-XODpOqNC.js +0 -1
  523. package/core/built/admin/assets/virtual-list-Dnoafqbk.js +0 -1
  524. package/core/built/admin/assets/web-z71lA1Y3.js +0 -2
  525. package/core/built/admin/assets/zapier-modal-Bp507Um7.js +0 -1
  526. package/core/frontend/meta/og-type.ts +0 -13
  527. package/core/frontend/services/routing/api-adapter.ts +0 -157
  528. package/core/frontend/services/routing/config.ts +0 -59
  529. package/core/frontend/services/routing/controllers/entry/canonical-url.ts +0 -14
  530. package/core/frontend/services/routing/controllers/entry/gift-links.ts +0 -56
  531. package/core/frontend/services/routing/controllers/entry/markdown.ts +0 -72
  532. package/core/frontend/services/routing/controllers/entry.ts +0 -120
  533. package/core/frontend/services/routing/controllers/rss.ts +0 -66
  534. package/core/frontend/services/routing/permalink-adapter.ts +0 -10
  535. package/core/frontend/src/utils/privacy.ts +0 -66
  536. package/core/server/adapters/redirects/FileStore.ts +0 -113
  537. package/core/server/adapters/redirects/S3RedirectsStore.ts +0 -185
  538. package/core/server/adapters/route-settings/FileStore.ts +0 -144
  539. package/core/server/adapters/route-settings/S3RouteSettingsStore.ts +0 -199
  540. package/core/server/adapters/route-settings/utils.ts +0 -17
  541. package/core/server/adapters/scheduling/deps.d.ts +0 -1
  542. package/core/server/adapters/scheduling/error-capture.ts +0 -91
  543. package/core/server/adapters/scheduling/scheduling-default.ts +0 -248
  544. package/core/server/adapters/scheduling/utils.ts +0 -36
  545. package/core/server/adapters/sso/DefaultSSOAdapter.ts +0 -15
  546. package/core/server/adapters/storage/LocalFilesStorage.ts +0 -24
  547. package/core/server/adapters/storage/LocalImagesStorage.ts +0 -24
  548. package/core/server/adapters/storage/LocalMediaStorage.ts +0 -24
  549. package/core/server/adapters/storage/LocalStorageBase.ts +0 -342
  550. package/core/server/adapters/storage/S3Storage.ts +0 -506
  551. package/core/server/adapters/storage/utils.ts +0 -60
  552. package/core/server/api/endpoints/automation-action-links.ts +0 -46
  553. package/core/server/api/endpoints/explore.js +0 -18
  554. package/core/server/api/endpoints/gift-links.ts +0 -87
  555. package/core/server/api/endpoints/libraries.d.ts +0 -2
  556. package/core/server/api/endpoints/member-commenting.ts +0 -92
  557. package/core/server/api/endpoints/member-custom-fields.ts +0 -106
  558. package/core/server/api/endpoints/utils/api-filter-utils.ts +0 -22
  559. package/core/server/api/endpoints/utils/gift-link-access.ts +0 -82
  560. package/core/server/api/endpoints/utils/public-cache-keys.ts +0 -47
  561. package/core/server/api/endpoints/utils/serializers/input/member-commenting.ts +0 -29
  562. package/core/server/api/endpoints/utils/serializers/output/explore.js +0 -11
  563. package/core/server/api/endpoints/utils/serializers/output/gift-links.ts +0 -21
  564. package/core/server/api/endpoints/utils/serializers/output/member-commenting.ts +0 -8
  565. package/core/server/api/endpoints/utils/serializers/output/member-custom-fields.ts +0 -25
  566. package/core/server/api/endpoints/utils/serializers/output/members.d.ts +0 -20
  567. package/core/server/api/endpoints/utils/serializers/output/posts-csv-transform.ts +0 -46
  568. package/core/server/api/endpoints/utils/serializers/output/stream-csv-response.ts +0 -47
  569. package/core/server/api/endpoints/utils/validate-email-sender-fields.ts +0 -42
  570. package/core/server/data/importer/email-template.ts +0 -213
  571. package/core/server/data/seeders/utils/topological-sort.ts +0 -48
  572. package/core/server/lib/auto-filling-map.ts +0 -23
  573. package/core/server/lib/bootstrap-socket.ts +0 -114
  574. package/core/server/lib/case-keys.ts +0 -30
  575. package/core/server/lib/common/to-plain.ts +0 -25
  576. package/core/server/lib/db-date.ts +0 -8
  577. package/core/server/lib/get-inbox-links.ts +0 -276
  578. package/core/server/lib/post-revisions.ts +0 -152
  579. package/core/server/lib/soonest-timer.ts +0 -57
  580. package/core/server/models/base/plugins/bulk-filters.ts +0 -35
  581. package/core/server/models/role-utils.ts +0 -56
  582. package/core/server/services/activitypub/activity-pub-service.ts +0 -216
  583. package/core/server/services/adapter-manager/adapter-manager.ts +0 -253
  584. package/core/server/services/adapter-manager/adapter-paths.ts +0 -26
  585. package/core/server/services/adapter-manager/base-classes.ts +0 -22
  586. package/core/server/services/adapter-manager/index.ts +0 -16
  587. package/core/server/services/adapter-manager/types.ts +0 -45
  588. package/core/server/services/adapter-manager/utils.ts +0 -308
  589. package/core/server/services/auth/reset-authentication.ts +0 -72
  590. package/core/server/services/automations/automations-api.ts +0 -396
  591. package/core/server/services/automations/automations-repository.ts +0 -218
  592. package/core/server/services/automations/constants.ts +0 -4
  593. package/core/server/services/automations/database-automations-repository.ts +0 -1513
  594. package/core/server/services/automations/database-date.ts +0 -26
  595. package/core/server/services/automations/fake-wait-hours-multiplier.ts +0 -12
  596. package/core/server/services/automations/get-scheduler-idempotency-key.ts +0 -8
  597. package/core/server/services/automations/mailgun-message-id.ts +0 -27
  598. package/core/server/services/automations/poll.ts +0 -325
  599. package/core/server/services/automations/scheduler-poll-time.ts +0 -38
  600. package/core/server/services/automations/service.ts +0 -131
  601. package/core/server/services/automations/stale-lock-cutoff.ts +0 -5
  602. package/core/server/services/comments/email-templates/new-comment-reply.txt.ts +0 -25
  603. package/core/server/services/comments/email-templates/new-comment.txt.ts +0 -25
  604. package/core/server/services/comments/email-templates/report.txt.ts +0 -34
  605. package/core/server/services/custom-redirects/redirect-config-parser.ts +0 -148
  606. package/core/server/services/custom-redirects/redirects-service.ts +0 -181
  607. package/core/server/services/custom-redirects/utils.ts +0 -7
  608. package/core/server/services/donations/donation-bookshelf-repository.ts +0 -63
  609. package/core/server/services/donations/donation-payment-event.ts +0 -51
  610. package/core/server/services/email-address/email-address-parser.d.ts +0 -12
  611. package/core/server/services/email-address/email-address-service.ts +0 -241
  612. package/core/server/services/email-analytics/automation-email-analytics-batch-processor.ts +0 -130
  613. package/core/server/services/email-analytics/batch-event-processor.ts +0 -18
  614. package/core/server/services/email-analytics/email-analytics-provider-mailgun.js +0 -57
  615. package/core/server/services/email-analytics/event-processing-result.ts +0 -66
  616. package/core/server/services/email-analytics/events/start-automation-email-analytics-job-event.ts +0 -14
  617. package/core/server/services/email-analytics/events/start-email-analytics-job-event.ts +0 -15
  618. package/core/server/services/email-analytics/index.ts +0 -109
  619. package/core/server/services/email-analytics/jobs/email-analytics-job-scheduler.ts +0 -126
  620. package/core/server/services/email-analytics/lib/queries.ts +0 -341
  621. package/core/server/services/email-service/domain-warming-service.ts +0 -91
  622. package/core/server/services/explore/explore-service.js +0 -59
  623. package/core/server/services/explore/index.js +0 -18
  624. package/core/server/services/explore-ping/explore-ping-service.ts +0 -198
  625. package/core/server/services/explore-ping/index.ts +0 -42
  626. package/core/server/services/files/file-type-utils.ts +0 -56
  627. package/core/server/services/gift-links/actions.ts +0 -51
  628. package/core/server/services/gift-links/codec.ts +0 -16
  629. package/core/server/services/gift-links/index.ts +0 -20
  630. package/core/server/services/gift-links/models.ts +0 -22
  631. package/core/server/services/gift-links/schema.ts +0 -33
  632. package/core/server/services/gift-links/serializers.ts +0 -20
  633. package/core/server/services/gift-links/service.ts +0 -95
  634. package/core/server/services/gifts/constants.ts +0 -3
  635. package/core/server/services/gifts/email-templates/gift-purchase-confirmation.ts +0 -43
  636. package/core/server/services/gifts/email-templates/gift-reminder.ts +0 -50
  637. package/core/server/services/gifts/gift-bookshelf-repository.ts +0 -366
  638. package/core/server/services/gifts/gift-checkout-offer.ts +0 -127
  639. package/core/server/services/gifts/gift-codec.ts +0 -62
  640. package/core/server/services/gifts/gift-controller.ts +0 -51
  641. package/core/server/services/gifts/gift-email-renderer.ts +0 -97
  642. package/core/server/services/gifts/gift-email-service.ts +0 -158
  643. package/core/server/services/gifts/gift-reminder-scheduler.ts +0 -107
  644. package/core/server/services/gifts/gift-schema.ts +0 -39
  645. package/core/server/services/gifts/gift-service-wrapper.js +0 -142
  646. package/core/server/services/gifts/gift-service.ts +0 -1034
  647. package/core/server/services/gifts/gift.ts +0 -234
  648. package/core/server/services/identity-tokens/identity-token-service.ts +0 -36
  649. package/core/server/services/indexnow-ping/constants.ts +0 -32
  650. package/core/server/services/indexnow-ping/index.ts +0 -35
  651. package/core/server/services/indexnow-ping/indexnow-ping-service.ts +0 -311
  652. package/core/server/services/internal-keys/index.ts +0 -53
  653. package/core/server/services/lib/dynamic-redirect-manager.d.ts +0 -20
  654. package/core/server/services/lib/in-memory-repository.ts +0 -78
  655. package/core/server/services/lib/member-signup-contexts.ts +0 -22
  656. package/core/server/services/link-redirection/link-redirect.ts +0 -24
  657. package/core/server/services/member-welcome-emails/constants.ts +0 -35
  658. package/core/server/services/members/commenting/index.ts +0 -2
  659. package/core/server/services/members/commenting/member-commenting-codec.ts +0 -73
  660. package/core/server/services/members/commenting/member-commenting.ts +0 -69
  661. package/core/server/services/members/create-paid-member-shim.ts +0 -40
  662. package/core/server/services/members/import-export/config.ts +0 -34
  663. package/core/server/services/members/import-export/csv/formula.ts +0 -14
  664. package/core/server/services/members/import-export/csv/index.ts +0 -3
  665. package/core/server/services/members/import-export/csv/parse.ts +0 -69
  666. package/core/server/services/members/import-export/csv/serialize.ts +0 -18
  667. package/core/server/services/members/import-export/export/exporter.ts +0 -325
  668. package/core/server/services/members/import-export/import/completion-email.ts +0 -146
  669. package/core/server/services/members/import-export/import/importer.ts +0 -489
  670. package/core/server/services/members/import-export/import/reader.ts +0 -33
  671. package/core/server/services/members/import-export/import/row.ts +0 -56
  672. package/core/server/services/members/import-export/import/spool.ts +0 -38
  673. package/core/server/services/members/import-export/index.ts +0 -143
  674. package/core/server/services/members/index.d.ts +0 -32
  675. package/core/server/services/members-custom-fields/actions.ts +0 -62
  676. package/core/server/services/members-custom-fields/codec.ts +0 -13
  677. package/core/server/services/members-custom-fields/config.ts +0 -38
  678. package/core/server/services/members-custom-fields/definitions-service.ts +0 -413
  679. package/core/server/services/members-custom-fields/index.ts +0 -50
  680. package/core/server/services/members-custom-fields/models.ts +0 -15
  681. package/core/server/services/members-custom-fields/queries.ts +0 -13
  682. package/core/server/services/members-custom-fields/schema.ts +0 -71
  683. package/core/server/services/members-custom-fields/serializers.ts +0 -22
  684. package/core/server/services/members-custom-fields/storage.ts +0 -122
  685. package/core/server/services/members-custom-fields/values-service.ts +0 -269
  686. package/core/server/services/notifications/notification-email.ts +0 -66
  687. package/core/server/services/notifications/sanitize-email-html.ts +0 -35
  688. package/core/server/services/post-scheduling/index.ts +0 -13
  689. package/core/server/services/post-scheduling/post-scheduling.ts +0 -133
  690. package/core/server/services/recommendations/service/bookshelf-click-event-repository.ts +0 -49
  691. package/core/server/services/recommendations/service/bookshelf-recommendation-repository.ts +0 -117
  692. package/core/server/services/recommendations/service/bookshelf-repository.ts +0 -192
  693. package/core/server/services/recommendations/service/bookshelf-subscribe-event-repository.ts +0 -49
  694. package/core/server/services/recommendations/service/click-event.ts +0 -32
  695. package/core/server/services/recommendations/service/in-memory-recommendation-repository.ts +0 -20
  696. package/core/server/services/recommendations/service/incoming-recommendation-controller.ts +0 -51
  697. package/core/server/services/recommendations/service/incoming-recommendation-email-renderer.ts +0 -37
  698. package/core/server/services/recommendations/service/incoming-recommendation-service.ts +0 -159
  699. package/core/server/services/recommendations/service/index.ts +0 -15
  700. package/core/server/services/recommendations/service/libraries.d.ts +0 -2
  701. package/core/server/services/recommendations/service/recommendation-controller.ts +0 -257
  702. package/core/server/services/recommendations/service/recommendation-metadata-service.ts +0 -132
  703. package/core/server/services/recommendations/service/recommendation-repository.ts +0 -13
  704. package/core/server/services/recommendations/service/recommendation-service.ts +0 -285
  705. package/core/server/services/recommendations/service/recommendation.ts +0 -200
  706. package/core/server/services/recommendations/service/subscribe-event.ts +0 -32
  707. package/core/server/services/recommendations/service/unsafe-data.ts +0 -217
  708. package/core/server/services/recommendations/service/well-known-service.ts +0 -47
  709. package/core/server/services/remote-flags/index.ts +0 -101
  710. package/core/server/services/remote-flags/remote-flags-service.ts +0 -236
  711. package/core/server/services/remote-flags/resolve.ts +0 -108
  712. package/core/server/services/route-settings/route-settings-parser.ts +0 -455
  713. package/core/server/services/route-settings/validation-errors.ts +0 -271
  714. package/core/server/services/route-settings/yaml-parser.d.ts +0 -4
  715. package/core/server/services/slack-ping/constants.ts +0 -15
  716. package/core/server/services/slack-ping/index.ts +0 -35
  717. package/core/server/services/slack-ping/slack-ping-service.ts +0 -295
  718. package/core/server/services/staff/email-templates/donation.txt.ts +0 -26
  719. package/core/server/services/staff/email-templates/gift.txt.ts +0 -27
  720. package/core/server/services/staff/email-templates/new-free-signup.txt.ts +0 -15
  721. package/core/server/services/staff/email-templates/new-gift-subscription.txt.ts +0 -26
  722. package/core/server/services/staff/email-templates/new-milestone-received.txt.ts +0 -20
  723. package/core/server/services/staff/email-templates/new-paid-cancellation.txt.ts +0 -15
  724. package/core/server/services/staff/email-templates/new-paid-started.txt.ts +0 -15
  725. package/core/server/services/staff/email-templates/recommendation-received.txt.ts +0 -23
  726. package/core/server/services/staff/email-templates/types.ts +0 -13
  727. package/core/server/services/url/lazy-find-resource.ts +0 -104
  728. package/core/server/services/url/lazy-url-service.ts +0 -647
  729. package/core/server/services/url/permalink-matcher.ts +0 -119
  730. package/core/server/services/url/router-filter.ts +0 -80
  731. package/core/server/services/verification/verification-webhook-service.ts +0 -137
  732. package/core/shared/config/helpers.ts +0 -133
  733. package/core/shared/config/index.ts +0 -12
  734. package/core/shared/config/loader.ts +0 -87
  735. package/core/shared/config/utils.ts +0 -104
  736. package/core/shared/errify.ts +0 -31
  737. package/core/shared/events-ts/index.ts +0 -8
  738. package/core/shared/events-ts/post-deleted-event.ts +0 -15
  739. package/core/shared/events-ts/posts-bulk-add-tags-event.ts +0 -13
  740. package/core/shared/events-ts/posts-bulk-destroyed-event.ts +0 -13
  741. package/core/shared/events-ts/posts-bulk-featured-event.ts +0 -13
  742. package/core/shared/events-ts/posts-bulk-unfeatured-event.ts +0 -13
  743. package/core/shared/events-ts/posts-bulk-unpublished-event.ts +0 -13
  744. package/core/shared/events-ts/posts-bulk-unscheduled-event.ts +0 -13
  745. package/core/shared/labs-flag-overrides.ts +0 -35
  746. package/core/shared/one-at-a-time.ts +0 -47
  747. package/core/shared/url-utils.ts +0 -20
@@ -1,325 +0,0 @@
1
- import moment from 'moment';
2
- import {Transform, pipeline, type Readable} from 'node:stream';
3
- import type {Knex} from 'knex';
4
-
5
- const logging = require('@tryghost/logging');
6
- const errors = require('@tryghost/errors');
7
- const {csvCellsForFields} = require('@tryghost/custom-field-types/csv');
8
-
9
- // Options accepted by the export, forwarded to the members query for filtering.
10
- export interface ExportOptions {
11
- limit?: number | 'all';
12
- filter?: string;
13
- search?: string;
14
- [option: string]: unknown;
15
- }
16
-
17
- // A custom field definition, opaque to the exporter: it only counts the set and hands
18
- // it to the values codec, which decides the columns. Named for intent; its shape is
19
- // the custom fields service's concern, not this one's.
20
- export type CustomFieldDefinition = Record<string, unknown>;
21
-
22
- // The custom fields collaborator: the active column set for this export, and the
23
- // per-member values that fill those columns. Both resolve empty when the feature is
24
- // off, so the exporter carries no flag of its own.
25
- export interface CustomFieldsService {
26
- activeDefinitions(): Promise<CustomFieldDefinition[]>;
27
- valuesForMembers(memberIds: string[]): Promise<Map<string, Record<string, unknown>>>;
28
- }
29
-
30
- // The members aggregate, narrowed to the one read the export makes: the ids matching
31
- // a filter, resolved without any of the related data the stream fetches itself.
32
- export interface MembersRepository {
33
- findFilteredIds(options: ExportOptions): Promise<string[]>;
34
- }
35
-
36
- export interface ExporterDeps {
37
- knex: Knex;
38
- members: MembersRepository;
39
- customFields: CustomFieldsService;
40
- }
41
-
42
- interface BatchRelatedData {
43
- tiersMap: Map<string, string>;
44
- labelsMap: Map<string, string>;
45
- stripeCustomerMap: Map<string, string>;
46
- subscribedSet: Set<string>;
47
- giftIdMap: Map<string, string>;
48
- customFieldValuesMap: Map<string, Record<string, unknown>>;
49
- }
50
-
51
- // The reference data read once up front and shared across every batch.
52
- interface ReferenceData {
53
- allProducts: Record<string, string>;
54
- allLabels: Record<string, string>;
55
- activeCustomFields: CustomFieldDefinition[];
56
- }
57
-
58
- // A member row as the export query selects it -- the shape the stream emits, and the
59
- // contract flattenBatch is total over. Its value types are declared here (knex streams
60
- // rows untyped); a change to the members table that this export should carry is made by
61
- // changing this type, which then ripples into flattenBatch until every field is handled.
62
- // The end-to-end e2e export test is what catches the table drifting from this shape.
63
- interface MemberDbRow {
64
- id: string;
65
- email: string;
66
- name: string | null;
67
- note: string | null;
68
- status: string;
69
- created_at: Date | string;
70
- }
71
-
72
- // The columns the export reads off the members table, checked against MemberDbRow so the
73
- // query cannot select a column the row type does not declare.
74
- const MEMBER_COLUMNS = ['id', 'email', 'name', 'note', 'status', 'created_at'] satisfies Array<keyof MemberDbRow>;
75
-
76
- // The db row with its related data resolved onto it. custom_field_cells later spreads
77
- // into one column per active custom field.
78
- interface MemberExportRow extends MemberDbRow {
79
- created_at: string;
80
- tiers: Array<{name: string}>;
81
- labels: Array<{name: string}>;
82
- subscribed: boolean;
83
- comped: boolean;
84
- gift_id: string | null;
85
- stripe_customer_id: string | null;
86
- custom_field_cells: Record<string, unknown>;
87
- }
88
-
89
- // One row of the members export CSV: a flattened export row encoded into cells. This
90
- // type is the export's column contract -- the output serializer takes the columns from
91
- // these keys. The fixed member columns are typed; custom_field_cells spreads in whatever
92
- // per-site columns the database holds, so the row also carries an open string index.
93
- type ExportCsvRow = {
94
- id: string;
95
- email: string;
96
- name: string | null;
97
- note: string | null;
98
- subscribed_to_emails: string;
99
- complimentary_plan: string;
100
- stripe_customer_id: string | null;
101
- created_at: string;
102
- deleted_at: null;
103
- labels: string;
104
- tiers: string;
105
- gift_id: string;
106
- } & Record<string, unknown>;
107
-
108
- function namesToCsv(items: Array<{name: string}>): string {
109
- return items.map(item => item.name).join(',');
110
- }
111
-
112
- // Encode a flattened export row into its CSV cells, type-checked against MemberExportRow:
113
- // a change to that row must be handled here or this stops compiling. deleted_at is always
114
- // null -- the export reads live members -- and complimentary_plan is written from comped.
115
- export function toExportCsvRow(row: MemberExportRow): ExportCsvRow {
116
- return {
117
- id: row.id,
118
- email: row.email,
119
- name: row.name,
120
- note: row.note,
121
- subscribed_to_emails: row.subscribed === true ? 'true' : 'false',
122
- complimentary_plan: row.comped === true ? 'true' : '',
123
- stripe_customer_id: row.stripe_customer_id,
124
- created_at: row.created_at,
125
- deleted_at: null,
126
- labels: namesToCsv(row.labels),
127
- tiers: namesToCsv(row.tiers),
128
- gift_id: row.gift_id || '',
129
- ...row.custom_field_cells
130
- };
131
- }
132
-
133
- const BATCH_SIZE = 1000;
134
-
135
- // Streams the matching members as flat rows, each carrying its related data (tiers,
136
- // labels, subscription, gift, Stripe customer, custom fields) for the output serializer
137
- // to turn into CSV lines. The members aggregate and custom fields are reached only
138
- // through the ports above, so nothing Bookshelf- or flag-shaped leaks into the export.
139
- export default class MembersCSVExporter {
140
- private _knex: Knex;
141
- private _members: MembersRepository;
142
- private _customFields: CustomFieldsService;
143
-
144
- constructor({knex, members, customFields}: ExporterDeps) {
145
- this._knex = knex;
146
- this._members = members;
147
- this._customFields = customFields;
148
- }
149
-
150
- async export(options: ExportOptions = {}): Promise<Readable> {
151
- const start = Date.now();
152
- const hasFilter = options.limit !== 'all' || options.filter || options.search;
153
- const ids = hasFilter ? await this._members.findFilteredIds(options) : null;
154
- if (ids) {
155
- logging.info(`[MembersExporter] Found ${ids.length} members matching filter criteria`);
156
- }
157
-
158
- const reference = await this.fetchReferenceData();
159
-
160
- const membersQuery = this._knex('members').select(...MEMBER_COLUMNS);
161
- if (ids) {
162
- membersQuery.whereIn('id', ids);
163
- }
164
-
165
- logging.info('[MembersExporter] Starting streaming export of members');
166
- const batchingTransform = this.createBatchingTransform();
167
- const processingTransform = this.createProcessingTransform(reference);
168
-
169
- pipeline(membersQuery.stream(), batchingTransform, processingTransform, (err) => {
170
- if (err) {
171
- logging.error({event: {name: 'members-export.stream.error'}, err}, 'Members export stream failed');
172
- } else {
173
- logging.info('[MembersExporter] Total time taken for member export: ' + (Date.now() - start) / 1000 + 's');
174
- }
175
- });
176
-
177
- return processingTransform;
178
- }
179
-
180
- // products and labels are small, stable tables, read once up front as id->name
181
- // maps. Custom field definitions are read once too, which fixes the column set for
182
- // the whole file: archiving a field mid-export cannot leave the header ragged. It
183
- // can still leave that field's cells empty from the batch after the archive
184
- // onwards, because the per-batch value read applies its own active filter.
185
- private async fetchReferenceData(): Promise<ReferenceData> {
186
- const start = Date.now();
187
-
188
- const allProducts = await this._knex('products').select('id', 'name').then(rows => rows.reduce((acc: Record<string, string>, product: {id: string; name: string}) => {
189
- acc[product.id] = product.name;
190
- return acc;
191
- }, {}));
192
-
193
- const allLabels = await this._knex('labels').select('id', 'name').then(rows => rows.reduce((acc: Record<string, string>, label: {id: string; name: string}) => {
194
- acc[label.id] = label.name;
195
- return acc;
196
- }, {}));
197
-
198
- logging.info('[MembersExporter] Fetched products and labels in ' + (Date.now() - start) + 'ms');
199
-
200
- const activeCustomFields = await this._customFields.activeDefinitions();
201
-
202
- return {allProducts, allLabels, activeCustomFields};
203
- }
204
-
205
- // Group the member stream into batches so the related-data reads are one query per
206
- // batch rather than one per member.
207
- private createBatchingTransform(): Transform {
208
- let currentBatch: MemberDbRow[] = [];
209
-
210
- return new Transform({
211
- objectMode: true,
212
- transform(member: MemberDbRow, encoding, callback) {
213
- currentBatch.push(member);
214
-
215
- if (currentBatch.length >= BATCH_SIZE) {
216
- this.push(currentBatch);
217
- currentBatch = [];
218
- }
219
-
220
- callback();
221
- },
222
- flush(callback) {
223
- if (currentBatch.length > 0) {
224
- this.push(currentBatch);
225
- }
226
- callback();
227
- }
228
- });
229
- }
230
-
231
- // Each flattened row is pushed individually so a batch's rows do not pile up in memory.
232
- private createProcessingTransform(reference: ReferenceData): Transform {
233
- const assembleRelatedData = (memberIds: string[]) => this.assembleRelatedData(memberIds, reference.activeCustomFields);
234
- const flattenBatch = (members: MemberDbRow[], related: BatchRelatedData) => this.flattenBatch(members, related, reference);
235
-
236
- return new Transform({
237
- objectMode: true,
238
- highWaterMark: BATCH_SIZE,
239
- async transform(batch: MemberDbRow[], encoding, callback) {
240
- try {
241
- const memberIds = batch.map(member => member.id);
242
- const related = await assembleRelatedData(memberIds);
243
- const rows = flattenBatch(batch, related);
244
- rows.forEach(row => this.push(row));
245
- callback();
246
- } catch (err) {
247
- callback(err instanceof Error ? err : new errors.InternalServerError({message: String(err)}));
248
- }
249
- }
250
- });
251
- }
252
-
253
- // One query per related table for the whole batch, not one per member. Custom field
254
- // values are read only when there are columns to fill.
255
- private async assembleRelatedData(memberIds: string[], activeCustomFields: CustomFieldDefinition[]): Promise<BatchRelatedData> {
256
- const knex = this._knex;
257
-
258
- const [tiers, labels, stripeCustomers, subscriptions, gifts, customFieldValuesMap] = await Promise.all([
259
- knex('members_products')
260
- .select('member_id', knex.raw('GROUP_CONCAT(product_id) as tiers'))
261
- .whereIn('member_id', memberIds)
262
- .groupBy('member_id'),
263
-
264
- knex('members_labels')
265
- .select('member_id', knex.raw('GROUP_CONCAT(label_id) as labels'))
266
- .whereIn('member_id', memberIds)
267
- .groupBy('member_id'),
268
-
269
- knex('members_stripe_customers')
270
- .select('member_id', knex.raw('MIN(customer_id) as stripe_customer_id'))
271
- .whereIn('member_id', memberIds)
272
- .groupBy('member_id'),
273
-
274
- knex('members_newsletters')
275
- .distinct('member_id')
276
- .whereIn('member_id', memberIds),
277
-
278
- knex('gifts')
279
- .select('id', 'redeemer_member_id')
280
- .where('status', 'redeemed')
281
- .whereIn('redeemer_member_id', memberIds),
282
-
283
- activeCustomFields.length > 0
284
- ? this._customFields.valuesForMembers(memberIds)
285
- : new Map<string, Record<string, unknown>>()
286
- ]);
287
-
288
- return {
289
- tiersMap: new Map(tiers.map((row: {member_id: string; tiers: string}) => [row.member_id, row.tiers])),
290
- labelsMap: new Map(labels.map((row: {member_id: string; labels: string}) => [row.member_id, row.labels])),
291
- stripeCustomerMap: new Map(stripeCustomers.map((row: {member_id: string; stripe_customer_id: string}) => [row.member_id, row.stripe_customer_id])),
292
- subscribedSet: new Set(subscriptions.map((row: {member_id: string}) => row.member_id)),
293
- giftIdMap: new Map(gifts.map((row: {id: string; redeemer_member_id: string}) => [row.redeemer_member_id, row.id])),
294
- customFieldValuesMap
295
- };
296
- }
297
-
298
- private flattenBatch(members: MemberDbRow[], related: BatchRelatedData, reference: ReferenceData): MemberExportRow[] {
299
- const {tiersMap, labelsMap, stripeCustomerMap, subscribedSet, giftIdMap, customFieldValuesMap} = related;
300
- const {allProducts, allLabels, activeCustomFields} = reference;
301
-
302
- return members.map((row) => {
303
- const tierConcat = tiersMap.get(row.id);
304
- const tierIds = tierConcat ? tierConcat.split(',') : [];
305
- const labelConcat = labelsMap.get(row.id);
306
- const labelIds = labelConcat ? labelConcat.split(',') : [];
307
-
308
- return {
309
- ...row,
310
- subscribed: subscribedSet.has(row.id),
311
- comped: row.status === 'comped',
312
- gift_id: giftIdMap.get(row.id) || null,
313
- stripe_customer_id: stripeCustomerMap.get(row.id) || null,
314
- created_at: moment(row.created_at).toISOString(),
315
- tiers: tierIds.map(id => ({name: allProducts[id]})),
316
- labels: labelIds.map(id => ({name: allLabels[id]})),
317
- // Flattened here rather than in the serializer because the column set is
318
- // only knowable from the database. Every member carries a cell for every
319
- // active field's column, so a member with no values still contributes the
320
- // full set -- the CSV header is taken from whichever row streams first.
321
- custom_field_cells: csvCellsForFields(activeCustomFields, customFieldValuesMap.get(row.id) || {})
322
- };
323
- });
324
- }
325
- }
@@ -1,146 +0,0 @@
1
- import {serialize} from '../csv';
2
- import {isCustomFieldColumn} from '@tryghost/custom-field-types/csv';
3
- import type {MemberImportRow, ImportErrorRow, ImportLabel, Label} from './row';
4
-
5
- const emailTemplate = require('./email-template');
6
-
7
- // The finished import as the email reads it: how many imported and which rows
8
- // failed. Structural, so the importer's richer result satisfies it directly.
9
- interface ImportSummary {
10
- imported: number;
11
- errors: ImportErrorRow[];
12
- }
13
-
14
- interface CompletionEmailInput {
15
- result: ImportSummary;
16
- recipient: string;
17
- labelName: string;
18
- importLabel: ImportLabel | null;
19
- urlFor: (type: string, data: unknown, absolute: boolean) => string;
20
- }
21
-
22
- interface EmailPayload {
23
- to: string;
24
- subject: string;
25
- html: string;
26
- forceTextContent: boolean;
27
- attachments: Array<{
28
- filename: string;
29
- content: string;
30
- contentType: string;
31
- contentDisposition: string;
32
- }>;
33
- }
34
-
35
- // Turn an ORM validation error into copy a member manager can act on. Presentation
36
- // only: the API response keeps the raw messages, and just the emailed report is
37
- // rewritten. Takes one reason at a time, so a rewrite matching to the end of its input
38
- // cannot consume the reason after it.
39
- function humaniseReason(message: string): string {
40
- return message
41
- .replace('Value in [members.email] cannot be blank.', 'Missing email address')
42
- .replace('Value in [members.note] exceeds maximum length of 2000 characters.', '"Note" exceeds maximum length of 2000 characters')
43
- .replace('Value in [members.subscribed] must be one of true, false, 0 or 1.', 'Value in "Subscribed to emails" must be "true" or "false"')
44
- .replace('Validation (isEmail) failed for email', 'Invalid email address')
45
- .replace(/No such customer:[\s\S]*/, 'Could not find Stripe customer');
46
- }
47
-
48
- function humaniseError(row: ImportErrorRow): string {
49
- return row.errors.map(humaniseReason).join('\n');
50
- }
51
-
52
- // One row of the fixed, member-vocabulary part of the error report, in emit order.
53
- // papaparse takes the fixed columns from these keys, so the report cannot drift from the
54
- // shaper -- a new member column must be added here or the shaper stops compiling. tiers
55
- // and deleted_at are export-vocabulary columns an import never fills; kept always-empty
56
- // so the report matches the members export CSV. Any custom_fields.* columns a submitted
57
- // row carried are dynamic, so they are threaded in separately by buildErrorReport.
58
- type ErrorReportRow = {
59
- id: MemberImportRow['id'];
60
- email: MemberImportRow['email'];
61
- name: MemberImportRow['name'];
62
- note: MemberImportRow['note'];
63
- subscribed_to_emails: MemberImportRow['subscribed'];
64
- complimentary_plan: MemberImportRow['complimentary_plan'];
65
- stripe_customer_id: MemberImportRow['stripe_customer_id'];
66
- created_at: MemberImportRow['created_at'];
67
- deleted_at: undefined;
68
- labels: string;
69
- tiers: '';
70
- gift_id: string | null;
71
- error: string;
72
- };
73
-
74
- function stringifyLabels(labels: Array<string | Label>): string {
75
- return labels.map(label => (typeof label === 'string' ? label : label.name)).join(',');
76
- }
77
-
78
- // The custom_fields.* cells a submitted row carried, echoed untouched so a manager can
79
- // fix a failed row and re-upload the values they mapped.
80
- function customFieldCells(row: ImportErrorRow): Record<string, unknown> {
81
- return Object.fromEntries(Object.entries(row).filter(([column]) => isCustomFieldColumn(column)));
82
- }
83
-
84
- // Shape a failed import row into its fixed error-report cells, with the raw ORM message
85
- // rewritten into copy the member manager can act on. Custom field cells are merged on by
86
- // buildErrorReport, which owns the dynamic column set.
87
- function toErrorReportRow(row: ImportErrorRow): ErrorReportRow {
88
- return {
89
- id: row.id,
90
- email: row.email,
91
- name: row.name,
92
- note: row.note,
93
- subscribed_to_emails: row.subscribed,
94
- complimentary_plan: row.complimentary_plan,
95
- stripe_customer_id: row.stripe_customer_id,
96
- created_at: row.created_at,
97
- deleted_at: undefined,
98
- labels: stringifyLabels(row.labels),
99
- tiers: '',
100
- gift_id: row.gift_id || null,
101
- error: humaniseError(row)
102
- };
103
- }
104
-
105
- // The error report attached to the completion email: the failed rows as CSV. It shares
106
- // the serialiser with the export but not the shaping -- the export writes db members,
107
- // this echoes submitted rows. Member columns come from the shaper's keys (so the type
108
- // stays the single source); the custom_fields.* columns across the rows are threaded in
109
- // before the last error column, and each row's custom cells merged on.
110
- function buildErrorReport(errors: ImportErrorRow[]): string {
111
- if (errors.length === 0) {
112
- return serialize([]);
113
- }
114
- const memberColumns = Object.keys(toErrorReportRow(errors[0])).filter(column => column !== 'error');
115
- const customColumns = [...new Set(errors.flatMap(row => Object.keys(customFieldCells(row))))];
116
- const columns = [...memberColumns, ...customColumns, 'error'];
117
- const rows = errors.map(row => ({...toErrorReportRow(row), ...customFieldCells(row)}));
118
- return serialize(rows, {columns});
119
- }
120
-
121
- // Compose the completion email for a finished import: the summary and its links,
122
- // plus the attached error report. Owns how the outcome is presented, so the
123
- // importer yields only the result and never touches email or CSV formatting.
124
- export default function buildCompletionEmail({result, recipient, labelName, importLabel, urlFor}: CompletionEmailInput): EmailPayload {
125
- const siteUrl = new URL(urlFor('home', null, true));
126
- const membersUrl = new URL('members', urlFor('admin', null, true));
127
- if (importLabel) {
128
- membersUrl.searchParams.set('label', importLabel.slug);
129
- }
130
-
131
- const html = emailTemplate({result, siteUrl, membersUrl, emailRecipient: recipient, importLabel});
132
- const subject = result.imported > 0 ? 'Your member import is complete' : 'Your member import was unsuccessful';
133
-
134
- return {
135
- to: recipient,
136
- subject,
137
- html,
138
- forceTextContent: true,
139
- attachments: [{
140
- filename: `${labelName} - Errors.csv`,
141
- content: buildErrorReport(result.errors),
142
- contentType: 'text/csv',
143
- contentDisposition: 'attachment'
144
- }]
145
- };
146
- }