@unidy.io/sdk 1.2.0-alpha9 → 1.2.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/dist/cjs/_commonjsHelpers-CFO10eej.js +10 -0
- package/dist/cjs/_commonjsHelpers-CFO10eej.js.map +1 -0
- package/dist/cjs/app-globals-C-Wl5lPS.js +10 -0
- package/dist/cjs/app-globals-C-Wl5lPS.js.map +1 -0
- package/dist/cjs/{auth-store-DPmGKHZ2.js → auth-store-0vv3uOib.js} +4 -4
- package/dist/cjs/{auth-store-DPmGKHZ2.js.map → auth-store-0vv3uOib.js.map} +1 -1
- package/dist/cjs/component-DLxnZCW6.js +34 -0
- package/dist/cjs/component-DLxnZCW6.js.map +1 -0
- package/dist/cjs/component-utils-XXctnOM9.js +38 -0
- package/dist/cjs/component-utils-XXctnOM9.js.map +1 -0
- package/dist/cjs/de-BWF6Glzg.js +704 -0
- package/dist/cjs/de-BWF6Glzg.js.map +1 -0
- package/dist/cjs/en-GB-DhD5mdQw.js +119 -0
- package/dist/cjs/en-GB-DhD5mdQw.js.map +1 -0
- package/dist/cjs/{flash-store-gbSYhPAV.js → flash-store-CR6Umh1O.js} +3 -3
- package/dist/cjs/{flash-store-gbSYhPAV.js.map → flash-store-CR6Umh1O.js.map} +1 -1
- package/dist/cjs/fr-j2wwoj-A.js +577 -0
- package/dist/cjs/fr-j2wwoj-A.js.map +1 -0
- package/dist/cjs/has-slot-content-CfJbU4t-.js +37 -0
- package/dist/cjs/has-slot-content-CfJbU4t-.js.map +1 -0
- package/dist/cjs/{i18n-D5j_Zl-4.js → i18n-ClWrNmGh.js} +100 -4
- package/dist/cjs/{i18n-D5j_Zl-4.js.map → i18n-ClWrNmGh.js.map} +1 -1
- package/dist/cjs/{index-B325yXfO.js → index-2Fz3r5o0.js} +5 -41
- package/dist/cjs/index-2Fz3r5o0.js.map +1 -0
- package/dist/cjs/{index-yaeiYlfa.js → index-C6ZBKFYr.js} +3 -3
- package/dist/cjs/{index-yaeiYlfa.js.map → index-C6ZBKFYr.js.map} +1 -1
- package/dist/cjs/{index-BzPYBLYC.js → index-CpPKy1CZ.js} +1170 -1087
- package/dist/cjs/index-CpPKy1CZ.js.map +1 -0
- package/dist/cjs/index.cjs.js +24 -11
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/cjs/loader.cjs.js +3 -3
- package/dist/cjs/{newsletter-helpers-hdDC5X-V.js → newsletter-helpers-BHvOI8M4.js} +46 -9
- package/dist/cjs/newsletter-helpers-BHvOI8M4.js.map +1 -0
- package/dist/cjs/{newsletter-store-CupsLgO9.js → newsletter-store-22Jswiqe.js} +5 -3
- package/dist/cjs/newsletter-store-22Jswiqe.js.map +1 -0
- package/dist/cjs/nl-BE-yKvOp1-G.js +542 -0
- package/dist/cjs/nl-BE-yKvOp1-G.js.map +1 -0
- package/dist/cjs/{profile-helpers-Bprrm-Xl.js → profile-helpers-BBpAqHjK.js} +4 -4
- package/dist/cjs/{profile-helpers-Bprrm-Xl.js.map → profile-helpers-BBpAqHjK.js.map} +1 -1
- package/dist/cjs/{profile-store-C_q-TuA_.js → profile-store-CQEQhPQD.js} +4 -4
- package/dist/cjs/{profile-store-C_q-TuA_.js.map → profile-store-CQEQhPQD.js.map} +1 -1
- package/dist/cjs/redirect-with-token-wupYX97S.js +37 -0
- package/dist/cjs/redirect-with-token-wupYX97S.js.map +1 -0
- package/dist/cjs/ro-CXq9d1lv.js +578 -0
- package/dist/cjs/ro-CXq9d1lv.js.map +1 -0
- package/dist/cjs/sdk.cjs.js +3 -3
- package/dist/cjs/sv-CMln4V33.js +597 -0
- package/dist/cjs/sv-CMln4V33.js.map +1 -0
- package/dist/cjs/u-conditional-render.cjs.entry.js +14 -14
- package/dist/cjs/u-conditional-render.entry.cjs.js.map +1 -1
- package/dist/cjs/u-config.cjs.entry.js +24 -11
- package/dist/cjs/u-config.entry.cjs.js.map +1 -1
- package/dist/cjs/u-email-field.cjs.entry.js +7 -7
- package/dist/cjs/u-error-message.cjs.entry.js +49 -22
- package/dist/cjs/u-error-message.entry.cjs.js.map +1 -1
- package/dist/cjs/u-field.u-raw-field.entry.cjs.js.map +1 -1
- package/dist/cjs/u-field_2.cjs.entry.js +124 -12
- package/dist/cjs/u-flash-message.cjs.entry.js +3 -3
- package/dist/cjs/u-full-profile.cjs.entry.js +6 -6
- package/dist/cjs/u-jump-to-service.cjs.entry.js +23 -44
- package/dist/cjs/u-jump-to-service.entry.cjs.js.map +1 -1
- package/dist/cjs/u-jump-to-unidy.cjs.entry.js +22 -43
- package/dist/cjs/u-jump-to-unidy.entry.cjs.js.map +1 -1
- package/dist/cjs/u-logout-button.u-signed-in.entry.cjs.js.map +1 -1
- package/dist/cjs/u-logout-button_2.cjs.entry.js +15 -22
- package/dist/cjs/u-magic-code-field.cjs.entry.js +8 -9
- package/dist/cjs/u-magic-code-field.entry.cjs.js.map +1 -1
- package/dist/cjs/u-missing-field.cjs.entry.js +6 -5
- package/dist/cjs/u-missing-field.entry.cjs.js.map +1 -1
- package/dist/cjs/u-missing-fields-submit-button.cjs.entry.js +16 -14
- package/dist/cjs/u-missing-fields-submit-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-checkbox.cjs.entry.js +11 -12
- package/dist/cjs/u-newsletter-checkbox.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-consent-checkbox.cjs.entry.js +4 -4
- package/dist/cjs/u-newsletter-logout-button.cjs.entry.js +15 -20
- package/dist/cjs/u-newsletter-logout-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-preference-checkbox.cjs.entry.js +11 -12
- package/dist/cjs/u-newsletter-preference-checkbox.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-resend-doi-button.cjs.entry.js +10 -11
- package/dist/cjs/u-newsletter-resend-doi-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-root.cjs.entry.js +45 -22
- package/dist/cjs/u-newsletter-root.entry.cjs.js.map +1 -1
- package/dist/cjs/u-newsletter-toggle-subscription-button.cjs.entry.js +11 -12
- package/dist/cjs/u-newsletter-toggle-subscription-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-pagination-button.cjs.entry.js +4 -4
- package/dist/cjs/u-pagination-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-pagination-page.cjs.entry.js +4 -4
- package/dist/cjs/u-pagination-page.entry.cjs.js.map +1 -1
- package/dist/cjs/u-passkey.cjs.entry.js +8 -9
- package/dist/cjs/u-passkey.entry.cjs.js.map +1 -1
- package/dist/cjs/u-password-field.cjs.entry.js +5 -5
- package/dist/cjs/u-profile.u-submit-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-profile_2.cjs.entry.js +31 -33
- package/dist/cjs/u-registration-button.cjs.entry.js +5 -5
- package/dist/cjs/u-reset-password-button.cjs.entry.js +12 -15
- package/dist/cjs/u-reset-password-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-send-magic-code-button.cjs.entry.js +8 -9
- package/dist/cjs/u-send-magic-code-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-signin-root.cjs.entry.js +6 -8
- package/dist/cjs/u-signin-root.entry.cjs.js.map +1 -1
- package/dist/cjs/u-signin-step.cjs.entry.js +17 -21
- package/dist/cjs/u-signin-step.entry.cjs.js.map +1 -1
- package/dist/cjs/u-social-login-button.cjs.entry.js +16 -15
- package/dist/cjs/u-social-login-button.entry.cjs.js.map +1 -1
- package/dist/cjs/u-spinner.cjs.entry.js +3 -3
- package/dist/cjs/u-spinner.entry.cjs.js.map +1 -1
- package/dist/cjs/u-ticketable-export.cjs.entry.js +76 -0
- package/dist/cjs/u-ticketable-export.entry.cjs.js.map +1 -0
- package/dist/cjs/u-ticketable-list-D3M8iA-g.js +3991 -0
- package/dist/cjs/u-ticketable-list-D3M8iA-g.js.map +1 -0
- package/dist/cjs/u-ticketable-list.cjs.entry.js +11 -6118
- package/dist/cjs/u-ticketable-list.entry.cjs.js.map +1 -1
- package/dist/cjs/{unidy-store-BGnWn9pc.js → unidy-store-Bvnl24i9.js} +3 -3
- package/dist/cjs/{unidy-store-BGnWn9pc.js.map → unidy-store-Bvnl24i9.js.map} +1 -1
- package/dist/collection/api/base-service.js.map +1 -1
- package/dist/collection/api/client.js.map +1 -1
- package/dist/collection/api/index.js +6 -6
- package/dist/collection/api/index.js.map +1 -1
- package/dist/collection/api/standalone.js +88 -39
- package/dist/collection/api/standalone.js.map +1 -1
- package/dist/collection/auth/api/auth.js.map +1 -1
- package/dist/collection/auth/api/schemas.js +5 -5
- package/dist/collection/auth/api/schemas.js.map +1 -1
- package/dist/collection/auth/auth-helpers.js +7 -8
- package/dist/collection/auth/auth-helpers.js.map +1 -1
- package/dist/collection/auth/auth.js +1 -0
- package/dist/collection/auth/auth.js.map +1 -1
- package/dist/collection/auth/components/jump-to-service/jump-to-service.js +20 -40
- package/dist/collection/auth/components/jump-to-service/jump-to-service.js.map +1 -1
- package/dist/collection/auth/components/jump-to-unidy/jump-to-unidy.js +20 -39
- package/dist/collection/auth/components/jump-to-unidy/jump-to-unidy.js.map +1 -1
- package/dist/collection/auth/components/logout-button/logout-button.js +7 -11
- package/dist/collection/auth/components/logout-button/logout-button.js.map +1 -1
- package/dist/collection/auth/components/missing-field/missing-field.js +25 -1
- package/dist/collection/auth/components/missing-field/missing-field.js.map +1 -1
- package/dist/collection/auth/components/missing-fields-submit-button/missing-fields-submit-button.js +33 -7
- package/dist/collection/auth/components/missing-fields-submit-button/missing-fields-submit-button.js.map +1 -1
- package/dist/collection/auth/components/password-field/password-field.js +1 -1
- package/dist/collection/auth/components/reset-pass-button/reset-pass-button.js +6 -8
- package/dist/collection/auth/components/reset-pass-button/reset-pass-button.js.map +1 -1
- package/dist/collection/auth/components/signed-in/signed-in.js +2 -5
- package/dist/collection/auth/components/signed-in/signed-in.js.map +1 -1
- package/dist/collection/auth/components/signin-root/signin-root.js +2 -5
- package/dist/collection/auth/components/signin-root/signin-root.js.map +1 -1
- package/dist/collection/auth/components/signin-step/signin-step.js +9 -13
- package/dist/collection/auth/components/signin-step/signin-step.js.map +1 -1
- package/dist/collection/auth/components/social-logins/social-login-button.css +1 -1
- package/dist/collection/auth/components/social-logins/social-login-button.js +11 -12
- package/dist/collection/auth/components/social-logins/social-login-button.js.map +1 -1
- package/dist/collection/auth/components/submit-button/auth-submit-button.js +10 -0
- package/dist/collection/auth/components/submit-button/auth-submit-button.js.map +1 -1
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/locales/de.json +16 -0
- package/dist/collection/locales/en.json +16 -0
- package/dist/collection/locales/fr.json +16 -0
- package/dist/collection/locales/it.json +16 -0
- package/dist/collection/locales/nl_be.json +16 -0
- package/dist/collection/locales/ro.json +16 -0
- package/dist/collection/logger.js +0 -37
- package/dist/collection/logger.js.map +1 -1
- package/dist/collection/newsletter/api/newsletters.js +19 -18
- package/dist/collection/newsletter/api/newsletters.js.map +1 -1
- package/dist/collection/newsletter/components/consent-checkbox/consent-checkbox.js +1 -1
- package/dist/collection/newsletter/components/logout-button/logout-button.js +6 -10
- package/dist/collection/newsletter/components/logout-button/logout-button.js.map +1 -1
- package/dist/collection/newsletter/components/newsletter-checkbox/newsletter-checkbox.js +1 -1
- package/dist/collection/newsletter/components/newsletter-root/newsletter-root.js +65 -10
- package/dist/collection/newsletter/components/newsletter-root/newsletter-root.js.map +1 -1
- package/dist/collection/newsletter/components/preference-checkbox/preference-checkbox.js +1 -1
- package/dist/collection/newsletter/components/toggle-subscription-button/toggle-subscription-button.js +1 -1
- package/dist/collection/newsletter/newsletter-helpers.js +39 -2
- package/dist/collection/newsletter/newsletter-helpers.js.map +1 -1
- package/dist/collection/newsletter/store/newsletter-store.js +2 -0
- package/dist/collection/newsletter/store/newsletter-store.js.map +1 -1
- package/dist/collection/profile/api/profile.js.map +1 -1
- package/dist/collection/profile/api/schemas.js +1 -1
- package/dist/collection/profile/api/schemas.js.map +1 -1
- package/dist/collection/profile/components/field/field.js +3 -1
- package/dist/collection/profile/components/field/field.js.map +1 -1
- package/dist/collection/profile/components/full-profile/full-profile.js +1 -1
- package/dist/collection/profile/components/raw-field/raw-field.js +40 -7
- package/dist/collection/profile/components/raw-field/raw-field.js.map +1 -1
- package/dist/collection/profile/store/profile-store.js +1 -1
- package/dist/collection/profile/store/profile-store.js.map +1 -1
- package/dist/collection/shared/base/component.js +28 -0
- package/dist/collection/shared/base/component.js.map +1 -0
- package/dist/collection/shared/base/has-slot-content.js +31 -0
- package/dist/collection/shared/base/has-slot-content.js.map +1 -0
- package/dist/collection/shared/component-utils.js +23 -27
- package/dist/collection/shared/component-utils.js.map +1 -1
- package/dist/collection/shared/components/conditional-render/conditional-render.js +4 -5
- package/dist/collection/shared/components/conditional-render/conditional-render.js.map +1 -1
- package/dist/collection/shared/components/config/config.js +18 -5
- package/dist/collection/shared/components/config/config.js.map +1 -1
- package/dist/collection/shared/components/email-field/email-field.js +1 -1
- package/dist/collection/shared/components/error-message/error-message.css +1 -1
- package/dist/collection/shared/components/error-message/error-message.js +44 -17
- package/dist/collection/shared/components/error-message/error-message.js.map +1 -1
- package/dist/collection/shared/components/spinner/spinner.css +1 -1
- package/dist/collection/shared/components/spinner/spinner.js +1 -1
- package/dist/collection/shared/components/submit-button/submit-button.css +1 -1
- package/dist/collection/shared/components/submit-button/submit-button.js +12 -23
- package/dist/collection/shared/components/submit-button/submit-button.js.map +1 -1
- package/dist/collection/shared/context-utils.js +96 -0
- package/dist/collection/shared/context-utils.js.map +1 -0
- package/dist/collection/shared/utils/redirect-with-token.js +30 -0
- package/dist/collection/shared/utils/redirect-with-token.js.map +1 -0
- package/dist/collection/shared/utils/url-utils.js +25 -0
- package/dist/collection/shared/utils/url-utils.js.map +1 -0
- package/dist/collection/ticketable/api/schemas.js +10 -2
- package/dist/collection/ticketable/api/schemas.js.map +1 -1
- package/dist/collection/ticketable/api/subscriptions.js +22 -1
- package/dist/collection/ticketable/api/subscriptions.js.map +1 -1
- package/dist/collection/ticketable/api/tickets.js +22 -1
- package/dist/collection/ticketable/api/tickets.js.map +1 -1
- package/dist/collection/ticketable/components/pagination/pagination-button.js +3 -5
- package/dist/collection/ticketable/components/pagination/pagination-button.js.map +1 -1
- package/dist/collection/ticketable/components/pagination/pagination-page.js +3 -5
- package/dist/collection/ticketable/components/pagination/pagination-page.js.map +1 -1
- package/dist/collection/ticketable/components/ticketable-export/ticketable-export.js +175 -0
- package/dist/collection/ticketable/components/ticketable-export/ticketable-export.js.map +1 -0
- package/dist/collection/ticketable/components/ticketable-list/ticketable-list.js +163 -25
- package/dist/collection/ticketable/components/ticketable-list/ticketable-list.js.map +1 -1
- package/dist/collection/ticketable/index.js +1 -0
- package/dist/collection/ticketable/index.js.map +1 -1
- package/dist/components/_commonjsHelpers.js +8 -0
- package/dist/components/_commonjsHelpers.js.map +1 -0
- package/dist/components/component-utils.js +25 -28
- package/dist/components/component-utils.js.map +1 -1
- package/dist/components/component.js +33 -0
- package/dist/components/component.js.map +1 -0
- package/dist/components/de.js +702 -0
- package/dist/components/de.js.map +1 -0
- package/dist/components/en-GB.js +117 -0
- package/dist/components/en-GB.js.map +1 -0
- package/dist/components/field.js +3 -1
- package/dist/components/field.js.map +1 -1
- package/dist/components/fr.js +575 -0
- package/dist/components/fr.js.map +1 -0
- package/dist/components/has-slot-content.js +35 -0
- package/dist/components/has-slot-content.js.map +1 -0
- package/dist/components/i18n.js +96 -0
- package/dist/components/i18n.js.map +1 -1
- package/dist/components/index.js +11 -3
- package/dist/components/index.js.map +1 -1
- package/dist/components/index2.js +1158 -1083
- package/dist/components/index2.js.map +1 -1
- package/dist/components/logger.js +1 -39
- package/dist/components/logger.js.map +1 -1
- package/dist/components/newsletter-helpers.js +39 -2
- package/dist/components/newsletter-helpers.js.map +1 -1
- package/dist/components/newsletter-store.js +2 -0
- package/dist/components/newsletter-store.js.map +1 -1
- package/dist/components/nl-BE.js +540 -0
- package/dist/components/nl-BE.js.map +1 -0
- package/dist/components/profile-store.js +1 -1
- package/dist/components/profile-store.js.map +1 -1
- package/dist/components/raw-field.js +116 -7
- package/dist/components/raw-field.js.map +1 -1
- package/dist/components/redirect-with-token.js +35 -0
- package/dist/components/redirect-with-token.js.map +1 -0
- package/dist/components/ro.js +576 -0
- package/dist/components/ro.js.map +1 -0
- package/dist/components/spinner.js +2 -2
- package/dist/components/spinner.js.map +1 -1
- package/dist/components/submit-button.js +21 -24
- package/dist/components/submit-button.js.map +1 -1
- package/dist/components/sv.js +595 -0
- package/dist/components/sv.js.map +1 -0
- package/dist/components/u-conditional-render.js +5 -6
- package/dist/components/u-conditional-render.js.map +1 -1
- package/dist/components/u-config.js +16 -3
- package/dist/components/u-config.js.map +1 -1
- package/dist/components/u-email-field.js +1 -1
- package/dist/components/u-error-message.js +44 -19
- package/dist/components/u-error-message.js.map +1 -1
- package/dist/components/u-full-profile.js +1 -1
- package/dist/components/u-jump-to-service.js +16 -38
- package/dist/components/u-jump-to-service.js.map +1 -1
- package/dist/components/u-jump-to-unidy.js +16 -37
- package/dist/components/u-jump-to-unidy.js.map +1 -1
- package/dist/components/u-logout-button.js +5 -11
- package/dist/components/u-logout-button.js.map +1 -1
- package/dist/components/u-missing-field.js +5 -2
- package/dist/components/u-missing-field.js.map +1 -1
- package/dist/components/u-missing-fields-submit-button.js +10 -8
- package/dist/components/u-missing-fields-submit-button.js.map +1 -1
- package/dist/components/u-newsletter-checkbox.js +1 -1
- package/dist/components/u-newsletter-consent-checkbox.js +1 -1
- package/dist/components/u-newsletter-logout-button.js +6 -12
- package/dist/components/u-newsletter-logout-button.js.map +1 -1
- package/dist/components/u-newsletter-preference-checkbox.js +1 -1
- package/dist/components/u-newsletter-root.js +35 -12
- package/dist/components/u-newsletter-root.js.map +1 -1
- package/dist/components/u-newsletter-toggle-subscription-button.js +1 -1
- package/dist/components/u-pagination-button.js +3 -4
- package/dist/components/u-pagination-button.js.map +1 -1
- package/dist/components/u-pagination-page.js +3 -4
- package/dist/components/u-pagination-page.js.map +1 -1
- package/dist/components/u-reset-password-button.js +4 -8
- package/dist/components/u-reset-password-button.js.map +1 -1
- package/dist/components/u-signed-in.js +3 -6
- package/dist/components/u-signed-in.js.map +1 -1
- package/dist/components/u-signin-root.js +3 -6
- package/dist/components/u-signin-root.js.map +1 -1
- package/dist/components/u-signin-step.js +10 -14
- package/dist/components/u-signin-step.js.map +1 -1
- package/dist/components/u-social-login-button.js +13 -14
- package/dist/components/u-social-login-button.js.map +1 -1
- package/dist/components/u-ticketable-export.d.ts +11 -0
- package/dist/components/u-ticketable-export.js +93 -0
- package/dist/components/u-ticketable-export.js.map +1 -0
- package/dist/components/u-ticketable-list.js +256 -2396
- package/dist/components/u-ticketable-list.js.map +1 -1
- package/dist/esm/_commonjsHelpers-B85MJLTf.js +8 -0
- package/dist/esm/_commonjsHelpers-B85MJLTf.js.map +1 -0
- package/dist/esm/app-globals-J743qnJf.js +8 -0
- package/dist/esm/app-globals-J743qnJf.js.map +1 -0
- package/dist/esm/{auth-store-DBlGNGhq.js → auth-store-CSpEdi46.js} +4 -4
- package/dist/esm/{auth-store-DBlGNGhq.js.map → auth-store-CSpEdi46.js.map} +1 -1
- package/dist/esm/component-qfegGRWr.js +32 -0
- package/dist/esm/component-qfegGRWr.js.map +1 -0
- package/dist/esm/component-utils-WEof9bTg.js +36 -0
- package/dist/esm/component-utils-WEof9bTg.js.map +1 -0
- package/dist/esm/de-C6AnCqsA.js +702 -0
- package/dist/esm/de-C6AnCqsA.js.map +1 -0
- package/dist/esm/en-GB-DO63WPxt.js +117 -0
- package/dist/esm/en-GB-DO63WPxt.js.map +1 -0
- package/dist/esm/{flash-store-Df2YkLTB.js → flash-store-Dn1Bava8.js} +3 -3
- package/dist/esm/{flash-store-Df2YkLTB.js.map → flash-store-Dn1Bava8.js.map} +1 -1
- package/dist/esm/fr-C0oU6-EJ.js +575 -0
- package/dist/esm/fr-C0oU6-EJ.js.map +1 -0
- package/dist/esm/has-slot-content-DSMkJu9G.js +35 -0
- package/dist/esm/has-slot-content-DSMkJu9G.js.map +1 -0
- package/dist/esm/{i18n-Da7S9Oqf.js → i18n-ioyZxWsT.js} +100 -4
- package/dist/esm/{i18n-Da7S9Oqf.js.map → i18n-ioyZxWsT.js.map} +1 -1
- package/dist/esm/{index-FTKB5a1d.js → index-BsJDptgj.js} +4 -40
- package/dist/esm/index-BsJDptgj.js.map +1 -0
- package/dist/esm/{index-BnAYOYR5.js → index-C8kmD3tu.js} +3 -3
- package/dist/esm/{index-BnAYOYR5.js.map → index-C8kmD3tu.js.map} +1 -1
- package/dist/esm/{index-BVlbCQEX.js → index-kgGjfc-n.js} +1163 -1088
- package/dist/esm/index-kgGjfc-n.js.map +1 -0
- package/dist/esm/index.js +18 -12
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/loader.js +4 -4
- package/dist/esm/{newsletter-helpers-fCpxzovf.js → newsletter-helpers-DoKGN_Kq.js} +46 -9
- package/dist/esm/newsletter-helpers-DoKGN_Kq.js.map +1 -0
- package/dist/esm/{newsletter-store-BB618FgS.js → newsletter-store-DpR85vaC.js} +5 -3
- package/dist/esm/newsletter-store-DpR85vaC.js.map +1 -0
- package/dist/esm/nl-BE-C8uPYb_H.js +540 -0
- package/dist/esm/nl-BE-C8uPYb_H.js.map +1 -0
- package/dist/esm/{profile-helpers-CXK2X6Ts.js → profile-helpers-BMJy0ei_.js} +4 -4
- package/dist/esm/{profile-helpers-CXK2X6Ts.js.map → profile-helpers-BMJy0ei_.js.map} +1 -1
- package/dist/esm/{profile-store-CHlSKuTY.js → profile-store-7wBS3gBH.js} +4 -4
- package/dist/esm/{profile-store-CHlSKuTY.js.map → profile-store-7wBS3gBH.js.map} +1 -1
- package/dist/esm/redirect-with-token-StCLJlSp.js +35 -0
- package/dist/esm/redirect-with-token-StCLJlSp.js.map +1 -0
- package/dist/esm/ro-BlDHz7d-.js +576 -0
- package/dist/esm/ro-BlDHz7d-.js.map +1 -0
- package/dist/esm/sdk.js +4 -4
- package/dist/esm/sv-B_Gq29K0.js +595 -0
- package/dist/esm/sv-B_Gq29K0.js.map +1 -0
- package/dist/esm/u-conditional-render.entry.js +14 -14
- package/dist/esm/u-conditional-render.entry.js.map +1 -1
- package/dist/esm/u-config.entry.js +24 -11
- package/dist/esm/u-config.entry.js.map +1 -1
- package/dist/esm/u-email-field.entry.js +7 -7
- package/dist/esm/u-error-message.entry.js +49 -22
- package/dist/esm/u-error-message.entry.js.map +1 -1
- package/dist/esm/u-field.u-raw-field.entry.js.map +1 -1
- package/dist/esm/u-field_2.entry.js +124 -12
- package/dist/esm/u-flash-message.entry.js +3 -3
- package/dist/esm/u-full-profile.entry.js +6 -6
- package/dist/esm/u-jump-to-service.entry.js +23 -44
- package/dist/esm/u-jump-to-service.entry.js.map +1 -1
- package/dist/esm/u-jump-to-unidy.entry.js +22 -43
- package/dist/esm/u-jump-to-unidy.entry.js.map +1 -1
- package/dist/esm/u-logout-button.u-signed-in.entry.js.map +1 -1
- package/dist/esm/u-logout-button_2.entry.js +15 -22
- package/dist/esm/u-magic-code-field.entry.js +8 -9
- package/dist/esm/u-magic-code-field.entry.js.map +1 -1
- package/dist/esm/u-missing-field.entry.js +6 -5
- package/dist/esm/u-missing-field.entry.js.map +1 -1
- package/dist/esm/u-missing-fields-submit-button.entry.js +16 -14
- package/dist/esm/u-missing-fields-submit-button.entry.js.map +1 -1
- package/dist/esm/u-newsletter-checkbox.entry.js +11 -12
- package/dist/esm/u-newsletter-checkbox.entry.js.map +1 -1
- package/dist/esm/u-newsletter-consent-checkbox.entry.js +4 -4
- package/dist/esm/u-newsletter-logout-button.entry.js +15 -20
- package/dist/esm/u-newsletter-logout-button.entry.js.map +1 -1
- package/dist/esm/u-newsletter-preference-checkbox.entry.js +11 -12
- package/dist/esm/u-newsletter-preference-checkbox.entry.js.map +1 -1
- package/dist/esm/u-newsletter-resend-doi-button.entry.js +10 -11
- package/dist/esm/u-newsletter-resend-doi-button.entry.js.map +1 -1
- package/dist/esm/u-newsletter-root.entry.js +42 -19
- package/dist/esm/u-newsletter-root.entry.js.map +1 -1
- package/dist/esm/u-newsletter-toggle-subscription-button.entry.js +11 -12
- package/dist/esm/u-newsletter-toggle-subscription-button.entry.js.map +1 -1
- package/dist/esm/u-pagination-button.entry.js +4 -4
- package/dist/esm/u-pagination-button.entry.js.map +1 -1
- package/dist/esm/u-pagination-page.entry.js +4 -4
- package/dist/esm/u-pagination-page.entry.js.map +1 -1
- package/dist/esm/u-passkey.entry.js +8 -9
- package/dist/esm/u-passkey.entry.js.map +1 -1
- package/dist/esm/u-password-field.entry.js +5 -5
- package/dist/esm/u-profile.u-submit-button.entry.js.map +1 -1
- package/dist/esm/u-profile_2.entry.js +31 -33
- package/dist/esm/u-registration-button.entry.js +5 -5
- package/dist/esm/u-reset-password-button.entry.js +12 -15
- package/dist/esm/u-reset-password-button.entry.js.map +1 -1
- package/dist/esm/u-send-magic-code-button.entry.js +8 -9
- package/dist/esm/u-send-magic-code-button.entry.js.map +1 -1
- package/dist/esm/u-signin-root.entry.js +6 -8
- package/dist/esm/u-signin-root.entry.js.map +1 -1
- package/dist/esm/u-signin-step.entry.js +17 -21
- package/dist/esm/u-signin-step.entry.js.map +1 -1
- package/dist/esm/u-social-login-button.entry.js +16 -15
- package/dist/esm/u-social-login-button.entry.js.map +1 -1
- package/dist/esm/u-spinner.entry.js +3 -3
- package/dist/esm/u-spinner.entry.js.map +1 -1
- package/dist/esm/u-ticketable-export.entry.js +74 -0
- package/dist/esm/u-ticketable-export.entry.js.map +1 -0
- package/dist/esm/u-ticketable-list-D2p21JjR.js +3981 -0
- package/dist/esm/u-ticketable-list-D2p21JjR.js.map +1 -0
- package/dist/esm/u-ticketable-list.entry.js +10 -6121
- package/dist/esm/u-ticketable-list.entry.js.map +1 -1
- package/dist/esm/{unidy-store-Bg7IaIMd.js → unidy-store-B5Bf4Vit.js} +3 -3
- package/dist/esm/{unidy-store-Bg7IaIMd.js.map → unidy-store-B5Bf4Vit.js.map} +1 -1
- package/dist/sdk/index.esm.js +1 -1
- package/dist/sdk/index.esm.js.map +1 -1
- package/dist/sdk/locales/de.json +16 -0
- package/dist/sdk/locales/en.json +16 -0
- package/dist/sdk/locales/fr.json +16 -0
- package/dist/sdk/locales/it.json +16 -0
- package/dist/sdk/locales/nl_be.json +16 -0
- package/dist/sdk/locales/ro.json +16 -0
- package/dist/sdk/p-02dce5da.entry.js +2 -0
- package/dist/sdk/p-02dce5da.entry.js.map +1 -0
- package/dist/sdk/p-043c7643.entry.js +2 -0
- package/dist/sdk/p-043c7643.entry.js.map +1 -0
- package/dist/sdk/p-18c17747.entry.js +2 -0
- package/dist/sdk/p-18c17747.entry.js.map +1 -0
- package/dist/sdk/p-1a1c1af0.entry.js +2 -0
- package/dist/sdk/p-1a1c1af0.entry.js.map +1 -0
- package/dist/sdk/p-271781c7.entry.js +2 -0
- package/dist/sdk/{p-1a8973a6.entry.js.map → p-271781c7.entry.js.map} +1 -1
- package/dist/sdk/p-29473a55.entry.js +2 -0
- package/dist/sdk/p-29473a55.entry.js.map +1 -0
- package/dist/sdk/p-2a25d62e.entry.js +2 -0
- package/dist/sdk/p-2a25d62e.entry.js.map +1 -0
- package/dist/sdk/{p-C8lRzJEX.js → p-2bKltz_F.js} +2 -2
- package/dist/sdk/{p-C8lRzJEX.js.map → p-2bKltz_F.js.map} +1 -1
- package/dist/sdk/p-2cc3a00d.entry.js +2 -0
- package/dist/sdk/p-2cc3a00d.entry.js.map +1 -0
- package/dist/sdk/p-2f49e0cb.entry.js +2 -0
- package/dist/sdk/p-2f49e0cb.entry.js.map +1 -0
- package/dist/sdk/p-34f5d201.entry.js +2 -0
- package/dist/sdk/p-34f5d201.entry.js.map +1 -0
- package/dist/sdk/p-52c4bdd9.entry.js +2 -0
- package/dist/sdk/p-52c4bdd9.entry.js.map +1 -0
- package/dist/sdk/p-585a0efa.entry.js +2 -0
- package/dist/sdk/p-585a0efa.entry.js.map +1 -0
- package/dist/sdk/p-60675019.entry.js +2 -0
- package/dist/sdk/p-60675019.entry.js.map +1 -0
- package/dist/sdk/p-79ef9a70.entry.js +2 -0
- package/dist/sdk/p-79ef9a70.entry.js.map +1 -0
- package/dist/sdk/p-7d88e21c.entry.js +2 -0
- package/dist/sdk/p-7d88e21c.entry.js.map +1 -0
- package/dist/sdk/p-7eaf3468.entry.js +2 -0
- package/dist/sdk/p-7eaf3468.entry.js.map +1 -0
- package/dist/sdk/{p-88beb872.entry.js → p-8412762c.entry.js} +2 -2
- package/dist/sdk/p-8ea70c08.entry.js +2 -0
- package/dist/sdk/p-8ea70c08.entry.js.map +1 -0
- package/dist/sdk/p-946cdb0a.entry.js +2 -0
- package/dist/sdk/p-946cdb0a.entry.js.map +1 -0
- package/dist/sdk/p-94bb0217.entry.js +2 -0
- package/dist/sdk/p-94bb0217.entry.js.map +1 -0
- package/dist/sdk/{p-bcca06f1.entry.js → p-96860b09.entry.js} +2 -2
- package/dist/sdk/p-B1A6Nu24.js +2 -0
- package/dist/sdk/p-B1A6Nu24.js.map +1 -0
- package/dist/sdk/p-B85MJLTf.js +2 -0
- package/dist/sdk/p-B85MJLTf.js.map +1 -0
- package/dist/sdk/p-B8N6Bwsa.js +2 -0
- package/dist/sdk/{p-DCG3L43i.js.map → p-B8N6Bwsa.js.map} +1 -1
- package/dist/sdk/p-Ba5szISo.js +2 -0
- package/dist/sdk/p-Ba5szISo.js.map +1 -0
- package/dist/sdk/p-BsJDptgj.js +14 -0
- package/dist/sdk/p-BsJDptgj.js.map +1 -0
- package/dist/sdk/{p-bpXpOZY_.js → p-C0Mo15qt.js} +2 -2
- package/dist/sdk/{p-bpXpOZY_.js.map → p-C0Mo15qt.js.map} +1 -1
- package/dist/sdk/p-C10MAuCE.js +2 -0
- package/dist/sdk/p-C10MAuCE.js.map +1 -0
- package/dist/sdk/p-CTy6pQSg.js +2 -0
- package/dist/sdk/p-CTy6pQSg.js.map +1 -0
- package/dist/sdk/p-CW6kGAuQ.js +2 -0
- package/dist/sdk/p-CW6kGAuQ.js.map +1 -0
- package/dist/sdk/{p-DdMKVWx8.js → p-CbSP8My1.js} +2 -2
- package/dist/sdk/{p-DdMKVWx8.js.map → p-CbSP8My1.js.map} +1 -1
- package/dist/sdk/p-CbzzI4uW.js +2 -0
- package/dist/sdk/p-CbzzI4uW.js.map +1 -0
- package/dist/sdk/p-CgT6fZjb.js +2 -0
- package/dist/sdk/p-CgT6fZjb.js.map +1 -0
- package/dist/sdk/p-CuHZ3IkE.js +2 -0
- package/dist/sdk/p-CuHZ3IkE.js.map +1 -0
- package/dist/sdk/p-Cysk_vik.js +2 -0
- package/dist/sdk/p-Cysk_vik.js.map +1 -0
- package/dist/sdk/p-D0ut3waq.js +2 -0
- package/dist/sdk/p-D0ut3waq.js.map +1 -0
- package/dist/sdk/{p-BigbTrKk.js → p-D2Rf-QGm.js} +2 -2
- package/dist/sdk/{p-BigbTrKk.js.map → p-D2Rf-QGm.js.map} +1 -1
- package/dist/sdk/{p-6rqGeAfT.js → p-D9yFO_ID.js} +2 -2
- package/dist/sdk/{p-6rqGeAfT.js.map → p-D9yFO_ID.js.map} +1 -1
- package/dist/sdk/p-DD_5soRi.js +2 -0
- package/dist/sdk/p-DD_5soRi.js.map +1 -0
- package/dist/sdk/p-DHuvvagO.js +2 -0
- package/dist/sdk/p-DHuvvagO.js.map +1 -0
- package/dist/sdk/p-DSMkJu9G.js +2 -0
- package/dist/sdk/p-DSMkJu9G.js.map +1 -0
- package/dist/sdk/p-DcirMfca.js +2 -0
- package/dist/sdk/p-DcirMfca.js.map +1 -0
- package/dist/sdk/p-J0cv5IOA.js +2 -0
- package/dist/sdk/p-J0cv5IOA.js.map +1 -0
- package/dist/sdk/p-_5evboqW.js +2 -0
- package/dist/sdk/{p-DSktNM_k.js.map → p-_5evboqW.js.map} +1 -1
- package/dist/sdk/{p-7ee2f2ab.entry.js → p-ac3a6bbf.entry.js} +2 -2
- package/dist/sdk/p-b498bcdd.entry.js +2 -0
- package/dist/sdk/p-b498bcdd.entry.js.map +1 -0
- package/dist/sdk/p-b5dd5b4c.entry.js +2 -0
- package/dist/sdk/p-b5dd5b4c.entry.js.map +1 -0
- package/dist/sdk/{p-6b061b18.entry.js → p-b99588a8.entry.js} +2 -2
- package/dist/sdk/p-bf9c27a8.entry.js +2 -0
- package/dist/sdk/p-bf9c27a8.entry.js.map +1 -0
- package/dist/sdk/p-c10d9b8e.entry.js +2 -0
- package/dist/sdk/p-c10d9b8e.entry.js.map +1 -0
- package/dist/sdk/{p-10e20afd.entry.js → p-c2634439.entry.js} +2 -2
- package/dist/sdk/p-d6777395.entry.js +2 -0
- package/dist/sdk/p-d6777395.entry.js.map +1 -0
- package/dist/sdk/p-dbfe7b29.entry.js +2 -0
- package/dist/sdk/p-dbfe7b29.entry.js.map +1 -0
- package/dist/sdk/p-def4e874.entry.js +2 -0
- package/dist/sdk/p-def4e874.entry.js.map +1 -0
- package/dist/sdk/p-e872a012.entry.js +2 -0
- package/dist/sdk/p-e872a012.entry.js.map +1 -0
- package/dist/sdk/p-eaaf3989.entry.js +2 -0
- package/dist/sdk/p-eaaf3989.entry.js.map +1 -0
- package/dist/sdk/p-fd46b459.entry.js +2 -0
- package/dist/sdk/{p-830778eb.entry.js.map → p-fd46b459.entry.js.map} +1 -1
- package/dist/sdk/sdk.esm.js +1 -1
- package/dist/sdk/u-conditional-render.entry.esm.js.map +1 -1
- package/dist/sdk/u-config.entry.esm.js.map +1 -1
- package/dist/sdk/u-error-message.entry.esm.js.map +1 -1
- package/dist/sdk/u-field.u-raw-field.entry.esm.js.map +1 -1
- package/dist/sdk/u-jump-to-service.entry.esm.js.map +1 -1
- package/dist/sdk/u-jump-to-unidy.entry.esm.js.map +1 -1
- package/dist/sdk/u-logout-button.u-signed-in.entry.esm.js.map +1 -1
- package/dist/sdk/u-magic-code-field.entry.esm.js.map +1 -1
- package/dist/sdk/u-missing-field.entry.esm.js.map +1 -1
- package/dist/sdk/u-missing-fields-submit-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-checkbox.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-logout-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-preference-checkbox.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-resend-doi-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-root.entry.esm.js.map +1 -1
- package/dist/sdk/u-newsletter-toggle-subscription-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-pagination-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-pagination-page.entry.esm.js.map +1 -1
- package/dist/sdk/u-passkey.entry.esm.js.map +1 -1
- package/dist/sdk/u-profile.u-submit-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-reset-password-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-send-magic-code-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-signin-root.entry.esm.js.map +1 -1
- package/dist/sdk/u-signin-step.entry.esm.js.map +1 -1
- package/dist/sdk/u-social-login-button.entry.esm.js.map +1 -1
- package/dist/sdk/u-spinner.entry.esm.js.map +1 -1
- package/dist/sdk/u-ticketable-export.entry.esm.js.map +1 -0
- package/dist/sdk/u-ticketable-list.entry.esm.js.map +1 -1
- package/dist/types/api/client.d.ts +1 -1
- package/dist/types/api/index.d.ts +4 -4
- package/dist/types/api/standalone.d.ts +9 -9
- package/dist/types/auth/api/auth.d.ts +2 -3
- package/dist/types/auth/api/schemas.d.ts +19 -19
- package/dist/types/auth/auth-helpers.d.ts +1 -0
- package/dist/types/auth/components/jump-to-service/jump-to-service.d.ts +13 -5
- package/dist/types/auth/components/jump-to-unidy/jump-to-unidy.d.ts +13 -9
- package/dist/types/auth/components/logout-button/logout-button.d.ts +13 -4
- package/dist/types/auth/components/missing-field/missing-field.d.ts +1 -0
- package/dist/types/auth/components/missing-fields-submit-button/missing-fields-submit-button.d.ts +14 -2
- package/dist/types/auth/components/reset-pass-button/reset-pass-button.d.ts +13 -4
- package/dist/types/auth/components/social-logins/social-login-button.d.ts +11 -7
- package/dist/types/components.d.ts +73 -0
- package/dist/types/logger.d.ts +0 -34
- package/dist/types/newsletter/components/logout-button/logout-button.d.ts +13 -4
- package/dist/types/newsletter/components/newsletter-root/newsletter-root.d.ts +16 -2
- package/dist/types/newsletter/newsletter-helpers.d.ts +8 -2
- package/dist/types/newsletter/store/newsletter-store.d.ts +8 -1
- package/dist/types/profile/api/profile.d.ts +2 -2
- package/dist/types/profile/api/schemas.d.ts +21 -21
- package/dist/types/profile/components/raw-field/raw-field.d.ts +14 -2
- package/dist/types/shared/base/component.d.ts +46 -0
- package/dist/types/shared/base/has-slot-content.d.ts +10 -0
- package/dist/types/shared/component-utils.d.ts +20 -12
- package/dist/types/shared/components/conditional-render/conditional-render.d.ts +7 -2
- package/dist/types/shared/components/config/config.d.ts +7 -2
- package/dist/types/shared/components/error-message/error-message.d.ts +14 -2
- package/dist/types/shared/components/submit-button/submit-button.d.ts +13 -4
- package/dist/types/shared/context-utils.d.ts +73 -0
- package/dist/types/shared/utils/redirect-with-token.d.ts +21 -0
- package/dist/types/shared/utils/url-utils.d.ts +16 -0
- package/dist/types/ticketable/api/schemas.d.ts +16 -2
- package/dist/types/ticketable/api/subscriptions.d.ts +8 -3
- package/dist/types/ticketable/api/tickets.d.ts +8 -3
- package/dist/types/ticketable/components/pagination/pagination-button.d.ts +8 -4
- package/dist/types/ticketable/components/pagination/pagination-page.d.ts +8 -4
- package/dist/types/ticketable/components/ticketable-export/ticketable-export.d.ts +24 -0
- package/dist/types/ticketable/components/ticketable-list/ticketable-list.d.ts +10 -4
- package/dist/types/ticketable/index.d.ts +1 -0
- package/package.json +6 -2
- package/readme.md +248 -27
- package/dist/cjs/app-globals-hdkLqF51.js +0 -10
- package/dist/cjs/app-globals-hdkLqF51.js.map +0 -1
- package/dist/cjs/component-utils-bu3SY4dE.js +0 -42
- package/dist/cjs/component-utils-bu3SY4dE.js.map +0 -1
- package/dist/cjs/index-B325yXfO.js.map +0 -1
- package/dist/cjs/index-BzPYBLYC.js.map +0 -1
- package/dist/cjs/newsletter-helpers-hdDC5X-V.js.map +0 -1
- package/dist/cjs/newsletter-store-CupsLgO9.js.map +0 -1
- package/dist/cjs/pagination-store-zo48QpTm.js +0 -16
- package/dist/cjs/pagination-store-zo48QpTm.js.map +0 -1
- package/dist/components/pagination-store.js +0 -14
- package/dist/components/pagination-store.js.map +0 -1
- package/dist/esm/app-globals-iHhGdwBB.js +0 -8
- package/dist/esm/app-globals-iHhGdwBB.js.map +0 -1
- package/dist/esm/component-utils-BGq0leDV.js +0 -39
- package/dist/esm/component-utils-BGq0leDV.js.map +0 -1
- package/dist/esm/index-BVlbCQEX.js.map +0 -1
- package/dist/esm/index-FTKB5a1d.js.map +0 -1
- package/dist/esm/newsletter-helpers-fCpxzovf.js.map +0 -1
- package/dist/esm/newsletter-store-BB618FgS.js.map +0 -1
- package/dist/esm/pagination-store-DxmcQH8R.js +0 -14
- package/dist/esm/pagination-store-DxmcQH8R.js.map +0 -1
- package/dist/sdk/p-1a8973a6.entry.js +0 -2
- package/dist/sdk/p-35ad60ab.entry.js +0 -2
- package/dist/sdk/p-35ad60ab.entry.js.map +0 -1
- package/dist/sdk/p-3f352f38.entry.js +0 -2
- package/dist/sdk/p-3f352f38.entry.js.map +0 -1
- package/dist/sdk/p-468aaf62.entry.js +0 -2
- package/dist/sdk/p-468aaf62.entry.js.map +0 -1
- package/dist/sdk/p-4e2e6a13.entry.js +0 -2
- package/dist/sdk/p-4e2e6a13.entry.js.map +0 -1
- package/dist/sdk/p-57c8dc68.entry.js +0 -2
- package/dist/sdk/p-57c8dc68.entry.js.map +0 -1
- package/dist/sdk/p-594aec0c.entry.js +0 -2
- package/dist/sdk/p-594aec0c.entry.js.map +0 -1
- package/dist/sdk/p-60c8be64.entry.js +0 -2
- package/dist/sdk/p-60c8be64.entry.js.map +0 -1
- package/dist/sdk/p-760718d3.entry.js +0 -2
- package/dist/sdk/p-760718d3.entry.js.map +0 -1
- package/dist/sdk/p-77f541f3.entry.js +0 -2
- package/dist/sdk/p-77f541f3.entry.js.map +0 -1
- package/dist/sdk/p-830778eb.entry.js +0 -2
- package/dist/sdk/p-8839648e.entry.js +0 -2
- package/dist/sdk/p-8839648e.entry.js.map +0 -1
- package/dist/sdk/p-B6MYe-dh.js +0 -2
- package/dist/sdk/p-B6MYe-dh.js.map +0 -1
- package/dist/sdk/p-BGq0leDV.js +0 -2
- package/dist/sdk/p-BGq0leDV.js.map +0 -1
- package/dist/sdk/p-C_UZBwdm.js +0 -2
- package/dist/sdk/p-C_UZBwdm.js.map +0 -1
- package/dist/sdk/p-CbazSxaZ.js +0 -2
- package/dist/sdk/p-CbazSxaZ.js.map +0 -1
- package/dist/sdk/p-DCG3L43i.js +0 -2
- package/dist/sdk/p-DEUPZOH-.js +0 -2
- package/dist/sdk/p-DEUPZOH-.js.map +0 -1
- package/dist/sdk/p-DSktNM_k.js +0 -2
- package/dist/sdk/p-FTKB5a1d.js +0 -14
- package/dist/sdk/p-FTKB5a1d.js.map +0 -1
- package/dist/sdk/p-a7ffcff9.entry.js +0 -2
- package/dist/sdk/p-a7ffcff9.entry.js.map +0 -1
- package/dist/sdk/p-acaba1d5.entry.js +0 -2
- package/dist/sdk/p-acaba1d5.entry.js.map +0 -1
- package/dist/sdk/p-ae47a7a3.entry.js +0 -2
- package/dist/sdk/p-ae47a7a3.entry.js.map +0 -1
- package/dist/sdk/p-aec580e4.entry.js +0 -2
- package/dist/sdk/p-aec580e4.entry.js.map +0 -1
- package/dist/sdk/p-b63438ff.entry.js +0 -2
- package/dist/sdk/p-b63438ff.entry.js.map +0 -1
- package/dist/sdk/p-baaaa7f5.entry.js +0 -2
- package/dist/sdk/p-baaaa7f5.entry.js.map +0 -1
- package/dist/sdk/p-bba2da84.entry.js +0 -2
- package/dist/sdk/p-bba2da84.entry.js.map +0 -1
- package/dist/sdk/p-bc47f42b.entry.js +0 -2
- package/dist/sdk/p-bc47f42b.entry.js.map +0 -1
- package/dist/sdk/p-bd51e26f.entry.js +0 -2
- package/dist/sdk/p-bd51e26f.entry.js.map +0 -1
- package/dist/sdk/p-c3552f75.entry.js +0 -2
- package/dist/sdk/p-c3552f75.entry.js.map +0 -1
- package/dist/sdk/p-d9900482.entry.js +0 -2
- package/dist/sdk/p-d9900482.entry.js.map +0 -1
- package/dist/sdk/p-e6796c38.entry.js +0 -2
- package/dist/sdk/p-e6796c38.entry.js.map +0 -1
- package/dist/sdk/p-f272eb38.entry.js +0 -2
- package/dist/sdk/p-f272eb38.entry.js.map +0 -1
- package/dist/sdk/p-f4a47ef8.entry.js +0 -2
- package/dist/sdk/p-f4a47ef8.entry.js.map +0 -1
- package/dist/sdk/p-f608e64a.entry.js +0 -2
- package/dist/sdk/p-f608e64a.entry.js.map +0 -1
- package/dist/sdk/p-f762ac70.entry.js +0 -2
- package/dist/sdk/p-f762ac70.entry.js.map +0 -1
- package/dist/sdk/p-l6NinBiD.js +0 -2
- package/dist/sdk/p-l6NinBiD.js.map +0 -1
- /package/dist/sdk/{p-88beb872.entry.js.map → p-8412762c.entry.js.map} +0 -0
- /package/dist/sdk/{p-bcca06f1.entry.js.map → p-96860b09.entry.js.map} +0 -0
- /package/dist/sdk/{p-7ee2f2ab.entry.js.map → p-ac3a6bbf.entry.js.map} +0 -0
- /package/dist/sdk/{p-6b061b18.entry.js.map → p-b99588a8.entry.js.map} +0 -0
- /package/dist/sdk/{p-10e20afd.entry.js.map → p-c2634439.entry.js.map} +0 -0
|
@@ -1,164 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { t } from './i18n-
|
|
5
|
-
import { a as authStore, s as state } from './auth-store-
|
|
6
|
-
import {
|
|
7
|
-
import { F as Flash } from './flash-store-Df2YkLTB.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Base API client with shared functionality for both browser and standalone environments.
|
|
11
|
-
*/
|
|
12
|
-
/**
|
|
13
|
-
* Abstract base class for API clients.
|
|
14
|
-
* Provides shared functionality for making HTTP requests.
|
|
15
|
-
*/
|
|
16
|
-
class BaseApiClient {
|
|
17
|
-
/**
|
|
18
|
-
* Error messages that indicate a connection failure rather than a server error.
|
|
19
|
-
* Grouped by source/environment.
|
|
20
|
-
*/
|
|
21
|
-
static CONNECTION_ERROR_MESSAGES = [
|
|
22
|
-
// Browser fetch API errors
|
|
23
|
-
"Failed to fetch", // Generic browser fetch failure (Chrome)
|
|
24
|
-
"NetworkError", // Firefox network error
|
|
25
|
-
"Load failed", // Safari network error
|
|
26
|
-
"The network connection was lost", // Safari connection lost
|
|
27
|
-
// Chromium/V8 error codes (used by Node.js and Chrome)
|
|
28
|
-
"ERR_CONNECTION_REFUSED", // Server not accepting connections
|
|
29
|
-
"ERR_NETWORK", // General network error
|
|
30
|
-
"ERR_INTERNET_DISCONNECTED", // No internet connection
|
|
31
|
-
// Node.js system error codes
|
|
32
|
-
"ECONNREFUSED", // Connection refused by server
|
|
33
|
-
"ENOTFOUND", // DNS lookup failed
|
|
34
|
-
"EAI_AGAIN", // Temporary DNS failure
|
|
35
|
-
];
|
|
36
|
-
onConnectionChange;
|
|
37
|
-
baseUrl;
|
|
38
|
-
api_key;
|
|
39
|
-
constructor(config) {
|
|
40
|
-
this.baseUrl = config.baseUrl;
|
|
41
|
-
this.api_key = config.apiKey;
|
|
42
|
-
this.onConnectionChange = config.onConnectionChange;
|
|
43
|
-
}
|
|
44
|
-
isConnectionError(error) {
|
|
45
|
-
if (error instanceof Error) {
|
|
46
|
-
return BaseApiClient.CONNECTION_ERROR_MESSAGES.some((msg) => error.message.includes(msg));
|
|
47
|
-
}
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
setConnectionStatus(isConnected) {
|
|
51
|
-
this.onConnectionChange?.(isConnected);
|
|
52
|
-
}
|
|
53
|
-
baseHeaders() {
|
|
54
|
-
const h = new Headers();
|
|
55
|
-
h.set("Content-Type", "application/json");
|
|
56
|
-
h.set("Accept", "application/json");
|
|
57
|
-
h.set("Authorization", `Bearer ${this.api_key}`);
|
|
58
|
-
return h;
|
|
59
|
-
}
|
|
60
|
-
mergeHeaders(base, extra) {
|
|
61
|
-
const out = new Headers(base);
|
|
62
|
-
if (extra) {
|
|
63
|
-
new Headers(extra).forEach((v, k) => {
|
|
64
|
-
out.set(k, v);
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
return out;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Builds a query string from params, filtering out undefined/null values.
|
|
71
|
-
*/
|
|
72
|
-
buildQueryString(params) {
|
|
73
|
-
if (!params)
|
|
74
|
-
return "";
|
|
75
|
-
const filtered = Object.entries(params)
|
|
76
|
-
.filter(([_, v]) => v !== undefined && v !== null)
|
|
77
|
-
.map(([k, v]) => [k, String(v)]);
|
|
78
|
-
if (filtered.length === 0)
|
|
79
|
-
return "";
|
|
80
|
-
return `?${new URLSearchParams(Object.fromEntries(filtered)).toString()}`;
|
|
81
|
-
}
|
|
82
|
-
async request(method, endpoint, body, headers) {
|
|
83
|
-
let res = null;
|
|
84
|
-
try {
|
|
85
|
-
res = await fetch(`${this.baseUrl}${endpoint}`, {
|
|
86
|
-
method,
|
|
87
|
-
...this.getRequestOptions(),
|
|
88
|
-
headers: this.mergeHeaders(this.baseHeaders(), headers),
|
|
89
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
90
|
-
});
|
|
91
|
-
let data;
|
|
92
|
-
try {
|
|
93
|
-
data = await res.json();
|
|
94
|
-
}
|
|
95
|
-
catch {
|
|
96
|
-
data = undefined;
|
|
97
|
-
}
|
|
98
|
-
this.setConnectionStatus(true);
|
|
99
|
-
return {
|
|
100
|
-
data,
|
|
101
|
-
status: res.status,
|
|
102
|
-
headers: res.headers,
|
|
103
|
-
success: res.ok,
|
|
104
|
-
connectionError: false,
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
catch (error) {
|
|
108
|
-
const connectionFailed = this.isConnectionError(error);
|
|
109
|
-
if (connectionFailed) {
|
|
110
|
-
this.setConnectionStatus(false);
|
|
111
|
-
this.handleConnectionError(error, endpoint, method);
|
|
112
|
-
}
|
|
113
|
-
return {
|
|
114
|
-
status: res?.status ?? (connectionFailed ? 0 : 500),
|
|
115
|
-
error: error instanceof Error ? error.message : String(error),
|
|
116
|
-
headers: res?.headers ?? new Headers(),
|
|
117
|
-
success: false,
|
|
118
|
-
data: undefined,
|
|
119
|
-
connectionError: connectionFailed,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
async get(endpoint, headers, params) {
|
|
124
|
-
const queryString = this.buildQueryString(params);
|
|
125
|
-
return this.request("GET", `${endpoint}${queryString}`, undefined, headers);
|
|
126
|
-
}
|
|
127
|
-
async post(endpoint, body, headers) {
|
|
128
|
-
return this.request("POST", endpoint, body, headers);
|
|
129
|
-
}
|
|
130
|
-
async patch(endpoint, body, headers) {
|
|
131
|
-
return this.request("PATCH", endpoint, body, headers);
|
|
132
|
-
}
|
|
133
|
-
async delete(endpoint, headers) {
|
|
134
|
-
return this.request("DELETE", endpoint, undefined, headers);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Browser-specific API client with CORS mode and Sentry error reporting.
|
|
140
|
-
*/
|
|
141
|
-
class ApiClient extends BaseApiClient {
|
|
142
|
-
constructor(baseUrl, apiKey, onConnectionChange) {
|
|
143
|
-
super({ baseUrl, apiKey, onConnectionChange });
|
|
144
|
-
}
|
|
145
|
-
setConnectionStatus(isConnected) {
|
|
146
|
-
super.setConnectionStatus(isConnected);
|
|
147
|
-
unidyState.backendConnected = isConnected;
|
|
148
|
-
}
|
|
149
|
-
getRequestOptions() {
|
|
150
|
-
return {
|
|
151
|
-
mode: "cors",
|
|
152
|
-
credentials: "include",
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
handleConnectionError(error, endpoint, method) {
|
|
156
|
-
captureException(error, {
|
|
157
|
-
tags: { error_type: "connection_error" },
|
|
158
|
-
extra: { endpoint, method },
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
}
|
|
1
|
+
import { s as state$1 } from './profile-store-7wBS3gBH.js';
|
|
2
|
+
import { i as createLogger, f as captureException } from './index-BsJDptgj.js';
|
|
3
|
+
import { w as waitForConfig, u as unidyState } from './unidy-store-B5Bf4Vit.js';
|
|
4
|
+
import { t } from './i18n-ioyZxWsT.js';
|
|
5
|
+
import { a as authStore, s as state } from './auth-store-CSpEdi46.js';
|
|
6
|
+
import { F as Flash } from './flash-store-Dn1Bava8.js';
|
|
162
7
|
|
|
163
8
|
/** A special constant with type `never` */
|
|
164
9
|
function $constructor(name, initializer, params) {
|
|
@@ -5148,7 +4993,7 @@ const BaseFieldDataSchema = object({
|
|
|
5148
4993
|
label: string(),
|
|
5149
4994
|
attr_name: string(),
|
|
5150
4995
|
locked: boolean().optional(),
|
|
5151
|
-
locked_text: string().
|
|
4996
|
+
locked_text: string().nullish(),
|
|
5152
4997
|
})
|
|
5153
4998
|
.strict();
|
|
5154
4999
|
// Select option schema
|
|
@@ -5362,7 +5207,7 @@ const ErrorSchema = BaseErrorSchema;
|
|
|
5362
5207
|
// Magic code response
|
|
5363
5208
|
const SendMagicCodeResponseSchema = object({
|
|
5364
5209
|
enable_resend_after: number(),
|
|
5365
|
-
sid: string().
|
|
5210
|
+
sid: string().nullish(),
|
|
5366
5211
|
login_options: object({
|
|
5367
5212
|
magic_link: boolean(),
|
|
5368
5213
|
})
|
|
@@ -5375,7 +5220,7 @@ const SendMagicCodeErrorSchema = BaseErrorSchema.extend({
|
|
|
5375
5220
|
// JWT token response
|
|
5376
5221
|
const TokenResponseSchema = object({
|
|
5377
5222
|
jwt: string(),
|
|
5378
|
-
sid: string().
|
|
5223
|
+
sid: string().nullish(),
|
|
5379
5224
|
});
|
|
5380
5225
|
// Missing required fields response extends base error with specific error_identifier
|
|
5381
5226
|
const RequiredFieldsResponseSchema = object({
|
|
@@ -5384,7 +5229,7 @@ const RequiredFieldsResponseSchema = object({
|
|
|
5384
5229
|
fields: UserProfileSchema.omit({ custom_attributes: true }).partial().extend({
|
|
5385
5230
|
custom_attributes: UserProfileSchema.shape.custom_attributes?.optional(),
|
|
5386
5231
|
}),
|
|
5387
|
-
sid: string().
|
|
5232
|
+
sid: string().nullish(),
|
|
5388
5233
|
}),
|
|
5389
5234
|
})
|
|
5390
5235
|
.transform(({ error_identifier, meta }) => ({
|
|
@@ -5426,8 +5271,8 @@ const JumpToUnidyErrorSchema = object({
|
|
|
5426
5271
|
});
|
|
5427
5272
|
const JumpToServiceRequestSchema = object({
|
|
5428
5273
|
email: string(),
|
|
5429
|
-
redirect_uri: string().
|
|
5430
|
-
scopes: array(string()).
|
|
5274
|
+
redirect_uri: string().nullish(),
|
|
5275
|
+
scopes: array(string()).nullish(),
|
|
5431
5276
|
skip_oauth_authorization: boolean().optional(),
|
|
5432
5277
|
});
|
|
5433
5278
|
const JumpToUnidyRequestSchema = object({
|
|
@@ -5698,672 +5543,158 @@ class AuthService extends BaseService {
|
|
|
5698
5543
|
}
|
|
5699
5544
|
}
|
|
5700
5545
|
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
|
|
5704
|
-
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
});
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
|
|
5723
|
-
|
|
5724
|
-
|
|
5725
|
-
|
|
5726
|
-
first_name: string().nullable(),
|
|
5727
|
-
last_name: string().nullable(),
|
|
5728
|
-
salutation: SalutationEnum.nullable(),
|
|
5729
|
-
phone_number: string().nullable(),
|
|
5730
|
-
date_of_birth: string().nullable(),
|
|
5731
|
-
company_name: string().nullable(),
|
|
5732
|
-
address_line_1: string().nullable(),
|
|
5733
|
-
address_line_2: string().nullable(),
|
|
5734
|
-
city: string().nullable(),
|
|
5735
|
-
postal_code: string().nullable(),
|
|
5736
|
-
country_code: string().nullable(),
|
|
5737
|
-
preferred_language: string().nullable(),
|
|
5738
|
-
custom_attributes: record(string(), unknown()).nullable(),
|
|
5739
|
-
})
|
|
5740
|
-
.partial();
|
|
5741
|
-
// Create subscriptions payload
|
|
5742
|
-
const CreateSubscriptionsPayloadSchema = object({
|
|
5743
|
-
email: string(),
|
|
5744
|
-
additional_fields: optional(AdditionalFieldsSchema),
|
|
5745
|
-
newsletter_subscriptions: array(object({
|
|
5746
|
-
newsletter_internal_name: string(),
|
|
5747
|
-
preference_identifiers: optional(array(string())),
|
|
5748
|
-
})),
|
|
5749
|
-
redirect_to_after_confirmation: optional(string()),
|
|
5750
|
-
});
|
|
5751
|
-
// Update subscription payload
|
|
5752
|
-
const UpdateSubscriptionPayloadSchema = object({
|
|
5753
|
-
preference_identifiers: array(string()),
|
|
5754
|
-
});
|
|
5755
|
-
// Login email payload
|
|
5756
|
-
const LoginEmailPayloadSchema = object({
|
|
5757
|
-
email: string(),
|
|
5758
|
-
redirect_uri: string(),
|
|
5759
|
-
});
|
|
5760
|
-
// Resend DOI payload
|
|
5761
|
-
const ResendDoiPayloadSchema = object({
|
|
5762
|
-
redirect_to_after_confirmation: string(),
|
|
5763
|
-
})
|
|
5764
|
-
.partial();
|
|
5765
|
-
// Preference schema
|
|
5766
|
-
const PreferenceSchema = object({
|
|
5767
|
-
id: number(),
|
|
5768
|
-
name: string(),
|
|
5769
|
-
description: string().nullable(),
|
|
5770
|
-
plugin_identifier: string().nullable(),
|
|
5771
|
-
position: number(),
|
|
5772
|
-
default: boolean(),
|
|
5773
|
-
hidden: boolean(),
|
|
5774
|
-
});
|
|
5775
|
-
// Preference group schema
|
|
5776
|
-
const PreferenceGroupSchema = object({
|
|
5777
|
-
id: number(),
|
|
5778
|
-
name: string(),
|
|
5779
|
-
position: number(),
|
|
5780
|
-
flat: boolean(),
|
|
5781
|
-
preferences: array(PreferenceSchema),
|
|
5782
|
-
});
|
|
5783
|
-
// Newsletter schema
|
|
5784
|
-
const NewsletterSchema = object({
|
|
5785
|
-
id: number(),
|
|
5786
|
-
internal_name: string(),
|
|
5787
|
-
default: boolean(),
|
|
5788
|
-
position: number(),
|
|
5789
|
-
opt_in_type: string(),
|
|
5790
|
-
title: string(),
|
|
5791
|
-
description: string().nullable(),
|
|
5792
|
-
created_at: string(),
|
|
5793
|
-
updated_at: string(),
|
|
5794
|
-
preference_groups: array(PreferenceGroupSchema),
|
|
5795
|
-
});
|
|
5796
|
-
// Newsletters list response
|
|
5797
|
-
const NewslettersResponseSchema = object({
|
|
5798
|
-
newsletters: array(NewsletterSchema),
|
|
5799
|
-
});
|
|
5800
|
-
// Delete subscription response
|
|
5801
|
-
const DeleteSubscriptionResponseSchema = object({
|
|
5802
|
-
new_preference_token: string(),
|
|
5803
|
-
})
|
|
5804
|
-
.nullable();
|
|
5805
|
-
// Generic newsletter error response (extends base error)
|
|
5806
|
-
const NewsletterErrorResponseSchema = BaseErrorSchema;
|
|
5807
|
-
|
|
5808
|
-
class NewsletterService extends BaseService {
|
|
5809
|
-
constructor(client, deps) {
|
|
5810
|
-
super(client, "NewsletterService", deps);
|
|
5546
|
+
class InvalidTokenError extends Error {
|
|
5547
|
+
}
|
|
5548
|
+
InvalidTokenError.prototype.name = "InvalidTokenError";
|
|
5549
|
+
function b64DecodeUnicode(str) {
|
|
5550
|
+
return decodeURIComponent(atob(str).replace(/(.)/g, (m, p) => {
|
|
5551
|
+
let code = p.charCodeAt(0).toString(16).toUpperCase();
|
|
5552
|
+
if (code.length < 2) {
|
|
5553
|
+
code = "0" + code;
|
|
5554
|
+
}
|
|
5555
|
+
return "%" + code;
|
|
5556
|
+
}));
|
|
5557
|
+
}
|
|
5558
|
+
function base64UrlDecode(str) {
|
|
5559
|
+
let output = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
5560
|
+
switch (output.length % 4) {
|
|
5561
|
+
case 0:
|
|
5562
|
+
break;
|
|
5563
|
+
case 2:
|
|
5564
|
+
output += "==";
|
|
5565
|
+
break;
|
|
5566
|
+
case 3:
|
|
5567
|
+
output += "=";
|
|
5568
|
+
break;
|
|
5569
|
+
default:
|
|
5570
|
+
throw new Error("base64 string is not of the correct length");
|
|
5811
5571
|
}
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
return this.buildAuthHeaders({
|
|
5815
|
-
"X-ID-Token": idToken ?? undefined,
|
|
5816
|
-
"X-Preference-Token": options?.preferenceToken,
|
|
5817
|
-
});
|
|
5572
|
+
try {
|
|
5573
|
+
return b64DecodeUnicode(output);
|
|
5818
5574
|
}
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
*/
|
|
5822
|
-
async create(args) {
|
|
5823
|
-
const { payload, options } = args;
|
|
5824
|
-
const validatedPayload = CreateSubscriptionsPayloadSchema.safeParse(payload);
|
|
5825
|
-
if (!validatedPayload.success) {
|
|
5826
|
-
this.logger.error("Invalid payload for create", validatedPayload.error);
|
|
5827
|
-
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
5828
|
-
}
|
|
5829
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5830
|
-
const response = await this.client.post("/api/sdk/v1/newsletters/newsletter_subscription", payload, headers);
|
|
5831
|
-
return this.handleResponse(response, () => {
|
|
5832
|
-
if (!response.success) {
|
|
5833
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5834
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5835
|
-
switch (response.status) {
|
|
5836
|
-
case 401:
|
|
5837
|
-
return ["unauthorized", error];
|
|
5838
|
-
case 429:
|
|
5839
|
-
this.logger.warn("Rate limit exceeded");
|
|
5840
|
-
return ["rate_limit_exceeded", error];
|
|
5841
|
-
case 500:
|
|
5842
|
-
this.errorReporter.captureException(response);
|
|
5843
|
-
return ["server_error", error];
|
|
5844
|
-
default:
|
|
5845
|
-
return ["server_error", error];
|
|
5846
|
-
}
|
|
5847
|
-
}
|
|
5848
|
-
const data = CreateSubscriptionsResponseSchema.parse(response.data);
|
|
5849
|
-
if (data.errors.length > 0) {
|
|
5850
|
-
return ["newsletter_error", data];
|
|
5851
|
-
}
|
|
5852
|
-
return [null, data];
|
|
5853
|
-
});
|
|
5575
|
+
catch (err) {
|
|
5576
|
+
return atob(output);
|
|
5854
5577
|
}
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
const headers = await this.buildNewsletterAuthHeaders(args?.options);
|
|
5860
|
-
const response = await this.client.get("/api/sdk/v1/newsletters/newsletter_subscription", headers);
|
|
5861
|
-
return this.handleResponse(response, () => {
|
|
5862
|
-
if (!response.success) {
|
|
5863
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5864
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5865
|
-
if (response.status === 401) {
|
|
5866
|
-
return ["unauthorized", error];
|
|
5867
|
-
}
|
|
5868
|
-
return ["server_error", error];
|
|
5869
|
-
}
|
|
5870
|
-
const data = array(NewsletterSubscriptionSchema).parse(response.data);
|
|
5871
|
-
return [null, data];
|
|
5872
|
-
});
|
|
5578
|
+
}
|
|
5579
|
+
function jwtDecode(token, options) {
|
|
5580
|
+
if (typeof token !== "string") {
|
|
5581
|
+
throw new InvalidTokenError("Invalid token specified: must be a string");
|
|
5873
5582
|
}
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5880
|
-
const response = await this.client.get(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, headers);
|
|
5881
|
-
return this.handleResponse(response, () => {
|
|
5882
|
-
if (!response.success) {
|
|
5883
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5884
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5885
|
-
if (response.status === 401) {
|
|
5886
|
-
return ["unauthorized", error];
|
|
5887
|
-
}
|
|
5888
|
-
if (response.status === 404) {
|
|
5889
|
-
return ["not_found", error];
|
|
5890
|
-
}
|
|
5891
|
-
return ["server_error", error];
|
|
5892
|
-
}
|
|
5893
|
-
const data = NewsletterSubscriptionSchema.parse(response.data);
|
|
5894
|
-
return [null, data];
|
|
5895
|
-
});
|
|
5583
|
+
options || (options = {});
|
|
5584
|
+
const pos = options.header === true ? 0 : 1;
|
|
5585
|
+
const part = token.split(".")[pos];
|
|
5586
|
+
if (typeof part !== "string") {
|
|
5587
|
+
throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);
|
|
5896
5588
|
}
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
async update(args) {
|
|
5901
|
-
const { internalName, payload, options } = args;
|
|
5902
|
-
const validatedPayload = UpdateSubscriptionPayloadSchema.safeParse(payload);
|
|
5903
|
-
if (!validatedPayload.success) {
|
|
5904
|
-
this.logger.error("Invalid payload for update", validatedPayload.error);
|
|
5905
|
-
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
5906
|
-
}
|
|
5907
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5908
|
-
const response = await this.client.patch(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, payload, headers);
|
|
5909
|
-
return this.handleResponse(response, () => {
|
|
5910
|
-
if (!response.success) {
|
|
5911
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5912
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5913
|
-
if (response.status === 401) {
|
|
5914
|
-
return ["unauthorized", error];
|
|
5915
|
-
}
|
|
5916
|
-
if (response.status === 404) {
|
|
5917
|
-
return ["not_found", error];
|
|
5918
|
-
}
|
|
5919
|
-
return ["server_error", error];
|
|
5920
|
-
}
|
|
5921
|
-
const data = NewsletterSubscriptionSchema.parse(response.data);
|
|
5922
|
-
return [null, data];
|
|
5923
|
-
});
|
|
5589
|
+
let decoded;
|
|
5590
|
+
try {
|
|
5591
|
+
decoded = base64UrlDecode(part);
|
|
5924
5592
|
}
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
*/
|
|
5928
|
-
async delete(args) {
|
|
5929
|
-
const { internalName, options } = args;
|
|
5930
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5931
|
-
const response = await this.client.delete(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, headers);
|
|
5932
|
-
return this.handleResponse(response, () => {
|
|
5933
|
-
if (!response.success) {
|
|
5934
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5935
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5936
|
-
if (response.status === 401) {
|
|
5937
|
-
return ["unauthorized", error];
|
|
5938
|
-
}
|
|
5939
|
-
if (response.status === 404) {
|
|
5940
|
-
return ["not_found", error];
|
|
5941
|
-
}
|
|
5942
|
-
if (response.status === 422) {
|
|
5943
|
-
return ["unprocessable_entity", error];
|
|
5944
|
-
}
|
|
5945
|
-
return ["server_error", error];
|
|
5946
|
-
}
|
|
5947
|
-
if (response.status === 204) {
|
|
5948
|
-
return [null, null];
|
|
5949
|
-
}
|
|
5950
|
-
const data = DeleteSubscriptionResponseSchema.parse(response.data);
|
|
5951
|
-
return [null, data];
|
|
5952
|
-
});
|
|
5593
|
+
catch (e) {
|
|
5594
|
+
throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);
|
|
5953
5595
|
}
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
*/
|
|
5957
|
-
async resendDoi(args) {
|
|
5958
|
-
const { internalName, payload, options } = args;
|
|
5959
|
-
const validatedPayload = ResendDoiPayloadSchema.safeParse(payload);
|
|
5960
|
-
if (!validatedPayload.success) {
|
|
5961
|
-
this.logger.error("Invalid payload for resendDoi", validatedPayload.error);
|
|
5962
|
-
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
5963
|
-
}
|
|
5964
|
-
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
5965
|
-
const response = await this.client.post(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription/resend_doi`, payload, headers);
|
|
5966
|
-
return this.handleResponse(response, () => {
|
|
5967
|
-
if (!response.success) {
|
|
5968
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5969
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5970
|
-
if (response.status === 401) {
|
|
5971
|
-
return ["unauthorized", error];
|
|
5972
|
-
}
|
|
5973
|
-
if (response.status === 404) {
|
|
5974
|
-
return ["not_found", error];
|
|
5975
|
-
}
|
|
5976
|
-
if (error.error_identifier === "already_confirmed") {
|
|
5977
|
-
return ["already_confirmed", error];
|
|
5978
|
-
}
|
|
5979
|
-
return ["server_error", error];
|
|
5980
|
-
}
|
|
5981
|
-
return [null, null];
|
|
5982
|
-
});
|
|
5596
|
+
try {
|
|
5597
|
+
return JSON.parse(decoded);
|
|
5983
5598
|
}
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
*/
|
|
5987
|
-
async sendLoginEmail(args) {
|
|
5988
|
-
const { payload } = args;
|
|
5989
|
-
const validatedPayload = LoginEmailPayloadSchema.safeParse(payload);
|
|
5990
|
-
if (!validatedPayload.success) {
|
|
5991
|
-
this.logger.error("Invalid payload for sendLoginEmail", validatedPayload.error);
|
|
5992
|
-
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
5993
|
-
}
|
|
5994
|
-
const response = await this.client.post("/api/sdk/v1/newsletters/newsletter_subscription/login_email", payload);
|
|
5995
|
-
return this.handleResponse(response, () => {
|
|
5996
|
-
if (!response.success) {
|
|
5997
|
-
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
5998
|
-
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
5999
|
-
if (response.status === 429) {
|
|
6000
|
-
return ["rate_limit_exceeded", error];
|
|
6001
|
-
}
|
|
6002
|
-
if (response.status === 404) {
|
|
6003
|
-
return ["not_found", error];
|
|
6004
|
-
}
|
|
6005
|
-
return ["server_error", error];
|
|
6006
|
-
}
|
|
6007
|
-
return [null, null];
|
|
6008
|
-
});
|
|
5599
|
+
catch (e) {
|
|
5600
|
+
throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);
|
|
6009
5601
|
}
|
|
6010
|
-
|
|
6011
|
-
|
|
6012
|
-
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
if (response.status === 404) {
|
|
6034
|
-
return ["not_found", error];
|
|
6035
|
-
}
|
|
6036
|
-
return ["server_error", error];
|
|
6037
|
-
}
|
|
6038
|
-
const data = NewsletterSchema.parse(response.data);
|
|
6039
|
-
return [null, data];
|
|
6040
|
-
});
|
|
5602
|
+
}
|
|
5603
|
+
|
|
5604
|
+
/**
|
|
5605
|
+
* Removes a query parameter from the current URL and updates the browser history.
|
|
5606
|
+
* Uses `replaceState` to avoid adding a new history entry.
|
|
5607
|
+
*
|
|
5608
|
+
* @param param - The name of the query parameter to remove
|
|
5609
|
+
* @returns The value of the removed parameter, or null if it wasn't present
|
|
5610
|
+
*
|
|
5611
|
+
* @example
|
|
5612
|
+
* ```ts
|
|
5613
|
+
* // URL: https://example.com?token=abc123&foo=bar
|
|
5614
|
+
* const token = clearUrlParam("token");
|
|
5615
|
+
* // token = "abc123"
|
|
5616
|
+
* // URL is now: https://example.com?foo=bar
|
|
5617
|
+
* ```
|
|
5618
|
+
*/
|
|
5619
|
+
function clearUrlParam(param) {
|
|
5620
|
+
const url = new URL(window.location.href);
|
|
5621
|
+
const value = url.searchParams.get(param);
|
|
5622
|
+
if (value) {
|
|
5623
|
+
url.searchParams.delete(param);
|
|
5624
|
+
window.history.replaceState(null, "", url.toString());
|
|
6041
5625
|
}
|
|
5626
|
+
return value;
|
|
6042
5627
|
}
|
|
6043
5628
|
|
|
6044
|
-
|
|
6045
|
-
const
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
|
|
6068
|
-
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6077
|
-
|
|
6078
|
-
|
|
6079
|
-
}
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
// Subscription schema based on SubscriptionSerializer
|
|
6086
|
-
const SubscriptionSchema = object({
|
|
6087
|
-
id: uuid(), // unidy_id
|
|
6088
|
-
title: string(),
|
|
6089
|
-
text: string(),
|
|
6090
|
-
payment_frequency: string().nullable(),
|
|
6091
|
-
metadata: record(string(), unknown()).nullable(),
|
|
6092
|
-
wallet_export: record(string(), unknown()).nullable(),
|
|
6093
|
-
state: string(),
|
|
6094
|
-
reference: string(),
|
|
6095
|
-
payment_state: string().nullable(),
|
|
6096
|
-
currency: string().nullable(),
|
|
6097
|
-
button_cta_url: string().nullable(),
|
|
6098
|
-
created_at: dateTransformer, // ISO8601(3) -> Date
|
|
6099
|
-
updated_at: dateTransformer, // ISO8601(3) -> Date
|
|
6100
|
-
starts_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6101
|
-
ends_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6102
|
-
next_payment_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6103
|
-
price: number(), // decimal(8, 2) -> float
|
|
6104
|
-
user_id: uuid(),
|
|
6105
|
-
subscription_category_id: uuid(),
|
|
6106
|
-
});
|
|
6107
|
-
// Subscriptions list response schema
|
|
6108
|
-
const SubscriptionsListResponseSchema = object({
|
|
6109
|
-
meta: PaginationMetaSchema,
|
|
6110
|
-
results: array(SubscriptionSchema),
|
|
6111
|
-
});
|
|
6112
|
-
|
|
6113
|
-
/**
|
|
6114
|
-
* Base service for ticketable resources (tickets and subscriptions).
|
|
6115
|
-
* Handles common query parameter building and response parsing.
|
|
6116
|
-
*/
|
|
6117
|
-
class TicketableService extends BaseService {
|
|
6118
|
-
/**
|
|
6119
|
-
* Builds query params from args, mapping camelCase to snake_case.
|
|
6120
|
-
* Returns undefined values filtered out.
|
|
6121
|
-
*/
|
|
6122
|
-
buildListParams(args = {}, categoryIdKey, categoryIdValue) {
|
|
6123
|
-
return {
|
|
6124
|
-
page: args.page,
|
|
6125
|
-
limit: args.perPage,
|
|
6126
|
-
state: args.state,
|
|
6127
|
-
payment_state: args.paymentState,
|
|
6128
|
-
order_by: args.orderBy,
|
|
6129
|
-
order_direction: args.orderDirection,
|
|
6130
|
-
service_id: args.serviceId,
|
|
6131
|
-
[categoryIdKey]: categoryIdValue,
|
|
6132
|
-
};
|
|
6133
|
-
}
|
|
6134
|
-
/**
|
|
6135
|
-
* Converts params to query string, filtering undefined/null and converting to strings.
|
|
6136
|
-
*/
|
|
6137
|
-
toQueryString(params) {
|
|
6138
|
-
const filtered = Object.entries(params)
|
|
6139
|
-
.filter(([_, v]) => v !== undefined && v !== null)
|
|
6140
|
-
.map(([k, v]) => [k, String(v)]);
|
|
6141
|
-
if (filtered.length === 0)
|
|
6142
|
-
return "";
|
|
6143
|
-
return `?${new URLSearchParams(Object.fromEntries(filtered)).toString()}`;
|
|
6144
|
-
}
|
|
6145
|
-
/**
|
|
6146
|
-
* Validates list arguments before making API request.
|
|
6147
|
-
* Uses Zod for input validation.
|
|
6148
|
-
*/
|
|
6149
|
-
validateListArgs(args) {
|
|
6150
|
-
const result = TicketableListParamsSchema.safeParse(args);
|
|
6151
|
-
if (!result.success) {
|
|
6152
|
-
this.logger.error("Invalid list parameters", result.error);
|
|
6153
|
-
return false;
|
|
6154
|
-
}
|
|
6155
|
-
return true;
|
|
5629
|
+
const logger = createLogger("PasskeyAuth");
|
|
5630
|
+
const PASSKEY_ERRORS = {
|
|
5631
|
+
NotSupportedError: "passkey_not_supported",
|
|
5632
|
+
NotAllowedError: "passkey_cancelled",
|
|
5633
|
+
SecurityError: "passkey_security_error",
|
|
5634
|
+
InvalidStateError: "passkey_invalid_state",
|
|
5635
|
+
};
|
|
5636
|
+
function decodeBase64Url(base64url) {
|
|
5637
|
+
const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
|
|
5638
|
+
const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
|
|
5639
|
+
return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
|
|
5640
|
+
}
|
|
5641
|
+
function buildPublicKeyOptions(options) {
|
|
5642
|
+
return {
|
|
5643
|
+
challenge: Uint8Array.from(atob(options.challenge), (c) => c.charCodeAt(0)),
|
|
5644
|
+
timeout: options.timeout || 60000,
|
|
5645
|
+
rpId: options.rpId,
|
|
5646
|
+
userVerification: options.userVerification || "required",
|
|
5647
|
+
allowCredentials: options.allowCredentials?.map((cred) => ({
|
|
5648
|
+
...cred,
|
|
5649
|
+
id: decodeBase64Url(cred.id),
|
|
5650
|
+
})),
|
|
5651
|
+
};
|
|
5652
|
+
}
|
|
5653
|
+
function formatCredentialForServer(credential) {
|
|
5654
|
+
const response = credential.response;
|
|
5655
|
+
return {
|
|
5656
|
+
id: credential.id,
|
|
5657
|
+
rawId: btoa(String.fromCharCode(...new Uint8Array(credential.rawId))),
|
|
5658
|
+
response: {
|
|
5659
|
+
authenticatorData: btoa(String.fromCharCode(...new Uint8Array(response.authenticatorData))),
|
|
5660
|
+
clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(response.clientDataJSON))),
|
|
5661
|
+
signature: btoa(String.fromCharCode(...new Uint8Array(response.signature))),
|
|
5662
|
+
},
|
|
5663
|
+
type: credential.type,
|
|
5664
|
+
};
|
|
5665
|
+
}
|
|
5666
|
+
function extractAndSetSignInId(tokenResponse) {
|
|
5667
|
+
if (tokenResponse.sid) {
|
|
5668
|
+
authStore.setSignInId(tokenResponse.sid);
|
|
5669
|
+
return;
|
|
6156
5670
|
}
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
if (!this.validateListArgs(args)) {
|
|
6163
|
-
return ["invalid_response", null]; // Invalid input treated same as invalid response
|
|
6164
|
-
}
|
|
6165
|
-
const idToken = await this.getIdToken();
|
|
6166
|
-
if (!idToken) {
|
|
6167
|
-
return ["missing_id_token", null];
|
|
5671
|
+
// Fallback: extract sid from JWT token payload
|
|
5672
|
+
try {
|
|
5673
|
+
const decoded = jwtDecode(tokenResponse.jwt);
|
|
5674
|
+
if (decoded.sid) {
|
|
5675
|
+
authStore.setSignInId(decoded.sid);
|
|
6168
5676
|
}
|
|
6169
|
-
const response = await this.client.get(`${endpoint}${queryString}`, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6170
|
-
return this.handleResponse(response, () => {
|
|
6171
|
-
if (!response.success) {
|
|
6172
|
-
this.logger.error(`Failed to fetch ${resourceName}`, response);
|
|
6173
|
-
return ["server_error", null];
|
|
6174
|
-
}
|
|
6175
|
-
const parsed = schema.safeParse(response.data);
|
|
6176
|
-
if (!parsed.success) {
|
|
6177
|
-
this.logger.error("Invalid response format", parsed.error);
|
|
6178
|
-
this.errorReporter.captureException(parsed.error, { resourceName, endpoint });
|
|
6179
|
-
return ["invalid_response", null];
|
|
6180
|
-
}
|
|
6181
|
-
return [null, parsed.data];
|
|
6182
|
-
});
|
|
6183
5677
|
}
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
*/
|
|
6187
|
-
async handleGet(endpoint, schema, resourceName) {
|
|
6188
|
-
const idToken = await this.getIdToken();
|
|
6189
|
-
if (!idToken) {
|
|
6190
|
-
return ["missing_id_token", null];
|
|
6191
|
-
}
|
|
6192
|
-
const response = await this.client.get(endpoint, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6193
|
-
return this.handleResponse(response, () => {
|
|
6194
|
-
if (!response.success) {
|
|
6195
|
-
if (response.status === 404) {
|
|
6196
|
-
return ["not_found", null];
|
|
6197
|
-
}
|
|
6198
|
-
this.logger.error(`Failed to fetch ${resourceName}`, response);
|
|
6199
|
-
return ["server_error", null];
|
|
6200
|
-
}
|
|
6201
|
-
const parsed = schema.safeParse(response.data);
|
|
6202
|
-
if (!parsed.success) {
|
|
6203
|
-
this.logger.error("Invalid response format", parsed.error);
|
|
6204
|
-
this.errorReporter.captureException(parsed.error, { resourceName, endpoint });
|
|
6205
|
-
return ["invalid_response", null];
|
|
6206
|
-
}
|
|
6207
|
-
return [null, parsed.data];
|
|
6208
|
-
});
|
|
5678
|
+
catch {
|
|
5679
|
+
// Failed to decode JWT token to extract sid, continue without it
|
|
6209
5680
|
}
|
|
6210
5681
|
}
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
async list(args = {}) {
|
|
6217
|
-
const params = this.buildListParams(args, "subscription_category_id", args.subscriptionCategoryId);
|
|
6218
|
-
const queryString = this.toQueryString(params);
|
|
6219
|
-
return this.handleList("/api/sdk/v1/subscriptions", queryString, SubscriptionsListResponseSchema, "subscriptions", args);
|
|
6220
|
-
}
|
|
6221
|
-
async get(args) {
|
|
6222
|
-
return this.handleGet(`/api/sdk/v1/subscriptions/${args.id}`, SubscriptionSchema, "subscription");
|
|
5682
|
+
function handlePasskeyError(error) {
|
|
5683
|
+
logger.error("Passkey error:", error);
|
|
5684
|
+
let errorMessage = "passkey_error";
|
|
5685
|
+
if (error instanceof DOMException) {
|
|
5686
|
+
errorMessage = PASSKEY_ERRORS[error.name] || "passkey_error";
|
|
6223
5687
|
}
|
|
5688
|
+
authStore.setFieldError("passkey", errorMessage);
|
|
5689
|
+
authStore.setLoading(false);
|
|
6224
5690
|
}
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
const queryString = this.toQueryString(params);
|
|
6233
|
-
return this.handleList("/api/sdk/v1/tickets", queryString, TicketsListResponseSchema, "tickets", args);
|
|
6234
|
-
}
|
|
6235
|
-
async get(args) {
|
|
6236
|
-
return this.handleGet(`/api/sdk/v1/tickets/${args.id}`, TicketSchema, "ticket");
|
|
6237
|
-
}
|
|
6238
|
-
}
|
|
6239
|
-
|
|
6240
|
-
class InvalidTokenError extends Error {
|
|
6241
|
-
}
|
|
6242
|
-
InvalidTokenError.prototype.name = "InvalidTokenError";
|
|
6243
|
-
function b64DecodeUnicode(str) {
|
|
6244
|
-
return decodeURIComponent(atob(str).replace(/(.)/g, (m, p) => {
|
|
6245
|
-
let code = p.charCodeAt(0).toString(16).toUpperCase();
|
|
6246
|
-
if (code.length < 2) {
|
|
6247
|
-
code = "0" + code;
|
|
6248
|
-
}
|
|
6249
|
-
return "%" + code;
|
|
6250
|
-
}));
|
|
6251
|
-
}
|
|
6252
|
-
function base64UrlDecode(str) {
|
|
6253
|
-
let output = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
6254
|
-
switch (output.length % 4) {
|
|
6255
|
-
case 0:
|
|
6256
|
-
break;
|
|
6257
|
-
case 2:
|
|
6258
|
-
output += "==";
|
|
6259
|
-
break;
|
|
6260
|
-
case 3:
|
|
6261
|
-
output += "=";
|
|
6262
|
-
break;
|
|
6263
|
-
default:
|
|
6264
|
-
throw new Error("base64 string is not of the correct length");
|
|
6265
|
-
}
|
|
6266
|
-
try {
|
|
6267
|
-
return b64DecodeUnicode(output);
|
|
6268
|
-
}
|
|
6269
|
-
catch (err) {
|
|
6270
|
-
return atob(output);
|
|
6271
|
-
}
|
|
6272
|
-
}
|
|
6273
|
-
function jwtDecode(token, options) {
|
|
6274
|
-
if (typeof token !== "string") {
|
|
6275
|
-
throw new InvalidTokenError("Invalid token specified: must be a string");
|
|
6276
|
-
}
|
|
6277
|
-
options || (options = {});
|
|
6278
|
-
const pos = options.header === true ? 0 : 1;
|
|
6279
|
-
const part = token.split(".")[pos];
|
|
6280
|
-
if (typeof part !== "string") {
|
|
6281
|
-
throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);
|
|
6282
|
-
}
|
|
6283
|
-
let decoded;
|
|
6284
|
-
try {
|
|
6285
|
-
decoded = base64UrlDecode(part);
|
|
6286
|
-
}
|
|
6287
|
-
catch (e) {
|
|
6288
|
-
throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);
|
|
6289
|
-
}
|
|
6290
|
-
try {
|
|
6291
|
-
return JSON.parse(decoded);
|
|
6292
|
-
}
|
|
6293
|
-
catch (e) {
|
|
6294
|
-
throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);
|
|
6295
|
-
}
|
|
6296
|
-
}
|
|
6297
|
-
|
|
6298
|
-
const logger = createLogger("PasskeyAuth");
|
|
6299
|
-
const PASSKEY_ERRORS = {
|
|
6300
|
-
NotSupportedError: "passkey_not_supported",
|
|
6301
|
-
NotAllowedError: "passkey_cancelled",
|
|
6302
|
-
SecurityError: "passkey_security_error",
|
|
6303
|
-
InvalidStateError: "passkey_invalid_state",
|
|
6304
|
-
};
|
|
6305
|
-
function decodeBase64Url(base64url) {
|
|
6306
|
-
const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/");
|
|
6307
|
-
const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
|
|
6308
|
-
return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
|
|
6309
|
-
}
|
|
6310
|
-
function buildPublicKeyOptions(options) {
|
|
6311
|
-
return {
|
|
6312
|
-
challenge: Uint8Array.from(atob(options.challenge), (c) => c.charCodeAt(0)),
|
|
6313
|
-
timeout: options.timeout || 60000,
|
|
6314
|
-
rpId: options.rpId,
|
|
6315
|
-
userVerification: options.userVerification || "required",
|
|
6316
|
-
allowCredentials: options.allowCredentials?.map((cred) => ({
|
|
6317
|
-
...cred,
|
|
6318
|
-
id: decodeBase64Url(cred.id),
|
|
6319
|
-
})),
|
|
6320
|
-
};
|
|
6321
|
-
}
|
|
6322
|
-
function formatCredentialForServer(credential) {
|
|
6323
|
-
const response = credential.response;
|
|
6324
|
-
return {
|
|
6325
|
-
id: credential.id,
|
|
6326
|
-
rawId: btoa(String.fromCharCode(...new Uint8Array(credential.rawId))),
|
|
6327
|
-
response: {
|
|
6328
|
-
authenticatorData: btoa(String.fromCharCode(...new Uint8Array(response.authenticatorData))),
|
|
6329
|
-
clientDataJSON: btoa(String.fromCharCode(...new Uint8Array(response.clientDataJSON))),
|
|
6330
|
-
signature: btoa(String.fromCharCode(...new Uint8Array(response.signature))),
|
|
6331
|
-
},
|
|
6332
|
-
type: credential.type,
|
|
6333
|
-
};
|
|
6334
|
-
}
|
|
6335
|
-
function extractAndSetSignInId(tokenResponse) {
|
|
6336
|
-
if (tokenResponse.sid) {
|
|
6337
|
-
authStore.setSignInId(tokenResponse.sid);
|
|
6338
|
-
return;
|
|
6339
|
-
}
|
|
6340
|
-
// Fallback: extract sid from JWT token payload
|
|
6341
|
-
try {
|
|
6342
|
-
const decoded = jwtDecode(tokenResponse.jwt);
|
|
6343
|
-
if (decoded.sid) {
|
|
6344
|
-
authStore.setSignInId(decoded.sid);
|
|
6345
|
-
}
|
|
6346
|
-
}
|
|
6347
|
-
catch {
|
|
6348
|
-
// Failed to decode JWT token to extract sid, continue without it
|
|
6349
|
-
}
|
|
6350
|
-
}
|
|
6351
|
-
function handlePasskeyError(error) {
|
|
6352
|
-
logger.error("Passkey error:", error);
|
|
6353
|
-
let errorMessage = "passkey_error";
|
|
6354
|
-
if (error instanceof DOMException) {
|
|
6355
|
-
errorMessage = PASSKEY_ERRORS[error.name] || "passkey_error";
|
|
6356
|
-
}
|
|
6357
|
-
authStore.setFieldError("passkey", errorMessage);
|
|
6358
|
-
authStore.setLoading(false);
|
|
6359
|
-
}
|
|
6360
|
-
async function authenticateWithPasskey(client, onSuccess) {
|
|
6361
|
-
authStore.setLoading(true);
|
|
6362
|
-
authStore.clearErrors();
|
|
6363
|
-
if (!window.PublicKeyCredential) {
|
|
6364
|
-
authStore.setFieldError("passkey", "passkey_not_supported");
|
|
6365
|
-
authStore.setLoading(false);
|
|
6366
|
-
return;
|
|
5691
|
+
async function authenticateWithPasskey(client, onSuccess) {
|
|
5692
|
+
authStore.setLoading(true);
|
|
5693
|
+
authStore.clearErrors();
|
|
5694
|
+
if (!window.PublicKeyCredential) {
|
|
5695
|
+
authStore.setFieldError("passkey", "passkey_not_supported");
|
|
5696
|
+
authStore.setLoading(false);
|
|
5697
|
+
return;
|
|
6367
5698
|
}
|
|
6368
5699
|
try {
|
|
6369
5700
|
const [optionsError, options] = await client.auth.getPasskeyOptions(state.sid ? { signInId: state.sid } : undefined);
|
|
@@ -6507,13 +5838,6 @@ class AuthHelpers {
|
|
|
6507
5838
|
return [error, _];
|
|
6508
5839
|
}
|
|
6509
5840
|
async refreshToken() {
|
|
6510
|
-
if (state.step === "missing-fields") {
|
|
6511
|
-
return;
|
|
6512
|
-
}
|
|
6513
|
-
const sid = clearUrlParam("sid");
|
|
6514
|
-
if (sid) {
|
|
6515
|
-
authStore.setSignInId(sid);
|
|
6516
|
-
}
|
|
6517
5841
|
if (!state.sid) {
|
|
6518
5842
|
this.logger.warn("No sign-in ID in the session");
|
|
6519
5843
|
return;
|
|
@@ -6527,6 +5851,12 @@ class AuthHelpers {
|
|
|
6527
5851
|
authStore.setToken(response.jwt);
|
|
6528
5852
|
}
|
|
6529
5853
|
}
|
|
5854
|
+
extractSidFromUrl() {
|
|
5855
|
+
const sid = clearUrlParam("sid");
|
|
5856
|
+
if (sid) {
|
|
5857
|
+
authStore.setSignInId(sid);
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
6530
5860
|
async checkSignedIn() {
|
|
6531
5861
|
if (state.authenticated)
|
|
6532
5862
|
return;
|
|
@@ -6569,307 +5899,1052 @@ class AuthHelpers {
|
|
|
6569
5899
|
}
|
|
6570
5900
|
return [error, response];
|
|
6571
5901
|
}
|
|
6572
|
-
async sendResetPasswordEmail() {
|
|
6573
|
-
if (!state.sid) {
|
|
6574
|
-
throw new Error(t("errors.no_sign_in_id"));
|
|
6575
|
-
}
|
|
6576
|
-
authStore.setLoading(true);
|
|
6577
|
-
authStore.setResetPasswordStep("requested");
|
|
6578
|
-
const [error, _] = await this.client.auth.sendResetPasswordEmail({
|
|
6579
|
-
signInId: state.sid,
|
|
6580
|
-
payload: { returnTo: window.location.href },
|
|
6581
|
-
});
|
|
6582
|
-
if (error) {
|
|
6583
|
-
authStore.setFieldError("resetPassword", error);
|
|
6584
|
-
}
|
|
6585
|
-
else {
|
|
6586
|
-
authStore.setResetPasswordStep("sent");
|
|
6587
|
-
authStore.clearErrors();
|
|
5902
|
+
async sendResetPasswordEmail() {
|
|
5903
|
+
if (!state.sid) {
|
|
5904
|
+
throw new Error(t("errors.no_sign_in_id"));
|
|
5905
|
+
}
|
|
5906
|
+
authStore.setLoading(true);
|
|
5907
|
+
authStore.setResetPasswordStep("requested");
|
|
5908
|
+
const [error, _] = await this.client.auth.sendResetPasswordEmail({
|
|
5909
|
+
signInId: state.sid,
|
|
5910
|
+
payload: { returnTo: window.location.href },
|
|
5911
|
+
});
|
|
5912
|
+
if (error) {
|
|
5913
|
+
authStore.setFieldError("resetPassword", error);
|
|
5914
|
+
}
|
|
5915
|
+
else {
|
|
5916
|
+
authStore.setResetPasswordStep("sent");
|
|
5917
|
+
authStore.clearErrors();
|
|
5918
|
+
}
|
|
5919
|
+
authStore.setLoading(false);
|
|
5920
|
+
}
|
|
5921
|
+
async resetPassword() {
|
|
5922
|
+
if (!state.resetPassword.token) {
|
|
5923
|
+
throw new Error("No reset token available");
|
|
5924
|
+
}
|
|
5925
|
+
if (!state.resetPassword.newPassword) {
|
|
5926
|
+
authStore.setFieldError("resetPassword", "password_required");
|
|
5927
|
+
return;
|
|
5928
|
+
}
|
|
5929
|
+
if (state.resetPassword.passwordConfirmation &&
|
|
5930
|
+
state.resetPassword.newPassword !== state.resetPassword.passwordConfirmation) {
|
|
5931
|
+
authStore.setFieldError("resetPassword", "passwords_do_not_match");
|
|
5932
|
+
return;
|
|
5933
|
+
}
|
|
5934
|
+
authStore.setLoading(true);
|
|
5935
|
+
authStore.clearErrors();
|
|
5936
|
+
const [error, response] = await this.client.auth.resetPassword({
|
|
5937
|
+
signInId: state.sid,
|
|
5938
|
+
token: state.resetPassword.token,
|
|
5939
|
+
payload: {
|
|
5940
|
+
password: state.resetPassword.newPassword,
|
|
5941
|
+
passwordConfirmation: state.resetPassword.passwordConfirmation,
|
|
5942
|
+
},
|
|
5943
|
+
});
|
|
5944
|
+
if (error) {
|
|
5945
|
+
authStore.setFieldError("resetPassword", error);
|
|
5946
|
+
// TODO: add proper password requirements handling --> for now this is fine
|
|
5947
|
+
if (error === "invalid_password") {
|
|
5948
|
+
authStore.setFieldError("password", response.error_details?.password.map((p) => t(`errors.password_requirements.${p}`)).join("\n"));
|
|
5949
|
+
}
|
|
5950
|
+
}
|
|
5951
|
+
else {
|
|
5952
|
+
authStore.setStep("email");
|
|
5953
|
+
authStore.updateResetPassword({
|
|
5954
|
+
step: "completed",
|
|
5955
|
+
token: null,
|
|
5956
|
+
newPassword: "",
|
|
5957
|
+
passwordConfirmation: "",
|
|
5958
|
+
});
|
|
5959
|
+
clearUrlParam("reset_password_token");
|
|
5960
|
+
Flash.success.addMessage("Password reset successfully");
|
|
5961
|
+
}
|
|
5962
|
+
authStore.setLoading(false);
|
|
5963
|
+
}
|
|
5964
|
+
async handleResetPasswordRedirect() {
|
|
5965
|
+
const url = new URL(window.location.href);
|
|
5966
|
+
const params = url.searchParams;
|
|
5967
|
+
const resetToken = params.get("reset_password_token");
|
|
5968
|
+
if (!resetToken) {
|
|
5969
|
+
return;
|
|
5970
|
+
}
|
|
5971
|
+
if (state.sid) {
|
|
5972
|
+
authStore.setLoading(true);
|
|
5973
|
+
const [error] = await this.client.auth.validateResetPasswordToken({
|
|
5974
|
+
signInId: state.sid,
|
|
5975
|
+
token: resetToken,
|
|
5976
|
+
});
|
|
5977
|
+
if (error) {
|
|
5978
|
+
authStore.setFieldError("resetPassword", error);
|
|
5979
|
+
authStore.setStep("reset-password");
|
|
5980
|
+
authStore.setLoading(false);
|
|
5981
|
+
return;
|
|
5982
|
+
}
|
|
5983
|
+
}
|
|
5984
|
+
authStore.setResetToken(resetToken);
|
|
5985
|
+
authStore.setStep("reset-password");
|
|
5986
|
+
authStore.setLoading(false);
|
|
5987
|
+
}
|
|
5988
|
+
handleSocialAuthRedirect() {
|
|
5989
|
+
const url = new URL(window.location.href);
|
|
5990
|
+
const params = url.searchParams;
|
|
5991
|
+
const error = params.get("error");
|
|
5992
|
+
// Not a social auth redirect (normal page load)
|
|
5993
|
+
if (!error && !params.has("sid")) {
|
|
5994
|
+
return;
|
|
5995
|
+
}
|
|
5996
|
+
// Handle successful social auth redirect
|
|
5997
|
+
if (!error && params.has("sid") && params.has("id_token")) {
|
|
5998
|
+
authStore.setSignInId(clearUrlParam("sid"));
|
|
5999
|
+
const idToken = clearUrlParam("id_token");
|
|
6000
|
+
if (idToken) {
|
|
6001
|
+
authStore.setToken(idToken);
|
|
6002
|
+
this.handleAuthSuccess({ jwt: idToken });
|
|
6003
|
+
}
|
|
6004
|
+
else {
|
|
6005
|
+
this.logger.error("No ID token found in the URL on social auth redirect");
|
|
6006
|
+
}
|
|
6007
|
+
return;
|
|
6008
|
+
}
|
|
6009
|
+
// Handle missing required fields
|
|
6010
|
+
if (error !== "missing_required_fields") {
|
|
6011
|
+
this.logger.error("Social auth redirect error:", error);
|
|
6012
|
+
return;
|
|
6013
|
+
}
|
|
6014
|
+
const fieldsFromUrl = clearUrlParam("fields");
|
|
6015
|
+
const sid = clearUrlParam("sid");
|
|
6016
|
+
clearUrlParam("error");
|
|
6017
|
+
if (!fieldsFromUrl || !sid) {
|
|
6018
|
+
return;
|
|
6019
|
+
}
|
|
6020
|
+
try {
|
|
6021
|
+
const fields = JSON.parse(fieldsFromUrl);
|
|
6022
|
+
authStore.setSignInId(sid);
|
|
6023
|
+
this.handleMissingFields(fields);
|
|
6024
|
+
}
|
|
6025
|
+
catch (e) {
|
|
6026
|
+
this.logger.error("Failed to parse missing fields payload:", e);
|
|
6027
|
+
authStore.setGlobalError("auth", "invalid_required_fields_payload");
|
|
6028
|
+
}
|
|
6029
|
+
}
|
|
6030
|
+
handleAuthError(error, response, fallbackField) {
|
|
6031
|
+
switch (error) {
|
|
6032
|
+
case "account_not_found":
|
|
6033
|
+
authStore.setFieldError("email", error);
|
|
6034
|
+
break;
|
|
6035
|
+
case "missing_required_fields": {
|
|
6036
|
+
const { fields, sid } = response;
|
|
6037
|
+
this.handleMissingFields(fields);
|
|
6038
|
+
if (sid) {
|
|
6039
|
+
authStore.setSignInId(sid);
|
|
6040
|
+
}
|
|
6041
|
+
break;
|
|
6042
|
+
}
|
|
6043
|
+
default:
|
|
6044
|
+
if (fallbackField === "password") {
|
|
6045
|
+
authStore.setFieldError("password", error);
|
|
6046
|
+
}
|
|
6047
|
+
else if (fallbackField === "magicCode") {
|
|
6048
|
+
authStore.setFieldError("magicCode", error);
|
|
6049
|
+
}
|
|
6050
|
+
else if (fallbackField === "email") {
|
|
6051
|
+
authStore.setFieldError("email", error);
|
|
6052
|
+
}
|
|
6053
|
+
else {
|
|
6054
|
+
// e.g. "account_locked", "internal_server_error"
|
|
6055
|
+
authStore.setGlobalError("auth", error);
|
|
6056
|
+
}
|
|
6057
|
+
break;
|
|
6058
|
+
}
|
|
6059
|
+
authStore.setLoading(false);
|
|
6060
|
+
}
|
|
6061
|
+
handleMissingFields(fields) {
|
|
6062
|
+
authStore.setMissingFields(fields);
|
|
6063
|
+
state$1.data = fields;
|
|
6064
|
+
authStore.setStep("missing-fields");
|
|
6065
|
+
authStore.setLoading(false);
|
|
6066
|
+
}
|
|
6067
|
+
handleAuthSuccess(response) {
|
|
6068
|
+
authStore.setToken(response.jwt);
|
|
6069
|
+
authStore.setLoading(false);
|
|
6070
|
+
authStore.getRootComponentRef()?.onAuth(response);
|
|
6071
|
+
}
|
|
6072
|
+
}
|
|
6073
|
+
|
|
6074
|
+
const DEFAULT_TOKEN_EXPIRATION_BUFFER_SECONDS = 10;
|
|
6075
|
+
class Auth {
|
|
6076
|
+
static instance;
|
|
6077
|
+
helpers;
|
|
6078
|
+
constructor(client) {
|
|
6079
|
+
this.helpers = new AuthHelpers(client);
|
|
6080
|
+
}
|
|
6081
|
+
static Errors = {
|
|
6082
|
+
email: {
|
|
6083
|
+
NOT_FOUND: "account_not_found",
|
|
6084
|
+
},
|
|
6085
|
+
magicCode: {
|
|
6086
|
+
RECENTLY_CREATED: "magic_code_recently_created",
|
|
6087
|
+
NOT_VALID: "magic_code_not_valid",
|
|
6088
|
+
EXPIRED: "magic_code_expired",
|
|
6089
|
+
USED: "magic_code_used",
|
|
6090
|
+
},
|
|
6091
|
+
password: {
|
|
6092
|
+
INVALID: "invalid_password",
|
|
6093
|
+
NOT_SET: "password_not_set",
|
|
6094
|
+
RESET_PASSWORD_ALREADY_SENT: "reset_password_already_sent",
|
|
6095
|
+
},
|
|
6096
|
+
general: {
|
|
6097
|
+
ACCOUNT_LOCKED: "account_locked",
|
|
6098
|
+
SIGN_IN_EXPIRED: "sign_in_expired",
|
|
6099
|
+
},
|
|
6100
|
+
};
|
|
6101
|
+
static async getInstance() {
|
|
6102
|
+
if (!Auth.isInitialized()) {
|
|
6103
|
+
await waitForConfig();
|
|
6104
|
+
return Auth.initialize(getUnidyClient());
|
|
6105
|
+
}
|
|
6106
|
+
return Auth.instance;
|
|
6107
|
+
}
|
|
6108
|
+
static async initialize(client) {
|
|
6109
|
+
if (Auth.instance) {
|
|
6110
|
+
return Auth.instance;
|
|
6111
|
+
}
|
|
6112
|
+
Auth.instance = new Auth(client);
|
|
6113
|
+
Auth.instance.helpers.handleSocialAuthRedirect();
|
|
6114
|
+
Auth.instance.helpers.extractSidFromUrl();
|
|
6115
|
+
await Auth.instance.helpers.handleResetPasswordRedirect();
|
|
6116
|
+
if (Auth.instance.isTokenValid(state.token)) {
|
|
6117
|
+
authStore.setAuthenticated(true);
|
|
6118
|
+
}
|
|
6119
|
+
return Auth.instance;
|
|
6120
|
+
}
|
|
6121
|
+
static isInitialized() {
|
|
6122
|
+
return !!Auth.instance;
|
|
6123
|
+
}
|
|
6124
|
+
/**
|
|
6125
|
+
* Checks whether a JWT token is valid and not expired.
|
|
6126
|
+
*
|
|
6127
|
+
* @param token - The JWT token to validate. Can be a raw JWT string, a decoded TokenPayload, or null.
|
|
6128
|
+
* @param expirationBuffer - Number of seconds before actual expiration to consider the token invalid, used to prevent race conditions with preemptive token refresh. Defaults to 10 seconds.
|
|
6129
|
+
* @returns `true` if the token is valid and won't expire within the buffer period, `false` otherwise.
|
|
6130
|
+
* @throws Error if expirationBuffer is not positive number
|
|
6131
|
+
*/
|
|
6132
|
+
isTokenValid(token, expirationBuffer = DEFAULT_TOKEN_EXPIRATION_BUFFER_SECONDS) {
|
|
6133
|
+
if (!Number.isFinite(expirationBuffer) || expirationBuffer <= 0) {
|
|
6134
|
+
throw new Error("expirationBuffer must be a positive finite number");
|
|
6135
|
+
}
|
|
6136
|
+
try {
|
|
6137
|
+
let decoded;
|
|
6138
|
+
if (typeof token === "string") {
|
|
6139
|
+
decoded = jwtDecode(token);
|
|
6140
|
+
}
|
|
6141
|
+
else {
|
|
6142
|
+
decoded = token;
|
|
6143
|
+
}
|
|
6144
|
+
if (!decoded)
|
|
6145
|
+
return false;
|
|
6146
|
+
if (typeof decoded.exp !== "number" || !Number.isFinite(decoded.exp)) {
|
|
6147
|
+
return false;
|
|
6148
|
+
}
|
|
6149
|
+
const currentTime = Date.now() / 1000;
|
|
6150
|
+
return decoded.exp > currentTime + expirationBuffer;
|
|
6151
|
+
}
|
|
6152
|
+
catch (error) {
|
|
6153
|
+
captureException(error);
|
|
6154
|
+
return false;
|
|
6155
|
+
}
|
|
6156
|
+
}
|
|
6157
|
+
async isAuthenticated() {
|
|
6158
|
+
const token = await this.getToken();
|
|
6159
|
+
return typeof token === "string";
|
|
6160
|
+
}
|
|
6161
|
+
async getToken() {
|
|
6162
|
+
const currentToken = state.token;
|
|
6163
|
+
if (currentToken && this.isTokenValid(currentToken)) {
|
|
6164
|
+
return currentToken;
|
|
6165
|
+
}
|
|
6166
|
+
await this.helpers.refreshToken();
|
|
6167
|
+
if (state.globalErrors.auth || !state.token) {
|
|
6168
|
+
return this.createAuthError(t("errors.refresh_failed"), "REFRESH_FAILED", true);
|
|
6169
|
+
}
|
|
6170
|
+
return state.token;
|
|
6171
|
+
}
|
|
6172
|
+
async userData() {
|
|
6173
|
+
const token = await this.getToken();
|
|
6174
|
+
if (typeof token !== "string") {
|
|
6175
|
+
return null;
|
|
6176
|
+
}
|
|
6177
|
+
if (!token) {
|
|
6178
|
+
return null;
|
|
6179
|
+
}
|
|
6180
|
+
try {
|
|
6181
|
+
return jwtDecode(token);
|
|
6182
|
+
}
|
|
6183
|
+
catch (error) {
|
|
6184
|
+
captureException(error);
|
|
6185
|
+
return null;
|
|
6186
|
+
}
|
|
6187
|
+
}
|
|
6188
|
+
async logout() {
|
|
6189
|
+
const [error, _] = await this.helpers.logout();
|
|
6190
|
+
if (error) {
|
|
6191
|
+
return this.createAuthError(t("errors.sign_out_failed", { reason: error }), "SIGN_OUT_FAILED", false);
|
|
6192
|
+
}
|
|
6193
|
+
authStore.reset();
|
|
6194
|
+
return true;
|
|
6195
|
+
}
|
|
6196
|
+
getEmail() {
|
|
6197
|
+
return state.email;
|
|
6198
|
+
}
|
|
6199
|
+
createAuthError(message, code, requiresReauth = false) {
|
|
6200
|
+
const error = new Error(message);
|
|
6201
|
+
error.code = code;
|
|
6202
|
+
error.requiresReauth = requiresReauth;
|
|
6203
|
+
return error;
|
|
6204
|
+
}
|
|
6205
|
+
}
|
|
6206
|
+
|
|
6207
|
+
// Salutation enum
|
|
6208
|
+
const SalutationEnum = _enum(["mr", "mrs", "mx"]);
|
|
6209
|
+
// Newsletter subscription from API
|
|
6210
|
+
const NewsletterSubscriptionSchema = object({
|
|
6211
|
+
id: number(),
|
|
6212
|
+
email: string(),
|
|
6213
|
+
newsletter_internal_name: string(),
|
|
6214
|
+
preference_identifiers: array(string()),
|
|
6215
|
+
preference_token: string(),
|
|
6216
|
+
confirmed_at: string().nullable(),
|
|
6217
|
+
});
|
|
6218
|
+
// Newsletter subscription error extends base error with typed meta
|
|
6219
|
+
const NewsletterSubscriptionErrorSchema = BaseErrorSchema.extend({
|
|
6220
|
+
error_details: record(string(), array(string())).optional(),
|
|
6221
|
+
meta: object({
|
|
6222
|
+
newsletter_internal_name: string(),
|
|
6223
|
+
}),
|
|
6224
|
+
});
|
|
6225
|
+
// Create subscriptions response
|
|
6226
|
+
const CreateSubscriptionsResponseSchema = object({
|
|
6227
|
+
results: array(NewsletterSubscriptionSchema),
|
|
6228
|
+
errors: array(NewsletterSubscriptionErrorSchema),
|
|
6229
|
+
});
|
|
6230
|
+
// Additional fields for subscription creation - using .partial() for all optional fields
|
|
6231
|
+
const AdditionalFieldsSchema = object({
|
|
6232
|
+
first_name: string().nullable(),
|
|
6233
|
+
last_name: string().nullable(),
|
|
6234
|
+
salutation: SalutationEnum.nullable(),
|
|
6235
|
+
phone_number: string().nullable(),
|
|
6236
|
+
date_of_birth: string().nullable(),
|
|
6237
|
+
company_name: string().nullable(),
|
|
6238
|
+
address_line_1: string().nullable(),
|
|
6239
|
+
address_line_2: string().nullable(),
|
|
6240
|
+
city: string().nullable(),
|
|
6241
|
+
postal_code: string().nullable(),
|
|
6242
|
+
country_code: string().nullable(),
|
|
6243
|
+
preferred_language: string().nullable(),
|
|
6244
|
+
custom_attributes: record(string(), unknown()).nullable(),
|
|
6245
|
+
})
|
|
6246
|
+
.partial();
|
|
6247
|
+
// Create subscriptions payload
|
|
6248
|
+
const CreateSubscriptionsPayloadSchema = object({
|
|
6249
|
+
email: string(),
|
|
6250
|
+
additional_fields: optional(AdditionalFieldsSchema),
|
|
6251
|
+
newsletter_subscriptions: array(object({
|
|
6252
|
+
newsletter_internal_name: string(),
|
|
6253
|
+
preference_identifiers: optional(array(string())),
|
|
6254
|
+
})),
|
|
6255
|
+
redirect_to_after_confirmation: optional(string()),
|
|
6256
|
+
});
|
|
6257
|
+
// Update subscription payload
|
|
6258
|
+
const UpdateSubscriptionPayloadSchema = object({
|
|
6259
|
+
preference_identifiers: array(string()),
|
|
6260
|
+
});
|
|
6261
|
+
// Login email payload
|
|
6262
|
+
const LoginEmailPayloadSchema = object({
|
|
6263
|
+
email: string(),
|
|
6264
|
+
redirect_uri: string(),
|
|
6265
|
+
});
|
|
6266
|
+
// Resend DOI payload
|
|
6267
|
+
const ResendDoiPayloadSchema = object({
|
|
6268
|
+
redirect_to_after_confirmation: string(),
|
|
6269
|
+
})
|
|
6270
|
+
.partial();
|
|
6271
|
+
// Preference schema
|
|
6272
|
+
const PreferenceSchema = object({
|
|
6273
|
+
id: number(),
|
|
6274
|
+
name: string(),
|
|
6275
|
+
description: string().nullable(),
|
|
6276
|
+
plugin_identifier: string().nullable(),
|
|
6277
|
+
position: number(),
|
|
6278
|
+
default: boolean(),
|
|
6279
|
+
hidden: boolean(),
|
|
6280
|
+
});
|
|
6281
|
+
// Preference group schema
|
|
6282
|
+
const PreferenceGroupSchema = object({
|
|
6283
|
+
id: number(),
|
|
6284
|
+
name: string(),
|
|
6285
|
+
position: number(),
|
|
6286
|
+
flat: boolean(),
|
|
6287
|
+
preferences: array(PreferenceSchema),
|
|
6288
|
+
});
|
|
6289
|
+
// Newsletter schema
|
|
6290
|
+
const NewsletterSchema = object({
|
|
6291
|
+
id: number(),
|
|
6292
|
+
internal_name: string(),
|
|
6293
|
+
default: boolean(),
|
|
6294
|
+
position: number(),
|
|
6295
|
+
opt_in_type: string(),
|
|
6296
|
+
title: string(),
|
|
6297
|
+
description: string().nullable(),
|
|
6298
|
+
created_at: string(),
|
|
6299
|
+
updated_at: string(),
|
|
6300
|
+
preference_groups: array(PreferenceGroupSchema),
|
|
6301
|
+
});
|
|
6302
|
+
// Newsletters list response
|
|
6303
|
+
const NewslettersResponseSchema = object({
|
|
6304
|
+
newsletters: array(NewsletterSchema),
|
|
6305
|
+
});
|
|
6306
|
+
// Delete subscription response
|
|
6307
|
+
const DeleteSubscriptionResponseSchema = object({
|
|
6308
|
+
new_preference_token: string(),
|
|
6309
|
+
})
|
|
6310
|
+
.nullable();
|
|
6311
|
+
// Generic newsletter error response (extends base error)
|
|
6312
|
+
const NewsletterErrorResponseSchema = BaseErrorSchema;
|
|
6313
|
+
|
|
6314
|
+
class NewsletterService extends BaseService {
|
|
6315
|
+
constructor(client, deps) {
|
|
6316
|
+
super(client, "NewsletterService", deps);
|
|
6317
|
+
}
|
|
6318
|
+
async buildNewsletterAuthHeaders(options) {
|
|
6319
|
+
const idToken = await this.getIdToken();
|
|
6320
|
+
return this.buildAuthHeaders({
|
|
6321
|
+
"X-ID-Token": idToken ?? undefined,
|
|
6322
|
+
"X-Preference-Token": options?.preferenceToken,
|
|
6323
|
+
});
|
|
6324
|
+
}
|
|
6325
|
+
/**
|
|
6326
|
+
* Create newsletter subscriptions for a user
|
|
6327
|
+
*/
|
|
6328
|
+
async create(args) {
|
|
6329
|
+
const { payload, options } = args;
|
|
6330
|
+
const validatedPayload = CreateSubscriptionsPayloadSchema.safeParse(payload);
|
|
6331
|
+
if (!validatedPayload.success) {
|
|
6332
|
+
this.logger.error("Invalid payload for create", validatedPayload.error);
|
|
6333
|
+
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
6334
|
+
}
|
|
6335
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6336
|
+
const response = await this.client.post("/api/sdk/v1/newsletters/newsletter_subscription", payload, headers);
|
|
6337
|
+
return this.handleResponse(response, () => {
|
|
6338
|
+
// Both success and 422 return CreateSubscriptionsResponse
|
|
6339
|
+
if (response.success || response.status === 422) {
|
|
6340
|
+
const data = CreateSubscriptionsResponseSchema.parse(response.data);
|
|
6341
|
+
if (data.errors.length > 0) {
|
|
6342
|
+
return ["newsletter_error", data];
|
|
6343
|
+
}
|
|
6344
|
+
return [null, data];
|
|
6345
|
+
}
|
|
6346
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6347
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6348
|
+
switch (response.status) {
|
|
6349
|
+
case 401:
|
|
6350
|
+
return ["unauthorized", error];
|
|
6351
|
+
case 429:
|
|
6352
|
+
this.logger.warn("Rate limit exceeded");
|
|
6353
|
+
return ["rate_limit_exceeded", error];
|
|
6354
|
+
case 500:
|
|
6355
|
+
this.errorReporter.captureException(response);
|
|
6356
|
+
return ["server_error", error];
|
|
6357
|
+
default:
|
|
6358
|
+
return ["server_error", error];
|
|
6359
|
+
}
|
|
6360
|
+
});
|
|
6361
|
+
}
|
|
6362
|
+
/**
|
|
6363
|
+
* List all subscriptions for the authenticated user
|
|
6364
|
+
*/
|
|
6365
|
+
async list(args) {
|
|
6366
|
+
const headers = await this.buildNewsletterAuthHeaders(args?.options);
|
|
6367
|
+
const response = await this.client.get("/api/sdk/v1/newsletters/newsletter_subscription", headers);
|
|
6368
|
+
return this.handleResponse(response, () => {
|
|
6369
|
+
if (!response.success) {
|
|
6370
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6371
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6372
|
+
if (response.status === 401) {
|
|
6373
|
+
return ["unauthorized", error];
|
|
6374
|
+
}
|
|
6375
|
+
return ["server_error", error];
|
|
6376
|
+
}
|
|
6377
|
+
const data = array(NewsletterSubscriptionSchema).parse(response.data);
|
|
6378
|
+
return [null, data];
|
|
6379
|
+
});
|
|
6380
|
+
}
|
|
6381
|
+
/**
|
|
6382
|
+
* Get a specific subscription by newsletter internal name
|
|
6383
|
+
*/
|
|
6384
|
+
async get(args) {
|
|
6385
|
+
const { internalName, options } = args;
|
|
6386
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6387
|
+
const response = await this.client.get(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, headers);
|
|
6388
|
+
return this.handleResponse(response, () => {
|
|
6389
|
+
if (!response.success) {
|
|
6390
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6391
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6392
|
+
if (response.status === 401) {
|
|
6393
|
+
return ["unauthorized", error];
|
|
6394
|
+
}
|
|
6395
|
+
if (response.status === 404) {
|
|
6396
|
+
return ["not_found", error];
|
|
6397
|
+
}
|
|
6398
|
+
return ["server_error", error];
|
|
6399
|
+
}
|
|
6400
|
+
const data = NewsletterSubscriptionSchema.parse(response.data);
|
|
6401
|
+
return [null, data];
|
|
6402
|
+
});
|
|
6403
|
+
}
|
|
6404
|
+
/**
|
|
6405
|
+
* Update a subscription's preferences
|
|
6406
|
+
*/
|
|
6407
|
+
async update(args) {
|
|
6408
|
+
const { internalName, payload, options } = args;
|
|
6409
|
+
const validatedPayload = UpdateSubscriptionPayloadSchema.safeParse(payload);
|
|
6410
|
+
if (!validatedPayload.success) {
|
|
6411
|
+
this.logger.error("Invalid payload for update", validatedPayload.error);
|
|
6412
|
+
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
6413
|
+
}
|
|
6414
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6415
|
+
const response = await this.client.patch(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, payload, headers);
|
|
6416
|
+
return this.handleResponse(response, () => {
|
|
6417
|
+
if (!response.success) {
|
|
6418
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6419
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6420
|
+
if (response.status === 401) {
|
|
6421
|
+
return ["unauthorized", error];
|
|
6422
|
+
}
|
|
6423
|
+
if (response.status === 404) {
|
|
6424
|
+
return ["not_found", error];
|
|
6425
|
+
}
|
|
6426
|
+
return ["server_error", error];
|
|
6427
|
+
}
|
|
6428
|
+
const data = NewsletterSubscriptionSchema.parse(response.data);
|
|
6429
|
+
return [null, data];
|
|
6430
|
+
});
|
|
6431
|
+
}
|
|
6432
|
+
/**
|
|
6433
|
+
* Delete a subscription
|
|
6434
|
+
*/
|
|
6435
|
+
async delete(args) {
|
|
6436
|
+
const { internalName, options } = args;
|
|
6437
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6438
|
+
const response = await this.client.delete(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription`, headers);
|
|
6439
|
+
return this.handleResponse(response, () => {
|
|
6440
|
+
if (!response.success) {
|
|
6441
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6442
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6443
|
+
if (response.status === 401) {
|
|
6444
|
+
return ["unauthorized", error];
|
|
6445
|
+
}
|
|
6446
|
+
if (response.status === 404) {
|
|
6447
|
+
return ["not_found", error];
|
|
6448
|
+
}
|
|
6449
|
+
if (response.status === 422) {
|
|
6450
|
+
return ["unprocessable_entity", error];
|
|
6451
|
+
}
|
|
6452
|
+
return ["server_error", error];
|
|
6453
|
+
}
|
|
6454
|
+
if (response.status === 204) {
|
|
6455
|
+
return [null, null];
|
|
6456
|
+
}
|
|
6457
|
+
const data = DeleteSubscriptionResponseSchema.parse(response.data);
|
|
6458
|
+
return [null, data];
|
|
6459
|
+
});
|
|
6460
|
+
}
|
|
6461
|
+
/**
|
|
6462
|
+
* Resend double opt-in confirmation email
|
|
6463
|
+
*/
|
|
6464
|
+
async resendDoi(args) {
|
|
6465
|
+
const { internalName, payload, options } = args;
|
|
6466
|
+
const validatedPayload = ResendDoiPayloadSchema.safeParse(payload);
|
|
6467
|
+
if (!validatedPayload.success) {
|
|
6468
|
+
this.logger.error("Invalid payload for resendDoi", validatedPayload.error);
|
|
6469
|
+
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
6470
|
+
}
|
|
6471
|
+
const headers = await this.buildNewsletterAuthHeaders(options);
|
|
6472
|
+
const response = await this.client.post(`/api/sdk/v1/newsletters/${internalName}/newsletter_subscription/resend_doi`, payload, headers);
|
|
6473
|
+
return this.handleResponse(response, () => {
|
|
6474
|
+
if (!response.success) {
|
|
6475
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6476
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6477
|
+
if (response.status === 401) {
|
|
6478
|
+
return ["unauthorized", error];
|
|
6479
|
+
}
|
|
6480
|
+
if (response.status === 404) {
|
|
6481
|
+
return ["not_found", error];
|
|
6482
|
+
}
|
|
6483
|
+
if (error.error_identifier === "already_confirmed") {
|
|
6484
|
+
return ["already_confirmed", error];
|
|
6485
|
+
}
|
|
6486
|
+
return ["server_error", error];
|
|
6487
|
+
}
|
|
6488
|
+
return [null, null];
|
|
6489
|
+
});
|
|
6490
|
+
}
|
|
6491
|
+
/**
|
|
6492
|
+
* Send a login email for newsletter management
|
|
6493
|
+
*/
|
|
6494
|
+
async sendLoginEmail(args) {
|
|
6495
|
+
const { payload } = args;
|
|
6496
|
+
const validatedPayload = LoginEmailPayloadSchema.safeParse(payload);
|
|
6497
|
+
if (!validatedPayload.success) {
|
|
6498
|
+
this.logger.error("Invalid payload for sendLoginEmail", validatedPayload.error);
|
|
6499
|
+
return ["schema_validation_error", { error_identifier: "schema_validation_error", errors: [String(validatedPayload.error)] }];
|
|
6500
|
+
}
|
|
6501
|
+
const response = await this.client.post("/api/sdk/v1/newsletters/newsletter_subscription/login_email", payload);
|
|
6502
|
+
return this.handleResponse(response, () => {
|
|
6503
|
+
if (!response.success) {
|
|
6504
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6505
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6506
|
+
if (response.status === 429) {
|
|
6507
|
+
return ["rate_limit_exceeded", error];
|
|
6508
|
+
}
|
|
6509
|
+
if (response.status === 404) {
|
|
6510
|
+
return ["not_found", error];
|
|
6511
|
+
}
|
|
6512
|
+
return ["server_error", error];
|
|
6513
|
+
}
|
|
6514
|
+
return [null, null];
|
|
6515
|
+
});
|
|
6516
|
+
}
|
|
6517
|
+
/**
|
|
6518
|
+
* List all available newsletters
|
|
6519
|
+
*/
|
|
6520
|
+
async listAll() {
|
|
6521
|
+
const response = await this.client.get("/api/sdk/v1/newsletters");
|
|
6522
|
+
return this.handleResponse(response, () => {
|
|
6523
|
+
if (!response.success) {
|
|
6524
|
+
return ["server_error", null];
|
|
6525
|
+
}
|
|
6526
|
+
const data = NewslettersResponseSchema.parse(response.data);
|
|
6527
|
+
return [null, data];
|
|
6528
|
+
});
|
|
6529
|
+
}
|
|
6530
|
+
/**
|
|
6531
|
+
* Get a newsletter by its internal name
|
|
6532
|
+
*/
|
|
6533
|
+
async getByName(args) {
|
|
6534
|
+
const { internalName } = args;
|
|
6535
|
+
const response = await this.client.get(`/api/sdk/v1/newsletters/${internalName}`);
|
|
6536
|
+
return this.handleResponse(response, () => {
|
|
6537
|
+
if (!response.success) {
|
|
6538
|
+
const parsed = NewsletterErrorResponseSchema.safeParse(response.data);
|
|
6539
|
+
const error = parsed.success ? parsed.data : { error_identifier: "unknown_error" };
|
|
6540
|
+
if (response.status === 404) {
|
|
6541
|
+
return ["not_found", error];
|
|
6542
|
+
}
|
|
6543
|
+
return ["server_error", error];
|
|
6544
|
+
}
|
|
6545
|
+
const data = NewsletterSchema.parse(response.data);
|
|
6546
|
+
return [null, data];
|
|
6547
|
+
});
|
|
6548
|
+
}
|
|
6549
|
+
}
|
|
6550
|
+
|
|
6551
|
+
// Export format and link response schemas
|
|
6552
|
+
const ExportFormat = _enum(["pdf", "pkpass"]);
|
|
6553
|
+
const ExportLinkResponseSchema = object({
|
|
6554
|
+
url: string().url(),
|
|
6555
|
+
expires_in: number(),
|
|
6556
|
+
});
|
|
6557
|
+
// Input validation schemas for ticketable list parameters
|
|
6558
|
+
const TicketableListParamsSchema = object({
|
|
6559
|
+
page: number().int().positive().optional(),
|
|
6560
|
+
perPage: number().int().positive().max(250).optional(),
|
|
6561
|
+
state: string().nullish(),
|
|
6562
|
+
paymentState: string().nullish(),
|
|
6563
|
+
orderBy: _enum(["starts_at", "ends_at", "reference", "created_at"]).optional(),
|
|
6564
|
+
orderDirection: _enum(["asc", "desc"]).optional(),
|
|
6565
|
+
serviceId: number().int().positive().optional(),
|
|
6566
|
+
});
|
|
6567
|
+
// Date transformer for ISO8601 strings
|
|
6568
|
+
const dateTransformer = date();
|
|
6569
|
+
const nullableDateTransformer = date().nullable();
|
|
6570
|
+
// Ticket schema based on TicketSerializer
|
|
6571
|
+
const TicketSchema = object({
|
|
6572
|
+
id: uuid(), // unidy_id
|
|
6573
|
+
title: string(),
|
|
6574
|
+
text: string().nullable(),
|
|
6575
|
+
reference: string(),
|
|
6576
|
+
metadata: record(string(), unknown()).nullable(),
|
|
6577
|
+
wallet_export: record(string(), unknown()).nullable(),
|
|
6578
|
+
exportable_to_wallet: boolean(),
|
|
6579
|
+
state: string(),
|
|
6580
|
+
payment_state: string().nullable(),
|
|
6581
|
+
button_cta_url: string().nullable(),
|
|
6582
|
+
info_banner: string().nullable(),
|
|
6583
|
+
seating: string().nullable(),
|
|
6584
|
+
venue: string().nullable(),
|
|
6585
|
+
currency: string().nullable(),
|
|
6586
|
+
starts_at: dateTransformer, // ISO8601(3) -> Date
|
|
6587
|
+
ends_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6588
|
+
created_at: dateTransformer, // ISO8601(3) -> Date
|
|
6589
|
+
updated_at: dateTransformer, // ISO8601(3) -> Date
|
|
6590
|
+
price: number(), // decimal(8, 2) -> float
|
|
6591
|
+
user_id: uuid(),
|
|
6592
|
+
ticket_category_id: uuid(),
|
|
6593
|
+
});
|
|
6594
|
+
// Tickets list response schema
|
|
6595
|
+
const TicketsListResponseSchema = object({
|
|
6596
|
+
meta: PaginationMetaSchema,
|
|
6597
|
+
results: array(TicketSchema),
|
|
6598
|
+
});
|
|
6599
|
+
// Subscription schema based on SubscriptionSerializer
|
|
6600
|
+
const SubscriptionSchema = object({
|
|
6601
|
+
id: uuid(), // unidy_id
|
|
6602
|
+
title: string(),
|
|
6603
|
+
text: string(),
|
|
6604
|
+
payment_frequency: string().nullable(),
|
|
6605
|
+
metadata: record(string(), unknown()).nullable(),
|
|
6606
|
+
wallet_export: record(string(), unknown()).nullable(),
|
|
6607
|
+
exportable_to_wallet: boolean(),
|
|
6608
|
+
state: string(),
|
|
6609
|
+
reference: string(),
|
|
6610
|
+
payment_state: string().nullable(),
|
|
6611
|
+
currency: string().nullable(),
|
|
6612
|
+
button_cta_url: string().nullable(),
|
|
6613
|
+
created_at: dateTransformer, // ISO8601(3) -> Date
|
|
6614
|
+
updated_at: dateTransformer, // ISO8601(3) -> Date
|
|
6615
|
+
starts_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6616
|
+
ends_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6617
|
+
next_payment_at: nullableDateTransformer, // ISO8601(3) -> Date | null
|
|
6618
|
+
price: number(), // decimal(8, 2) -> float
|
|
6619
|
+
user_id: uuid(),
|
|
6620
|
+
subscription_category_id: uuid(),
|
|
6621
|
+
});
|
|
6622
|
+
// Subscriptions list response schema
|
|
6623
|
+
const SubscriptionsListResponseSchema = object({
|
|
6624
|
+
meta: PaginationMetaSchema,
|
|
6625
|
+
results: array(SubscriptionSchema),
|
|
6626
|
+
});
|
|
6627
|
+
|
|
6628
|
+
/**
|
|
6629
|
+
* Base service for ticketable resources (tickets and subscriptions).
|
|
6630
|
+
* Handles common query parameter building and response parsing.
|
|
6631
|
+
*/
|
|
6632
|
+
class TicketableService extends BaseService {
|
|
6633
|
+
/**
|
|
6634
|
+
* Builds query params from args, mapping camelCase to snake_case.
|
|
6635
|
+
* Returns undefined values filtered out.
|
|
6636
|
+
*/
|
|
6637
|
+
buildListParams(args = {}, categoryIdKey, categoryIdValue) {
|
|
6638
|
+
return {
|
|
6639
|
+
page: args.page,
|
|
6640
|
+
limit: args.perPage,
|
|
6641
|
+
state: args.state,
|
|
6642
|
+
payment_state: args.paymentState,
|
|
6643
|
+
order_by: args.orderBy,
|
|
6644
|
+
order_direction: args.orderDirection,
|
|
6645
|
+
service_id: args.serviceId,
|
|
6646
|
+
[categoryIdKey]: categoryIdValue,
|
|
6647
|
+
};
|
|
6648
|
+
}
|
|
6649
|
+
/**
|
|
6650
|
+
* Converts params to query string, filtering undefined/null and converting to strings.
|
|
6651
|
+
*/
|
|
6652
|
+
toQueryString(params) {
|
|
6653
|
+
const filtered = Object.entries(params)
|
|
6654
|
+
.filter(([_, v]) => v !== undefined && v !== null)
|
|
6655
|
+
.map(([k, v]) => [k, String(v)]);
|
|
6656
|
+
if (filtered.length === 0)
|
|
6657
|
+
return "";
|
|
6658
|
+
return `?${new URLSearchParams(Object.fromEntries(filtered)).toString()}`;
|
|
6659
|
+
}
|
|
6660
|
+
/**
|
|
6661
|
+
* Validates list arguments before making API request.
|
|
6662
|
+
* Uses Zod for input validation.
|
|
6663
|
+
*/
|
|
6664
|
+
validateListArgs(args) {
|
|
6665
|
+
const result = TicketableListParamsSchema.safeParse(args);
|
|
6666
|
+
if (!result.success) {
|
|
6667
|
+
this.logger.error("Invalid list parameters", result.error);
|
|
6668
|
+
return false;
|
|
6588
6669
|
}
|
|
6589
|
-
|
|
6670
|
+
return true;
|
|
6590
6671
|
}
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
return;
|
|
6672
|
+
/**
|
|
6673
|
+
* Generic list handler with schema validation.
|
|
6674
|
+
*/
|
|
6675
|
+
async handleList(endpoint, queryString, schema, resourceName, args = {}) {
|
|
6676
|
+
// Validate input parameters
|
|
6677
|
+
if (!this.validateListArgs(args)) {
|
|
6678
|
+
return ["invalid_response", null]; // Invalid input treated same as invalid response
|
|
6598
6679
|
}
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
return;
|
|
6680
|
+
const idToken = await this.getIdToken();
|
|
6681
|
+
if (!idToken) {
|
|
6682
|
+
return ["missing_id_token", null];
|
|
6603
6683
|
}
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
payload: {
|
|
6610
|
-
password: state.resetPassword.newPassword,
|
|
6611
|
-
passwordConfirmation: state.resetPassword.passwordConfirmation,
|
|
6612
|
-
},
|
|
6613
|
-
});
|
|
6614
|
-
if (error) {
|
|
6615
|
-
authStore.setFieldError("resetPassword", error);
|
|
6616
|
-
// TODO: add proper password requirements handling --> for now this is fine
|
|
6617
|
-
if (error === "invalid_password") {
|
|
6618
|
-
authStore.setFieldError("password", response.error_details?.password.map((p) => t(`errors.password_requirements.${p}`)).join("\n"));
|
|
6684
|
+
const response = await this.client.get(`${endpoint}${queryString}`, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6685
|
+
return this.handleResponse(response, () => {
|
|
6686
|
+
if (!response.success) {
|
|
6687
|
+
this.logger.error(`Failed to fetch ${resourceName}`, response);
|
|
6688
|
+
return ["server_error", null];
|
|
6619
6689
|
}
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
token: null,
|
|
6626
|
-
newPassword: "",
|
|
6627
|
-
passwordConfirmation: "",
|
|
6628
|
-
});
|
|
6629
|
-
clearUrlParam("reset_password_token");
|
|
6630
|
-
Flash.success.addMessage("Password reset successfully");
|
|
6631
|
-
}
|
|
6632
|
-
authStore.setLoading(false);
|
|
6633
|
-
}
|
|
6634
|
-
async handleResetPasswordRedirect() {
|
|
6635
|
-
const url = new URL(window.location.href);
|
|
6636
|
-
const params = url.searchParams;
|
|
6637
|
-
const resetToken = params.get("reset_password_token");
|
|
6638
|
-
if (!resetToken) {
|
|
6639
|
-
return;
|
|
6640
|
-
}
|
|
6641
|
-
if (state.sid) {
|
|
6642
|
-
authStore.setLoading(true);
|
|
6643
|
-
const [error] = await this.client.auth.validateResetPasswordToken({
|
|
6644
|
-
signInId: state.sid,
|
|
6645
|
-
token: resetToken,
|
|
6646
|
-
});
|
|
6647
|
-
if (error) {
|
|
6648
|
-
authStore.setFieldError("resetPassword", error);
|
|
6649
|
-
authStore.setStep("reset-password");
|
|
6650
|
-
authStore.setLoading(false);
|
|
6651
|
-
return;
|
|
6690
|
+
const parsed = schema.safeParse(response.data);
|
|
6691
|
+
if (!parsed.success) {
|
|
6692
|
+
this.logger.error("Invalid response format", parsed.error);
|
|
6693
|
+
this.errorReporter.captureException(parsed.error, { resourceName, endpoint });
|
|
6694
|
+
return ["invalid_response", null];
|
|
6652
6695
|
}
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
authStore.setStep("reset-password");
|
|
6656
|
-
authStore.setLoading(false);
|
|
6696
|
+
return [null, parsed.data];
|
|
6697
|
+
});
|
|
6657
6698
|
}
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
if (!
|
|
6664
|
-
return;
|
|
6699
|
+
/**
|
|
6700
|
+
* Generic get handler with schema validation.
|
|
6701
|
+
*/
|
|
6702
|
+
async handleGet(endpoint, schema, resourceName) {
|
|
6703
|
+
const idToken = await this.getIdToken();
|
|
6704
|
+
if (!idToken) {
|
|
6705
|
+
return ["missing_id_token", null];
|
|
6665
6706
|
}
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
this.
|
|
6707
|
+
const response = await this.client.get(endpoint, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6708
|
+
return this.handleResponse(response, () => {
|
|
6709
|
+
if (!response.success) {
|
|
6710
|
+
if (response.status === 404) {
|
|
6711
|
+
return ["not_found", null];
|
|
6712
|
+
}
|
|
6713
|
+
this.logger.error(`Failed to fetch ${resourceName}`, response);
|
|
6714
|
+
return ["server_error", null];
|
|
6673
6715
|
}
|
|
6674
|
-
|
|
6675
|
-
|
|
6716
|
+
const parsed = schema.safeParse(response.data);
|
|
6717
|
+
if (!parsed.success) {
|
|
6718
|
+
this.logger.error("Invalid response format", parsed.error);
|
|
6719
|
+
this.errorReporter.captureException(parsed.error, { resourceName, endpoint });
|
|
6720
|
+
return ["invalid_response", null];
|
|
6676
6721
|
}
|
|
6677
|
-
return;
|
|
6678
|
-
}
|
|
6679
|
-
// Handle missing required fields
|
|
6680
|
-
if (error !== "missing_required_fields") {
|
|
6681
|
-
this.logger.error("Social auth redirect error:", error);
|
|
6682
|
-
return;
|
|
6683
|
-
}
|
|
6684
|
-
const fieldsFromUrl = clearUrlParam("fields");
|
|
6685
|
-
const sid = clearUrlParam("sid");
|
|
6686
|
-
clearUrlParam("error");
|
|
6687
|
-
if (!fieldsFromUrl || !sid) {
|
|
6688
|
-
return;
|
|
6689
|
-
}
|
|
6690
|
-
try {
|
|
6691
|
-
const fields = JSON.parse(fieldsFromUrl);
|
|
6692
|
-
authStore.setSignInId(sid);
|
|
6693
|
-
this.handleMissingFields(fields);
|
|
6694
|
-
}
|
|
6695
|
-
catch (e) {
|
|
6696
|
-
this.logger.error("Failed to parse missing fields payload:", e);
|
|
6697
|
-
authStore.setGlobalError("auth", "invalid_required_fields_payload");
|
|
6698
|
-
}
|
|
6722
|
+
return [null, parsed.data];
|
|
6723
|
+
});
|
|
6699
6724
|
}
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6725
|
+
}
|
|
6726
|
+
|
|
6727
|
+
class SubscriptionsService extends TicketableService {
|
|
6728
|
+
constructor(client, deps) {
|
|
6729
|
+
super(client, "SubscriptionsService", deps);
|
|
6730
|
+
}
|
|
6731
|
+
async list(args = {}) {
|
|
6732
|
+
const params = this.buildListParams(args, "subscription_category_id", args.subscriptionCategoryId);
|
|
6733
|
+
const queryString = this.toQueryString(params);
|
|
6734
|
+
return this.handleList("/api/sdk/v1/subscriptions", queryString, SubscriptionsListResponseSchema, "subscriptions", args);
|
|
6735
|
+
}
|
|
6736
|
+
async get(args) {
|
|
6737
|
+
return this.handleGet(`/api/sdk/v1/subscriptions/${args.id}`, SubscriptionSchema, "subscription");
|
|
6738
|
+
}
|
|
6739
|
+
async getExportLink(args) {
|
|
6740
|
+
const idToken = await this.getIdToken();
|
|
6741
|
+
if (!idToken) {
|
|
6742
|
+
return ["missing_id_token", null];
|
|
6743
|
+
}
|
|
6744
|
+
const response = await this.client.post(`/api/sdk/v1/subscriptions/${args.id}/export_link`, { format: args.format }, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6745
|
+
return this.handleResponse(response, () => {
|
|
6746
|
+
if (!response.success) {
|
|
6747
|
+
if (response.status === 401 || response.status === 403) {
|
|
6748
|
+
return ["unauthorized", null];
|
|
6710
6749
|
}
|
|
6711
|
-
|
|
6750
|
+
return ["server_error", null];
|
|
6712
6751
|
}
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
else if (fallbackField === "email") {
|
|
6721
|
-
authStore.setFieldError("email", error);
|
|
6722
|
-
}
|
|
6723
|
-
else {
|
|
6724
|
-
// e.g. "account_locked", "internal_server_error"
|
|
6725
|
-
authStore.setGlobalError("auth", error);
|
|
6726
|
-
}
|
|
6727
|
-
break;
|
|
6728
|
-
}
|
|
6729
|
-
authStore.setLoading(false);
|
|
6752
|
+
const parsed = ExportLinkResponseSchema.safeParse(response.data);
|
|
6753
|
+
if (!parsed.success) {
|
|
6754
|
+
this.logger.error("Invalid export link response", parsed.error);
|
|
6755
|
+
return ["invalid_response", null];
|
|
6756
|
+
}
|
|
6757
|
+
return [null, parsed.data];
|
|
6758
|
+
});
|
|
6730
6759
|
}
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6760
|
+
}
|
|
6761
|
+
|
|
6762
|
+
class TicketsService extends TicketableService {
|
|
6763
|
+
constructor(client, deps) {
|
|
6764
|
+
super(client, "TicketsService", deps);
|
|
6736
6765
|
}
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6766
|
+
async list(args = {}) {
|
|
6767
|
+
const params = this.buildListParams(args, "ticket_category_id", args.ticketCategoryId);
|
|
6768
|
+
const queryString = this.toQueryString(params);
|
|
6769
|
+
return this.handleList("/api/sdk/v1/tickets", queryString, TicketsListResponseSchema, "tickets", args);
|
|
6770
|
+
}
|
|
6771
|
+
async get(args) {
|
|
6772
|
+
return this.handleGet(`/api/sdk/v1/tickets/${args.id}`, TicketSchema, "ticket");
|
|
6773
|
+
}
|
|
6774
|
+
async getExportLink(args) {
|
|
6775
|
+
const idToken = await this.getIdToken();
|
|
6776
|
+
if (!idToken) {
|
|
6777
|
+
return ["missing_id_token", null];
|
|
6778
|
+
}
|
|
6779
|
+
const response = await this.client.post(`/api/sdk/v1/tickets/${args.id}/export_link`, { format: args.format }, this.buildAuthHeaders({ "X-ID-Token": idToken }));
|
|
6780
|
+
return this.handleResponse(response, () => {
|
|
6781
|
+
if (!response.success) {
|
|
6782
|
+
if (response.status === 401 || response.status === 403) {
|
|
6783
|
+
return ["unauthorized", null];
|
|
6784
|
+
}
|
|
6785
|
+
return ["server_error", null];
|
|
6786
|
+
}
|
|
6787
|
+
const parsed = ExportLinkResponseSchema.safeParse(response.data);
|
|
6788
|
+
if (!parsed.success) {
|
|
6789
|
+
this.logger.error("Invalid export link response", parsed.error);
|
|
6790
|
+
return ["invalid_response", null];
|
|
6791
|
+
}
|
|
6792
|
+
return [null, parsed.data];
|
|
6793
|
+
});
|
|
6741
6794
|
}
|
|
6742
6795
|
}
|
|
6743
6796
|
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6797
|
+
/**
|
|
6798
|
+
* Base API client with shared functionality for both browser and standalone environments.
|
|
6799
|
+
*/
|
|
6800
|
+
/**
|
|
6801
|
+
* Abstract base class for API clients.
|
|
6802
|
+
* Provides shared functionality for making HTTP requests.
|
|
6803
|
+
*/
|
|
6804
|
+
class BaseApiClient {
|
|
6805
|
+
/**
|
|
6806
|
+
* Error messages that indicate a connection failure rather than a server error.
|
|
6807
|
+
* Grouped by source/environment.
|
|
6808
|
+
*/
|
|
6809
|
+
static CONNECTION_ERROR_MESSAGES = [
|
|
6810
|
+
// Browser fetch API errors
|
|
6811
|
+
"Failed to fetch", // Generic browser fetch failure (Chrome)
|
|
6812
|
+
"NetworkError", // Firefox network error
|
|
6813
|
+
"Load failed", // Safari network error
|
|
6814
|
+
"The network connection was lost", // Safari connection lost
|
|
6815
|
+
// Chromium/V8 error codes (used by Node.js and Chrome)
|
|
6816
|
+
"ERR_CONNECTION_REFUSED", // Server not accepting connections
|
|
6817
|
+
"ERR_NETWORK", // General network error
|
|
6818
|
+
"ERR_INTERNET_DISCONNECTED", // No internet connection
|
|
6819
|
+
// Node.js system error codes
|
|
6820
|
+
"ECONNREFUSED", // Connection refused by server
|
|
6821
|
+
"ENOTFOUND", // DNS lookup failed
|
|
6822
|
+
"EAI_AGAIN", // Temporary DNS failure
|
|
6823
|
+
];
|
|
6824
|
+
onConnectionChange;
|
|
6825
|
+
baseUrl;
|
|
6826
|
+
api_key;
|
|
6827
|
+
constructor(config) {
|
|
6828
|
+
this.baseUrl = config.baseUrl;
|
|
6829
|
+
this.api_key = config.apiKey;
|
|
6830
|
+
this.onConnectionChange = config.onConnectionChange;
|
|
6750
6831
|
}
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
},
|
|
6755
|
-
magicCode: {
|
|
6756
|
-
RECENTLY_CREATED: "magic_code_recently_created",
|
|
6757
|
-
NOT_VALID: "magic_code_not_valid",
|
|
6758
|
-
EXPIRED: "magic_code_expired",
|
|
6759
|
-
USED: "magic_code_used",
|
|
6760
|
-
},
|
|
6761
|
-
password: {
|
|
6762
|
-
INVALID: "invalid_password",
|
|
6763
|
-
NOT_SET: "password_not_set",
|
|
6764
|
-
RESET_PASSWORD_ALREADY_SENT: "reset_password_already_sent",
|
|
6765
|
-
},
|
|
6766
|
-
general: {
|
|
6767
|
-
ACCOUNT_LOCKED: "account_locked",
|
|
6768
|
-
SIGN_IN_EXPIRED: "sign_in_expired",
|
|
6769
|
-
},
|
|
6770
|
-
};
|
|
6771
|
-
static async getInstance() {
|
|
6772
|
-
if (!Auth.isInitialized()) {
|
|
6773
|
-
await waitForConfig();
|
|
6774
|
-
return Auth.initialize(getUnidyClient());
|
|
6832
|
+
isConnectionError(error) {
|
|
6833
|
+
if (error instanceof Error) {
|
|
6834
|
+
return BaseApiClient.CONNECTION_ERROR_MESSAGES.some((msg) => error.message.includes(msg));
|
|
6775
6835
|
}
|
|
6776
|
-
return
|
|
6836
|
+
return false;
|
|
6777
6837
|
}
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
return Auth.instance;
|
|
6781
|
-
}
|
|
6782
|
-
Auth.instance = new Auth(client);
|
|
6783
|
-
Auth.instance.helpers.handleSocialAuthRedirect();
|
|
6784
|
-
await Auth.instance.helpers.handleResetPasswordRedirect();
|
|
6785
|
-
if (Auth.instance.isTokenValid(state.token)) {
|
|
6786
|
-
authStore.setAuthenticated(true);
|
|
6787
|
-
}
|
|
6788
|
-
return Auth.instance;
|
|
6838
|
+
setConnectionStatus(isConnected) {
|
|
6839
|
+
this.onConnectionChange?.(isConnected);
|
|
6789
6840
|
}
|
|
6790
|
-
|
|
6791
|
-
|
|
6841
|
+
baseHeaders() {
|
|
6842
|
+
const h = new Headers();
|
|
6843
|
+
h.set("Content-Type", "application/json");
|
|
6844
|
+
h.set("Accept", "application/json");
|
|
6845
|
+
h.set("Authorization", `Bearer ${this.api_key}`);
|
|
6846
|
+
return h;
|
|
6847
|
+
}
|
|
6848
|
+
mergeHeaders(base, extra) {
|
|
6849
|
+
const out = new Headers(base);
|
|
6850
|
+
if (extra) {
|
|
6851
|
+
new Headers(extra).forEach((v, k) => {
|
|
6852
|
+
out.set(k, v);
|
|
6853
|
+
});
|
|
6854
|
+
}
|
|
6855
|
+
return out;
|
|
6792
6856
|
}
|
|
6793
6857
|
/**
|
|
6794
|
-
*
|
|
6795
|
-
*
|
|
6796
|
-
* @param token - The JWT token to validate. Can be a raw JWT string, a decoded TokenPayload, or null.
|
|
6797
|
-
* @param expirationBuffer - Number of seconds before actual expiration to consider the token invalid, used to prevent race conditions with preemptive token refresh. Defaults to 10 seconds.
|
|
6798
|
-
* @returns `true` if the token is valid and won't expire within the buffer period, `false` otherwise.
|
|
6799
|
-
* @throws Error if expirationBuffer is not positive number
|
|
6858
|
+
* Builds a query string from params, filtering out undefined/null values.
|
|
6800
6859
|
*/
|
|
6801
|
-
|
|
6802
|
-
if (!
|
|
6803
|
-
|
|
6804
|
-
|
|
6860
|
+
buildQueryString(params) {
|
|
6861
|
+
if (!params)
|
|
6862
|
+
return "";
|
|
6863
|
+
const filtered = Object.entries(params)
|
|
6864
|
+
.filter(([_, v]) => v !== undefined && v !== null)
|
|
6865
|
+
.map(([k, v]) => [k, String(v)]);
|
|
6866
|
+
if (filtered.length === 0)
|
|
6867
|
+
return "";
|
|
6868
|
+
return `?${new URLSearchParams(Object.fromEntries(filtered)).toString()}`;
|
|
6869
|
+
}
|
|
6870
|
+
async request(method, endpoint, body, headers) {
|
|
6871
|
+
let res = null;
|
|
6805
6872
|
try {
|
|
6806
|
-
|
|
6807
|
-
|
|
6808
|
-
|
|
6809
|
-
|
|
6810
|
-
|
|
6811
|
-
|
|
6873
|
+
res = await fetch(`${this.baseUrl}${endpoint}`, {
|
|
6874
|
+
method,
|
|
6875
|
+
...this.getRequestOptions(),
|
|
6876
|
+
headers: this.mergeHeaders(this.baseHeaders(), headers),
|
|
6877
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
6878
|
+
});
|
|
6879
|
+
let data;
|
|
6880
|
+
try {
|
|
6881
|
+
data = await res.json();
|
|
6812
6882
|
}
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
if (typeof decoded.exp !== "number" || !Number.isFinite(decoded.exp)) {
|
|
6816
|
-
return false;
|
|
6883
|
+
catch {
|
|
6884
|
+
data = undefined;
|
|
6817
6885
|
}
|
|
6818
|
-
|
|
6819
|
-
return
|
|
6886
|
+
this.setConnectionStatus(true);
|
|
6887
|
+
return {
|
|
6888
|
+
data,
|
|
6889
|
+
status: res.status,
|
|
6890
|
+
headers: res.headers,
|
|
6891
|
+
success: res.ok,
|
|
6892
|
+
connectionError: false,
|
|
6893
|
+
};
|
|
6820
6894
|
}
|
|
6821
6895
|
catch (error) {
|
|
6822
|
-
|
|
6823
|
-
|
|
6896
|
+
const connectionFailed = this.isConnectionError(error);
|
|
6897
|
+
if (connectionFailed) {
|
|
6898
|
+
this.setConnectionStatus(false);
|
|
6899
|
+
this.handleConnectionError(error, endpoint, method);
|
|
6900
|
+
}
|
|
6901
|
+
return {
|
|
6902
|
+
status: res?.status ?? (connectionFailed ? 0 : 500),
|
|
6903
|
+
error: error instanceof Error ? error.message : String(error),
|
|
6904
|
+
headers: res?.headers ?? new Headers(),
|
|
6905
|
+
success: false,
|
|
6906
|
+
data: undefined,
|
|
6907
|
+
connectionError: connectionFailed,
|
|
6908
|
+
};
|
|
6824
6909
|
}
|
|
6825
6910
|
}
|
|
6826
|
-
async
|
|
6827
|
-
const
|
|
6828
|
-
return
|
|
6911
|
+
async get(endpoint, headers, params) {
|
|
6912
|
+
const queryString = this.buildQueryString(params);
|
|
6913
|
+
return this.request("GET", `${endpoint}${queryString}`, undefined, headers);
|
|
6829
6914
|
}
|
|
6830
|
-
async
|
|
6831
|
-
|
|
6832
|
-
if (currentToken && this.isTokenValid(currentToken)) {
|
|
6833
|
-
return currentToken;
|
|
6834
|
-
}
|
|
6835
|
-
await this.helpers.refreshToken();
|
|
6836
|
-
if (state.globalErrors.auth || !state.token) {
|
|
6837
|
-
return this.createAuthError(t("errors.refresh_failed"), "REFRESH_FAILED", true);
|
|
6838
|
-
}
|
|
6839
|
-
return state.token;
|
|
6915
|
+
async post(endpoint, body, headers) {
|
|
6916
|
+
return this.request("POST", endpoint, body, headers);
|
|
6840
6917
|
}
|
|
6841
|
-
async
|
|
6842
|
-
|
|
6843
|
-
if (typeof token !== "string") {
|
|
6844
|
-
return null;
|
|
6845
|
-
}
|
|
6846
|
-
if (!token) {
|
|
6847
|
-
return null;
|
|
6848
|
-
}
|
|
6849
|
-
try {
|
|
6850
|
-
return jwtDecode(token);
|
|
6851
|
-
}
|
|
6852
|
-
catch (error) {
|
|
6853
|
-
captureException(error);
|
|
6854
|
-
return null;
|
|
6855
|
-
}
|
|
6918
|
+
async patch(endpoint, body, headers) {
|
|
6919
|
+
return this.request("PATCH", endpoint, body, headers);
|
|
6856
6920
|
}
|
|
6857
|
-
async
|
|
6858
|
-
|
|
6859
|
-
if (error) {
|
|
6860
|
-
return this.createAuthError(t("errors.sign_out_failed", { reason: error }), "SIGN_OUT_FAILED", false);
|
|
6861
|
-
}
|
|
6862
|
-
authStore.reset();
|
|
6863
|
-
return true;
|
|
6921
|
+
async delete(endpoint, headers) {
|
|
6922
|
+
return this.request("DELETE", endpoint, undefined, headers);
|
|
6864
6923
|
}
|
|
6865
|
-
|
|
6866
|
-
|
|
6924
|
+
}
|
|
6925
|
+
|
|
6926
|
+
/**
|
|
6927
|
+
* Browser-specific API client with CORS mode and Sentry error reporting.
|
|
6928
|
+
*/
|
|
6929
|
+
class ApiClient extends BaseApiClient {
|
|
6930
|
+
constructor(baseUrl, apiKey, onConnectionChange) {
|
|
6931
|
+
super({ baseUrl, apiKey, onConnectionChange });
|
|
6867
6932
|
}
|
|
6868
|
-
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6933
|
+
setConnectionStatus(isConnected) {
|
|
6934
|
+
super.setConnectionStatus(isConnected);
|
|
6935
|
+
unidyState.backendConnected = isConnected;
|
|
6936
|
+
}
|
|
6937
|
+
getRequestOptions() {
|
|
6938
|
+
return {
|
|
6939
|
+
mode: "cors",
|
|
6940
|
+
credentials: "include",
|
|
6941
|
+
};
|
|
6942
|
+
}
|
|
6943
|
+
handleConnectionError(error, endpoint, method) {
|
|
6944
|
+
captureException(error, {
|
|
6945
|
+
tags: { error_type: "connection_error" },
|
|
6946
|
+
extra: { endpoint, method },
|
|
6947
|
+
});
|
|
6873
6948
|
}
|
|
6874
6949
|
}
|
|
6875
6950
|
|
|
@@ -6916,7 +6991,7 @@ function getUnidyClient() {
|
|
|
6916
6991
|
return instance;
|
|
6917
6992
|
}
|
|
6918
6993
|
|
|
6919
|
-
export { AuthService as A, BaseApiClient as B, NewsletterService as N, ProfileService as P, SubscriptionsService as S, TicketsService as T, UnidyClient as U, ApiClient as a, UserProfileSchema as b,
|
|
6920
|
-
//# sourceMappingURL=index-
|
|
6994
|
+
export { AuthService as A, BaseApiClient as B, ExportFormat as E, NewsletterService as N, ProfileService as P, SubscriptionsService as S, TicketsService as T, UnidyClient as U, ApiClient as a, UserProfileSchema as b, BaseService as c, BaseErrorSchema as d, SchemaValidationErrorSchema as e, PaginationMetaSchema as f, getUnidyClient as g, PaginationParamsSchema as h, Auth as i, ExportLinkResponseSchema as j, TicketableListParamsSchema as k, TicketSchema as l, TicketsListResponseSchema as m, SubscriptionSchema as n, SubscriptionsListResponseSchema as o, clearUrlParam as p };
|
|
6995
|
+
//# sourceMappingURL=index-kgGjfc-n.js.map
|
|
6921
6996
|
|
|
6922
|
-
//# sourceMappingURL=index-
|
|
6997
|
+
//# sourceMappingURL=index-kgGjfc-n.js.map
|