ghost 6.60.0 → 6.62.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 (613) hide show
  1. package/components/ghost-storage-base-3.0.0.tgz +0 -0
  2. package/components/tryghost-adapter-base-cache-0.2.0.tgz +0 -0
  3. package/components/tryghost-adapter-base-jobs-0.0.0.tgz +0 -0
  4. package/components/tryghost-adapter-base-redirects-0.0.0.tgz +0 -0
  5. package/components/tryghost-adapter-base-route-settings-0.0.0.tgz +0 -0
  6. package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
  7. package/components/tryghost-adapter-base-sso-0.1.3.tgz +0 -0
  8. package/components/tryghost-admin-api-schema-0.0.0.tgz +0 -0
  9. package/components/tryghost-checkout-0.0.0.tgz +0 -0
  10. package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
  11. package/components/tryghost-i18n-0.0.0.tgz +0 -0
  12. package/components/tryghost-kg-card-factory-5.2.4.tgz +0 -0
  13. package/components/tryghost-kg-clean-basic-html-4.3.4.tgz +0 -0
  14. package/components/tryghost-kg-converters-1.2.5.tgz +0 -0
  15. package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
  16. package/components/tryghost-kg-default-nodes-2.2.1.tgz +0 -0
  17. package/components/tryghost-kg-default-transforms-1.3.4.tgz +0 -0
  18. package/components/tryghost-kg-html-to-lexical-1.4.0.tgz +0 -0
  19. package/components/tryghost-kg-lexical-html-renderer-1.5.0.tgz +0 -0
  20. package/components/tryghost-kg-markdown-html-renderer-7.2.4.tgz +0 -0
  21. package/components/tryghost-kg-utils-1.1.4.tgz +0 -0
  22. package/components/tryghost-nql-string-0.0.0.tgz +0 -0
  23. package/components/tryghost-parse-email-address-0.0.0.tgz +0 -0
  24. package/content/settings/README.md +1 -1
  25. package/content/themes/casper/.gitignore +28 -0
  26. package/content/themes/casper/assets/built/casper.js +1 -1
  27. package/content/themes/casper/assets/built/screen.css +1 -1
  28. package/content/themes/casper/assets/css/screen.css +2 -1
  29. package/content/themes/casper/assets/js/lightbox.js +63 -46
  30. package/content/themes/casper/package.json +6 -6
  31. package/content/themes/casper/page.hbs +1 -0
  32. package/content/themes/casper/post.hbs +1 -0
  33. package/content/themes/source/.gitignore +28 -0
  34. package/content/themes/source/assets/built/screen.css +1 -1
  35. package/content/themes/source/assets/built/source.js +1 -1
  36. package/content/themes/source/assets/css/screen.css +2 -1
  37. package/content/themes/source/assets/js/lightbox.js +62 -45
  38. package/content/themes/source/assets/js/main.js +2 -2
  39. package/content/themes/source/package.json +4 -4
  40. package/content/themes/source/partials/feature-image.hbs +1 -0
  41. package/core/boot.js +62 -21
  42. package/core/built/admin/assets/Combination-B0l4MKVh.js +41 -0
  43. package/core/built/admin/assets/InterVariable-DiVDrmQJ.woff2 +0 -0
  44. package/core/built/admin/assets/InterVariable-Italic-FCBEiFp6.woff2 +0 -0
  45. package/core/built/admin/assets/{PolarAngleAxis-C4qtHy1B.js → PolarAngleAxis-pkMyqz8g.js} +1 -1
  46. package/core/built/admin/assets/{RadialBarChart-Bh09Stsj.js → RadialBarChart-JAKoS4KT.js} +1 -1
  47. package/core/built/admin/assets/{about-BgpmhCuM.js → about-Dyae_UT6.js} +1 -1
  48. package/core/built/admin/assets/account-migration-CESa0mnX.js +1 -0
  49. package/core/built/admin/assets/{action-list-lGzZLHc8.js → action-list-C4v0-du8.js} +1 -1
  50. package/core/built/admin/assets/activitypub/{account-migration-DMHuPnJn.js → account-migration-By69CgCp.js} +16 -16
  51. package/core/built/admin/assets/activitypub/activitypub.js +9 -10
  52. package/core/built/admin/assets/activitypub/{avatar-DhTo5D1B.js → avatar-DLPL3Abs.js} +59 -68
  53. package/core/built/admin/assets/activitypub/{avatar-flipboard-DnVgbEfa.js → avatar-flipboard-C9iDY-QV.js} +2 -2
  54. package/core/built/admin/assets/activitypub/{bluesky-sharing-BT4zAlW7.js → bluesky-sharing-BJcPMrDd.js} +37 -37
  55. package/core/built/admin/assets/activitypub/{content-formatters-BeDZ-DIa.js → content-formatters-3rTHg3mp.js} +18 -18
  56. package/core/built/admin/assets/activitypub/{copy-8sqxUuNd.js → copy-DIAOQoCZ.js} +2 -2
  57. package/core/built/admin/assets/activitypub/{domain-xQDDu1CS.js → domain-DUR4xSkV.js} +121 -121
  58. package/core/built/admin/assets/activitypub/{edit-profile-BXdF_r2G.js → edit-profile-BqtfzxCp.js} +40 -40
  59. package/core/built/admin/assets/activitypub/{explore-CMt7gKlL.js → explore-BxuJd-J4.js} +27 -27
  60. package/core/built/admin/assets/activitypub/{feed-Bwqdddp_.js → feed-BM1TcksA.js} +51 -51
  61. package/core/built/admin/assets/activitypub/{field-4co_8FVg.js → field-Dn7HHx2-.js} +3 -3
  62. package/core/built/admin/assets/activitypub/{hash-DwakMs4X.js → hash-Bm3WxYN4.js} +2 -2
  63. package/core/built/admin/assets/activitypub/inbox-CCjkuow2.js +1284 -0
  64. package/core/built/admin/assets/activitypub/{inbox-ckD4wo_r.js → inbox-d8oJRTf4.js} +2 -2
  65. package/core/built/admin/assets/activitypub/label-1AA_s9Fa.js +16 -0
  66. package/core/built/admin/assets/activitypub/layout-2-0bw6HN.js +1 -0
  67. package/core/built/admin/assets/activitypub/{moderation-KCCO7L2J.js → moderation-CnmxEB8w.js} +91 -91
  68. package/core/built/admin/assets/activitypub/{note-BX_Bz5A0.js → note-ZKc_Bnba.js} +24 -24
  69. package/core/built/admin/assets/activitypub/{notifications-BQOYGvRv.js → notifications-CB2tJZau.js} +51 -51
  70. package/core/built/admin/assets/activitypub/{onboarding-CNelD_uF.js → onboarding-BsJ9E5qf.js} +2 -2
  71. package/core/built/admin/assets/activitypub/{onboarding-mat5Hrl0.js → onboarding-CSUJJIlh.js} +2 -2
  72. package/core/built/admin/assets/activitypub/{preferences-6h43G9_q.js → preferences-0-JZnUkI.js} +1519 -1519
  73. package/core/built/admin/assets/activitypub/{profile-BMN9VVZ2.js → profile-C35cFIhM.js} +256 -256
  74. package/core/built/admin/assets/activitypub/{reply-ZNo04xsO.js → reply-DYK5vVqb.js} +2 -2
  75. package/core/built/admin/assets/activitypub/{routes-3B9mUQ7i.js → routes-BD4vscyc.js} +796 -790
  76. package/core/built/admin/assets/activitypub/{separator-D9taVCCa.js → separator-BbQqTm-p.js} +3 -3
  77. package/core/built/admin/assets/activitypub/settings-BsMROdqh.js +315 -0
  78. package/core/built/admin/assets/activitypub/{site-DHoMupSB.js → site-O0RL9YCN.js} +2 -2
  79. package/core/built/admin/assets/activitypub/{step-1-BsGGnBuT.js → step-1-BMSx7c_X.js} +6 -6
  80. package/core/built/admin/assets/activitypub/{step-2-teosIS0k.js → step-2-DtPQzlTH.js} +6 -6
  81. package/core/built/admin/assets/activitypub/{step-3-BjD5TokC.js → step-3-CLlOZTyt.js} +11 -11
  82. package/core/built/admin/assets/activitypub/{tabs-Cvwl1wXU.js → tabs-Dxk-b9M-.js} +306 -306
  83. package/core/built/admin/assets/activitypub/{topic-filter-C3LZJc2X.js → topic-filter-5yZH6tId.js} +3 -3
  84. package/core/built/admin/assets/activitypub/{use-activity-pub-queries-Dp9f0gov.js → use-activity-pub-queries-CV50qe03.js} +3 -3
  85. package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-C4RI0sa9.js → use-navigate-with-base-path-Bmk5h4lW.js} +220 -220
  86. package/core/built/admin/assets/activitypub/{use-reply-chain-data-C2oNDMUH.js → use-reply-chain-data-Cbvzgjzd.js} +30 -30
  87. package/core/built/admin/assets/activitypub/{users-CoX6FT_K.js → users-BjcoP_HC.js} +7 -5
  88. package/core/built/admin/assets/activitypub/{x-Dxm6pV9X.js → x-DbQZOLiI.js} +2 -2
  89. package/core/built/admin/assets/add-integration-modal-BlF6rs_f.js +1 -0
  90. package/core/built/admin/assets/add-newsletter-modal-CglVQqah.js +1 -0
  91. package/core/built/admin/assets/add-recommendation-modal-wz7BsuaG.js +1 -0
  92. package/core/built/admin/assets/analytics-C4HE1gBg.js +1 -0
  93. package/core/built/admin/assets/{announcement-bar-modal-BTHiy1ZO.js → announcement-bar-modal-Ci4zz8jO.js} +1 -1
  94. package/core/built/admin/assets/{api-keys-Boy5pLbD.js → api-keys-Ck-Yteiv.js} +1 -1
  95. package/core/built/admin/assets/audience-CtbA54Sn.js +1 -0
  96. package/core/built/admin/assets/{automated-emails-te1D5kq-.js → automated-emails-D5VVMND9.js} +1 -1
  97. package/core/built/admin/assets/automations-CzKt5fb8.js +1 -0
  98. package/core/built/admin/assets/bluesky-sharing-BEtJ_gL_.js +1 -0
  99. package/core/built/admin/assets/{box-By_EgGtm.js → box-CdfQAP_F.js} +1 -1
  100. package/core/built/admin/assets/{brand-icon-09YqFZjV.js → brand-icon-CrIGOA3Z.js} +1 -1
  101. package/core/built/admin/assets/{breadcrumb-CcFr_ltt.js → breadcrumb-zUrZrBtW.js} +1 -1
  102. package/core/built/admin/assets/{button-BshWPHvn.js → button-eNMKQWXr.js} +1 -1
  103. package/core/built/admin/assets/{card-CiiE7QfM.js → card--VNbfgo3.js} +1 -1
  104. package/core/built/admin/assets/{chart-BnXyfH11.js → chart-BrhA41Zi.js} +1 -1
  105. package/core/built/admin/assets/chart-helpers-CfBKt0vT.js +1 -0
  106. package/core/built/admin/assets/{checkbox-Dwwr_3Py.js → checkbox-CgOn_tKW.js} +1 -1
  107. package/core/built/admin/assets/{chunk.524.91ecb33e6afc3bd8949b.js → chunk.524.a697dee88db67fdf6021.js} +4 -4
  108. package/core/built/admin/assets/{chunk.582.512549909741883f960c.js → chunk.582.5ed5d124cfca9c259b9c.js} +6 -6
  109. package/core/built/admin/assets/{chunk.16.f76a6314082d813d67e0.js → chunk.598.7e056fabb47ce7dbd73f.js} +14 -14
  110. package/core/built/admin/assets/{code-editor-view-BwIdPy_k.js → code-editor-view-BYNoAoNV.js} +1 -1
  111. package/core/built/admin/assets/{code-editor-view-CtkF82Fv.js → code-editor-view-K2wI-I5f.js} +1 -1
  112. package/core/built/admin/assets/color-picker-Ddw80xX6.js +3 -0
  113. package/core/built/admin/assets/color-picker-field-D9nUhvA7.js +1 -0
  114. package/core/built/admin/assets/combobox-w9j8PPQT.js +1 -0
  115. package/core/built/admin/assets/command-BfpHORBv.js +1 -0
  116. package/core/built/admin/assets/comments-BLmCmyCs.js +1 -0
  117. package/core/built/admin/assets/confirmation-context-CBM8G0Vj.js +1 -0
  118. package/core/built/admin/assets/{container-LiZf3XdY.js → container-BuQG1wuP.js} +1 -1
  119. package/core/built/admin/assets/{content-api-modal-BtpNI92-.js → content-api-modal-TXRz3U7S.js} +1 -1
  120. package/core/built/admin/assets/context-menu-_QMdd3kp.js +1 -0
  121. package/core/built/admin/assets/{copy-field-CglgRZyG.js → copy-field-6N01S07E.js} +1 -1
  122. package/core/built/admin/assets/create-ghost-browse-value-source-qIBymvvf.js +1 -0
  123. package/core/built/admin/assets/custom-field-type-option-BddFlJFa.js +1 -0
  124. package/core/built/admin/assets/custom-integration-modal-DmNquxUV.js +1 -0
  125. package/core/built/admin/assets/{data-list-CupF7bjM.js → data-list-CA2jYGPq.js} +1 -1
  126. package/core/built/admin/assets/{date-range-select-JPwM0yUj.js → date-range-select-uvz_DtPh.js} +1 -1
  127. package/core/built/admin/assets/design-and-theme-modal-BSmo12Op.js +2 -0
  128. package/core/built/admin/assets/{detail-page-D8lx2SdP.js → detail-page-Dnv-CdR1.js} +1 -1
  129. package/core/built/admin/assets/dirty-confirm-dialog-BZ1iytEd.js +1 -0
  130. package/core/built/admin/assets/{disabled-sources-indicator-BTJ2ClQu.js → disabled-sources-indicator-DMRrxsiJ.js} +1 -1
  131. package/core/built/admin/assets/{dist-DzcfoDJ3.js → dist-8YJUlf3B.js} +1 -1
  132. package/core/built/admin/assets/{dist-Cb5RSHSg.js → dist-B3keLvjj.js} +1 -1
  133. package/core/built/admin/assets/dist-Dcsslyo72.js +1 -0
  134. package/core/built/admin/assets/{dist-BT_Z-eCn.js → dist-Dgt2cr6a.js} +1 -1
  135. package/core/built/admin/assets/domain-BNYrt0aD.js +1 -0
  136. package/core/built/admin/assets/dropzone-D7nFdAe5.js +5 -0
  137. package/core/built/admin/assets/edit-profile-C5Asm4LA.js +1 -0
  138. package/core/built/admin/assets/editor-REokrzci.js +8 -0
  139. package/core/built/admin/assets/{embed-signup-form-modal-BFTPf04i.js → embed-signup-form-modal-Ds6mPEi5.js} +1 -1
  140. package/core/built/admin/assets/{empty-indicator-WB1WgT9h.js → empty-indicator-D9QdpuNX.js} +1 -1
  141. package/core/built/admin/assets/en-B1jX3WMs.js +1 -0
  142. package/core/built/admin/assets/explore-UY10Egsp.js +1 -0
  143. package/core/built/admin/assets/feature-image-placeholder-D1iF_8bc.js +1 -0
  144. package/core/built/admin/assets/feed-81C8mJWR.js +1 -0
  145. package/core/built/admin/assets/{field-LmNk7wZh.js → field-Dihp5p18.js} +1 -1
  146. package/core/built/admin/assets/filter-bar-Da1qxybu.js +1 -0
  147. package/core/built/admin/assets/filter-sources-BO9xUPj7.js +1 -0
  148. package/core/built/admin/assets/filters-CRUWecfY.js +1 -0
  149. package/core/built/admin/assets/filters-DirqNXjH.js +1 -0
  150. package/core/built/admin/assets/first-promoter-modal-CT6MxYZb.js +1 -0
  151. package/core/built/admin/assets/{ghost-c8807202a07c20030acb719ee0114815.css → ghost-8eabfc1ece81b03cf7b90780d31487e8.css} +1 -1
  152. package/core/built/admin/assets/{ghost-403cb39badad3df411fc0ba27d220047.js → ghost-c2848508292937415f20f5a830eea59e.js} +31 -28
  153. package/core/built/admin/assets/{ghost-dark-fbf1e384aaef3ae315e540f0eb7373a7.css → ghost-dark-a7bebe2c561f55369dcf29f4c820f7ff.css} +1 -1
  154. package/core/built/admin/assets/gift-link-modal-CQVAye17.js +1 -0
  155. package/core/built/admin/assets/{grid-CUciBfjf.js → grid-Dj29PY05.js} +1 -1
  156. package/core/built/admin/assets/growth-BWIu-6xj.js +3 -0
  157. package/core/built/admin/assets/growth-DU29oxeA.js +1 -0
  158. package/core/built/admin/assets/{heading-CRZZ2FUe.js → heading-Dh5SFVjL.js} +1 -1
  159. package/core/built/admin/assets/history-modal-CFd1Hvx6.js +1 -0
  160. package/core/built/admin/assets/html-field-CJBCLTvv.js +1 -0
  161. package/core/built/admin/assets/{images-C0XvUYMb.js → images-scfkWZiK.js} +1 -1
  162. package/core/built/admin/assets/{inbox-DZXDUt4s.js → inbox-Mcp4DXZN.js} +14 -14
  163. package/core/built/admin/assets/index-6MkPdCtr.js +4 -0
  164. package/core/built/admin/assets/index-Bn7QhcZu.css +2 -0
  165. package/core/built/admin/assets/index.es-CNnuNH0d.js +1 -0
  166. package/core/built/admin/assets/{inline-Cw-gigDW.js → inline-BWSs_VzR.js} +1 -1
  167. package/core/built/admin/assets/{input-group-BPAxETpQ.js → input-group-CMhe2DvY.js} +1 -1
  168. package/core/built/admin/assets/{input-surface-BdOe4KzO.js → input-surface-BsrIZeSF.js} +1 -1
  169. package/core/built/admin/assets/{integration-header-B4DyXV06.js → integration-header-Bm6IDb1A.js} +1 -1
  170. package/core/built/admin/assets/invite-user-modal-DfheMXs0.js +1 -0
  171. package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +14 -14
  172. package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +3 -3
  173. package/core/built/admin/assets/koenig-lexical/style.css +1 -1
  174. package/core/built/admin/assets/{koenig-lexical-60O_8aiO.js → koenig-lexical-DBSqAuiI.js} +3 -3
  175. package/core/built/admin/assets/koenig-loader-aFQNlJlD.js +2 -0
  176. package/core/built/admin/assets/kpi-card-DBRMfGOW.js +1 -0
  177. package/core/built/admin/assets/{kpi-card-fUHZlzBX.js → kpi-card-DFafD1qq.js} +1 -1
  178. package/core/built/admin/assets/kpi-helpers-Cv8i8hns.js +1 -0
  179. package/core/built/admin/assets/kpi-tabs-BJItvLYm.js +1 -0
  180. package/core/built/admin/assets/{label-VIG969IC.js → label-BnSCvffu.js} +1 -1
  181. package/core/built/admin/assets/label-picker-KVoo91sh.js +1 -0
  182. package/core/built/admin/assets/layout-Bjv2Ll-5.js +1 -0
  183. package/core/built/admin/assets/{link-helpers-Dtq9fxQg.js → link-helpers-MVDdnFCY.js} +1 -1
  184. package/core/built/admin/assets/{list-page-CdsnQR9N.js → list-page-BucXJ0hi.js} +1 -1
  185. package/core/built/admin/assets/member-custom-fields-DDQV6QeG.js +1 -0
  186. package/core/built/admin/assets/member-detail-CdJF6Agw.js +1 -0
  187. package/core/built/admin/assets/members-DjQbq9Z2.js +4 -0
  188. package/core/built/admin/assets/{modal-page-BMTzFHVO.js → modal-page-xCivTMvI.js} +1 -1
  189. package/core/built/admin/assets/moderation-AgCIEso4.js +1 -0
  190. package/core/built/admin/assets/{multi-select-combobox-CGohnsxJ.js → multi-select-combobox-BcITkUVr.js} +1 -1
  191. package/core/built/admin/assets/navigation-modal-BkT7b1M2.js +1 -0
  192. package/core/built/admin/assets/newsletter-BMMAuvgq.js +1 -0
  193. package/core/built/admin/assets/newsletter-detail-modal-0SCJ7Zpm.js +1 -0
  194. package/core/built/admin/assets/{newsletter-emails-D5ql1rud.js → newsletter-emails-DKzwafuh.js} +1 -1
  195. package/core/built/admin/assets/newsletters-BRBb_uQC.js +1 -0
  196. package/core/built/admin/assets/note-DyGHtS9a.js +1 -0
  197. package/core/built/admin/assets/notifications-ZgWniKna.js +1 -0
  198. package/core/built/admin/assets/nql-BLpCn7qX.js +21 -0
  199. package/core/built/admin/assets/offers-container-modal-B-E8TIWr.js +1 -0
  200. package/core/built/admin/assets/{onboarding-B4YhlZ0i.js → onboarding-CzIsre-d.js} +1 -1
  201. package/core/built/admin/assets/onboarding-qg8Akovm.js +1 -0
  202. package/core/built/admin/assets/{onboarding-route-Cu_ROWPn.js → onboarding-route-CaavZulg.js} +1 -1
  203. package/core/built/admin/assets/overview-BW8GLeYi.js +1 -0
  204. package/core/built/admin/assets/overview-BkXZNzaZ.js +1 -0
  205. package/core/built/admin/assets/{page-header-Cfds8pCg.js → page-header-De0VzKBi.js} +1 -1
  206. package/core/built/admin/assets/pagemenu-B5KKCpbA.js +1 -0
  207. package/core/built/admin/assets/pages-jgaFm69d.js +1 -0
  208. package/core/built/admin/assets/pages-route-CIUAQxtY.js +1 -0
  209. package/core/built/admin/assets/papaparse.min-cQwnxGCG.js +10 -0
  210. package/core/built/admin/assets/{pintura-modal-TDTrJ89x.js → pintura-modal-BZ2J9w3n.js} +1 -1
  211. package/core/built/admin/assets/portal-frame-B6Hr9wHc.js +1 -0
  212. package/core/built/admin/assets/portal-modal-D4ceei3t.js +1 -0
  213. package/core/built/admin/assets/post-analytics-header-BYCsT0GP.js +1 -0
  214. package/core/built/admin/assets/post-analytics-ot7f6pih.js +1 -0
  215. package/core/built/admin/assets/{post-analytics-provider-Cu3jNeFh.js → post-analytics-provider-Bo1gmYaP.js} +1 -1
  216. package/core/built/admin/assets/{post-share-modal-P1_M6o-H.js → post-share-modal-C-PaYZ_e.js} +1 -1
  217. package/core/built/admin/assets/posts-DuGazgTb.js +1 -0
  218. package/core/built/admin/assets/posts-list-screen-CBGGgjjj.js +2 -0
  219. package/core/built/admin/assets/posts-route-D6xmS7Vf.js +1 -0
  220. package/core/built/admin/assets/preferences-C5YJLp74.js +5 -0
  221. package/core/built/admin/assets/{preview-chrome-BOVO6_PE.js → preview-chrome-BljUBlOk.js} +1 -1
  222. package/core/built/admin/assets/{preview-modal-MlTjP8UU.js → preview-modal-BfeFqi5y.js} +1 -1
  223. package/core/built/admin/assets/profile-B8mx2yAu.js +1 -0
  224. package/core/built/admin/assets/{radio-group-CjtmsCPl.js → radio-group-DczlLKOn.js} +1 -1
  225. package/core/built/admin/assets/{router-provider-CJC58zTy.js → router-provider-B0gZyiGJ.js} +1 -1
  226. package/core/built/admin/assets/{schemas-CRsC53ls.js → schemas-DppqmpeJ.js} +2 -2
  227. package/core/built/admin/assets/select-cb0t_TAJ.js +1 -0
  228. package/core/built/admin/assets/settings-DZqxR0Da.js +1 -0
  229. package/core/built/admin/assets/settings-DvfTNdHQ.js +4 -0
  230. package/core/built/admin/assets/{settings-breadcrumbs-sLDNedBW.js → settings-breadcrumbs-DLzbRRSt.js} +1 -1
  231. package/core/built/admin/assets/{shade-app-F7WxOyfk-nufqw1hd.js → shade-app-CcS3f8MZ-vwURazk8.js} +2 -2
  232. package/core/built/admin/assets/share-modal-D2-Bz1_I.js +1 -0
  233. package/core/built/admin/assets/{skeleton-D7hwjdry.js → skeleton-Ce9GgUpf.js} +1 -1
  234. package/core/built/admin/assets/slack-modal-DYDTUria.js +1 -0
  235. package/core/built/admin/assets/sort-button-VVeQjjbu.js +1 -0
  236. package/core/built/admin/assets/{source-icon-BPsD5ees.js → source-icon-Ck5_5Kgq.js} +1 -1
  237. package/core/built/admin/assets/{stack-CIfOAAVf.js → stack-B2eszIiq.js} +1 -1
  238. package/core/built/admin/assets/stats-Rjmk5owg.js +1 -0
  239. package/core/built/admin/assets/stats-view-BGGmkmgv.js +1 -0
  240. package/core/built/admin/assets/{step-1-CMta6YFO.js → step-1-CsaBjeN4.js} +1 -1
  241. package/core/built/admin/assets/{step-2-BG04nh5q.js → step-2-D2vnxOOM.js} +1 -1
  242. package/core/built/admin/assets/{step-3-ZnMaVIPj.js → step-3-wBoLdGEb.js} +2 -2
  243. package/core/built/admin/assets/{stripe-button-DDoUKN5a.js → stripe-button-CDgLz0S0.js} +1 -1
  244. package/core/built/admin/assets/stripe-connect-modal-CSjMJetP.js +1 -0
  245. package/core/built/admin/assets/{switch-C9djUIMO.js → switch-CI4gLWqb.js} +1 -1
  246. package/core/built/admin/assets/{table-CrqQtkR2.js → table-Do6iQ83Q.js} +1 -1
  247. package/core/built/admin/assets/{tabs-CGisSbWq.js → tabs-D2yWLMp_.js} +1 -1
  248. package/core/built/admin/assets/tag-detail-BhXlOsCa.js +2 -0
  249. package/core/built/admin/assets/tags-ldukRApe.js +1 -0
  250. package/core/built/admin/assets/testimonials-modal-CtnZBJKl.js +1 -0
  251. package/core/built/admin/assets/{text-DU9Hv33_.js → text-BQDSDsKs.js} +1 -1
  252. package/core/built/admin/assets/{textarea-d9qEkMOP.js → textarea-DJ1Q5V39.js} +1 -1
  253. package/core/built/admin/assets/tier-detail-modal-BOs8e_G8.js +1 -0
  254. package/core/built/admin/assets/{toggle-group-CtKZURJd.js → toggle-group-ByUJsxwD.js} +1 -1
  255. package/core/built/admin/assets/{topic-filter-D8JT8Tq1.js → topic-filter-BgC3g5_v.js} +1 -1
  256. package/core/built/admin/assets/{transistor-modal-6PUf0idx.js → transistor-modal-Drr0SNfo.js} +1 -1
  257. package/core/built/admin/assets/trend-badge-6ye93YAW.js +1 -0
  258. package/core/built/admin/assets/{unsplash-modal-BPuDBPja.js → unsplash-modal-p6AoQoWp.js} +1 -1
  259. package/core/built/admin/assets/{use-analytics-data--opuzwcz.js → use-analytics-data-CWCMAESo.js} +1 -1
  260. package/core/built/admin/assets/use-check-theme-limit-error-B8bjF-gO.css +1 -0
  261. package/core/built/admin/assets/use-check-theme-limit-error-Cw3WQHy8.js +2 -0
  262. package/core/built/admin/assets/use-filter-params-BIni9taJ.js +1 -0
  263. package/core/built/admin/assets/use-growth-stats-DCVG3s9w.js +1 -0
  264. package/core/built/admin/assets/{use-limiter-TDSNiHPB.js → use-limiter-D2WRRx0H.js} +1 -1
  265. package/core/built/admin/assets/{use-navigate-with-base-path-CK989MlC.js → use-navigate-with-base-path-BHPA228f.js} +1 -1
  266. package/core/built/admin/assets/{use-pintura-config-CnCGrDFk.js → use-pintura-config-h-J0Lvta.js} +1 -1
  267. package/core/built/admin/assets/{use-pintura-editor-ntphvtUd.js → use-pintura-editor-BfN1UwzH.js} +1 -1
  268. package/core/built/admin/assets/use-post-referrers-Czg47m8s.js +1 -0
  269. package/core/built/admin/assets/use-reply-chain-data-ns0caK8k.js +1 -0
  270. package/core/built/admin/assets/{use-router-history-entry-BwfQS2mq.js → use-router-history-entry-uldn7zJO.js} +1 -1
  271. package/core/built/admin/assets/{use-setting-group-DQxV42-O.js → use-setting-group-DpcuCUDg.js} +1 -1
  272. package/core/built/admin/assets/use-settings-navigation-CZjGrhsp.js +1 -0
  273. package/core/built/admin/assets/{use-simple-pagination-B2TdNX67.js → use-simple-pagination-DzJWobPR.js} +1 -1
  274. package/core/built/admin/assets/{use-staff-users-QrR9voeC.js → use-staff-users-Csipb-O0.js} +1 -1
  275. package/core/built/admin/assets/use-tinybird-query-CSnGXzZh.js +1 -0
  276. package/core/built/admin/assets/use-tinybird-token-DTOKRR7e.js +1 -0
  277. package/core/built/admin/assets/{use-unsaved-changes-guard-DpYJcj1d.js → use-unsaved-changes-guard-CBzs-KPi.js} +1 -1
  278. package/core/built/admin/assets/{use-url-input-WnIqckzS.js → use-url-input-DFr8lCbS.js} +1 -1
  279. package/core/built/admin/assets/user-detail-modal-B_iUClI6.js +1 -0
  280. package/core/built/admin/assets/users-Cg-OeGzC.js +1 -0
  281. package/core/built/admin/assets/{virtual-list-D3MfPNOh.js → virtual-list-BW-padMe.js} +1 -1
  282. package/core/built/admin/assets/web-C1v33ehA.js +2 -0
  283. package/core/built/admin/assets/web-C4BKzn2T.js +1 -0
  284. package/core/built/admin/assets/{zapier-modal-BO6PS_Vd.js → zapier-modal-BBFfI6Ml.js} +1 -1
  285. package/core/built/admin/index.html +24 -30
  286. package/core/frontend/apps/private-blogging/lib/views/private.hbs +44 -43
  287. package/core/frontend/helpers/cancel_link.js +2 -2
  288. package/core/frontend/helpers/pagination.js +2 -2
  289. package/core/frontend/helpers/social_accounts.js +2 -2
  290. package/core/frontend/public/ghost.css +1 -1
  291. package/core/frontend/public/ghost.min.css +1 -1
  292. package/core/frontend/services/rendering/renderer.js +15 -0
  293. package/core/frontend/services/sitemap/user-map-generator.js +9 -2
  294. package/core/server/adapters/storage/LocalStorageBase.js +8 -5
  295. package/core/server/api/endpoints/db.js +19 -5
  296. package/core/server/api/endpoints/index.js +6 -2
  297. package/core/server/api/endpoints/mail.js +1 -1
  298. package/core/server/api/endpoints/member-metafields.js +89 -0
  299. package/core/server/api/endpoints/members.js +4 -4
  300. package/core/server/api/endpoints/posts.js +4 -3
  301. package/core/server/api/endpoints/tiers-checkout-config.js +59 -0
  302. package/core/server/api/endpoints/utils/serializers/input/members.js +4 -7
  303. package/core/server/api/endpoints/utils/serializers/output/config.js +1 -0
  304. package/core/server/api/endpoints/utils/serializers/output/index.js +6 -2
  305. package/core/server/api/endpoints/utils/serializers/output/{member-custom-fields.js → member-metafields.js} +2 -4
  306. package/core/server/api/endpoints/utils/serializers/output/members.js +2 -4
  307. package/core/server/api/endpoints/utils/serializers/output/tiers-checkout-config.js +12 -0
  308. package/core/server/api/endpoints/utils/validators/input/invitations.js +0 -5
  309. package/core/server/api/endpoints/utils/validators/input/pages.js +1 -1
  310. package/core/server/api/endpoints/utils/validators/input/posts.js +1 -1
  311. package/core/server/data/exporter/table-lists.js +3 -0
  312. package/core/server/data/importer/content-files.js +57 -0
  313. package/core/server/data/importer/handlers/image.js +2 -2
  314. package/core/server/data/importer/import-archive.js +131 -0
  315. package/core/server/data/importer/import-manager.js +18 -180
  316. package/core/server/data/importer/importers/content-file-importer.js +66 -4
  317. package/core/server/data/importer/importers/data/data-importer.js +3 -3
  318. package/core/server/data/migrations/utils/migrations.js +1 -1
  319. 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
  320. package/core/server/data/migrations/versions/6.61/2026-08-19-14-38-53-add-members-custom-field-bindings-table.js +26 -0
  321. package/core/server/data/migrations/versions/6.61/2026-08-19-14-48-06-add-tier-checkout-field-tables.js +35 -0
  322. package/core/server/data/schema/schema.js +90 -0
  323. package/core/server/data/seeders/importers/automation-action-revisions-importer.js +3 -3
  324. package/core/server/data/seeders/importers/automation-actions-importer.js +3 -3
  325. package/core/server/data/seeders/importers/automation-run-steps-importer.js +3 -3
  326. package/core/server/data/seeders/importers/automation-runs-importer.js +5 -5
  327. package/core/server/data/seeders/importers/automations-importer.js +3 -3
  328. package/core/server/data/seeders/importers/comment-reports-importer.js +1 -1
  329. package/core/server/data/seeders/importers/comments-importer.js +1 -1
  330. package/core/server/data/seeders/importers/email-batches-importer.js +1 -1
  331. package/core/server/data/seeders/importers/email-recipients-importer.js +1 -1
  332. package/core/server/data/seeders/importers/emails-importer.js +1 -1
  333. package/core/server/data/seeders/importers/labels-importer.js +1 -1
  334. package/core/server/data/seeders/importers/members-click-events-importer.js +1 -1
  335. package/core/server/data/seeders/importers/members-created-events-importer.js +1 -1
  336. package/core/server/data/seeders/importers/members-feedback-importer.js +1 -1
  337. package/core/server/data/seeders/importers/members-importer.js +1 -1
  338. package/core/server/data/seeders/importers/members-login-events-importer.js +1 -1
  339. package/core/server/data/seeders/importers/members-products-importer.js +1 -1
  340. package/core/server/data/seeders/importers/members-status-events-importer.js +1 -1
  341. package/core/server/data/seeders/importers/members-stripe-customers-importer.js +1 -1
  342. package/core/server/data/seeders/importers/members-stripe-customers-subscriptions-importer.js +1 -1
  343. package/core/server/data/seeders/importers/members-subscribe-events-importer.js +1 -1
  344. package/core/server/data/seeders/importers/members-subscription-created-events-importer.js +1 -1
  345. package/core/server/data/seeders/importers/offer-redemptions-importer.js +1 -1
  346. package/core/server/data/seeders/importers/offers-importer.js +1 -1
  347. package/core/server/data/seeders/importers/posts-importer.js +1 -1
  348. package/core/server/data/seeders/importers/table-importer.js +2 -2
  349. package/core/server/data/seeders/importers/tags-importer.js +1 -1
  350. package/core/server/data/seeders/importers/users-importer.js +1 -1
  351. package/core/server/data/seeders/importers/web-mentions-importer.js +1 -1
  352. package/core/server/data/seeders/utils/random.js +3 -3
  353. package/core/server/ghost-server.js +3 -2
  354. package/core/server/lib/db-types/boolean.js +18 -0
  355. package/core/server/lib/image/image-size.js +24 -0
  356. package/core/server/lib/package-json/parse.js +2 -2
  357. package/core/server/lib/promise-pool.js +31 -0
  358. package/core/server/models/member.js +6 -17
  359. package/core/server/models/post.js +2 -2
  360. package/core/server/models/relations/authors.js +2 -16
  361. package/core/server/models/user.js +9 -2
  362. package/core/server/services/auth/passwordreset.js +13 -0
  363. package/core/server/services/automations/database-automations-repository.js +26 -26
  364. package/core/server/services/automations/poll.js +1 -0
  365. package/core/server/services/comments/comments-controller.js +30 -9
  366. package/core/server/services/comments/comments-service.js +55 -5
  367. package/core/server/services/content-import/csv/formula.js +12 -0
  368. package/core/server/services/content-import/csv/index.js +6 -1
  369. package/core/server/services/content-import/csv/parse.js +27 -6
  370. package/core/server/services/content-import/csv/serialize.js +13 -0
  371. package/core/server/services/content-import/import/assets.js +74 -0
  372. package/core/server/services/content-import/import/completion-email.js +164 -0
  373. package/core/server/services/content-import/import/errors-file.js +36 -0
  374. package/core/server/services/content-import/import/importer.js +204 -54
  375. package/core/server/services/content-import/import/local-media-url.js +63 -0
  376. package/core/server/services/content-import/import/media.js +254 -0
  377. package/core/server/services/content-import/import/post-data.js +1 -1
  378. package/core/server/services/content-import/import/post-link.js +11 -0
  379. package/core/server/services/content-import/import/post-repository.js +100 -0
  380. package/core/server/services/content-import/import/reader.js +9 -2
  381. package/core/server/services/content-import/import/relations.js +149 -0
  382. package/core/server/services/content-import/import/report.js +34 -0
  383. package/core/server/services/content-import/import/row.js +11 -2
  384. package/core/server/services/content-import/import/schema.js +30 -0
  385. package/core/server/services/content-import/import/source.js +125 -0
  386. package/core/server/services/content-import/import/staged-file.js +29 -0
  387. package/core/server/services/content-import/import/store.js +25 -2
  388. package/core/server/services/content-import/index.js +58 -34
  389. package/core/server/services/content-import/jobs/content-csv-import-job.js +20 -0
  390. package/core/server/services/custom-redirects/redirect-config-parser.js +2 -2
  391. package/core/server/services/custom-redirects/redirects-service.js +1 -1
  392. package/core/server/services/custom-redirects/validation.js +1 -1
  393. package/core/server/services/email-address/email-address-parser.js +30 -38
  394. package/core/server/services/email-address/email-address-service.js +37 -4
  395. package/core/server/services/email-analytics/email-analytics-service.js +8 -1
  396. package/core/server/services/email-analytics/index.js +2 -7
  397. package/core/server/services/email-analytics/lib/queries.js +7 -1
  398. package/core/server/services/email-service/batch-sending-service.js +0 -4
  399. package/core/server/services/email-service/email-renderer.js +14 -4
  400. package/core/server/services/email-service/email-service-wrapper.js +0 -9
  401. package/core/server/services/email-service/mailgun-email-provider.js +20 -9
  402. package/core/server/services/gift-links/schema.js +3 -3
  403. package/core/server/services/gifts/CONTEXT.md +1 -1
  404. package/core/server/services/gifts/constants.js +1 -1
  405. package/core/server/services/gifts/email-templates/gift-delivery.hbs +3 -3
  406. package/core/server/services/gifts/gift-bookshelf-repository.js +2 -2
  407. package/core/server/services/gifts/gift-delivery-bookshelf-repository.js +18 -9
  408. package/core/server/services/gifts/gift-delivery-schema.js +5 -5
  409. package/core/server/services/gifts/gift-delivery-service.js +4 -0
  410. package/core/server/services/gifts/gift-email-service.js +0 -1
  411. package/core/server/services/gifts/gift-schema.js +10 -10
  412. package/core/server/services/gifts/gift-service.js +4 -2
  413. package/core/server/services/gifts/index.js +3 -3
  414. package/core/server/services/gifts/jobs/index.js +4 -4
  415. package/core/server/services/indexnow-ping/indexnow-ping-service.js +2 -2
  416. package/core/server/services/invitations/accept.js +4 -2
  417. package/core/server/services/jobs/job-service.js +0 -9
  418. package/core/server/services/jobs-service/register-job-handlers.js +25 -15
  419. package/core/server/services/lib/mailgun-client.js +44 -8
  420. package/core/server/services/mail/ghost-mailer.js +4 -4
  421. package/core/server/services/media-inliner/external-media-inliner-job.js +12 -0
  422. package/core/server/services/media-inliner/external-media-inliner.js +103 -29
  423. package/core/server/services/media-inliner/service.js +13 -41
  424. package/core/server/services/media-inliner/types.js +2 -0
  425. package/core/server/services/member-welcome-emails/service.js +7 -7
  426. package/core/server/services/members/api.js +1 -0
  427. package/core/server/services/members/import-export/csv/parse.js +0 -7
  428. package/core/server/services/members/import-export/export/exporter.js +4 -6
  429. package/core/server/services/members/import-export/import/completion-email.js +2 -5
  430. package/core/server/services/members/import-export/import/importer.js +21 -5
  431. package/core/server/services/members/import-export/import/row.js +0 -3
  432. package/core/server/services/members/import-export/import/stripe-utils.js +6 -1
  433. package/core/server/services/members/import-export/index.js +10 -12
  434. package/core/server/services/members/jobs/clean-expired-comped-job.js +7 -0
  435. package/core/server/services/members/jobs/clean-expired-comped-task.js +145 -0
  436. package/core/server/services/members/jobs/index.js +48 -24
  437. package/core/server/services/members/members-api/controllers/member-controller.js +11 -0
  438. package/core/server/services/members/members-api/controllers/router-controller.js +3 -6
  439. package/core/server/services/members/members-api/members-api.js +9 -6
  440. package/core/server/services/members/members-api/repositories/event-repository.js +0 -4
  441. package/core/server/services/members/members-api/services/member-bread-service.js +53 -63
  442. package/core/server/services/members/members-api/services/payments-service.js +47 -1
  443. package/core/server/services/members/service.js +1 -5
  444. package/core/server/services/members-custom-fields/actions.js +27 -1
  445. package/core/server/services/members-custom-fields/bindings-service.js +120 -0
  446. package/core/server/services/members-custom-fields/codec.js +3 -4
  447. package/core/server/services/members-custom-fields/definitions-service.js +165 -22
  448. package/core/server/services/members-custom-fields/filter.js +75 -93
  449. package/core/server/services/members-custom-fields/index.js +11 -4
  450. package/core/server/services/members-custom-fields/key.js +2 -1
  451. package/core/server/services/members-custom-fields/models.js +1 -1
  452. package/core/server/services/members-custom-fields/queries.js +5 -0
  453. package/core/server/services/members-custom-fields/schema.js +37 -6
  454. package/core/server/services/members-custom-fields/serializers.js +3 -5
  455. package/core/server/services/members-custom-fields/values-service.js +65 -31
  456. package/core/server/services/mentions/mention-controller.js +23 -21
  457. package/core/server/services/mentions/process-webmention-job.js +16 -0
  458. package/core/server/services/mentions/service.js +8 -4
  459. package/core/server/services/public-config/config.js +7 -0
  460. package/core/server/services/route-settings/validation-errors.js +1 -1
  461. package/core/server/services/route-settings/yaml-parser.js +1 -1
  462. package/core/server/services/settings/settings-service.js +1 -8
  463. package/core/server/services/settings-helpers/settings-helpers.js +4 -6
  464. package/core/server/services/slack-ping/slack-ping-service.js +1 -1
  465. package/core/server/services/staff/staff-service-emails.js +2 -2
  466. package/core/server/services/stripe/config.js +14 -8
  467. package/core/server/services/stripe/service.js +10 -1
  468. package/core/server/services/stripe/services/checkout/completed-session.js +68 -0
  469. package/core/server/services/stripe/services/checkout/session-options.js +100 -0
  470. package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +71 -1
  471. package/core/server/services/stripe/stripe-api.js +31 -0
  472. package/core/server/services/stripe/stripe-service.js +26 -9
  473. package/core/server/services/stripe/webhook-controller.js +10 -0
  474. package/core/server/services/tier-checkout-config/codec.js +99 -0
  475. package/core/server/services/tier-checkout-config/index.js +26 -0
  476. package/core/server/services/tier-checkout-config/models.js +63 -0
  477. package/core/server/services/tier-checkout-config/queries.js +80 -0
  478. package/core/server/services/tier-checkout-config/schema.js +33 -0
  479. package/core/server/services/tier-checkout-config/serializers.js +128 -0
  480. package/core/server/services/tier-checkout-config/service.js +304 -0
  481. package/core/server/services/tiers/service.js +21 -0
  482. package/core/server/services/update-check/index.js +13 -13
  483. package/core/server/services/update-check/jobs/update-check-job.js +7 -0
  484. package/core/server/services/update-check/update-check-service.js +2 -2
  485. package/core/server/web/admin/controller.js +1 -1
  486. package/core/server/web/api/endpoints/admin/routes.js +34 -20
  487. package/core/server/web/api/middleware/upload.js +2 -2
  488. package/core/server/web/parent/app.js +5 -0
  489. package/core/server/web/parent/middleware/filter-query-parameters.js +94 -0
  490. package/core/server/web/parent/middleware/index.js +1 -0
  491. package/core/server/web/query-parameter-policy/index.js +9 -0
  492. package/core/server/web/query-parameter-policy/policy.json +58 -0
  493. package/core/server/web/query-parameter-policy/schema.js +38 -0
  494. package/core/shared/config/defaults.json +3 -0
  495. package/core/shared/config/env/config.testing-mysql.json +4 -1
  496. package/core/shared/config/env/config.testing.json +3 -0
  497. package/core/shared/config/overrides.json +4 -2
  498. package/core/shared/labs.js +9 -15
  499. package/package.json +25 -25
  500. package/pnpm-lock.yaml +741 -108
  501. package/pnpm-workspace.yaml +12 -9
  502. package/tsconfig.json +2 -3
  503. package/components/tryghost-kg-default-nodes-2.2.0.tgz +0 -0
  504. package/core/built/admin/assets/Combination-gnJO3vIw.js +0 -41
  505. package/core/built/admin/assets/account-migration-8qTEI1i1.js +0 -1
  506. package/core/built/admin/assets/activitypub/inbox-DQ5CwLma.js +0 -1284
  507. package/core/built/admin/assets/activitypub/label-B72sfvEU.js +0 -16
  508. package/core/built/admin/assets/activitypub/layout-CXajhRsL.js +0 -1
  509. package/core/built/admin/assets/activitypub/settings-71gCm3SO.js +0 -315
  510. package/core/built/admin/assets/add-integration-modal--YpTq3c0.js +0 -1
  511. package/core/built/admin/assets/add-newsletter-modal-C8Ix2hol.js +0 -1
  512. package/core/built/admin/assets/add-recommendation-modal-CScuNFz4.js +0 -1
  513. package/core/built/admin/assets/alert-dialog-wEbVxANM.js +0 -1
  514. package/core/built/admin/assets/analytics-Cnji45H5.js +0 -1
  515. package/core/built/admin/assets/app-utils-D2Wp7ZSS.js +0 -1
  516. package/core/built/admin/assets/audience-DTLMXAFH.js +0 -1
  517. package/core/built/admin/assets/automations-BWpRCZ_f.js +0 -1
  518. package/core/built/admin/assets/bluesky-sharing-DHOpQxff.js +0 -1
  519. package/core/built/admin/assets/chart-helpers-B3OqQ6Ez.js +0 -1
  520. package/core/built/admin/assets/color-picker-Bmo1r9Fc.js +0 -3
  521. package/core/built/admin/assets/color-picker-field-DywowPhF.js +0 -1
  522. package/core/built/admin/assets/combobox-C4QCh6Yw.js +0 -1
  523. package/core/built/admin/assets/command-DcLbSifC.js +0 -1
  524. package/core/built/admin/assets/comments-Bxy_3WyE.js +0 -1
  525. package/core/built/admin/assets/confirmation-context-CLFHhyyH.js +0 -1
  526. package/core/built/admin/assets/custom-field-type-option-D0PXoSnP.js +0 -10
  527. package/core/built/admin/assets/custom-integration-modal-DCIHKN33.js +0 -1
  528. package/core/built/admin/assets/design-and-theme-modal-CZ-PkW7o.js +0 -23
  529. package/core/built/admin/assets/dialog-Db7c164G.js +0 -1
  530. package/core/built/admin/assets/dirty-confirm-dialog-CmARpZQS.js +0 -1
  531. package/core/built/admin/assets/dist-QLZuGq7o2.js +0 -1
  532. package/core/built/admin/assets/domain-D0SAtc-T.js +0 -1
  533. package/core/built/admin/assets/dropzone-CaPOeDRZ.js +0 -5
  534. package/core/built/admin/assets/edit-profile-By7v5XW5.js +0 -1
  535. package/core/built/admin/assets/editor-COXn4Atu.js +0 -8
  536. package/core/built/admin/assets/explore-BsNYrubV.js +0 -1
  537. package/core/built/admin/assets/feed-8RR1O1bK.js +0 -1
  538. package/core/built/admin/assets/filter-sources-4C0kF1NU.js +0 -1
  539. package/core/built/admin/assets/filters-CV5jCb9n.js +0 -1
  540. package/core/built/admin/assets/filters-Dmr0PoqU.js +0 -1
  541. package/core/built/admin/assets/first-promoter-modal-OCzSaL3B.js +0 -1
  542. package/core/built/admin/assets/gift-link-modal-0mzjn5oF.js +0 -1
  543. package/core/built/admin/assets/growth-55vWlGT_.js +0 -1
  544. package/core/built/admin/assets/growth-DA5AluYw.js +0 -3
  545. package/core/built/admin/assets/history-modal-G1s5hHz7.js +0 -1
  546. package/core/built/admin/assets/html-field-BegxsWpw.js +0 -1
  547. package/core/built/admin/assets/index-CDP9tIOk.js +0 -4
  548. package/core/built/admin/assets/index-Dqf2x-ry.css +0 -1
  549. package/core/built/admin/assets/index.es-BMUCj9TR.js +0 -1
  550. package/core/built/admin/assets/input-UHrKuvBT.js +0 -1
  551. package/core/built/admin/assets/invite-user-modal-BrAkxEO3.js +0 -1
  552. package/core/built/admin/assets/koenig-loader-DwVY_V-H.js +0 -1
  553. package/core/built/admin/assets/kpi-card-LERqWBoY.js +0 -1
  554. package/core/built/admin/assets/kpi-helpers-DB3ouhYF.js +0 -1
  555. package/core/built/admin/assets/kpi-tabs-BGvtMD8S.js +0 -1
  556. package/core/built/admin/assets/label-picker-BBWykUeA.js +0 -1
  557. package/core/built/admin/assets/layout-Di5K7doM.js +0 -1
  558. package/core/built/admin/assets/loading-indicator-SFTqyYVE.js +0 -1
  559. package/core/built/admin/assets/member-custom-fields-gOv6Hoh3.js +0 -1
  560. package/core/built/admin/assets/member-detail-D7mZDDp3.js +0 -1
  561. package/core/built/admin/assets/member-route-0Aa52Ntz.js +0 -1
  562. package/core/built/admin/assets/members-DvZG9t69.js +0 -2
  563. package/core/built/admin/assets/moderation-DzzPLDyl.js +0 -1
  564. package/core/built/admin/assets/navigation-modal-CI8Bx5vn.js +0 -1
  565. package/core/built/admin/assets/newsletter-Bg3cq5U-.js +0 -1
  566. package/core/built/admin/assets/newsletter-detail-modal-DQU3r4g2.js +0 -1
  567. package/core/built/admin/assets/newsletters-DMDfZbMS.js +0 -1
  568. package/core/built/admin/assets/note-i8k6pjaw.js +0 -1
  569. package/core/built/admin/assets/notifications-psA_2Ph4.js +0 -1
  570. package/core/built/admin/assets/offers-container-modal-BWfjSdyg.js +0 -1
  571. package/core/built/admin/assets/onboarding-DGQuV7Ew.js +0 -1
  572. package/core/built/admin/assets/overview-C-6xOLaf.js +0 -1
  573. package/core/built/admin/assets/overview-DaLhpRrC.js +0 -1
  574. package/core/built/admin/assets/pages-B6vr9F_D.js +0 -1
  575. package/core/built/admin/assets/popover-CFgqFDvC.js +0 -1
  576. package/core/built/admin/assets/portal-frame-DjBF-uy2.js +0 -1
  577. package/core/built/admin/assets/portal-modal-Cf0pBAk8.js +0 -1
  578. package/core/built/admin/assets/post-analytics-Buz1COoY.js +0 -1
  579. package/core/built/admin/assets/post-analytics-header-B-P0eFnT.js +0 -1
  580. package/core/built/admin/assets/posts-KY3aUhVV.js +0 -1
  581. package/core/built/admin/assets/preferences-Cq1aOiLy.js +0 -5
  582. package/core/built/admin/assets/profile-D6dHYf2o.js +0 -1
  583. package/core/built/admin/assets/select-D_RQaXgt.js +0 -1
  584. package/core/built/admin/assets/settings-B5hJKZ5C.js +0 -1
  585. package/core/built/admin/assets/settings-DIo_F-MF.js +0 -4
  586. package/core/built/admin/assets/share-modal-CLBfj377.js +0 -1
  587. package/core/built/admin/assets/shim-ClF_m5ux.js +0 -1
  588. package/core/built/admin/assets/slack-modal-Bt9I_tEo.js +0 -1
  589. package/core/built/admin/assets/sort-button-DMBXF7tP.js +0 -1
  590. package/core/built/admin/assets/stats-B_YkF7bp.js +0 -1
  591. package/core/built/admin/assets/stats-view-BOCp9RG8.js +0 -1
  592. package/core/built/admin/assets/stripe-connect-modal-BeSukI8q.js +0 -1
  593. package/core/built/admin/assets/tag-detail-2a3BfzTW.js +0 -2
  594. package/core/built/admin/assets/tags-Dp2_8UzL.js +0 -1
  595. package/core/built/admin/assets/testimonials-modal-C9nrypNo.js +0 -1
  596. package/core/built/admin/assets/tier-detail-modal-CxRwgTPR.js +0 -1
  597. package/core/built/admin/assets/use-check-theme-limit-error-C9-QhGdV.js +0 -1
  598. package/core/built/admin/assets/use-filter-params-CSpAvgD2.js +0 -1
  599. package/core/built/admin/assets/use-growth-stats-BOmoPDHJ.js +0 -1
  600. package/core/built/admin/assets/use-post-referrers-CbXLFIex.js +0 -1
  601. package/core/built/admin/assets/use-reply-chain-data-JYFKSO83.js +0 -1
  602. package/core/built/admin/assets/use-settings-navigation-BBzro2-V.js +0 -1
  603. package/core/built/admin/assets/use-tinybird-query-D2Aeoty5.js +0 -39
  604. package/core/built/admin/assets/use-tinybird-token-DBuwMmln.js +0 -1
  605. package/core/built/admin/assets/user-detail-modal-59mBJqxN.js +0 -1
  606. package/core/built/admin/assets/users-5msE1WMs.js +0 -1
  607. package/core/built/admin/assets/web-DUuX7nE2.js +0 -2
  608. package/core/built/admin/assets/web-N8ucs2aG.js +0 -1
  609. package/core/server/api/endpoints/member-custom-fields.js +0 -100
  610. package/core/server/services/jobs/worker-model-event-bridge.js +0 -149
  611. package/core/server/services/members/jobs/clean-expired-comped.js +0 -132
  612. package/core/server/services/update-check/run-update-check.js +0 -63
  613. /package/core/server/lib/{db-date.js → db-types/date.js} +0 -0
@@ -3,12 +3,17 @@ const path = require('path');
3
3
  const dbBackup = require('../../data/db/backup');
4
4
  const exporter = require('../../data/exporter');
5
5
  const importer = require('../../data/importer');
6
- const mediaInliner = require('../../services/media-inliner');
6
+ const jobsService = require('../../services/jobs-service');
7
+ const ExternalMediaInlinerJob =
8
+ require('../../services/media-inliner/external-media-inliner-job').default;
7
9
  const errors = require('@tryghost/errors');
8
- const { pool } = require('@tryghost/promise');
10
+ const logging = require('@tryghost/logging');
11
+ const { promisePool } = require('../../lib/promise-pool');
9
12
  const models = require('../../models');
10
13
  const settingsCache = require('../../../shared/settings-cache');
11
14
 
15
+ const DEFAULT_MEDIA_INLINER_DOMAINS = ['https://s3.amazonaws.com/revue', 'https://substackcdn.com'];
16
+
12
17
  /** @type {import('@tryghost/api-framework').Controller} */
13
18
  const controller = {
14
19
  docName: 'db',
@@ -125,7 +130,16 @@ const controller = {
125
130
  },
126
131
  },
127
132
  async query(frame) {
128
- return mediaInliner.api.startMediaInliner(frame.data.domains);
133
+ const domains = frame.data.domains?.length
134
+ ? frame.data.domains
135
+ : DEFAULT_MEDIA_INLINER_DOMAINS;
136
+
137
+ logging.info('[Background Job] external-media-inliner queued');
138
+ await jobsService.getInstance().dispatch(new ExternalMediaInlinerJob({ domains }));
139
+
140
+ return {
141
+ status: 'success',
142
+ };
129
143
  },
130
144
  },
131
145
 
@@ -157,7 +171,7 @@ const controller = {
157
171
  try {
158
172
  const allPosts = await models.Post.findAll(queryOpts);
159
173
 
160
- await pool(
174
+ await promisePool(
161
175
  allPosts.map((post) => () => {
162
176
  return models.Post.destroy(Object.assign({ id: post.id }, queryOpts));
163
177
  }),
@@ -166,7 +180,7 @@ const controller = {
166
180
 
167
181
  const allTags = await models.Tag.findAll(queryOpts);
168
182
 
169
- await pool(
183
+ await promisePool(
170
184
  allTags.map((tag) => () => {
171
185
  return models.Tag.destroy(Object.assign({ id: tag.id }, queryOpts));
172
186
  }),
@@ -112,8 +112,12 @@ module.exports = {
112
112
  return apiFramework.pipeline(require('./members'), localUtils);
113
113
  },
114
114
 
115
- get membersCustomFields() {
116
- return apiFramework.pipeline(require('./member-custom-fields'), localUtils);
115
+ get membersMetafields() {
116
+ return apiFramework.pipeline(require('./member-metafields'), localUtils);
117
+ },
118
+
119
+ get tiersCheckoutConfig() {
120
+ return apiFramework.pipeline(require('./tiers-checkout-config'), localUtils);
117
121
  },
118
122
 
119
123
  get memberCommenting() {
@@ -25,7 +25,7 @@ _private.sendMail = (object) => {
25
25
  message: [
26
26
  tpl(messages.unableToSendEmail),
27
27
  tpl(messages.seeLinkForInstructions, {
28
- link: 'https://ghost.org/docs/concepts/config/#mail',
28
+ link: 'https://docs.ghost.org/concepts/config/#mail',
29
29
  }),
30
30
  ].join(' '),
31
31
  },
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const members_custom_fields_1 = require("../../services/members-custom-fields");
4
+ const permissionsService = require('../../services/permissions');
5
+ // With `permissions: true` the framework checks against the Bookshelf model named after
6
+ // the resource. These fields have no Bookshelf model, so each handler asks the permissions
7
+ // service directly.
8
+ function canThis(frame) {
9
+ return permissionsService.canThis(frame.options.context);
10
+ }
11
+ const noCacheInvalidation = { cacheInvalidate: false };
12
+ const controller = {
13
+ docName: 'members_metafields',
14
+ browse: {
15
+ headers: noCacheInvalidation,
16
+ options: ['namespace', 'filter'],
17
+ validation: { options: { namespace: { required: true } } },
18
+ permissions(frame) {
19
+ return canThis(frame).browse.member_custom_field();
20
+ },
21
+ query(frame) {
22
+ return members_custom_fields_1.definitions.browse({
23
+ namespace: frame.options.namespace,
24
+ filter: frame.options.filter,
25
+ });
26
+ },
27
+ },
28
+ read: {
29
+ headers: noCacheInvalidation,
30
+ options: ['namespace', 'key'],
31
+ validation: { options: { namespace: { required: true }, key: { required: true } } },
32
+ permissions(frame) {
33
+ return canThis(frame).read.member_custom_field(frame.options.key);
34
+ },
35
+ query(frame) {
36
+ return members_custom_fields_1.definitions.read(frame.options.namespace, frame.options.key);
37
+ },
38
+ },
39
+ add: {
40
+ statusCode: 201,
41
+ headers: noCacheInvalidation,
42
+ options: ['namespace'],
43
+ validation: { options: { namespace: { required: true } } },
44
+ permissions(frame) {
45
+ return canThis(frame).add.member_custom_field();
46
+ },
47
+ query(frame) {
48
+ return members_custom_fields_1.definitions.add((0, members_custom_fields_1.actingContext)(frame.options.context), frame.options.namespace, frame.data.members_metafields);
49
+ },
50
+ },
51
+ reorder: {
52
+ headers: noCacheInvalidation,
53
+ options: ['namespace'],
54
+ validation: { options: { namespace: { required: true } } },
55
+ permissions(frame) {
56
+ return canThis(frame).edit.member_custom_field();
57
+ },
58
+ query(frame) {
59
+ return members_custom_fields_1.definitions.reorder((0, members_custom_fields_1.actingContext)(frame.options.context), frame.options.namespace, frame.data.members_metafields);
60
+ },
61
+ },
62
+ edit: {
63
+ headers: noCacheInvalidation,
64
+ options: ['namespace', 'key'],
65
+ validation: { options: { namespace: { required: true }, key: { required: true } } },
66
+ permissions(frame) {
67
+ return canThis(frame).edit.member_custom_field(frame.options.key);
68
+ },
69
+ query(frame) {
70
+ return members_custom_fields_1.definitions.edit((0, members_custom_fields_1.actingContext)(frame.options.context), frame.options.namespace, frame.options.key, frame.data.members_metafields[0]);
71
+ },
72
+ },
73
+ destroy: {
74
+ statusCode: 204,
75
+ headers: noCacheInvalidation,
76
+ options: ['namespace', 'key'],
77
+ validation: { options: { namespace: { required: true }, key: { required: true } } },
78
+ permissions(frame) {
79
+ return canThis(frame).destroy.member_custom_field(frame.options.key);
80
+ },
81
+ async query(frame) {
82
+ await members_custom_fields_1.definitions.destroy((0, members_custom_fields_1.actingContext)(frame.options.context), frame.options.namespace, frame.options.key);
83
+ return null;
84
+ },
85
+ },
86
+ };
87
+ // The API framework loads this file with `require()`, so it exports CommonJS-style;
88
+ // `export default` would not be picked up.
89
+ module.exports = controller;
@@ -44,10 +44,10 @@ const messages = {
44
44
  resourceNotFound: '{resource} not found.',
45
45
  };
46
46
 
47
- // `custom_fields` is a browse include only: a read returns values whenever the
48
- // flag is on, the same way it returns tiers. Values are not a member relation, so
49
- // the input serializer lifts the key out of withRelated before the model sees it.
50
- const allowedIncludes = ['email_recipients', 'products', 'tiers', 'custom_fields'];
47
+ // `metafields` is not a relation on the member model. It is allowed here only so callers
48
+ // can ask for it with `include=`; the input serializer removes it before the model tries
49
+ // to eager-load it.
50
+ const allowedIncludes = ['email_recipients', 'products', 'tiers', 'metafields'];
51
51
 
52
52
  /** @type {import('@tryghost/api-framework').Controller} */
53
53
  const controller = {
@@ -129,12 +129,13 @@ const controller = {
129
129
  method: 'importContent',
130
130
  },
131
131
  async query(frame) {
132
- // The CSV must be parsed before the response goes out: the uploaded temp file is
133
- // deleted as soon as it is sent. The posts are written by a background job behind
134
- // the 202.
132
+ // The content-import service stages and validates the upload before this response;
133
+ // Multer deletes the request temp file as soon as the 202 is sent.
135
134
  const { importId, total } = await contentImportService.importCSV({
136
135
  filePath: frame.file.path,
136
+ fileName: frame.file.name,
137
137
  mapping: frame.data.mapping,
138
+ requestUserEmail: frame.user ? frame.user.get('email') : null,
138
139
  });
139
140
  return { meta: { import_id: importId, total } };
140
141
  },
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const members_custom_fields_1 = require("../../services/members-custom-fields");
4
+ const tier_checkout_config_1 = require("../../services/tier-checkout-config");
5
+ const tiersService = require('../../services/tiers');
6
+ /**
7
+ * Reads one tier's checkout settings for the API to return.
8
+ *
9
+ * The service answers with null when nobody has ever set up checkout for the tier, because
10
+ * there is genuinely nothing stored for it. The API still answers with a resource: the tier
11
+ * itself exists, so a client asking what it collects should be told "nothing" in the same
12
+ * shape as any other answer, rather than getting a 404 or an empty body to puzzle over.
13
+ */
14
+ async function forTier(id) {
15
+ return (await tiersService.checkout.read(id)) ?? (0, tier_checkout_config_1.emptyCheckoutConfig)(id);
16
+ }
17
+ /**
18
+ * A tier's checkout configuration, as a sub-resource of the tier rather than an attribute
19
+ * of it.
20
+ *
21
+ * The tier resource is generally available and this concept is not, so putting it on the
22
+ * tier payload would add a key to every tier response on every site whether or not the
23
+ * feature is on. A route of its own can carry the flag, and be removed with it.
24
+ *
25
+ * Every operation here is one call. A tier's configuration is one shape the service hands
26
+ * out and takes back, and that it spans tables, that destinations are site-wide, and that a
27
+ * binding exists at all are facts about the inside of that domain.
28
+ */
29
+ const controller = {
30
+ docName: 'tiers_checkout_config',
31
+ browse: {
32
+ headers: { cacheInvalidate: false },
33
+ permissions: { docName: 'products', method: 'browse' },
34
+ query() {
35
+ return tiersService.checkout.browse();
36
+ },
37
+ },
38
+ read: {
39
+ headers: { cacheInvalidate: false },
40
+ options: ['id'],
41
+ validation: { options: { id: { required: true } } },
42
+ permissions: { docName: 'products', method: 'read' },
43
+ async query(frame) {
44
+ return [await forTier(frame.options.id)];
45
+ },
46
+ },
47
+ edit: {
48
+ headers: { cacheInvalidate: true },
49
+ options: ['id'],
50
+ validation: { options: { id: { required: true } } },
51
+ permissions: { docName: 'products', method: 'edit' },
52
+ async query(frame) {
53
+ await tiersService.checkout.edit((0, members_custom_fields_1.actingContext)(frame.options.context), frame.options.id, frame.data.tiers_checkout_config?.[0] ?? {});
54
+ return [await forTier(frame.options.id)];
55
+ },
56
+ },
57
+ };
58
+ // module.exports (not export): the API framework loads controllers via require().
59
+ module.exports = controller;
@@ -34,16 +34,13 @@ function mapSubscribedFlagToNewsletterRelation(frame) {
34
34
  });
35
35
  }
36
36
 
37
- // Values are not a member relation — they're stored per field type and read by
38
- // the custom fields service — so `include=custom_fields` must not reach the model
39
- // layer as something to eager-load. Lift it out and leave a flag browse can act on.
40
- function liftCustomFieldsInclude(frame) {
41
- if (!frame.options.withRelated.includes('custom_fields')) {
37
+ function liftMetafieldsInclude(frame) {
38
+ if (!frame.options.withRelated.includes('metafields')) {
42
39
  return;
43
40
  }
44
41
 
45
42
  frame.options.withRelated = frame.options.withRelated.filter(
46
- (relation) => relation !== 'custom_fields',
43
+ (relation) => relation !== 'metafields',
47
44
  );
48
45
  frame.options.includeCustomFields = true;
49
46
  }
@@ -54,7 +51,7 @@ module.exports = {
54
51
  return;
55
52
  }
56
53
 
57
- liftCustomFieldsInclude(frame);
54
+ liftMetafieldsInclude(frame);
58
55
 
59
56
  frame.options.withRelated = frame.options.withRelated.map((relation) => {
60
57
  if (relation === 'tiers') {
@@ -25,6 +25,7 @@ module.exports = {
25
25
  'security',
26
26
  'exploreTestimonialsUrl',
27
27
  'featurebase',
28
+ 'docsbot',
28
29
  ];
29
30
 
30
31
  frame.response = {
@@ -76,14 +76,18 @@ module.exports = {
76
76
  return require('./members');
77
77
  },
78
78
 
79
- get members_custom_fields() {
80
- return require('./member-custom-fields');
79
+ get members_metafields() {
80
+ return require('./member-metafields');
81
81
  },
82
82
 
83
83
  get tiers() {
84
84
  return require('./tiers');
85
85
  },
86
86
 
87
+ get tiers_checkout_config() {
88
+ return require('./tiers-checkout-config');
89
+ },
90
+
87
91
  get images() {
88
92
  return require('./images');
89
93
  },
@@ -7,13 +7,11 @@ const serializeOne = (field, _apiConfig, frame) => {
7
7
  const serializeMany = (fields, _apiConfig, frame) => {
8
8
  frame.response = serializers_1.toCustomFieldsResponse.parse(fields);
9
9
  };
10
- // module.exports (not export): the API framework loads serializers via require(). The endpoint ->
11
- // serializer mapping lives here; the response shaping lives with the members-custom-fields service.
10
+ // The API framework loads this file with `require()`, so it exports CommonJS-style;
11
+ // `export default` would not be picked up.
12
12
  module.exports = {
13
13
  browse: serializeMany,
14
14
  read: serializeOne,
15
- // Create is a batch, so it returns every definition it made. The response is
16
- // already an array, so a one-item create looks exactly as it did before.
17
15
  add: serializeMany,
18
16
  reorder: serializeMany,
19
17
  edit: serializeOne,
@@ -131,10 +131,8 @@ function serializeMember(member, options) {
131
131
  serialized.tiers = json.products;
132
132
  }
133
133
 
134
- // Present on a read whenever the flag is on; absent otherwise, and absent on
135
- // browse. An empty object is a member with no values set.
136
- if (json.custom_fields) {
137
- serialized.custom_fields = json.custom_fields;
134
+ if (json.metafields) {
135
+ serialized.metafields = json.metafields;
138
136
  }
139
137
 
140
138
  serialized.current_subscription = json.current_subscription || null;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tier_checkout_config_1 = require("../../../../../services/tier-checkout-config");
4
+ const serialize = (configs, _apiConfig, frame) => {
5
+ frame.response = tier_checkout_config_1.toCheckoutConfigResponse.parse(configs);
6
+ };
7
+ // module.exports (not export): the API framework loads serializers via require().
8
+ module.exports = {
9
+ browse: serialize,
10
+ read: serialize,
11
+ edit: serialize,
12
+ };
@@ -4,7 +4,6 @@ const tpl = require('@tryghost/tpl');
4
4
  const errors = require('@tryghost/errors');
5
5
 
6
6
  const messages = {
7
- noEmailProvided: 'No email provided.',
8
7
  noNameProvided: 'No name provided.',
9
8
  noPasswordProvided: 'No password provided.',
10
9
  noTokenProvided: 'No token provided.',
@@ -21,10 +20,6 @@ module.exports = {
21
20
  return Promise.reject(new errors.ValidationError({ message: tpl(messages.noTokenProvided) }));
22
21
  }
23
22
 
24
- if (!data.email) {
25
- return Promise.reject(new errors.ValidationError({ message: tpl(messages.noEmailProvided) }));
26
- }
27
-
28
23
  if (!data.password) {
29
24
  return Promise.reject(
30
25
  new errors.ValidationError({ message: tpl(messages.noPasswordProvided) }),
@@ -8,7 +8,7 @@ const messages = {
8
8
  onlySingleContentSource: 'Pages can have either a mobiledoc or a lexical property, never both.',
9
9
  onlySingleContentSourceContext:
10
10
  'Both the mobiledoc and lexical properties are set, one must be null',
11
- onlySingleContentSourceHelp: 'https://ghost.org/docs/admin-api/#the-post-object',
11
+ onlySingleContentSourceHelp: 'https://docs.ghost.org/admin-api/#the-post-object',
12
12
  };
13
13
 
14
14
  const validateVisibility = async function (frame) {
@@ -8,7 +8,7 @@ const messages = {
8
8
  onlySingleContentSource: 'Posts can have either a mobiledoc or a lexical property, never both.',
9
9
  onlySingleContentSourceContext:
10
10
  'Both the mobiledoc and lexical properties are set, one must be null',
11
- onlySingleContentSourceHelp: 'https://ghost.org/docs/admin-api/#the-post-object',
11
+ onlySingleContentSourceHelp: 'https://docs.ghost.org/admin-api/#the-post-object',
12
12
  };
13
13
 
14
14
  const validateVisibility = async function (frame) {
@@ -44,6 +44,9 @@ const BACKUP_TABLES = [
44
44
  'members_newsletters',
45
45
  'members_custom_fields',
46
46
  'members_custom_field_values',
47
+ 'members_custom_field_bindings',
48
+ 'products_checkout_fields',
49
+ 'products_checkout_config',
47
50
  'mentions',
48
51
  'comments',
49
52
  'comment_likes',
@@ -0,0 +1,57 @@
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.createContentFileHandlers = createContentFileHandlers;
7
+ exports.createContentFileImporters = createContentFileImporters;
8
+ const config_1 = __importDefault(require("../../../shared/config"));
9
+ const url_utils_1 = __importDefault(require("../../../shared/url-utils"));
10
+ // Keep adapter loading on the existing CommonJS path so the configured adapter
11
+ // and its base class share the same module instance during the legacy /db/ import.
12
+ const adapterManager = require('../../services/adapter-manager').default;
13
+ const ImageHandler = require('./handlers/image');
14
+ const ImporterContentFileHandler = require('./handlers/importer-content-file-handler');
15
+ const ContentFileImporter = require('./importers/content-file-importer');
16
+ function createContentFileHandlers() {
17
+ const mediaStorage = adapterManager.getAdapter('storage:media');
18
+ const fileStorage = adapterManager.getAdapter('storage:files');
19
+ return [
20
+ ImageHandler,
21
+ new ImporterContentFileHandler({
22
+ type: 'media',
23
+ // These broad directory names preserve the existing /db/ archive behavior.
24
+ directories: ['media', 'content'],
25
+ ignoreRootFolderFiles: true,
26
+ extensions: config_1.default.get('uploads').media.extensions,
27
+ contentTypes: config_1.default.get('uploads').media.contentTypes,
28
+ urlUtils: url_utils_1.default,
29
+ storage: mediaStorage,
30
+ }),
31
+ new ImporterContentFileHandler({
32
+ type: 'files',
33
+ directories: ['files', 'content'],
34
+ ignoreRootFolderFiles: true,
35
+ extensions: config_1.default.get('uploads').files.extensions,
36
+ contentTypes: config_1.default.get('uploads').files.contentTypes,
37
+ urlUtils: url_utils_1.default,
38
+ storage: fileStorage,
39
+ }),
40
+ ];
41
+ }
42
+ function createContentFileImporters() {
43
+ return [
44
+ new ContentFileImporter({
45
+ type: 'images',
46
+ store: adapterManager.getAdapter('storage:images'),
47
+ }),
48
+ new ContentFileImporter({
49
+ type: 'media',
50
+ store: adapterManager.getAdapter('storage:media'),
51
+ }),
52
+ new ContentFileImporter({
53
+ type: 'files',
54
+ store: adapterManager.getAdapter('storage:files'),
55
+ }),
56
+ ];
57
+ }
@@ -30,7 +30,7 @@ ImageHandler = {
30
30
 
31
31
  file.originalPath = noBaseDir;
32
32
  file.name = noGhostDirs;
33
- file.targetDir = path.join(config.getContentPath('images'), path.dirname(noGhostDirs));
33
+ file.targetDir = path.join(store.storagePath, path.dirname(noGhostDirs));
34
34
  return file;
35
35
  });
36
36
 
@@ -41,7 +41,7 @@ ImageHandler = {
41
41
  '/',
42
42
  urlUtils.getSubdir(),
43
43
  store.staticFileURLPrefix,
44
- path.relative(config.getContentPath('images'), targetFilename),
44
+ path.relative(store.storagePath, targetFilename),
45
45
  );
46
46
 
47
47
  return image;
@@ -0,0 +1,131 @@
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
+ const node_crypto_1 = __importDefault(require("node:crypto"));
7
+ const node_os_1 = __importDefault(require("node:os"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const fs_extra_1 = __importDefault(require("fs-extra"));
10
+ const glob_1 = require("glob");
11
+ const { extract } = require('@tryghost/zip');
12
+ const tpl = require('@tryghost/tpl');
13
+ const errors = require('@tryghost/errors');
14
+ const messages = {
15
+ noContentToImport: 'Zip did not include any content to import.',
16
+ invalidZipStructure: 'Invalid zip file structure.',
17
+ invalidZipFileBaseDirectory: 'Invalid zip file: base directory read failed',
18
+ invalidZipFileNameEncoding: 'The uploaded zip could not be read',
19
+ invalidZipFileNameEncodingContext: 'The filename was too long or contained invalid characters',
20
+ invalidZipFileNameEncodingHelp: 'Remove any special characters from the file name, or alternatively try another archiving tool if using MacOS Archive Utility',
21
+ };
22
+ const ROOT_ONLY = 0;
23
+ const ROOT_OR_SINGLE_DIR = 1;
24
+ const ALL_DIRS = 2;
25
+ class ImportArchive {
26
+ extensions;
27
+ directories;
28
+ extractArchive;
29
+ constructor({ extensions, directories }, { extract: extractArchive = extract } = {}) {
30
+ this.extensions = extensions;
31
+ this.directories = directories;
32
+ this.extractArchive = extractArchive;
33
+ }
34
+ getGlobPattern(items) {
35
+ return `+(${items.join('|')})`;
36
+ }
37
+ getExtensionGlob(extensions, level) {
38
+ const prefix = level === ALL_DIRS ? '**/*' : level === ROOT_OR_SINGLE_DIR ? '{*/*,*}' : '*';
39
+ return prefix + this.getGlobPattern(extensions);
40
+ }
41
+ getDirectoryGlob(directories, level) {
42
+ const prefix = level === ALL_DIRS ? '**/' : level === ROOT_OR_SINGLE_DIR ? '{*/,}' : '';
43
+ return prefix + this.getGlobPattern(directories);
44
+ }
45
+ isValid(directory) {
46
+ const extMatchesBase = (0, glob_1.globSync)(this.getExtensionGlob(this.extensions, ROOT_OR_SINGLE_DIR), {
47
+ cwd: directory,
48
+ nocase: true,
49
+ });
50
+ const extMatchesAll = (0, glob_1.globSync)(this.getExtensionGlob(this.extensions, ALL_DIRS), {
51
+ cwd: directory,
52
+ nocase: true,
53
+ });
54
+ const dirMatches = this.directories.length
55
+ ? (0, glob_1.globSync)(this.getDirectoryGlob(this.directories, ROOT_OR_SINGLE_DIR), {
56
+ cwd: directory,
57
+ })
58
+ : [];
59
+ if (extMatchesBase.length > 0 || (dirMatches.length > 0 && extMatchesAll.length > 0)) {
60
+ return true;
61
+ }
62
+ if (extMatchesAll.length < 1) {
63
+ throw new errors.UnsupportedMediaTypeError({ message: tpl(messages.noContentToImport) });
64
+ }
65
+ throw new errors.UnsupportedMediaTypeError({ message: tpl(messages.invalidZipStructure) });
66
+ }
67
+ getBaseDirectory(directory) {
68
+ const extMatches = (0, glob_1.globSync)(this.getExtensionGlob(this.extensions, ROOT_ONLY), {
69
+ cwd: directory,
70
+ nocase: true,
71
+ });
72
+ const dirMatches = this.directories.length
73
+ ? (0, glob_1.globSync)(this.getDirectoryGlob(this.directories, ROOT_ONLY), {
74
+ cwd: directory,
75
+ nocase: true,
76
+ })
77
+ : [];
78
+ if (extMatches.length > 0 || dirMatches.length > 0) {
79
+ return;
80
+ }
81
+ const extMatchesAll = (0, glob_1.globSync)(this.getExtensionGlob(this.extensions, ALL_DIRS), {
82
+ cwd: directory,
83
+ nocase: true,
84
+ });
85
+ const firstMatch = extMatchesAll[0];
86
+ if (!firstMatch) {
87
+ throw new errors.ValidationError({ message: tpl(messages.invalidZipFileBaseDirectory) });
88
+ }
89
+ return firstMatch.split('/')[0];
90
+ }
91
+ getFiles(directory, extensions) {
92
+ const globPattern = this.getExtensionGlob(extensions, ALL_DIRS);
93
+ return (0, glob_1.globSync)(globPattern, { cwd: directory, nocase: true }).map((file) => ({
94
+ name: file,
95
+ path: node_path_1.default.join(directory, file),
96
+ }));
97
+ }
98
+ async extract(filePath) {
99
+ const tmpDir = node_path_1.default.join(node_os_1.default.tmpdir(), node_crypto_1.default.randomUUID());
100
+ try {
101
+ await this.extractArchive(filePath, tmpDir);
102
+ const files = (0, glob_1.globSync)('**/*', { cwd: tmpDir, nodir: true });
103
+ await Promise.all(files.map((file) => fs_extra_1.default.chmod(node_path_1.default.join(tmpDir, file), 0o644)));
104
+ }
105
+ catch (error) {
106
+ await fs_extra_1.default.remove(tmpDir).catch(() => { });
107
+ const message = messageOf(error);
108
+ if (message.startsWith('ENAMETOOLONG:')) {
109
+ throw new errors.UnsupportedMediaTypeError({
110
+ message: tpl(messages.invalidZipFileNameEncoding),
111
+ context: tpl(messages.invalidZipFileNameEncodingContext),
112
+ help: tpl(messages.invalidZipFileNameEncodingHelp),
113
+ code: 'INVALID_ZIP_FILE_NAME_ENCODING',
114
+ });
115
+ }
116
+ if (message.includes('end of central directory record signature not found') ||
117
+ message.includes('invalid comment length')) {
118
+ throw new errors.UnsupportedMediaTypeError({
119
+ message: tpl(messages.invalidZipFileNameEncoding),
120
+ code: 'INVALID_ZIP_FILE',
121
+ });
122
+ }
123
+ throw error;
124
+ }
125
+ return tmpDir;
126
+ }
127
+ }
128
+ exports.default = ImportArchive;
129
+ function messageOf(error) {
130
+ return error instanceof Error ? error.message : '';
131
+ }