@akinon/next 1.56.0-rc.4 → 1.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +1 -544
  2. package/api/client.ts +9 -39
  3. package/assets/styles/index.scss +26 -50
  4. package/bin/pz-prebuild.js +0 -1
  5. package/bin/pz-predev.js +0 -1
  6. package/components/index.ts +0 -1
  7. package/components/input.tsx +7 -21
  8. package/components/link.tsx +13 -17
  9. package/components/price.tsx +4 -11
  10. package/components/pz-root.tsx +3 -15
  11. package/components/selected-payment-option-view.tsx +38 -26
  12. package/data/client/account.ts +9 -10
  13. package/data/client/api.ts +1 -1
  14. package/data/client/b2b.ts +2 -35
  15. package/data/client/basket.ts +5 -6
  16. package/data/client/checkout.ts +0 -37
  17. package/data/client/user.ts +2 -3
  18. package/data/server/category.ts +19 -43
  19. package/data/server/flatpage.ts +7 -29
  20. package/data/server/form.ts +11 -29
  21. package/data/server/landingpage.ts +7 -26
  22. package/data/server/list.ts +6 -16
  23. package/data/server/menu.ts +2 -15
  24. package/data/server/product.ts +13 -33
  25. package/data/server/seo.ts +24 -17
  26. package/data/server/special-page.ts +5 -15
  27. package/data/server/widget.ts +7 -14
  28. package/data/urls.ts +1 -8
  29. package/hocs/server/with-segment-defaults.tsx +1 -4
  30. package/hooks/index.ts +1 -2
  31. package/hooks/use-pagination.ts +2 -2
  32. package/hooks/use-payment-options.ts +1 -2
  33. package/lib/cache.ts +6 -8
  34. package/middlewares/default.ts +2 -46
  35. package/middlewares/pretty-url.ts +1 -11
  36. package/middlewares/url-redirection.ts +0 -4
  37. package/package.json +3 -4
  38. package/plugins.d.ts +0 -1
  39. package/redux/middlewares/checkout.ts +10 -69
  40. package/redux/reducers/checkout.ts +3 -23
  41. package/types/commerce/account.ts +0 -1
  42. package/types/commerce/address.ts +1 -1
  43. package/types/commerce/b2b.ts +2 -12
  44. package/types/commerce/checkout.ts +0 -30
  45. package/types/commerce/order.ts +0 -1
  46. package/types/index.ts +2 -17
  47. package/utils/app-fetch.ts +8 -16
  48. package/utils/generate-commerce-search-params.ts +1 -3
  49. package/utils/index.ts +6 -27
  50. package/utils/server-translation.ts +1 -11
  51. package/with-pz-config.js +2 -13
  52. package/assets/styles/index.css +0 -49
  53. package/assets/styles/index.css.map +0 -1
  54. package/bin/pz-generate-translations.js +0 -41
  55. package/components/file-input.tsx +0 -8
  56. package/hooks/use-message-listener.ts +0 -24
  57. package/lib/cache-handler.mjs +0 -33
  58. package/routes/pretty-url.tsx +0 -192
  59. package/utils/redirection-iframe.ts +0 -85
@@ -1,53 +1,29 @@
1
1
  .checkout-payment-iframe-wrapper {
2
- position: fixed;
3
- top: 0;
4
- left: 0;
5
- width: 100%;
6
- height: 100%;
7
- border: none;
8
- z-index: 1000;
9
- background-color: white;
2
+ position: fixed;
3
+ top: 0;
4
+ left: 0;
5
+ width: 100%;
6
+ height: 100%;
7
+ border: none;
8
+ z-index: 1000;
9
+ background-color: white;
10
10
 
11
- iframe {
12
- width: 100%;
13
- height: 100%;
14
- border: none;
15
- background-color: white;
16
- }
11
+ iframe {
12
+ width: 100%;
13
+ height: 100%;
14
+ border: none;
15
+ background-color: white;
16
+ }
17
17
 
18
- .close-button {
19
- position: fixed;
20
- top: 16px;
21
- right: 16px;
22
- width: 32px;
23
- height: 32px;
24
- display: flex;
25
- align-items: center;
26
- justify-content: center;
27
- z-index: 1001;
28
- }
29
- }
30
-
31
- .checkout-payment-redirection-iframe-wrapper {
32
- width: 100%;
33
- position: relative;
34
-
35
- iframe {
36
- width: 100%;
37
- height: 100%;
38
- border: none;
39
- background-color: white;
40
- }
41
-
42
- .close-button {
43
- position: absolute;
44
- top: 16px;
45
- right: 16px;
46
- width: 32px;
47
- height: 32px;
48
- display: flex;
49
- align-items: center;
50
- justify-content: center;
51
- z-index: 1001;
52
- }
53
- }
18
+ .close-button {
19
+ position: fixed;
20
+ top: 16px;
21
+ right: 16px;
22
+ width: 32px;
23
+ height: 32px;
24
+ display: flex;
25
+ align-items: center;
26
+ justify-content: center;
27
+ z-index: 1001;
28
+ }
29
+ }
@@ -4,4 +4,3 @@ const runScript = require('./run-script');
4
4
 
5
5
  runScript('pz-install-theme.js');
6
6
  runScript('pz-pre-check-dist.js');
7
- runScript('pz-generate-translations.js');
package/bin/pz-predev.js CHANGED
@@ -5,4 +5,3 @@ const runScript = require('./run-script');
5
5
  runScript('pz-install-extensions.js');
6
6
  runScript('pz-check-env.js');
7
7
  runScript('pz-install-theme.js');
8
- runScript('pz-generate-translations.js');
@@ -19,4 +19,3 @@ export * from './trans';
19
19
  export * from './link';
20
20
  export * from './pagination';
21
21
  export * from './live-commerce';
22
- export * from './file-input';
@@ -1,30 +1,17 @@
1
1
  import clsx from 'clsx';
2
- import { forwardRef, FocusEvent, useState, Ref } from 'react';
2
+ import { forwardRef, FocusEvent, useState } from 'react';
3
3
  import { Controller } from 'react-hook-form';
4
-
5
- // @ts-ignore
6
- import { PatternFormat, PatternFormatProps } from 'react-number-format';
4
+ import NumberFormat, { NumberFormatProps } from 'react-number-format';
7
5
  import { InputProps } from '../types';
8
6
  import { twMerge } from 'tailwind-merge';
9
7
 
10
- const PatternFormatWithRef = forwardRef(
11
- (props: PatternFormatProps, ref: Ref<HTMLInputElement>) => {
12
- return <PatternFormat {...props} getInputRef={ref} />;
13
- }
14
- );
15
- PatternFormatWithRef.displayName = 'PatternFormatWithRef';
16
-
17
8
  export const Input = forwardRef<
18
9
  HTMLInputElement,
19
10
  InputProps &
20
11
  Pick<
21
- PatternFormatProps,
22
- 'mask' | 'allowEmptyFormatting' | 'onValueChange'
23
- > & {
24
- format?: string;
25
- defaultValue?: string;
26
- type?: string;
27
- }
12
+ NumberFormatProps,
13
+ 'format' | 'mask' | 'allowEmptyFormatting' | 'onValueChange'
14
+ >
28
15
  >((props, ref) => {
29
16
  const [focused, setFocused] = useState(false);
30
17
  const [hasValue, setHasValue] = useState(false);
@@ -50,7 +37,6 @@ export const Input = forwardRef<
50
37
  ),
51
38
  props.className
52
39
  );
53
-
54
40
  const inputProps: any = {
55
41
  id,
56
42
  ref,
@@ -93,14 +79,14 @@ export const Input = forwardRef<
93
79
  <Controller
94
80
  name={props.name ?? ''}
95
81
  control={props.control}
82
+ defaultValue={false}
96
83
  render={({ field }) => (
97
- <PatternFormatWithRef
84
+ <NumberFormat
98
85
  format={format}
99
86
  mask={mask ?? ''}
100
87
  {...rest}
101
88
  {...field}
102
89
  {...inputProps}
103
- type={props.type as 'text' | 'password' | 'tel'}
104
90
  />
105
91
  )}
106
92
  />
@@ -10,32 +10,28 @@ type LinkProps = Omit<
10
10
  React.AnchorHTMLAttributes<HTMLAnchorElement>,
11
11
  keyof NextLinkProps
12
12
  > &
13
- NextLinkProps & {
14
- href: string;
15
- };
13
+ NextLinkProps;
16
14
 
17
15
  export const Link = ({ children, href, ...rest }: LinkProps) => {
18
16
  const { locale, defaultLocaleValue, localeUrlStrategy } = useLocalization();
19
17
  const formattedHref = useMemo(() => {
20
- if (!href) {
21
- return '#';
18
+ if (typeof href !== 'string' || href.startsWith('http')) {
19
+ return href;
22
20
  }
23
21
 
24
- if (typeof href === 'string' && !href.startsWith('http')) {
25
- const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
26
- const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
22
+ const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
23
+ const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
27
24
 
28
- if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
29
- return hrefWithLocale;
30
- } else if (
31
- localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
32
- locale !== defaultLocaleValue
33
- ) {
34
- return hrefWithLocale;
35
- }
25
+ if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
26
+ return hrefWithLocale;
27
+ } else if (
28
+ localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
29
+ locale !== defaultLocaleValue
30
+ ) {
31
+ return hrefWithLocale;
36
32
  }
37
33
 
38
- return href;
34
+ return href || '#';
39
35
  }, [href, defaultLocaleValue, locale, localeUrlStrategy]);
40
36
 
41
37
  return (
@@ -1,14 +1,11 @@
1
1
  import { useMemo } from 'react';
2
-
3
- // @ts-ignore
4
- import { NumericFormat, NumericFormatProps } from 'react-number-format';
2
+ import NumberFormat, { NumberFormatProps } from 'react-number-format';
5
3
  import { getCurrency } from '@akinon/next/utils';
6
4
 
7
5
  import { useLocalization } from '@akinon/next/hooks';
8
6
  import { PriceProps } from '../types';
9
- import Settings from 'settings';
10
7
 
11
- export const Price = (props: NumericFormatProps & PriceProps) => {
8
+ export const Price = (props: NumberFormatProps & PriceProps) => {
12
9
  const {
13
10
  value,
14
11
  currencyCode,
@@ -30,10 +27,6 @@ export const Price = (props: NumericFormatProps & PriceProps) => {
30
27
  // TODO: This is very bad practice. It broke decimalScale.
31
28
  const _value = value?.toString().replace('.', ',');
32
29
 
33
- const currentCurrencyDecimalScale = Settings.localization.currencies.find(
34
- (currency) => currency.code === currencyCode_
35
- ).decimalScale;
36
-
37
30
  const currency = useMemo(
38
31
  () =>
39
32
  getCurrency({
@@ -46,14 +39,14 @@ export const Price = (props: NumericFormatProps & PriceProps) => {
46
39
  );
47
40
 
48
41
  return (
49
- <NumericFormat
42
+ <NumberFormat
50
43
  value={useNegative ? `-${useNegativeSpace}${_value}` : _value}
51
44
  {...{
52
45
  [useCurrencyAfterPrice ? 'suffix' : 'prefix']: currency
53
46
  }}
54
47
  displayType={displayType}
55
48
  thousandSeparator={thousandSeparator}
56
- decimalScale={currentCurrencyDecimalScale ?? decimalScale}
49
+ decimalScale={decimalScale}
57
50
  decimalSeparator={decimalSeparator}
58
51
  fixedDecimalScale={fixedDecimalScale}
59
52
  {...rest}
@@ -3,29 +3,17 @@ import ClientRoot from './client-root';
3
3
  import { cookies } from 'next/headers';
4
4
  import PzProviders from './pz-providers';
5
5
  import { WebVitals } from './web-vitals';
6
- import settings from 'settings';
7
6
 
8
- export default async function PzRoot({
7
+ export default function PzRoot({
9
8
  translations,
10
- children,
11
- locale
9
+ children
12
10
  }: {
13
- translations?: any;
11
+ translations: any;
14
12
  children: React.ReactNode;
15
- locale?: string;
16
13
  }) {
17
14
  const nextCookies = cookies();
18
15
  const sessionid = nextCookies.get('osessionid')?.value;
19
16
 
20
- if (!translations) {
21
- const { getTranslations } =
22
- settings.useOptimizedTranslations && locale
23
- ? require('translations')
24
- : require('../utils/server-translation');
25
-
26
- translations = await getTranslations(locale);
27
- }
28
-
29
17
  return (
30
18
  <PzProviders translations={translations}>
31
19
  <WebVitals />
@@ -6,21 +6,6 @@ import dynamic from 'next/dynamic';
6
6
  import { PaymentOptionViews } from 'views/checkout/steps/payment';
7
7
  import { useMemo } from 'react';
8
8
 
9
- const fallbackView = () => <div />;
10
-
11
- const paymentTypeToView = {
12
- bkm_express: 'bkm',
13
- credit_card: 'credit-card',
14
- credit_payment: 'credit-payment',
15
- funds_transfer: 'funds-transfer',
16
- gpay: 'gpay',
17
- loyalty_money: 'loyalty',
18
- masterpass: 'credit-card',
19
- pay_on_delivery: 'pay-on-delivery',
20
- redirection: 'redirection'
21
- // Add other mappings as needed
22
- };
23
-
24
9
  export default function SelectedPaymentOptionView() {
25
10
  const { payment_option } = useAppSelector(
26
11
  (state: RootState) => state.checkout.preOrder
@@ -29,7 +14,7 @@ export default function SelectedPaymentOptionView() {
29
14
  const Component = useMemo(
30
15
  () =>
31
16
  dynamic(
32
- async () => {
17
+ () => {
33
18
  const customOption = PaymentOptionViews.find(
34
19
  (opt) => opt.slug === payment_option?.slug
35
20
  );
@@ -44,19 +29,46 @@ export default function SelectedPaymentOptionView() {
44
29
  });
45
30
  }
46
31
 
47
- const view = paymentTypeToView[payment_option?.payment_type];
48
- if (view) {
49
- try {
50
- const mod = await import(
51
- `views/checkout/steps/payment/options/${view}`
32
+ let promise: any;
33
+
34
+ try {
35
+ if (payment_option?.payment_type === 'credit_card') {
36
+ promise = import(
37
+ `views/checkout/steps/payment/options/credit-card`
38
+ );
39
+ } else if (payment_option?.payment_type === 'funds_transfer') {
40
+ promise = import(
41
+ `views/checkout/steps/payment/options/funds-transfer`
42
+ );
43
+ } else if (payment_option?.payment_type === 'redirection') {
44
+ promise = import(
45
+ `views/checkout/steps/payment/options/redirection`
46
+ );
47
+ } else if (payment_option?.payment_type === 'pay_on_delivery') {
48
+ promise = import(
49
+ `views/checkout/steps/payment/options/pay-on-delivery`
50
+ );
51
+ } else if (payment_option?.payment_type === 'loyalty_money') {
52
+ promise = import(`views/checkout/steps/payment/options/loyalty`);
53
+ } else if (payment_option?.payment_type === 'masterpass') {
54
+ promise = import(
55
+ `views/checkout/steps/payment/options/credit-card`
52
56
  );
53
- return mod.default || fallbackView;
54
- } catch (error) {
55
- return fallbackView;
56
57
  }
57
- }
58
+ // else if (payment_option.payment_type === 'credit_payment') {
59
+ // promise = import(`views/checkout/steps/payment/options/credit-payment`);
60
+ // }
61
+ // else if (payment_option.payment_type === 'gpay') {
62
+ // promise = import(`views/checkout/steps/payment/options/gpay`);
63
+ // }
64
+ // else if (payment_option.payment_type === 'bkm_express') {
65
+ // promise = import(`views/checkout/steps/payment/options/bkm`);
66
+ // }
67
+ } catch (error) {}
58
68
 
59
- return fallbackView;
69
+ return promise
70
+ ? promise.then((mod) => mod.default).catch(() => () => null)
71
+ : new Promise<any>((resolve) => resolve(() => null));
60
72
  },
61
73
  { ssr: false }
62
74
  ),
@@ -123,16 +123,15 @@ const accountApi = api.injectEndpoints({
123
123
  query: ({ page, status, limit }) =>
124
124
  buildClientRequestUrl(account.getQuotations(page, status, limit))
125
125
  }),
126
- sendContact: builder.mutation<void, FormData>({
127
- query: (body) => {
128
- return {
129
- url: buildClientRequestUrl(account.sendContact, {
130
- useFormData: true
131
- }),
132
- method: 'POST',
133
- body
134
- };
135
- }
126
+ sendContact: builder.mutation<void, ContactFormType>({
127
+ query: (body) => ({
128
+ url: buildClientRequestUrl(account.sendContact, {
129
+ contentType: 'application/json',
130
+ responseType: 'text'
131
+ }),
132
+ method: 'POST',
133
+ body
134
+ })
136
135
  }),
137
136
  cancelOrder: builder.mutation<void, AccountOrderCancellation>({
138
137
  query: ({ id, ...body }) => ({
@@ -67,7 +67,7 @@ export const api = createApi({
67
67
  baseQuery: customBaseQuery,
68
68
  tagTypes: [
69
69
  'Basket',
70
- 'MultiBasket',
70
+ 'AllBaskets',
71
71
  'BasketB2b',
72
72
  'DraftsB2b',
73
73
  'Product',
@@ -12,9 +12,7 @@ import {
12
12
  SaveBasketParams,
13
13
  UpdateProductParams,
14
14
  DeleteProductParams,
15
- CreateQuotationParams,
16
- BasketStatusResponse,
17
- ExportBasketResponse
15
+ CreateQuotationParams
18
16
  } from '../../types';
19
17
 
20
18
  const b2bApi = api.injectEndpoints({
@@ -91,34 +89,6 @@ const b2bApi = api.injectEndpoints({
91
89
  }),
92
90
  invalidatesTags: ['BasketB2b', 'DraftsB2b']
93
91
  }),
94
- exportBasket: build.mutation<ExportBasketResponse, string>({
95
- query: (queryString) => {
96
- return {
97
- url: buildClientRequestUrl(b2b.basketExport(queryString)),
98
- method: 'GET'
99
- };
100
- }
101
- }),
102
- getBasketStatus: build.mutation<BasketStatusResponse, string>({
103
- query: (cacheKey) => {
104
- return {
105
- url: buildClientRequestUrl(b2b.statusBasket(cacheKey)),
106
- method: 'GET'
107
- };
108
- }
109
- }),
110
- uploadFile: build.mutation<void, FormData>({
111
- query: (body) => {
112
- return {
113
- url: buildClientRequestUrl(b2b.basketImport, {
114
- useFormData: true
115
- }),
116
- method: 'POST',
117
- body
118
- };
119
- },
120
- invalidatesTags: ['BasketB2b']
121
- })
122
92
  }),
123
93
  overrideExisting: true
124
94
  });
@@ -132,8 +102,5 @@ export const {
132
102
  useLoadBasketMutation,
133
103
  useUpdateProductMutation,
134
104
  useDeleteProductMutation,
135
- useCreateQuotationMutation,
136
- useGetBasketStatusMutation,
137
- useExportBasketMutation,
138
- useUploadFileMutation
105
+ useCreateQuotationMutation
139
106
  } = b2bApi;
@@ -28,7 +28,7 @@ export const basketApi = api.injectEndpoints({
28
28
  query: ({ namespace }) =>
29
29
  buildClientRequestUrl(basket.getBasketDetail(namespace)),
30
30
  transformResponse: (response: { basket: Basket }) => response.basket,
31
- providesTags: ['MultiBasket']
31
+ providesTags: ['AllBaskets']
32
32
  }),
33
33
  getAllBaskets: build.query<Basket[], void>({
34
34
  query: () =>
@@ -36,7 +36,7 @@ export const basketApi = api.injectEndpoints({
36
36
  contentType: 'application/json'
37
37
  }),
38
38
  transformResponse: (response: { baskets: Basket[] }) => response.baskets,
39
- providesTags: ['MultiBasket']
39
+ providesTags: ['AllBaskets']
40
40
  }),
41
41
  removeBasket: build.mutation<Basket, { pk: number }>({
42
42
  query: ({ pk }) => ({
@@ -46,7 +46,7 @@ export const basketApi = api.injectEndpoints({
46
46
  method: 'DELETE',
47
47
  body: { pk }
48
48
  }),
49
- invalidatesTags: ['MultiBasket', 'Basket']
49
+ invalidatesTags: ['AllBaskets', 'Basket']
50
50
  }),
51
51
  selectMainBasket: build.mutation<Basket, { pk: number }>({
52
52
  query: ({ pk }) => ({
@@ -57,7 +57,7 @@ export const basketApi = api.injectEndpoints({
57
57
  body: { pk }
58
58
  }),
59
59
  transformResponse: (response: { baskets: Basket }) => response.baskets,
60
- invalidatesTags: ['MultiBasket', 'Basket']
60
+ invalidatesTags: ['AllBaskets', 'Basket']
61
61
  }),
62
62
  updateQuantity: build.mutation<
63
63
  UpdateQuantityResponse,
@@ -69,8 +69,7 @@ export const basketApi = api.injectEndpoints({
69
69
  }),
70
70
  method: 'PUT',
71
71
  body
72
- }),
73
- invalidatesTags: ['MultiBasket', 'Basket']
72
+ })
74
73
  }),
75
74
  clearBasket: build.mutation<Basket, void>({
76
75
  query: (body) => ({
@@ -380,22 +380,6 @@ export const checkoutApi = api.injectEndpoints({
380
380
  dispatch(setShippingStepBusy(false));
381
381
  }
382
382
  }),
383
- setDataSourceShippingOptions: build.mutation<CheckoutResponse, number[]>({
384
- query: (pks) => ({
385
- url: buildClientRequestUrl(checkout.setDataSourceShippingOption, {
386
- useFormData: true
387
- }),
388
- method: 'POST',
389
- body: {
390
- data_source_shipping_options: JSON.stringify(pks)
391
- }
392
- }),
393
- async onQueryStarted(arg, { dispatch, queryFulfilled }) {
394
- dispatch(setShippingStepBusy(true));
395
- await queryFulfilled;
396
- dispatch(setShippingStepBusy(false));
397
- }
398
- }),
399
383
  setRetailStore: build.mutation<CheckoutResponse, SetRetailStoreParams>({
400
384
  query: ({ retailStorePk, billingAddressPk }) => ({
401
385
  url: buildClientRequestUrl(
@@ -697,25 +681,6 @@ export const checkoutApi = api.injectEndpoints({
697
681
  };
698
682
  }
699
683
  }),
700
- setAttributeBasedShippingOptions: build.mutation<
701
- CheckoutResponse,
702
- Record<string, number>
703
- >({
704
- query: (options) => ({
705
- url: buildClientRequestUrl(checkout.setAttributeBasedShippingOption, {
706
- useFormData: true
707
- }),
708
- method: 'POST',
709
- body: {
710
- attribute_based_shipping_options: JSON.stringify(options)
711
- }
712
- }),
713
- async onQueryStarted(arg, { dispatch, queryFulfilled }) {
714
- dispatch(setShippingStepBusy(true));
715
- await queryFulfilled;
716
- dispatch(setShippingStepBusy(false));
717
- }
718
- }),
719
684
  setOrderSelectionPage: build.mutation<
720
685
  CheckoutResponse,
721
686
  { extra_field: ExtraField }
@@ -747,7 +712,6 @@ export const {
747
712
  useSetDeliveryOptionMutation,
748
713
  useSetAddressesMutation,
749
714
  useSetShippingOptionMutation,
750
- useSetDataSourceShippingOptionsMutation,
751
715
  useSetPaymentOptionMutation,
752
716
  useSetBinNumberMutation,
753
717
  useSetInstallmentOptionMutation,
@@ -766,6 +730,5 @@ export const {
766
730
  usePayWithLoyaltyBalanceMutation,
767
731
  useSetOrderNoteMutation,
768
732
  useSetDeliveryBagsMutation,
769
- useSetAttributeBasedShippingOptionsMutation,
770
733
  useSetOrderSelectionPageMutation
771
734
  } = checkoutApi;
@@ -22,12 +22,11 @@ const userApi = api.injectEndpoints({
22
22
  getCaptcha: build.query<GetCaptchaResponse, void>({
23
23
  query: () => buildClientRequestUrl(user.captcha),
24
24
  transformResponse: (response: { html: string }) => {
25
- const siteKey = response.html.match(/data-sitekey="([^"]+)"/i)[1];
26
-
25
+ const siteKeyMatch = response.html.match(/sitekey=["|'][^"']+/gi);
27
26
  const csrfTokenMatch = response.html.match(
28
27
  /name=['|"]csrfmiddlewaretoken['|"] value=['|"][^'"]+/gi
29
28
  );
30
-
29
+ const siteKey = siteKeyMatch?.[0].replace(/sitekey=["|']/, '') || '';
31
30
  const csrfToken =
32
31
  csrfTokenMatch?.[0].replace(
33
32
  /name=['|"]csrfmiddlewaretoken['|"] value=['|"]/gi,