@akinon/next 1.22.0 → 1.23.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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # @akinon/next
2
2
 
3
+ ## 1.23.0-rc.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 2e44646: ZERO-2434: Fix category URL in getCategoryDataHandler function
8
+
9
+ ## 1.23.0-rc.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 0181251: ZERO-2440: move otp popup state to redux
14
+ - 07cc81a: Add infinite and more types to pagination
15
+ - 8d6caba: ZERO-2434: enhance error handling and logging in appFetch function
16
+ - b4452e9: ZERO-2463: Refactor Sentry initialization and add Sentry DSN option to settings
17
+ - b2da5e4: Revert ZERO-2435
18
+
19
+ ### Patch Changes
20
+
21
+ - da1e501: ZERO-2296: Fix ROUTES import
22
+
3
23
  ## 1.22.0
4
24
 
5
25
  ### 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
  };
@@ -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
  }
@@ -39,7 +39,7 @@ function getCategoryDataHandler(
39
39
  numberValueParser
40
40
  ) as GetCategoryResponse;
41
41
  } catch (error) {
42
- logger.error('Error while parsing category data', {
42
+ logger.fatal('Error while parsing category data', {
43
43
  handler: 'getCategoryDataHandler',
44
44
  error,
45
45
  rawData: rawData.startsWith('<!DOCTYPE html>')
@@ -108,7 +108,7 @@ function getCategoryBySlugDataHandler(slug: string) {
108
108
  numberValueParser
109
109
  ) as GetCategoryResponse;
110
110
  } catch (error) {
111
- logger.error('Error while parsing category data', {
111
+ logger.fatal('Error while parsing category data', {
112
112
  handler: 'getCategoryBySlugDataHandler',
113
113
  error,
114
114
  rawData: rawData.startsWith('<!DOCTYPE html>')
@@ -38,7 +38,7 @@ const getListDataHandler = (
38
38
  numberValueParser
39
39
  ) as GetCategoryResponse;
40
40
  } catch (error) {
41
- logger.error('Error while parsing list data', {
41
+ logger.fatal('Error while parsing list data', {
42
42
  error,
43
43
  rawData: rawData.startsWith('<!DOCTYPE html>')
44
44
  ? `${rawData.substring(0, 50)}...`
@@ -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.22.0",
4
+ "version": "1.23.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.22.0",
35
+ "@akinon/eslint-plugin-projectzero": "1.23.0-rc.1",
36
36
  "eslint-config-prettier": "8.5.0"
37
37
  }
38
38
  }
package/plugins.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  declare module '@akinon/pz-masterpass' {
2
2
  export const masterpassReducer: unknown;
3
3
  }
4
+
5
+ declare module '@akinon/pz-otp' {
6
+ export const otpReducer: unknown;
7
+ }
@@ -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
- process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
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
- // TODO: Handle options with ESLint rules
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
- tracesSampleRate: 1.0,
25
- integrations: []
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
  };
@@ -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 = '';
@@ -28,7 +28,7 @@ const appFetch = async <T>(
28
28
 
29
29
  if (commerceUrl === 'default') {
30
30
  logger.error('Commerce URL is not set. Current value is "default"');
31
- return undefined;
31
+ throw new Error('Commerce URL is not set');
32
32
  }
33
33
 
34
34
  const requestURL = `${decodeURIComponent(commerceUrl)}${url}`;
@@ -48,19 +48,30 @@ 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();
51
+ if (!req.ok) {
52
+ throw new Error(`Request failed with status ${status}`);
53
+ }
52
54
 
53
55
  if (responseType === FetchResponseType.JSON) {
54
- response = JSON.parse(rawData);
56
+ response = (await req.json()) as T;
55
57
  } else {
56
- response = rawData as unknown as T;
58
+ response = (await req.text()) as unknown as T;
57
59
  }
58
60
 
59
61
  logger.trace(`FETCH RESPONSE`, { url, response, ip });
60
62
  } catch (error) {
63
+ const logType = status === 500 ? 'fatal' : 'error';
64
+
61
65
  if (!url.toString().includes('/cms/seo/')) {
62
- logger.error(`FETCH FAILED`, { url, status, error, ip });
66
+ logger[logType](`FETCH FAILED`, { url, status, error, ip });
63
67
  }
68
+
69
+ // throw the error if it's fatal, so it can be caught and handled at higher levels
70
+ if (logType === 'fatal') {
71
+ throw error;
72
+ }
73
+
74
+ return Promise.reject(error);
64
75
  }
65
76
 
66
77
  return response;