@akinon/next 1.0.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/.prettierrc +13 -0
- package/api/auth.ts +217 -0
- package/api/cache.ts +44 -0
- package/api/client.ts +157 -0
- package/api/logout.ts +42 -0
- package/assets/styles/index.scss +24 -0
- package/bin/pz-install-plugins.js +33 -0
- package/components/client-root.tsx +69 -0
- package/components/image.tsx +133 -0
- package/components/mobile-app-toggler.tsx +15 -0
- package/components/oauth-login.tsx +24 -0
- package/components/plugin-module.tsx +78 -0
- package/components/pz-providers.tsx +24 -0
- package/components/pz-root.tsx +21 -0
- package/components/redirect-three-d/content/index.tsx +64 -0
- package/components/redirect-three-d/index.tsx +17 -0
- package/components/selected-payment-option-view.tsx +66 -0
- package/components/trans.tsx +39 -0
- package/data/client/account.ts +188 -0
- package/data/client/address.ts +107 -0
- package/data/client/api.ts +42 -0
- package/data/client/basket.ts +85 -0
- package/data/client/checkout.ts +477 -0
- package/data/client/misc.ts +101 -0
- package/data/client/product.ts +90 -0
- package/data/client/user.ts +83 -0
- package/data/client/wishlist.ts +79 -0
- package/data/server/category.ts +121 -0
- package/data/server/flatpage.ts +21 -0
- package/data/server/index.ts +8 -0
- package/data/server/list.ts +56 -0
- package/data/server/menu.ts +35 -0
- package/data/server/product.ts +86 -0
- package/data/server/seo.ts +48 -0
- package/data/server/special-page.ts +42 -0
- package/data/server/widget.ts +27 -0
- package/data/urls.ts +184 -0
- package/hocs/client/index.ts +1 -0
- package/hocs/client/with-segment-defaults.tsx +26 -0
- package/hocs/server/index.ts +1 -0
- package/hocs/server/with-segment-defaults.tsx +83 -0
- package/hooks/index.ts +8 -0
- package/hooks/use-captcha.tsx +76 -0
- package/hooks/use-common-product-attributes.ts +36 -0
- package/hooks/use-debounce.ts +20 -0
- package/hooks/use-localization.ts +63 -0
- package/hooks/use-media-query.ts +36 -0
- package/hooks/use-on-click-outside.tsx +28 -0
- package/hooks/use-router.ts +45 -0
- package/hooks/use-translation.ts +14 -0
- package/lib/cache.ts +185 -0
- package/localization/index.ts +5 -0
- package/localization/provider.tsx +58 -0
- package/middlewares/currency.ts +55 -0
- package/middlewares/default.ts +224 -0
- package/middlewares/index.ts +29 -0
- package/middlewares/locale.ts +61 -0
- package/middlewares/oauth-login.ts +78 -0
- package/middlewares/pretty-url.ts +94 -0
- package/middlewares/redirection-payment.ts +117 -0
- package/middlewares/three-d-redirection.ts +122 -0
- package/middlewares/url-redirection.ts +61 -0
- package/package.json +20 -0
- package/plugins.js +7 -0
- package/redux/hooks.ts +7 -0
- package/redux/middlewares/checkout.ts +231 -0
- package/redux/middlewares/index.ts +50 -0
- package/redux/reducers/checkout.ts +164 -0
- package/redux/reducers/config.ts +28 -0
- package/redux/reducers/header.ts +59 -0
- package/redux/reducers/index.ts +15 -0
- package/redux/reducers/root.ts +61 -0
- package/tailwind/rtl.js +137 -0
- package/types/commerce/account.ts +68 -0
- package/types/commerce/address.ts +94 -0
- package/types/commerce/basket.ts +43 -0
- package/types/commerce/category.ts +114 -0
- package/types/commerce/checkout.ts +132 -0
- package/types/commerce/flatpage.ts +7 -0
- package/types/commerce/index.ts +10 -0
- package/types/commerce/misc.ts +127 -0
- package/types/commerce/order.ts +108 -0
- package/types/commerce/product.ts +110 -0
- package/types/commerce/widget.ts +28 -0
- package/types/gtm.ts +16 -0
- package/types/index.ts +207 -0
- package/types/next-auth.d.ts +24 -0
- package/utils/app-fetch.ts +62 -0
- package/utils/generate-commerce-search-params.ts +22 -0
- package/utils/get-currency.ts +29 -0
- package/utils/image-loader.ts +31 -0
- package/utils/index.ts +132 -0
- package/utils/localization.ts +29 -0
- package/utils/log.ts +138 -0
- package/utils/menu-generator.ts +27 -0
- package/utils/mobile-3d-iframe.ts +58 -0
- package/utils/server-translation.ts +57 -0
- package/utils/server-variables.ts +9 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { District } from './address';
|
|
2
|
+
export interface Config {
|
|
3
|
+
user_phone_regex: string;
|
|
4
|
+
user_phone_format: string;
|
|
5
|
+
country: {
|
|
6
|
+
pk: number;
|
|
7
|
+
name: string;
|
|
8
|
+
code: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface RetailStore {
|
|
13
|
+
address: string;
|
|
14
|
+
name: string;
|
|
15
|
+
pk: number;
|
|
16
|
+
district: District;
|
|
17
|
+
township: {
|
|
18
|
+
name: string;
|
|
19
|
+
pk: number;
|
|
20
|
+
city: {
|
|
21
|
+
country: number;
|
|
22
|
+
name: string;
|
|
23
|
+
pk: number;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type Pagination = {
|
|
29
|
+
current_page: number;
|
|
30
|
+
num_pages: number;
|
|
31
|
+
page_size: number;
|
|
32
|
+
total_count: number;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type EmailSubscriptionType = {
|
|
36
|
+
email: string;
|
|
37
|
+
subscribe_contract: boolean;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type ImageType = {
|
|
41
|
+
data_type?: 'image';
|
|
42
|
+
url?: string;
|
|
43
|
+
value?: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export interface Error {
|
|
47
|
+
status: number;
|
|
48
|
+
data: {
|
|
49
|
+
error_code: string;
|
|
50
|
+
non_field_errors: string;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type Discount = {
|
|
55
|
+
description: string;
|
|
56
|
+
discount: string;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type MenuItemExtraContentImageType = {
|
|
60
|
+
kwargs: {
|
|
61
|
+
value: {
|
|
62
|
+
image: {
|
|
63
|
+
url: string;
|
|
64
|
+
value: string;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
value: {
|
|
69
|
+
image: string;
|
|
70
|
+
link_text: string;
|
|
71
|
+
title: string;
|
|
72
|
+
url: string;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export type MenuItemExtraContentStoryType = {
|
|
77
|
+
value: {
|
|
78
|
+
url: string;
|
|
79
|
+
alt: string;
|
|
80
|
+
image: string;
|
|
81
|
+
};
|
|
82
|
+
kwargs: {
|
|
83
|
+
data_type: 'nested';
|
|
84
|
+
value: {
|
|
85
|
+
image: ImageType;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type MenuItemExtraContentType = {
|
|
91
|
+
attributes: {
|
|
92
|
+
category_id: number;
|
|
93
|
+
images: Array<MenuItemExtraContentImageType>;
|
|
94
|
+
[key: string]: any;
|
|
95
|
+
};
|
|
96
|
+
include_parent: boolean;
|
|
97
|
+
numchild: number;
|
|
98
|
+
[key: string]: any;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export type MenuItemType = {
|
|
102
|
+
extra_context: MenuItemExtraContentType;
|
|
103
|
+
generator_name: 'menu_item';
|
|
104
|
+
label: string;
|
|
105
|
+
level: number;
|
|
106
|
+
parent: null | MenuItemType;
|
|
107
|
+
parent_pk: null | string;
|
|
108
|
+
children: null | MenuItemType[];
|
|
109
|
+
path: string;
|
|
110
|
+
pk: string;
|
|
111
|
+
sort_order: number;
|
|
112
|
+
url: string;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export type ForgotPasswordFormType = {
|
|
116
|
+
email: string;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export interface UpsellDetail {
|
|
120
|
+
message: string;
|
|
121
|
+
params: {
|
|
122
|
+
partial_percentage: number;
|
|
123
|
+
required: number;
|
|
124
|
+
partial: number;
|
|
125
|
+
remaining: number;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { Product } from './product';
|
|
2
|
+
import { Address } from './address';
|
|
3
|
+
|
|
4
|
+
export interface OrderStatus {
|
|
5
|
+
value: string;
|
|
6
|
+
label: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface Currency {
|
|
10
|
+
value: string;
|
|
11
|
+
label: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface PaymentOption {
|
|
15
|
+
name: string;
|
|
16
|
+
payment_type: string;
|
|
17
|
+
payment_type_label: string;
|
|
18
|
+
pk: number;
|
|
19
|
+
slug: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface OrderItem {
|
|
23
|
+
id: number;
|
|
24
|
+
status: OrderStatus;
|
|
25
|
+
price_currency: Currency;
|
|
26
|
+
product: Product;
|
|
27
|
+
is_cancelled: boolean;
|
|
28
|
+
is_cancellable: boolean;
|
|
29
|
+
is_refundable: boolean;
|
|
30
|
+
is_tradable: boolean;
|
|
31
|
+
available_easy_return_shipping_companies: {
|
|
32
|
+
pk: number;
|
|
33
|
+
shipping_company: {
|
|
34
|
+
value: string;
|
|
35
|
+
label: string;
|
|
36
|
+
};
|
|
37
|
+
}[];
|
|
38
|
+
active_cancellation_request: [
|
|
39
|
+
{
|
|
40
|
+
easy_return: {
|
|
41
|
+
code: string;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
];
|
|
45
|
+
created_date: string;
|
|
46
|
+
modified_date: string;
|
|
47
|
+
price: string;
|
|
48
|
+
tax_rate: string;
|
|
49
|
+
retail_price: string;
|
|
50
|
+
order: number;
|
|
51
|
+
length: number;
|
|
52
|
+
quantity: string;
|
|
53
|
+
unit_price: string;
|
|
54
|
+
total_amount: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface Order {
|
|
58
|
+
id: number;
|
|
59
|
+
status: OrderStatus;
|
|
60
|
+
currency: Currency;
|
|
61
|
+
orderitem_set: OrderItem[];
|
|
62
|
+
discountitem_set: [
|
|
63
|
+
{
|
|
64
|
+
amount: string;
|
|
65
|
+
cancel_amount: string;
|
|
66
|
+
code: null;
|
|
67
|
+
created_date: string;
|
|
68
|
+
modified_date: string;
|
|
69
|
+
name: string;
|
|
70
|
+
offer_type: string;
|
|
71
|
+
order: number;
|
|
72
|
+
pk: number;
|
|
73
|
+
promotion: number;
|
|
74
|
+
session_offer_type: null;
|
|
75
|
+
}
|
|
76
|
+
];
|
|
77
|
+
is_cancelled: boolean;
|
|
78
|
+
is_cancellable: boolean;
|
|
79
|
+
is_refundable: boolean;
|
|
80
|
+
shipping_address: Address;
|
|
81
|
+
billing_address: Address;
|
|
82
|
+
client_type: string;
|
|
83
|
+
payment_option: PaymentOption;
|
|
84
|
+
amount_without_discount: string;
|
|
85
|
+
is_payable: boolean;
|
|
86
|
+
created_date: string;
|
|
87
|
+
modified_date: string;
|
|
88
|
+
number: string;
|
|
89
|
+
amount: string;
|
|
90
|
+
discount_amount: string;
|
|
91
|
+
shipping_amount: string;
|
|
92
|
+
refund_amount: string;
|
|
93
|
+
discount_refund_amount: string;
|
|
94
|
+
shipping_refund_amount: string;
|
|
95
|
+
remote_addr: string;
|
|
96
|
+
has_gift_box: boolean;
|
|
97
|
+
language_code: string;
|
|
98
|
+
user_email: string;
|
|
99
|
+
shipping_option_slug: string;
|
|
100
|
+
payment_option_slug: string;
|
|
101
|
+
installment_count: 1;
|
|
102
|
+
installment_interest_amount: string;
|
|
103
|
+
user: number;
|
|
104
|
+
basket: number;
|
|
105
|
+
shipping_option: number;
|
|
106
|
+
tracking_number: string;
|
|
107
|
+
tracking_url: string;
|
|
108
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Category } from './category';
|
|
2
|
+
|
|
3
|
+
type Values<T> = T[keyof T];
|
|
4
|
+
|
|
5
|
+
export interface Product {
|
|
6
|
+
absolute_url: string;
|
|
7
|
+
attribute_set: number;
|
|
8
|
+
attributes: {
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
};
|
|
11
|
+
attributes_kwargs: any;
|
|
12
|
+
base_code: string;
|
|
13
|
+
basket_offers: {
|
|
14
|
+
kwargs: { show_benefit_products: boolean };
|
|
15
|
+
label: string;
|
|
16
|
+
listing_kwargs: {
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
};
|
|
19
|
+
pk: number;
|
|
20
|
+
};
|
|
21
|
+
currency_type: string;
|
|
22
|
+
data_source: null;
|
|
23
|
+
extra_attributes: {
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
};
|
|
26
|
+
form_schema: null;
|
|
27
|
+
image?: string;
|
|
28
|
+
in_stock: boolean;
|
|
29
|
+
is_ready_to_basket: boolean;
|
|
30
|
+
name: string;
|
|
31
|
+
pk: number;
|
|
32
|
+
price: string;
|
|
33
|
+
price_type: string;
|
|
34
|
+
product_type: string;
|
|
35
|
+
productimage_set: Array<{
|
|
36
|
+
created_date: Date;
|
|
37
|
+
image: string;
|
|
38
|
+
order: number;
|
|
39
|
+
pk: number;
|
|
40
|
+
specialimage_set: Array<{
|
|
41
|
+
[key: string]: any;
|
|
42
|
+
}>;
|
|
43
|
+
status: string;
|
|
44
|
+
}>;
|
|
45
|
+
productvideo_set: Array<{
|
|
46
|
+
[key: string]: any;
|
|
47
|
+
}>;
|
|
48
|
+
retail_price: string;
|
|
49
|
+
sku: string;
|
|
50
|
+
stock: number;
|
|
51
|
+
unit_type: string;
|
|
52
|
+
created_date: string;
|
|
53
|
+
modified_date: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
quantity: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface FavoriteItem {
|
|
59
|
+
pk: number;
|
|
60
|
+
product: Product;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type VariantOption = {
|
|
64
|
+
in_stock: boolean;
|
|
65
|
+
is_selectable: boolean;
|
|
66
|
+
is_selectable_without_stock: boolean;
|
|
67
|
+
is_selected: boolean;
|
|
68
|
+
label: string;
|
|
69
|
+
order: string;
|
|
70
|
+
product: Product;
|
|
71
|
+
value: string;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export type StockResultType = [
|
|
75
|
+
{
|
|
76
|
+
address: string;
|
|
77
|
+
latitude: string;
|
|
78
|
+
longitude: string;
|
|
79
|
+
name: string;
|
|
80
|
+
stock: string;
|
|
81
|
+
store_hours: Array<any>;
|
|
82
|
+
}
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
export type FindInStoreFormType = {
|
|
86
|
+
store: string;
|
|
87
|
+
variant: string;
|
|
88
|
+
productPk: string;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export interface ProductCategoryResult {
|
|
92
|
+
count: number;
|
|
93
|
+
next: string;
|
|
94
|
+
previous: null | string;
|
|
95
|
+
results: Category[];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type VariantType = {
|
|
99
|
+
attribute_key: Values<any>;
|
|
100
|
+
attribute_name: string;
|
|
101
|
+
options: Array<VariantOption>;
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export type ProductResult = {
|
|
105
|
+
in_stock: boolean;
|
|
106
|
+
product: Product;
|
|
107
|
+
group_products?: Array<Product>;
|
|
108
|
+
selected_variant?: Product | null;
|
|
109
|
+
variants?: Array<VariantType>;
|
|
110
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ImageType } from './misc';
|
|
2
|
+
import { Product } from './product';
|
|
3
|
+
|
|
4
|
+
export type WidgetType = {
|
|
5
|
+
kwargs?: {
|
|
6
|
+
data_type?: 'nested';
|
|
7
|
+
value?: {
|
|
8
|
+
image?: ImageType;
|
|
9
|
+
mobile_image?: ImageType;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
value?: {
|
|
13
|
+
alt?: string;
|
|
14
|
+
image?: string;
|
|
15
|
+
mobile_image?: string;
|
|
16
|
+
url?: string;
|
|
17
|
+
item_slug?: string;
|
|
18
|
+
title?: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type WidgetResultType<T> = {
|
|
23
|
+
attributes?: T;
|
|
24
|
+
products?: Array<Product>;
|
|
25
|
+
name?: string;
|
|
26
|
+
slug?: string;
|
|
27
|
+
template?: string;
|
|
28
|
+
};
|
package/types/gtm.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface GTMEvent {
|
|
2
|
+
Action: string;
|
|
3
|
+
Category?: string;
|
|
4
|
+
Label: string;
|
|
5
|
+
Value?: number;
|
|
6
|
+
ecommerce: Record<string, any>;
|
|
7
|
+
event: `ee${string}`;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface GTMUserType {
|
|
11
|
+
pk: number;
|
|
12
|
+
hashedEmail: string;
|
|
13
|
+
dateJoined: string;
|
|
14
|
+
gender: string;
|
|
15
|
+
emailAllowed: boolean;
|
|
16
|
+
}
|
package/types/index.ts
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { LocaleUrlStrategy } from '../localization';
|
|
2
|
+
import { PzNextRequest } from '../middlewares';
|
|
3
|
+
|
|
4
|
+
declare global {
|
|
5
|
+
export interface Window {
|
|
6
|
+
dataLayer: Record<string, any>[];
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export * from './commerce';
|
|
11
|
+
export * from './gtm';
|
|
12
|
+
|
|
13
|
+
export interface Locale {
|
|
14
|
+
label: string;
|
|
15
|
+
/**
|
|
16
|
+
* Lowercased locale value in `ISO 639-1` format or including country code in `ISO 3166-1 alpha-2` format.
|
|
17
|
+
*
|
|
18
|
+
* -- If you use uppercase characters, it will be considered as lowercase.
|
|
19
|
+
*
|
|
20
|
+
* ***
|
|
21
|
+
* @example
|
|
22
|
+
* value: 'en'
|
|
23
|
+
* value: 'en-us'
|
|
24
|
+
* value: 'tr'
|
|
25
|
+
*
|
|
26
|
+
* @see https://en.wikipedia.org/wiki/ISO_639-1
|
|
27
|
+
* @see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
|
|
28
|
+
*/
|
|
29
|
+
value: string;
|
|
30
|
+
localePath?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Corresponding Commerce API value for fetching data. It will be used in `Accept-Language` header.
|
|
33
|
+
*/
|
|
34
|
+
apiValue: string;
|
|
35
|
+
rtl?: boolean;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface Currency {
|
|
39
|
+
/**
|
|
40
|
+
* It will be used for displaying currency in currency switcher.
|
|
41
|
+
* Can be symbol, code, etc.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* label: '$'
|
|
45
|
+
* label: '€'
|
|
46
|
+
* label: 'USD'
|
|
47
|
+
* label: 'US Dollar'
|
|
48
|
+
* label: '$ - USD'
|
|
49
|
+
*/
|
|
50
|
+
label: string;
|
|
51
|
+
/**
|
|
52
|
+
* Lowercased currency code in `ISO 4217` format.
|
|
53
|
+
*
|
|
54
|
+
* It should match with one of the values returned from Commerce API.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* code: 'usd'
|
|
58
|
+
* code: 'eur'
|
|
59
|
+
* code: 'try'
|
|
60
|
+
*
|
|
61
|
+
* @see https://en.wikipedia.org/wiki/ISO_4217
|
|
62
|
+
*/
|
|
63
|
+
code: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface Settings {
|
|
67
|
+
commerceUrl: string;
|
|
68
|
+
redis: {
|
|
69
|
+
defaultExpirationTime: number;
|
|
70
|
+
};
|
|
71
|
+
commonProductAttributes: Array<{
|
|
72
|
+
translationKey: string;
|
|
73
|
+
key: string;
|
|
74
|
+
}>;
|
|
75
|
+
localization: {
|
|
76
|
+
locales: Locale[];
|
|
77
|
+
currencies: Array<Currency>;
|
|
78
|
+
/**
|
|
79
|
+
* Default locale value in `ISO 639-1` format or including country code in `ISO 3166-1 alpha-2` format.
|
|
80
|
+
*
|
|
81
|
+
* It will be used for redirections and fallbacks.
|
|
82
|
+
*
|
|
83
|
+
* It should be one of the values in `locales` array.
|
|
84
|
+
*/
|
|
85
|
+
defaultLocaleValue: string;
|
|
86
|
+
/**
|
|
87
|
+
* Determines url behavior according to locale.
|
|
88
|
+
*
|
|
89
|
+
* Available options:
|
|
90
|
+
* - LocaleUrlStrategy.HideDefaultLocale
|
|
91
|
+
* - LocaleUrlStrategy.HideAllLocales
|
|
92
|
+
* - LocaleUrlStrategy.ShowAllLocales
|
|
93
|
+
*
|
|
94
|
+
* @default LocaleUrlStrategy.HideDefaultLocale
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* // Example configuration
|
|
98
|
+
* locales: [{ value: 'en'}, { value: 'tr' }]
|
|
99
|
+
* defaultLocaleValue: 'en'
|
|
100
|
+
* // -------------------------------
|
|
101
|
+
*
|
|
102
|
+
* LocaleUrlStrategy.HideDefaultLocale:
|
|
103
|
+
* en -> "/women"
|
|
104
|
+
* tr -> "/tr/women"
|
|
105
|
+
*
|
|
106
|
+
* LocaleUrlStrategy.ShowAllLocales:
|
|
107
|
+
* en -> "/en/women"
|
|
108
|
+
* tr -> "/tr/women"
|
|
109
|
+
*
|
|
110
|
+
* LocaleUrlStrategy.HideAllLocales:
|
|
111
|
+
* en -> "/women"
|
|
112
|
+
* tr -> "/women"
|
|
113
|
+
*/
|
|
114
|
+
localeUrlStrategy?: LocaleUrlStrategy;
|
|
115
|
+
redirectToDefaultLocale?: boolean;
|
|
116
|
+
defaultCurrencyCode: string;
|
|
117
|
+
/**
|
|
118
|
+
* The default behavior of `getActiveCurrencyCode` function is to get active currency code from cookie named `pz-currency`.
|
|
119
|
+
*
|
|
120
|
+
* You can use this function to override existing and get currency code from cookie, header, url, etc.
|
|
121
|
+
*
|
|
122
|
+
* If return value does not match with any currency code in `currencies` array, default currency code will be used.
|
|
123
|
+
*
|
|
124
|
+
* @param req - Incoming request. You can use this to get cookie, header, url, etc.
|
|
125
|
+
* @param locale - Active locale value. E.g. 'en', 'tr', 'en-us', 'tr-tr'
|
|
126
|
+
* @param defaultCurrencyCode - Default currency code in `ISO 4217` format. E.g. 'usd', 'eur', 'try'
|
|
127
|
+
* @returns Currency code in `ISO 4217` format. E.g. 'usd', 'eur', 'try'
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* getActiveCurrencyCode: ({ req, locale, defaultCurrencyCode }) => {
|
|
131
|
+
* const [, countryCode] = locale.split('-');
|
|
132
|
+
*
|
|
133
|
+
* if (countryCode === 'ae') {
|
|
134
|
+
* return 'aed';
|
|
135
|
+
* } else if (countryCode === 'qa') {
|
|
136
|
+
* return 'qar';
|
|
137
|
+
* }
|
|
138
|
+
*
|
|
139
|
+
* return defaultCurrencyCode;
|
|
140
|
+
* }
|
|
141
|
+
*/
|
|
142
|
+
getActiveCurrencyCode?: ({
|
|
143
|
+
req,
|
|
144
|
+
locale,
|
|
145
|
+
defaultCurrencyCode
|
|
146
|
+
}: {
|
|
147
|
+
req: PzNextRequest;
|
|
148
|
+
locale: string;
|
|
149
|
+
defaultCurrencyCode: string;
|
|
150
|
+
}) => string;
|
|
151
|
+
};
|
|
152
|
+
rewrites?: Array<{
|
|
153
|
+
source: string;
|
|
154
|
+
destination: string;
|
|
155
|
+
}>;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface CacheOptions {
|
|
159
|
+
cache?: boolean;
|
|
160
|
+
expire?: number;
|
|
161
|
+
useProxy?: boolean;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface ClientRequestOptions {
|
|
165
|
+
useTrailingSlash?: boolean;
|
|
166
|
+
useFormData?: boolean;
|
|
167
|
+
accept?: string;
|
|
168
|
+
contentType?: string;
|
|
169
|
+
responseType?: 'json' | 'text';
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export type CDNOptions = {
|
|
173
|
+
width?: number;
|
|
174
|
+
height?: number;
|
|
175
|
+
quality?: number;
|
|
176
|
+
crop?: 'center' | 'top' | 'bottom' | 'left' | 'right';
|
|
177
|
+
upscale?: boolean;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export type ImageOptions = CDNOptions & {
|
|
181
|
+
sources?: Array<{ media: string; options: CDNOptions }>;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export type Translations = { [key: string]: object };
|
|
185
|
+
|
|
186
|
+
export interface PageProps<T = any> {
|
|
187
|
+
params: T;
|
|
188
|
+
searchParams: URLSearchParams;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export interface LayoutProps<T = any> extends PageProps<T> {
|
|
192
|
+
children: React.ReactNode;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
export interface RootLayoutProps<
|
|
196
|
+
T = { commerce: string; locale: string; currency: string }
|
|
197
|
+
> extends LayoutProps<T> {
|
|
198
|
+
translations: Translations;
|
|
199
|
+
locale: Locale & {
|
|
200
|
+
isoCode: string;
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export interface AuthError {
|
|
205
|
+
type: string;
|
|
206
|
+
data?: any;
|
|
207
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import NextAuth from 'next-auth';
|
|
2
|
+
|
|
3
|
+
declare module 'next-auth' {
|
|
4
|
+
interface User {
|
|
5
|
+
id?: number;
|
|
6
|
+
pk: number;
|
|
7
|
+
firstName: string;
|
|
8
|
+
lastName: string;
|
|
9
|
+
email: string;
|
|
10
|
+
phone: string;
|
|
11
|
+
emailAllowed: boolean;
|
|
12
|
+
smsAllowed: boolean;
|
|
13
|
+
dateJoined: string;
|
|
14
|
+
lastLogin: string;
|
|
15
|
+
dateOfBirth: string;
|
|
16
|
+
token: string;
|
|
17
|
+
hashedEmail: string;
|
|
18
|
+
gender: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface Session {
|
|
22
|
+
user: User;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import Settings from 'settings';
|
|
2
|
+
import { ServerVariables } from './server-variables';
|
|
3
|
+
import logger from '../utils/log';
|
|
4
|
+
|
|
5
|
+
export enum FetchResponseType {
|
|
6
|
+
JSON = 'json',
|
|
7
|
+
TEXT = 'text'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const appFetch = async <T>(
|
|
11
|
+
url: RequestInfo,
|
|
12
|
+
init: RequestInit = {},
|
|
13
|
+
responseType = FetchResponseType.JSON
|
|
14
|
+
) => {
|
|
15
|
+
let response: T;
|
|
16
|
+
let status: number;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const commerceUrl = Settings.commerceUrl;
|
|
20
|
+
const currentLocale = Settings.localization.locales.find(
|
|
21
|
+
(locale) => locale.value === ServerVariables.locale
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
if (commerceUrl === 'default') {
|
|
25
|
+
logger.error('Commerce URL is not set. Current value is "default"');
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const requestURL = `${decodeURIComponent(commerceUrl)}${url}`;
|
|
30
|
+
|
|
31
|
+
init.headers = {
|
|
32
|
+
...(init.headers ?? {}),
|
|
33
|
+
'Accept-Language': currentLocale.apiValue,
|
|
34
|
+
'x-currency': ServerVariables.currency
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
init.next = {
|
|
38
|
+
revalidate: 60
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
logger.debug(`FETCH START ${url}`, { requestURL, init });
|
|
42
|
+
const req = await fetch(requestURL, init);
|
|
43
|
+
status = req.status;
|
|
44
|
+
logger.debug(`FETCH END ${url}`, { status: req.status });
|
|
45
|
+
|
|
46
|
+
const rawData = await req.text();
|
|
47
|
+
|
|
48
|
+
if (responseType === FetchResponseType.JSON) {
|
|
49
|
+
response = JSON.parse(rawData);
|
|
50
|
+
} else {
|
|
51
|
+
response = rawData as unknown as T;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
logger.trace(`FETCH RESPONSE`, { url, response });
|
|
55
|
+
} catch (error) {
|
|
56
|
+
logger.error(`FETCH FAILED`, { url, status, error });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return response;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default appFetch;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import logger from './log';
|
|
2
|
+
|
|
3
|
+
export const generateCommerceSearchParams = (searchParams?: URLSearchParams) => {
|
|
4
|
+
if (!searchParams) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const urlSerchParams = new URLSearchParams(searchParams);
|
|
9
|
+
|
|
10
|
+
Object.entries(searchParams).forEach(([key, value]) => {
|
|
11
|
+
if (typeof value === 'object') {
|
|
12
|
+
urlSerchParams.delete(key);
|
|
13
|
+
value.forEach((val) => {
|
|
14
|
+
urlSerchParams.append(key, val);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
logger.debug(`generateCommerceSearchParams: ${urlSerchParams.toString()}`);
|
|
20
|
+
|
|
21
|
+
return `?${urlSerchParams.toString()}`;
|
|
22
|
+
};
|