@akinon/next 2.0.16-rc.0 → 2.0.16

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.
@@ -7,111 +7,224 @@ import { getCheckoutPath } from '../utils';
7
7
 
8
8
  const withMasterpassRestCallback =
9
9
  (middleware: NextMiddleware) =>
10
- async (req: PzNextRequest, event: NextFetchEvent) => {
11
- const url = req.nextUrl.clone();
12
- const ip = req.headers.get('x-forwarded-for') ?? '';
13
-
14
- const isMasterpassCompletePage =
15
- url.pathname.includes('/orders/checkout') &&
16
- url.searchParams.get('page') === 'MasterpassRestCompletePage';
10
+ async (req: PzNextRequest, event: NextFetchEvent) => {
11
+ const url = req.nextUrl.clone();
12
+ const ip = req.headers.get('x-forwarded-for') ?? '';
13
+ const sessionId = req.cookies.get('osessionid');
14
+
15
+ if (!url.pathname.includes('/orders/masterpass-rest-callback')) {
16
+ return middleware(req, event);
17
+ }
18
+
19
+ if (req.method !== 'POST') {
20
+ logger.warn('Invalid request method for masterpass REST callback', {
21
+ middleware: 'masterpass-rest-callback',
22
+ method: req.method,
23
+ ip
24
+ });
25
+
26
+ return NextResponse.redirect(
27
+ `${url.origin}${getUrlPathWithLocale(
28
+ '/orders/checkout/',
29
+ req.cookies.get('pz-locale')?.value
30
+ )}`,
31
+ 303
32
+ );
33
+ }
34
+
35
+ const responseCode = url.searchParams.get('responseCode');
36
+ const token = url.searchParams.get('token');
37
+
38
+ if (!responseCode || !token) {
39
+ logger.warn('Missing required parameters for masterpass REST callback', {
40
+ middleware: 'masterpass-rest-callback',
41
+ responseCode,
42
+ token,
43
+ ip
44
+ });
45
+
46
+ return NextResponse.redirect(
47
+ `${url.origin}${getUrlPathWithLocale(
48
+ '/orders/checkout/',
49
+ req.cookies.get('pz-locale')?.value
50
+ )}`,
51
+ 303
52
+ );
53
+ }
54
+
55
+ try {
56
+ const formData = await req.formData();
57
+ const body: Record<string, string> = {};
58
+
59
+ Array.from(formData.entries()).forEach(([key, value]) => {
60
+ body[key] = value.toString();
61
+ });
62
+
63
+ if (!sessionId) {
64
+ logger.warn(
65
+ 'Make sure that the SESSION_COOKIE_SAMESITE environment variable is set to None in Commerce.',
66
+ {
67
+ middleware: 'masterpass-rest-callback',
68
+ ip
69
+ }
70
+ );
17
71
 
18
- if (!isMasterpassCompletePage) {
19
- return middleware(req, event);
72
+ return NextResponse.redirect(
73
+ `${url.origin}${getUrlPathWithLocale(
74
+ '/orders/checkout/',
75
+ req.cookies.get('pz-locale')?.value
76
+ )}`,
77
+ 303
78
+ );
20
79
  }
21
80
 
22
- try {
23
- const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
24
- const requestUrl = new URL(getCheckoutPath(isPostCheckout), Settings.commerceUrl);
81
+ const isPostCheckout = req.cookies.get('pz-post-checkout-flow')?.value === 'true';
82
+ const requestUrl = new URL(getCheckoutPath(isPostCheckout), Settings.commerceUrl);
83
+ requestUrl.searchParams.set('page', 'MasterpassRestCompletePage');
84
+ requestUrl.searchParams.set('responseCode', responseCode);
85
+ requestUrl.searchParams.set('token', token);
86
+ requestUrl.searchParams.set(
87
+ 'three_d_secure',
88
+ body.transactionType?.includes('3D') ? 'true' : 'false'
89
+ );
90
+ requestUrl.searchParams.set(
91
+ 'transactionType',
92
+ body.transactionType || ''
93
+ );
94
+
95
+ const requestHeaders = {
96
+ 'Content-Type': 'application/x-www-form-urlencoded',
97
+ 'X-Requested-With': 'XMLHttpRequest',
98
+ Cookie: req.headers.get('cookie') ?? '',
99
+ 'x-currency': req.cookies.get('pz-currency')?.value ?? '',
100
+ 'x-forwarded-for': ip,
101
+ 'User-Agent': req.headers.get('user-agent') ?? ''
102
+ };
103
+
104
+ const request = await fetch(requestUrl.toString(), {
105
+ method: 'POST',
106
+ headers: requestHeaders,
107
+ body: new URLSearchParams(body)
108
+ });
109
+
110
+ logger.info('Masterpass REST callback request', {
111
+ requestUrl: requestUrl.toString(),
112
+ status: request.status,
113
+ requestHeaders,
114
+ ip
115
+ });
116
+
117
+ const response = await request.json();
118
+
119
+ const { context_list: contextList, errors } = response;
120
+
121
+ let redirectUrl = response.redirect_url;
122
+
123
+ if (!redirectUrl && contextList && contextList.length > 0) {
124
+ for (const context of contextList) {
125
+ if (context.page_context && context.page_context.redirect_url) {
126
+ redirectUrl = context.page_context.redirect_url;
127
+ break;
128
+ }
129
+ }
130
+ }
25
131
 
26
- url.searchParams.forEach((value, key) => {
27
- requestUrl.searchParams.set(key, value);
132
+ if (errors && Object.keys(errors).length) {
133
+ logger.error('Error while processing masterpass REST callback', {
134
+ middleware: 'masterpass-rest-callback',
135
+ errors,
136
+ requestHeaders,
137
+ ip
28
138
  });
29
139
 
30
- const formData = await req.formData();
31
- const body: Record<string, string> = {};
32
-
33
- Array.from(formData.entries()).forEach(([key, value]) => {
34
- body[key] = value.toString();
35
- });
140
+ const errorResponse = NextResponse.redirect(
141
+ `${url.origin}${getUrlPathWithLocale(
142
+ '/orders/checkout/',
143
+ req.cookies.get('pz-locale')?.value
144
+ )}`,
145
+ {
146
+ status: 303,
147
+ headers: {
148
+ 'Set-Cookie': `pz-pos-error=${encodeURIComponent(JSON.stringify(errors))}; path=/;`
149
+ }
150
+ }
151
+ );
36
152
 
37
- const requestHeaders = {
38
- 'Content-Type': 'application/x-www-form-urlencoded',
39
- 'X-Requested-With': 'XMLHttpRequest',
40
- Cookie: req.headers.get('cookie') ?? '',
41
- 'x-currency': req.cookies.get('pz-currency')?.value ?? '',
42
- 'x-forwarded-for': ip,
43
- 'User-Agent': req.headers.get('user-agent') ?? ''
44
- };
45
-
46
- const request = await fetch(requestUrl.toString(), {
47
- method: 'POST',
48
- headers: requestHeaders,
49
- body: new URLSearchParams(body)
153
+ // Add error cookie
154
+ errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
155
+ path: '/'
50
156
  });
51
157
 
52
- const response = await request.json();
53
- const { errors } = response;
158
+ return errorResponse;
159
+ }
54
160
 
55
- if (errors && Object.keys(errors).length) {
56
- logger.error('Error while processing MasterpassRestCompletePage', {
161
+ logger.info('Masterpass REST callback response', {
162
+ middleware: 'masterpass-rest-callback',
163
+ contextList,
164
+ redirectUrl,
165
+ ip
166
+ });
167
+
168
+ if (!redirectUrl) {
169
+ logger.warn(
170
+ 'No redirection url found in response. Redirecting to checkout page.',
171
+ {
57
172
  middleware: 'masterpass-rest-callback',
58
- errors,
173
+ requestHeaders,
174
+ response: JSON.stringify(response),
59
175
  ip
60
- });
61
-
62
- const errorResponse = NextResponse.redirect(
63
- `${url.origin}${getUrlPathWithLocale(
64
- '/orders/checkout/',
65
- req.cookies.get('pz-locale')?.value
66
- )}`,
67
- 303
68
- );
69
-
70
- // Add error cookie
71
- errorResponse.cookies.set('pz-pos-error', JSON.stringify(errors), {
72
- path: '/'
73
- });
74
-
75
- return errorResponse;
76
- }
77
-
78
- const redirectUrl =
79
- response.redirect_url ||
80
- response.context_list?.[0]?.page_context?.redirect_url;
81
-
82
- if (redirectUrl) {
83
- const nextResponse = NextResponse.redirect(
84
- `${url.origin}${getUrlPathWithLocale(redirectUrl, req.cookies.get('pz-locale')?.value)}`,
85
- 303
86
- );
87
-
88
- // Forward set-cookie headers from the upstream response
89
- const setCookieHeader = request.headers.get('set-cookie');
90
- if (setCookieHeader) {
91
- setCookieHeader.split(',').forEach((cookie) => {
92
- nextResponse.headers.append('Set-Cookie', cookie.trim());
93
- });
94
176
  }
177
+ );
95
178
 
96
- return nextResponse;
97
- }
179
+ const redirectUrlWithLocale = `${url.origin}${getUrlPathWithLocale(
180
+ '/orders/checkout/',
181
+ req.cookies.get('pz-locale')?.value
182
+ )}`;
98
183
 
99
- return NextResponse.redirect(
100
- `${url.origin}${getUrlPathWithLocale('/orders/checkout/', req.cookies.get('pz-locale')?.value)}`,
101
- 303
102
- );
103
- } catch (error) {
104
- logger.error('Error while processing MasterpassRestCompletePage', {
105
- middleware: 'masterpass-rest-callback',
106
- error,
107
- ip
108
- });
184
+ return NextResponse.redirect(redirectUrlWithLocale, 303);
185
+ }
109
186
 
110
- return NextResponse.redirect(
111
- `${url.origin}${getUrlPathWithLocale('/orders/checkout/', req.cookies.get('pz-locale')?.value)}`,
112
- 303
113
- );
187
+ const redirectUrlWithLocale = `${url.origin}${getUrlPathWithLocale(
188
+ redirectUrl,
189
+ req.cookies.get('pz-locale')?.value
190
+ )}`;
191
+
192
+ logger.info('Redirecting after masterpass REST callback', {
193
+ middleware: 'masterpass-rest-callback',
194
+ redirectUrl: redirectUrlWithLocale,
195
+ ip
196
+ });
197
+
198
+ const nextResponse = NextResponse.redirect(redirectUrlWithLocale, 303);
199
+
200
+ // Forward set-cookie headers from the upstream response
201
+ const setCookieHeader = request.headers.get('set-cookie');
202
+ if (setCookieHeader) {
203
+ setCookieHeader.split(',').forEach((cookie) => {
204
+ nextResponse.headers.append('Set-Cookie', cookie.trim());
205
+ });
114
206
  }
115
- };
207
+
208
+ return nextResponse;
209
+ } catch (error) {
210
+ logger.error('Error while processing masterpass REST callback', {
211
+ middleware: 'masterpass-rest-callback',
212
+ error,
213
+ requestHeaders: {
214
+ Cookie: req.headers.get('cookie') ?? '',
215
+ 'x-currency': req.cookies.get('pz-currency')?.value ?? ''
216
+ },
217
+ ip
218
+ });
219
+
220
+ return NextResponse.redirect(
221
+ `${url.origin}${getUrlPathWithLocale(
222
+ '/orders/checkout/',
223
+ req.cookies.get('pz-locale')?.value
224
+ )}`,
225
+ 303
226
+ );
227
+ }
228
+ };
116
229
 
117
230
  export default withMasterpassRestCallback;
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": "2.0.16-rc.0",
4
+ "version": "2.0.16",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -36,7 +36,7 @@
36
36
  "set-cookie-parser": "2.6.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@akinon/eslint-plugin-projectzero": "2.0.16-rc.0",
39
+ "@akinon/eslint-plugin-projectzero": "2.0.16",
40
40
  "@babel/core": "7.26.10",
41
41
  "@babel/preset-env": "7.26.9",
42
42
  "@babel/preset-typescript": "7.27.0",
package/plugins.d.ts CHANGED
@@ -37,16 +37,6 @@ 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
-
50
40
  declare module '@akinon/pz-cybersource-uc/src/redux/reducer' {
51
41
  export default reducer as any;
52
42
  }
package/plugins.js CHANGED
@@ -16,7 +16,6 @@ module.exports = [
16
16
  'pz-tabby-extension',
17
17
  'pz-apple-pay',
18
18
  'pz-tamara-extension',
19
- 'pz-similar-products',
20
19
  'pz-cybersource-uc',
21
20
  'pz-hepsipay',
22
21
  'pz-flow-payment',
@@ -26,28 +26,13 @@ import {
26
26
  } from '../../redux/reducers/checkout';
27
27
  import { RootState, TypedDispatch } from 'redux/store';
28
28
  import { checkoutApi } from '../../data/client/checkout';
29
- import { CheckoutContext, MiddlewareAction, PreOrder } from '../../types';
29
+ import { CheckoutContext, PreOrder } from '../../types';
30
30
  import { getCookie } from '../../utils';
31
31
  import settings from 'settings';
32
32
  import { LocaleUrlStrategy } from '../../localization';
33
33
  import { showMobile3dIframe } from '../../utils/mobile-3d-iframe';
34
34
  import { showRedirectionIframe } from '../../utils/redirection-iframe';
35
35
 
36
- const IFRAME_REDIRECTION_KEY = 'pz-iframe-redirection-active';
37
-
38
- const isIframeRedirectionActive = () =>
39
- typeof window !== 'undefined' &&
40
- sessionStorage.getItem(IFRAME_REDIRECTION_KEY) === 'true';
41
-
42
- const setIframeRedirectionActive = (active: boolean) => {
43
- if (typeof window === 'undefined') return;
44
- if (active) {
45
- sessionStorage.setItem(IFRAME_REDIRECTION_KEY, 'true');
46
- } else {
47
- sessionStorage.removeItem(IFRAME_REDIRECTION_KEY);
48
- }
49
- };
50
-
51
36
  interface CheckoutResult {
52
37
  payload: {
53
38
  errors?: Record<string, string[]>;
@@ -84,7 +69,7 @@ export const redirectUrlMiddleware: Middleware = () => {
84
69
  const result = next(action) as CheckoutResult;
85
70
  const redirectUrl = result?.payload?.redirect_url;
86
71
 
87
- if (redirectUrl && !isIframeRedirectionActive()) {
72
+ if (redirectUrl) {
88
73
  const currentLocale = getCookie('pz-locale');
89
74
 
90
75
  let url = redirectUrl;
@@ -114,15 +99,8 @@ export const contextListMiddleware: Middleware = ({
114
99
  const { isMobileApp, userPhoneNumber } = getState().root;
115
100
  const result = next(action) as CheckoutResult;
116
101
  const preOrder = result?.payload?.pre_order;
117
- const act = action as MiddlewareAction;
118
102
 
119
103
  if (result?.payload?.context_list) {
120
- const endpointName = act.meta?.arg?.endpointName;
121
- const isBinNumberResponse = endpointName === 'setBinNumber';
122
- const hasCardTypeInContextList = result.payload.context_list.some(
123
- (ctx) => ctx.page_context.card_type
124
- );
125
-
126
104
  result.payload.context_list.forEach((context) => {
127
105
  const redirectUrl = context.page_context.redirect_url;
128
106
  const isIframe = context.page_context.is_iframe ?? false;
@@ -156,7 +134,6 @@ export const contextListMiddleware: Middleware = ({
156
134
  if (isMobileDevice && isIframePaymentOptionIncluded) {
157
135
  showMobile3dIframe(urlObj.toString());
158
136
  } else if (isIframe) {
159
- setIframeRedirectionActive(true);
160
137
  showRedirectionIframe(urlObj.toString());
161
138
  } else {
162
139
  window.location.href = urlObj.toString();
@@ -232,34 +209,15 @@ export const contextListMiddleware: Middleware = ({
232
209
  (ctx) => ctx.page_name === 'DeliveryOptionSelectionPage'
233
210
  )
234
211
  ) {
235
- const isCreditCardPayment =
236
- preOrder?.payment_option?.payment_type === 'credit_card' ||
237
- preOrder?.payment_option?.payment_type === 'masterpass';
238
-
239
212
  if (context.page_context.card_type) {
240
213
  dispatch(setCardType(context.page_context.card_type));
241
- } else if (
242
- isCreditCardPayment &&
243
- isBinNumberResponse &&
244
- !hasCardTypeInContextList
245
- ) {
246
- dispatch(setCardType(null));
247
- dispatch(setInstallmentOptions([]));
248
214
  }
249
215
 
250
216
  if (
251
217
  context.page_context.installments &&
252
218
  preOrder?.payment_option?.payment_type !== 'masterpass_rest'
253
219
  ) {
254
- if (
255
- !isCreditCardPayment ||
256
- context.page_context.card_type ||
257
- hasCardTypeInContextList
258
- ) {
259
- dispatch(
260
- setInstallmentOptions(context.page_context.installments)
261
- );
262
- }
220
+ dispatch(setInstallmentOptions(context.page_context.installments));
263
221
  }
264
222
  }
265
223
 
@@ -14,17 +14,9 @@ export const installmentOptionMiddleware: Middleware = ({
14
14
  return result;
15
15
  }
16
16
 
17
- const { installmentOptions, cardType } = getState().checkout;
17
+ const { installmentOptions } = getState().checkout;
18
18
  const { endpoints: apiEndpoints } = checkoutApi;
19
19
 
20
- const isCreditCardPayment =
21
- preOrder?.payment_option?.payment_type === 'credit_card' ||
22
- preOrder?.payment_option?.payment_type === 'masterpass';
23
-
24
- if (isCreditCardPayment && !cardType) {
25
- return result;
26
- }
27
-
28
20
  if (
29
21
  !preOrder?.installment &&
30
22
  preOrder?.payment_option?.payment_type !== 'saved_card' &&
package/types/index.ts CHANGED
@@ -86,11 +86,24 @@ export interface Settings {
86
86
  usePrettyUrlRoute?: boolean;
87
87
  commerceUrl: string;
88
88
  /**
89
- * This option allows you to track Sentry events on the client side, in addition to server and edge environments.
89
+ * CSRF cookie hardening settings.
90
90
  *
91
- * It overrides process.env.NEXT_PUBLIC_SENTRY_DSN and process.env.SENTRY_DSN.
91
+ * When `httpOnly` is `true`, the `csrftoken` cookie is set with the
92
+ * `HttpOnly`, `Secure` (production) and `SameSite=Lax` flags. The token is
93
+ * never exposed to the browser: instead of the client mirroring the cookie
94
+ * into the `x-csrftoken` header, the Next.js proxy (BFF) reads the cookie
95
+ * server-side and injects the header before forwarding state-changing
96
+ * requests to the commerce backend, after validating the request `Origin`.
97
+ *
98
+ * Because the token no longer reaches JS, brand code must NOT rely on
99
+ * reading `csrftoken` from `document.cookie` or `getCookie('csrftoken')`
100
+ * when this flag is enabled — all CSRF handling happens on the server.
101
+ *
102
+ * @default false
92
103
  */
93
- sentryDsn?: string;
104
+ csrf?: {
105
+ httpOnly?: boolean;
106
+ };
94
107
  redis: {
95
108
  defaultExpirationTime: number;
96
109
  };
@@ -223,7 +236,6 @@ export interface Settings {
223
236
  separator?: string;
224
237
  segments: PzSegmentDefinition[];
225
238
  };
226
- payloadOptimization?: import('../utils/payload-optimizer').PayloadOptimizationConfig;
227
239
  }
228
240
 
229
241
  export interface CacheOptions {
@@ -48,13 +48,19 @@ const appFetch = async <T>({
48
48
 
49
49
  // Replay mode: serve from fixtures without hitting the API
50
50
  if (mockMode === MockMode.REPLAY) {
51
- const { found, fixture } = await fixtureManager.read(method, String(url), init.body);
51
+ const { found, fixture } = await fixtureManager.read(
52
+ method,
53
+ String(url),
54
+ init.body
55
+ );
52
56
 
53
57
  if (found) {
54
58
  status = fixture.response.status;
55
- response = (responseType === FetchResponseType.JSON
56
- ? fixture.response.body
57
- : JSON.stringify(fixture.response.body)) as T;
59
+ response = (
60
+ responseType === FetchResponseType.JSON
61
+ ? fixture.response.body
62
+ : JSON.stringify(fixture.response.body)
63
+ ) as T;
58
64
  return response;
59
65
  }
60
66
 
@@ -74,6 +80,8 @@ const appFetch = async <T>({
74
80
  revalidate: Settings.usePrettyUrlRoute ? 0 : 60
75
81
  };
76
82
 
83
+ // console.log('APP FETCH', init);
84
+
77
85
  logger.debug(`FETCH START ${url}`, { requestURL, init, ip });
78
86
  const req = await fetch(requestURL, init);
79
87
  status = req.status;
package/utils/csrf.ts ADDED
@@ -0,0 +1,37 @@
1
+ import settings from 'settings';
2
+
3
+ /**
4
+ * Whether the Django `csrftoken` cookie should be hardened with the
5
+ * `HttpOnly` flag.
6
+ *
7
+ * When enabled, the token never reaches the browser: the Next.js proxy
8
+ * (BFF) reads the cookie server-side and injects the `x-csrftoken` header
9
+ * before forwarding state-changing requests to the commerce backend. See
10
+ * `api/client.ts`.
11
+ */
12
+ export function isCsrfHttpOnly(): boolean {
13
+ return settings.csrf?.httpOnly === true;
14
+ }
15
+
16
+ export interface CsrfCookieFlags {
17
+ httpOnly: boolean;
18
+ secure: boolean;
19
+ sameSite: 'lax';
20
+ }
21
+
22
+ /**
23
+ * Cookie attributes applied to the `csrftoken` cookie wherever it is set
24
+ * (middleware bootstrap, auth login rotation, proxy passthrough).
25
+ *
26
+ * `SameSite=Lax` is the Next.js-layer CSRF defense: the browser will not
27
+ * attach the cookie on cross-site state-changing requests, so the proxy's
28
+ * server-side header injection cannot be abused from a third-party origin.
29
+ */
30
+ export function getCsrfCookieFlags(): CsrfCookieFlags {
31
+ const httpOnly = isCsrfHttpOnly();
32
+ return {
33
+ httpOnly,
34
+ secure: httpOnly && process.env.NODE_ENV === 'production',
35
+ sameSite: 'lax'
36
+ };
37
+ }
@@ -1,4 +1,5 @@
1
1
  import Settings from 'settings';
2
+ import { LocaleUrlStrategy } from '../localization';
2
3
 
3
4
  export default function getRootHostname(
4
5
  url: string | undefined
@@ -26,3 +27,20 @@ export default function getRootHostname(
26
27
  return null;
27
28
  }
28
29
  }
30
+
31
+ interface HeaderLike {
32
+ get(name: string): string | null;
33
+ }
34
+
35
+ export function getRequestRootHostname(
36
+ headerStore: HeaderLike
37
+ ): string | null {
38
+ if (Settings.localization.localeUrlStrategy !== LocaleUrlStrategy.Subdomain) {
39
+ return null;
40
+ }
41
+
42
+ const fallbackHost =
43
+ headerStore.get('x-forwarded-host') || headerStore.get('host');
44
+ const hostname = process.env.NEXT_PUBLIC_URL || `https://${fallbackHost}`;
45
+ return getRootHostname(hostname);
46
+ }
package/utils/index.ts CHANGED
@@ -10,6 +10,7 @@ export * from './get-currency-label';
10
10
  export * from './pz-segments';
11
11
  export * from './get-checkout-path';
12
12
  export * from './format-error-message';
13
+ export * from './csrf';
13
14
 
14
15
  export function getCookie(name: string) {
15
16
  if (typeof document === 'undefined') {
package/with-pz-config.js CHANGED
@@ -69,8 +69,7 @@ const defaultConfig = {
69
69
  acc[`@akinon/${plugin}`] = false;
70
70
  return acc;
71
71
  }, {}),
72
- translations: false,
73
- '@opentelemetry/exporter-jaeger': false
72
+ translations: false
74
73
  };
75
74
  // Ensure webpack can resolve deps from the app's node_modules when
76
75
  // compiling transpiled packages (e.g. @akinon/next) whose imports