@akinon/next 1.30.0 → 1.31.0-rc.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @akinon/next
2
2
 
3
+ ## 1.31.0-rc.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6d4aadb: ZERO-2476: Auto install recommendenent extension
8
+ - f0c23bc: ZERO-2135: add custom not found page
9
+ - 495d155: ZERO-2505: findBaseDir function is united and move on to the utils
10
+ - 40ad73e: ZERO-2504: add cookie filter to api client request
11
+ - 495d155: ZERO-2524: Zero-cli dist checks for changes and renders it to the terminal.
12
+ - 6b2972b: ZERO-2514: Fix handling of status 204 and return Commerce status code in client proxy API.
13
+
3
14
  ## 1.30.0
4
15
 
5
16
  ### Minor Changes
package/api/client.ts CHANGED
@@ -2,6 +2,8 @@ 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';
5
7
 
6
8
  interface RouteParams {
7
9
  params: {
@@ -113,6 +115,14 @@ async function proxyRequest(...args) {
113
115
 
114
116
  try {
115
117
  const request = await fetch(url, fetchOptions);
118
+
119
+ // Using NextResponse.json with status 204 will cause an error
120
+ if (request.status === 204) {
121
+ return new Response(null, {
122
+ status: 204
123
+ });
124
+ }
125
+
116
126
  let response = {} as any;
117
127
 
118
128
  try {
@@ -131,20 +141,26 @@ async function proxyRequest(...args) {
131
141
  );
132
142
  }
133
143
 
134
- const setCookieHeader = request.headers.get('set-cookie');
144
+ const setCookieHeaders = req.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
+
135
153
  const responseHeaders: any = {};
136
154
 
137
- if (setCookieHeader) {
138
- responseHeaders['set-cookie'] = setCookieHeader;
155
+ if (filteredCookies.length > 0) {
156
+ responseHeaders['set-cookie'] = filteredCookies
157
+ .map(formatCookieString)
158
+ .join(', ');
139
159
  }
140
160
 
141
- const statusCode = new RegExp(/^20./).test(request.status.toString())
142
- ? 200
143
- : request.status;
144
-
145
161
  return NextResponse.json(
146
162
  options.responseType === 'text' ? { result: response } : response,
147
- { status: statusCode, headers: responseHeaders }
163
+ { status: request.status, headers: responseHeaders }
148
164
  );
149
165
  } catch (error) {
150
166
  logger.error('Client proxy request failed', error);
@@ -0,0 +1,43 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const projectZeroNextDir = path.join(
4
+ __dirname,
5
+ '../../../apps/projectzeronext'
6
+ );
7
+
8
+ const templatesDir = path.join(
9
+ __dirname,
10
+ '../../../packages/projectzero-cli/app-template'
11
+ );
12
+
13
+ if (fs.existsSync(templatesDir)) {
14
+ fs.rmdirSync(templatesDir, { recursive: true });
15
+ }
16
+
17
+ function copyRecursively(src, dest) {
18
+ if (path.basename(src) === 'node_modules') {
19
+ return;
20
+ }
21
+
22
+ if (fs.existsSync(src) && fs.statSync(src).isDirectory()) {
23
+ fs.mkdirSync(dest, { recursive: true });
24
+ fs.readdirSync(src).forEach((childItemName) => {
25
+ const childSrcPath = path.join(src, childItemName);
26
+ const childDestPath = path.join(dest, childItemName);
27
+ copyRecursively(childSrcPath, childDestPath);
28
+ });
29
+ } else {
30
+ fs.copyFileSync(src, dest);
31
+ }
32
+ }
33
+
34
+ if (!fs.existsSync(templatesDir)) {
35
+ fs.mkdirSync(templatesDir, { recursive: true });
36
+ }
37
+
38
+ copyRecursively(projectZeroNextDir, templatesDir);
39
+
40
+ console.log(
41
+ '\x1b[33m%s\x1b[0m',
42
+ 'projectzeronext content has been copied to templates.'
43
+ );
@@ -0,0 +1,27 @@
1
+ const { execSync } = require('child_process');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+
5
+ function findBaseDir() {
6
+ let currentDir = __dirname;
7
+ while (currentDir !== path.resolve(currentDir, '..')) {
8
+ if (fs.existsSync(path.join(currentDir, 'turbo.json'))) {
9
+ return currentDir;
10
+ }
11
+ currentDir = path.resolve(currentDir, '..');
12
+ }
13
+ return null;
14
+ }
15
+
16
+ const BASE_DIR = findBaseDir();
17
+
18
+ if (BASE_DIR) {
19
+ const extensions = ['bilal-akinon.pznext'];
20
+ extensions.forEach((extension) => {
21
+ try {
22
+ execSync(`code --install-extension ${extension}`, { stdio: 'inherit' });
23
+ } catch (error) {
24
+ console.error(`Error installing ${extension}:`);
25
+ }
26
+ });
27
+ }
@@ -1,13 +1,7 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
3
  const { execSync } = require('child_process');
4
-
5
- function findBaseDir() {
6
- const insideNodeModules = __dirname.includes('node_modules');
7
- return insideNodeModules
8
- ? process.cwd()
9
- : path.resolve(__dirname, '../../../apps/projectzeronext');
10
- }
4
+ const findBaseDir = require('../utils/find-base-dir');
11
5
 
12
6
  const BASE_DIR = findBaseDir();
13
7
  const getFullPath = (relativePath) => path.join(BASE_DIR, relativePath);
@@ -3,16 +3,7 @@
3
3
  const fs = require('fs');
4
4
  const path = require('path');
5
5
  const spawn = require('cross-spawn');
6
-
7
- function findBaseDir() {
8
- const insideNodeModules = __dirname.includes('node_modules');
9
-
10
- if (insideNodeModules) {
11
- return path.resolve(__dirname, '../../../../');
12
- } else {
13
- return path.resolve(__dirname, '../../../apps/projectzeronext');
14
- }
15
- }
6
+ const findBaseDir = require('../utils/find-base-dir');
16
7
 
17
8
  const BASE_DIR = findBaseDir();
18
9
 
@@ -0,0 +1,14 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const hashDirectory = require('../utils/hash-directory');
4
+
5
+ const packageDistPath = path.join(
6
+ __dirname,
7
+ '../../../packages/projectzero-cli/dist/commands'
8
+ );
9
+
10
+ const hash = hashDirectory(packageDistPath);
11
+ fs.writeFileSync(
12
+ path.join(__dirname, '../../../packages/projectzero-cli/dist/dist-hash.txt'),
13
+ hash
14
+ );
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const runScript = require('./run-script');
4
+
4
5
  runScript('pz-install-theme.js');
6
+ runScript('pz-pre-check-dist.js');
package/bin/pz-predev.js CHANGED
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const runScript = require('./run-script');
4
+
5
+ runScript('pz-install-extensions.js');
4
6
  runScript('pz-check-env.js');
5
7
  runScript('pz-install-theme.js');
@@ -153,6 +153,7 @@ const withPzDefault =
153
153
 
154
154
  req.middlewareParams = {
155
155
  commerceUrl,
156
+ found: true,
156
157
  rewrites: {}
157
158
  };
158
159
 
@@ -186,6 +187,19 @@ const withPzDefault =
186
187
  locale.length ? `${locale}/` : ''
187
188
  }${currency}${prettyUrl ?? pathnameWithoutLocale}`;
188
189
 
190
+ if (
191
+ !req.middlewareParams.found &&
192
+ Settings.customNotFoundEnabled
193
+ ) {
194
+ let pathname = url.pathname
195
+ .replace(/\/+$/, '')
196
+ .split('/');
197
+ url.pathname = url.pathname.replace(
198
+ pathname.pop(),
199
+ 'pz-not-found'
200
+ );
201
+ }
202
+
189
203
  Settings.rewrites.forEach((rewrite) => {
190
204
  url.pathname = url.pathname.replace(
191
205
  rewrite.source,
@@ -26,6 +26,7 @@ export {
26
26
  export interface PzNextRequest extends NextRequest {
27
27
  middlewareParams: {
28
28
  commerceUrl: string;
29
+ found: boolean;
29
30
  rewrites: {
30
31
  locale?: string;
31
32
  prettyUrl?: string;
@@ -98,6 +98,8 @@ const withPrettyUrl =
98
98
  return middleware(req, event);
99
99
  }
100
100
 
101
+ req.middlewareParams.found = false;
102
+
101
103
  return middleware(req, event);
102
104
  };
103
105
 
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.30.0",
4
+ "version": "1.31.0-rc.0",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -25,14 +25,16 @@
25
25
  "react-redux": "8.1.3",
26
26
  "react-string-replace": "1.1.1",
27
27
  "redis": "4.5.1",
28
- "semver": "7.5.4"
28
+ "semver": "7.5.4",
29
+ "set-cookie-parser": "2.6.0"
29
30
  },
30
31
  "devDependencies": {
31
32
  "@types/react-redux": "7.1.30",
33
+ "@types/set-cookie-parser": "2.4.7",
32
34
  "@typescript-eslint/eslint-plugin": "6.7.4",
33
35
  "@typescript-eslint/parser": "6.7.4",
34
36
  "eslint": "^8.14.0",
35
- "@akinon/eslint-plugin-projectzero": "1.30.0",
37
+ "@akinon/eslint-plugin-projectzero": "1.31.0-rc.0",
36
38
  "eslint-config-prettier": "8.5.0"
37
39
  }
38
40
  }
package/types/index.ts CHANGED
@@ -181,6 +181,7 @@ export interface Settings {
181
181
  extraPaymentTypes?: string[];
182
182
  masterpassJsUrl?: string;
183
183
  };
184
+ customNotFoundEnabled: boolean;
184
185
  }
185
186
 
186
187
  export interface CacheOptions {
@@ -0,0 +1,13 @@
1
+ const path = require('path');
2
+
3
+ function findBaseDir() {
4
+ const insideNodeModules = __dirname.includes('node_modules');
5
+
6
+ if (insideNodeModules) {
7
+ return path.resolve(__dirname, '../../../../');
8
+ } else {
9
+ return path.resolve(__dirname, '../../../apps/projectzeronext');
10
+ }
11
+ }
12
+
13
+ module.exports = findBaseDir;
@@ -0,0 +1,27 @@
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
+ }
@@ -0,0 +1,18 @@
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;