@akinon/next 1.114.0-snapshot-ZERO-3890-20251209002835 → 1.115.0-rc.22
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/CHANGELOG.md +18 -3
- package/components/plugin-module.tsx +5 -19
- package/data/urls.ts +5 -1
- package/hocs/server/with-segment-defaults.tsx +5 -2
- package/lib/cache-handler.mjs +1 -1
- package/package.json +2 -2
- package/plugins.d.ts +10 -0
- package/plugins.js +2 -3
- package/types/index.ts +6 -0
- package/utils/app-fetch.ts +2 -2
- package/utils/mobile-3d-iframe.ts +8 -2
- package/utils/redirection-iframe.ts +8 -2
- package/api/product-categories.ts +0 -53
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
# @akinon/next
|
|
2
2
|
|
|
3
|
-
## 1.
|
|
3
|
+
## 1.115.0-rc.22
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
7
|
+
- d2c0e759: ZERO-3684: Handle cross-origin iframe access in iframeURLChange function
|
|
8
|
+
- b55acb76: ZERO-2577: Fix pagination bug and update usePagination hook and ensure pagination controls rendering correctly
|
|
9
|
+
- 143be2b9: ZERO-3457: Crop styles are customizable and logic improved for rendering similar products modal
|
|
10
|
+
- 9f8cd3bc: ZERO-3449: AI Search Active Filters & Crop Style changes have been implemented
|
|
11
|
+
- d99a6a7d: ZERO-3457_1: Fixed the settings prop and made sure everything is customizable.
|
|
12
|
+
- 7056203a: ZERO-3875: removed shared_tags through stripTags function for unused keys
|
|
13
|
+
- 4de5303c: ZERO-2504: add cookie filter to api client request
|
|
14
|
+
- 95b139dc: ZERO-3795: Remove duplicate entry for SavedCard in PluginComponents map
|
|
15
|
+
|
|
16
|
+
## 1.114.0
|
|
17
|
+
|
|
18
|
+
### Minor Changes
|
|
19
|
+
|
|
20
|
+
- 65d3b862: ZERO-3054: Update headers in appFetch
|
|
21
|
+
- 43c182ee: ZERO-3054: Update Redis variable checks to conditionally include CACHE_SECRET
|
|
22
|
+
- eeb20bea: Revert "ZERO-3054: Refactor cache handler to use custom Redis handler and implement key hashing"
|
|
23
|
+
- fdd255ee: ZERO-3054: Refactor cache handler to use custom Redis handler and implement key hashing
|
|
9
24
|
|
|
10
25
|
## 1.113.0
|
|
11
26
|
|
|
@@ -24,9 +24,7 @@ enum Plugin {
|
|
|
24
24
|
FlowPayment = 'pz-flow-payment',
|
|
25
25
|
VirtualTryOn = 'pz-virtual-try-on',
|
|
26
26
|
Hepsipay = 'pz-hepsipay',
|
|
27
|
-
MasterpassRest = 'pz-masterpass-rest'
|
|
28
|
-
SimilarProducts = 'pz-similar-products',
|
|
29
|
-
Haso = 'pz-haso'
|
|
27
|
+
MasterpassRest = 'pz-masterpass-rest'
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
export enum Component {
|
|
@@ -57,15 +55,7 @@ export enum Component {
|
|
|
57
55
|
IyzicoSavedCard = 'IyzicoSavedCardOption',
|
|
58
56
|
Hepsipay = 'Hepsipay',
|
|
59
57
|
FlowPayment = 'FlowPayment',
|
|
60
|
-
MasterpassRest = 'MasterpassRestOption'
|
|
61
|
-
SimilarProductsModal = 'SimilarProductsModal',
|
|
62
|
-
SimilarProductsFilterSidebar = 'SimilarProductsFilterSidebar',
|
|
63
|
-
SimilarProductsResultsGrid = 'SimilarProductsResultsGrid',
|
|
64
|
-
SimilarProductsPlugin = 'SimilarProductsPlugin',
|
|
65
|
-
ProductImageSearchFeature = 'ProductImageSearchFeature',
|
|
66
|
-
ImageSearchButton = 'ImageSearchButton',
|
|
67
|
-
HeaderImageSearchFeature = 'HeaderImageSearchFeature',
|
|
68
|
-
HasoPaymentGateway = 'HasoPaymentGateway'
|
|
58
|
+
MasterpassRest = 'MasterpassRestOption'
|
|
69
59
|
}
|
|
70
60
|
|
|
71
61
|
const PluginComponents = new Map([
|
|
@@ -111,7 +101,6 @@ const PluginComponents = new Map([
|
|
|
111
101
|
]
|
|
112
102
|
],
|
|
113
103
|
[Plugin.SavedCard, [Component.SavedCard, Component.IyzicoSavedCard]],
|
|
114
|
-
[Plugin.SavedCard, [Component.SavedCard]],
|
|
115
104
|
[Plugin.FlowPayment, [Component.FlowPayment]],
|
|
116
105
|
[
|
|
117
106
|
Plugin.VirtualTryOn,
|
|
@@ -119,8 +108,7 @@ const PluginComponents = new Map([
|
|
|
119
108
|
],
|
|
120
109
|
[Plugin.Hepsipay, [Component.Hepsipay]],
|
|
121
110
|
[Plugin.Hepsipay, [Component.Hepsipay]],
|
|
122
|
-
[Plugin.MasterpassRest, [Component.MasterpassRest]]
|
|
123
|
-
[Plugin.Haso, [Component.HasoPaymentGateway]]
|
|
111
|
+
[Plugin.MasterpassRest, [Component.MasterpassRest]]
|
|
124
112
|
]);
|
|
125
113
|
|
|
126
114
|
const getPlugin = (component: Component) => {
|
|
@@ -185,6 +173,8 @@ export default function PluginModule({
|
|
|
185
173
|
promise = import(`${'@akinon/pz-multi-basket'}`);
|
|
186
174
|
} else if (plugin === Plugin.SavedCard) {
|
|
187
175
|
promise = import(`${'@akinon/pz-saved-card'}`);
|
|
176
|
+
} else if (plugin === Plugin.SimilarProducts) {
|
|
177
|
+
promise = import(`${'@akinon/pz-similar-products'}`);
|
|
188
178
|
} else if (plugin === Plugin.Hepsipay) {
|
|
189
179
|
promise = import(`${'@akinon/pz-hepsipay'}`);
|
|
190
180
|
} else if (plugin === Plugin.FlowPayment) {
|
|
@@ -193,10 +183,6 @@ export default function PluginModule({
|
|
|
193
183
|
promise = import(`${'@akinon/pz-virtual-try-on'}`);
|
|
194
184
|
} else if (plugin === Plugin.MasterpassRest) {
|
|
195
185
|
promise = import(`${'@akinon/pz-masterpass-rest'}`);
|
|
196
|
-
} else if (plugin === Plugin.SimilarProducts) {
|
|
197
|
-
promise = import(`${'@akinon/pz-similar-products'}`);
|
|
198
|
-
} else if (plugin === Plugin.Haso) {
|
|
199
|
-
promise = import(`${'@akinon/pz-haso'}`);
|
|
200
186
|
}
|
|
201
187
|
} catch (error) {
|
|
202
188
|
logger.error(error);
|
package/data/urls.ts
CHANGED
|
@@ -183,7 +183,11 @@ export const product = {
|
|
|
183
183
|
breadcrumbUrl: (menuitemmodel: string) =>
|
|
184
184
|
`/menus/generate_breadcrumb/?item=${menuitemmodel}&generator_name=menu_item`,
|
|
185
185
|
bundleProduct: (productPk: string, queryString: string) =>
|
|
186
|
-
`/bundle-product/${productPk}/?${queryString}
|
|
186
|
+
`/bundle-product/${productPk}/?${queryString}`,
|
|
187
|
+
similarProducts: (params?: string) =>
|
|
188
|
+
`/similar-products${params ? `?${params}` : ''}`,
|
|
189
|
+
similarProductsList: (params?: string) =>
|
|
190
|
+
`/similar-product-list${params ? `?${params}` : ''}`
|
|
187
191
|
};
|
|
188
192
|
|
|
189
193
|
export const wishlist = {
|
|
@@ -72,10 +72,13 @@ const addRootLayoutProps = async (componentProps: RootLayoutProps) => {
|
|
|
72
72
|
const checkRedisVariables = () => {
|
|
73
73
|
const requiredVariableValues = [
|
|
74
74
|
process.env.CACHE_HOST,
|
|
75
|
-
process.env.CACHE_PORT
|
|
76
|
-
process.env.CACHE_SECRET
|
|
75
|
+
process.env.CACHE_PORT
|
|
77
76
|
];
|
|
78
77
|
|
|
78
|
+
if (!settings.usePrettyUrlRoute) {
|
|
79
|
+
requiredVariableValues.push(process.env.CACHE_SECRET);
|
|
80
|
+
}
|
|
81
|
+
|
|
79
82
|
if (
|
|
80
83
|
!requiredVariableValues.every((v) => v) &&
|
|
81
84
|
process.env.NODE_ENV === 'production'
|
package/lib/cache-handler.mjs
CHANGED
|
@@ -518,8 +518,8 @@ CacheHandler.onCreation(async () => {
|
|
|
518
518
|
localSetResult = { status: 'fulfilled' };
|
|
519
519
|
} catch (error) {
|
|
520
520
|
localSetResult = { status: 'rejected', reason: error };
|
|
521
|
+
return localSetResult;
|
|
521
522
|
}
|
|
522
|
-
return localSetResult;
|
|
523
523
|
},
|
|
524
524
|
delete: async (key, context) => {
|
|
525
525
|
const vKey = versionKey(key);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/next",
|
|
3
3
|
"description": "Core package for Project Zero Next",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.115.0-rc.22",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"set-cookie-parser": "2.6.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@akinon/eslint-plugin-projectzero": "1.
|
|
38
|
+
"@akinon/eslint-plugin-projectzero": "1.115.0-rc.22",
|
|
39
39
|
"@babel/core": "7.26.10",
|
|
40
40
|
"@babel/preset-env": "7.26.9",
|
|
41
41
|
"@babel/preset-typescript": "7.27.0",
|
package/plugins.d.ts
CHANGED
|
@@ -37,6 +37,16 @@ declare module '@akinon/pz-cybersource-uc/src/redux/middleware' {
|
|
|
37
37
|
export default middleware as any;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
declare module '@akinon/pz-apple-pay' {}
|
|
41
|
+
|
|
42
|
+
declare module '@akinon/pz-similar-products' {
|
|
43
|
+
export const SimilarProductsModal: any;
|
|
44
|
+
export const SimilarProductsFilterSidebar: any;
|
|
45
|
+
export const SimilarProductsResultsGrid: any;
|
|
46
|
+
export const SimilarProductsPlugin: any;
|
|
47
|
+
export const SimilarProductsButtonPlugin: any;
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
declare module '@akinon/pz-cybersource-uc/src/redux/reducer' {
|
|
41
51
|
export default reducer as any;
|
|
42
52
|
}
|
package/plugins.js
CHANGED
|
@@ -16,11 +16,10 @@ module.exports = [
|
|
|
16
16
|
'pz-tabby-extension',
|
|
17
17
|
'pz-apple-pay',
|
|
18
18
|
'pz-tamara-extension',
|
|
19
|
+
'pz-similar-products',
|
|
19
20
|
'pz-cybersource-uc',
|
|
20
21
|
'pz-hepsipay',
|
|
21
22
|
'pz-flow-payment',
|
|
22
23
|
'pz-virtual-try-on',
|
|
23
|
-
'pz-masterpass-rest'
|
|
24
|
-
'pz-similar-products',
|
|
25
|
-
'pz-haso'
|
|
24
|
+
'pz-masterpass-rest'
|
|
26
25
|
];
|
package/types/index.ts
CHANGED
|
@@ -83,6 +83,12 @@ export interface Settings {
|
|
|
83
83
|
};
|
|
84
84
|
usePrettyUrlRoute?: boolean;
|
|
85
85
|
commerceUrl: string;
|
|
86
|
+
/**
|
|
87
|
+
* This option allows you to track Sentry events on the client side, in addition to server and edge environments.
|
|
88
|
+
*
|
|
89
|
+
* It overrides process.env.NEXT_PUBLIC_SENTRY_DSN and process.env.SENTRY_DSN.
|
|
90
|
+
*/
|
|
91
|
+
sentryDsn?: string;
|
|
86
92
|
redis: {
|
|
87
93
|
defaultExpirationTime: number;
|
|
88
94
|
};
|
package/utils/app-fetch.ts
CHANGED
|
@@ -43,12 +43,12 @@ const appFetch = async <T>({
|
|
|
43
43
|
const requestURL = `${decodeURIComponent(commerceUrl)}${url}`;
|
|
44
44
|
|
|
45
45
|
init.headers = {
|
|
46
|
+
cookie: nextCookies.toString(),
|
|
46
47
|
...(init.headers ?? {}),
|
|
47
48
|
...(ServerVariables.globalHeaders ?? {}),
|
|
48
49
|
'Accept-Language': currentLocale.apiValue,
|
|
49
50
|
'x-currency': currency,
|
|
50
|
-
'x-forwarded-for': ip
|
|
51
|
-
cookie: nextCookies.toString()
|
|
51
|
+
'x-forwarded-for': ip
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
init.next = {
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
const iframeURLChange = (iframe, callback) => {
|
|
2
2
|
iframe.addEventListener('load', () => {
|
|
3
3
|
setTimeout(() => {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
try {
|
|
5
|
+
if (iframe?.contentWindow?.location) {
|
|
6
|
+
const iframeLocation = iframe.contentWindow.location;
|
|
7
|
+
|
|
8
|
+
callback(iframeLocation);
|
|
9
|
+
}
|
|
10
|
+
} catch (error) {
|
|
11
|
+
// Expected: browser blocks cross-origin iframe access for security
|
|
6
12
|
}
|
|
7
13
|
}, 0);
|
|
8
14
|
});
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
const iframeURLChange = (iframe, callback) => {
|
|
2
2
|
iframe.addEventListener('load', () => {
|
|
3
3
|
setTimeout(() => {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
try {
|
|
5
|
+
if (iframe?.contentWindow?.location) {
|
|
6
|
+
const iframeLocation = iframe.contentWindow.location;
|
|
7
|
+
|
|
8
|
+
callback(iframeLocation);
|
|
9
|
+
}
|
|
10
|
+
} catch (error) {
|
|
11
|
+
// Expected: browser blocks cross-origin iframe access for security
|
|
6
12
|
}
|
|
7
13
|
}, 0);
|
|
8
14
|
});
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
-
import { getProductData } from '@akinon/next/data/server';
|
|
3
|
-
|
|
4
|
-
export async function GET(request: NextRequest) {
|
|
5
|
-
try {
|
|
6
|
-
const { searchParams } = new URL(request.url);
|
|
7
|
-
const pksParam = searchParams.get('pks');
|
|
8
|
-
|
|
9
|
-
if (!pksParam) {
|
|
10
|
-
return NextResponse.json(
|
|
11
|
-
{ error: 'pks parameter required' },
|
|
12
|
-
{ status: 400 }
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const pks = pksParam.split(',').map(Number).filter(Boolean);
|
|
17
|
-
|
|
18
|
-
if (pks.length === 0) {
|
|
19
|
-
return NextResponse.json({ error: 'Invalid pks' }, { status: 400 });
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const results = await Promise.all(
|
|
23
|
-
pks.map(async (pk) => {
|
|
24
|
-
try {
|
|
25
|
-
const { breadcrumbData } = await getProductData({ pk });
|
|
26
|
-
|
|
27
|
-
const categoryIds =
|
|
28
|
-
breadcrumbData
|
|
29
|
-
?.map((item: any) => item.extra_context?.attributes?.category_id)
|
|
30
|
-
.filter(Boolean) || [];
|
|
31
|
-
|
|
32
|
-
return { pk, categoryIds };
|
|
33
|
-
} catch (error) {
|
|
34
|
-
console.error(`Error fetching product ${pk}:`, error);
|
|
35
|
-
return { pk, categoryIds: [] };
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
const mapping: Record<string, number[]> = {};
|
|
41
|
-
results.forEach(({ pk, categoryIds }) => {
|
|
42
|
-
mapping[String(pk)] = categoryIds;
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
return NextResponse.json(mapping);
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.error('Error in product-categories API:', error);
|
|
48
|
-
return NextResponse.json(
|
|
49
|
-
{ error: 'Internal server error' },
|
|
50
|
-
{ status: 500 }
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
}
|