ghost 6.60.0 → 6.61.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 (399) hide show
  1. package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
  2. package/components/tryghost-adapter-base-sso-0.1.3.tgz +0 -0
  3. package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
  4. package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
  5. package/core/boot.js +13 -4
  6. package/core/built/admin/assets/{Combination-gnJO3vIw.js → Combination-5fYEzgbs.js} +1 -1
  7. package/core/built/admin/assets/{PolarAngleAxis-C4qtHy1B.js → PolarAngleAxis-pkMyqz8g.js} +1 -1
  8. package/core/built/admin/assets/{RadialBarChart-Bh09Stsj.js → RadialBarChart-JAKoS4KT.js} +1 -1
  9. package/core/built/admin/assets/{about-BgpmhCuM.js → about-Bve7IJS2.js} +1 -1
  10. package/core/built/admin/assets/{account-migration-8qTEI1i1.js → account-migration-DRhAehfw.js} +1 -1
  11. package/core/built/admin/assets/{action-list-lGzZLHc8.js → action-list-C4v0-du8.js} +1 -1
  12. package/core/built/admin/assets/activitypub/{account-migration-DMHuPnJn.js → account-migration-C-aej4x_.js} +7 -7
  13. package/core/built/admin/assets/activitypub/activitypub.js +3 -4
  14. package/core/built/admin/assets/activitypub/{avatar-DhTo5D1B.js → avatar-DLPL3Abs.js} +59 -68
  15. package/core/built/admin/assets/activitypub/{avatar-flipboard-DnVgbEfa.js → avatar-flipboard-C9iDY-QV.js} +2 -2
  16. package/core/built/admin/assets/activitypub/{bluesky-sharing-BT4zAlW7.js → bluesky-sharing-BXkA5mqV.js} +8 -8
  17. package/core/built/admin/assets/activitypub/{content-formatters-BeDZ-DIa.js → content-formatters-CHcyMFk4.js} +17 -17
  18. package/core/built/admin/assets/activitypub/{copy-8sqxUuNd.js → copy-DIAOQoCZ.js} +2 -2
  19. package/core/built/admin/assets/activitypub/{domain-xQDDu1CS.js → domain-B3ihkPde.js} +8 -8
  20. package/core/built/admin/assets/activitypub/{edit-profile-BXdF_r2G.js → edit-profile-DsZM3rTX.js} +5 -5
  21. package/core/built/admin/assets/activitypub/{explore-CMt7gKlL.js → explore-BodNrZgR.js} +8 -8
  22. package/core/built/admin/assets/activitypub/{feed-Bwqdddp_.js → feed-PwH1iJ84.js} +9 -9
  23. package/core/built/admin/assets/activitypub/{field-4co_8FVg.js → field-D06-kmOJ.js} +3 -3
  24. package/core/built/admin/assets/activitypub/{hash-DwakMs4X.js → hash-Bm3WxYN4.js} +2 -2
  25. package/core/built/admin/assets/activitypub/{inbox-DQ5CwLma.js → inbox-BluD2ucT.js} +16 -16
  26. package/core/built/admin/assets/activitypub/{inbox-ckD4wo_r.js → inbox-d8oJRTf4.js} +2 -2
  27. package/core/built/admin/assets/activitypub/{label-B72sfvEU.js → label-FHSh6ZAw.js} +3 -3
  28. package/core/built/admin/assets/activitypub/layout-Cq4NG0Xr.js +1 -0
  29. package/core/built/admin/assets/activitypub/{moderation-KCCO7L2J.js → moderation-D1Yapsod.js} +9 -9
  30. package/core/built/admin/assets/activitypub/{note-BX_Bz5A0.js → note-C5zjqq5C.js} +8 -8
  31. package/core/built/admin/assets/activitypub/{notifications-BQOYGvRv.js → notifications-B9p8eCHD.js} +9 -9
  32. package/core/built/admin/assets/activitypub/{preferences-6h43G9_q.js → preferences-BCqUdC3v.js} +9 -9
  33. package/core/built/admin/assets/activitypub/{profile-BMN9VVZ2.js → profile-BRCWoFem.js} +178 -178
  34. package/core/built/admin/assets/activitypub/{reply-ZNo04xsO.js → reply-DYK5vVqb.js} +2 -2
  35. package/core/built/admin/assets/activitypub/{routes-3B9mUQ7i.js → routes-BSXT992i.js} +81 -84
  36. package/core/built/admin/assets/activitypub/{separator-D9taVCCa.js → separator-BbQqTm-p.js} +3 -3
  37. package/core/built/admin/assets/activitypub/{settings-71gCm3SO.js → settings-DQDkr06X.js} +6 -6
  38. package/core/built/admin/assets/activitypub/{step-1-BsGGnBuT.js → step-1-B-YfsVeO.js} +5 -5
  39. package/core/built/admin/assets/activitypub/{step-2-teosIS0k.js → step-2-DtPQzlTH.js} +6 -6
  40. package/core/built/admin/assets/activitypub/{step-3-BjD5TokC.js → step-3-D6BFMXL_.js} +10 -10
  41. package/core/built/admin/assets/activitypub/{tabs-Cvwl1wXU.js → tabs-GpNecvfB.js} +6 -6
  42. package/core/built/admin/assets/activitypub/{topic-filter-C3LZJc2X.js → topic-filter-BPDeQQys.js} +3 -3
  43. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-Dp9f0gov.js → use-activity-pub-queries-BoVOxXkV.js} +2 -2
  44. package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-C4RI0sa9.js → use-navigate-with-base-path-Bmk5h4lW.js} +220 -220
  45. package/core/built/admin/assets/activitypub/{use-reply-chain-data-C2oNDMUH.js → use-reply-chain-data-wVBX7swM.js} +5 -5
  46. package/core/built/admin/assets/activitypub/{x-Dxm6pV9X.js → x-DbQZOLiI.js} +2 -2
  47. package/core/built/admin/assets/{add-integration-modal--YpTq3c0.js → add-integration-modal-BC0jExDZ.js} +1 -1
  48. package/core/built/admin/assets/{add-newsletter-modal-C8Ix2hol.js → add-newsletter-modal-DchTkA7l.js} +1 -1
  49. package/core/built/admin/assets/{add-recommendation-modal-CScuNFz4.js → add-recommendation-modal-DMvaJZKp.js} +1 -1
  50. package/core/built/admin/assets/alert-dialog-QhXzdHfc.js +1 -0
  51. package/core/built/admin/assets/{analytics-Cnji45H5.js → analytics-No1DDY3A.js} +1 -1
  52. package/core/built/admin/assets/{announcement-bar-modal-BTHiy1ZO.js → announcement-bar-modal-DM3cYOpo.js} +1 -1
  53. package/core/built/admin/assets/{api-keys-Boy5pLbD.js → api-keys-BLm2NDBh.js} +1 -1
  54. package/core/built/admin/assets/audience-9mwU5TW6.js +1 -0
  55. package/core/built/admin/assets/{automations-BWpRCZ_f.js → automations-DpUNUdcZ.js} +1 -1
  56. package/core/built/admin/assets/{bluesky-sharing-DHOpQxff.js → bluesky-sharing-Cjrv_f62.js} +1 -1
  57. package/core/built/admin/assets/{box-By_EgGtm.js → box-CdfQAP_F.js} +1 -1
  58. package/core/built/admin/assets/{brand-icon-09YqFZjV.js → brand-icon-CrIGOA3Z.js} +1 -1
  59. package/core/built/admin/assets/{breadcrumb-CcFr_ltt.js → breadcrumb-DLiqCyFc.js} +1 -1
  60. package/core/built/admin/assets/{button-BshWPHvn.js → button-B2jcu6bk.js} +1 -1
  61. package/core/built/admin/assets/{card-CiiE7QfM.js → card--VNbfgo3.js} +1 -1
  62. package/core/built/admin/assets/{chart-BnXyfH11.js → chart-BrhA41Zi.js} +1 -1
  63. package/core/built/admin/assets/chart-helpers-Fo3bUL3K.js +1 -0
  64. package/core/built/admin/assets/{checkbox-Dwwr_3Py.js → checkbox-BfKktMph.js} +1 -1
  65. package/core/built/admin/assets/{chunk.524.91ecb33e6afc3bd8949b.js → chunk.524.60ca4692d91c6022042f.js} +4 -4
  66. package/core/built/admin/assets/{chunk.582.512549909741883f960c.js → chunk.582.525c7617c2d9e94c940a.js} +6 -6
  67. package/core/built/admin/assets/{chunk.16.f76a6314082d813d67e0.js → chunk.896.435fe0637944d4a69810.js} +3 -3
  68. package/core/built/admin/assets/{code-editor-view-BwIdPy_k.js → code-editor-view-CYVu4EW6.js} +1 -1
  69. package/core/built/admin/assets/{code-editor-view-CtkF82Fv.js → code-editor-view-DCQJxsfU.js} +1 -1
  70. package/core/built/admin/assets/{color-picker-Bmo1r9Fc.js → color-picker-BTY_NdEm.js} +1 -1
  71. package/core/built/admin/assets/{color-picker-field-DywowPhF.js → color-picker-field-CPlkzOH0.js} +1 -1
  72. package/core/built/admin/assets/{combobox-C4QCh6Yw.js → combobox-DrMtv_4P.js} +1 -1
  73. package/core/built/admin/assets/command-ZdgYJpoI.js +1 -0
  74. package/core/built/admin/assets/comments-kidj60-h.js +1 -0
  75. package/core/built/admin/assets/{confirmation-context-CLFHhyyH.js → confirmation-context-BhbmQQEl.js} +1 -1
  76. package/core/built/admin/assets/{container-LiZf3XdY.js → container-BuQG1wuP.js} +1 -1
  77. package/core/built/admin/assets/{content-api-modal-BtpNI92-.js → content-api-modal-CyQEC3fr.js} +1 -1
  78. package/core/built/admin/assets/{copy-field-CglgRZyG.js → copy-field-B3M1s78L.js} +1 -1
  79. package/core/built/admin/assets/{custom-field-type-option-D0PXoSnP.js → custom-field-type-option-CsGIZk1J.js} +1 -1
  80. package/core/built/admin/assets/{custom-integration-modal-DCIHKN33.js → custom-integration-modal-BY37O_9X.js} +1 -1
  81. package/core/built/admin/assets/{data-list-CupF7bjM.js → data-list-CA2jYGPq.js} +1 -1
  82. package/core/built/admin/assets/{date-range-select-JPwM0yUj.js → date-range-select-DD2RKkgB.js} +1 -1
  83. package/core/built/admin/assets/design-and-theme-modal-DUSKM4uC.js +22 -0
  84. package/core/built/admin/assets/{detail-page-D8lx2SdP.js → detail-page-Dnv-CdR1.js} +1 -1
  85. package/core/built/admin/assets/dialog-B44iRwlc.js +1 -0
  86. package/core/built/admin/assets/{dirty-confirm-dialog-CmARpZQS.js → dirty-confirm-dialog-BxgQgQ6H.js} +1 -1
  87. package/core/built/admin/assets/{disabled-sources-indicator-BTJ2ClQu.js → disabled-sources-indicator-Cvy47bE2.js} +1 -1
  88. package/core/built/admin/assets/{dist-DzcfoDJ3.js → dist-8YJUlf3B.js} +1 -1
  89. package/core/built/admin/assets/{dist-Cb5RSHSg.js → dist-B3keLvjj.js} +1 -1
  90. package/core/built/admin/assets/{dist-QLZuGq7o2.js → dist-Cy8tfrp_.js} +1 -1
  91. package/core/built/admin/assets/{dist-BT_Z-eCn.js → dist-Dgt2cr6a.js} +1 -1
  92. package/core/built/admin/assets/{domain-D0SAtc-T.js → domain-Ca6KhoQt.js} +1 -1
  93. package/core/built/admin/assets/{dropzone-CaPOeDRZ.js → dropzone-Bb-5zQTk.js} +1 -1
  94. package/core/built/admin/assets/edit-profile-BdupLlus.js +1 -0
  95. package/core/built/admin/assets/{editor-COXn4Atu.js → editor-BP883Lpn.js} +3 -3
  96. package/core/built/admin/assets/{embed-signup-form-modal-BFTPf04i.js → embed-signup-form-modal-DeBMLxlL.js} +1 -1
  97. package/core/built/admin/assets/{empty-indicator-WB1WgT9h.js → empty-indicator-D9QdpuNX.js} +1 -1
  98. package/core/built/admin/assets/{explore-BsNYrubV.js → explore-FB-CimXw.js} +1 -1
  99. package/core/built/admin/assets/{feed-8RR1O1bK.js → feed-C1GxsmI2.js} +1 -1
  100. package/core/built/admin/assets/{field-LmNk7wZh.js → field-Cj8lmDOo.js} +1 -1
  101. package/core/built/admin/assets/{filter-sources-4C0kF1NU.js → filter-sources-D5n5bFA2.js} +1 -1
  102. package/core/built/admin/assets/{filters-CV5jCb9n.js → filters-DJEzkMUK.js} +1 -1
  103. package/core/built/admin/assets/{filters-Dmr0PoqU.js → filters-MZXvdH5D.js} +1 -1
  104. package/core/built/admin/assets/{first-promoter-modal-OCzSaL3B.js → first-promoter-modal-CGTGLCr5.js} +1 -1
  105. package/core/built/admin/assets/{ghost-403cb39badad3df411fc0ba27d220047.js → ghost-3894eedcc6968f658578c0abfe942aab.js} +2 -2
  106. package/core/built/admin/assets/{gift-link-modal-0mzjn5oF.js → gift-link-modal-B6v0tnRN.js} +1 -1
  107. package/core/built/admin/assets/{grid-CUciBfjf.js → grid-Dj29PY05.js} +1 -1
  108. package/core/built/admin/assets/growth-BGAJD1rs.js +3 -0
  109. package/core/built/admin/assets/growth-D6mhcx3q.js +1 -0
  110. package/core/built/admin/assets/{heading-CRZZ2FUe.js → heading-Dh5SFVjL.js} +1 -1
  111. package/core/built/admin/assets/history-modal-iKwUY3XR.js +1 -0
  112. package/core/built/admin/assets/html-field-C8qVGGC1.js +1 -0
  113. package/core/built/admin/assets/{images-C0XvUYMb.js → images-h8VZEQ9k.js} +1 -1
  114. package/core/built/admin/assets/{inbox-DZXDUt4s.js → inbox-BYd1M06Q.js} +13 -13
  115. package/core/built/admin/assets/index-DjQe-e5s.js +4 -0
  116. package/core/built/admin/assets/{index.es-BMUCj9TR.js → index.es-VihPwfeH.js} +1 -1
  117. package/core/built/admin/assets/{inline-Cw-gigDW.js → inline-BWSs_VzR.js} +1 -1
  118. package/core/built/admin/assets/{input-UHrKuvBT.js → input--W-rCTrX.js} +1 -1
  119. package/core/built/admin/assets/{input-group-BPAxETpQ.js → input-group-D8sCXRF5.js} +1 -1
  120. package/core/built/admin/assets/{input-surface-BdOe4KzO.js → input-surface-BsrIZeSF.js} +1 -1
  121. package/core/built/admin/assets/{integration-header-B4DyXV06.js → integration-header-Bm6IDb1A.js} +1 -1
  122. package/core/built/admin/assets/{invite-user-modal-BrAkxEO3.js → invite-user-modal-MdImLCaJ.js} +1 -1
  123. package/core/built/admin/assets/{koenig-lexical-60O_8aiO.js → koenig-lexical-_-IsVI7E.js} +1 -1
  124. package/core/built/admin/assets/koenig-loader-DYZpm6El.js +2 -0
  125. package/core/built/admin/assets/{kpi-card-fUHZlzBX.js → kpi-card-DW_2y3ug.js} +1 -1
  126. package/core/built/admin/assets/kpi-card-DZQk_0W8.js +1 -0
  127. package/core/built/admin/assets/kpi-helpers-PueTKuA6.js +1 -0
  128. package/core/built/admin/assets/kpi-tabs-CojDs-Qz.js +1 -0
  129. package/core/built/admin/assets/{label-VIG969IC.js → label-DjbT91GM.js} +1 -1
  130. package/core/built/admin/assets/{label-picker-BBWykUeA.js → label-picker-cB51xl1r.js} +1 -1
  131. package/core/built/admin/assets/layout-c_B_1hax.js +1 -0
  132. package/core/built/admin/assets/{link-helpers-Dtq9fxQg.js → link-helpers-MVDdnFCY.js} +1 -1
  133. package/core/built/admin/assets/{list-page-CdsnQR9N.js → list-page-BucXJ0hi.js} +1 -1
  134. package/core/built/admin/assets/{loading-indicator-SFTqyYVE.js → loading-indicator-BpFWTVgh.js} +1 -1
  135. package/core/built/admin/assets/{member-custom-fields-gOv6Hoh3.js → member-custom-fields-qs0dIkxM.js} +1 -1
  136. package/core/built/admin/assets/member-detail-B6uec2a6.js +1 -0
  137. package/core/built/admin/assets/members-BQF3CqhI.js +2 -0
  138. package/core/built/admin/assets/{modal-page-BMTzFHVO.js → modal-page-xCivTMvI.js} +1 -1
  139. package/core/built/admin/assets/{moderation-DzzPLDyl.js → moderation-DY4wF1Q3.js} +1 -1
  140. package/core/built/admin/assets/{multi-select-combobox-CGohnsxJ.js → multi-select-combobox-B6LiRzDO.js} +1 -1
  141. package/core/built/admin/assets/navigation-modal-DX-gNF3X.js +1 -0
  142. package/core/built/admin/assets/newsletter-CyQA7m3m.js +1 -0
  143. package/core/built/admin/assets/{newsletter-detail-modal-DQU3r4g2.js → newsletter-detail-modal-BDrptuxn.js} +1 -1
  144. package/core/built/admin/assets/{newsletter-emails-D5ql1rud.js → newsletter-emails-CFeLlt4z.js} +1 -1
  145. package/core/built/admin/assets/newsletters-DXuNmC42.js +1 -0
  146. package/core/built/admin/assets/{note-i8k6pjaw.js → note-Cgo2LCJ6.js} +1 -1
  147. package/core/built/admin/assets/notifications-BC50AMku.js +1 -0
  148. package/core/built/admin/assets/{offers-container-modal-BWfjSdyg.js → offers-container-modal-DWycIMzT.js} +1 -1
  149. package/core/built/admin/assets/{onboarding-route-Cu_ROWPn.js → onboarding-route-Dmc4IPm3.js} +1 -1
  150. package/core/built/admin/assets/overview-CVbFtn-k.js +1 -0
  151. package/core/built/admin/assets/overview-YKj7SZaK.js +1 -0
  152. package/core/built/admin/assets/{page-header-Cfds8pCg.js → page-header-BR_nbIPp.js} +1 -1
  153. package/core/built/admin/assets/{pintura-modal-TDTrJ89x.js → pintura-modal-BR9hEvS8.js} +1 -1
  154. package/core/built/admin/assets/popover-CCy0h5rq.js +1 -0
  155. package/core/built/admin/assets/{portal-frame-DjBF-uy2.js → portal-frame-dc4XKr0e.js} +1 -1
  156. package/core/built/admin/assets/portal-modal-BvvdF_B9.js +1 -0
  157. package/core/built/admin/assets/{post-analytics-Buz1COoY.js → post-analytics-DX470WRG.js} +1 -1
  158. package/core/built/admin/assets/{post-analytics-header-B-P0eFnT.js → post-analytics-header-CXpJmdDv.js} +1 -1
  159. package/core/built/admin/assets/{post-analytics-provider-Cu3jNeFh.js → post-analytics-provider-CLfKGWZy.js} +1 -1
  160. package/core/built/admin/assets/{post-share-modal-P1_M6o-H.js → post-share-modal-Cl0NXRJr.js} +1 -1
  161. package/core/built/admin/assets/{preferences-Cq1aOiLy.js → preferences-DO0UUWFp.js} +2 -2
  162. package/core/built/admin/assets/{preview-chrome-BOVO6_PE.js → preview-chrome-BljUBlOk.js} +1 -1
  163. package/core/built/admin/assets/{preview-modal-MlTjP8UU.js → preview-modal-C-BL-F9k.js} +1 -1
  164. package/core/built/admin/assets/profile-CxT-0l4d.js +1 -0
  165. package/core/built/admin/assets/radio-group-Bgz60i81.js +1 -0
  166. package/core/built/admin/assets/{router-provider-CJC58zTy.js → router-provider-B0gZyiGJ.js} +1 -1
  167. package/core/built/admin/assets/{schemas-CRsC53ls.js → schemas-4UPic-oD.js} +2 -2
  168. package/core/built/admin/assets/select-DuDUFdPq.js +1 -0
  169. package/core/built/admin/assets/{settings-B5hJKZ5C.js → settings-BjCii7BM.js} +1 -1
  170. package/core/built/admin/assets/settings-b8kNzZSQ.js +4 -0
  171. package/core/built/admin/assets/{settings-breadcrumbs-sLDNedBW.js → settings-breadcrumbs-CyP_9zTo.js} +1 -1
  172. package/core/built/admin/assets/{shade-app-F7WxOyfk-nufqw1hd.js → shade-app-CcS3f8MZ-vwURazk8.js} +2 -2
  173. package/core/built/admin/assets/{share-modal-CLBfj377.js → share-modal-BV70mr9k.js} +1 -1
  174. package/core/built/admin/assets/{skeleton-D7hwjdry.js → skeleton-Ce9GgUpf.js} +1 -1
  175. package/core/built/admin/assets/{slack-modal-Bt9I_tEo.js → slack-modal-Be2_KK-z.js} +1 -1
  176. package/core/built/admin/assets/sort-button-Cc-Z96sA.js +1 -0
  177. package/core/built/admin/assets/{source-icon-BPsD5ees.js → source-icon-v6PUnmyM.js} +1 -1
  178. package/core/built/admin/assets/{stack-CIfOAAVf.js → stack-B2eszIiq.js} +1 -1
  179. package/core/built/admin/assets/{stats-B_YkF7bp.js → stats-C4reGh9O.js} +1 -1
  180. package/core/built/admin/assets/{stats-view-BOCp9RG8.js → stats-view-DP9pQ62k.js} +1 -1
  181. package/core/built/admin/assets/{step-1-CMta6YFO.js → step-1-DSRp2vBj.js} +1 -1
  182. package/core/built/admin/assets/{step-2-BG04nh5q.js → step-2-COqv2g0u.js} +1 -1
  183. package/core/built/admin/assets/{step-3-ZnMaVIPj.js → step-3-6W1NMVQc.js} +2 -2
  184. package/core/built/admin/assets/{stripe-button-DDoUKN5a.js → stripe-button-D2K42Uty.js} +1 -1
  185. package/core/built/admin/assets/{stripe-connect-modal-BeSukI8q.js → stripe-connect-modal-Z-UT_BGc.js} +1 -1
  186. package/core/built/admin/assets/{switch-C9djUIMO.js → switch-CI4gLWqb.js} +1 -1
  187. package/core/built/admin/assets/{table-CrqQtkR2.js → table-B2pIKjVh.js} +1 -1
  188. package/core/built/admin/assets/{tabs-CGisSbWq.js → tabs-SaW_UT-Q.js} +1 -1
  189. package/core/built/admin/assets/tag-detail-Dc0nTOtU.js +2 -0
  190. package/core/built/admin/assets/tags-BLaXBwnb.js +1 -0
  191. package/core/built/admin/assets/testimonials-modal-sFwRnNLh.js +1 -0
  192. package/core/built/admin/assets/{text-DU9Hv33_.js → text-BQDSDsKs.js} +1 -1
  193. package/core/built/admin/assets/{textarea-d9qEkMOP.js → textarea-DJ1Q5V39.js} +1 -1
  194. package/core/built/admin/assets/{tier-detail-modal-CxRwgTPR.js → tier-detail-modal-BCFpWwUS.js} +1 -1
  195. package/core/built/admin/assets/{toggle-group-CtKZURJd.js → toggle-group-EM9WpESu.js} +1 -1
  196. package/core/built/admin/assets/{topic-filter-D8JT8Tq1.js → topic-filter-DY4gNHn2.js} +1 -1
  197. package/core/built/admin/assets/{transistor-modal-6PUf0idx.js → transistor-modal-CpyPG-MH.js} +1 -1
  198. package/core/built/admin/assets/trend-badge-ByMkuAuH.js +1 -0
  199. package/core/built/admin/assets/{unsplash-modal-BPuDBPja.js → unsplash-modal-Cv2Q6GtY.js} +1 -1
  200. package/core/built/admin/assets/{use-analytics-data--opuzwcz.js → use-analytics-data-CHvjMYuT.js} +1 -1
  201. package/core/built/admin/assets/use-check-theme-limit-error-Qv4SVXqw.js +2 -0
  202. package/core/built/admin/assets/use-filter-params-CAvfDvf1.js +1 -0
  203. package/core/built/admin/assets/use-growth-stats-D6mZXGhK.js +1 -0
  204. package/core/built/admin/assets/{use-limiter-TDSNiHPB.js → use-limiter-cwJvsNBo.js} +1 -1
  205. package/core/built/admin/assets/{use-navigate-with-base-path-CK989MlC.js → use-navigate-with-base-path-BHPA228f.js} +1 -1
  206. package/core/built/admin/assets/{use-pintura-config-CnCGrDFk.js → use-pintura-config-CzTfnufz.js} +1 -1
  207. package/core/built/admin/assets/{use-pintura-editor-ntphvtUd.js → use-pintura-editor-BDBXWUYq.js} +1 -1
  208. package/core/built/admin/assets/{use-post-referrers-CbXLFIex.js → use-post-referrers-DbY-mzci.js} +1 -1
  209. package/core/built/admin/assets/{use-reply-chain-data-JYFKSO83.js → use-reply-chain-data-BeQwz8oF.js} +1 -1
  210. package/core/built/admin/assets/{use-router-history-entry-BwfQS2mq.js → use-router-history-entry-Bg6BhBQQ.js} +1 -1
  211. package/core/built/admin/assets/{use-setting-group-DQxV42-O.js → use-setting-group-VM7FQwMY.js} +1 -1
  212. package/core/built/admin/assets/{use-settings-navigation-BBzro2-V.js → use-settings-navigation-BbrSUVcf.js} +1 -1
  213. package/core/built/admin/assets/{use-simple-pagination-B2TdNX67.js → use-simple-pagination-Dum6Irbs.js} +1 -1
  214. package/core/built/admin/assets/{use-staff-users-QrR9voeC.js → use-staff-users-cZg4ugOF.js} +1 -1
  215. package/core/built/admin/assets/{use-tinybird-query-D2Aeoty5.js → use-tinybird-query-B1IMyAcv.js} +1 -1
  216. package/core/built/admin/assets/{use-tinybird-token-DBuwMmln.js → use-tinybird-token-Bow0Zwn8.js} +1 -1
  217. package/core/built/admin/assets/{use-unsaved-changes-guard-DpYJcj1d.js → use-unsaved-changes-guard-BAy0RANR.js} +1 -1
  218. package/core/built/admin/assets/{use-url-input-WnIqckzS.js → use-url-input-Df5QzNa7.js} +1 -1
  219. package/core/built/admin/assets/user-detail-modal-yipSoQfv.js +1 -0
  220. package/core/built/admin/assets/{virtual-list-D3MfPNOh.js → virtual-list-DEx8WgiO.js} +1 -1
  221. package/core/built/admin/assets/web-CKcXAu86.js +1 -0
  222. package/core/built/admin/assets/web-DR4TqM3E.js +2 -0
  223. package/core/built/admin/assets/{zapier-modal-BO6PS_Vd.js → zapier-modal-Cw3BTBUu.js} +1 -1
  224. package/core/built/admin/index.html +24 -25
  225. package/core/frontend/services/rendering/renderer.js +15 -0
  226. package/core/server/adapters/storage/LocalStorageBase.js +8 -5
  227. package/core/server/api/endpoints/db.js +19 -5
  228. package/core/server/api/endpoints/index.js +4 -0
  229. package/core/server/api/endpoints/member-custom-fields.js +4 -14
  230. package/core/server/api/endpoints/posts.js +1 -0
  231. package/core/server/api/endpoints/tiers-checkout-config.js +59 -0
  232. package/core/server/api/endpoints/utils/serializers/output/config.js +1 -0
  233. package/core/server/api/endpoints/utils/serializers/output/index.js +4 -0
  234. package/core/server/api/endpoints/utils/serializers/output/tiers-checkout-config.js +12 -0
  235. package/core/server/data/exporter/table-lists.js +3 -0
  236. package/core/server/data/importer/content-files.js +57 -0
  237. package/core/server/data/importer/handlers/image.js +2 -2
  238. package/core/server/data/importer/import-archive.js +131 -0
  239. package/core/server/data/importer/import-manager.js +18 -180
  240. package/core/server/data/importer/importers/content-file-importer.js +66 -4
  241. package/core/server/data/migrations/versions/6.61/2026-08-19-14-30-20-add-written-by-to-members-custom-field-values.js +42 -0
  242. package/core/server/data/migrations/versions/6.61/2026-08-19-14-38-53-add-members-custom-field-bindings-table.js +26 -0
  243. package/core/server/data/migrations/versions/6.61/2026-08-19-14-48-06-add-tier-checkout-field-tables.js +35 -0
  244. package/core/server/data/schema/schema.js +90 -0
  245. package/core/server/data/seeders/importers/automation-action-revisions-importer.js +3 -3
  246. package/core/server/data/seeders/importers/automation-actions-importer.js +3 -3
  247. package/core/server/data/seeders/importers/automation-run-steps-importer.js +3 -3
  248. package/core/server/data/seeders/importers/automation-runs-importer.js +5 -5
  249. package/core/server/data/seeders/importers/automations-importer.js +3 -3
  250. package/core/server/data/seeders/importers/comment-reports-importer.js +1 -1
  251. package/core/server/data/seeders/importers/comments-importer.js +1 -1
  252. package/core/server/data/seeders/importers/email-batches-importer.js +1 -1
  253. package/core/server/data/seeders/importers/email-recipients-importer.js +1 -1
  254. package/core/server/data/seeders/importers/emails-importer.js +1 -1
  255. package/core/server/data/seeders/importers/labels-importer.js +1 -1
  256. package/core/server/data/seeders/importers/members-click-events-importer.js +1 -1
  257. package/core/server/data/seeders/importers/members-created-events-importer.js +1 -1
  258. package/core/server/data/seeders/importers/members-feedback-importer.js +1 -1
  259. package/core/server/data/seeders/importers/members-importer.js +1 -1
  260. package/core/server/data/seeders/importers/members-login-events-importer.js +1 -1
  261. package/core/server/data/seeders/importers/members-products-importer.js +1 -1
  262. package/core/server/data/seeders/importers/members-status-events-importer.js +1 -1
  263. package/core/server/data/seeders/importers/members-stripe-customers-importer.js +1 -1
  264. package/core/server/data/seeders/importers/members-stripe-customers-subscriptions-importer.js +1 -1
  265. package/core/server/data/seeders/importers/members-subscribe-events-importer.js +1 -1
  266. package/core/server/data/seeders/importers/members-subscription-created-events-importer.js +1 -1
  267. package/core/server/data/seeders/importers/offer-redemptions-importer.js +1 -1
  268. package/core/server/data/seeders/importers/offers-importer.js +1 -1
  269. package/core/server/data/seeders/importers/posts-importer.js +1 -1
  270. package/core/server/data/seeders/importers/table-importer.js +2 -2
  271. package/core/server/data/seeders/importers/tags-importer.js +1 -1
  272. package/core/server/data/seeders/importers/users-importer.js +1 -1
  273. package/core/server/data/seeders/importers/web-mentions-importer.js +1 -1
  274. package/core/server/data/seeders/utils/random.js +3 -3
  275. package/core/server/ghost-server.js +3 -2
  276. package/core/server/lib/db-types/boolean.js +18 -0
  277. package/core/server/lib/promise-pool.js +31 -0
  278. package/core/server/services/automations/database-automations-repository.js +26 -26
  279. package/core/server/services/automations/poll.js +1 -0
  280. package/core/server/services/content-import/import/assets.js +74 -0
  281. package/core/server/services/content-import/import/importer.js +57 -14
  282. package/core/server/services/content-import/import/post-data.js +1 -0
  283. package/core/server/services/content-import/import/post-repository.js +78 -0
  284. package/core/server/services/content-import/import/relations.js +149 -0
  285. package/core/server/services/content-import/import/row.js +11 -0
  286. package/core/server/services/content-import/import/schema.js +29 -0
  287. package/core/server/services/content-import/import/source.js +125 -0
  288. package/core/server/services/content-import/index.js +6 -28
  289. package/core/server/services/email-analytics/email-analytics-service.js +8 -1
  290. package/core/server/services/email-analytics/lib/queries.js +7 -1
  291. package/core/server/services/gift-links/schema.js +3 -3
  292. package/core/server/services/gifts/CONTEXT.md +1 -1
  293. package/core/server/services/gifts/constants.js +1 -1
  294. package/core/server/services/gifts/gift-bookshelf-repository.js +2 -2
  295. package/core/server/services/gifts/gift-delivery-bookshelf-repository.js +18 -9
  296. package/core/server/services/gifts/gift-delivery-schema.js +5 -5
  297. package/core/server/services/gifts/gift-delivery-service.js +4 -0
  298. package/core/server/services/gifts/gift-schema.js +10 -10
  299. package/core/server/services/gifts/gift-service.js +4 -2
  300. package/core/server/services/jobs-service/register-job-handlers.js +5 -5
  301. package/core/server/services/lib/mailgun-client.js +44 -8
  302. package/core/server/services/media-inliner/external-media-inliner-job.js +12 -0
  303. package/core/server/services/media-inliner/external-media-inliner.js +103 -29
  304. package/core/server/services/media-inliner/service.js +13 -41
  305. package/core/server/services/media-inliner/types.js +2 -0
  306. package/core/server/services/members/import-export/export/exporter.js +4 -6
  307. package/core/server/services/members/import-export/import/importer.js +21 -5
  308. package/core/server/services/members/import-export/import/stripe-utils.js +6 -1
  309. package/core/server/services/members/import-export/index.js +6 -1
  310. package/core/server/services/members/members-api/members-api.js +5 -0
  311. package/core/server/services/members/members-api/services/member-bread-service.js +19 -1
  312. package/core/server/services/members/members-api/services/payments-service.js +47 -1
  313. package/core/server/services/members-custom-fields/actions.js +27 -1
  314. package/core/server/services/members-custom-fields/bindings-service.js +119 -0
  315. package/core/server/services/members-custom-fields/definitions-service.js +104 -13
  316. package/core/server/services/members-custom-fields/index.js +11 -4
  317. package/core/server/services/members-custom-fields/queries.js +5 -0
  318. package/core/server/services/members-custom-fields/schema.js +37 -6
  319. package/core/server/services/members-custom-fields/values-service.js +15 -3
  320. package/core/server/services/public-config/config.js +7 -0
  321. package/core/server/services/stripe/services/checkout/allowed-countries.js +267 -0
  322. package/core/server/services/stripe/services/checkout/completed-session.js +68 -0
  323. package/core/server/services/stripe/services/checkout/field-ports.js +34 -0
  324. package/core/server/services/stripe/services/checkout/session-options.js +97 -0
  325. package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +49 -0
  326. package/core/server/services/stripe/stripe-api.js +29 -0
  327. package/core/server/services/stripe/stripe-service.js +7 -0
  328. package/core/server/services/tier-checkout-config/codec.js +95 -0
  329. package/core/server/services/tier-checkout-config/destinations.js +17 -0
  330. package/core/server/services/tier-checkout-config/index.js +26 -0
  331. package/core/server/services/tier-checkout-config/models.js +57 -0
  332. package/core/server/services/tier-checkout-config/queries.js +80 -0
  333. package/core/server/services/tier-checkout-config/schema.js +33 -0
  334. package/core/server/services/tier-checkout-config/serializers.js +122 -0
  335. package/core/server/services/tier-checkout-config/service.js +303 -0
  336. package/core/server/services/tiers/service.js +21 -0
  337. package/core/server/web/api/endpoints/admin/routes.js +24 -13
  338. package/core/server/web/api/middleware/upload.js +2 -2
  339. package/core/server/web/parent/app.js +5 -0
  340. package/core/server/web/parent/middleware/filter-query-parameters.js +94 -0
  341. package/core/server/web/parent/middleware/index.js +1 -0
  342. package/core/server/web/query-parameter-policy/index.js +9 -0
  343. package/core/server/web/query-parameter-policy/policy.json +58 -0
  344. package/core/server/web/query-parameter-policy/schema.js +38 -0
  345. package/core/shared/config/defaults.json +3 -0
  346. package/core/shared/config/env/config.testing-mysql.json +3 -0
  347. package/core/shared/config/env/config.testing.json +3 -0
  348. package/core/shared/config/overrides.json +4 -2
  349. package/core/shared/labs.js +5 -14
  350. package/package.json +12 -13
  351. package/pnpm-lock.yaml +44 -46
  352. package/pnpm-workspace.yaml +6 -6
  353. package/tsconfig.json +2 -3
  354. package/core/built/admin/assets/activitypub/layout-CXajhRsL.js +0 -1
  355. package/core/built/admin/assets/alert-dialog-wEbVxANM.js +0 -1
  356. package/core/built/admin/assets/app-utils-D2Wp7ZSS.js +0 -1
  357. package/core/built/admin/assets/audience-DTLMXAFH.js +0 -1
  358. package/core/built/admin/assets/chart-helpers-B3OqQ6Ez.js +0 -1
  359. package/core/built/admin/assets/command-DcLbSifC.js +0 -1
  360. package/core/built/admin/assets/comments-Bxy_3WyE.js +0 -1
  361. package/core/built/admin/assets/design-and-theme-modal-CZ-PkW7o.js +0 -23
  362. package/core/built/admin/assets/dialog-Db7c164G.js +0 -1
  363. package/core/built/admin/assets/edit-profile-By7v5XW5.js +0 -1
  364. package/core/built/admin/assets/growth-55vWlGT_.js +0 -1
  365. package/core/built/admin/assets/growth-DA5AluYw.js +0 -3
  366. package/core/built/admin/assets/history-modal-G1s5hHz7.js +0 -1
  367. package/core/built/admin/assets/html-field-BegxsWpw.js +0 -1
  368. package/core/built/admin/assets/index-CDP9tIOk.js +0 -4
  369. package/core/built/admin/assets/koenig-loader-DwVY_V-H.js +0 -1
  370. package/core/built/admin/assets/kpi-card-LERqWBoY.js +0 -1
  371. package/core/built/admin/assets/kpi-helpers-DB3ouhYF.js +0 -1
  372. package/core/built/admin/assets/kpi-tabs-BGvtMD8S.js +0 -1
  373. package/core/built/admin/assets/layout-Di5K7doM.js +0 -1
  374. package/core/built/admin/assets/member-detail-D7mZDDp3.js +0 -1
  375. package/core/built/admin/assets/member-route-0Aa52Ntz.js +0 -1
  376. package/core/built/admin/assets/members-DvZG9t69.js +0 -2
  377. package/core/built/admin/assets/navigation-modal-CI8Bx5vn.js +0 -1
  378. package/core/built/admin/assets/newsletter-Bg3cq5U-.js +0 -1
  379. package/core/built/admin/assets/newsletters-DMDfZbMS.js +0 -1
  380. package/core/built/admin/assets/notifications-psA_2Ph4.js +0 -1
  381. package/core/built/admin/assets/overview-C-6xOLaf.js +0 -1
  382. package/core/built/admin/assets/overview-DaLhpRrC.js +0 -1
  383. package/core/built/admin/assets/popover-CFgqFDvC.js +0 -1
  384. package/core/built/admin/assets/portal-modal-Cf0pBAk8.js +0 -1
  385. package/core/built/admin/assets/profile-D6dHYf2o.js +0 -1
  386. package/core/built/admin/assets/radio-group-CjtmsCPl.js +0 -1
  387. package/core/built/admin/assets/select-D_RQaXgt.js +0 -1
  388. package/core/built/admin/assets/settings-DIo_F-MF.js +0 -4
  389. package/core/built/admin/assets/sort-button-DMBXF7tP.js +0 -1
  390. package/core/built/admin/assets/tag-detail-2a3BfzTW.js +0 -2
  391. package/core/built/admin/assets/tags-Dp2_8UzL.js +0 -1
  392. package/core/built/admin/assets/testimonials-modal-C9nrypNo.js +0 -1
  393. package/core/built/admin/assets/use-check-theme-limit-error-C9-QhGdV.js +0 -1
  394. package/core/built/admin/assets/use-filter-params-CSpAvgD2.js +0 -1
  395. package/core/built/admin/assets/use-growth-stats-BOmoPDHJ.js +0 -1
  396. package/core/built/admin/assets/user-detail-modal-59mBJqxN.js +0 -1
  397. package/core/built/admin/assets/web-DUuX7nE2.js +0 -2
  398. package/core/built/admin/assets/web-N8ucs2aG.js +0 -1
  399. /package/core/server/lib/{db-date.js → db-types/date.js} +0 -0
@@ -16,6 +16,9 @@ exports.EDITORIAL_POST_FIELDS = [
16
16
  'created_at',
17
17
  'updated_at',
18
18
  'published_at',
19
+ 'authors',
20
+ 'author_emails',
21
+ 'tags',
19
22
  'feature_image',
20
23
  'feature_image_alt',
21
24
  'feature_image_caption',
@@ -29,6 +32,7 @@ exports.EDITORIAL_POST_FIELDS = [
29
32
  'twitter_image',
30
33
  'twitter_title',
31
34
  'twitter_description',
35
+ 'comment_id',
32
36
  'custom_template',
33
37
  'codeinjection_head',
34
38
  'codeinjection_foot',
@@ -58,6 +62,9 @@ exports.postImportRowSchema = zod_1.z
58
62
  created_at: optionalCell,
59
63
  updated_at: optionalCell,
60
64
  published_at: optionalCell,
65
+ authors: optionalCell,
66
+ author_emails: optionalCell,
67
+ tags: optionalCell,
61
68
  feature_image: optionalCell,
62
69
  feature_image_alt: optionalCell,
63
70
  feature_image_caption: optionalCell,
@@ -71,6 +78,7 @@ exports.postImportRowSchema = zod_1.z
71
78
  twitter_image: optionalCell,
72
79
  twitter_title: optionalCell,
73
80
  twitter_description: optionalCell,
81
+ comment_id: optionalCell,
74
82
  custom_template: optionalCell,
75
83
  codeinjection_head: optionalCell,
76
84
  codeinjection_foot: optionalCell,
@@ -95,6 +103,9 @@ exports.importableRowSchema = exports.postImportRowSchema.superRefine((row, ctx)
95
103
  else if (row.title.length > 255) {
96
104
  ctx.addIssue({ code: 'custom', message: 'title must be 255 characters or fewer' });
97
105
  }
106
+ if (row.comment_id && row.comment_id.length > 50) {
107
+ ctx.addIssue({ code: 'custom', message: 'comment_id must be 50 characters or fewer' });
108
+ }
98
109
  for (const field of DATE_FIELDS) {
99
110
  const value = row[field];
100
111
  if (value && !isValidDate(value)) {
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.importRequestSchema = exports.mappingSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const row_1 = require("./row");
6
+ const importableFields = new Set(row_1.EDITORIAL_POST_FIELDS);
7
+ exports.mappingSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.string()).superRefine((mapping, ctx) => {
8
+ const targets = new Set();
9
+ for (const [header, target] of Object.entries(mapping)) {
10
+ if (!header || header in Object.prototype) {
11
+ ctx.addIssue({ code: 'custom', message: `Invalid CSV header mapping: "${header}"` });
12
+ }
13
+ if (target && !importableFields.has(target)) {
14
+ ctx.addIssue({ code: 'custom', message: `Unknown post field mapping: "${target}"` });
15
+ }
16
+ if (target && targets.has(target)) {
17
+ ctx.addIssue({ code: 'custom', message: `Post field is mapped more than once: "${target}"` });
18
+ }
19
+ targets.add(target);
20
+ }
21
+ if (!targets.has('title')) {
22
+ ctx.addIssue({ code: 'custom', message: 'Post field mapping must include "title"' });
23
+ }
24
+ });
25
+ exports.importRequestSchema = zod_1.z.object({
26
+ filePath: zod_1.z.string().min(1),
27
+ fileName: zod_1.z.string().min(1),
28
+ mapping: exports.mappingSchema.optional(),
29
+ });
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.prepareImportSource = prepareImportSource;
7
+ exports.isDataFile = isDataFile;
8
+ const fs_extra_1 = __importDefault(require("fs-extra"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const glob_1 = require("glob");
11
+ const import_archive_1 = __importDefault(require("../../../data/importer/import-archive"));
12
+ const assets_1 = require("./assets");
13
+ const errors = require('@tryghost/errors');
14
+ const DATA_EXTENSIONS = new Set(['.csv', '.json', '.md', '.markdown']);
15
+ const noCleanup = async () => { };
16
+ async function prepareImportSource(request) {
17
+ const extension = path_1.default.extname(request.fileName).toLowerCase();
18
+ if (extension === '.csv') {
19
+ return { filePath: request.filePath, cleanup: noCleanup };
20
+ }
21
+ if (extension !== '.zip') {
22
+ throw new errors.ValidationError({ message: 'Please select a valid CSV or ZIP file.' });
23
+ }
24
+ const archive = new import_archive_1.default({
25
+ extensions: [...DATA_EXTENSIONS],
26
+ directories: [],
27
+ });
28
+ const directory = await archive.extract(request.filePath);
29
+ let cleaned = false;
30
+ const cleanup = async () => {
31
+ if (!cleaned) {
32
+ cleaned = true;
33
+ await fs_extra_1.default.remove(directory);
34
+ }
35
+ };
36
+ try {
37
+ archive.isValid(directory);
38
+ const baseDirectory = archive.getBaseDirectory(directory);
39
+ const entries = (0, glob_1.globSync)('**/*', { cwd: directory, nodir: true, dot: true });
40
+ const dataFiles = entries.filter(isDataFile);
41
+ const csvFiles = dataFiles.filter((file) => extensionOf(file) === '.csv');
42
+ if (csvFiles.length === 0) {
43
+ throw new errors.ValidationError({
44
+ message: 'ZIP files uploaded here must contain one CSV file.',
45
+ });
46
+ }
47
+ if (csvFiles.length > 1) {
48
+ throw new errors.ValidationError({
49
+ message: 'ZIP files can contain only one CSV file. Remove the extra CSV files and try again.',
50
+ });
51
+ }
52
+ if (dataFiles.length > 1 || entries.some(isUnsupportedCompetingDataFile)) {
53
+ throw new errors.ValidationError({
54
+ message: 'ZIP files cannot contain CSV, JSON, or Markdown import files together. Keep only the CSV file and try again.',
55
+ });
56
+ }
57
+ validateWrapper(entries, csvFiles[0]);
58
+ const csvParts = csvFiles[0].split('/').filter(Boolean);
59
+ const csvBaseDirectory = csvParts.length === 2 ? csvParts[0] : undefined;
60
+ if (csvBaseDirectory !== baseDirectory) {
61
+ throw new errors.ValidationError({ message: 'Invalid ZIP file structure.' });
62
+ }
63
+ return {
64
+ filePath: path_1.default.join(directory, csvFiles[0]),
65
+ assets: await (0, assets_1.prepareAssetBatch)(archive, directory, baseDirectory),
66
+ cleanup,
67
+ };
68
+ }
69
+ catch (error) {
70
+ await cleanup();
71
+ throw error;
72
+ }
73
+ }
74
+ function validateWrapper(entries, csvFile) {
75
+ const csvParts = csvFile.split('/').filter(Boolean);
76
+ if (csvParts.length !== 2) {
77
+ return;
78
+ }
79
+ const wrapper = csvParts[0];
80
+ const outsideWrapper = entries.some((entry) => {
81
+ const parts = entry.split('/').filter(Boolean);
82
+ return !isMetadata(parts) && parts[0] !== wrapper;
83
+ });
84
+ if (outsideWrapper) {
85
+ throw new errors.ValidationError({ message: 'Invalid ZIP file structure.' });
86
+ }
87
+ }
88
+ function isDataFile(fileName) {
89
+ const parts = fileName.split('/').filter(Boolean);
90
+ if (parts.length === 0 || isMetadata(parts)) {
91
+ return false;
92
+ }
93
+ const extension = extensionOf(fileName);
94
+ if (!DATA_EXTENSIONS.has(extension)) {
95
+ return false;
96
+ }
97
+ if (parts.length === 1) {
98
+ return true;
99
+ }
100
+ return parts.length === 2;
101
+ }
102
+ function extensionOf(fileName) {
103
+ return path_1.default.posix.extname(fileName).toLowerCase();
104
+ }
105
+ function isUnsupportedCompetingDataFile(fileName) {
106
+ const extension = extensionOf(fileName);
107
+ if (extension === '.csv' || !DATA_EXTENSIONS.has(extension)) {
108
+ return false;
109
+ }
110
+ const parts = fileName.split('/').filter(Boolean);
111
+ if (parts.length === 0 || isMetadata(parts) || isFileAttachment(parts)) {
112
+ return false;
113
+ }
114
+ return !isDataFile(fileName);
115
+ }
116
+ function isFileAttachment(parts) {
117
+ const assetParts = ['content', 'files'].includes(parts[0]) ? [...parts] : parts.slice(1);
118
+ if (assetParts[0] === 'content') {
119
+ assetParts.shift();
120
+ }
121
+ return assetParts.length > 1 && assetParts[0] === 'files';
122
+ }
123
+ function isMetadata(parts) {
124
+ return (parts[0] === '__MACOSX' || parts.some((part) => part.startsWith('._') || part === '.DS_Store'));
125
+ }
@@ -7,34 +7,13 @@ exports.init = init;
7
7
  exports.importCSV = importCSV;
8
8
  const zod_1 = require("zod");
9
9
  const importer_1 = __importDefault(require("./import/importer"));
10
+ const post_repository_1 = require("./import/post-repository");
10
11
  const reader_1 = __importDefault(require("./import/reader"));
11
- const row_1 = require("./import/row");
12
+ const schema_1 = require("./import/schema");
12
13
  const store_1 = require("./import/store");
14
+ const source_1 = require("./import/source");
13
15
  // The request is built from HTTP upload metadata, so it is validated at the
14
16
  // service boundary rather than trusted.
15
- const importableFields = new Set(row_1.EDITORIAL_POST_FIELDS);
16
- const mappingSchema = zod_1.z.record(zod_1.z.string(), zod_1.z.string()).superRefine((mapping, ctx) => {
17
- const targets = new Set();
18
- for (const [header, target] of Object.entries(mapping)) {
19
- if (!header || header in Object.prototype) {
20
- ctx.addIssue({ code: 'custom', message: `Invalid CSV header mapping: "${header}"` });
21
- }
22
- if (target && !importableFields.has(target)) {
23
- ctx.addIssue({ code: 'custom', message: `Unknown post field mapping: "${target}"` });
24
- }
25
- if (target && targets.has(target)) {
26
- ctx.addIssue({ code: 'custom', message: `Post field is mapped more than once: "${target}"` });
27
- }
28
- targets.add(target);
29
- }
30
- if (!targets.has('title')) {
31
- ctx.addIssue({ code: 'custom', message: 'Post field mapping must include "title"' });
32
- }
33
- });
34
- const importRequestSchema = zod_1.z.object({
35
- filePath: zod_1.z.string().min(1),
36
- mapping: mappingSchema.optional(),
37
- });
38
17
  // A junk timezone setting falls back to UTC rather than mis-stamping the batch tag.
39
18
  const timezoneSchema = zod_1.z.string().min(1).catch('Etc/UTC');
40
19
  const errors = require('@tryghost/errors');
@@ -64,9 +43,8 @@ function makeImporter() {
64
43
  };
65
44
  return new importer_1.default({
66
45
  readRows: reader_1.default,
67
- posts: {
68
- create: (data, options) => models.Post.add(data, options),
69
- },
46
+ prepareSource: source_1.prepareImportSource,
47
+ posts: new post_repository_1.BookshelfPostsRepository(models),
70
48
  getHtmlToLexical: () => lexicalLib.htmlToLexicalConverter,
71
49
  getMarkdownToHtml: () => require('@tryghost/kg-markdown-html-renderer').render,
72
50
  getCleanHTML: () => require('@tryghost/mg-clean-html').cleanHTML,
@@ -88,7 +66,7 @@ function importCSV(request) {
88
66
  if (!importer) {
89
67
  throw new errors.InternalServerError({ message: 'Content import service used before init' });
90
68
  }
91
- const parsedRequest = importRequestSchema.safeParse(request);
69
+ const parsedRequest = schema_1.importRequestSchema.safeParse(request);
92
70
  if (!parsedRequest.success) {
93
71
  throw new errors.ValidationError({
94
72
  message: parsedRequest.error.issues[0]?.message ?? 'Invalid content import request',
@@ -364,15 +364,22 @@ class EmailAnalyticsService {
364
364
  }
365
365
  };
366
366
  try {
367
- await this.#fetchEvents({
367
+ const fetchResult = await this.#fetchEvents({
368
368
  batchHandler: processBatch,
369
369
  begin,
370
370
  end,
371
371
  maxEvents,
372
372
  events: eventTypes,
373
373
  });
374
+ if (fetchResult?.safeCursor &&
375
+ (!fetchData.lastEventTimestamp || fetchResult.safeCursor < fetchData.lastEventTimestamp)) {
376
+ fetchData.lastEventTimestamp = fetchResult.safeCursor;
377
+ }
374
378
  }
375
379
  catch (err) {
380
+ // A fetch can process events from one domain before another domain fails. Keep the
381
+ // in-memory cursor at the start of this run so the next attempt retries every domain.
382
+ fetchData.lastEventTimestamp = begin;
376
383
  if (!(err instanceof Error) || err.message !== 'Fetching canceled') {
377
384
  logging_1.default.error('[EmailAnalytics] Error while fetching');
378
385
  logging_1.default.error(err);
@@ -122,7 +122,13 @@ class Queries {
122
122
  */
123
123
  async getLastJobRunTimestamp(jobName) {
124
124
  const jobData = await this.getJobData(jobName);
125
- return jobData ? jobData.finished_at || jobData.started_at : null;
125
+ const timestamp = jobData?.finished_at ?? jobData?.started_at ?? null;
126
+ if (timestamp === null) {
127
+ return null;
128
+ }
129
+ // SQLite returns datetime columns as strings or numbers, so normalise to a Date to match
130
+ // the declared return type and keep callers using Date methods (e.g. getTime()) safe.
131
+ return timestamp instanceof Date ? timestamp : new Date(timestamp);
126
132
  }
127
133
  /**
128
134
  * Sets the timestamp of the last seen event for the specified email analytics events.
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DbGiftLink = void 0;
4
4
  const zod_1 = require("zod");
5
- const db_date_1 = require("../../lib/db-date");
5
+ const date_1 = require("../../lib/db-types/date");
6
6
  exports.DbGiftLink = zod_1.z.object({
7
7
  token: zod_1.z.string(),
8
8
  post_id: zod_1.z.string(),
9
- created_at: db_date_1.DbDate,
10
- updated_at: db_date_1.DbDate.nullable(),
9
+ created_at: date_1.DbDate,
10
+ updated_at: date_1.DbDate.nullable(),
11
11
  });
@@ -37,7 +37,7 @@ The buyer's chosen way of handing over a gift subscription: the publication emai
37
37
  _Avoid_: Delivery mode
38
38
 
39
39
  **Redemption link**:
40
- A single-use, time-limited link through which a purchased gift subscription can be viewed and claimed. Its bearer may see the gift's buyer name, intended recipient name, and personal message, but not email-routing or delivery details.
40
+ A single-use, time-limited link through which a purchased gift subscription can be viewed and claimed. Its bearer may see the gift's buyer name, intended recipient name, recipient email, and personal message; the intended recipient does not reserve redemption.
41
41
  _Avoid_: Gift Link
42
42
 
43
43
  **Gift redemption**:
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GIFT_DELIVERY_EMAIL_TAG = exports.GIFT_DELIVERY_STALE_AFTER_MS = exports.GIFT_REMINDER_FLOOR_DAYS = exports.GIFT_REMINDER_LEAD_DAYS = exports.GIFT_SEND_HOUR = exports.GIFT_MAX_SCHEDULE_DAYS = exports.GIFT_EXPIRY_DAYS = void 0;
4
4
  exports.GIFT_EXPIRY_DAYS = 365;
5
5
  // How far ahead a delivery may be scheduled. Portal's picker carries its own
6
- // copy (GIFT_MAX_SCHEDULE_DAYS in beta-gift-page.jsx) since Portal ships
6
+ // copy (GIFT_MAX_SCHEDULE_DAYS in beta-gift-page.tsx) since Portal ships
7
7
  // separately — change them together.
8
8
  exports.GIFT_MAX_SCHEDULE_DAYS = 365;
9
9
  // Site-local hour a scheduled delivery is sent at. Portal never derives
@@ -7,7 +7,7 @@ exports.GiftBookshelfRepository = void 0;
7
7
  const errors_1 = __importDefault(require("@tryghost/errors"));
8
8
  const mongo_utils_1 = require("@tryghost/mongo-utils");
9
9
  const gift_codec_1 = require("./gift-codec");
10
- const db_date_1 = require("../../lib/db-date");
10
+ const date_1 = require("../../lib/db-types/date");
11
11
  class GiftBookshelfRepository {
12
12
  model;
13
13
  knex;
@@ -117,7 +117,7 @@ class GiftBookshelfRepository {
117
117
  async deleteAbandonedCheckouts(cutoff) {
118
118
  return this.knex('gifts')
119
119
  .where({ status: 'payment_pending' })
120
- .where('checkout_started_at', '<=', (0, db_date_1.toDatabaseDate)(cutoff))
120
+ .where('checkout_started_at', '<=', (0, date_1.toDatabaseDate)(cutoff))
121
121
  .del();
122
122
  }
123
123
  async create(gift, options = {}) {
@@ -5,7 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.GiftDeliveryBookshelfRepository = void 0;
7
7
  const errors_1 = __importDefault(require("@tryghost/errors"));
8
- const db_date_1 = require("../../lib/db-date");
8
+ const date_1 = require("../../lib/db-types/date");
9
9
  const gift_codec_1 = require("./gift-codec");
10
10
  const gift_delivery_codec_1 = require("./gift-delivery-codec");
11
11
  // A null scheduled_at means the delivery was due at purchase time, so it is
@@ -14,7 +14,7 @@ function dueDeliveries(query, now) {
14
14
  query.andWhere((due) => {
15
15
  due
16
16
  .whereNull('gift_deliveries.scheduled_at')
17
- .orWhere('gift_deliveries.scheduled_at', '<=', (0, db_date_1.toDatabaseDate)(now));
17
+ .orWhere('gift_deliveries.scheduled_at', '<=', (0, date_1.toDatabaseDate)(now));
18
18
  });
19
19
  }
20
20
  // Deliveries that still need a send attempt: never started, or claimed by a
@@ -24,7 +24,7 @@ function recoverableDeliveries(query, staleBefore) {
24
24
  recoverable.where('gift_deliveries.status', 'pending').orWhere((stale) => {
25
25
  stale
26
26
  .where('gift_deliveries.status', 'sending')
27
- .where('gift_deliveries.started_at', '<=', (0, db_date_1.toDatabaseDate)(staleBefore));
27
+ .where('gift_deliveries.started_at', '<=', (0, date_1.toDatabaseDate)(staleBefore));
28
28
  });
29
29
  });
30
30
  }
@@ -43,6 +43,15 @@ class GiftDeliveryBookshelfRepository {
43
43
  const model = await this.model.findOne({ gift_id: giftId }, { require: false, ...options });
44
44
  return model ? (0, gift_delivery_codec_1.decodeGiftDeliveryRow)(model.toJSON()) : null;
45
45
  }
46
+ async getByGiftToken(giftToken, options = {}) {
47
+ const db = options.transacting ?? this.knex;
48
+ const row = await db('gift_deliveries')
49
+ .select('gift_deliveries.*')
50
+ .join('gifts', 'gifts.id', 'gift_deliveries.gift_id')
51
+ .where('gifts.token', giftToken)
52
+ .first();
53
+ return row ? (0, gift_delivery_codec_1.decodeGiftDeliveryRow)(row) : null;
54
+ }
46
55
  async getByProviderMessageId(providerMessageId) {
47
56
  const model = await this.model.findOne({ email_provider_message_id: providerMessageId }, { require: false });
48
57
  return model ? (0, gift_delivery_codec_1.decodeGiftDeliveryRow)(model.toJSON()) : null;
@@ -83,8 +92,8 @@ class GiftDeliveryBookshelfRepository {
83
92
  .join('gifts', 'gifts.id', 'gift_deliveries.gift_id')
84
93
  .where('gift_deliveries.status', 'pending')
85
94
  .where('gifts.status', 'purchased')
86
- .where('gift_deliveries.scheduled_at', '>', (0, db_date_1.toDatabaseDate)(now));
87
- return rows.map((row) => (0, db_date_1.fromDatabaseDate)(row.scheduled_at));
95
+ .where('gift_deliveries.scheduled_at', '>', (0, date_1.toDatabaseDate)(now));
96
+ return rows.map((row) => (0, date_1.fromDatabaseDate)(row.scheduled_at));
88
97
  }
89
98
  async tryStartDelivery(id, now, staleBefore) {
90
99
  const claimed = await this.knex('gift_deliveries')
@@ -100,7 +109,7 @@ class GiftDeliveryBookshelfRepository {
100
109
  .modify(recoverableDeliveries, staleBefore)
101
110
  .update({
102
111
  status: 'sending',
103
- started_at: (0, db_date_1.toDatabaseDate)(now),
112
+ started_at: (0, date_1.toDatabaseDate)(now),
104
113
  });
105
114
  if (claimed !== 1) {
106
115
  return null;
@@ -110,7 +119,7 @@ class GiftDeliveryBookshelfRepository {
110
119
  async markSent(id, sentAt, providerMessageId) {
111
120
  return this.updateState(id, 'sending', {
112
121
  status: 'sent',
113
- email_sent_at: (0, db_date_1.toDatabaseDate)(sentAt),
122
+ email_sent_at: (0, date_1.toDatabaseDate)(sentAt),
114
123
  email_provider_message_id: providerMessageId,
115
124
  started_at: null,
116
125
  });
@@ -119,7 +128,7 @@ class GiftDeliveryBookshelfRepository {
119
128
  // details so the message can still be correlated with transport outcomes
120
129
  async recordCancelledAcceptance(id, sentAt, providerMessageId) {
121
130
  return this.updateState(id, 'cancelled', {
122
- email_sent_at: (0, db_date_1.toDatabaseDate)(sentAt),
131
+ email_sent_at: (0, date_1.toDatabaseDate)(sentAt),
123
132
  email_provider_message_id: providerMessageId,
124
133
  });
125
134
  }
@@ -145,7 +154,7 @@ class GiftDeliveryBookshelfRepository {
145
154
  return updated === 1;
146
155
  }
147
156
  async recordOutcome({ providerMessageId, outcome, timestamp, error, }) {
148
- const outcomeAt = (0, db_date_1.toDatabaseDate)(timestamp);
157
+ const outcomeAt = (0, date_1.toDatabaseDate)(timestamp);
149
158
  const lowerPriorityOutcomes = outcome === 'permanent_failed'
150
159
  ? ['temporary_failed', 'delivered']
151
160
  : outcome === 'delivered'
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DbGiftDelivery = exports.GiftDeliveryOutcomeSchema = exports.GiftDeliveryStatusSchema = void 0;
4
4
  const zod_1 = require("zod");
5
- const db_date_1 = require("../../lib/db-date");
5
+ const date_1 = require("../../lib/db-types/date");
6
6
  exports.GiftDeliveryStatusSchema = zod_1.z.enum([
7
7
  'pending',
8
8
  'sending',
@@ -21,11 +21,11 @@ exports.DbGiftDelivery = zod_1.z.object({
21
21
  gift_id: zod_1.z.string(),
22
22
  recipient_email: zod_1.z.string().email(),
23
23
  status: exports.GiftDeliveryStatusSchema.default('pending'),
24
- scheduled_at: db_date_1.DbDate.nullable().default(null),
25
- started_at: db_date_1.DbDate.nullable().default(null),
26
- email_sent_at: db_date_1.DbDate.nullable().default(null),
24
+ scheduled_at: date_1.DbDate.nullable().default(null),
25
+ started_at: date_1.DbDate.nullable().default(null),
26
+ email_sent_at: date_1.DbDate.nullable().default(null),
27
27
  email_provider_message_id: zod_1.z.string().nullable().default(null),
28
28
  outcome: exports.GiftDeliveryOutcomeSchema.default('unknown'),
29
- outcome_at: db_date_1.DbDate.nullable().default(null),
29
+ outcome_at: date_1.DbDate.nullable().default(null),
30
30
  outcome_error: zod_1.z.string().nullable().default(null),
31
31
  });
@@ -41,6 +41,10 @@ class GiftDeliveryService {
41
41
  await this.deps.giftDeliveryRepository.create(delivery, options);
42
42
  return delivery.id;
43
43
  }
44
+ async getRecipientEmailForGift(giftToken, options = {}) {
45
+ const delivery = await this.deps.giftDeliveryRepository.getByGiftToken(giftToken, options);
46
+ return delivery?.recipientEmail ?? null;
47
+ }
44
48
  async dispatchForGift({ giftId, }) {
45
49
  const delivery = await this.deps.giftDeliveryRepository.getByGiftId(giftId);
46
50
  if (!delivery || delivery.status !== 'pending') {
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DbGift = exports.GiftStatusSchema = exports.GiftCadenceSchema = void 0;
4
4
  const zod_1 = require("zod");
5
- const db_date_1 = require("../../lib/db-date");
5
+ const date_1 = require("../../lib/db-types/date");
6
6
  exports.GiftCadenceSchema = zod_1.z.enum(['month', 'year']);
7
7
  exports.GiftStatusSchema = zod_1.z.enum([
8
8
  'payment_pending',
@@ -32,14 +32,14 @@ exports.DbGift = zod_1.z.object({
32
32
  amount: zod_1.z.number().int().nonnegative(),
33
33
  stripe_checkout_session_id: zod_1.z.string().nullable(),
34
34
  stripe_payment_intent_id: zod_1.z.string().nullable(),
35
- checkout_started_at: db_date_1.DbDate.nullable().default(null),
36
- consumes_at: db_date_1.DbDate.nullable(),
37
- expires_at: db_date_1.DbDate.nullable(),
35
+ checkout_started_at: date_1.DbDate.nullable().default(null),
36
+ consumes_at: date_1.DbDate.nullable(),
37
+ expires_at: date_1.DbDate.nullable(),
38
38
  status: exports.GiftStatusSchema,
39
- purchased_at: db_date_1.DbDate.nullable(),
40
- redeemed_at: db_date_1.DbDate.nullable(),
41
- consumed_at: db_date_1.DbDate.nullable(),
42
- expired_at: db_date_1.DbDate.nullable(),
43
- refunded_at: db_date_1.DbDate.nullable(),
44
- consumes_soon_reminder_sent_at: db_date_1.DbDate.nullable().default(null),
39
+ purchased_at: date_1.DbDate.nullable(),
40
+ redeemed_at: date_1.DbDate.nullable(),
41
+ consumed_at: date_1.DbDate.nullable(),
42
+ expired_at: date_1.DbDate.nullable(),
43
+ refunded_at: date_1.DbDate.nullable(),
44
+ consumes_soon_reminder_sent_at: date_1.DbDate.nullable().default(null),
45
45
  });
@@ -565,7 +565,7 @@ class GiftService {
565
565
  transacting,
566
566
  newMember: input.newMember,
567
567
  });
568
- const redemption = await this.serializeRedemption(redeemed);
568
+ const redemption = await this.serializeRedemption(redeemed, { transacting });
569
569
  return { redeemed, member, redemption };
570
570
  };
571
571
  const { redeemed, member, redemption } = input.transacting
@@ -1044,7 +1044,8 @@ class GiftService {
1044
1044
  });
1045
1045
  return true;
1046
1046
  }
1047
- async serializeRedemption(gift) {
1047
+ async serializeRedemption(gift, options = {}) {
1048
+ const recipientEmail = await this.deps.giftDeliveryService.getRecipientEmailForGift(gift.token, options);
1048
1049
  const tier = await this.deps.tiersService.api.read(gift.tierId);
1049
1050
  if (!tier) {
1050
1051
  throw new errors_1.default.InternalServerError({
@@ -1060,6 +1061,7 @@ class GiftService {
1060
1061
  amount: gift.amount,
1061
1062
  buyer_name: gift.buyerName,
1062
1063
  recipient_name: gift.recipientName,
1064
+ recipient_email: recipientEmail,
1063
1065
  message: gift.personalMessage,
1064
1066
  expires_at: gift.expiresAt,
1065
1067
  consumes_at: gift.consumesAt,
@@ -38,15 +38,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.default = registerJobHandlers;
40
40
  const errors_1 = __importDefault(require("@tryghost/errors"));
41
- const index_1 = require("./index");
42
41
  const clean_tokens_job_1 = __importDefault(require("../members/jobs/clean-tokens-job"));
43
42
  const clean_tokens_task_1 = __importDefault(require("../members/jobs/clean-tokens-task"));
44
43
  const gifts = __importStar(require("../gifts"));
45
44
  const clean_gifts_job_1 = __importDefault(require("../gifts/jobs/clean-gifts-job"));
46
- const logging = require('@tryghost/logging');
47
- function registerJobHandlers() {
48
- const jobsService = (0, index_1.getInstance)();
49
- const db = require('../../data/db');
45
+ const external_media_inliner_job_1 = __importDefault(require("../media-inliner/external-media-inliner-job"));
46
+ function registerJobHandlers({ jobsService, db, logging, mediaInliner, }) {
50
47
  jobsService.handle(clean_tokens_job_1.default, async () => {
51
48
  await (0, clean_tokens_task_1.default)({ db, logging });
52
49
  });
@@ -58,4 +55,7 @@ function registerJobHandlers() {
58
55
  }
59
56
  await gifts.service.cleanup();
60
57
  });
58
+ jobsService.handle(external_media_inliner_job_1.default, async (job) => {
59
+ await mediaInliner.inline(job.domains);
60
+ });
61
61
  }