ghost 6.61.0 → 6.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ghost-storage-base-3.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-cache-0.2.0.tgz +0 -0
- package/components/tryghost-adapter-base-jobs-0.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-redirects-0.0.0.tgz +0 -0
- package/components/tryghost-adapter-base-route-settings-0.0.0.tgz +0 -0
- 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-admin-api-schema-0.0.0.tgz +0 -0
- package/components/tryghost-checkout-0.0.0.tgz +0 -0
- package/components/tryghost-custom-field-types-0.0.0.tgz +0 -0
- package/components/tryghost-i18n-0.0.0.tgz +0 -0
- package/components/tryghost-kg-card-factory-5.2.4.tgz +0 -0
- package/components/tryghost-kg-clean-basic-html-4.3.4.tgz +0 -0
- package/components/tryghost-kg-converters-1.2.5.tgz +0 -0
- package/components/tryghost-kg-default-cards-10.3.5.tgz +0 -0
- package/components/tryghost-kg-default-nodes-2.2.1.tgz +0 -0
- package/components/tryghost-kg-default-transforms-1.3.4.tgz +0 -0
- package/components/tryghost-kg-html-to-lexical-1.4.0.tgz +0 -0
- package/components/tryghost-kg-lexical-html-renderer-1.5.0.tgz +0 -0
- package/components/tryghost-kg-markdown-html-renderer-7.2.4.tgz +0 -0
- package/components/tryghost-kg-utils-1.1.4.tgz +0 -0
- package/components/tryghost-nql-string-0.0.0.tgz +0 -0
- package/components/tryghost-parse-email-address-0.0.0.tgz +0 -0
- package/content/settings/README.md +1 -1
- package/content/themes/casper/.gitignore +28 -0
- package/content/themes/casper/assets/built/casper.js +1 -1
- package/content/themes/casper/assets/built/screen.css +1 -1
- package/content/themes/casper/assets/css/screen.css +2 -1
- package/content/themes/casper/assets/js/lightbox.js +63 -46
- package/content/themes/casper/package.json +6 -6
- package/content/themes/casper/page.hbs +1 -0
- package/content/themes/casper/post.hbs +1 -0
- package/content/themes/source/.gitignore +28 -0
- package/content/themes/source/assets/built/screen.css +1 -1
- package/content/themes/source/assets/built/source.js +1 -1
- package/content/themes/source/assets/css/screen.css +2 -1
- package/content/themes/source/assets/js/lightbox.js +62 -45
- package/content/themes/source/assets/js/main.js +2 -2
- package/content/themes/source/package.json +4 -4
- package/content/themes/source/partials/feature-image.hbs +1 -0
- package/core/boot.js +54 -22
- package/core/built/admin/assets/Combination-B0l4MKVh.js +41 -0
- package/core/built/admin/assets/InterVariable-DiVDrmQJ.woff2 +0 -0
- package/core/built/admin/assets/InterVariable-Italic-FCBEiFp6.woff2 +0 -0
- package/core/built/admin/assets/{about-Bve7IJS2.js → about-Dyae_UT6.js} +1 -1
- package/core/built/admin/assets/account-migration-CESa0mnX.js +1 -0
- package/core/built/admin/assets/activitypub/{account-migration-C-aej4x_.js → account-migration-By69CgCp.js} +16 -16
- package/core/built/admin/assets/activitypub/activitypub.js +9 -9
- package/core/built/admin/assets/activitypub/{bluesky-sharing-BXkA5mqV.js → bluesky-sharing-BJcPMrDd.js} +36 -36
- package/core/built/admin/assets/activitypub/{content-formatters-CHcyMFk4.js → content-formatters-3rTHg3mp.js} +3 -3
- package/core/built/admin/assets/activitypub/{domain-B3ihkPde.js → domain-DUR4xSkV.js} +121 -121
- package/core/built/admin/assets/activitypub/{edit-profile-DsZM3rTX.js → edit-profile-BqtfzxCp.js} +40 -40
- package/core/built/admin/assets/activitypub/{explore-BodNrZgR.js → explore-BxuJd-J4.js} +26 -26
- package/core/built/admin/assets/activitypub/{feed-PwH1iJ84.js → feed-BM1TcksA.js} +48 -48
- package/core/built/admin/assets/activitypub/{field-D06-kmOJ.js → field-Dn7HHx2-.js} +2 -2
- package/core/built/admin/assets/activitypub/inbox-CCjkuow2.js +1284 -0
- package/core/built/admin/assets/activitypub/label-1AA_s9Fa.js +16 -0
- package/core/built/admin/assets/activitypub/layout-2-0bw6HN.js +1 -0
- package/core/built/admin/assets/activitypub/{moderation-D1Yapsod.js → moderation-CnmxEB8w.js} +91 -91
- package/core/built/admin/assets/activitypub/{note-C5zjqq5C.js → note-ZKc_Bnba.js} +23 -23
- package/core/built/admin/assets/activitypub/{notifications-B9p8eCHD.js → notifications-CB2tJZau.js} +48 -48
- package/core/built/admin/assets/activitypub/{onboarding-CNelD_uF.js → onboarding-BsJ9E5qf.js} +2 -2
- package/core/built/admin/assets/activitypub/{onboarding-mat5Hrl0.js → onboarding-CSUJJIlh.js} +2 -2
- package/core/built/admin/assets/activitypub/{preferences-BCqUdC3v.js → preferences-0-JZnUkI.js} +1519 -1519
- package/core/built/admin/assets/activitypub/{profile-BRCWoFem.js → profile-C35cFIhM.js} +183 -183
- package/core/built/admin/assets/activitypub/{routes-BSXT992i.js → routes-BD4vscyc.js} +740 -731
- package/core/built/admin/assets/activitypub/settings-BsMROdqh.js +315 -0
- package/core/built/admin/assets/activitypub/{site-DHoMupSB.js → site-O0RL9YCN.js} +2 -2
- package/core/built/admin/assets/activitypub/{step-1-B-YfsVeO.js → step-1-BMSx7c_X.js} +4 -4
- package/core/built/admin/assets/activitypub/{step-3-D6BFMXL_.js → step-3-CLlOZTyt.js} +3 -3
- package/core/built/admin/assets/activitypub/{tabs-GpNecvfB.js → tabs-Dxk-b9M-.js} +306 -306
- package/core/built/admin/assets/activitypub/{topic-filter-BPDeQQys.js → topic-filter-5yZH6tId.js} +2 -2
- package/core/built/admin/assets/activitypub/{use-activity-pub-queries-BoVOxXkV.js → use-activity-pub-queries-CV50qe03.js} +2 -2
- package/core/built/admin/assets/activitypub/{use-reply-chain-data-wVBX7swM.js → use-reply-chain-data-Cbvzgjzd.js} +30 -30
- package/core/built/admin/assets/activitypub/{users-CoX6FT_K.js → users-BjcoP_HC.js} +7 -5
- package/core/built/admin/assets/add-integration-modal-BlF6rs_f.js +1 -0
- package/core/built/admin/assets/add-newsletter-modal-CglVQqah.js +1 -0
- package/core/built/admin/assets/add-recommendation-modal-wz7BsuaG.js +1 -0
- package/core/built/admin/assets/analytics-C4HE1gBg.js +1 -0
- package/core/built/admin/assets/{announcement-bar-modal-DM3cYOpo.js → announcement-bar-modal-Ci4zz8jO.js} +1 -1
- package/core/built/admin/assets/{api-keys-BLm2NDBh.js → api-keys-Ck-Yteiv.js} +1 -1
- package/core/built/admin/assets/{audience-9mwU5TW6.js → audience-CtbA54Sn.js} +1 -1
- package/core/built/admin/assets/{automated-emails-te1D5kq-.js → automated-emails-D5VVMND9.js} +1 -1
- package/core/built/admin/assets/automations-CzKt5fb8.js +1 -0
- package/core/built/admin/assets/bluesky-sharing-BEtJ_gL_.js +1 -0
- package/core/built/admin/assets/{breadcrumb-DLiqCyFc.js → breadcrumb-zUrZrBtW.js} +1 -1
- package/core/built/admin/assets/{button-B2jcu6bk.js → button-eNMKQWXr.js} +1 -1
- package/core/built/admin/assets/{chart-helpers-Fo3bUL3K.js → chart-helpers-CfBKt0vT.js} +1 -1
- package/core/built/admin/assets/{checkbox-BfKktMph.js → checkbox-CgOn_tKW.js} +1 -1
- package/core/built/admin/assets/{chunk.524.60ca4692d91c6022042f.js → chunk.524.a697dee88db67fdf6021.js} +4 -4
- package/core/built/admin/assets/{chunk.582.525c7617c2d9e94c940a.js → chunk.582.5ed5d124cfca9c259b9c.js} +6 -6
- package/core/built/admin/assets/{chunk.896.435fe0637944d4a69810.js → chunk.598.7e056fabb47ce7dbd73f.js} +14 -14
- package/core/built/admin/assets/{code-editor-view-CYVu4EW6.js → code-editor-view-BYNoAoNV.js} +1 -1
- package/core/built/admin/assets/{code-editor-view-DCQJxsfU.js → code-editor-view-K2wI-I5f.js} +1 -1
- package/core/built/admin/assets/color-picker-Ddw80xX6.js +3 -0
- package/core/built/admin/assets/color-picker-field-D9nUhvA7.js +1 -0
- package/core/built/admin/assets/combobox-w9j8PPQT.js +1 -0
- package/core/built/admin/assets/command-BfpHORBv.js +1 -0
- package/core/built/admin/assets/comments-BLmCmyCs.js +1 -0
- package/core/built/admin/assets/confirmation-context-CBM8G0Vj.js +1 -0
- package/core/built/admin/assets/{content-api-modal-CyQEC3fr.js → content-api-modal-TXRz3U7S.js} +1 -1
- package/core/built/admin/assets/context-menu-_QMdd3kp.js +1 -0
- package/core/built/admin/assets/{copy-field-B3M1s78L.js → copy-field-6N01S07E.js} +1 -1
- package/core/built/admin/assets/create-ghost-browse-value-source-qIBymvvf.js +1 -0
- package/core/built/admin/assets/custom-field-type-option-BddFlJFa.js +1 -0
- package/core/built/admin/assets/custom-integration-modal-DmNquxUV.js +1 -0
- package/core/built/admin/assets/{date-range-select-DD2RKkgB.js → date-range-select-uvz_DtPh.js} +1 -1
- package/core/built/admin/assets/design-and-theme-modal-BSmo12Op.js +2 -0
- package/core/built/admin/assets/dirty-confirm-dialog-BZ1iytEd.js +1 -0
- package/core/built/admin/assets/{disabled-sources-indicator-Cvy47bE2.js → disabled-sources-indicator-DMRrxsiJ.js} +1 -1
- package/core/built/admin/assets/dist-Dcsslyo72.js +1 -0
- package/core/built/admin/assets/domain-BNYrt0aD.js +1 -0
- package/core/built/admin/assets/dropzone-D7nFdAe5.js +5 -0
- package/core/built/admin/assets/edit-profile-C5Asm4LA.js +1 -0
- package/core/built/admin/assets/editor-REokrzci.js +8 -0
- package/core/built/admin/assets/{embed-signup-form-modal-DeBMLxlL.js → embed-signup-form-modal-Ds6mPEi5.js} +1 -1
- package/core/built/admin/assets/en-B1jX3WMs.js +1 -0
- package/core/built/admin/assets/explore-UY10Egsp.js +1 -0
- package/core/built/admin/assets/feature-image-placeholder-D1iF_8bc.js +1 -0
- package/core/built/admin/assets/feed-81C8mJWR.js +1 -0
- package/core/built/admin/assets/{field-Cj8lmDOo.js → field-Dihp5p18.js} +1 -1
- package/core/built/admin/assets/filter-bar-Da1qxybu.js +1 -0
- package/core/built/admin/assets/filter-sources-BO9xUPj7.js +1 -0
- package/core/built/admin/assets/filters-CRUWecfY.js +1 -0
- package/core/built/admin/assets/filters-DirqNXjH.js +1 -0
- package/core/built/admin/assets/first-promoter-modal-CT6MxYZb.js +1 -0
- package/core/built/admin/assets/{ghost-c8807202a07c20030acb719ee0114815.css → ghost-8eabfc1ece81b03cf7b90780d31487e8.css} +1 -1
- package/core/built/admin/assets/{ghost-3894eedcc6968f658578c0abfe942aab.js → ghost-c2848508292937415f20f5a830eea59e.js} +31 -28
- package/core/built/admin/assets/{ghost-dark-fbf1e384aaef3ae315e540f0eb7373a7.css → ghost-dark-a7bebe2c561f55369dcf29f4c820f7ff.css} +1 -1
- package/core/built/admin/assets/gift-link-modal-CQVAye17.js +1 -0
- package/core/built/admin/assets/growth-BWIu-6xj.js +3 -0
- package/core/built/admin/assets/growth-DU29oxeA.js +1 -0
- package/core/built/admin/assets/history-modal-CFd1Hvx6.js +1 -0
- package/core/built/admin/assets/{html-field-C8qVGGC1.js → html-field-CJBCLTvv.js} +1 -1
- package/core/built/admin/assets/{images-h8VZEQ9k.js → images-scfkWZiK.js} +1 -1
- package/core/built/admin/assets/{inbox-BYd1M06Q.js → inbox-Mcp4DXZN.js} +14 -14
- package/core/built/admin/assets/index-6MkPdCtr.js +4 -0
- package/core/built/admin/assets/index-Bn7QhcZu.css +2 -0
- package/core/built/admin/assets/index.es-CNnuNH0d.js +1 -0
- package/core/built/admin/assets/{input-group-D8sCXRF5.js → input-group-CMhe2DvY.js} +1 -1
- package/core/built/admin/assets/invite-user-modal-DfheMXs0.js +1 -0
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.js +14 -14
- package/core/built/admin/assets/koenig-lexical/koenig-lexical.umd.js +3 -3
- package/core/built/admin/assets/koenig-lexical/style.css +1 -1
- package/core/built/admin/assets/{koenig-lexical-_-IsVI7E.js → koenig-lexical-DBSqAuiI.js} +3 -3
- package/core/built/admin/assets/koenig-loader-aFQNlJlD.js +2 -0
- package/core/built/admin/assets/{kpi-card-DZQk_0W8.js → kpi-card-DBRMfGOW.js} +1 -1
- package/core/built/admin/assets/{kpi-card-DW_2y3ug.js → kpi-card-DFafD1qq.js} +1 -1
- package/core/built/admin/assets/{kpi-helpers-PueTKuA6.js → kpi-helpers-Cv8i8hns.js} +1 -1
- package/core/built/admin/assets/{kpi-tabs-CojDs-Qz.js → kpi-tabs-BJItvLYm.js} +1 -1
- package/core/built/admin/assets/{label-DjbT91GM.js → label-BnSCvffu.js} +1 -1
- package/core/built/admin/assets/label-picker-KVoo91sh.js +1 -0
- package/core/built/admin/assets/layout-Bjv2Ll-5.js +1 -0
- package/core/built/admin/assets/member-custom-fields-DDQV6QeG.js +1 -0
- package/core/built/admin/assets/member-detail-CdJF6Agw.js +1 -0
- package/core/built/admin/assets/members-DjQbq9Z2.js +4 -0
- package/core/built/admin/assets/moderation-AgCIEso4.js +1 -0
- package/core/built/admin/assets/{multi-select-combobox-B6LiRzDO.js → multi-select-combobox-BcITkUVr.js} +1 -1
- package/core/built/admin/assets/navigation-modal-BkT7b1M2.js +1 -0
- package/core/built/admin/assets/newsletter-BMMAuvgq.js +1 -0
- package/core/built/admin/assets/newsletter-detail-modal-0SCJ7Zpm.js +1 -0
- package/core/built/admin/assets/{newsletter-emails-CFeLlt4z.js → newsletter-emails-DKzwafuh.js} +1 -1
- package/core/built/admin/assets/newsletters-BRBb_uQC.js +1 -0
- package/core/built/admin/assets/note-DyGHtS9a.js +1 -0
- package/core/built/admin/assets/notifications-ZgWniKna.js +1 -0
- package/core/built/admin/assets/nql-BLpCn7qX.js +21 -0
- package/core/built/admin/assets/offers-container-modal-B-E8TIWr.js +1 -0
- package/core/built/admin/assets/{onboarding-B4YhlZ0i.js → onboarding-CzIsre-d.js} +1 -1
- package/core/built/admin/assets/onboarding-qg8Akovm.js +1 -0
- package/core/built/admin/assets/{onboarding-route-Dmc4IPm3.js → onboarding-route-CaavZulg.js} +1 -1
- package/core/built/admin/assets/overview-BW8GLeYi.js +1 -0
- package/core/built/admin/assets/overview-BkXZNzaZ.js +1 -0
- package/core/built/admin/assets/{page-header-BR_nbIPp.js → page-header-De0VzKBi.js} +1 -1
- package/core/built/admin/assets/pagemenu-B5KKCpbA.js +1 -0
- package/core/built/admin/assets/pages-jgaFm69d.js +1 -0
- package/core/built/admin/assets/pages-route-CIUAQxtY.js +1 -0
- package/core/built/admin/assets/papaparse.min-cQwnxGCG.js +10 -0
- package/core/built/admin/assets/{pintura-modal-BR9hEvS8.js → pintura-modal-BZ2J9w3n.js} +1 -1
- package/core/built/admin/assets/portal-frame-B6Hr9wHc.js +1 -0
- package/core/built/admin/assets/portal-modal-D4ceei3t.js +1 -0
- package/core/built/admin/assets/post-analytics-header-BYCsT0GP.js +1 -0
- package/core/built/admin/assets/post-analytics-ot7f6pih.js +1 -0
- package/core/built/admin/assets/{post-analytics-provider-CLfKGWZy.js → post-analytics-provider-Bo1gmYaP.js} +1 -1
- package/core/built/admin/assets/{post-share-modal-Cl0NXRJr.js → post-share-modal-C-PaYZ_e.js} +1 -1
- package/core/built/admin/assets/posts-DuGazgTb.js +1 -0
- package/core/built/admin/assets/posts-list-screen-CBGGgjjj.js +2 -0
- package/core/built/admin/assets/posts-route-D6xmS7Vf.js +1 -0
- package/core/built/admin/assets/preferences-C5YJLp74.js +5 -0
- package/core/built/admin/assets/{preview-modal-C-BL-F9k.js → preview-modal-BfeFqi5y.js} +1 -1
- package/core/built/admin/assets/profile-B8mx2yAu.js +1 -0
- package/core/built/admin/assets/radio-group-DczlLKOn.js +1 -0
- package/core/built/admin/assets/{schemas-4UPic-oD.js → schemas-DppqmpeJ.js} +1 -1
- package/core/built/admin/assets/select-cb0t_TAJ.js +1 -0
- package/core/built/admin/assets/settings-DZqxR0Da.js +1 -0
- package/core/built/admin/assets/settings-DvfTNdHQ.js +4 -0
- package/core/built/admin/assets/{settings-breadcrumbs-CyP_9zTo.js → settings-breadcrumbs-DLzbRRSt.js} +1 -1
- package/core/built/admin/assets/share-modal-D2-Bz1_I.js +1 -0
- package/core/built/admin/assets/slack-modal-DYDTUria.js +1 -0
- package/core/built/admin/assets/{sort-button-Cc-Z96sA.js → sort-button-VVeQjjbu.js} +1 -1
- package/core/built/admin/assets/{source-icon-v6PUnmyM.js → source-icon-Ck5_5Kgq.js} +1 -1
- package/core/built/admin/assets/stats-Rjmk5owg.js +1 -0
- package/core/built/admin/assets/stats-view-BGGmkmgv.js +1 -0
- package/core/built/admin/assets/{step-1-DSRp2vBj.js → step-1-CsaBjeN4.js} +1 -1
- package/core/built/admin/assets/{step-2-COqv2g0u.js → step-2-D2vnxOOM.js} +1 -1
- package/core/built/admin/assets/{step-3-6W1NMVQc.js → step-3-wBoLdGEb.js} +2 -2
- package/core/built/admin/assets/{stripe-button-D2K42Uty.js → stripe-button-CDgLz0S0.js} +1 -1
- package/core/built/admin/assets/stripe-connect-modal-CSjMJetP.js +1 -0
- package/core/built/admin/assets/{table-B2pIKjVh.js → table-Do6iQ83Q.js} +1 -1
- package/core/built/admin/assets/{tabs-SaW_UT-Q.js → tabs-D2yWLMp_.js} +1 -1
- package/core/built/admin/assets/tag-detail-BhXlOsCa.js +2 -0
- package/core/built/admin/assets/tags-ldukRApe.js +1 -0
- package/core/built/admin/assets/testimonials-modal-CtnZBJKl.js +1 -0
- package/core/built/admin/assets/tier-detail-modal-BOs8e_G8.js +1 -0
- package/core/built/admin/assets/{toggle-group-EM9WpESu.js → toggle-group-ByUJsxwD.js} +1 -1
- package/core/built/admin/assets/{topic-filter-DY4gNHn2.js → topic-filter-BgC3g5_v.js} +1 -1
- package/core/built/admin/assets/{transistor-modal-CpyPG-MH.js → transistor-modal-Drr0SNfo.js} +1 -1
- package/core/built/admin/assets/{trend-badge-ByMkuAuH.js → trend-badge-6ye93YAW.js} +1 -1
- package/core/built/admin/assets/{unsplash-modal-Cv2Q6GtY.js → unsplash-modal-p6AoQoWp.js} +1 -1
- package/core/built/admin/assets/{use-analytics-data-CHvjMYuT.js → use-analytics-data-CWCMAESo.js} +1 -1
- package/core/built/admin/assets/use-check-theme-limit-error-B8bjF-gO.css +1 -0
- package/core/built/admin/assets/{use-check-theme-limit-error-Qv4SVXqw.js → use-check-theme-limit-error-Cw3WQHy8.js} +1 -1
- package/core/built/admin/assets/use-filter-params-BIni9taJ.js +1 -0
- package/core/built/admin/assets/use-growth-stats-DCVG3s9w.js +1 -0
- package/core/built/admin/assets/{use-limiter-cwJvsNBo.js → use-limiter-D2WRRx0H.js} +1 -1
- package/core/built/admin/assets/{use-pintura-config-CzTfnufz.js → use-pintura-config-h-J0Lvta.js} +1 -1
- package/core/built/admin/assets/{use-pintura-editor-BDBXWUYq.js → use-pintura-editor-BfN1UwzH.js} +1 -1
- package/core/built/admin/assets/use-post-referrers-Czg47m8s.js +1 -0
- package/core/built/admin/assets/use-reply-chain-data-ns0caK8k.js +1 -0
- package/core/built/admin/assets/{use-router-history-entry-Bg6BhBQQ.js → use-router-history-entry-uldn7zJO.js} +1 -1
- package/core/built/admin/assets/{use-setting-group-VM7FQwMY.js → use-setting-group-DpcuCUDg.js} +1 -1
- package/core/built/admin/assets/use-settings-navigation-CZjGrhsp.js +1 -0
- package/core/built/admin/assets/{use-simple-pagination-Dum6Irbs.js → use-simple-pagination-DzJWobPR.js} +1 -1
- package/core/built/admin/assets/{use-staff-users-cZg4ugOF.js → use-staff-users-Csipb-O0.js} +1 -1
- package/core/built/admin/assets/use-tinybird-query-CSnGXzZh.js +1 -0
- package/core/built/admin/assets/use-tinybird-token-DTOKRR7e.js +1 -0
- package/core/built/admin/assets/{use-unsaved-changes-guard-BAy0RANR.js → use-unsaved-changes-guard-CBzs-KPi.js} +1 -1
- package/core/built/admin/assets/{use-url-input-Df5QzNa7.js → use-url-input-DFr8lCbS.js} +1 -1
- package/core/built/admin/assets/user-detail-modal-B_iUClI6.js +1 -0
- package/core/built/admin/assets/users-Cg-OeGzC.js +1 -0
- package/core/built/admin/assets/{virtual-list-DEx8WgiO.js → virtual-list-BW-padMe.js} +1 -1
- package/core/built/admin/assets/web-C1v33ehA.js +2 -0
- package/core/built/admin/assets/web-C4BKzn2T.js +1 -0
- package/core/built/admin/assets/{zapier-modal-Cw3BTBUu.js → zapier-modal-BBFfI6Ml.js} +1 -1
- package/core/built/admin/index.html +17 -22
- package/core/frontend/apps/private-blogging/lib/views/private.hbs +44 -43
- package/core/frontend/helpers/cancel_link.js +2 -2
- package/core/frontend/helpers/pagination.js +2 -2
- package/core/frontend/helpers/social_accounts.js +2 -2
- package/core/frontend/public/ghost.css +1 -1
- package/core/frontend/public/ghost.min.css +1 -1
- package/core/frontend/services/sitemap/user-map-generator.js +9 -2
- package/core/server/api/endpoints/index.js +2 -2
- package/core/server/api/endpoints/mail.js +1 -1
- package/core/server/api/endpoints/{member-custom-fields.js → member-metafields.js} +27 -28
- package/core/server/api/endpoints/members.js +4 -4
- package/core/server/api/endpoints/posts.js +3 -3
- package/core/server/api/endpoints/utils/serializers/input/members.js +4 -7
- package/core/server/api/endpoints/utils/serializers/output/index.js +2 -2
- package/core/server/api/endpoints/utils/serializers/output/{member-custom-fields.js → member-metafields.js} +2 -4
- package/core/server/api/endpoints/utils/serializers/output/members.js +2 -4
- package/core/server/api/endpoints/utils/validators/input/invitations.js +0 -5
- package/core/server/api/endpoints/utils/validators/input/pages.js +1 -1
- package/core/server/api/endpoints/utils/validators/input/posts.js +1 -1
- package/core/server/data/importer/importers/data/data-importer.js +3 -3
- package/core/server/data/migrations/utils/migrations.js +1 -1
- package/core/server/lib/image/image-size.js +24 -0
- package/core/server/lib/package-json/parse.js +2 -2
- package/core/server/models/member.js +6 -17
- package/core/server/models/post.js +2 -2
- package/core/server/models/relations/authors.js +2 -16
- package/core/server/models/user.js +9 -2
- package/core/server/services/auth/passwordreset.js +13 -0
- package/core/server/services/comments/comments-controller.js +30 -9
- package/core/server/services/comments/comments-service.js +55 -5
- package/core/server/services/content-import/csv/formula.js +12 -0
- package/core/server/services/content-import/csv/index.js +6 -1
- package/core/server/services/content-import/csv/parse.js +27 -6
- package/core/server/services/content-import/csv/serialize.js +13 -0
- package/core/server/services/content-import/import/completion-email.js +164 -0
- package/core/server/services/content-import/import/errors-file.js +36 -0
- package/core/server/services/content-import/import/importer.js +160 -53
- package/core/server/services/content-import/import/local-media-url.js +63 -0
- package/core/server/services/content-import/import/media.js +254 -0
- package/core/server/services/content-import/import/post-data.js +0 -1
- package/core/server/services/content-import/import/post-link.js +11 -0
- package/core/server/services/content-import/import/post-repository.js +25 -3
- package/core/server/services/content-import/import/reader.js +9 -2
- package/core/server/services/content-import/import/report.js +34 -0
- package/core/server/services/content-import/import/row.js +0 -2
- package/core/server/services/content-import/import/schema.js +1 -0
- package/core/server/services/content-import/import/staged-file.js +29 -0
- package/core/server/services/content-import/import/store.js +25 -2
- package/core/server/services/content-import/index.js +52 -6
- package/core/server/services/content-import/jobs/content-csv-import-job.js +20 -0
- package/core/server/services/custom-redirects/redirect-config-parser.js +2 -2
- package/core/server/services/custom-redirects/redirects-service.js +1 -1
- package/core/server/services/custom-redirects/validation.js +1 -1
- package/core/server/services/email-address/email-address-parser.js +30 -38
- package/core/server/services/email-address/email-address-service.js +37 -4
- package/core/server/services/email-analytics/index.js +2 -7
- package/core/server/services/email-service/batch-sending-service.js +0 -4
- package/core/server/services/email-service/email-renderer.js +14 -4
- package/core/server/services/email-service/email-service-wrapper.js +0 -9
- package/core/server/services/email-service/mailgun-email-provider.js +20 -9
- package/core/server/services/gifts/email-templates/gift-delivery.hbs +3 -3
- package/core/server/services/gifts/gift-email-service.js +0 -1
- package/core/server/services/gifts/index.js +3 -3
- package/core/server/services/gifts/jobs/index.js +4 -4
- package/core/server/services/indexnow-ping/indexnow-ping-service.js +2 -2
- package/core/server/services/invitations/accept.js +4 -2
- package/core/server/services/jobs/job-service.js +0 -9
- package/core/server/services/jobs-service/register-job-handlers.js +21 -11
- package/core/server/services/mail/ghost-mailer.js +4 -4
- package/core/server/services/member-welcome-emails/service.js +7 -7
- package/core/server/services/members/api.js +1 -0
- package/core/server/services/members/import-export/csv/parse.js +0 -7
- package/core/server/services/members/import-export/import/completion-email.js +2 -5
- package/core/server/services/members/import-export/import/row.js +0 -3
- package/core/server/services/members/import-export/index.js +4 -11
- package/core/server/services/members/jobs/clean-expired-comped-job.js +7 -0
- package/core/server/services/members/jobs/clean-expired-comped-task.js +145 -0
- package/core/server/services/members/jobs/index.js +48 -24
- package/core/server/services/members/members-api/controllers/member-controller.js +11 -0
- package/core/server/services/members/members-api/controllers/router-controller.js +3 -6
- package/core/server/services/members/members-api/members-api.js +4 -6
- package/core/server/services/members/members-api/repositories/event-repository.js +0 -4
- package/core/server/services/members/members-api/services/member-bread-service.js +34 -62
- package/core/server/services/members/members-api/services/payments-service.js +1 -1
- package/core/server/services/members/service.js +1 -5
- package/core/server/services/members-custom-fields/bindings-service.js +2 -1
- package/core/server/services/members-custom-fields/codec.js +3 -4
- package/core/server/services/members-custom-fields/definitions-service.js +62 -10
- package/core/server/services/members-custom-fields/filter.js +75 -93
- package/core/server/services/members-custom-fields/key.js +2 -1
- package/core/server/services/members-custom-fields/models.js +1 -1
- package/core/server/services/members-custom-fields/serializers.js +3 -5
- package/core/server/services/members-custom-fields/values-service.js +50 -28
- package/core/server/services/mentions/mention-controller.js +23 -21
- package/core/server/services/mentions/process-webmention-job.js +16 -0
- package/core/server/services/mentions/service.js +8 -4
- package/core/server/services/route-settings/validation-errors.js +1 -1
- package/core/server/services/route-settings/yaml-parser.js +1 -1
- package/core/server/services/settings/settings-service.js +1 -8
- package/core/server/services/settings-helpers/settings-helpers.js +4 -6
- package/core/server/services/slack-ping/slack-ping-service.js +1 -1
- package/core/server/services/staff/staff-service-emails.js +2 -2
- package/core/server/services/stripe/config.js +14 -8
- package/core/server/services/stripe/service.js +10 -1
- package/core/server/services/stripe/services/checkout/completed-session.js +2 -2
- package/core/server/services/stripe/services/checkout/session-options.js +18 -15
- package/core/server/services/stripe/services/webhook/checkout-session-event-service.js +26 -5
- package/core/server/services/stripe/stripe-api.js +2 -0
- package/core/server/services/stripe/stripe-service.js +20 -10
- package/core/server/services/stripe/webhook-controller.js +10 -0
- package/core/server/services/tier-checkout-config/codec.js +9 -5
- package/core/server/services/tier-checkout-config/models.js +9 -3
- package/core/server/services/tier-checkout-config/queries.js +4 -4
- package/core/server/services/tier-checkout-config/serializers.js +16 -10
- package/core/server/services/tier-checkout-config/service.js +13 -12
- package/core/server/services/update-check/index.js +13 -13
- package/core/server/services/update-check/jobs/update-check-job.js +7 -0
- package/core/server/services/update-check/update-check-service.js +2 -2
- package/core/server/web/admin/controller.js +1 -1
- package/core/server/web/api/endpoints/admin/routes.js +19 -16
- package/core/shared/config/env/config.testing-mysql.json +1 -1
- package/core/shared/labs.js +5 -2
- package/package.json +24 -23
- package/pnpm-lock.yaml +704 -69
- package/pnpm-workspace.yaml +8 -5
- package/components/tryghost-kg-default-nodes-2.2.0.tgz +0 -0
- package/core/built/admin/assets/Combination-5fYEzgbs.js +0 -41
- package/core/built/admin/assets/account-migration-DRhAehfw.js +0 -1
- package/core/built/admin/assets/activitypub/inbox-BluD2ucT.js +0 -1284
- package/core/built/admin/assets/activitypub/label-FHSh6ZAw.js +0 -16
- package/core/built/admin/assets/activitypub/layout-Cq4NG0Xr.js +0 -1
- package/core/built/admin/assets/activitypub/settings-DQDkr06X.js +0 -315
- package/core/built/admin/assets/add-integration-modal-BC0jExDZ.js +0 -1
- package/core/built/admin/assets/add-newsletter-modal-DchTkA7l.js +0 -1
- package/core/built/admin/assets/add-recommendation-modal-DMvaJZKp.js +0 -1
- package/core/built/admin/assets/alert-dialog-QhXzdHfc.js +0 -1
- package/core/built/admin/assets/analytics-No1DDY3A.js +0 -1
- package/core/built/admin/assets/automations-DpUNUdcZ.js +0 -1
- package/core/built/admin/assets/bluesky-sharing-Cjrv_f62.js +0 -1
- package/core/built/admin/assets/color-picker-BTY_NdEm.js +0 -3
- package/core/built/admin/assets/color-picker-field-CPlkzOH0.js +0 -1
- package/core/built/admin/assets/combobox-DrMtv_4P.js +0 -1
- package/core/built/admin/assets/command-ZdgYJpoI.js +0 -1
- package/core/built/admin/assets/comments-kidj60-h.js +0 -1
- package/core/built/admin/assets/confirmation-context-BhbmQQEl.js +0 -1
- package/core/built/admin/assets/custom-field-type-option-CsGIZk1J.js +0 -10
- package/core/built/admin/assets/custom-integration-modal-BY37O_9X.js +0 -1
- package/core/built/admin/assets/design-and-theme-modal-DUSKM4uC.js +0 -22
- package/core/built/admin/assets/dialog-B44iRwlc.js +0 -1
- package/core/built/admin/assets/dirty-confirm-dialog-BxgQgQ6H.js +0 -1
- package/core/built/admin/assets/dist-Cy8tfrp_.js +0 -1
- package/core/built/admin/assets/domain-Ca6KhoQt.js +0 -1
- package/core/built/admin/assets/dropzone-Bb-5zQTk.js +0 -5
- package/core/built/admin/assets/edit-profile-BdupLlus.js +0 -1
- package/core/built/admin/assets/editor-BP883Lpn.js +0 -8
- package/core/built/admin/assets/explore-FB-CimXw.js +0 -1
- package/core/built/admin/assets/feed-C1GxsmI2.js +0 -1
- package/core/built/admin/assets/filter-sources-D5n5bFA2.js +0 -1
- package/core/built/admin/assets/filters-DJEzkMUK.js +0 -1
- package/core/built/admin/assets/filters-MZXvdH5D.js +0 -1
- package/core/built/admin/assets/first-promoter-modal-CGTGLCr5.js +0 -1
- package/core/built/admin/assets/gift-link-modal-B6v0tnRN.js +0 -1
- package/core/built/admin/assets/growth-BGAJD1rs.js +0 -3
- package/core/built/admin/assets/growth-D6mhcx3q.js +0 -1
- package/core/built/admin/assets/history-modal-iKwUY3XR.js +0 -1
- package/core/built/admin/assets/index-DjQe-e5s.js +0 -4
- package/core/built/admin/assets/index-Dqf2x-ry.css +0 -1
- package/core/built/admin/assets/index.es-VihPwfeH.js +0 -1
- package/core/built/admin/assets/input--W-rCTrX.js +0 -1
- package/core/built/admin/assets/invite-user-modal-MdImLCaJ.js +0 -1
- package/core/built/admin/assets/koenig-loader-DYZpm6El.js +0 -2
- package/core/built/admin/assets/label-picker-cB51xl1r.js +0 -1
- package/core/built/admin/assets/layout-c_B_1hax.js +0 -1
- package/core/built/admin/assets/loading-indicator-BpFWTVgh.js +0 -1
- package/core/built/admin/assets/member-custom-fields-qs0dIkxM.js +0 -1
- package/core/built/admin/assets/member-detail-B6uec2a6.js +0 -1
- package/core/built/admin/assets/members-BQF3CqhI.js +0 -2
- package/core/built/admin/assets/moderation-DY4wF1Q3.js +0 -1
- package/core/built/admin/assets/navigation-modal-DX-gNF3X.js +0 -1
- package/core/built/admin/assets/newsletter-CyQA7m3m.js +0 -1
- package/core/built/admin/assets/newsletter-detail-modal-BDrptuxn.js +0 -1
- package/core/built/admin/assets/newsletters-DXuNmC42.js +0 -1
- package/core/built/admin/assets/note-Cgo2LCJ6.js +0 -1
- package/core/built/admin/assets/notifications-BC50AMku.js +0 -1
- package/core/built/admin/assets/offers-container-modal-DWycIMzT.js +0 -1
- package/core/built/admin/assets/onboarding-DGQuV7Ew.js +0 -1
- package/core/built/admin/assets/overview-CVbFtn-k.js +0 -1
- package/core/built/admin/assets/overview-YKj7SZaK.js +0 -1
- package/core/built/admin/assets/pages-B6vr9F_D.js +0 -1
- package/core/built/admin/assets/popover-CCy0h5rq.js +0 -1
- package/core/built/admin/assets/portal-frame-dc4XKr0e.js +0 -1
- package/core/built/admin/assets/portal-modal-BvvdF_B9.js +0 -1
- package/core/built/admin/assets/post-analytics-DX470WRG.js +0 -1
- package/core/built/admin/assets/post-analytics-header-CXpJmdDv.js +0 -1
- package/core/built/admin/assets/posts-KY3aUhVV.js +0 -1
- package/core/built/admin/assets/preferences-DO0UUWFp.js +0 -5
- package/core/built/admin/assets/profile-CxT-0l4d.js +0 -1
- package/core/built/admin/assets/radio-group-Bgz60i81.js +0 -1
- package/core/built/admin/assets/select-DuDUFdPq.js +0 -1
- package/core/built/admin/assets/settings-BjCii7BM.js +0 -1
- package/core/built/admin/assets/settings-b8kNzZSQ.js +0 -4
- package/core/built/admin/assets/share-modal-BV70mr9k.js +0 -1
- package/core/built/admin/assets/shim-ClF_m5ux.js +0 -1
- package/core/built/admin/assets/slack-modal-Be2_KK-z.js +0 -1
- package/core/built/admin/assets/stats-C4reGh9O.js +0 -1
- package/core/built/admin/assets/stats-view-DP9pQ62k.js +0 -1
- package/core/built/admin/assets/stripe-connect-modal-Z-UT_BGc.js +0 -1
- package/core/built/admin/assets/tag-detail-Dc0nTOtU.js +0 -2
- package/core/built/admin/assets/tags-BLaXBwnb.js +0 -1
- package/core/built/admin/assets/testimonials-modal-sFwRnNLh.js +0 -1
- package/core/built/admin/assets/tier-detail-modal-BCFpWwUS.js +0 -1
- package/core/built/admin/assets/use-filter-params-CAvfDvf1.js +0 -1
- package/core/built/admin/assets/use-growth-stats-D6mZXGhK.js +0 -1
- package/core/built/admin/assets/use-post-referrers-DbY-mzci.js +0 -1
- package/core/built/admin/assets/use-reply-chain-data-BeQwz8oF.js +0 -1
- package/core/built/admin/assets/use-settings-navigation-BbrSUVcf.js +0 -1
- package/core/built/admin/assets/use-tinybird-query-B1IMyAcv.js +0 -39
- package/core/built/admin/assets/use-tinybird-token-Bow0Zwn8.js +0 -1
- package/core/built/admin/assets/user-detail-modal-yipSoQfv.js +0 -1
- package/core/built/admin/assets/users-5msE1WMs.js +0 -1
- package/core/built/admin/assets/web-CKcXAu86.js +0 -1
- package/core/built/admin/assets/web-DR4TqM3E.js +0 -2
- package/core/server/services/jobs/worker-model-event-bridge.js +0 -149
- package/core/server/services/members/jobs/clean-expired-comped.js +0 -132
- package/core/server/services/stripe/services/checkout/allowed-countries.js +0 -267
- package/core/server/services/stripe/services/checkout/field-ports.js +0 -34
- package/core/server/services/tier-checkout-config/destinations.js +0 -17
- package/core/server/services/update-check/run-update-check.js +0 -63
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
|
+
const ProcessWebmentionJob = require('./process-webmention-job').default;
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @typedef {import('./mentions-api')} MentionsAPI
|
|
@@ -22,11 +23,6 @@ const logging = require('@tryghost/logging');
|
|
|
22
23
|
* @prop {Resource} resource
|
|
23
24
|
*/
|
|
24
25
|
|
|
25
|
-
/**
|
|
26
|
-
* @typedef {object} IJobService
|
|
27
|
-
* @prop {(name: string, fn: Function) => void} addJob
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
26
|
/**
|
|
31
27
|
* @typedef {object} IMentionResourceService
|
|
32
28
|
* @prop {(id: import('bson-objectid').default) => Promise<MentionResource>} getByID
|
|
@@ -36,8 +32,8 @@ module.exports = class MentionController {
|
|
|
36
32
|
/** @type {import('./mentions-api')} */
|
|
37
33
|
#api;
|
|
38
34
|
|
|
39
|
-
/** @type {
|
|
40
|
-
#
|
|
35
|
+
/** @type {import('../jobs-service/jobs-service').JobsService} */
|
|
36
|
+
#jobsService;
|
|
41
37
|
|
|
42
38
|
/** @type {IMentionResourceService} */
|
|
43
39
|
#mentionResourceService;
|
|
@@ -45,12 +41,12 @@ module.exports = class MentionController {
|
|
|
45
41
|
/**
|
|
46
42
|
* @param {object} deps
|
|
47
43
|
* @param {import('./mentions-api')} deps.api
|
|
48
|
-
* @param {
|
|
44
|
+
* @param {import('../jobs-service/jobs-service').JobsService} deps.jobsService
|
|
49
45
|
* @param {IMentionResourceService} deps.mentionResourceService
|
|
50
46
|
*/
|
|
51
47
|
async init(deps) {
|
|
52
48
|
this.#api = deps.api;
|
|
53
|
-
this.#
|
|
49
|
+
this.#jobsService = deps.jobsService;
|
|
54
50
|
this.#mentionResourceService = deps.mentionResourceService;
|
|
55
51
|
}
|
|
56
52
|
|
|
@@ -127,17 +123,23 @@ module.exports = class MentionController {
|
|
|
127
123
|
*/
|
|
128
124
|
async receive(frame) {
|
|
129
125
|
logging.info('[Webmention] ' + JSON.stringify(frame.data));
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
126
|
+
const { source, target, ...payload } = frame.data;
|
|
127
|
+
await this.#jobsService.dispatch(new ProcessWebmentionJob({ source, target, payload }));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {import('./process-webmention-job').default} job
|
|
132
|
+
* @returns {Promise<void>}
|
|
133
|
+
*/
|
|
134
|
+
async processWebmention({ source, target, payload }) {
|
|
135
|
+
try {
|
|
136
|
+
await this.#api.processWebmention({
|
|
137
|
+
source: new URL(source),
|
|
138
|
+
target: new URL(target),
|
|
139
|
+
payload,
|
|
140
|
+
});
|
|
141
|
+
} catch (err) {
|
|
142
|
+
logging.error(err, '[Webmention] Failed processing webmention');
|
|
143
|
+
}
|
|
142
144
|
}
|
|
143
145
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const job_1 = require("../jobs-service/job");
|
|
4
|
+
class ProcessWebmentionJob extends job_1.Job {
|
|
5
|
+
static type = 'process-webmention';
|
|
6
|
+
source;
|
|
7
|
+
target;
|
|
8
|
+
payload;
|
|
9
|
+
constructor({ source, target, payload, }) {
|
|
10
|
+
super();
|
|
11
|
+
this.source = source;
|
|
12
|
+
this.target = target;
|
|
13
|
+
this.payload = payload;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.default = ProcessWebmentionJob;
|
|
@@ -15,7 +15,7 @@ const urlService = require('../url');
|
|
|
15
15
|
const settingsCache = require('../../../shared/settings-cache');
|
|
16
16
|
const DomainEvents = require('@tryghost/domain-events');
|
|
17
17
|
const logging = require('@tryghost/logging');
|
|
18
|
-
const
|
|
18
|
+
const mentionsJobService = require('../mentions-jobs');
|
|
19
19
|
|
|
20
20
|
// Serializes a post model to the data the URL service needs, loading the
|
|
21
21
|
// relations it reads for filtered collections (event-emitted models don't
|
|
@@ -45,7 +45,7 @@ function makeLoggingJobService() {
|
|
|
45
45
|
return {
|
|
46
46
|
async addJob(name, fn) {
|
|
47
47
|
logging.info(`[Background Job] ${name} queued`);
|
|
48
|
-
|
|
48
|
+
mentionsJobService.addJob({
|
|
49
49
|
name,
|
|
50
50
|
job: async () => {
|
|
51
51
|
const startedAt = Date.now();
|
|
@@ -75,7 +75,11 @@ module.exports = {
|
|
|
75
75
|
/** @type {import('./mention-sending-service')} */
|
|
76
76
|
sendingService: null,
|
|
77
77
|
didInit: false,
|
|
78
|
-
|
|
78
|
+
/**
|
|
79
|
+
* @param {object} deps
|
|
80
|
+
* @param {import('../jobs-service/jobs-service').JobsService} deps.jobsService
|
|
81
|
+
*/
|
|
82
|
+
async init({ jobsService }) {
|
|
79
83
|
if (this.didInit) {
|
|
80
84
|
return;
|
|
81
85
|
}
|
|
@@ -110,7 +114,7 @@ module.exports = {
|
|
|
110
114
|
|
|
111
115
|
this.controller.init({
|
|
112
116
|
api,
|
|
113
|
-
|
|
117
|
+
jobsService,
|
|
114
118
|
mentionResourceService: {
|
|
115
119
|
async getByID(id) {
|
|
116
120
|
if (!id) {
|
|
@@ -14,7 +14,7 @@ const tpl_1 = __importDefault(require("@tryghost/tpl"));
|
|
|
14
14
|
const messages = {
|
|
15
15
|
validationError: 'The following definition "{at}" is invalid: {reason}',
|
|
16
16
|
};
|
|
17
|
-
const DOCS_URL = 'https://ghost.org/
|
|
17
|
+
const DOCS_URL = 'https://docs.ghost.org/themes/routing/';
|
|
18
18
|
const MAX_SHOWN_LENGTH = 40;
|
|
19
19
|
/**
|
|
20
20
|
* Stable, machine-readable codes describing the class of a routes.yaml failure.
|
|
@@ -200,14 +200,7 @@ module.exports = {
|
|
|
200
200
|
type: 'boolean',
|
|
201
201
|
group: 'members',
|
|
202
202
|
fn: settingsHelpers.allowSelfSignup.bind(settingsHelpers),
|
|
203
|
-
dependents: [
|
|
204
|
-
'members_signup_access',
|
|
205
|
-
'portal_plans',
|
|
206
|
-
'stripe_secret_key',
|
|
207
|
-
'stripe_publishable_key',
|
|
208
|
-
'stripe_connect_secret_key',
|
|
209
|
-
'stripe_connect_publishable_key',
|
|
210
|
-
],
|
|
203
|
+
dependents: ['members_signup_access'],
|
|
211
204
|
}),
|
|
212
205
|
);
|
|
213
206
|
fields.push(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const net = require('net');
|
|
2
2
|
const tpl = require('@tryghost/tpl');
|
|
3
3
|
const errors = require('@tryghost/errors');
|
|
4
|
-
const
|
|
4
|
+
const emailAddressParser = require('../email-address/email-address-parser');
|
|
5
5
|
const logging = require('@tryghost/logging');
|
|
6
6
|
const crypto = require('crypto');
|
|
7
7
|
const debug = require('@tryghost/debug')('services:settings-helpers');
|
|
@@ -130,11 +130,9 @@ class SettingsHelpers {
|
|
|
130
130
|
if (!supportAddress) {
|
|
131
131
|
// In the new flow, we make a difference between an empty setting (= use default) and a 'noreply' setting (=use noreply @ domain)
|
|
132
132
|
// Also keep the name of the default email!
|
|
133
|
-
return
|
|
133
|
+
return emailAddressParser.stringify(this.getDefaultEmail());
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
supportAddress = supportAddress || 'noreply';
|
|
137
|
-
|
|
138
136
|
// Any fromAddress without domain uses site domain, like default setting `noreply`
|
|
139
137
|
if (supportAddress.indexOf('@') < 0) {
|
|
140
138
|
return `${supportAddress}@${this.getDefaultEmailDomain()}`;
|
|
@@ -143,7 +141,7 @@ class SettingsHelpers {
|
|
|
143
141
|
}
|
|
144
142
|
|
|
145
143
|
/**
|
|
146
|
-
* @deprecated Use getDefaultEmail().address (without name) or
|
|
144
|
+
* @deprecated Use getDefaultEmail().address (without name) or emailAddressParser.stringify(this.getDefaultEmail()) (with name) instead
|
|
147
145
|
*/
|
|
148
146
|
getNoReplyAddress() {
|
|
149
147
|
return this.getDefaultEmailAddress();
|
|
@@ -157,7 +155,7 @@ class SettingsHelpers {
|
|
|
157
155
|
// parse the email here and remove the sender name
|
|
158
156
|
// E.g. when set to "bar" <from@default.com>
|
|
159
157
|
const configAddress = this.config.get('mail:from');
|
|
160
|
-
const parsed =
|
|
158
|
+
const parsed = emailAddressParser.parse(configAddress);
|
|
161
159
|
if (parsed) {
|
|
162
160
|
return parsed;
|
|
163
161
|
}
|
|
@@ -173,7 +173,7 @@ class SlackPingService {
|
|
|
173
173
|
this.logging.error(new errors_1.default.InternalServerError({
|
|
174
174
|
err: err,
|
|
175
175
|
context: (0, tpl_1.default)(constants_1.messages.requestFailedError, { service: 'slack' }),
|
|
176
|
-
help: (0, tpl_1.default)(constants_1.messages.requestFailedHelp, { url: 'https://ghost.org/
|
|
176
|
+
help: (0, tpl_1.default)(constants_1.messages.requestFailedHelp, { url: 'https://docs.ghost.org/' }),
|
|
177
177
|
}));
|
|
178
178
|
});
|
|
179
179
|
}
|
|
@@ -2,7 +2,7 @@ const { promises: fs, readFileSync } = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const moment = require('moment');
|
|
4
4
|
const { globSync } = require('glob');
|
|
5
|
-
const
|
|
5
|
+
const emailAddressParser = require('../email-address/email-address-parser');
|
|
6
6
|
|
|
7
7
|
class StaffServiceEmails {
|
|
8
8
|
constructor({
|
|
@@ -593,7 +593,7 @@ class StaffServiceEmails {
|
|
|
593
593
|
}
|
|
594
594
|
|
|
595
595
|
get fromEmailAddress() {
|
|
596
|
-
return
|
|
596
|
+
return emailAddressParser.stringify(this.settingsHelpers.getDefaultEmail());
|
|
597
597
|
}
|
|
598
598
|
|
|
599
599
|
extractInitials(name = '') {
|
|
@@ -4,7 +4,7 @@ const labs = require('../../../shared/labs');
|
|
|
4
4
|
|
|
5
5
|
const messages = {
|
|
6
6
|
remoteWebhooksInDevelopment:
|
|
7
|
-
'Cannot use remote webhooks in development. See https://ghost.org/
|
|
7
|
+
'Cannot use remote webhooks in development. See https://docs.ghost.org/webhooks/#stripe-webhooks for developing with Stripe.',
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
// @TODO Refactor to a class w/ constructor
|
|
@@ -62,16 +62,19 @@ module.exports = {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const env = config.get('env');
|
|
65
|
-
|
|
65
|
+
const remoteWebhooks = env !== 'production' && config.get('stripeRemoteWebhooks') === true;
|
|
66
|
+
let webhookSecret = remoteWebhooks ? undefined : process.env.WEBHOOK_SECRET;
|
|
66
67
|
|
|
67
|
-
if (env !== 'production') {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
logging.warn(tpl(messages.remoteWebhooksInDevelopment));
|
|
71
|
-
}
|
|
68
|
+
if (env !== 'production' && !remoteWebhooks && !webhookSecret) {
|
|
69
|
+
webhookSecret = 'DEFAULT_WEBHOOK_SECRET';
|
|
70
|
+
logging.warn(tpl(messages.remoteWebhooksInDevelopment));
|
|
72
71
|
}
|
|
73
72
|
|
|
74
|
-
|
|
73
|
+
// Development can tunnel the webhook URL alone while the site stays on localhost.
|
|
74
|
+
const webhookHandlerUrl = new URL(
|
|
75
|
+
config.get('stripeWebhookUrl') || 'members/webhooks/stripe/',
|
|
76
|
+
urlUtils.getSiteUrl(),
|
|
77
|
+
);
|
|
75
78
|
const webhookCustomerIgnoreList = parseIgnoreCustomerList(
|
|
76
79
|
config.get('stripeWebhookCustomerIgnoreList'),
|
|
77
80
|
);
|
|
@@ -88,6 +91,9 @@ module.exports = {
|
|
|
88
91
|
},
|
|
89
92
|
webhookSecret: webhookSecret,
|
|
90
93
|
webhookHandlerUrl: webhookHandlerUrl.href,
|
|
94
|
+
// A development registration points at a tunnel that closes with the process,
|
|
95
|
+
// so it is removed on shutdown rather than kept for the next boot.
|
|
96
|
+
ephemeralWebhook: remoteWebhooks,
|
|
91
97
|
webhookCustomerIgnoreList,
|
|
92
98
|
siteUrl,
|
|
93
99
|
};
|
|
@@ -14,6 +14,12 @@ const giftService = require('../gifts');
|
|
|
14
14
|
const staffService = require('../staff');
|
|
15
15
|
const labs = require('../../../shared/labs');
|
|
16
16
|
const settingsCache = require('../../../shared/settings-cache');
|
|
17
|
+
const tpl = require('@tryghost/tpl');
|
|
18
|
+
|
|
19
|
+
const messages = {
|
|
20
|
+
remoteWebhooksWithoutStripe:
|
|
21
|
+
'stripeRemoteWebhooks is set but Stripe is not connected, so no webhook endpoint was registered. Connect Stripe in Ghost Admin under Settings, then restart.',
|
|
22
|
+
};
|
|
17
23
|
|
|
18
24
|
async function configureApi() {
|
|
19
25
|
const cfg = getConfig({ settingsHelpers, config, urlUtils });
|
|
@@ -84,7 +90,10 @@ function stripeSettingsChanged(model) {
|
|
|
84
90
|
|
|
85
91
|
module.exports.init = async function init() {
|
|
86
92
|
try {
|
|
87
|
-
await configureApi();
|
|
93
|
+
const configured = await configureApi();
|
|
94
|
+
if (!configured && config.get('stripeRemoteWebhooks') === true) {
|
|
95
|
+
logging.warn(tpl(messages.remoteWebhooksWithoutStripe));
|
|
96
|
+
}
|
|
88
97
|
} catch (err) {
|
|
89
98
|
logging.error(err);
|
|
90
99
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.collectedByPort = exports.CompletedSession = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
-
const
|
|
5
|
+
const checkout_1 = require("@tryghost/checkout");
|
|
6
6
|
/**
|
|
7
7
|
* What Ghost reads off a completed session.
|
|
8
8
|
*
|
|
@@ -63,6 +63,6 @@ exports.collectedByPort = exports.CompletedSession.transform((session) => {
|
|
|
63
63
|
const answers = (session.custom_fields ?? [])
|
|
64
64
|
.filter((field) => Boolean(field?.key && field.text?.value))
|
|
65
65
|
.map((field) => ({ port: field.key, value: field.text.value }));
|
|
66
|
-
const ports =
|
|
66
|
+
const ports = checkout_1.STRIPE_PORTS.map((port) => ({ port, value: PORT_VALUES[port](session) })).filter((entry) => entry.value !== undefined);
|
|
67
67
|
return [...answers, ...ports];
|
|
68
68
|
});
|
|
@@ -5,13 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.stripeCheckoutCollectionOptions = stripeCheckoutCollectionOptions;
|
|
7
7
|
const logging_1 = __importDefault(require("@tryghost/logging"));
|
|
8
|
-
const
|
|
8
|
+
const checkout_1 = require("@tryghost/checkout");
|
|
9
9
|
/** Keyed on the eligible types, so this and the configure-time rule cannot drift apart. */
|
|
10
10
|
const QUESTION_TYPES = {
|
|
11
11
|
short_text: 'text',
|
|
12
12
|
};
|
|
13
13
|
function askable(question) {
|
|
14
|
-
if (!(0,
|
|
14
|
+
if (!(0, checkout_1.isCheckoutEligible)(question.type)) {
|
|
15
15
|
logging_1.default.warn({
|
|
16
16
|
event: { name: 'stripe.checkout.question_skipped' },
|
|
17
17
|
customFieldKey: question.key,
|
|
@@ -20,7 +20,7 @@ function askable(question) {
|
|
|
20
20
|
}, 'Skipping a Stripe checkout question');
|
|
21
21
|
return false;
|
|
22
22
|
}
|
|
23
|
-
if (question.prompt.length >
|
|
23
|
+
if (question.prompt.length > checkout_1.MAX_CHECKOUT_LABEL_LENGTH) {
|
|
24
24
|
logging_1.default.warn({
|
|
25
25
|
event: { name: 'stripe.checkout.question_skipped' },
|
|
26
26
|
customFieldKey: question.key,
|
|
@@ -43,7 +43,7 @@ function stripeCheckoutCollectionOptions(checkout) {
|
|
|
43
43
|
return options;
|
|
44
44
|
}
|
|
45
45
|
const eligible = checkout.customFields.filter(askable);
|
|
46
|
-
const questions = eligible.slice(0,
|
|
46
|
+
const questions = eligible.slice(0, checkout_1.MAX_CHECKOUT_CUSTOM_FIELDS);
|
|
47
47
|
if (questions.length < eligible.length) {
|
|
48
48
|
logging_1.default.warn({
|
|
49
49
|
event: { name: 'stripe.checkout.questions_trimmed' },
|
|
@@ -64,15 +64,20 @@ function stripeCheckoutCollectionOptions(checkout) {
|
|
|
64
64
|
}));
|
|
65
65
|
}
|
|
66
66
|
if (checkout.shipping) {
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
//
|
|
67
|
+
// Ghost stores "everywhere" as no list, because the set of countries moves and a
|
|
68
|
+
// stored copy of it would quietly become a restriction. Stripe has no such sentinel:
|
|
69
|
+
// `allowed_countries` is the only key `shipping_address_collection` has, so a request
|
|
70
|
+
// that omits it carries no parameter at all, and Stripe accepts it precisely because
|
|
71
|
+
// it was never asked to collect anything — a session that succeeds and collects no
|
|
72
|
+
// address. So everywhere is expanded to every country here, at the one point that
|
|
73
|
+
// builds the request.
|
|
71
74
|
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
|
|
75
|
+
// An empty list is neither everywhere nor a real restriction, and would encode to the
|
|
76
|
+
// same absent parameter. Defended here rather than trusted from the settings screen:
|
|
77
|
+
// this is the checkout path, and a malformed configuration must cost the collection
|
|
78
|
+
// rather than throw inside a session build.
|
|
79
|
+
const allowedCountries = checkout.shipping.allowedCountries ?? [...checkout_1.STRIPE_ALLOWED_COUNTRIES];
|
|
80
|
+
if (allowedCountries.length === 0) {
|
|
76
81
|
logging_1.default.warn({
|
|
77
82
|
event: { name: 'stripe.checkout.collection_skipped' },
|
|
78
83
|
port: 'shipping_address',
|
|
@@ -80,9 +85,7 @@ function stripeCheckoutCollectionOptions(checkout) {
|
|
|
80
85
|
}, 'Skipping a Stripe checkout collection');
|
|
81
86
|
}
|
|
82
87
|
else {
|
|
83
|
-
options.shipping_address_collection = {
|
|
84
|
-
allowed_countries: checkout.shipping.allowedCountries,
|
|
85
|
-
};
|
|
88
|
+
options.shipping_address_collection = { allowed_countries: allowedCountries };
|
|
86
89
|
}
|
|
87
90
|
}
|
|
88
91
|
// Unioned with whatever automatic tax asks for. Both want the same thing, so a site
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
const _ = require('lodash');
|
|
2
2
|
const errors = require('@tryghost/errors');
|
|
3
3
|
const logging = require('@tryghost/logging');
|
|
4
|
-
const {
|
|
4
|
+
const {
|
|
5
|
+
SIGNUP_CONTEXTS,
|
|
6
|
+
canWelcomeEmailReplaceSignupPaidEmail,
|
|
7
|
+
} = require('../../../lib/member-signup-contexts');
|
|
5
8
|
const { collectedByPort } = require('../checkout/completed-session');
|
|
6
9
|
/** @typedef {import('../../../lib/member-signup-contexts').SignupContext} SignupContext */
|
|
7
10
|
|
|
@@ -335,6 +338,7 @@ module.exports = class CheckoutSessionEventService {
|
|
|
335
338
|
email: customer.email,
|
|
336
339
|
});
|
|
337
340
|
|
|
341
|
+
const memberPreexisted = Boolean(member);
|
|
338
342
|
const checkoutType = _.get(session, 'metadata.checkoutType');
|
|
339
343
|
|
|
340
344
|
if (!member) {
|
|
@@ -426,7 +430,7 @@ module.exports = class CheckoutSessionEventService {
|
|
|
426
430
|
// After the subscription work, and deliberately not part of it: a value the member
|
|
427
431
|
// gave us for free must never be able to fail the webhook. A throw here would make
|
|
428
432
|
// Stripe retry the event and risk doing the payment work twice.
|
|
429
|
-
await this.writeCollectedFields(member.id, session);
|
|
433
|
+
await this.writeCollectedFields(member.id, session, { memberPreexisted });
|
|
430
434
|
|
|
431
435
|
if (checkoutType !== 'upgrade') {
|
|
432
436
|
const ghostSignupContext = /** @type {SignupContext | undefined} */ (
|
|
@@ -457,18 +461,35 @@ module.exports = class CheckoutSessionEventService {
|
|
|
457
461
|
*
|
|
458
462
|
* @param {string} memberId
|
|
459
463
|
* @param {import('stripe').Stripe.Checkout.Session} session
|
|
464
|
+
* @param {object} options
|
|
465
|
+
* @param {boolean} options.memberPreexisted Whether the member's record existed before this event resolved it
|
|
460
466
|
*/
|
|
461
|
-
async writeCollectedFields(memberId, session) {
|
|
467
|
+
async writeCollectedFields(memberId, session, { memberPreexisted }) {
|
|
462
468
|
// Stamped at create time. A session predating this feature carries none. Read
|
|
463
469
|
// outside the try so a failure below can name the tier whose answers were lost.
|
|
464
470
|
const tierId = session.metadata?.ghostTierId;
|
|
465
471
|
|
|
466
472
|
try {
|
|
467
|
-
if (!
|
|
473
|
+
if (!tierId) {
|
|
468
474
|
return;
|
|
469
475
|
}
|
|
470
476
|
|
|
471
|
-
|
|
477
|
+
// A checkout can be started with nothing but an email address, and typing an
|
|
478
|
+
// email is not proof of owning it. Values may land on the member this event just
|
|
479
|
+
// created — that record holds nothing the buyer didn't supply — but a record
|
|
480
|
+
// that existed before the checkout belongs to whoever verified that email, so it
|
|
481
|
+
// is only written when the session was created by a signed-in member.
|
|
482
|
+
const wasAuthenticated =
|
|
483
|
+
session.metadata?.ghostSignupContext === SIGNUP_CONTEXTS.ALREADY_AUTHENTICATED;
|
|
484
|
+
if (memberPreexisted && !wasAuthenticated) {
|
|
485
|
+
logging.warn(
|
|
486
|
+
{
|
|
487
|
+
event: { name: 'stripe_checkout.collected_fields.write_skipped' },
|
|
488
|
+
memberId,
|
|
489
|
+
tierId,
|
|
490
|
+
},
|
|
491
|
+
'Skipped storing the fields an unverified checkout collected for an existing member',
|
|
492
|
+
);
|
|
472
493
|
return;
|
|
473
494
|
}
|
|
474
495
|
|
|
@@ -25,6 +25,7 @@ const customFields = require('../members-custom-fields');
|
|
|
25
25
|
* @prop {boolean} testEnv Whether this is a test environment
|
|
26
26
|
* @prop {string} webhookSecret The Stripe webhook secret
|
|
27
27
|
* @prop {string} webhookHandlerUrl The URL to handle Stripe webhooks
|
|
28
|
+
* @prop {boolean} [ephemeralWebhook] Whether the webhook endpoint is deleted on shutdown
|
|
28
29
|
* @prop {string[]} webhookCustomerIgnoreList List of customer IDs for customer.subscription.updated webhook bypass
|
|
29
30
|
* @prop {string} siteUrl The site URL for billing portal return URL
|
|
30
31
|
*/
|
|
@@ -134,7 +135,6 @@ module.exports = class StripeService {
|
|
|
134
135
|
memberWelcomeEmailService.init();
|
|
135
136
|
return memberWelcomeEmailService.api.isMemberWelcomeEmailActive('paid');
|
|
136
137
|
},
|
|
137
|
-
labsService: labs,
|
|
138
138
|
// A getter because the custom field services are built during boot: reading the
|
|
139
139
|
// binding at construction would capture the empty value it had beforehand.
|
|
140
140
|
get customFieldBindings() {
|
|
@@ -162,6 +162,8 @@ module.exports = class StripeService {
|
|
|
162
162
|
this.migrations = migrations;
|
|
163
163
|
this.webhookController = webhookController;
|
|
164
164
|
this.billingPortalManager = billingPortalManager;
|
|
165
|
+
/** @private */
|
|
166
|
+
this.ephemeralWebhook = false;
|
|
165
167
|
}
|
|
166
168
|
|
|
167
169
|
async connect() {
|
|
@@ -213,23 +215,31 @@ module.exports = class StripeService {
|
|
|
213
215
|
webhookSecret: config.webhookSecret,
|
|
214
216
|
webhookHandlerUrl: config.webhookHandlerUrl,
|
|
215
217
|
});
|
|
218
|
+
this.ephemeralWebhook = config.ephemeralWebhook === true;
|
|
216
219
|
|
|
217
220
|
this.billingPortalManager.configure({
|
|
218
221
|
siteUrl: config.siteUrl,
|
|
219
222
|
});
|
|
220
223
|
|
|
221
|
-
// webhookManager.start()
|
|
222
|
-
//
|
|
223
|
-
//
|
|
224
|
-
//
|
|
225
|
-
//
|
|
226
|
-
//
|
|
227
|
-
// configurations, so this network-registration call only error-logs on
|
|
228
|
-
// every boot. Tests never need a registered portal configuration. Skip it
|
|
229
|
-
// under test; prod and dev register exactly as before.
|
|
224
|
+
// webhookManager.start() registers a webhook URL with Stripe only when no webhook
|
|
225
|
+
// secret was supplied. Outside production config.js supplies a placeholder secret
|
|
226
|
+
// unless stripeRemoteWebhooks is set, so start() normally returns without touching
|
|
227
|
+
// Stripe. billingPortalManager has no such guard: in the test environment the mock
|
|
228
|
+
// Stripe answers its registration call with a 500 on every boot, and tests never
|
|
229
|
+
// need a registered portal, so skip it under test only.
|
|
230
230
|
await this.webhookManager.start();
|
|
231
231
|
if (!config.testEnv) {
|
|
232
232
|
await this.billingPortalManager.start();
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Removes the webhook registration from Stripe, but only when it was marked ephemeral.
|
|
238
|
+
* A production registration is kept and reused on the next boot.
|
|
239
|
+
*/
|
|
240
|
+
async shutdown() {
|
|
241
|
+
if (this.ephemeralWebhook) {
|
|
242
|
+
await this.webhookManager.stop();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
235
245
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const logging = require('@tryghost/logging');
|
|
2
|
+
const StripeAPI = require('./stripe-api');
|
|
2
3
|
|
|
3
4
|
module.exports = class WebhookController {
|
|
4
5
|
/**
|
|
@@ -89,6 +90,15 @@ module.exports = class WebhookController {
|
|
|
89
90
|
return res.end();
|
|
90
91
|
}
|
|
91
92
|
|
|
93
|
+
// Stripe shapes each event for the API version of the URL it was sent to. A different
|
|
94
|
+
// version means this event did not come through the URL Ghost registered, and fields
|
|
95
|
+
// may not be where Ghost reads them.
|
|
96
|
+
if (event.api_version !== StripeAPI.API_VERSION) {
|
|
97
|
+
logging.error(
|
|
98
|
+
`Webhook ${event.type} was rendered at Stripe API version ${event.api_version}, Ghost expects ${StripeAPI.API_VERSION}`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
92
102
|
const customerId = this.getEventCustomerId(event);
|
|
93
103
|
if (this.shouldIgnoreEvent(event, customerId)) {
|
|
94
104
|
logging.info(
|
|
@@ -8,19 +8,23 @@ const schema_1 = require("./schema");
|
|
|
8
8
|
const models_1 = require("./models");
|
|
9
9
|
const SEPARATOR = ',';
|
|
10
10
|
exports.optionsCodec = zod_1.z.codec(schema_1.DbCheckoutOptions, models_1.CheckoutOptions, {
|
|
11
|
+
// An absent list is everywhere, so the column is null rather than a copy of every
|
|
12
|
+
// country. An empty list is neither, and stays representable on purpose: nothing writes
|
|
13
|
+
// one, and the session builder refuses to collect against it rather than asking the
|
|
14
|
+
// processor for an address form it would never render.
|
|
11
15
|
decode: (columns) => ({
|
|
12
|
-
shippingAllowedCountries:
|
|
16
|
+
shippingAllowedCountries: columns.shipping_allowed_countries === null
|
|
17
|
+
? null
|
|
18
|
+
: splitList(columns.shipping_allowed_countries),
|
|
13
19
|
taxNumber: columns.tax_number_collect,
|
|
14
20
|
}),
|
|
15
21
|
encode: (options) => ({
|
|
16
|
-
shipping_allowed_countries: options.shippingAllowedCountries.
|
|
17
|
-
? joinList(options.shippingAllowedCountries)
|
|
18
|
-
: null,
|
|
22
|
+
shipping_allowed_countries: options.shippingAllowedCountries === null ? null : joinList(options.shippingAllowedCountries),
|
|
19
23
|
tax_number_collect: options.taxNumber,
|
|
20
24
|
}),
|
|
21
25
|
});
|
|
22
26
|
function splitList(stored) {
|
|
23
|
-
return stored
|
|
27
|
+
return stored.split(SEPARATOR).filter(Boolean);
|
|
24
28
|
}
|
|
25
29
|
function joinList(values) {
|
|
26
30
|
return [...new Set(values)].join(SEPARATOR);
|
|
@@ -13,8 +13,14 @@ exports.CheckoutQuestion = zod_1.z.object({
|
|
|
13
13
|
* under one parameter, but a publisher keeps a name and an address in different fields.
|
|
14
14
|
*/
|
|
15
15
|
exports.ShippingCollection = zod_1.z.object({
|
|
16
|
-
/**
|
|
17
|
-
|
|
16
|
+
/**
|
|
17
|
+
* ISO 3166-1 alpha-2, or null for everywhere the processor ships.
|
|
18
|
+
*
|
|
19
|
+
* Null rather than a stored enumeration of every country, because that list moves: the
|
|
20
|
+
* day the processor adds one, a saved "everywhere" would silently be a restriction that
|
|
21
|
+
* excludes it, and nothing would say so.
|
|
22
|
+
*/
|
|
23
|
+
allowedCountries: zod_1.z.array(zod_1.z.string()).nullable(),
|
|
18
24
|
nameCustomFieldKey: zod_1.z.string(),
|
|
19
25
|
addressCustomFieldKey: zod_1.z.string(),
|
|
20
26
|
});
|
|
@@ -42,7 +48,7 @@ const emptyCheckoutConfig = (tierId) => ({
|
|
|
42
48
|
});
|
|
43
49
|
exports.emptyCheckoutConfig = emptyCheckoutConfig;
|
|
44
50
|
exports.CheckoutOptions = zod_1.z.object({
|
|
45
|
-
shippingAllowedCountries: zod_1.z.array(zod_1.z.string()),
|
|
51
|
+
shippingAllowedCountries: zod_1.z.array(zod_1.z.string()).nullable(),
|
|
46
52
|
taxNumber: zod_1.z.boolean(),
|
|
47
53
|
});
|
|
48
54
|
exports.ResolvedQuestion = exports.CheckoutQuestion.extend({
|