ghost 6.54.0 → 6.54.1

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 (238) 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-scheduling-0.2.0.tgz +0 -0
  4. package/components/tryghost-adapter-base-sso-0.1.1.tgz +0 -0
  5. package/components/tryghost-kg-default-nodes-2.1.3.tgz +0 -0
  6. package/core/built/admin/assets/Growth-BTP1LthE.js +3 -0
  7. package/core/built/admin/assets/Newsletters-CSEX0myc.js +1 -0
  8. package/core/built/admin/assets/Overview-BjACEsJF.js +1 -0
  9. package/core/built/admin/assets/Web-CxxxjCcv.js +2 -0
  10. package/core/built/admin/assets/{account-migration-DLvVA5yq.js → account-migration-BklF2I_I.js} +1 -1
  11. package/core/built/admin/assets/activitypub/{account-migration-DHbZcxGM.js → account-migration-CNovr6W-.js} +4 -4
  12. package/core/built/admin/assets/activitypub/activitypub.js +2 -2
  13. package/core/built/admin/assets/activitypub/{bluesky-sharing-zfxUey_L.js → bluesky-sharing-Ceslb1_M.js} +4 -4
  14. package/core/built/admin/assets/activitypub/{dist-BqkDUQxJ2.js → dist-ByFmDSNP2.js} +64 -63
  15. package/core/built/admin/assets/activitypub/{dist-Ba_QxHHl.js → dist-DHAjBcV3.js} +2 -2
  16. package/core/built/admin/assets/activitypub/{domain-CmwSZLHK.js → domain-C1qQvJ8C.js} +5 -5
  17. package/core/built/admin/assets/activitypub/{edit-profile-CXdwNmVG.js → edit-profile-BcH-jEfM.js} +3 -3
  18. package/core/built/admin/assets/activitypub/{explore-DfbjzGM1.js → explore-AxwBh9dI.js} +3 -3
  19. package/core/built/admin/assets/activitypub/{feed-DSEBJOqf.js → feed-BaOlbh7a.js} +3 -3
  20. package/core/built/admin/assets/activitypub/{field-CY7XVcx6.js → field-B7mYYQpN.js} +2 -2
  21. package/core/built/admin/assets/activitypub/{inbox-DtQ0kytT.js → inbox-vXez-5uJ.js} +4 -4
  22. package/core/built/admin/assets/activitypub/{label-Dw96GQ7u.js → label-Chv5T8bw.js} +2 -2
  23. package/core/built/admin/assets/activitypub/layout-CziktJXo.js +1 -0
  24. package/core/built/admin/assets/activitypub/{moderation-Dg_-I-8C.js → moderation-DtSM2i1I.js} +4 -4
  25. package/core/built/admin/assets/activitypub/{note-Cy1-uKMY.js → note-Dckp4S-2.js} +3 -3
  26. package/core/built/admin/assets/activitypub/{notifications-B_fvoLIM.js → notifications-CG5T22vg.js} +3 -3
  27. package/core/built/admin/assets/activitypub/{preferences-ByJseZp6.js → preferences-D_799jdl.js} +6 -6
  28. package/core/built/admin/assets/activitypub/{profile-BFtbnIjz.js → profile-D2JfXBQl.js} +6 -6
  29. package/core/built/admin/assets/activitypub/{routes-Dh3xXfce.js → routes-CCHe2dQp.js} +28 -25
  30. package/core/built/admin/assets/activitypub/{settings-DTgqJPxM.js → settings-kx-9Enkz.js} +3 -3
  31. package/core/built/admin/assets/activitypub/{site-CdL9ZLqm.js → site-x4_IjVJ0.js} +2 -2
  32. package/core/built/admin/assets/activitypub/{tabs-ogqwoBlb.js → tabs-CyPRQQ1N.js} +3 -3
  33. package/core/built/admin/assets/activitypub/{use-reply-chain-data-CxonteFD.js → use-reply-chain-data-BAB6fNGt.js} +2 -2
  34. package/core/built/admin/assets/{audience-BKRdsFmy.js → audience-X_XsZivI.js} +1 -1
  35. package/core/built/admin/assets/{automated-emails-Cn87L5Md.js → automated-emails-of1MvVsv.js} +1 -1
  36. package/core/built/admin/assets/{automations-BP_aHamJ.js → automations-DRFjW5fw.js} +1 -1
  37. package/core/built/admin/assets/{bluesky-sharing-Bh36XPh4.js → bluesky-sharing-BbbjWdzs.js} +1 -1
  38. package/core/built/admin/assets/{breadcrumb-D34YWnaw.js → breadcrumb-B-M9Ip_2.js} +1 -1
  39. package/core/built/admin/assets/{chart-helpers-DbklaJw9.js → chart-helpers-xiSsW8r0.js} +1 -1
  40. package/core/built/admin/assets/checkbox-EhJKHFdZ.js +1 -0
  41. package/core/built/admin/assets/{chunk.962.b73442b07be930bb5d85.js → chunk.211.6f7328d63c41536451b3.js} +737 -559
  42. package/core/built/admin/assets/{chunk.962.b73442b07be930bb5d85.js.LICENSE.txt → chunk.211.6f7328d63c41536451b3.js.LICENSE.txt} +2 -0
  43. package/core/built/admin/assets/{chunk.589.096f4d0bb775e5229aa9.js → chunk.361.3cdb584b973959e52ccc.js} +3 -3
  44. package/core/built/admin/assets/chunk.524.8365cd9280405c0f6216.js +25 -0
  45. package/core/built/admin/assets/chunk.582.61d078937e6102769f2c.js +27 -0
  46. package/core/built/admin/assets/code-editor-view-CZtJFGhR.js +1 -0
  47. package/core/built/admin/assets/comments-CvyXxOyN.js +1 -0
  48. package/core/built/admin/assets/{date-range-select-B5vSsrpx.js → date-range-select-CTlyo8zW.js} +1 -1
  49. package/core/built/admin/assets/{disabled-sources-indicator-NkOIoMue.js → disabled-sources-indicator-qs2GfLvl.js} +1 -1
  50. package/core/built/admin/assets/dist-2Tnz2Yfq.js +1 -0
  51. package/core/built/admin/assets/dist-CjY-f5Z1.js +1 -0
  52. package/core/built/admin/assets/dist-DIC8yz5C.js +1 -0
  53. package/core/built/admin/assets/{domain-B7_n5nfx.js → domain-CPNXKVOV.js} +1 -1
  54. package/core/built/admin/assets/dropzone-BmCXnw6J.js +5 -0
  55. package/core/built/admin/assets/{edit-profile-rvDGrS8J.js → edit-profile-SGrJve5M.js} +1 -1
  56. package/core/built/admin/assets/editor-BOG2YPUm.js +8 -0
  57. package/core/built/admin/assets/{explore-BZAZOg5X.js → explore-CUYLv9G9.js} +1 -1
  58. package/core/built/admin/assets/{feed-CFV8xDw9.js → feed-CPdJMttL.js} +1 -1
  59. package/core/built/admin/assets/{field-BW-M2Zwp.js → field-D0XISCK2.js} +1 -1
  60. package/core/built/admin/assets/{filter-sources-Fx8wiYYw.js → filter-sources-Bieps75g.js} +1 -1
  61. package/core/built/admin/assets/{filters-CGX_pf2N.js → filters-CuB-A7ma.js} +1 -1
  62. package/core/built/admin/assets/filters-bXkkWro8.js +1 -0
  63. package/core/built/admin/assets/{ghost-b1dce91ad3232cc259ee5fbbf9526243.js → ghost-05f9a7182ed56903dba05878a5b8422b.js} +290 -289
  64. package/core/built/admin/assets/{gift-link-modal-Bk8qpnMw.js → gift-link-modal-su8MsRdg.js} +1 -1
  65. package/core/built/admin/assets/{growth-Ck2s3JjR.js → growth-Ba6S5FQX.js} +1 -1
  66. package/core/built/admin/assets/{inbox-BRp1_aaC.js → inbox-Xx1CdnfO.js} +8 -8
  67. package/core/built/admin/assets/index-D8PbzuT9.css +1 -0
  68. package/core/built/admin/assets/index-ukW_0Uie.js +67 -0
  69. package/core/built/admin/assets/input-group-CGOXcy4l.js +1 -0
  70. package/core/built/admin/assets/input-surface-BpAjZXY5.js +1 -0
  71. package/core/built/admin/assets/{koenig-lexical-CM7UFNdL.js → koenig-lexical-B61IALf5.js} +1 -1
  72. package/core/built/admin/assets/{kpi-card-CIGyijjx.js → kpi-card-BlZaG1Lo.js} +1 -1
  73. package/core/built/admin/assets/{kpi-card-BrGH6FsT.js → kpi-card-DCdlyaSS.js} +1 -1
  74. package/core/built/admin/assets/{kpi-helpers-_HRRsklE.js → kpi-helpers-DpAuS1Nb.js} +1 -1
  75. package/core/built/admin/assets/{kpi-tabs-BSvh9eoq.js → kpi-tabs-Dme44bQS.js} +1 -1
  76. package/core/built/admin/assets/{label-BOR9XdKl.js → label-dSs5aepE.js} +1 -1
  77. package/core/built/admin/assets/{label-picker-BdNAWuUX.js → label-picker-Uq91atex.js} +1 -1
  78. package/core/built/admin/assets/layout-WUcz6tu1.js +1 -0
  79. package/core/built/admin/assets/{member-custom-fields-DvFyamLu.js → member-custom-fields-NCzrMuba.js} +1 -1
  80. package/core/built/admin/assets/member-detail-DPWDtYnN.js +1 -0
  81. package/core/built/admin/assets/{members-DsPxYAVm.js → members-B9rO7qr4.js} +2 -2
  82. package/core/built/admin/assets/modals-CxRaan1J.js +31 -0
  83. package/core/built/admin/assets/{moderation-Dlp7M5sa.js → moderation-D8zon60E.js} +1 -1
  84. package/core/built/admin/assets/{multi-select-combobox-CH1o8XXQ.js → multi-select-combobox-1wYm3nle.js} +1 -1
  85. package/core/built/admin/assets/newsletter-DbYMRxRS.js +1 -0
  86. package/core/built/admin/assets/{note-BrAZ7Z0o.js → note-PiWPnnrh.js} +1 -1
  87. package/core/built/admin/assets/{notifications-BnbHLOPC.js → notifications-DEgqqB9G.js} +1 -1
  88. package/core/built/admin/assets/{onboarding-route-eU146kuA.js → onboarding-route-BzF6HeVn.js} +1 -1
  89. package/core/built/admin/assets/{overview-BpbaK-xu.js → overview-DixLeIqY.js} +1 -1
  90. package/core/built/admin/assets/{page-header-C0jVxtS8.js → page-header-op0eN36I.js} +1 -1
  91. package/core/built/admin/assets/{post-analytics-Iw7dk1mT.js → post-analytics-WwRDEnrV.js} +1 -1
  92. package/core/built/admin/assets/post-analytics-header-DsMoLx0R.js +1 -0
  93. package/core/built/admin/assets/{post-analytics-provider-BDqcfBor.js → post-analytics-provider-BJCPLMIb.js} +1 -1
  94. package/core/built/admin/assets/{post-share-modal-DBfKl2GZ.js → post-share-modal-Dx-MEjhI.js} +1 -1
  95. package/core/built/admin/assets/preferences-D7-j6A4C.js +5 -0
  96. package/core/built/admin/assets/profile-Dl69QPp0.js +1 -0
  97. package/core/built/admin/assets/select-C1qDZnW4.js +1 -0
  98. package/core/built/admin/assets/settings-BbmC_Iqq.js +4 -0
  99. package/core/built/admin/assets/{settings-Bz3RZRmE.js → settings-H6HxFgfI.js} +1 -1
  100. package/core/built/admin/assets/shade-app-B3heOAfz-CGXQwWeO.js +3 -0
  101. package/core/built/admin/assets/{share-modal-CkdTTMJd.js → share-modal-BJCadJyp.js} +1 -1
  102. package/core/built/admin/assets/social-urls-BPL1nADp.js +8 -0
  103. package/core/built/admin/assets/{sort-button-DZp9Y2r1.js → sort-button-DyYlfYp7.js} +1 -1
  104. package/core/built/admin/assets/{source-icon-CHr9qJ2Y.js → source-icon-_ubRDbg_.js} +1 -1
  105. package/core/built/admin/assets/{stats-DGoXZxWE.js → stats-BQZMGMvn.js} +1 -1
  106. package/core/built/admin/assets/{stats-view-D2-1L0ms.js → stats-view-Doei-qCX.js} +1 -1
  107. package/core/built/admin/assets/{step-1-RdahbwyG.js → step-1-IKiLBPoC.js} +1 -1
  108. package/core/built/admin/assets/{step-2-D83PeRwd.js → step-2-jJ41PsDN.js} +1 -1
  109. package/core/built/admin/assets/{step-3-p_Op4wv4.js → step-3-CaqFAEqf.js} +2 -2
  110. package/core/built/admin/assets/switch-t-WyENU2.js +1 -0
  111. package/core/built/admin/assets/{table-B8LgTQJZ.js → table-DxUL78jU.js} +1 -1
  112. package/core/built/admin/assets/{tabs-D3ZOYkM7.js → tabs-BQcJQ1ke.js} +1 -1
  113. package/core/built/admin/assets/{tags-B4l891z2.js → tags-CNujGwkT.js} +1 -1
  114. package/core/built/admin/assets/textarea-Bjccvh_E.js +1 -0
  115. package/core/built/admin/assets/{toggle-group-DNXDkAwf.js → toggle-group-BeEpQ69p.js} +1 -1
  116. package/core/built/admin/assets/{topic-filter-DZGjEcz3.js → topic-filter-Bb5MOD-1.js} +1 -1
  117. package/core/built/admin/assets/{use-analytics-data-CaT8RirX.js → use-analytics-data-Cds6XDjg.js} +1 -1
  118. package/core/built/admin/assets/use-filter-params-DjXkhO54.js +1 -0
  119. package/core/built/admin/assets/{use-growth-stats-9Db2CuJe.js → use-growth-stats-D8uf98-G.js} +1 -1
  120. package/core/built/admin/assets/{use-post-referrers-BV54YcQS.js → use-post-referrers-CRtgyuXB.js} +1 -1
  121. package/core/built/admin/assets/{use-reply-chain-data-DuYZGDan.js → use-reply-chain-data-DbKYX50v.js} +1 -1
  122. package/core/built/admin/assets/{use-simple-pagination-8fTua9Nt.js → use-simple-pagination-DC01kpo0.js} +1 -1
  123. package/core/built/admin/assets/{use-tinybird-query-Dz156HvZ.js → use-tinybird-query-C7bQRJWw.js} +1 -1
  124. package/core/built/admin/assets/{use-tinybird-token-C9RUdL_n.js → use-tinybird-token-Az4tam7_.js} +1 -1
  125. package/core/built/admin/assets/{virtual-list-BCvP0YF-.js → virtual-list-Dhuh9fGx.js} +1 -1
  126. package/core/built/admin/assets/web-LtHNiNBV.js +1 -0
  127. package/core/built/admin/index.html +11 -7
  128. package/core/frontend/services/proxy.js +11 -1
  129. package/core/server/adapters/storage/LocalFilesStorage.js +13 -11
  130. package/core/server/adapters/storage/LocalFilesStorage.ts +24 -0
  131. package/core/server/adapters/storage/LocalImagesStorage.js +14 -12
  132. package/core/server/adapters/storage/LocalImagesStorage.ts +24 -0
  133. package/core/server/adapters/storage/LocalMediaStorage.js +13 -11
  134. package/core/server/adapters/storage/LocalMediaStorage.ts +24 -0
  135. package/core/server/adapters/storage/LocalStorageBase.js +107 -167
  136. package/core/server/adapters/storage/LocalStorageBase.ts +342 -0
  137. package/core/server/adapters/storage/utils.js +36 -50
  138. package/core/server/adapters/storage/utils.ts +60 -0
  139. package/core/server/api/endpoints/db.js +6 -0
  140. package/core/server/api/endpoints/members.js +25 -28
  141. package/core/server/api/endpoints/pages.js +6 -1
  142. package/core/server/api/endpoints/posts.js +11 -2
  143. package/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +4 -1
  144. package/core/server/api/endpoints/utils/serializers/output/members.js +18 -87
  145. package/core/server/data/exporter/export-filename.js +2 -1
  146. package/core/server/data/importer/importers/data/revue-subscriber-importer.js +6 -10
  147. package/core/server/data/importer/importers/json-to-html.js +24 -4
  148. package/core/server/lib/image/image-size.js +3 -17
  149. package/core/server/lib/image/image-utils.js +15 -1
  150. package/core/server/lib/request-external.js +1 -1
  151. package/core/server/models/user.js +46 -70
  152. package/core/server/services/auth/session/session-service.js +28 -1
  153. package/core/server/services/automations/automations-api.js +6 -6
  154. package/core/server/services/automations/automations-api.ts +6 -6
  155. package/core/server/services/automations/automations-repository.ts +1 -0
  156. package/core/server/services/automations/database-automations-repository.js +7 -2
  157. package/core/server/services/automations/database-automations-repository.ts +8 -2
  158. package/core/server/services/comments/comments-service-emails.js +4 -1
  159. package/core/server/services/members/{importer → import-export}/config.js +4 -9
  160. package/core/server/services/members/{importer → import-export}/config.ts +4 -9
  161. package/core/server/services/members/{csv → import-export/csv}/index.js +3 -3
  162. package/core/server/services/members/import-export/csv/index.ts +2 -0
  163. package/core/server/services/members/import-export/csv/parse.js +64 -0
  164. package/core/server/services/members/import-export/csv/parse.ts +69 -0
  165. package/core/server/services/members/import-export/csv/serialize.js +13 -0
  166. package/core/server/services/members/import-export/csv/serialize.ts +18 -0
  167. package/core/server/services/members/import-export/export/exporter.js +202 -0
  168. package/core/server/services/members/import-export/export/exporter.ts +325 -0
  169. package/core/server/services/members/import-export/import/completion-email.js +65 -0
  170. package/core/server/services/members/import-export/import/completion-email.ts +119 -0
  171. package/core/server/services/members/import-export/import/importer.js +276 -0
  172. package/core/server/services/members/import-export/import/importer.ts +430 -0
  173. package/core/server/services/members/import-export/import/reader.js +32 -0
  174. package/core/server/services/members/import-export/import/reader.ts +33 -0
  175. package/core/server/services/members/import-export/import/row.js +33 -0
  176. package/core/server/services/members/import-export/import/row.ts +52 -0
  177. package/core/server/services/members/import-export/import/spool.js +30 -0
  178. package/core/server/services/members/import-export/import/spool.ts +38 -0
  179. package/core/server/services/members/import-export/index.js +90 -0
  180. package/core/server/services/members/import-export/index.ts +118 -0
  181. package/core/server/services/members/members-api/controllers/router-controller.js +7 -0
  182. package/core/server/services/members/service.js +17 -19
  183. package/core/server/services/posts/posts-exporter.js +6 -4
  184. package/core/server/services/posts/posts-service.js +2 -2
  185. package/core/server/services/themes/storage.js +9 -0
  186. package/core/server/services/themes/theme-storage.js +1 -1
  187. package/core/shared/config/defaults.json +2 -1
  188. package/core/shared/express.js +6 -1
  189. package/core/shared/labs.js +2 -1
  190. package/package.json +9 -9
  191. package/pnpm-lock.yaml +17 -17
  192. package/pnpm-workspace.yaml +7 -7
  193. package/components/tryghost-adapter-base-scheduling-0.1.1.tgz +0 -0
  194. package/core/built/admin/assets/Growth-CSaHoSVD.js +0 -3
  195. package/core/built/admin/assets/Newsletters-C5cs6FGo.js +0 -1
  196. package/core/built/admin/assets/Overview-j4NaeUNm.js +0 -1
  197. package/core/built/admin/assets/Web-_fD935OX.js +0 -2
  198. package/core/built/admin/assets/activitypub/layout-IdVq3lRy.js +0 -1
  199. package/core/built/admin/assets/checkbox-DA4-1UiI.js +0 -1
  200. package/core/built/admin/assets/chunk.524.45e0875f41b71e46e849.js +0 -25
  201. package/core/built/admin/assets/chunk.582.51defd4b009f0de8d4d5.js +0 -27
  202. package/core/built/admin/assets/code-editor-view-BKBrkffZ.js +0 -1
  203. package/core/built/admin/assets/comments-CzVNIT8b.js +0 -1
  204. package/core/built/admin/assets/dist-CT46_f_J.js +0 -1
  205. package/core/built/admin/assets/dropzone-DcuJEEUf.js +0 -5
  206. package/core/built/admin/assets/editor-BCiIyFjm.js +0 -8
  207. package/core/built/admin/assets/filters-DtcXMZDU.js +0 -1
  208. package/core/built/admin/assets/index-BBf502Wg.js +0 -69
  209. package/core/built/admin/assets/index-BCCZKxP2.css +0 -1
  210. package/core/built/admin/assets/input-group-DjuYnNCd.js +0 -1
  211. package/core/built/admin/assets/layout-Bw4GnxXp.js +0 -1
  212. package/core/built/admin/assets/member-detail-Cg2vTqvJ.js +0 -1
  213. package/core/built/admin/assets/modals-Bf_fyvHZ.js +0 -31
  214. package/core/built/admin/assets/newsletter-CQ5CAYUI.js +0 -1
  215. package/core/built/admin/assets/post-analytics-header-D9pJ4iNm.js +0 -1
  216. package/core/built/admin/assets/preferences-D4EANGoc.js +0 -5
  217. package/core/built/admin/assets/profile-dJ44Bn_W.js +0 -1
  218. package/core/built/admin/assets/select--2uVN9_-.js +0 -1
  219. package/core/built/admin/assets/settings-SD9bxIpt.js +0 -4
  220. package/core/built/admin/assets/social-urls-BvFZwYcE.js +0 -8
  221. package/core/built/admin/assets/switch-qp518gFQ.js +0 -1
  222. package/core/built/admin/assets/textarea-CTlb3Uu6.js +0 -1
  223. package/core/built/admin/assets/use-filter-params-DeQ8sX4N.js +0 -1
  224. package/core/built/admin/assets/web-DTZnnUGr.js +0 -1
  225. package/core/server/services/mail/templates/newsletter.html +0 -876
  226. package/core/server/services/members/csv/index.ts +0 -3
  227. package/core/server/services/members/csv/parse.js +0 -94
  228. package/core/server/services/members/csv/parse.ts +0 -111
  229. package/core/server/services/members/csv/types.js +0 -2
  230. package/core/server/services/members/csv/types.ts +0 -39
  231. package/core/server/services/members/csv/unparse.js +0 -69
  232. package/core/server/services/members/csv/unparse.ts +0 -79
  233. package/core/server/services/members/exporter/query.js +0 -233
  234. package/core/server/services/members/importer/index.js +0 -30
  235. package/core/server/services/members/importer/labels.js +0 -125
  236. package/core/server/services/members/importer/members-csv-importer.js +0 -520
  237. /package/core/server/services/members/{importer → import-export/import}/email-template.js +0 -0
  238. /package/core/server/services/members/{importer/members-csv-importer-stripe-utils.js → import-export/import/stripe-utils.js} +0 -0
@@ -0,0 +1,90 @@
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.makeImporter = makeImporter;
7
+ exports.makeExporter = makeExporter;
8
+ const importer_1 = __importDefault(require("./import/importer"));
9
+ const reader_1 = __importDefault(require("./import/reader"));
10
+ const spool_1 = require("./import/spool");
11
+ const exporter_1 = __importDefault(require("./export/exporter"));
12
+ const MembersCSVImporterStripeUtils = require('./import/stripe-utils');
13
+ const db = require('../../../data/db');
14
+ const models = require('../../../models');
15
+ const labs = require('../../../../shared/labs');
16
+ // Build the members CSV importer. This is the composition root: today's models and
17
+ // services are wired behind the collaborators the importer declares, one per
18
+ // concern, so nothing Bookshelf-shaped leaks into the import service itself.
19
+ function makeImporter(deps) {
20
+ // The members repository resolves asynchronously and is stable once ready, so
21
+ // cache the promise and reuse it across every call the import makes.
22
+ let membersRepositoryPromise;
23
+ const getMembersRepository = () => (membersRepositoryPromise ??= deps.getMembersRepository());
24
+ // The members aggregate, plus the import label lookup folded in so the label
25
+ // (member-tagging data) does not need a source of its own.
26
+ const members = {
27
+ get: async (query, options) => (await getMembersRepository()).get(query, options),
28
+ create: async (values, options) => (await getMembersRepository()).create(values, options),
29
+ update: async (values, options) => (await getMembersRepository()).update(values, options),
30
+ getCustomerIdByEmail: async (email) => (await getMembersRepository()).getCustomerIdByEmail(email),
31
+ linkStripeCustomer: async (link, options) => (await getMembersRepository()).linkStripeCustomer(link, options),
32
+ getImportLabel: name => models.Label.findOne({ name })
33
+ };
34
+ // The completion email: its recipient, links and delivery in one collaborator.
35
+ const email = {
36
+ send: deps.sendEmail,
37
+ getDefaultRecipient: async () => (await models.User.getOwnerUser()).get('email'),
38
+ urlFor: deps.urlFor
39
+ };
40
+ // Gifts is initialised at boot and always present at request time; the getter
41
+ // resolves it lazily so the ready service is picked up whenever a row uses it.
42
+ const gifts = {
43
+ reassignRedeemer: (giftId, memberId, options) => deps.getGiftService().reassignRedeemer(giftId, memberId, options)
44
+ };
45
+ return new importer_1.default({
46
+ knex: deps.knex,
47
+ readRows: reader_1.default,
48
+ spool: (0, spool_1.createRowSpool)(),
49
+ members,
50
+ tiers: {
51
+ getDefault: deps.getDefaultTier,
52
+ getByName: deps.getTierByName
53
+ },
54
+ stripe: new MembersCSVImporterStripeUtils({
55
+ stripeAPIService: deps.stripeAPIService,
56
+ productRepository: deps.productRepository
57
+ }),
58
+ gifts,
59
+ email,
60
+ addJob: deps.addJob,
61
+ getTimezone: deps.getTimezone,
62
+ getInlineThreshold: deps.getInlineThreshold
63
+ });
64
+ }
65
+ // Build the members CSV exporter. The same composition root from the other direction:
66
+ // knex and the members id lookup are wired here, and the custom fields definitions and
67
+ // values services are injected (boot builds them before this one). The labs flag alone
68
+ // decides whether custom field columns appear, so nothing flag-shaped leaks into the
69
+ // exporter itself.
70
+ function makeExporter({ definitions, values }) {
71
+ const exporter = new exporter_1.default({
72
+ knex: db.knex,
73
+ members: {
74
+ // Minimal query, only to fetch the ids of the filtered members; the stream
75
+ // reads their related data itself.
76
+ findFilteredIds: async (options) => {
77
+ const page = await models.Member.findPage({ ...options, withRelated: [], columns: ['id'], limit: 'all' });
78
+ return page.data.map((member) => member.id);
79
+ }
80
+ },
81
+ customFields: {
82
+ // Boot builds the definitions and values services before this one, so they
83
+ // are always present -- no not-initialised state to guard. The flag decides
84
+ // whether their columns are included at all.
85
+ activeDefinitions: async () => (labs.isSet('membersCustomFields') ? definitions.browse() : []),
86
+ valuesForMembers: memberIds => values.getValuesForMembers(memberIds)
87
+ }
88
+ });
89
+ return (options = {}) => exporter.export(options);
90
+ }
@@ -0,0 +1,118 @@
1
+ import type {Knex} from 'knex';
2
+ import MembersCSVImporter, {type MembersRepository, type GiftService, type EmailNotifications, type Tier} from './import/importer';
3
+ import readMemberRows from './import/reader';
4
+ import {createRowSpool} from './import/spool';
5
+ import MembersCSVExporter, {type ExportOptions, type CustomFieldDefinition} from './export/exporter';
6
+
7
+ const MembersCSVImporterStripeUtils = require('./import/stripe-utils');
8
+ const db = require('../../../data/db');
9
+ const models = require('../../../models');
10
+ const labs = require('../../../../shared/labs');
11
+
12
+ // The raw collaborators the members service hands the import composition root, before
13
+ // they are adapted into the ports the importer declares. The members repository is the
14
+ // importer's aggregate minus the import-label lookup, which the root folds in itself.
15
+ interface ImporterServices {
16
+ knex: Knex;
17
+ getMembersRepository(): Promise<Omit<MembersRepository, 'getImportLabel'>>;
18
+ getDefaultTier(): Promise<Tier>;
19
+ getTierByName(name: string): Promise<Tier | null>;
20
+ getGiftService(): GiftService;
21
+ sendEmail: EmailNotifications['send'];
22
+ urlFor: EmailNotifications['urlFor'];
23
+ addJob(job: {job: () => Promise<void>; offloaded: boolean; name: string}): void;
24
+ getTimezone(): string;
25
+ getInlineThreshold(): number;
26
+ stripeAPIService: unknown;
27
+ productRepository: unknown;
28
+ }
29
+
30
+ // The custom fields services the members service hands the export composition root.
31
+ interface CustomFieldsServices {
32
+ definitions: {browse(): Promise<CustomFieldDefinition[]>};
33
+ values: {getValuesForMembers(memberIds: string[]): Promise<Map<string, Record<string, unknown>>>};
34
+ }
35
+
36
+ // Build the members CSV importer. This is the composition root: today's models and
37
+ // services are wired behind the collaborators the importer declares, one per
38
+ // concern, so nothing Bookshelf-shaped leaks into the import service itself.
39
+ export function makeImporter(deps: ImporterServices) {
40
+ // The members repository resolves asynchronously and is stable once ready, so
41
+ // cache the promise and reuse it across every call the import makes.
42
+ let membersRepositoryPromise: Promise<Omit<MembersRepository, 'getImportLabel'>> | undefined;
43
+ const getMembersRepository = () => (membersRepositoryPromise ??= deps.getMembersRepository());
44
+
45
+ // The members aggregate, plus the import label lookup folded in so the label
46
+ // (member-tagging data) does not need a source of its own.
47
+ const members: MembersRepository = {
48
+ get: async (query, options) => (await getMembersRepository()).get(query, options),
49
+ create: async (values, options) => (await getMembersRepository()).create(values, options),
50
+ update: async (values, options) => (await getMembersRepository()).update(values, options),
51
+ getCustomerIdByEmail: async email => (await getMembersRepository()).getCustomerIdByEmail(email),
52
+ linkStripeCustomer: async (link, options) => (await getMembersRepository()).linkStripeCustomer(link, options),
53
+ getImportLabel: name => models.Label.findOne({name})
54
+ };
55
+
56
+ // The completion email: its recipient, links and delivery in one collaborator.
57
+ const email: EmailNotifications = {
58
+ send: deps.sendEmail,
59
+ getDefaultRecipient: async () => (await models.User.getOwnerUser()).get('email'),
60
+ urlFor: deps.urlFor
61
+ };
62
+
63
+ // Gifts is initialised at boot and always present at request time; the getter
64
+ // resolves it lazily so the ready service is picked up whenever a row uses it.
65
+ const gifts: GiftService = {
66
+ reassignRedeemer: (giftId, memberId, options) => deps.getGiftService().reassignRedeemer(giftId, memberId, options)
67
+ };
68
+
69
+ return new MembersCSVImporter({
70
+ knex: deps.knex,
71
+ readRows: readMemberRows,
72
+ spool: createRowSpool(),
73
+ members,
74
+ tiers: {
75
+ getDefault: deps.getDefaultTier,
76
+ getByName: deps.getTierByName
77
+ },
78
+ stripe: new MembersCSVImporterStripeUtils({
79
+ stripeAPIService: deps.stripeAPIService,
80
+ productRepository: deps.productRepository
81
+ }),
82
+ gifts,
83
+ email,
84
+ addJob: deps.addJob,
85
+ getTimezone: deps.getTimezone,
86
+ getInlineThreshold: deps.getInlineThreshold
87
+ });
88
+ }
89
+
90
+ // Build the members CSV exporter. The same composition root from the other direction:
91
+ // knex and the members id lookup are wired here, and the custom fields definitions and
92
+ // values services are injected (boot builds them before this one). The labs flag alone
93
+ // decides whether custom field columns appear, so nothing flag-shaped leaks into the
94
+ // exporter itself.
95
+ export function makeExporter({definitions, values}: CustomFieldsServices): (options?: ExportOptions) => Promise<NodeJS.ReadableStream> {
96
+ const exporter = new MembersCSVExporter({
97
+ knex: db.knex,
98
+
99
+ members: {
100
+ // Minimal query, only to fetch the ids of the filtered members; the stream
101
+ // reads their related data itself.
102
+ findFilteredIds: async (options) => {
103
+ const page = await models.Member.findPage({...options, withRelated: [], columns: ['id'], limit: 'all'});
104
+ return page.data.map((member: {id: string}) => member.id);
105
+ }
106
+ },
107
+
108
+ customFields: {
109
+ // Boot builds the definitions and values services before this one, so they
110
+ // are always present -- no not-initialised state to guard. The flag decides
111
+ // whether their columns are included at all.
112
+ activeDefinitions: async (): Promise<CustomFieldDefinition[]> => (labs.isSet('membersCustomFields') ? definitions.browse() : []),
113
+ valuesForMembers: memberIds => values.getValuesForMembers(memberIds)
114
+ }
115
+ });
116
+
117
+ return (options = {}) => exporter.export(options);
118
+ }
@@ -467,6 +467,13 @@ module.exports = class RouterController {
467
467
  });
468
468
  }
469
469
 
470
+ if (offer.status && offer.status !== 'active') {
471
+ throw new BadRequestError({
472
+ message: tpl(messages.offerArchived),
473
+ context: 'Offer with id "' + offerId + '" is no longer active'
474
+ });
475
+ }
476
+
470
477
  if (!offer.tier) {
471
478
  throw new BadRequestError({
472
479
  message: 'Offer does not have a tier'
@@ -4,13 +4,12 @@ const tpl = require('@tryghost/tpl');
4
4
  const MembersSSR = require('./members-ssr');
5
5
  const db = require('../../data/db');
6
6
  const MembersConfigProvider = require('./members-config-provider');
7
- const makeMembersCSVImporter = require('./importer');
8
- const {resolveInlineThreshold} = require('./importer/config');
7
+ const {makeImporter, makeExporter} = require('./import-export');
8
+ const {resolveInlineThreshold} = require('./import-export/config');
9
9
  const MembersStats = require('./stats/members-stats');
10
10
  const memberJobs = require('./jobs');
11
11
  const logging = require('@tryghost/logging');
12
12
  const urlUtils = require('../../../shared/url-utils').default;
13
- const labsService = require('../../../shared/labs');
14
13
  const settingsCache = require('../../../shared/settings-cache');
15
14
  const config = require('../../../shared/config');
16
15
  const models = require('../../models');
@@ -47,9 +46,8 @@ const membersStats = new MembersStats({
47
46
  let membersApi;
48
47
  let verificationTrigger;
49
48
 
50
- const initMembersCSVImporter = ({stripeAPIService}) => {
51
- return makeMembersCSVImporter({
52
- storagePath: config.getContentPath('data'),
49
+ const buildImporterDeps = ({stripeAPIService}) => {
50
+ return {
53
51
  getTimezone: () => settingsCache.get('timezone'),
54
52
  // A getter rather than a value because the threshold is an operator
55
53
  // setting that can change between requests
@@ -79,16 +77,12 @@ const initMembersCSVImporter = ({stripeAPIService}) => {
79
77
  },
80
78
  getGiftService: () => giftService.service,
81
79
  sendEmail: ghostMailer.send.bind(ghostMailer),
82
- isSet: flag => labsService.isSet(flag),
83
80
  addJob: jobsService.addJob.bind(jobsService),
84
81
  knex: db.knex,
85
82
  urlFor: urlUtils.urlFor.bind(urlUtils),
86
- context: {
87
- importer: true
88
- },
89
83
  stripeAPIService,
90
84
  productRepository: membersApi.productRepository
91
- });
85
+ };
92
86
  };
93
87
 
94
88
  const initVerificationTrigger = () => {
@@ -154,19 +148,23 @@ module.exports = {
154
148
  }
155
149
  module.exports.verificationTrigger = verificationTrigger;
156
150
 
157
- const membersCSVImporter = initMembersCSVImporter({stripeAPIService: stripeService.api});
151
+ const importerDeps = buildImporterDeps({stripeAPIService: stripeService.api});
152
+ const membersCSVImporter = makeImporter(importerDeps);
153
+ // The importer takes plain arguments and returns the domain outcome; callers build
154
+ // the request and shape the response. importCSV decides inline vs deferred by load
155
+ // (the endpoint); importInline always runs now (the Revue data import). This only
156
+ // supplies the verification trigger, a members-service internal.
157
+ module.exports.importCSV = (request) => membersCSVImporter.importCSV(request, verificationTrigger);
158
+ module.exports.importInline = (request) => membersCSVImporter.importInline(request, verificationTrigger);
159
+
158
160
  // Constructed here rather than required statically: the exporter needs the
159
161
  // custom fields services, which boot builds before this one.
160
162
  const customFields = require('../members-custom-fields');
161
- module.exports.export = require('./exporter/query')({
163
+ module.exports.export = makeExporter({
162
164
  definitions: customFields.definitions,
163
165
  values: customFields.values
164
166
  });
165
167
 
166
- module.exports.processImport = async (options) => {
167
- return await membersCSVImporter.process({...options, verificationTrigger});
168
- };
169
-
170
168
  if (!env?.startsWith('testing')) {
171
169
  const membersMigrationJobName = 'members-migrations';
172
170
  if (!(await jobsService.hasExecutedSuccessfully(membersMigrationJobName))) {
@@ -205,10 +203,10 @@ module.exports = {
205
203
 
206
204
  stripeConnect: require('./stripe-connect'),
207
205
 
208
- processImport: null,
206
+ importCSV: null,
207
+ importInline: null,
209
208
 
210
209
  stats: membersStats,
211
-
212
210
  export: null
213
211
  };
214
212
 
@@ -83,7 +83,7 @@ class PostsExporter {
83
83
  * @param {string|number} [options.limit]
84
84
  * @returns {Promise<Readable>}
85
85
  */
86
- async export({filter, order, limit}) {
86
+ async export({filter, order, limit, mongoTransformer}) {
87
87
  const exportContext = await this.#getExportContext();
88
88
  const requestedLimit = parseExportLimit(limit);
89
89
  const pageLimit = Math.min(EXPORT_BATCH_SIZE, requestedLimit);
@@ -93,7 +93,8 @@ class PostsExporter {
93
93
  order: withStableExportOrder(order),
94
94
  requestedLimit,
95
95
  pageLimit,
96
- exportContext
96
+ exportContext,
97
+ mongoTransformer
97
98
  }), {objectMode: true});
98
99
  }
99
100
 
@@ -119,7 +120,7 @@ class PostsExporter {
119
120
  * @param {ExportContext} options.exportContext
120
121
  * @returns {AsyncGenerator<object>}
121
122
  */
122
- async *#streamPosts({filter, order, requestedLimit, pageLimit, exportContext}) {
123
+ async *#streamPosts({filter, order, requestedLimit, pageLimit, exportContext, mongoTransformer}) {
123
124
  let emitted = 0;
124
125
 
125
126
  for (let page = 1; emitted < requestedLimit; page++) {
@@ -129,7 +130,8 @@ class PostsExporter {
129
130
  limit: pageLimit,
130
131
  page,
131
132
  skipPagination: true,
132
- withRelated: EXPORT_WITH_RELATED
133
+ withRelated: EXPORT_WITH_RELATED,
134
+ mongoTransformer
133
135
  });
134
136
 
135
137
  if (posts.data.length === 0) {
@@ -329,8 +329,8 @@ class PostsService {
329
329
  return result;
330
330
  }
331
331
 
332
- async export(frame) {
333
- return await this.postsExporter.export(frame.options);
332
+ async export(options) {
333
+ return await this.postsExporter.export(options);
334
334
  }
335
335
 
336
336
  async #updatePosts(data, options) {
@@ -27,6 +27,8 @@ const messages = {
27
27
  destroyActive: 'Deleting the active theme is not allowed.'
28
28
  };
29
29
 
30
+ const INVALID_THEME_REGEX = /^[./]*$/;
31
+
30
32
  let themeStorage;
31
33
 
32
34
  const getStorage = () => {
@@ -60,6 +62,13 @@ module.exports = {
60
62
  });
61
63
  }
62
64
 
65
+ // Reject theme names that only contain path elements.
66
+ if (INVALID_THEME_REGEX.test(themeName)) {
67
+ throw new errors.ValidationError({
68
+ message: 'Invalid theme name.'
69
+ });
70
+ }
71
+
63
72
  let checkedTheme;
64
73
  let overrideTheme;
65
74
  let renamedExisting = false;
@@ -4,7 +4,7 @@ const path = require('path');
4
4
  const config = require('../../../shared/config');
5
5
  const security = require('@tryghost/security');
6
6
  const {compress} = require('@tryghost/zip');
7
- const LocalStorageBase = require('../../adapters/storage/LocalStorageBase');
7
+ const LocalStorageBase = require('../../adapters/storage/LocalStorageBase').default;
8
8
 
9
9
  /**
10
10
  * @TODO: combine with loader.js?
@@ -366,5 +366,6 @@
366
366
  "captureLinkClickBadMemberUuid": false
367
367
  },
368
368
  "disableJSBackups": false,
369
- "disableMigrationBackups": false
369
+ "disableMigrationBackups": false,
370
+ "usingLoopbackReverseProxy": false
370
371
  }
@@ -2,6 +2,7 @@ const debug = require('@tryghost/debug')('shared:express');
2
2
  const express = require('express');
3
3
  const {createLazyRouter} = require('express-lazy-router');
4
4
  const sentry = require('./sentry');
5
+ const config = require('../../core/shared/config');
5
6
 
6
7
  const lazyLoad = createLazyRouter();
7
8
 
@@ -17,7 +18,11 @@ module.exports = (name) => {
17
18
 
18
19
  // Make sure 'req.secure' is valid for proxied requests
19
20
  // (X-Forwarded-Proto header will be checked, if present)
20
- app.enable('trust proxy');
21
+ if (config.get('usingLoopbackReverseProxy')) {
22
+ app.set('trust proxy', 'loopback');
23
+ } else {
24
+ app.enable('trust proxy');
25
+ }
21
26
 
22
27
  // Sentry must be our first error handler. Mounting it here means all custom error handlers will come after
23
28
  app.use(sentry.errorHandler);
@@ -64,7 +64,8 @@ const PRIVATE_FEATURES = [
64
64
  'getHelperDeduplication',
65
65
  'memberDetailsReact',
66
66
  'membersCustomFields',
67
- 'previewByTier'
67
+ 'previewByTier',
68
+ 'paywallImprovements'
68
69
  ];
69
70
 
70
71
  module.exports.GA_KEYS = [...GA_FEATURES];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghost",
3
- "version": "6.54.0",
3
+ "version": "6.54.1",
4
4
  "description": "The professional publishing platform",
5
5
  "author": "Ghost Foundation",
6
6
  "homepage": "https://ghost.org",
@@ -192,22 +192,22 @@
192
192
  "ua-parser-js": "1.0.41",
193
193
  "xml": "1.0.1",
194
194
  "zod": "4.4.3",
195
- "@tryghost/adapter-base-redirects": "file:components/tryghost-adapter-base-redirects-0.0.0.tgz",
195
+ "@tryghost/adapter-base-cache": "file:components/tryghost-adapter-base-cache-0.2.0.tgz",
196
196
  "@tryghost/adapter-base-route-settings": "file:components/tryghost-adapter-base-route-settings-0.0.0.tgz",
197
- "@tryghost/adapter-base-scheduling": "file:components/tryghost-adapter-base-scheduling-0.1.1.tgz",
197
+ "@tryghost/adapter-base-redirects": "file:components/tryghost-adapter-base-redirects-0.0.0.tgz",
198
+ "@tryghost/adapter-base-scheduling": "file:components/tryghost-adapter-base-scheduling-0.2.0.tgz",
198
199
  "@tryghost/adapter-base-sso": "file:components/tryghost-adapter-base-sso-0.1.1.tgz",
199
200
  "@tryghost/admin-api-schema": "file:components/tryghost-admin-api-schema-0.0.0.tgz",
200
- "@tryghost/i18n": "file:components/tryghost-i18n-0.0.0.tgz",
201
201
  "@tryghost/custom-field-types": "file:components/tryghost-custom-field-types-0.0.0.tgz",
202
- "@tryghost/kg-converters": "file:components/tryghost-kg-converters-1.2.3.tgz",
202
+ "@tryghost/i18n": "file:components/tryghost-i18n-0.0.0.tgz",
203
203
  "@tryghost/kg-default-cards": "file:components/tryghost-kg-default-cards-10.3.3.tgz",
204
- "@tryghost/kg-card-factory": "file:components/tryghost-kg-card-factory-5.2.3.tgz",
205
204
  "@tryghost/kg-html-to-lexical": "file:components/tryghost-kg-html-to-lexical-1.3.3.tgz",
206
205
  "@tryghost/kg-default-nodes": "file:components/tryghost-kg-default-nodes-2.1.3.tgz",
207
- "ghost-storage-base": "file:components/ghost-storage-base-3.0.0.tgz",
208
- "@tryghost/adapter-base-cache": "file:components/tryghost-adapter-base-cache-0.2.0.tgz",
209
206
  "@tryghost/kg-lexical-html-renderer": "file:components/tryghost-kg-lexical-html-renderer-1.4.3.tgz",
210
- "@tryghost/parse-email-address": "file:components/tryghost-parse-email-address-0.0.0.tgz"
207
+ "@tryghost/kg-card-factory": "file:components/tryghost-kg-card-factory-5.2.3.tgz",
208
+ "@tryghost/parse-email-address": "file:components/tryghost-parse-email-address-0.0.0.tgz",
209
+ "ghost-storage-base": "file:components/ghost-storage-base-3.0.0.tgz",
210
+ "@tryghost/kg-converters": "file:components/tryghost-kg-converters-1.2.3.tgz"
211
211
  },
212
212
  "optionalDependencies": {
213
213
  "better-sqlite3": "12.11.1"
package/pnpm-lock.yaml CHANGED
@@ -60,19 +60,19 @@ overrides:
60
60
  '@xmldom/xmldom@<0.8.13': ^0.9.0
61
61
  perf-primitives: ^0.0.6
62
62
  '@tryghost/adapter-base-redirects': file:components/tryghost-adapter-base-redirects-0.0.0.tgz
63
+ '@tryghost/adapter-base-cache': file:components/tryghost-adapter-base-cache-0.2.0.tgz
63
64
  '@tryghost/adapter-base-route-settings': file:components/tryghost-adapter-base-route-settings-0.0.0.tgz
64
- '@tryghost/admin-api-schema': file:components/tryghost-admin-api-schema-0.0.0.tgz
65
- '@tryghost/custom-field-types': file:components/tryghost-custom-field-types-0.0.0.tgz
66
- '@tryghost/i18n': file:components/tryghost-i18n-0.0.0.tgz
67
65
  '@tryghost/adapter-base-sso': file:components/tryghost-adapter-base-sso-0.1.1.tgz
68
- '@tryghost/adapter-base-scheduling': file:components/tryghost-adapter-base-scheduling-0.1.1.tgz
69
- '@tryghost/adapter-base-cache': file:components/tryghost-adapter-base-cache-0.2.0.tgz
66
+ '@tryghost/custom-field-types': file:components/tryghost-custom-field-types-0.0.0.tgz
67
+ '@tryghost/adapter-base-scheduling': file:components/tryghost-adapter-base-scheduling-0.2.0.tgz
70
68
  '@tryghost/kg-card-factory': file:components/tryghost-kg-card-factory-5.2.3.tgz
71
- '@tryghost/parse-email-address': file:components/tryghost-parse-email-address-0.0.0.tgz
69
+ '@tryghost/admin-api-schema': file:components/tryghost-admin-api-schema-0.0.0.tgz
72
70
  '@tryghost/kg-utils': file:components/tryghost-kg-utils-1.1.3.tgz
73
- '@tryghost/kg-clean-basic-html': file:components/tryghost-kg-clean-basic-html-4.3.3.tgz
74
71
  '@tryghost/kg-converters': file:components/tryghost-kg-converters-1.2.3.tgz
72
+ '@tryghost/kg-clean-basic-html': file:components/tryghost-kg-clean-basic-html-4.3.3.tgz
73
+ '@tryghost/parse-email-address': file:components/tryghost-parse-email-address-0.0.0.tgz
75
74
  ghost-storage-base: file:components/ghost-storage-base-3.0.0.tgz
75
+ '@tryghost/i18n': file:components/tryghost-i18n-0.0.0.tgz
76
76
  '@tryghost/kg-markdown-html-renderer': file:components/tryghost-kg-markdown-html-renderer-7.2.3.tgz
77
77
  '@tryghost/kg-default-cards': file:components/tryghost-kg-default-cards-10.3.3.tgz
78
78
  '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.3.tgz
@@ -114,8 +114,8 @@ importers:
114
114
  specifier: file:components/tryghost-adapter-base-route-settings-0.0.0.tgz
115
115
  version: file:components/tryghost-adapter-base-route-settings-0.0.0.tgz
116
116
  '@tryghost/adapter-base-scheduling':
117
- specifier: file:components/tryghost-adapter-base-scheduling-0.1.1.tgz
118
- version: file:components/tryghost-adapter-base-scheduling-0.1.1.tgz(supports-color@10.2.2)
117
+ specifier: file:components/tryghost-adapter-base-scheduling-0.2.0.tgz
118
+ version: file:components/tryghost-adapter-base-scheduling-0.2.0.tgz(supports-color@10.2.2)
119
119
  '@tryghost/adapter-base-sso':
120
120
  specifier: file:components/tryghost-adapter-base-sso-0.1.1.tgz
121
121
  version: file:components/tryghost-adapter-base-sso-0.1.1.tgz
@@ -1292,7 +1292,7 @@ packages:
1292
1292
  engines: {node: '>= 10'}
1293
1293
 
1294
1294
  '@tryghost/adapter-base-cache@file:components/tryghost-adapter-base-cache-0.2.0.tgz':
1295
- resolution: {integrity: sha512-u1hW+3obsj1vnQ+tk+48XbYW+vdsza65Wam1814XHYLczUkYfziyTWGGnxBbxGLB/IHRxu0TsmAYBgvSIS84HQ==, tarball: file:components/tryghost-adapter-base-cache-0.2.0.tgz}
1295
+ resolution: {integrity: sha512-L2QmYEtYSjq2ikZaqoEYAu0qZK+akv+6BapZBGnrYdWikjqNTK8YBnDWtglN2HTOf4entlqchqfcCzPKjQ2OPg==, tarball: file:components/tryghost-adapter-base-cache-0.2.0.tgz}
1296
1296
  version: 0.2.0
1297
1297
 
1298
1298
  '@tryghost/adapter-base-redirects@file:components/tryghost-adapter-base-redirects-0.0.0.tgz':
@@ -1303,12 +1303,12 @@ packages:
1303
1303
  resolution: {integrity: sha512-jynk3ZwdyNKmla/uFMmGk2cXoVBigSIuDIG9fAJK/7EK7LDReMFVtUn2ePQIVQuv98zL5GnEBKXb8qe7Vz5ukA==, tarball: file:components/tryghost-adapter-base-route-settings-0.0.0.tgz}
1304
1304
  version: 0.0.0
1305
1305
 
1306
- '@tryghost/adapter-base-scheduling@file:components/tryghost-adapter-base-scheduling-0.1.1.tgz':
1307
- resolution: {integrity: sha512-BtlUlMBw7o+7b0NGyEuscvjabzwwerlkOKlF4t+FXnh/6L9KCXhiGe6R39DxCfVm5gJYEakGxnhtCn/KtYQ+pA==, tarball: file:components/tryghost-adapter-base-scheduling-0.1.1.tgz}
1308
- version: 0.1.1
1306
+ '@tryghost/adapter-base-scheduling@file:components/tryghost-adapter-base-scheduling-0.2.0.tgz':
1307
+ resolution: {integrity: sha512-GpXwbQLqrlzPBLUXoW0Bv4v47jjJ6sW3uanFHannFqYeOyJliBrG+IUz6PPQYt023AKTq6pkZnqnrKBr3FwD2w==, tarball: file:components/tryghost-adapter-base-scheduling-0.2.0.tgz}
1308
+ version: 0.2.0
1309
1309
 
1310
1310
  '@tryghost/adapter-base-sso@file:components/tryghost-adapter-base-sso-0.1.1.tgz':
1311
- resolution: {integrity: sha512-9faVBpVQG2fLmshXi3gP3fEQF2h6ngf47lgWURGeOo3gyn8BvuGcjhRrRU9cKMdnIt2fQKhx/7WhqRkRnN41ew==, tarball: file:components/tryghost-adapter-base-sso-0.1.1.tgz}
1311
+ resolution: {integrity: sha512-X1kS2Jfl7nPt9/TZN/S/+0ajMmN0rn5z/NrxKayV3KqPEvrFoUaM3+RYVXpp0bhrYugwCaAaj5H/e1IC/XSGFg==, tarball: file:components/tryghost-adapter-base-sso-0.1.1.tgz}
1312
1312
  version: 0.1.1
1313
1313
 
1314
1314
  '@tryghost/admin-api-schema@file:components/tryghost-admin-api-schema-0.0.0.tgz':
@@ -1449,7 +1449,7 @@ packages:
1449
1449
  engines: {node: ^22.13.1 || ^24.0.0}
1450
1450
 
1451
1451
  '@tryghost/kg-default-nodes@file:components/tryghost-kg-default-nodes-2.1.3.tgz':
1452
- resolution: {integrity: sha512-4Hb1cQf1olvNiPIVRTrL5OvEiyg5d+S5Uio/joYL7tPH6iLuMn2bTjGpvbVapShuFu/fwAx1myJu/tC9vZt+Ig==, tarball: file:components/tryghost-kg-default-nodes-2.1.3.tgz}
1452
+ resolution: {integrity: sha512-R10lI/G/kHBeRgHg6z/0uraR4zJkMXnql6lhIU+pG1Yo5sJivKQ3yjNMR+yIsZ8ng8QK5Yd+CTOReQ7Mfk9rcg==, tarball: file:components/tryghost-kg-default-nodes-2.1.3.tgz}
1453
1453
  version: 2.1.3
1454
1454
  engines: {node: ^22.13.1 || ^24.0.0}
1455
1455
 
@@ -3101,7 +3101,7 @@ packages:
3101
3101
  resolution: {integrity: sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==}
3102
3102
 
3103
3103
  ghost-storage-base@file:components/ghost-storage-base-3.0.0.tgz:
3104
- resolution: {integrity: sha512-FBFXuCXSsTQ188Kv6Xh5vAkTkp/p8d+DhKx0Jm9qHwF28PYgLgklKrf4i4XiVM9w6fl4G5KaGb1UXXv6goh4uQ==, tarball: file:components/ghost-storage-base-3.0.0.tgz}
3104
+ resolution: {integrity: sha512-Y/vXTRSvDSHXXiYAly1iAHAcDqMiqW/OkTyQyudRSlKm4GLrcIv4G2XPNPn2T6ChpdlVvIAZdee8sqf5UxyRqg==, tarball: file:components/ghost-storage-base-3.0.0.tgz}
3105
3105
  version: 3.0.0
3106
3106
 
3107
3107
  github-from-package@0.0.0:
@@ -6234,7 +6234,7 @@ snapshots:
6234
6234
 
6235
6235
  '@tryghost/adapter-base-route-settings@file:components/tryghost-adapter-base-route-settings-0.0.0.tgz': {}
6236
6236
 
6237
- '@tryghost/adapter-base-scheduling@file:components/tryghost-adapter-base-scheduling-0.1.1.tgz(supports-color@10.2.2)':
6237
+ '@tryghost/adapter-base-scheduling@file:components/tryghost-adapter-base-scheduling-0.2.0.tgz(supports-color@10.2.2)':
6238
6238
  dependencies:
6239
6239
  '@tryghost/logging': 5.3.0(supports-color@10.2.2)
6240
6240
  transitivePeerDependencies:
@@ -220,19 +220,19 @@ overrides:
220
220
  '@xmldom/xmldom@<0.8.13': ^0.9.0
221
221
  perf-primitives: ^0.0.6
222
222
  '@tryghost/adapter-base-redirects': file:components/tryghost-adapter-base-redirects-0.0.0.tgz
223
+ '@tryghost/adapter-base-cache': file:components/tryghost-adapter-base-cache-0.2.0.tgz
223
224
  '@tryghost/adapter-base-route-settings': file:components/tryghost-adapter-base-route-settings-0.0.0.tgz
224
- '@tryghost/admin-api-schema': file:components/tryghost-admin-api-schema-0.0.0.tgz
225
- '@tryghost/custom-field-types': file:components/tryghost-custom-field-types-0.0.0.tgz
226
- '@tryghost/i18n': file:components/tryghost-i18n-0.0.0.tgz
227
225
  '@tryghost/adapter-base-sso': file:components/tryghost-adapter-base-sso-0.1.1.tgz
228
- '@tryghost/adapter-base-scheduling': file:components/tryghost-adapter-base-scheduling-0.1.1.tgz
229
- '@tryghost/adapter-base-cache': file:components/tryghost-adapter-base-cache-0.2.0.tgz
226
+ '@tryghost/custom-field-types': file:components/tryghost-custom-field-types-0.0.0.tgz
227
+ '@tryghost/adapter-base-scheduling': file:components/tryghost-adapter-base-scheduling-0.2.0.tgz
230
228
  '@tryghost/kg-card-factory': file:components/tryghost-kg-card-factory-5.2.3.tgz
231
- '@tryghost/parse-email-address': file:components/tryghost-parse-email-address-0.0.0.tgz
229
+ '@tryghost/admin-api-schema': file:components/tryghost-admin-api-schema-0.0.0.tgz
232
230
  '@tryghost/kg-utils': file:components/tryghost-kg-utils-1.1.3.tgz
233
- '@tryghost/kg-clean-basic-html': file:components/tryghost-kg-clean-basic-html-4.3.3.tgz
234
231
  '@tryghost/kg-converters': file:components/tryghost-kg-converters-1.2.3.tgz
232
+ '@tryghost/kg-clean-basic-html': file:components/tryghost-kg-clean-basic-html-4.3.3.tgz
233
+ '@tryghost/parse-email-address': file:components/tryghost-parse-email-address-0.0.0.tgz
235
234
  ghost-storage-base: file:components/ghost-storage-base-3.0.0.tgz
235
+ '@tryghost/i18n': file:components/tryghost-i18n-0.0.0.tgz
236
236
  '@tryghost/kg-markdown-html-renderer': file:components/tryghost-kg-markdown-html-renderer-7.2.3.tgz
237
237
  '@tryghost/kg-default-cards': file:components/tryghost-kg-default-cards-10.3.3.tgz
238
238
  '@tryghost/kg-default-nodes': file:components/tryghost-kg-default-nodes-2.1.3.tgz