ghost 6.60.0 → 6.61.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/tryghost-adapter-base-scheduling-0.2.3.tgz +0 -0
- package/components/tryghost-adapter-base-sso-0.1.3.tgz +0 -0
- package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
- package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
- package/core/boot.js +13 -4
- package/core/built/admin/assets/{Combination-gnJO3vIw.js → Combination-5fYEzgbs.js} +1 -1
- package/core/built/admin/assets/{PolarAngleAxis-C4qtHy1B.js → PolarAngleAxis-pkMyqz8g.js} +1 -1
- package/core/built/admin/assets/{RadialBarChart-Bh09Stsj.js → RadialBarChart-JAKoS4KT.js} +1 -1
- package/core/built/admin/assets/{about-BgpmhCuM.js → about-Bve7IJS2.js} +1 -1
- package/core/built/admin/assets/{account-migration-8qTEI1i1.js → account-migration-DRhAehfw.js} +1 -1
- package/core/built/admin/assets/{action-list-lGzZLHc8.js → action-list-C4v0-du8.js} +1 -1
- package/core/built/admin/assets/activitypub/{account-migration-DMHuPnJn.js → account-migration-C-aej4x_.js} +7 -7
- package/core/built/admin/assets/activitypub/activitypub.js +3 -4
- package/core/built/admin/assets/activitypub/{avatar-DhTo5D1B.js → avatar-DLPL3Abs.js} +59 -68
- package/core/built/admin/assets/activitypub/{avatar-flipboard-DnVgbEfa.js → avatar-flipboard-C9iDY-QV.js} +2 -2
- package/core/built/admin/assets/activitypub/{bluesky-sharing-BT4zAlW7.js → bluesky-sharing-BXkA5mqV.js} +8 -8
- package/core/built/admin/assets/activitypub/{content-formatters-BeDZ-DIa.js → content-formatters-CHcyMFk4.js} +17 -17
- package/core/built/admin/assets/activitypub/{copy-8sqxUuNd.js → copy-DIAOQoCZ.js} +2 -2
- package/core/built/admin/assets/activitypub/{domain-xQDDu1CS.js → domain-B3ihkPde.js} +8 -8
- package/core/built/admin/assets/activitypub/{edit-profile-BXdF_r2G.js → edit-profile-DsZM3rTX.js} +5 -5
- package/core/built/admin/assets/activitypub/{explore-CMt7gKlL.js → explore-BodNrZgR.js} +8 -8
- package/core/built/admin/assets/activitypub/{feed-Bwqdddp_.js → feed-PwH1iJ84.js} +9 -9
- package/core/built/admin/assets/activitypub/{field-4co_8FVg.js → field-D06-kmOJ.js} +3 -3
- package/core/built/admin/assets/activitypub/{hash-DwakMs4X.js → hash-Bm3WxYN4.js} +2 -2
- package/core/built/admin/assets/activitypub/{inbox-DQ5CwLma.js → inbox-BluD2ucT.js} +16 -16
- package/core/built/admin/assets/activitypub/{inbox-ckD4wo_r.js → inbox-d8oJRTf4.js} +2 -2
- package/core/built/admin/assets/activitypub/{label-B72sfvEU.js → label-FHSh6ZAw.js} +3 -3
- package/core/built/admin/assets/activitypub/layout-Cq4NG0Xr.js +1 -0
- package/core/built/admin/assets/activitypub/{moderation-KCCO7L2J.js → moderation-D1Yapsod.js} +9 -9
- package/core/built/admin/assets/activitypub/{note-BX_Bz5A0.js → note-C5zjqq5C.js} +8 -8
- package/core/built/admin/assets/activitypub/{notifications-BQOYGvRv.js → notifications-B9p8eCHD.js} +9 -9
- package/core/built/admin/assets/activitypub/{preferences-6h43G9_q.js → preferences-BCqUdC3v.js} +9 -9
- package/core/built/admin/assets/activitypub/{profile-BMN9VVZ2.js → profile-BRCWoFem.js} +178 -178
- package/core/built/admin/assets/activitypub/{reply-ZNo04xsO.js → reply-DYK5vVqb.js} +2 -2
- package/core/built/admin/assets/activitypub/{routes-3B9mUQ7i.js → routes-BSXT992i.js} +81 -84
- package/core/built/admin/assets/activitypub/{separator-D9taVCCa.js → separator-BbQqTm-p.js} +3 -3
- package/core/built/admin/assets/activitypub/{settings-71gCm3SO.js → settings-DQDkr06X.js} +6 -6
- package/core/built/admin/assets/activitypub/{step-1-BsGGnBuT.js → step-1-B-YfsVeO.js} +5 -5
- package/core/built/admin/assets/activitypub/{step-2-teosIS0k.js → step-2-DtPQzlTH.js} +6 -6
- package/core/built/admin/assets/activitypub/{step-3-BjD5TokC.js → step-3-D6BFMXL_.js} +10 -10
- package/core/built/admin/assets/activitypub/{tabs-Cvwl1wXU.js → tabs-GpNecvfB.js} +6 -6
- package/core/built/admin/assets/activitypub/{topic-filter-C3LZJc2X.js → topic-filter-BPDeQQys.js} +3 -3
- package/core/built/admin/assets/activitypub/{use-activity-pub-queries-Dp9f0gov.js → use-activity-pub-queries-BoVOxXkV.js} +2 -2
- package/core/built/admin/assets/activitypub/{use-navigate-with-base-path-C4RI0sa9.js → use-navigate-with-base-path-Bmk5h4lW.js} +220 -220
- package/core/built/admin/assets/activitypub/{use-reply-chain-data-C2oNDMUH.js → use-reply-chain-data-wVBX7swM.js} +5 -5
- package/core/built/admin/assets/activitypub/{x-Dxm6pV9X.js → x-DbQZOLiI.js} +2 -2
- package/core/built/admin/assets/{add-integration-modal--YpTq3c0.js → add-integration-modal-BC0jExDZ.js} +1 -1
- package/core/built/admin/assets/{add-newsletter-modal-C8Ix2hol.js → add-newsletter-modal-DchTkA7l.js} +1 -1
- package/core/built/admin/assets/{add-recommendation-modal-CScuNFz4.js → add-recommendation-modal-DMvaJZKp.js} +1 -1
- package/core/built/admin/assets/alert-dialog-QhXzdHfc.js +1 -0
- package/core/built/admin/assets/{analytics-Cnji45H5.js → analytics-No1DDY3A.js} +1 -1
- package/core/built/admin/assets/{announcement-bar-modal-BTHiy1ZO.js → announcement-bar-modal-DM3cYOpo.js} +1 -1
- package/core/built/admin/assets/{api-keys-Boy5pLbD.js → api-keys-BLm2NDBh.js} +1 -1
- package/core/built/admin/assets/audience-9mwU5TW6.js +1 -0
- package/core/built/admin/assets/{automations-BWpRCZ_f.js → automations-DpUNUdcZ.js} +1 -1
- package/core/built/admin/assets/{bluesky-sharing-DHOpQxff.js → bluesky-sharing-Cjrv_f62.js} +1 -1
- package/core/built/admin/assets/{box-By_EgGtm.js → box-CdfQAP_F.js} +1 -1
- package/core/built/admin/assets/{brand-icon-09YqFZjV.js → brand-icon-CrIGOA3Z.js} +1 -1
- package/core/built/admin/assets/{breadcrumb-CcFr_ltt.js → breadcrumb-DLiqCyFc.js} +1 -1
- package/core/built/admin/assets/{button-BshWPHvn.js → button-B2jcu6bk.js} +1 -1
- package/core/built/admin/assets/{card-CiiE7QfM.js → card--VNbfgo3.js} +1 -1
- package/core/built/admin/assets/{chart-BnXyfH11.js → chart-BrhA41Zi.js} +1 -1
- package/core/built/admin/assets/chart-helpers-Fo3bUL3K.js +1 -0
- package/core/built/admin/assets/{checkbox-Dwwr_3Py.js → checkbox-BfKktMph.js} +1 -1
- package/core/built/admin/assets/{chunk.524.91ecb33e6afc3bd8949b.js → chunk.524.60ca4692d91c6022042f.js} +4 -4
- package/core/built/admin/assets/{chunk.582.512549909741883f960c.js → chunk.582.525c7617c2d9e94c940a.js} +6 -6
- package/core/built/admin/assets/{chunk.16.f76a6314082d813d67e0.js → chunk.896.435fe0637944d4a69810.js} +3 -3
- package/core/built/admin/assets/{code-editor-view-BwIdPy_k.js → code-editor-view-CYVu4EW6.js} +1 -1
- package/core/built/admin/assets/{code-editor-view-CtkF82Fv.js → code-editor-view-DCQJxsfU.js} +1 -1
- package/core/built/admin/assets/{color-picker-Bmo1r9Fc.js → color-picker-BTY_NdEm.js} +1 -1
- package/core/built/admin/assets/{color-picker-field-DywowPhF.js → color-picker-field-CPlkzOH0.js} +1 -1
- package/core/built/admin/assets/{combobox-C4QCh6Yw.js → combobox-DrMtv_4P.js} +1 -1
- package/core/built/admin/assets/command-ZdgYJpoI.js +1 -0
- package/core/built/admin/assets/comments-kidj60-h.js +1 -0
- package/core/built/admin/assets/{confirmation-context-CLFHhyyH.js → confirmation-context-BhbmQQEl.js} +1 -1
- package/core/built/admin/assets/{container-LiZf3XdY.js → container-BuQG1wuP.js} +1 -1
- package/core/built/admin/assets/{content-api-modal-BtpNI92-.js → content-api-modal-CyQEC3fr.js} +1 -1
- package/core/built/admin/assets/{copy-field-CglgRZyG.js → copy-field-B3M1s78L.js} +1 -1
- package/core/built/admin/assets/{custom-field-type-option-D0PXoSnP.js → custom-field-type-option-CsGIZk1J.js} +1 -1
- package/core/built/admin/assets/{custom-integration-modal-DCIHKN33.js → custom-integration-modal-BY37O_9X.js} +1 -1
- package/core/built/admin/assets/{data-list-CupF7bjM.js → data-list-CA2jYGPq.js} +1 -1
- package/core/built/admin/assets/{date-range-select-JPwM0yUj.js → date-range-select-DD2RKkgB.js} +1 -1
- package/core/built/admin/assets/design-and-theme-modal-DUSKM4uC.js +22 -0
- package/core/built/admin/assets/{detail-page-D8lx2SdP.js → detail-page-Dnv-CdR1.js} +1 -1
- package/core/built/admin/assets/dialog-B44iRwlc.js +1 -0
- package/core/built/admin/assets/{dirty-confirm-dialog-CmARpZQS.js → dirty-confirm-dialog-BxgQgQ6H.js} +1 -1
- package/core/built/admin/assets/{disabled-sources-indicator-BTJ2ClQu.js → disabled-sources-indicator-Cvy47bE2.js} +1 -1
- package/core/built/admin/assets/{dist-DzcfoDJ3.js → dist-8YJUlf3B.js} +1 -1
- package/core/built/admin/assets/{dist-Cb5RSHSg.js → dist-B3keLvjj.js} +1 -1
- package/core/built/admin/assets/{dist-QLZuGq7o2.js → dist-Cy8tfrp_.js} +1 -1
- package/core/built/admin/assets/{dist-BT_Z-eCn.js → dist-Dgt2cr6a.js} +1 -1
- package/core/built/admin/assets/{domain-D0SAtc-T.js → domain-Ca6KhoQt.js} +1 -1
- package/core/built/admin/assets/{dropzone-CaPOeDRZ.js → dropzone-Bb-5zQTk.js} +1 -1
- package/core/built/admin/assets/edit-profile-BdupLlus.js +1 -0
- package/core/built/admin/assets/{editor-COXn4Atu.js → editor-BP883Lpn.js} +3 -3
- package/core/built/admin/assets/{embed-signup-form-modal-BFTPf04i.js → embed-signup-form-modal-DeBMLxlL.js} +1 -1
- package/core/built/admin/assets/{empty-indicator-WB1WgT9h.js → empty-indicator-D9QdpuNX.js} +1 -1
- package/core/built/admin/assets/{explore-BsNYrubV.js → explore-FB-CimXw.js} +1 -1
- package/core/built/admin/assets/{feed-8RR1O1bK.js → feed-C1GxsmI2.js} +1 -1
- package/core/built/admin/assets/{field-LmNk7wZh.js → field-Cj8lmDOo.js} +1 -1
- package/core/built/admin/assets/{filter-sources-4C0kF1NU.js → filter-sources-D5n5bFA2.js} +1 -1
- package/core/built/admin/assets/{filters-CV5jCb9n.js → filters-DJEzkMUK.js} +1 -1
- package/core/built/admin/assets/{filters-Dmr0PoqU.js → filters-MZXvdH5D.js} +1 -1
- package/core/built/admin/assets/{first-promoter-modal-OCzSaL3B.js → first-promoter-modal-CGTGLCr5.js} +1 -1
- package/core/built/admin/assets/{ghost-403cb39badad3df411fc0ba27d220047.js → ghost-3894eedcc6968f658578c0abfe942aab.js} +2 -2
- package/core/built/admin/assets/{gift-link-modal-0mzjn5oF.js → gift-link-modal-B6v0tnRN.js} +1 -1
- package/core/built/admin/assets/{grid-CUciBfjf.js → grid-Dj29PY05.js} +1 -1
- package/core/built/admin/assets/growth-BGAJD1rs.js +3 -0
- package/core/built/admin/assets/growth-D6mhcx3q.js +1 -0
- package/core/built/admin/assets/{heading-CRZZ2FUe.js → heading-Dh5SFVjL.js} +1 -1
- package/core/built/admin/assets/history-modal-iKwUY3XR.js +1 -0
- package/core/built/admin/assets/html-field-C8qVGGC1.js +1 -0
- package/core/built/admin/assets/{images-C0XvUYMb.js → images-h8VZEQ9k.js} +1 -1
- package/core/built/admin/assets/{inbox-DZXDUt4s.js → inbox-BYd1M06Q.js} +13 -13
- package/core/built/admin/assets/index-DjQe-e5s.js +4 -0
- package/core/built/admin/assets/{index.es-BMUCj9TR.js → index.es-VihPwfeH.js} +1 -1
- package/core/built/admin/assets/{inline-Cw-gigDW.js → inline-BWSs_VzR.js} +1 -1
- package/core/built/admin/assets/{input-UHrKuvBT.js → input--W-rCTrX.js} +1 -1
- package/core/built/admin/assets/{input-group-BPAxETpQ.js → input-group-D8sCXRF5.js} +1 -1
- package/core/built/admin/assets/{input-surface-BdOe4KzO.js → input-surface-BsrIZeSF.js} +1 -1
- package/core/built/admin/assets/{integration-header-B4DyXV06.js → integration-header-Bm6IDb1A.js} +1 -1
- package/core/built/admin/assets/{invite-user-modal-BrAkxEO3.js → invite-user-modal-MdImLCaJ.js} +1 -1
- package/core/built/admin/assets/{koenig-lexical-60O_8aiO.js → koenig-lexical-_-IsVI7E.js} +1 -1
- package/core/built/admin/assets/koenig-loader-DYZpm6El.js +2 -0
- package/core/built/admin/assets/{kpi-card-fUHZlzBX.js → kpi-card-DW_2y3ug.js} +1 -1
- package/core/built/admin/assets/kpi-card-DZQk_0W8.js +1 -0
- package/core/built/admin/assets/kpi-helpers-PueTKuA6.js +1 -0
- package/core/built/admin/assets/kpi-tabs-CojDs-Qz.js +1 -0
- package/core/built/admin/assets/{label-VIG969IC.js → label-DjbT91GM.js} +1 -1
- package/core/built/admin/assets/{label-picker-BBWykUeA.js → label-picker-cB51xl1r.js} +1 -1
- package/core/built/admin/assets/layout-c_B_1hax.js +1 -0
- package/core/built/admin/assets/{link-helpers-Dtq9fxQg.js → link-helpers-MVDdnFCY.js} +1 -1
- package/core/built/admin/assets/{list-page-CdsnQR9N.js → list-page-BucXJ0hi.js} +1 -1
- package/core/built/admin/assets/{loading-indicator-SFTqyYVE.js → loading-indicator-BpFWTVgh.js} +1 -1
- package/core/built/admin/assets/{member-custom-fields-gOv6Hoh3.js → member-custom-fields-qs0dIkxM.js} +1 -1
- package/core/built/admin/assets/member-detail-B6uec2a6.js +1 -0
- package/core/built/admin/assets/members-BQF3CqhI.js +2 -0
- package/core/built/admin/assets/{modal-page-BMTzFHVO.js → modal-page-xCivTMvI.js} +1 -1
- package/core/built/admin/assets/{moderation-DzzPLDyl.js → moderation-DY4wF1Q3.js} +1 -1
- package/core/built/admin/assets/{multi-select-combobox-CGohnsxJ.js → multi-select-combobox-B6LiRzDO.js} +1 -1
- package/core/built/admin/assets/navigation-modal-DX-gNF3X.js +1 -0
- package/core/built/admin/assets/newsletter-CyQA7m3m.js +1 -0
- package/core/built/admin/assets/{newsletter-detail-modal-DQU3r4g2.js → newsletter-detail-modal-BDrptuxn.js} +1 -1
- package/core/built/admin/assets/{newsletter-emails-D5ql1rud.js → newsletter-emails-CFeLlt4z.js} +1 -1
- package/core/built/admin/assets/newsletters-DXuNmC42.js +1 -0
- package/core/built/admin/assets/{note-i8k6pjaw.js → note-Cgo2LCJ6.js} +1 -1
- package/core/built/admin/assets/notifications-BC50AMku.js +1 -0
- package/core/built/admin/assets/{offers-container-modal-BWfjSdyg.js → offers-container-modal-DWycIMzT.js} +1 -1
- package/core/built/admin/assets/{onboarding-route-Cu_ROWPn.js → onboarding-route-Dmc4IPm3.js} +1 -1
- package/core/built/admin/assets/overview-CVbFtn-k.js +1 -0
- package/core/built/admin/assets/overview-YKj7SZaK.js +1 -0
- package/core/built/admin/assets/{page-header-Cfds8pCg.js → page-header-BR_nbIPp.js} +1 -1
- package/core/built/admin/assets/{pintura-modal-TDTrJ89x.js → pintura-modal-BR9hEvS8.js} +1 -1
- package/core/built/admin/assets/popover-CCy0h5rq.js +1 -0
- package/core/built/admin/assets/{portal-frame-DjBF-uy2.js → portal-frame-dc4XKr0e.js} +1 -1
- package/core/built/admin/assets/portal-modal-BvvdF_B9.js +1 -0
- package/core/built/admin/assets/{post-analytics-Buz1COoY.js → post-analytics-DX470WRG.js} +1 -1
- package/core/built/admin/assets/{post-analytics-header-B-P0eFnT.js → post-analytics-header-CXpJmdDv.js} +1 -1
- package/core/built/admin/assets/{post-analytics-provider-Cu3jNeFh.js → post-analytics-provider-CLfKGWZy.js} +1 -1
- package/core/built/admin/assets/{post-share-modal-P1_M6o-H.js → post-share-modal-Cl0NXRJr.js} +1 -1
- package/core/built/admin/assets/{preferences-Cq1aOiLy.js → preferences-DO0UUWFp.js} +2 -2
- package/core/built/admin/assets/{preview-chrome-BOVO6_PE.js → preview-chrome-BljUBlOk.js} +1 -1
- package/core/built/admin/assets/{preview-modal-MlTjP8UU.js → preview-modal-C-BL-F9k.js} +1 -1
- package/core/built/admin/assets/profile-CxT-0l4d.js +1 -0
- package/core/built/admin/assets/radio-group-Bgz60i81.js +1 -0
- package/core/built/admin/assets/{router-provider-CJC58zTy.js → router-provider-B0gZyiGJ.js} +1 -1
- package/core/built/admin/assets/{schemas-CRsC53ls.js → schemas-4UPic-oD.js} +2 -2
- package/core/built/admin/assets/select-DuDUFdPq.js +1 -0
- package/core/built/admin/assets/{settings-B5hJKZ5C.js → settings-BjCii7BM.js} +1 -1
- package/core/built/admin/assets/settings-b8kNzZSQ.js +4 -0
- package/core/built/admin/assets/{settings-breadcrumbs-sLDNedBW.js → settings-breadcrumbs-CyP_9zTo.js} +1 -1
- package/core/built/admin/assets/{shade-app-F7WxOyfk-nufqw1hd.js → shade-app-CcS3f8MZ-vwURazk8.js} +2 -2
- package/core/built/admin/assets/{share-modal-CLBfj377.js → share-modal-BV70mr9k.js} +1 -1
- package/core/built/admin/assets/{skeleton-D7hwjdry.js → skeleton-Ce9GgUpf.js} +1 -1
- package/core/built/admin/assets/{slack-modal-Bt9I_tEo.js → slack-modal-Be2_KK-z.js} +1 -1
- package/core/built/admin/assets/sort-button-Cc-Z96sA.js +1 -0
- package/core/built/admin/assets/{source-icon-BPsD5ees.js → source-icon-v6PUnmyM.js} +1 -1
- package/core/built/admin/assets/{stack-CIfOAAVf.js → stack-B2eszIiq.js} +1 -1
- package/core/built/admin/assets/{stats-B_YkF7bp.js → stats-C4reGh9O.js} +1 -1
- package/core/built/admin/assets/{stats-view-BOCp9RG8.js → stats-view-DP9pQ62k.js} +1 -1
- package/core/built/admin/assets/{step-1-CMta6YFO.js → step-1-DSRp2vBj.js} +1 -1
- package/core/built/admin/assets/{step-2-BG04nh5q.js → step-2-COqv2g0u.js} +1 -1
- package/core/built/admin/assets/{step-3-ZnMaVIPj.js → step-3-6W1NMVQc.js} +2 -2
- package/core/built/admin/assets/{stripe-button-DDoUKN5a.js → stripe-button-D2K42Uty.js} +1 -1
- package/core/built/admin/assets/{stripe-connect-modal-BeSukI8q.js → stripe-connect-modal-Z-UT_BGc.js} +1 -1
- package/core/built/admin/assets/{switch-C9djUIMO.js → switch-CI4gLWqb.js} +1 -1
- package/core/built/admin/assets/{table-CrqQtkR2.js → table-B2pIKjVh.js} +1 -1
- package/core/built/admin/assets/{tabs-CGisSbWq.js → tabs-SaW_UT-Q.js} +1 -1
- package/core/built/admin/assets/tag-detail-Dc0nTOtU.js +2 -0
- package/core/built/admin/assets/tags-BLaXBwnb.js +1 -0
- package/core/built/admin/assets/testimonials-modal-sFwRnNLh.js +1 -0
- package/core/built/admin/assets/{text-DU9Hv33_.js → text-BQDSDsKs.js} +1 -1
- package/core/built/admin/assets/{textarea-d9qEkMOP.js → textarea-DJ1Q5V39.js} +1 -1
- package/core/built/admin/assets/{tier-detail-modal-CxRwgTPR.js → tier-detail-modal-BCFpWwUS.js} +1 -1
- package/core/built/admin/assets/{toggle-group-CtKZURJd.js → toggle-group-EM9WpESu.js} +1 -1
- package/core/built/admin/assets/{topic-filter-D8JT8Tq1.js → topic-filter-DY4gNHn2.js} +1 -1
- package/core/built/admin/assets/{transistor-modal-6PUf0idx.js → transistor-modal-CpyPG-MH.js} +1 -1
- package/core/built/admin/assets/trend-badge-ByMkuAuH.js +1 -0
- package/core/built/admin/assets/{unsplash-modal-BPuDBPja.js → unsplash-modal-Cv2Q6GtY.js} +1 -1
- package/core/built/admin/assets/{use-analytics-data--opuzwcz.js → use-analytics-data-CHvjMYuT.js} +1 -1
- package/core/built/admin/assets/use-check-theme-limit-error-Qv4SVXqw.js +2 -0
- package/core/built/admin/assets/use-filter-params-CAvfDvf1.js +1 -0
- package/core/built/admin/assets/use-growth-stats-D6mZXGhK.js +1 -0
- package/core/built/admin/assets/{use-limiter-TDSNiHPB.js → use-limiter-cwJvsNBo.js} +1 -1
- package/core/built/admin/assets/{use-navigate-with-base-path-CK989MlC.js → use-navigate-with-base-path-BHPA228f.js} +1 -1
- package/core/built/admin/assets/{use-pintura-config-CnCGrDFk.js → use-pintura-config-CzTfnufz.js} +1 -1
- package/core/built/admin/assets/{use-pintura-editor-ntphvtUd.js → use-pintura-editor-BDBXWUYq.js} +1 -1
- package/core/built/admin/assets/{use-post-referrers-CbXLFIex.js → use-post-referrers-DbY-mzci.js} +1 -1
- package/core/built/admin/assets/{use-reply-chain-data-JYFKSO83.js → use-reply-chain-data-BeQwz8oF.js} +1 -1
- package/core/built/admin/assets/{use-router-history-entry-BwfQS2mq.js → use-router-history-entry-Bg6BhBQQ.js} +1 -1
- package/core/built/admin/assets/{use-setting-group-DQxV42-O.js → use-setting-group-VM7FQwMY.js} +1 -1
- package/core/built/admin/assets/{use-settings-navigation-BBzro2-V.js → use-settings-navigation-BbrSUVcf.js} +1 -1
- package/core/built/admin/assets/{use-simple-pagination-B2TdNX67.js → use-simple-pagination-Dum6Irbs.js} +1 -1
- package/core/built/admin/assets/{use-staff-users-QrR9voeC.js → use-staff-users-cZg4ugOF.js} +1 -1
- package/core/built/admin/assets/{use-tinybird-query-D2Aeoty5.js → use-tinybird-query-B1IMyAcv.js} +1 -1
- package/core/built/admin/assets/{use-tinybird-token-DBuwMmln.js → use-tinybird-token-Bow0Zwn8.js} +1 -1
- package/core/built/admin/assets/{use-unsaved-changes-guard-DpYJcj1d.js → use-unsaved-changes-guard-BAy0RANR.js} +1 -1
- package/core/built/admin/assets/{use-url-input-WnIqckzS.js → use-url-input-Df5QzNa7.js} +1 -1
- package/core/built/admin/assets/user-detail-modal-yipSoQfv.js +1 -0
- package/core/built/admin/assets/{virtual-list-D3MfPNOh.js → virtual-list-DEx8WgiO.js} +1 -1
- package/core/built/admin/assets/web-CKcXAu86.js +1 -0
- package/core/built/admin/assets/web-DR4TqM3E.js +2 -0
- package/core/built/admin/assets/{zapier-modal-BO6PS_Vd.js → zapier-modal-Cw3BTBUu.js} +1 -1
- package/core/built/admin/index.html +24 -25
- package/core/frontend/services/rendering/renderer.js +15 -0
- package/core/server/adapters/storage/LocalStorageBase.js +8 -5
- package/core/server/api/endpoints/db.js +19 -5
- package/core/server/api/endpoints/index.js +4 -0
- package/core/server/api/endpoints/member-custom-fields.js +4 -14
- package/core/server/api/endpoints/posts.js +1 -0
- package/core/server/api/endpoints/tiers-checkout-config.js +59 -0
- package/core/server/api/endpoints/utils/serializers/output/config.js +1 -0
- package/core/server/api/endpoints/utils/serializers/output/index.js +4 -0
- package/core/server/api/endpoints/utils/serializers/output/tiers-checkout-config.js +12 -0
- package/core/server/data/exporter/table-lists.js +3 -0
- package/core/server/data/importer/content-files.js +57 -0
- package/core/server/data/importer/handlers/image.js +2 -2
- package/core/server/data/importer/import-archive.js +131 -0
- package/core/server/data/importer/import-manager.js +18 -180
- package/core/server/data/importer/importers/content-file-importer.js +66 -4
- 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
- package/core/server/data/migrations/versions/6.61/2026-08-19-14-38-53-add-members-custom-field-bindings-table.js +26 -0
- package/core/server/data/migrations/versions/6.61/2026-08-19-14-48-06-add-tier-checkout-field-tables.js +35 -0
- package/core/server/data/schema/schema.js +90 -0
- package/core/server/data/seeders/importers/automation-action-revisions-importer.js +3 -3
- package/core/server/data/seeders/importers/automation-actions-importer.js +3 -3
- package/core/server/data/seeders/importers/automation-run-steps-importer.js +3 -3
- package/core/server/data/seeders/importers/automation-runs-importer.js +5 -5
- package/core/server/data/seeders/importers/automations-importer.js +3 -3
- package/core/server/data/seeders/importers/comment-reports-importer.js +1 -1
- package/core/server/data/seeders/importers/comments-importer.js +1 -1
- package/core/server/data/seeders/importers/email-batches-importer.js +1 -1
- package/core/server/data/seeders/importers/email-recipients-importer.js +1 -1
- package/core/server/data/seeders/importers/emails-importer.js +1 -1
- package/core/server/data/seeders/importers/labels-importer.js +1 -1
- package/core/server/data/seeders/importers/members-click-events-importer.js +1 -1
- package/core/server/data/seeders/importers/members-created-events-importer.js +1 -1
- package/core/server/data/seeders/importers/members-feedback-importer.js +1 -1
- package/core/server/data/seeders/importers/members-importer.js +1 -1
- package/core/server/data/seeders/importers/members-login-events-importer.js +1 -1
- package/core/server/data/seeders/importers/members-products-importer.js +1 -1
- package/core/server/data/seeders/importers/members-status-events-importer.js +1 -1
- package/core/server/data/seeders/importers/members-stripe-customers-importer.js +1 -1
- package/core/server/data/seeders/importers/members-stripe-customers-subscriptions-importer.js +1 -1
- package/core/server/data/seeders/importers/members-subscribe-events-importer.js +1 -1
- package/core/server/data/seeders/importers/members-subscription-created-events-importer.js +1 -1
- package/core/server/data/seeders/importers/offer-redemptions-importer.js +1 -1
- package/core/server/data/seeders/importers/offers-importer.js +1 -1
- package/core/server/data/seeders/importers/posts-importer.js +1 -1
- package/core/server/data/seeders/importers/table-importer.js +2 -2
- package/core/server/data/seeders/importers/tags-importer.js +1 -1
- package/core/server/data/seeders/importers/users-importer.js +1 -1
- package/core/server/data/seeders/importers/web-mentions-importer.js +1 -1
- package/core/server/data/seeders/utils/random.js +3 -3
- package/core/server/ghost-server.js +3 -2
- package/core/server/lib/db-types/boolean.js +18 -0
- package/core/server/lib/promise-pool.js +31 -0
- package/core/server/services/automations/database-automations-repository.js +26 -26
- package/core/server/services/automations/poll.js +1 -0
- package/core/server/services/content-import/import/assets.js +74 -0
- package/core/server/services/content-import/import/importer.js +57 -14
- package/core/server/services/content-import/import/post-data.js +1 -0
- package/core/server/services/content-import/import/post-repository.js +78 -0
- package/core/server/services/content-import/import/relations.js +149 -0
- package/core/server/services/content-import/import/row.js +11 -0
- package/core/server/services/content-import/import/schema.js +29 -0
- package/core/server/services/content-import/import/source.js +125 -0
- package/core/server/services/content-import/index.js +6 -28
- package/core/server/services/email-analytics/email-analytics-service.js +8 -1
- package/core/server/services/email-analytics/lib/queries.js +7 -1
- package/core/server/services/gift-links/schema.js +3 -3
- package/core/server/services/gifts/CONTEXT.md +1 -1
- package/core/server/services/gifts/constants.js +1 -1
- package/core/server/services/gifts/gift-bookshelf-repository.js +2 -2
- package/core/server/services/gifts/gift-delivery-bookshelf-repository.js +18 -9
- package/core/server/services/gifts/gift-delivery-schema.js +5 -5
- package/core/server/services/gifts/gift-delivery-service.js +4 -0
- package/core/server/services/gifts/gift-schema.js +10 -10
- package/core/server/services/gifts/gift-service.js +4 -2
- package/core/server/services/jobs-service/register-job-handlers.js +5 -5
- package/core/server/services/lib/mailgun-client.js +44 -8
- package/core/server/services/media-inliner/external-media-inliner-job.js +12 -0
- package/core/server/services/media-inliner/external-media-inliner.js +103 -29
- package/core/server/services/media-inliner/service.js +13 -41
- package/core/server/services/media-inliner/types.js +2 -0
- package/core/server/services/members/import-export/export/exporter.js +4 -6
- package/core/server/services/members/import-export/import/importer.js +21 -5
- package/core/server/services/members/import-export/import/stripe-utils.js +6 -1
- package/core/server/services/members/import-export/index.js +6 -1
- package/core/server/services/members/members-api/members-api.js +5 -0
- package/core/server/services/members/members-api/services/member-bread-service.js +19 -1
- package/core/server/services/members/members-api/services/payments-service.js +47 -1
- package/core/server/services/members-custom-fields/actions.js +27 -1
- package/core/server/services/members-custom-fields/bindings-service.js +119 -0
- package/core/server/services/members-custom-fields/definitions-service.js +104 -13
- package/core/server/services/members-custom-fields/index.js +11 -4
- package/core/server/services/members-custom-fields/queries.js +5 -0
- package/core/server/services/members-custom-fields/schema.js +37 -6
- package/core/server/services/members-custom-fields/values-service.js +15 -3
- package/core/server/services/public-config/config.js +7 -0
- package/core/server/services/stripe/services/checkout/allowed-countries.js +267 -0
- package/core/server/services/stripe/services/checkout/completed-session.js +68 -0
- package/core/server/services/stripe/services/checkout/field-ports.js +34 -0
- package/core/server/services/stripe/services/checkout/session-options.js +97 -0
- package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +49 -0
- package/core/server/services/stripe/stripe-api.js +29 -0
- package/core/server/services/stripe/stripe-service.js +7 -0
- package/core/server/services/tier-checkout-config/codec.js +95 -0
- package/core/server/services/tier-checkout-config/destinations.js +17 -0
- package/core/server/services/tier-checkout-config/index.js +26 -0
- package/core/server/services/tier-checkout-config/models.js +57 -0
- package/core/server/services/tier-checkout-config/queries.js +80 -0
- package/core/server/services/tier-checkout-config/schema.js +33 -0
- package/core/server/services/tier-checkout-config/serializers.js +122 -0
- package/core/server/services/tier-checkout-config/service.js +303 -0
- package/core/server/services/tiers/service.js +21 -0
- package/core/server/web/api/endpoints/admin/routes.js +24 -13
- package/core/server/web/api/middleware/upload.js +2 -2
- package/core/server/web/parent/app.js +5 -0
- package/core/server/web/parent/middleware/filter-query-parameters.js +94 -0
- package/core/server/web/parent/middleware/index.js +1 -0
- package/core/server/web/query-parameter-policy/index.js +9 -0
- package/core/server/web/query-parameter-policy/policy.json +58 -0
- package/core/server/web/query-parameter-policy/schema.js +38 -0
- package/core/shared/config/defaults.json +3 -0
- package/core/shared/config/env/config.testing-mysql.json +3 -0
- package/core/shared/config/env/config.testing.json +3 -0
- package/core/shared/config/overrides.json +4 -2
- package/core/shared/labs.js +5 -14
- package/package.json +12 -13
- package/pnpm-lock.yaml +44 -46
- package/pnpm-workspace.yaml +6 -6
- package/tsconfig.json +2 -3
- package/core/built/admin/assets/activitypub/layout-CXajhRsL.js +0 -1
- package/core/built/admin/assets/alert-dialog-wEbVxANM.js +0 -1
- package/core/built/admin/assets/app-utils-D2Wp7ZSS.js +0 -1
- package/core/built/admin/assets/audience-DTLMXAFH.js +0 -1
- package/core/built/admin/assets/chart-helpers-B3OqQ6Ez.js +0 -1
- package/core/built/admin/assets/command-DcLbSifC.js +0 -1
- package/core/built/admin/assets/comments-Bxy_3WyE.js +0 -1
- package/core/built/admin/assets/design-and-theme-modal-CZ-PkW7o.js +0 -23
- package/core/built/admin/assets/dialog-Db7c164G.js +0 -1
- package/core/built/admin/assets/edit-profile-By7v5XW5.js +0 -1
- package/core/built/admin/assets/growth-55vWlGT_.js +0 -1
- package/core/built/admin/assets/growth-DA5AluYw.js +0 -3
- package/core/built/admin/assets/history-modal-G1s5hHz7.js +0 -1
- package/core/built/admin/assets/html-field-BegxsWpw.js +0 -1
- package/core/built/admin/assets/index-CDP9tIOk.js +0 -4
- package/core/built/admin/assets/koenig-loader-DwVY_V-H.js +0 -1
- package/core/built/admin/assets/kpi-card-LERqWBoY.js +0 -1
- package/core/built/admin/assets/kpi-helpers-DB3ouhYF.js +0 -1
- package/core/built/admin/assets/kpi-tabs-BGvtMD8S.js +0 -1
- package/core/built/admin/assets/layout-Di5K7doM.js +0 -1
- package/core/built/admin/assets/member-detail-D7mZDDp3.js +0 -1
- package/core/built/admin/assets/member-route-0Aa52Ntz.js +0 -1
- package/core/built/admin/assets/members-DvZG9t69.js +0 -2
- package/core/built/admin/assets/navigation-modal-CI8Bx5vn.js +0 -1
- package/core/built/admin/assets/newsletter-Bg3cq5U-.js +0 -1
- package/core/built/admin/assets/newsletters-DMDfZbMS.js +0 -1
- package/core/built/admin/assets/notifications-psA_2Ph4.js +0 -1
- package/core/built/admin/assets/overview-C-6xOLaf.js +0 -1
- package/core/built/admin/assets/overview-DaLhpRrC.js +0 -1
- package/core/built/admin/assets/popover-CFgqFDvC.js +0 -1
- package/core/built/admin/assets/portal-modal-Cf0pBAk8.js +0 -1
- package/core/built/admin/assets/profile-D6dHYf2o.js +0 -1
- package/core/built/admin/assets/radio-group-CjtmsCPl.js +0 -1
- package/core/built/admin/assets/select-D_RQaXgt.js +0 -1
- package/core/built/admin/assets/settings-DIo_F-MF.js +0 -4
- package/core/built/admin/assets/sort-button-DMBXF7tP.js +0 -1
- package/core/built/admin/assets/tag-detail-2a3BfzTW.js +0 -2
- package/core/built/admin/assets/tags-Dp2_8UzL.js +0 -1
- package/core/built/admin/assets/testimonials-modal-C9nrypNo.js +0 -1
- package/core/built/admin/assets/use-check-theme-limit-error-C9-QhGdV.js +0 -1
- package/core/built/admin/assets/use-filter-params-CSpAvgD2.js +0 -1
- package/core/built/admin/assets/use-growth-stats-BOmoPDHJ.js +0 -1
- package/core/built/admin/assets/user-detail-modal-59mBJqxN.js +0 -1
- package/core/built/admin/assets/web-DUuX7nE2.js +0 -2
- package/core/built/admin/assets/web-N8ucs2aG.js +0 -1
- /package/core/server/lib/{db-date.js → db-types/date.js} +0 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.STRIPE_ALLOWED_COUNTRIES = void 0;
|
|
4
|
+
exports.isStripeAllowedCountry = isStripeAllowedCountry;
|
|
5
|
+
/**
|
|
6
|
+
* The countries Stripe Checkout will accept in `shipping_address_collection`.
|
|
7
|
+
*
|
|
8
|
+
* Not a general list of countries. This is not a question about which places exist, it is
|
|
9
|
+
* a question about where this payment processor will ship, and only the processor's answer
|
|
10
|
+
* decides whether a session can be created at all. A general ISO list gets it wrong in both
|
|
11
|
+
* directions: it omits places Stripe accepts, and it includes the sanctioned countries
|
|
12
|
+
* Stripe refuses.
|
|
13
|
+
*
|
|
14
|
+
* Measured against the live API at the pinned version by `e2e/scripts/probe-stripe-constraints.ts`,
|
|
15
|
+
* not read from the SDK's `AllowedCountry` union, because that union is wrong: it omits
|
|
16
|
+
* `SD`, which the live API accepts. Every other code the union carries was confirmed
|
|
17
|
+
* accepted, so the union is a subset of this list rather than a different one — which is
|
|
18
|
+
* what the accompanying test holds it to, so a country Stripe adds cannot pass unnoticed.
|
|
19
|
+
*
|
|
20
|
+
* A code Stripe rejects fails the whole session create, which is a publisher who cannot
|
|
21
|
+
* sell. So this is checked when a publisher chooses a country rather than when a member
|
|
22
|
+
* tries to buy.
|
|
23
|
+
*/
|
|
24
|
+
exports.STRIPE_ALLOWED_COUNTRIES = [
|
|
25
|
+
'AC',
|
|
26
|
+
'AD',
|
|
27
|
+
'AE',
|
|
28
|
+
'AF',
|
|
29
|
+
'AG',
|
|
30
|
+
'AI',
|
|
31
|
+
'AL',
|
|
32
|
+
'AM',
|
|
33
|
+
'AO',
|
|
34
|
+
'AQ',
|
|
35
|
+
'AR',
|
|
36
|
+
'AT',
|
|
37
|
+
'AU',
|
|
38
|
+
'AW',
|
|
39
|
+
'AX',
|
|
40
|
+
'AZ',
|
|
41
|
+
'BA',
|
|
42
|
+
'BB',
|
|
43
|
+
'BD',
|
|
44
|
+
'BE',
|
|
45
|
+
'BF',
|
|
46
|
+
'BG',
|
|
47
|
+
'BH',
|
|
48
|
+
'BI',
|
|
49
|
+
'BJ',
|
|
50
|
+
'BL',
|
|
51
|
+
'BM',
|
|
52
|
+
'BN',
|
|
53
|
+
'BO',
|
|
54
|
+
'BQ',
|
|
55
|
+
'BR',
|
|
56
|
+
'BS',
|
|
57
|
+
'BT',
|
|
58
|
+
'BV',
|
|
59
|
+
'BW',
|
|
60
|
+
'BY',
|
|
61
|
+
'BZ',
|
|
62
|
+
'CA',
|
|
63
|
+
'CD',
|
|
64
|
+
'CF',
|
|
65
|
+
'CG',
|
|
66
|
+
'CH',
|
|
67
|
+
'CI',
|
|
68
|
+
'CK',
|
|
69
|
+
'CL',
|
|
70
|
+
'CM',
|
|
71
|
+
'CN',
|
|
72
|
+
'CO',
|
|
73
|
+
'CR',
|
|
74
|
+
'CV',
|
|
75
|
+
'CW',
|
|
76
|
+
'CY',
|
|
77
|
+
'CZ',
|
|
78
|
+
'DE',
|
|
79
|
+
'DJ',
|
|
80
|
+
'DK',
|
|
81
|
+
'DM',
|
|
82
|
+
'DO',
|
|
83
|
+
'DZ',
|
|
84
|
+
'EC',
|
|
85
|
+
'EE',
|
|
86
|
+
'EG',
|
|
87
|
+
'EH',
|
|
88
|
+
'ER',
|
|
89
|
+
'ES',
|
|
90
|
+
'ET',
|
|
91
|
+
'FI',
|
|
92
|
+
'FJ',
|
|
93
|
+
'FK',
|
|
94
|
+
'FO',
|
|
95
|
+
'FR',
|
|
96
|
+
'GA',
|
|
97
|
+
'GB',
|
|
98
|
+
'GD',
|
|
99
|
+
'GE',
|
|
100
|
+
'GF',
|
|
101
|
+
'GG',
|
|
102
|
+
'GH',
|
|
103
|
+
'GI',
|
|
104
|
+
'GL',
|
|
105
|
+
'GM',
|
|
106
|
+
'GN',
|
|
107
|
+
'GP',
|
|
108
|
+
'GQ',
|
|
109
|
+
'GR',
|
|
110
|
+
'GS',
|
|
111
|
+
'GT',
|
|
112
|
+
'GU',
|
|
113
|
+
'GW',
|
|
114
|
+
'GY',
|
|
115
|
+
'HK',
|
|
116
|
+
'HN',
|
|
117
|
+
'HR',
|
|
118
|
+
'HT',
|
|
119
|
+
'HU',
|
|
120
|
+
'ID',
|
|
121
|
+
'IE',
|
|
122
|
+
'IL',
|
|
123
|
+
'IM',
|
|
124
|
+
'IN',
|
|
125
|
+
'IO',
|
|
126
|
+
'IQ',
|
|
127
|
+
'IS',
|
|
128
|
+
'IT',
|
|
129
|
+
'JE',
|
|
130
|
+
'JM',
|
|
131
|
+
'JO',
|
|
132
|
+
'JP',
|
|
133
|
+
'KE',
|
|
134
|
+
'KG',
|
|
135
|
+
'KH',
|
|
136
|
+
'KI',
|
|
137
|
+
'KM',
|
|
138
|
+
'KN',
|
|
139
|
+
'KR',
|
|
140
|
+
'KW',
|
|
141
|
+
'KY',
|
|
142
|
+
'KZ',
|
|
143
|
+
'LA',
|
|
144
|
+
'LB',
|
|
145
|
+
'LC',
|
|
146
|
+
'LI',
|
|
147
|
+
'LK',
|
|
148
|
+
'LR',
|
|
149
|
+
'LS',
|
|
150
|
+
'LT',
|
|
151
|
+
'LU',
|
|
152
|
+
'LV',
|
|
153
|
+
'LY',
|
|
154
|
+
'MA',
|
|
155
|
+
'MC',
|
|
156
|
+
'MD',
|
|
157
|
+
'ME',
|
|
158
|
+
'MF',
|
|
159
|
+
'MG',
|
|
160
|
+
'MK',
|
|
161
|
+
'ML',
|
|
162
|
+
'MM',
|
|
163
|
+
'MN',
|
|
164
|
+
'MO',
|
|
165
|
+
'MQ',
|
|
166
|
+
'MR',
|
|
167
|
+
'MS',
|
|
168
|
+
'MT',
|
|
169
|
+
'MU',
|
|
170
|
+
'MV',
|
|
171
|
+
'MW',
|
|
172
|
+
'MX',
|
|
173
|
+
'MY',
|
|
174
|
+
'MZ',
|
|
175
|
+
'NA',
|
|
176
|
+
'NC',
|
|
177
|
+
'NE',
|
|
178
|
+
'NG',
|
|
179
|
+
'NI',
|
|
180
|
+
'NL',
|
|
181
|
+
'NO',
|
|
182
|
+
'NP',
|
|
183
|
+
'NR',
|
|
184
|
+
'NU',
|
|
185
|
+
'NZ',
|
|
186
|
+
'OM',
|
|
187
|
+
'PA',
|
|
188
|
+
'PE',
|
|
189
|
+
'PF',
|
|
190
|
+
'PG',
|
|
191
|
+
'PH',
|
|
192
|
+
'PK',
|
|
193
|
+
'PL',
|
|
194
|
+
'PM',
|
|
195
|
+
'PN',
|
|
196
|
+
'PR',
|
|
197
|
+
'PS',
|
|
198
|
+
'PT',
|
|
199
|
+
'PY',
|
|
200
|
+
'QA',
|
|
201
|
+
'RE',
|
|
202
|
+
'RO',
|
|
203
|
+
'RS',
|
|
204
|
+
'RU',
|
|
205
|
+
'RW',
|
|
206
|
+
'SA',
|
|
207
|
+
'SB',
|
|
208
|
+
'SC',
|
|
209
|
+
'SD',
|
|
210
|
+
'SE',
|
|
211
|
+
'SG',
|
|
212
|
+
'SH',
|
|
213
|
+
'SI',
|
|
214
|
+
'SJ',
|
|
215
|
+
'SK',
|
|
216
|
+
'SL',
|
|
217
|
+
'SM',
|
|
218
|
+
'SN',
|
|
219
|
+
'SO',
|
|
220
|
+
'SR',
|
|
221
|
+
'SS',
|
|
222
|
+
'ST',
|
|
223
|
+
'SV',
|
|
224
|
+
'SX',
|
|
225
|
+
'SZ',
|
|
226
|
+
'TA',
|
|
227
|
+
'TC',
|
|
228
|
+
'TD',
|
|
229
|
+
'TF',
|
|
230
|
+
'TG',
|
|
231
|
+
'TH',
|
|
232
|
+
'TJ',
|
|
233
|
+
'TK',
|
|
234
|
+
'TL',
|
|
235
|
+
'TM',
|
|
236
|
+
'TN',
|
|
237
|
+
'TO',
|
|
238
|
+
'TR',
|
|
239
|
+
'TT',
|
|
240
|
+
'TV',
|
|
241
|
+
'TW',
|
|
242
|
+
'TZ',
|
|
243
|
+
'UA',
|
|
244
|
+
'UG',
|
|
245
|
+
'US',
|
|
246
|
+
'UY',
|
|
247
|
+
'UZ',
|
|
248
|
+
'VA',
|
|
249
|
+
'VC',
|
|
250
|
+
'VE',
|
|
251
|
+
'VG',
|
|
252
|
+
'VN',
|
|
253
|
+
'VU',
|
|
254
|
+
'WF',
|
|
255
|
+
'WS',
|
|
256
|
+
'XK',
|
|
257
|
+
'YE',
|
|
258
|
+
'YT',
|
|
259
|
+
'ZA',
|
|
260
|
+
'ZM',
|
|
261
|
+
'ZW',
|
|
262
|
+
'ZZ',
|
|
263
|
+
];
|
|
264
|
+
const ALLOWED = new Set(exports.STRIPE_ALLOWED_COUNTRIES);
|
|
265
|
+
function isStripeAllowedCountry(code) {
|
|
266
|
+
return ALLOWED.has(code);
|
|
267
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.collectedByPort = exports.CompletedSession = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const field_ports_1 = require("./field-ports");
|
|
6
|
+
/**
|
|
7
|
+
* What Ghost reads off a completed session.
|
|
8
|
+
*
|
|
9
|
+
* `shipping` is where the address lives at Ghost's pinned Stripe API version; later
|
|
10
|
+
* versions moved it to `collected_information.shipping_details`. An Event is an immutable
|
|
11
|
+
* snapshot rendered at the account's version, so nothing in a payload would warn us if
|
|
12
|
+
* that pin ever changed.
|
|
13
|
+
*
|
|
14
|
+
* A tax number is deliberately not read: Stripe keeps it against the customer it invoices
|
|
15
|
+
* and Ghost never stores one.
|
|
16
|
+
*/
|
|
17
|
+
const Collected = zod_1.z
|
|
18
|
+
.string()
|
|
19
|
+
.nullish()
|
|
20
|
+
.transform((given) => (given && given.trim() !== '' ? given : undefined));
|
|
21
|
+
exports.CompletedSession = zod_1.z
|
|
22
|
+
.object({
|
|
23
|
+
custom_fields: zod_1.z
|
|
24
|
+
.array(zod_1.z
|
|
25
|
+
.object({
|
|
26
|
+
key: zod_1.z.string().nullish(),
|
|
27
|
+
text: zod_1.z.object({ value: Collected }).nullish(),
|
|
28
|
+
})
|
|
29
|
+
.nullable())
|
|
30
|
+
.nullish(),
|
|
31
|
+
shipping: zod_1.z
|
|
32
|
+
.object({
|
|
33
|
+
name: Collected,
|
|
34
|
+
address: zod_1.z.record(zod_1.z.string(), Collected).nullish(),
|
|
35
|
+
})
|
|
36
|
+
.nullish(),
|
|
37
|
+
customer_details: zod_1.z.object({ phone: Collected }).nullish(),
|
|
38
|
+
})
|
|
39
|
+
.loose();
|
|
40
|
+
/** Our address type needs at least one part; an empty value would erase what is there. */
|
|
41
|
+
function addressValue(address) {
|
|
42
|
+
const value = Object.fromEntries(Object.entries(address ?? {}).filter((entry) => entry[1] !== undefined));
|
|
43
|
+
return Object.keys(value).length > 0 ? value : undefined;
|
|
44
|
+
}
|
|
45
|
+
const PORT_VALUES = {
|
|
46
|
+
// Stripe returns the recipient's name alongside the address rather than as part of it,
|
|
47
|
+
// while Ghost keeps a name and an address in two separate custom fields. So the name is
|
|
48
|
+
// carried back separately here, under its own name, to be routed to its own field.
|
|
49
|
+
shipping_name: (session) => session.shipping?.name,
|
|
50
|
+
shipping_address: (session) => addressValue(session.shipping?.address),
|
|
51
|
+
phone: (session) => session.customer_details?.phone,
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Everything a completed checkout gives back, as a list of pairs: the name Stripe used for
|
|
55
|
+
* a value, and the value itself. Answers to questions and values Stripe collected on its
|
|
56
|
+
* own both come back this way, because both are saved by the same route afterwards.
|
|
57
|
+
*
|
|
58
|
+
* Order matters. The values Stripe collected come last, so that if a question's answer and
|
|
59
|
+
* a collected value are both saved into the same custom field, the collected value is the
|
|
60
|
+
* one the field ends up holding.
|
|
61
|
+
*/
|
|
62
|
+
exports.collectedByPort = exports.CompletedSession.transform((session) => {
|
|
63
|
+
const answers = (session.custom_fields ?? [])
|
|
64
|
+
.filter((field) => Boolean(field?.key && field.text?.value))
|
|
65
|
+
.map((field) => ({ port: field.key, value: field.text.value }));
|
|
66
|
+
const ports = field_ports_1.STRIPE_PORTS.map((port) => ({ port, value: PORT_VALUES[port](session) })).filter((entry) => entry.value !== undefined);
|
|
67
|
+
return [...answers, ...ports];
|
|
68
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* What Stripe Checkout will render, measured against the live API at Ghost's pinned
|
|
4
|
+
* version rather than read from the reference — which disagreed with the API in three of
|
|
5
|
+
* five probes, missing the field cap and the key format entirely. A wrong bound here fails
|
|
6
|
+
* the session create, which fails the checkout.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.CHECKOUT_ELIGIBLE_FIELD_TYPES = exports.MAX_CHECKOUT_LABEL_LENGTH = exports.MAX_CHECKOUT_CUSTOM_FIELDS = exports.STRIPE_PORT = exports.STRIPE_PORTS = void 0;
|
|
10
|
+
exports.isStripePort = isStripePort;
|
|
11
|
+
exports.isCheckoutEligible = isCheckoutEligible;
|
|
12
|
+
/** The names Stripe returns values under, and the only ports a binding for it may use. */
|
|
13
|
+
exports.STRIPE_PORTS = ['shipping_name', 'shipping_address', 'phone'];
|
|
14
|
+
function isStripePort(key) {
|
|
15
|
+
return exports.STRIPE_PORTS.includes(key);
|
|
16
|
+
}
|
|
17
|
+
exports.STRIPE_PORT = {
|
|
18
|
+
shippingName: 'shipping_name',
|
|
19
|
+
shippingAddress: 'shipping_address',
|
|
20
|
+
phone: 'phone',
|
|
21
|
+
};
|
|
22
|
+
/** Stripe rejects a fourth. */
|
|
23
|
+
exports.MAX_CHECKOUT_CUSTOM_FIELDS = 3;
|
|
24
|
+
/** Stripe caps a custom label at 50, where a field name may be 191 — hence a question label. */
|
|
25
|
+
exports.MAX_CHECKOUT_LABEL_LENGTH = 50;
|
|
26
|
+
/**
|
|
27
|
+
* What Stripe Checkout can ask for. No `long_text`: its text input caps shorter than that
|
|
28
|
+
* type allows. No `address`: Stripe has no custom-field equivalent, so an address is
|
|
29
|
+
* collected through its own parameter instead.
|
|
30
|
+
*/
|
|
31
|
+
exports.CHECKOUT_ELIGIBLE_FIELD_TYPES = ['short_text'];
|
|
32
|
+
function isCheckoutEligible(type) {
|
|
33
|
+
return exports.CHECKOUT_ELIGIBLE_FIELD_TYPES.includes(type);
|
|
34
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
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.stripeCheckoutCollectionOptions = stripeCheckoutCollectionOptions;
|
|
7
|
+
const logging_1 = __importDefault(require("@tryghost/logging"));
|
|
8
|
+
const field_ports_1 = require("./field-ports");
|
|
9
|
+
/** Keyed on the eligible types, so this and the configure-time rule cannot drift apart. */
|
|
10
|
+
const QUESTION_TYPES = {
|
|
11
|
+
short_text: 'text',
|
|
12
|
+
};
|
|
13
|
+
function askable(question) {
|
|
14
|
+
if (!(0, field_ports_1.isCheckoutEligible)(question.type)) {
|
|
15
|
+
logging_1.default.warn({
|
|
16
|
+
event: { name: 'stripe.checkout.question_skipped' },
|
|
17
|
+
customFieldKey: question.key,
|
|
18
|
+
fieldType: question.type,
|
|
19
|
+
reason: 'unsupported_type',
|
|
20
|
+
}, 'Skipping a Stripe checkout question');
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
if (question.prompt.length > field_ports_1.MAX_CHECKOUT_LABEL_LENGTH) {
|
|
24
|
+
logging_1.default.warn({
|
|
25
|
+
event: { name: 'stripe.checkout.question_skipped' },
|
|
26
|
+
customFieldKey: question.key,
|
|
27
|
+
promptLength: question.prompt.length,
|
|
28
|
+
reason: 'label_too_long',
|
|
29
|
+
}, 'Skipping a Stripe checkout question');
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Build the collection parameters for a checkout, or nothing at all.
|
|
36
|
+
*
|
|
37
|
+
* Returns an object with no keys when a tier asks for nothing, so a caller can spread it
|
|
38
|
+
* over its session options unconditionally and change nothing.
|
|
39
|
+
*/
|
|
40
|
+
function stripeCheckoutCollectionOptions(checkout) {
|
|
41
|
+
const options = {};
|
|
42
|
+
if (!checkout) {
|
|
43
|
+
return options;
|
|
44
|
+
}
|
|
45
|
+
const eligible = checkout.customFields.filter(askable);
|
|
46
|
+
const questions = eligible.slice(0, field_ports_1.MAX_CHECKOUT_CUSTOM_FIELDS);
|
|
47
|
+
if (questions.length < eligible.length) {
|
|
48
|
+
logging_1.default.warn({
|
|
49
|
+
event: { name: 'stripe.checkout.questions_trimmed' },
|
|
50
|
+
asked: questions.length,
|
|
51
|
+
configured: eligible.length,
|
|
52
|
+
}, 'Some Stripe checkout questions were not asked');
|
|
53
|
+
}
|
|
54
|
+
if (questions.length > 0) {
|
|
55
|
+
options.custom_fields = questions.map((question) => ({
|
|
56
|
+
// Ghost sends the custom field's own key as the question's identifier, and Stripe
|
|
57
|
+
// returns the buyer's answer labelled with that same key. Using it in both places
|
|
58
|
+
// means reading an answer is a direct lookup of the field it belongs to, with
|
|
59
|
+
// nothing in between that could map it to the wrong one.
|
|
60
|
+
key: question.key,
|
|
61
|
+
label: { type: 'custom', custom: question.prompt },
|
|
62
|
+
type: QUESTION_TYPES[question.type],
|
|
63
|
+
optional: question.optional,
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
if (checkout.shipping) {
|
|
67
|
+
// The country list is what makes this reach Stripe at all. An empty
|
|
68
|
+
// `shipping_address_collection` form-encodes to nothing, so a request built that
|
|
69
|
+
// way carries no parameter and Stripe accepts it precisely because it was never
|
|
70
|
+
// asked to collect anything — which reads as success and collects no addresses.
|
|
71
|
+
//
|
|
72
|
+
// Defended again here rather than trusted from the settings screen: this is the
|
|
73
|
+
// checkout path, and a malformed configuration must cost the collection rather than
|
|
74
|
+
// throw inside a session build.
|
|
75
|
+
if (checkout.shipping.allowedCountries.length === 0) {
|
|
76
|
+
logging_1.default.warn({
|
|
77
|
+
event: { name: 'stripe.checkout.collection_skipped' },
|
|
78
|
+
port: 'shipping_address',
|
|
79
|
+
reason: 'no_allowed_countries',
|
|
80
|
+
}, 'Skipping a Stripe checkout collection');
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
options.shipping_address_collection = {
|
|
84
|
+
allowed_countries: checkout.shipping.allowedCountries,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// Unioned with whatever automatic tax asks for. Both want the same thing, so a site
|
|
89
|
+
// running the 2024 tax beta keeps collecting and a site that asked for it starts.
|
|
90
|
+
if (checkout.taxNumber) {
|
|
91
|
+
options.tax_id_collection = { enabled: true };
|
|
92
|
+
}
|
|
93
|
+
if (checkout.phone) {
|
|
94
|
+
options.phone_number_collection = { enabled: true };
|
|
95
|
+
}
|
|
96
|
+
return options;
|
|
97
|
+
}
|
|
@@ -2,6 +2,7 @@ const _ = require('lodash');
|
|
|
2
2
|
const errors = require('@tryghost/errors');
|
|
3
3
|
const logging = require('@tryghost/logging');
|
|
4
4
|
const { canWelcomeEmailReplaceSignupPaidEmail } = require('../../../lib/member-signup-contexts');
|
|
5
|
+
const { collectedByPort } = require('../checkout/completed-session');
|
|
5
6
|
/** @typedef {import('../../../lib/member-signup-contexts').SignupContext} SignupContext */
|
|
6
7
|
|
|
7
8
|
function isStripeMetadataTrue(value) {
|
|
@@ -422,6 +423,11 @@ module.exports = class CheckoutSessionEventService {
|
|
|
422
423
|
}
|
|
423
424
|
}
|
|
424
425
|
|
|
426
|
+
// After the subscription work, and deliberately not part of it: a value the member
|
|
427
|
+
// gave us for free must never be able to fail the webhook. A throw here would make
|
|
428
|
+
// Stripe retry the event and risk doing the payment work twice.
|
|
429
|
+
await this.writeCollectedFields(member.id, session);
|
|
430
|
+
|
|
425
431
|
if (checkoutType !== 'upgrade') {
|
|
426
432
|
const ghostSignupContext = /** @type {SignupContext | undefined} */ (
|
|
427
433
|
session.metadata?.ghostSignupContext
|
|
@@ -440,4 +446,47 @@ module.exports = class CheckoutSessionEventService {
|
|
|
440
446
|
}
|
|
441
447
|
}
|
|
442
448
|
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* This service knows how to read a completed Stripe session. It does not know, and must
|
|
452
|
+
* not know, which custom field any of those values belongs in — that is what a binding
|
|
453
|
+
* decides, so no field key appears anywhere in this code.
|
|
454
|
+
*
|
|
455
|
+
* Nothing here may be fatal: a throw fails the webhook, which makes Stripe retry it and
|
|
456
|
+
* risks doing the payment work twice.
|
|
457
|
+
*
|
|
458
|
+
* @param {string} memberId
|
|
459
|
+
* @param {import('stripe').Stripe.Checkout.Session} session
|
|
460
|
+
*/
|
|
461
|
+
async writeCollectedFields(memberId, session) {
|
|
462
|
+
// Stamped at create time. A session predating this feature carries none. Read
|
|
463
|
+
// outside the try so a failure below can name the tier whose answers were lost.
|
|
464
|
+
const tierId = session.metadata?.ghostTierId;
|
|
465
|
+
|
|
466
|
+
try {
|
|
467
|
+
if (!this.deps.labsService.isSet('membersCustomFields')) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (!tierId) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
await this.deps.customFieldBindings.writeCollected(
|
|
476
|
+
memberId,
|
|
477
|
+
tierId,
|
|
478
|
+
collectedByPort.parse(session),
|
|
479
|
+
);
|
|
480
|
+
} catch (err) {
|
|
481
|
+
logging.error(
|
|
482
|
+
{
|
|
483
|
+
event: { name: 'stripe_checkout.collected_fields.write_failed' },
|
|
484
|
+
err,
|
|
485
|
+
memberId,
|
|
486
|
+
tierId,
|
|
487
|
+
},
|
|
488
|
+
'Failed to store the fields a checkout collected',
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
443
492
|
};
|
|
@@ -3,6 +3,7 @@ const debug = require('@tryghost/debug')('stripe');
|
|
|
3
3
|
const ghostConfig = require('../../../shared/config');
|
|
4
4
|
const stripe = require('stripe');
|
|
5
5
|
const i18n = require('../i18n');
|
|
6
|
+
const { stripeCheckoutCollectionOptions } = require('./services/checkout/session-options');
|
|
6
7
|
|
|
7
8
|
/* Stripe has the following rate limits:
|
|
8
9
|
* - For most APIs, 100 read requests per second in live mode, 25 read requests per second in test mode
|
|
@@ -556,6 +557,8 @@ module.exports = class StripeAPI {
|
|
|
556
557
|
* @param {string} options.customerEmail
|
|
557
558
|
* @param {number} options.trialDays
|
|
558
559
|
* @param {string} [options.coupon]
|
|
560
|
+
* @param {import('../tier-checkout-config').ResolvedCheckout} [options.checkout] What
|
|
561
|
+
* the tier's checkout asks for beyond the payment. Absent, or empty, adds nothing.
|
|
559
562
|
*
|
|
560
563
|
* @returns {Promise<ICheckoutSession>}
|
|
561
564
|
*/
|
|
@@ -636,6 +639,32 @@ module.exports = class StripeAPI {
|
|
|
636
639
|
hasCustomer: Boolean(customerId),
|
|
637
640
|
});
|
|
638
641
|
|
|
642
|
+
// Applied after automatic tax so the two agree about `tax_id_collection`: both ask
|
|
643
|
+
// for the same thing, and a site with either reason to collect gets it. Nothing is
|
|
644
|
+
// added for a tier that has configured nothing, so an unconfigured site's request
|
|
645
|
+
// is unchanged.
|
|
646
|
+
Object.assign(stripeSessionOptions, stripeCheckoutCollectionOptions(options.checkout));
|
|
647
|
+
|
|
648
|
+
// Stripe refuses to collect a tax id for a customer it may not rename:
|
|
649
|
+
//
|
|
650
|
+
// Tax ID collection requires updating business name on the customer. To enable tax
|
|
651
|
+
// ID collection for an existing customer, please set `customer_update[name]`.
|
|
652
|
+
//
|
|
653
|
+
// Measured against the live API rather than read — `pnpm --filter @tryghost/e2e
|
|
654
|
+
// stripe:probe` — because the same probe shows shipping and phone collection need no
|
|
655
|
+
// such thing. Every signed-in checkout carries a customer, so without this a tier
|
|
656
|
+
// that collects a tax number cannot be bought by an existing member.
|
|
657
|
+
//
|
|
658
|
+
// Merged rather than assigned: automatic tax sets this too, and whichever ran first
|
|
659
|
+
// must not lose its keys. Still never set without a customer, which is the shape
|
|
660
|
+
// that took the tax beta down.
|
|
661
|
+
if (stripeSessionOptions.tax_id_collection && customerId) {
|
|
662
|
+
stripeSessionOptions.customer_update = {
|
|
663
|
+
...stripeSessionOptions.customer_update,
|
|
664
|
+
name: 'auto',
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
|
|
639
668
|
const session = await this._stripe.checkout.sessions.create(stripeSessionOptions);
|
|
640
669
|
|
|
641
670
|
return session;
|
|
@@ -10,6 +10,7 @@ const InvoiceEventService = require('./services/webhook/invoice-event-service');
|
|
|
10
10
|
const CheckoutSessionEventService = require('./services/webhook/checkout-session-event-service');
|
|
11
11
|
const ChargeRefundedEventService = require('./services/webhook/charge-refunded-event-service');
|
|
12
12
|
const memberWelcomeEmailService = require('../member-welcome-emails/service');
|
|
13
|
+
const customFields = require('../members-custom-fields');
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* @typedef {object} IStripeServiceConfig
|
|
@@ -133,6 +134,12 @@ module.exports = class StripeService {
|
|
|
133
134
|
memberWelcomeEmailService.init();
|
|
134
135
|
return memberWelcomeEmailService.api.isMemberWelcomeEmailActive('paid');
|
|
135
136
|
},
|
|
137
|
+
labsService: labs,
|
|
138
|
+
// A getter because the custom field services are built during boot: reading the
|
|
139
|
+
// binding at construction would capture the empty value it had beforehand.
|
|
140
|
+
get customFieldBindings() {
|
|
141
|
+
return customFields.bindings;
|
|
142
|
+
},
|
|
136
143
|
});
|
|
137
144
|
|
|
138
145
|
const chargeRefundedEventService = new ChargeRefundedEventService({
|