@akinon/next 1.34.0-rc.9 → 1.35.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.
@@ -5,6 +5,7 @@ module.exports = {
5
5
  es2021: true
6
6
  },
7
7
  extends: [
8
+ 'eslint:recommended',
8
9
  'next/core-web-vitals',
9
10
  'eslint:recommended',
10
11
  'plugin:@typescript-eslint/recommended',
@@ -17,7 +18,7 @@ module.exports = {
17
18
  env: {
18
19
  node: true
19
20
  },
20
- files: ['eslint.config.{js,cjs}', 'middlewares/default.ts'],
21
+ files: ['.eslintrc.{js,cjs}', 'middlewares/default.ts'],
21
22
  rules: {
22
23
  '@akinon/projectzero/check-middleware-order': 'error'
23
24
  },
package/CHANGELOG.md CHANGED
@@ -1,39 +1,16 @@
1
1
  # @akinon/next
2
2
 
3
- ## 1.34.0-rc.9
4
-
5
- ### Minor Changes
6
-
7
- - beb499e: ZERO-2551: Add new tsconfig paths
8
-
9
- ## 1.34.0-rc.8
10
-
11
- ### Minor Changes
12
-
13
- - 91265bb: ZERO-2551: Improve pretty url and caching performance
14
-
15
- ## 1.34.0-rc.7
16
-
17
- ## 1.34.0-rc.6
3
+ ## 1.35.0
18
4
 
19
5
  ### Minor Changes
20
6
 
21
7
  - d09b677: ZERO-2577: Fix pagination bug and update usePagination hook and ensure pagination controls rendering correctly
22
8
  - 6d4aadb: ZERO-2476: Auto install recommendenent extension
23
- - ebb63ce: ZERO-2525: Fix category facet removal bug and add close icon to active filters
24
- - 7cebe87: ZERO-2524: Add check monorepo utility function
25
9
  - f0c23bc: ZERO-2135: add custom not found page
26
- - 3420416: ZERO-2533: extend eslint config from @akinon/next
27
- - 495d155: ZERO-2505: findBaseDir function is united and move on to the utils
28
- - 40ad73e: ZERO-2504: add cookie filter to api client request
29
- - 495d155: ZERO-2524: Zero-cli dist checks for changes and renders it to the terminal.
30
- - f046f8e: ZERO-2575: update version for react-number-format
10
+ - f488ea8: ZERO-2505: findBaseDir function is united and move on to the utils
31
11
  - 6b2972b: ZERO-2514: Fix handling of status 204 and return Commerce status code in client proxy API.
32
- - 3e68768: ZERO-2578: Add osessionid check in middleware
33
-
34
- ### Patch Changes
35
12
 
36
- - 59fb7c3: ZERO-2504: get set-cookie headers from commerce request
13
+ ## 1.34.0
37
14
 
38
15
  ## 1.33.2
39
16
 
package/api/client.ts CHANGED
@@ -2,8 +2,6 @@ import { ClientRequestOptions } from '../types';
2
2
  import { NextResponse } from 'next/server';
3
3
  import settings from 'settings';
4
4
  import logger from '../utils/log';
5
- import formatCookieString from '../utils/format-cookie-string';
6
- import cookieParser from 'set-cookie-parser';
7
5
 
8
6
  interface RouteParams {
9
7
  params: {
@@ -141,21 +139,11 @@ async function proxyRequest(...args) {
141
139
  );
142
140
  }
143
141
 
144
- const setCookieHeaders = request.headers.getSetCookie();
145
- const exceptCookieKeys = ['pz-locale', 'pz-currency'];
146
-
147
- const isExcludedCookie = (name: string) => exceptCookieKeys.includes(name);
148
-
149
- const filteredCookies = cookieParser
150
- .parse(setCookieHeaders)
151
- .filter((cookie) => !isExcludedCookie(cookie.name));
152
-
142
+ const setCookieHeader = request.headers.get('set-cookie');
153
143
  const responseHeaders: any = {};
154
144
 
155
- if (filteredCookies.length > 0) {
156
- responseHeaders['set-cookie'] = filteredCookies
157
- .map(formatCookieString)
158
- .join(', ');
145
+ if (setCookieHeader) {
146
+ responseHeaders['set-cookie'] = setCookieHeader;
159
147
  }
160
148
 
161
149
  return NextResponse.json(
@@ -1,6 +1,4 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const runScript = require('./run-script');
4
-
5
4
  runScript('pz-install-theme.js');
6
- // runScript('pz-pre-check-dist.js');
@@ -1,28 +1,17 @@
1
1
  import clsx from 'clsx';
2
- import { forwardRef, FocusEvent, useState, Ref } from 'react';
2
+ import { forwardRef, FocusEvent, useState } from 'react';
3
3
  import { Controller } from 'react-hook-form';
4
- import { PatternFormat, PatternFormatProps } from 'react-number-format';
4
+ import NumberFormat, { NumberFormatProps } from 'react-number-format';
5
5
  import { InputProps } from '../types';
6
6
  import { twMerge } from 'tailwind-merge';
7
7
 
8
- const PatternFormatWithRef = forwardRef(
9
- (props: PatternFormatProps, ref: Ref<HTMLInputElement>) => {
10
- return <PatternFormat {...props} getInputRef={ref} />;
11
- }
12
- );
13
- PatternFormatWithRef.displayName = 'PatternFormatWithRef';
14
-
15
8
  export const Input = forwardRef<
16
9
  HTMLInputElement,
17
10
  InputProps &
18
11
  Pick<
19
- PatternFormatProps,
20
- 'mask' | 'allowEmptyFormatting' | 'onValueChange'
21
- > & {
22
- format?: string;
23
- defaultValue?: string;
24
- type?: string;
25
- }
12
+ NumberFormatProps,
13
+ 'format' | 'mask' | 'allowEmptyFormatting' | 'onValueChange'
14
+ >
26
15
  >((props, ref) => {
27
16
  const [focused, setFocused] = useState(false);
28
17
  const [hasValue, setHasValue] = useState(false);
@@ -48,7 +37,6 @@ export const Input = forwardRef<
48
37
  ),
49
38
  props.className
50
39
  );
51
-
52
40
  const inputProps: any = {
53
41
  id,
54
42
  ref,
@@ -91,14 +79,14 @@ export const Input = forwardRef<
91
79
  <Controller
92
80
  name={props.name ?? ''}
93
81
  control={props.control}
82
+ defaultValue={false}
94
83
  render={({ field }) => (
95
- <PatternFormatWithRef
84
+ <NumberFormat
96
85
  format={format}
97
86
  mask={mask ?? ''}
98
87
  {...rest}
99
88
  {...field}
100
89
  {...inputProps}
101
- type={props.type as 'text' | 'password' | 'tel'}
102
90
  />
103
91
  )}
104
92
  />
@@ -1,11 +1,11 @@
1
1
  import { useMemo } from 'react';
2
- import { NumericFormat, NumericFormatProps } from 'react-number-format';
2
+ import NumberFormat, { NumberFormatProps } from 'react-number-format';
3
3
  import { getCurrency } from '@akinon/next/utils';
4
4
 
5
5
  import { useLocalization } from '@akinon/next/hooks';
6
6
  import { PriceProps } from '../types';
7
7
 
8
- export const Price = (props: NumericFormatProps & PriceProps) => {
8
+ export const Price = (props: NumberFormatProps & PriceProps) => {
9
9
  const {
10
10
  value,
11
11
  currencyCode,
@@ -39,7 +39,7 @@ export const Price = (props: NumericFormatProps & PriceProps) => {
39
39
  );
40
40
 
41
41
  return (
42
- <NumericFormat
42
+ <NumberFormat
43
43
  value={useNegative ? `-${useNegativeSpace}${_value}` : _value}
44
44
  {...{
45
45
  [useCurrencyAfterPrice ? 'suffix' : 'prefix']: currency
@@ -8,7 +8,7 @@ import logger from '../../utils/log';
8
8
 
9
9
  function getCategoryDataHandler(
10
10
  pk: number,
11
- searchParams?: { [key: string]: string | string[] | undefined },
11
+ searchParams?: URLSearchParams,
12
12
  headers?: Record<string, string>
13
13
  ) {
14
14
  return async function () {
@@ -78,7 +78,7 @@ export const getCategoryData = ({
78
78
  headers
79
79
  }: {
80
80
  pk: number;
81
- searchParams?: { [key: string]: string | string[] | undefined };
81
+ searchParams?: URLSearchParams;
82
82
  headers?: Record<string, string>;
83
83
  }) => {
84
84
  return Cache.wrap(
@@ -7,7 +7,7 @@ import { parse } from 'lossless-json';
7
7
  import logger from '../../utils/log';
8
8
 
9
9
  const getListDataHandler = (
10
- searchParams: { [key: string]: string | string[] | undefined },
10
+ searchParams: URLSearchParams,
11
11
  headers?: Record<string, string>
12
12
  ) => {
13
13
  return async function () {
@@ -54,7 +54,7 @@ export const getListData = async ({
54
54
  searchParams,
55
55
  headers
56
56
  }: {
57
- searchParams: { [key: string]: string | string[] | undefined };
57
+ searchParams: URLSearchParams;
58
58
  headers?: Record<string, string>;
59
59
  }) => {
60
60
  return Cache.wrap(
@@ -9,7 +9,7 @@ import appFetch from '../../utils/app-fetch';
9
9
 
10
10
  type GetProduct = {
11
11
  pk: number;
12
- searchParams?: { [key: string]: string | string[] | undefined };
12
+ searchParams?: URLSearchParams;
13
13
  groupProduct?: boolean;
14
14
  };
15
15
 
@@ -74,7 +74,10 @@ export const getProductData = async ({
74
74
  groupProduct
75
75
  }: GetProduct) => {
76
76
  return Cache.wrap(
77
- CacheKey[groupProduct ? 'GroupProduct' : 'Product'](pk, searchParams ?? {}),
77
+ CacheKey[groupProduct ? 'GroupProduct' : 'Product'](
78
+ pk,
79
+ searchParams ?? new URLSearchParams()
80
+ ),
78
81
  getProductDataHandler({ pk, searchParams, groupProduct }),
79
82
  {
80
83
  expire: 300
@@ -7,7 +7,7 @@ import header from '../../redux/reducers/header';
7
7
 
8
8
  const getSpecialPageDataHandler = (
9
9
  pk: number,
10
- searchParams: { [key: string]: string | string[] | undefined },
10
+ searchParams: URLSearchParams,
11
11
  headers?: Record<string, string>
12
12
  ) => {
13
13
  return async function () {
@@ -34,7 +34,7 @@ export const getSpecialPageData = async ({
34
34
  headers
35
35
  }: {
36
36
  pk: number;
37
- searchParams: { [key: string]: string | string[] | undefined };
37
+ searchParams: URLSearchParams;
38
38
  headers?: Record<string, string>;
39
39
  }) => {
40
40
  return Cache.wrap(
package/lib/cache.ts CHANGED
@@ -20,16 +20,13 @@ const hashCacheKey = (object?: Record<string, string>) => {
20
20
  return `_${encodeURIComponent(cacheKey)}`;
21
21
  };
22
22
  export const CacheKey = {
23
- List: (
24
- searchParams: { [key: string]: string | string[] | undefined },
25
- headers?: Record<string, string>
26
- ) =>
23
+ List: (searchParams: URLSearchParams, headers?: Record<string, string>) =>
27
24
  `list_${encodeURIComponent(JSON.stringify(searchParams))}${hashCacheKey(
28
25
  headers
29
26
  )}`,
30
27
  Category: (
31
28
  pk: number,
32
- searchParams?: { [key: string]: string | string[] | undefined },
29
+ searchParams?: URLSearchParams,
33
30
  headers?: Record<string, string>
34
31
  ) =>
35
32
  `category_${pk}_${encodeURIComponent(
@@ -38,20 +35,15 @@ export const CacheKey = {
38
35
  CategorySlug: (slug: string) => `category_${slug}`,
39
36
  SpecialPage: (
40
37
  pk: number,
41
- searchParams: { [key: string]: string | string[] | undefined },
38
+ searchParams: URLSearchParams,
42
39
  headers?: Record<string, string>
43
40
  ) =>
44
41
  `special_page_${pk}_${encodeURIComponent(
45
42
  JSON.stringify(searchParams)
46
43
  )}${hashCacheKey(headers)}`,
47
- Product: (
48
- pk: number,
49
- searchParams: { [key: string]: string | string[] | undefined }
50
- ) => `product_${pk}_${encodeURIComponent(JSON.stringify(searchParams))}`,
51
- GroupProduct: (
52
- pk: number,
53
- searchParams: { [key: string]: string | string[] | undefined }
54
- ) =>
44
+ Product: (pk: number, searchParams: URLSearchParams) =>
45
+ `product_${pk}_${encodeURIComponent(JSON.stringify(searchParams))}`,
46
+ GroupProduct: (pk: number, searchParams: URLSearchParams) =>
55
47
  `group_product_${pk}_${encodeURIComponent(JSON.stringify(searchParams))}`,
56
48
  FlatPage: (pk: number) => `flat_page_${pk}`,
57
49
  LandingPage: (pk: number) => `landing_page_${pk}`,
@@ -166,10 +158,6 @@ export class Cache {
166
158
  handler: () => Promise<T>,
167
159
  options?: CacheOptions
168
160
  ): Promise<T> {
169
- if (Settings.usePrettyUrlRoute) {
170
- return await handler();
171
- }
172
-
173
161
  const requiredVariables = [
174
162
  process.env.CACHE_HOST,
175
163
  process.env.CACHE_PORT,
@@ -33,7 +33,6 @@ const withCompleteGpay =
33
33
  async (req: PzNextRequest, event: NextFetchEvent) => {
34
34
  const url = req.nextUrl.clone();
35
35
  const ip = req.headers.get('x-forwarded-for') ?? '';
36
- const sessionId = req.cookies.get('osessionid');
37
36
 
38
37
  if (url.search.indexOf('GPayCompletePage') === -1) {
39
38
  return middleware(req, event);
@@ -51,24 +50,6 @@ const withCompleteGpay =
51
50
  try {
52
51
  const body = await streamToString(req.body);
53
52
 
54
- if (!sessionId) {
55
- logger.warn(
56
- 'Make sure that the SESSION_COOKIE_SAMESITE environment variable is set to None in Commerce.',
57
- {
58
- middleware: 'complete-masterpass',
59
- ip
60
- }
61
- );
62
-
63
- return NextResponse.redirect(
64
- `${url.origin}${getUrlPathWithLocale(
65
- '/orders/checkout/',
66
- req.cookies.get('pz-locale')?.value
67
- )}`,
68
- 303
69
- );
70
- }
71
-
72
53
  const request = await fetch(requestUrl, {
73
54
  method: 'POST',
74
55
  headers: requestHeaders,
@@ -33,7 +33,6 @@ const withCompleteMasterpass =
33
33
  async (req: PzNextRequest, event: NextFetchEvent) => {
34
34
  const url = req.nextUrl.clone();
35
35
  const ip = req.headers.get('x-forwarded-for') ?? '';
36
- const sessionId = req.cookies.get('osessionid');
37
36
 
38
37
  if (url.search.indexOf('MasterpassCompletePage') === -1) {
39
38
  return middleware(req, event);
@@ -51,24 +50,6 @@ const withCompleteMasterpass =
51
50
  try {
52
51
  const body = await streamToString(req.body);
53
52
 
54
- if (!sessionId) {
55
- logger.warn(
56
- 'Make sure that the SESSION_COOKIE_SAMESITE environment variable is set to None in Commerce.',
57
- {
58
- middleware: 'complete-masterpass',
59
- ip
60
- }
61
- );
62
-
63
- return NextResponse.redirect(
64
- `${url.origin}${getUrlPathWithLocale(
65
- '/orders/checkout/',
66
- req.cookies.get('pz-locale')?.value
67
- )}`,
68
- 303
69
- );
70
- }
71
-
72
53
  const request = await fetch(requestUrl, {
73
54
  method: 'POST',
74
55
  headers: requestHeaders,
@@ -200,15 +200,6 @@ const withPzDefault =
200
200
  );
201
201
  }
202
202
 
203
- if (
204
- Settings.usePrettyUrlRoute &&
205
- url.searchParams.toString().length > 0
206
- ) {
207
- url.pathname =
208
- url.pathname +
209
- `searchparams|${url.searchParams.toString()}`;
210
- }
211
-
212
203
  Settings.rewrites.forEach((rewrite) => {
213
204
  url.pathname = url.pathname.replace(
214
205
  rewrite.source,
@@ -56,10 +56,6 @@ const resolvePrettyUrl = async (pathname: string, ip: string | null) => {
56
56
  const withPrettyUrl =
57
57
  (middleware: NextMiddleware) =>
58
58
  async (req: PzNextRequest, event: NextFetchEvent) => {
59
- if (Settings.usePrettyUrlRoute) {
60
- return middleware(req, event);
61
- }
62
-
63
59
  const url = req.nextUrl.clone();
64
60
  const matchedLanguagePrefix = url.pathname.match(
65
61
  urlLocaleMatcherRegex
@@ -34,7 +34,6 @@ const withRedirectionPayment =
34
34
  const url = req.nextUrl.clone();
35
35
  const searchParams = new URLSearchParams(url.search);
36
36
  const ip = req.headers.get('x-forwarded-for') ?? '';
37
- const sessionId = req.cookies.get('osessionid');
38
37
 
39
38
  if (searchParams.get('page') !== 'RedirectionPageCompletePage') {
40
39
  return middleware(req, event);
@@ -47,29 +46,12 @@ const withRedirectionPayment =
47
46
  Cookie: req.headers.get('cookie') ?? '',
48
47
  'x-currency': req.cookies.get('pz-currency')?.value ?? '',
49
48
  'x-forwarded-for': ip
49
+
50
50
  };
51
51
 
52
52
  try {
53
53
  const body = await streamToString(req.body);
54
54
 
55
- if (!sessionId) {
56
- logger.warn(
57
- 'Make sure that the SESSION_COOKIE_SAMESITE environment variable is set to None in Commerce.',
58
- {
59
- middleware: 'redirection-payment',
60
- ip
61
- }
62
- );
63
-
64
- return NextResponse.redirect(
65
- `${url.origin}${getUrlPathWithLocale(
66
- '/orders/checkout/',
67
- req.cookies.get('pz-locale')?.value
68
- )}`,
69
- 303
70
- );
71
- }
72
-
73
55
  const request = await fetch(requestUrl, {
74
56
  method: 'POST',
75
57
  headers: requestHeaders,
@@ -33,7 +33,6 @@ const withThreeDRedirection =
33
33
  async (req: PzNextRequest, event: NextFetchEvent) => {
34
34
  const url = req.nextUrl.clone();
35
35
  const ip = req.headers.get('x-forwarded-for') ?? '';
36
- const sessionId = req.cookies.get('osessionid');
37
36
 
38
37
  if (url.search.indexOf('CreditCardThreeDSecurePage') === -1) {
39
38
  return middleware(req, event);
@@ -51,24 +50,6 @@ const withThreeDRedirection =
51
50
  try {
52
51
  const body = await streamToString(req.body);
53
52
 
54
- if (!sessionId) {
55
- logger.warn(
56
- 'Make sure that the SESSION_COOKIE_SAMESITE environment variable is set to None in Commerce.',
57
- {
58
- middleware: 'three-d-redirection',
59
- ip
60
- }
61
- );
62
-
63
- return NextResponse.redirect(
64
- `${url.origin}${getUrlPathWithLocale(
65
- '/orders/checkout/',
66
- req.cookies.get('pz-locale')?.value
67
- )}`,
68
- 303
69
- );
70
- }
71
-
72
53
  const request = await fetch(requestUrl, {
73
54
  method: 'POST',
74
55
  headers: requestHeaders,
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.34.0-rc.9",
4
+ "version": "1.35.0",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -20,22 +20,19 @@
20
20
  "@opentelemetry/sdk-trace-node": "1.19.0",
21
21
  "@opentelemetry/semantic-conventions": "1.19.0",
22
22
  "@reduxjs/toolkit": "1.9.7",
23
- "@neshca/cache-handler": "1.0.7",
24
23
  "cross-spawn": "7.0.3",
25
24
  "generic-pool": "3.9.0",
26
25
  "react-redux": "8.1.3",
27
26
  "react-string-replace": "1.1.1",
28
- "redis": "4.6.13",
29
- "semver": "7.5.4",
30
- "set-cookie-parser": "2.6.0"
27
+ "redis": "4.5.1",
28
+ "semver": "7.5.4"
31
29
  },
32
30
  "devDependencies": {
33
31
  "@types/react-redux": "7.1.30",
34
- "@types/set-cookie-parser": "2.4.7",
35
32
  "@typescript-eslint/eslint-plugin": "6.7.4",
36
33
  "@typescript-eslint/parser": "6.7.4",
37
34
  "eslint": "^8.14.0",
38
- "@akinon/eslint-plugin-projectzero": "1.34.0-rc.9",
35
+ "@akinon/eslint-plugin-projectzero": "1.35.0",
39
36
  "eslint-config-prettier": "8.5.0"
40
37
  }
41
38
  }
@@ -36,7 +36,6 @@ export type FacetChoice = {
36
36
  quantity: number;
37
37
  is_selected: boolean;
38
38
  url?: string;
39
- real_depth?: string;
40
39
  [key: string]: any;
41
40
  };
42
41
 
package/types/index.ts CHANGED
@@ -70,7 +70,6 @@ export interface Currency {
70
70
  }
71
71
 
72
72
  export interface Settings {
73
- usePrettyUrlRoute?: boolean;
74
73
  commerceUrl: string;
75
74
  redis: {
76
75
  defaultExpirationTime: number;
@@ -215,7 +214,7 @@ export type Translations = { [key: string]: object };
215
214
 
216
215
  export interface PageProps<T = any> {
217
216
  params: T;
218
- searchParams: { [key: string]: string | string[] | undefined };
217
+ searchParams: URLSearchParams;
219
218
  }
220
219
 
221
220
  export interface LayoutProps<T = any> extends PageProps<T> {
@@ -41,7 +41,7 @@ const appFetch = async <T>(
41
41
  };
42
42
 
43
43
  init.next = {
44
- revalidate: Settings.usePrettyUrlRoute ? 0 : 60
44
+ revalidate: 60
45
45
  };
46
46
 
47
47
  logger.debug(`FETCH START ${url}`, { requestURL, init, ip });
@@ -1,15 +1,11 @@
1
1
  import logger from './log';
2
2
 
3
- export const generateCommerceSearchParams = (searchParams?: {
4
- [key: string]: string | string[] | undefined;
5
- }) => {
3
+ export const generateCommerceSearchParams = (searchParams?: URLSearchParams) => {
6
4
  if (!searchParams) {
7
5
  return null;
8
6
  }
9
7
 
10
- const urlSerchParams = new URLSearchParams(
11
- searchParams as Record<string, string>
12
- );
8
+ const urlSerchParams = new URLSearchParams(searchParams);
13
9
 
14
10
  Object.entries(searchParams).forEach(([key, value]) => {
15
11
  if (typeof value === 'object') {
package/with-pz-config.js CHANGED
@@ -8,7 +8,6 @@ const defaultConfig = {
8
8
  transpilePackages: ['@akinon/next', ...pzPlugins.map((p) => `@akinon/${p}`)],
9
9
  skipTrailingSlashRedirect: true,
10
10
  poweredByHeader: false,
11
- cacheMaxMemorySize: 0,
12
11
  env: {
13
12
  NEXT_PUBLIC_SENTRY_DSN: process.env.SENTRY_DSN
14
13
  },
@@ -66,12 +65,7 @@ const defaultConfig = {
66
65
  }
67
66
  };
68
67
 
69
- const withPzConfig = (
70
- myNextConfig = {},
71
- options = {
72
- useCacheHandler: false
73
- }
74
- ) => {
68
+ const withPzConfig = (myNextConfig = {}) => {
75
69
  let extendedConfig = deepMerge({}, defaultConfig, myNextConfig);
76
70
 
77
71
  const originalPzHeadersFunction = defaultConfig.headers;
@@ -97,10 +91,6 @@ const withPzConfig = (
97
91
  return [...pzRewrites, ...myRewrites];
98
92
  };
99
93
 
100
- if (options.useCacheHandler) {
101
- extendedConfig.cacheHandler = require.resolve('./lib/cache-handler.mjs');
102
- }
103
-
104
94
  return extendedConfig;
105
95
  };
106
96
 
@@ -1,21 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const hashDirectory = require('../utils/hash-directory');
4
- const checkMonorepo = require('../utils/check-monorepo');
5
-
6
- const BASE_DIR = checkMonorepo();
7
-
8
- if (!BASE_DIR) {
9
- process.exit(0);
10
- }
11
-
12
- const packageDistPath = path.join(
13
- __dirname,
14
- '../../../packages/projectzero-cli/dist/commands'
15
- );
16
-
17
- const hash = hashDirectory(packageDistPath);
18
- fs.writeFileSync(
19
- path.join(__dirname, '../../../packages/projectzero-cli/dist/dist-hash.txt'),
20
- hash
21
- );
@@ -1,33 +0,0 @@
1
- import { CacheHandler } from '@neshca/cache-handler';
2
- import createLruHandler from '@neshca/cache-handler/local-lru';
3
- import createRedisHandler from '@neshca/cache-handler/redis-stack';
4
- import { createClient } from 'redis';
5
-
6
- CacheHandler.onCreation(async () => {
7
- const redisUrl = `redis://${process.env.CACHE_HOST}:${
8
- process.env.CACHE_PORT
9
- }/${process.env.CACHE_BUCKET ?? '0'}`;
10
-
11
- const client = createClient({
12
- url: redisUrl
13
- });
14
-
15
- client.on('error', (error) => {
16
- console.error('Redis client error', { redisUrl, error });
17
- });
18
-
19
- await client.connect();
20
-
21
- const redisHandler = await createRedisHandler({
22
- client,
23
- timeoutMs: 5000
24
- });
25
-
26
- const localHandler = createLruHandler();
27
-
28
- return {
29
- handlers: [redisHandler, localHandler]
30
- };
31
- });
32
-
33
- export default CacheHandler;
@@ -1,194 +0,0 @@
1
- import { URLS } from '@akinon/next/data/urls';
2
- import { Metadata, PageProps } from '@akinon/next/types';
3
- import logger from '@akinon/next/utils/log';
4
- import { notFound } from 'next/navigation';
5
-
6
- type PrettyUrlResult = {
7
- matched: boolean;
8
- path?: string;
9
- pk?: number;
10
- };
11
-
12
- const resolvePrettyUrlHandler =
13
- (pathname: string, ip: string | null) => async () => {
14
- let results = [] as { old_path: string }[];
15
- let prettyUrlResult: PrettyUrlResult = {
16
- matched: false
17
- };
18
-
19
- try {
20
- const requestUrl = URLS.misc.prettyUrls(`/${pathname}/`);
21
-
22
- logger.debug(`Resolving pretty url`, { pathname, requestUrl, ip });
23
-
24
- const start = Date.now();
25
- const apiResponse = await fetch(requestUrl, {
26
- next: {
27
- revalidate: 0
28
- }
29
- });
30
- const data = await apiResponse.json();
31
- ({ results } = data);
32
- const end = Date.now();
33
- console.warn('Pretty url response time', end - start, requestUrl);
34
-
35
- const matched = results.length > 0;
36
- const [{ old_path: path } = { old_path: '' }] = results;
37
- let pk;
38
-
39
- if (matched) {
40
- const pkRegex = /\/(\d+)\/$/;
41
- const match = path.match(pkRegex);
42
- pk = match ? parseInt(match[1]) : undefined;
43
- }
44
-
45
- prettyUrlResult = {
46
- matched,
47
- path,
48
- pk
49
- };
50
-
51
- logger.trace('Pretty url result', { prettyUrlResult, ip });
52
- } catch (error) {
53
- logger.error('Error resolving pretty url', { error, pathname, ip });
54
- }
55
-
56
- return prettyUrlResult;
57
- };
58
-
59
- export async function generateMetadata({ params }: PageProps) {
60
- let result: Metadata = {};
61
- const { prettyurl } = params;
62
- const pageSlug = prettyurl
63
- .filter((x) => !x.startsWith('searchparams'))
64
- .join('/');
65
-
66
- const searchParams = Object.fromEntries(
67
- new URLSearchParams(
68
- decodeURIComponent(
69
- prettyurl
70
- .find((x) => x.startsWith('searchparams'))
71
- ?.replace('searchparams%7C', '')
72
- ) ?? {}
73
- ).entries()
74
- );
75
-
76
- const prettyUrlResult = await resolvePrettyUrlHandler(pageSlug, null)();
77
-
78
- if (!prettyUrlResult.matched) {
79
- return notFound();
80
- }
81
-
82
- const commonProps = {
83
- params: {
84
- ...params,
85
- pk: prettyUrlResult.pk
86
- },
87
- searchParams
88
- };
89
-
90
- try {
91
- if (prettyUrlResult.path.startsWith('/product/')) {
92
- await import('@product/[pk]/page').then(async (module) => {
93
- result = await module['generateMetadata']?.(commonProps);
94
- });
95
- }
96
-
97
- if (prettyUrlResult.path.startsWith('/group-product/')) {
98
- await import('@group-product/[pk]/page').then(async (module) => {
99
- result = await module['generateMetadata']?.(commonProps);
100
- });
101
- }
102
-
103
- if (prettyUrlResult.path.startsWith('/category/')) {
104
- await import('@category/[pk]/page').then(async (module) => {
105
- result = await module['generateMetadata']?.(commonProps);
106
- });
107
- }
108
-
109
- if (prettyUrlResult.path.startsWith('/special-page/')) {
110
- await import('@special-page/[pk]/page').then(async (module) => {
111
- result = await module['generateMetadata']?.(commonProps);
112
- });
113
- }
114
-
115
- if (prettyUrlResult.path.startsWith('/flat-page/')) {
116
- await import('@flat-page/[pk]/page').then(async (module) => {
117
- result = await module['generateMetadata']?.(commonProps);
118
- });
119
- }
120
- // eslint-disable-next-line no-empty
121
- } catch (error) {}
122
-
123
- return result;
124
- }
125
-
126
- export const dynamic = 'force-static';
127
- export const revalidate = 300;
128
-
129
- export default async function Page({ params }) {
130
- const { prettyurl } = params;
131
- const pageSlug = prettyurl
132
- .filter((x) => !x.startsWith('searchparams'))
133
- .join('/');
134
-
135
- const urlSearchParams = new URLSearchParams(
136
- decodeURIComponent(
137
- prettyurl
138
- .find((x) => x.startsWith('searchparams'))
139
- ?.replace('searchparams%7C', '')
140
- ) ?? {}
141
- );
142
-
143
- const searchParams = {};
144
-
145
- for (const [key, value] of urlSearchParams.entries() as unknown as Array<
146
- [string, string]
147
- >) {
148
- if (!searchParams[key]) {
149
- searchParams[key] = [];
150
- }
151
- searchParams[key].push(value);
152
- }
153
-
154
- const result = await resolvePrettyUrlHandler(pageSlug, null)();
155
-
156
- if (!result.matched) {
157
- return notFound();
158
- }
159
-
160
- const commonProps = {
161
- params: {
162
- ...params,
163
- pk: result.pk
164
- },
165
- searchParams
166
- };
167
-
168
- if (result.path.startsWith('/category/')) {
169
- const CategoryPage = (await import('@category/[pk]/page')).default;
170
- return <CategoryPage {...commonProps} />;
171
- }
172
-
173
- if (result.path.startsWith('/product/')) {
174
- const ProductPage = (await import('@product/[pk]/page')).default;
175
- return <ProductPage {...commonProps} />;
176
- }
177
-
178
- if (result.path.startsWith('/group-product/')) {
179
- const GroupProduct = (await import('@group-product/[pk]/page')).default;
180
- return <GroupProduct {...commonProps} />;
181
- }
182
-
183
- if (result.path.startsWith('/special-page/')) {
184
- const SpecialPage = (await import('@special-page/[pk]/page')).default;
185
- return <SpecialPage {...commonProps} />;
186
- }
187
-
188
- if (result.path.startsWith('/flat-page/')) {
189
- const FlatPage = (await import('@flat-page/[pk]/page')).default;
190
- return <FlatPage {...commonProps} />;
191
- }
192
-
193
- return null;
194
- }
@@ -1,15 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- function checkMonorepo() {
5
- let currentDir = __dirname;
6
- while (currentDir !== path.resolve(currentDir, '..')) {
7
- if (fs.existsSync(path.join(currentDir, 'turbo.json'))) {
8
- return currentDir;
9
- }
10
- currentDir = path.resolve(currentDir, '..');
11
- }
12
- return null;
13
- }
14
-
15
- module.exports = checkMonorepo;
@@ -1,27 +0,0 @@
1
- export default function formatCookieString(cookieObj: Record<string, any>) {
2
- const cookieParts = [`${cookieObj.name}=${cookieObj.value}`];
3
-
4
- if (cookieObj.expires) {
5
- cookieParts.push(`Expires=${cookieObj.expires.toUTCString()}`);
6
- }
7
- if (cookieObj.maxAge) {
8
- cookieParts.push(`Max-Age=${cookieObj.maxAge}`);
9
- }
10
- if (cookieObj.path) {
11
- cookieParts.push(`Path=${cookieObj.path}`);
12
- }
13
- if (cookieObj.domain) {
14
- cookieParts.push(`Domain=${cookieObj.domain}`);
15
- }
16
- if (cookieObj.secure) {
17
- cookieParts.push('Secure');
18
- }
19
- if (cookieObj.httpOnly) {
20
- cookieParts.push('HttpOnly');
21
- }
22
- if (cookieObj.sameSite) {
23
- cookieParts.push(`SameSite=${cookieObj.sameSite}`);
24
- }
25
-
26
- return cookieParts.join('; ');
27
- }
@@ -1,18 +0,0 @@
1
- const { createHash } = require('crypto');
2
- const fs = require('fs');
3
- const path = require('path');
4
-
5
- function hashDirectory(directory) {
6
- const files = fs.readdirSync(directory).sort();
7
- const hash = createHash('sha256');
8
- files.forEach((file) => {
9
- const filePath = path.join(directory, file);
10
- if (fs.statSync(filePath).isFile()) {
11
- const fileBuffer = fs.readFileSync(filePath);
12
- hash.update(fileBuffer);
13
- }
14
- });
15
- return hash.digest('hex');
16
- }
17
-
18
- module.exports = hashDirectory;