@akinon/next 1.23.0 → 1.24.0-rc.1
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 +24 -0
- package/api/auth.ts +11 -0
- package/data/client/address.ts +8 -6
- package/data/client/wishlist.ts +4 -2
- package/data/server/category.ts +10 -2
- package/data/server/list.ts +1 -1
- package/hooks/use-pagination.ts +0 -4
- package/package.json +2 -2
- package/plugins.d.ts +8 -0
- package/redux/reducers/index.ts +3 -1
- package/sentry/index.ts +20 -14
- package/types/index.ts +6 -0
- package/utils/app-fetch.ts +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @akinon/next
|
|
2
2
|
|
|
3
|
+
## 1.24.0-rc.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9b10323: ZERO-2440: Add type declarations for @akinon/pz-otp modules
|
|
8
|
+
|
|
9
|
+
## 1.24.0-rc.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 8bc6085: ZERO-2472: RTK Query Invalidate
|
|
14
|
+
- 02a3c58: ZERO-2460: Breadcrumb checks for undefined values
|
|
15
|
+
- 0181251: ZERO-2440: move otp popup state to redux
|
|
16
|
+
- 07cc81a: Add infinite and more types to pagination
|
|
17
|
+
- 8d6caba: ZERO-2434: enhance error handling and logging in appFetch function
|
|
18
|
+
- b4452e9: ZERO-2463: Refactor Sentry initialization and add Sentry DSN option to settings
|
|
19
|
+
- b2da5e4: Revert ZERO-2435
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- da1e501: ZERO-2296: Fix ROUTES import
|
|
24
|
+
- 2e44646: ZERO-2434: Fix category URL in getCategoryDataHandler function
|
|
25
|
+
- 2e9476c: ZERO-2434: remove error throwing in appFetch
|
|
26
|
+
|
|
3
27
|
## 1.23.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
package/api/auth.ts
CHANGED
|
@@ -220,6 +220,17 @@ const nextAuthOptions = (req: NextApiRequest, res: NextApiResponse) => {
|
|
|
220
220
|
pages: {
|
|
221
221
|
signIn: ROUTES.AUTH,
|
|
222
222
|
error: ROUTES.AUTH
|
|
223
|
+
},
|
|
224
|
+
cookies: {
|
|
225
|
+
sessionToken: {
|
|
226
|
+
name: `__Secure-next-auth.session-token`,
|
|
227
|
+
options: {
|
|
228
|
+
httpOnly: true,
|
|
229
|
+
sameSite: 'none',
|
|
230
|
+
path: '/',
|
|
231
|
+
secure: true
|
|
232
|
+
}
|
|
233
|
+
}
|
|
223
234
|
}
|
|
224
235
|
};
|
|
225
236
|
};
|
package/data/client/address.ts
CHANGED
|
@@ -32,10 +32,12 @@ const addressApi = api.injectEndpoints({
|
|
|
32
32
|
query: () => buildClientRequestUrl(address.getRetailStore)
|
|
33
33
|
}),
|
|
34
34
|
getRetailStoreCities: builder.query<GetResponse<any>, string>({
|
|
35
|
-
query: (country) =>
|
|
35
|
+
query: (country) =>
|
|
36
|
+
buildClientRequestUrl(address.getRetailStoreCities(country))
|
|
36
37
|
}),
|
|
37
38
|
getRetailStoreTownships: builder.query<GetResponse<any>, string>({
|
|
38
|
-
query: (city) =>
|
|
39
|
+
query: (city) =>
|
|
40
|
+
buildClientRequestUrl(address.getRetailStoreTownships(city))
|
|
39
41
|
}),
|
|
40
42
|
addAddress: builder.mutation<Address, Partial<Address>>({
|
|
41
43
|
query: (body) => ({
|
|
@@ -48,7 +50,7 @@ const addressApi = api.injectEndpoints({
|
|
|
48
50
|
type: body.is_corporate === 'true' ? 'corporate' : 'personal'
|
|
49
51
|
}
|
|
50
52
|
}),
|
|
51
|
-
invalidatesTags:
|
|
53
|
+
invalidatesTags: (_, error) => (error ? [] : ['Addresses', 'Checkout'])
|
|
52
54
|
}),
|
|
53
55
|
editAddress: builder.mutation<Address, Partial<Address>>({
|
|
54
56
|
query: ({ pk, ...body }) => ({
|
|
@@ -62,14 +64,14 @@ const addressApi = api.injectEndpoints({
|
|
|
62
64
|
type: body.is_corporate === 'true' ? 'corporate' : 'personal'
|
|
63
65
|
}
|
|
64
66
|
}),
|
|
65
|
-
invalidatesTags: ['Addresses', 'Checkout'] // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
|
|
67
|
+
invalidatesTags: (_, error) => (error ? [] : ['Addresses', 'Checkout']) // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
|
|
66
68
|
}),
|
|
67
69
|
removeAddress: builder.mutation<void, number>({
|
|
68
70
|
query: (id) => ({
|
|
69
71
|
url: buildClientRequestUrl(address.removeAddress(id)),
|
|
70
72
|
method: 'DELETE'
|
|
71
73
|
}),
|
|
72
|
-
invalidatesTags: ['Addresses', 'Checkout'] // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
|
|
74
|
+
invalidatesTags: (_, error) => (error ? [] : ['Addresses', 'Checkout']) // TODO: Invalidate one of these tags when necessary (e.g. Address page invalidates Addresses tag, Checkout page invalidates Checkout tag)
|
|
73
75
|
}),
|
|
74
76
|
setDefaultAddress: builder.mutation<Address, Partial<Address>>({
|
|
75
77
|
query: ({ pk, primary }) => ({
|
|
@@ -79,7 +81,7 @@ const addressApi = api.injectEndpoints({
|
|
|
79
81
|
method: 'PATCH',
|
|
80
82
|
body: { primary }
|
|
81
83
|
}),
|
|
82
|
-
invalidatesTags: ['Addresses']
|
|
84
|
+
invalidatesTags: (_, error) => (error ? [] : ['Addresses'])
|
|
83
85
|
}),
|
|
84
86
|
getStores: builder.query<GetResponse<Address>, void>({
|
|
85
87
|
query: () => ({
|
package/data/client/wishlist.ts
CHANGED
|
@@ -20,6 +20,8 @@ interface GetStockParams {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
interface GetFavoritesResponse {
|
|
23
|
+
next?: string | null;
|
|
24
|
+
previous?: string | null;
|
|
23
25
|
count: number;
|
|
24
26
|
results: FavoriteItem[];
|
|
25
27
|
}
|
|
@@ -71,14 +73,14 @@ export const wishlistApi = api.injectEndpoints({
|
|
|
71
73
|
product: productPk
|
|
72
74
|
}
|
|
73
75
|
}),
|
|
74
|
-
invalidatesTags: ['Favorite']
|
|
76
|
+
invalidatesTags: (_, error) => (error ? [] : ['Favorite'])
|
|
75
77
|
}),
|
|
76
78
|
removeFavorite: build.mutation<RemoteFavoriteResponse, number>({
|
|
77
79
|
query: (favPk: number) => ({
|
|
78
80
|
url: buildClientRequestUrl(wishlist.removeFavorite(favPk)),
|
|
79
81
|
method: 'DELETE'
|
|
80
82
|
}),
|
|
81
|
-
invalidatesTags: ['Favorite']
|
|
83
|
+
invalidatesTags: (_, error) => (error ? [] : ['Favorite'])
|
|
82
84
|
}),
|
|
83
85
|
addStockAlert: build.mutation<AddStockAlertResponse, AddStockAlertRequest>({
|
|
84
86
|
query: ({ productPk, email }) => ({
|
package/data/server/category.ts
CHANGED
|
@@ -39,7 +39,7 @@ function getCategoryDataHandler(
|
|
|
39
39
|
numberValueParser
|
|
40
40
|
) as GetCategoryResponse;
|
|
41
41
|
} catch (error) {
|
|
42
|
-
logger.
|
|
42
|
+
logger.fatal('Error while parsing category data', {
|
|
43
43
|
handler: 'getCategoryDataHandler',
|
|
44
44
|
error,
|
|
45
45
|
rawData: rawData.startsWith('<!DOCTYPE html>')
|
|
@@ -50,6 +50,14 @@ function getCategoryDataHandler(
|
|
|
50
50
|
|
|
51
51
|
const menuItemModel = data?.category?.menuitemmodel;
|
|
52
52
|
|
|
53
|
+
if (!menuItemModel) {
|
|
54
|
+
logger.warn('menuItemModel is undefined, skipping breadcrumbData fetch', {
|
|
55
|
+
handler: 'getCategoryDataHandler',
|
|
56
|
+
pk
|
|
57
|
+
});
|
|
58
|
+
return { data, breadcrumbData: undefined };
|
|
59
|
+
}
|
|
60
|
+
|
|
53
61
|
const breadcrumbData = await appFetch<any>(
|
|
54
62
|
product.breadcrumbUrl(menuItemModel),
|
|
55
63
|
{
|
|
@@ -108,7 +116,7 @@ function getCategoryBySlugDataHandler(slug: string) {
|
|
|
108
116
|
numberValueParser
|
|
109
117
|
) as GetCategoryResponse;
|
|
110
118
|
} catch (error) {
|
|
111
|
-
logger.
|
|
119
|
+
logger.fatal('Error while parsing category data', {
|
|
112
120
|
handler: 'getCategoryBySlugDataHandler',
|
|
113
121
|
error,
|
|
114
122
|
rawData: rawData.startsWith('<!DOCTYPE html>')
|
package/data/server/list.ts
CHANGED
|
@@ -38,7 +38,7 @@ const getListDataHandler = (
|
|
|
38
38
|
numberValueParser
|
|
39
39
|
) as GetCategoryResponse;
|
|
40
40
|
} catch (error) {
|
|
41
|
-
logger.
|
|
41
|
+
logger.fatal('Error while parsing list data', {
|
|
42
42
|
error,
|
|
43
43
|
rawData: rawData.startsWith('<!DOCTYPE html>')
|
|
44
44
|
? `${rawData.substring(0, 50)}...`
|
package/hooks/use-pagination.ts
CHANGED
|
@@ -70,10 +70,6 @@ export default function usePagination(
|
|
|
70
70
|
dispatch({ type: 'setLimit', payload: limit });
|
|
71
71
|
}, [limit]);
|
|
72
72
|
|
|
73
|
-
useEffect(() => {
|
|
74
|
-
window.scrollTo(0, 0);
|
|
75
|
-
}, [state.page, state.limit]);
|
|
76
|
-
|
|
77
73
|
const setTotal = useCallback(
|
|
78
74
|
(total: number) => {
|
|
79
75
|
dispatch({ type: 'setTotal', payload: total });
|
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.24.0-rc.1",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@typescript-eslint/eslint-plugin": "6.7.4",
|
|
33
33
|
"@typescript-eslint/parser": "6.7.4",
|
|
34
34
|
"eslint": "^8.14.0",
|
|
35
|
-
"@akinon/eslint-plugin-projectzero": "1.
|
|
35
|
+
"@akinon/eslint-plugin-projectzero": "1.24.0-rc.1",
|
|
36
36
|
"eslint-config-prettier": "8.5.0"
|
|
37
37
|
}
|
|
38
38
|
}
|
package/plugins.d.ts
CHANGED
|
@@ -13,3 +13,11 @@ declare module '@akinon/pz-masterpass/src/redux/reducer' {
|
|
|
13
13
|
export const setError: any;
|
|
14
14
|
export const setOtpModalVisible: any;
|
|
15
15
|
}
|
|
16
|
+
|
|
17
|
+
declare module '@akinon/pz-otp' {
|
|
18
|
+
export const otpReducer: any;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare module '@akinon/pz-otp/src/redux/reducer' {
|
|
22
|
+
export const showPopup: any;
|
|
23
|
+
}
|
package/redux/reducers/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { api } from '../../data/client/api';
|
|
|
6
6
|
|
|
7
7
|
// Plugin reducers
|
|
8
8
|
import { masterpassReducer } from '@akinon/pz-masterpass';
|
|
9
|
+
import { otpReducer } from '@akinon/pz-otp';
|
|
9
10
|
|
|
10
11
|
const reducers = {
|
|
11
12
|
[api.reducerPath]: api.reducer,
|
|
@@ -13,7 +14,8 @@ const reducers = {
|
|
|
13
14
|
checkout: checkoutReducer,
|
|
14
15
|
config: configReducer,
|
|
15
16
|
header: headerReducer,
|
|
16
|
-
masterpass: masterpassReducer
|
|
17
|
+
masterpass: masterpassReducer,
|
|
18
|
+
otp: otpReducer
|
|
17
19
|
};
|
|
18
20
|
|
|
19
21
|
export default reducers;
|
package/sentry/index.ts
CHANGED
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
import * as Sentry from '@sentry/nextjs';
|
|
2
|
+
import settings from 'settings';
|
|
2
3
|
|
|
3
4
|
const SENTRY_DSN: string =
|
|
4
|
-
|
|
5
|
+
settings.sentryDsn ||
|
|
6
|
+
process.env.SENTRY_DSN ||
|
|
7
|
+
process.env.NEXT_PUBLIC_SENTRY_DSN;
|
|
5
8
|
|
|
6
9
|
export const initSentry = (
|
|
7
10
|
type: 'Server' | 'Client' | 'Edge',
|
|
8
|
-
options: Sentry.BrowserOptions | Sentry.NodeOptions | Sentry.EdgeOptions = {
|
|
11
|
+
options: Sentry.BrowserOptions | Sentry.NodeOptions | Sentry.EdgeOptions = {
|
|
12
|
+
dsn: SENTRY_DSN,
|
|
13
|
+
integrations: [],
|
|
14
|
+
tracesSampleRate: 1.0
|
|
15
|
+
}
|
|
9
16
|
) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
// TODO: Remove Zero Project DSN
|
|
13
|
-
|
|
14
|
-
Sentry.init({
|
|
15
|
-
dsn:
|
|
16
|
-
SENTRY_DSN ||
|
|
17
|
-
'https://d8558ef8997543deacf376c7d8d7cf4b@o64293.ingest.sentry.io/4504338423742464',
|
|
17
|
+
const initOptions = {
|
|
18
|
+
...options,
|
|
18
19
|
initialScope: {
|
|
19
20
|
tags: {
|
|
21
|
+
...((
|
|
22
|
+
options.initialScope as {
|
|
23
|
+
tags?: Record<string, string>;
|
|
24
|
+
}
|
|
25
|
+
)?.tags ?? {}),
|
|
20
26
|
APP_TYPE: 'ProjectZeroNext',
|
|
21
27
|
TYPE: type
|
|
22
28
|
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
Sentry.init(initOptions);
|
|
27
33
|
};
|
package/types/index.ts
CHANGED
|
@@ -71,6 +71,12 @@ export interface Currency {
|
|
|
71
71
|
|
|
72
72
|
export interface Settings {
|
|
73
73
|
commerceUrl: string;
|
|
74
|
+
/**
|
|
75
|
+
* This option allows you to track Sentry events on the client side, in addition to server and edge environments.
|
|
76
|
+
*
|
|
77
|
+
* It overrides process.env.NEXT_PUBLIC_SENTRY_DSN and process.env.SENTRY_DSN.
|
|
78
|
+
*/
|
|
79
|
+
sentryDsn?: string;
|
|
74
80
|
redis: {
|
|
75
81
|
defaultExpirationTime: number;
|
|
76
82
|
};
|
package/utils/app-fetch.ts
CHANGED
|
@@ -12,7 +12,7 @@ const appFetch = async <T>(
|
|
|
12
12
|
url: RequestInfo,
|
|
13
13
|
init: RequestInit = {},
|
|
14
14
|
responseType = FetchResponseType.JSON
|
|
15
|
-
) => {
|
|
15
|
+
): Promise<T> => {
|
|
16
16
|
let response: T;
|
|
17
17
|
let status: number;
|
|
18
18
|
let ip = '';
|
|
@@ -48,18 +48,18 @@ const appFetch = async <T>(
|
|
|
48
48
|
status = req.status;
|
|
49
49
|
logger.debug(`FETCH END ${url}`, { status: req.status, ip });
|
|
50
50
|
|
|
51
|
-
const rawData = await req.text();
|
|
52
|
-
|
|
53
51
|
if (responseType === FetchResponseType.JSON) {
|
|
54
|
-
response =
|
|
52
|
+
response = (await req.json()) as T;
|
|
55
53
|
} else {
|
|
56
|
-
response =
|
|
54
|
+
response = (await req.text()) as unknown as T;
|
|
57
55
|
}
|
|
58
56
|
|
|
59
57
|
logger.trace(`FETCH RESPONSE`, { url, response, ip });
|
|
60
58
|
} catch (error) {
|
|
59
|
+
const logType = status === 500 ? 'fatal' : 'error';
|
|
60
|
+
|
|
61
61
|
if (!url.toString().includes('/cms/seo/')) {
|
|
62
|
-
logger
|
|
62
|
+
logger[logType](`FETCH FAILED`, { url, status, error, ip });
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|