@sitecore-jss/sitecore-jss-nextjs 22.6.0-canary.6 → 22.6.0-canary.8

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.
@@ -33,6 +33,86 @@ class RedirectsMiddleware extends middleware_1.MiddlewareBase {
33
33
  super(config);
34
34
  this.config = config;
35
35
  this.handler = (req, res) => __awaiter(this, void 0, void 0, function* () {
36
+ return this.processRedirectRequest(req, res);
37
+ });
38
+ // NOTE: we provide native fetch for compatibility on Next.js Edge Runtime
39
+ // (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
40
+ this.redirectsService = new site_1.GraphQLRedirectsService(Object.assign(Object.assign({}, config), { fetch: fetch }));
41
+ this.locales = config.locales;
42
+ }
43
+ /**
44
+ * Gets the Next.js middleware handler with error handling
45
+ * @returns route handler
46
+ */
47
+ getHandler() {
48
+ return (req, res) => __awaiter(this, void 0, void 0, function* () {
49
+ try {
50
+ return yield this.handler(req, res);
51
+ }
52
+ catch (error) {
53
+ console.log('Redirect middleware failed:');
54
+ console.log(error);
55
+ return res || server_1.NextResponse.next();
56
+ }
57
+ });
58
+ }
59
+ /**
60
+ * Method returns RedirectInfo when matches
61
+ * @param {NextRequest} req request
62
+ * @param {string} siteName site name
63
+ * @returns Promise<RedirectInfo | undefined> The redirect info or undefined if no redirect is found
64
+ * @protected
65
+ */
66
+ getExistsRedirect(req, siteName) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ const { pathname: targetURL, search: targetQS = '', locale } = this.normalizeUrl(req.nextUrl.clone());
69
+ const normalizedPath = targetURL.replace(/\/*$/gi, '');
70
+ const redirects = yield this.redirectsService.fetchRedirects(siteName);
71
+ const language = this.getLanguage(req);
72
+ const modifyRedirects = structuredClone(redirects);
73
+ let matchedQueryString;
74
+ return modifyRedirects.length
75
+ ? modifyRedirects.find((redirect) => {
76
+ var _a;
77
+ if ((0, utils_1.isRegexOrUrl)(redirect.pattern) === 'url') {
78
+ const parseUrlPattern = redirect.pattern.endsWith('/')
79
+ ? redirect.pattern.slice(0, -1).split('?')
80
+ : redirect.pattern.split('?');
81
+ return ((parseUrlPattern[0] === normalizedPath ||
82
+ parseUrlPattern[0] === `/${locale}${normalizedPath}`) &&
83
+ (0, utils_1.areURLSearchParamsEqual)(new URLSearchParams((_a = parseUrlPattern[1]) !== null && _a !== void 0 ? _a : ''), new URLSearchParams(targetQS)));
84
+ }
85
+ // Modify the redirect pattern to ignore the language prefix in the path
86
+ // And escapes non-special "?" characters in a string or regex.
87
+ redirect.pattern = (0, utils_1.escapeNonSpecialQuestionMarks)(redirect.pattern.replace(new RegExp(`^[^]?/${language}/`, 'gi'), ''));
88
+ // Prepare the redirect pattern as a regular expression, making it more flexible for matching URLs
89
+ redirect.pattern = `/^\/${redirect.pattern
90
+ .replace(/^\/|\/$/g, '') // Removes leading and trailing slashes
91
+ .replace(/^\^\/|\/\$$/g, '') // Removes unnecessary start (^) and end ($) anchors
92
+ .replace(/^\^|\$$/g, '') // Further cleans up anchors
93
+ .replace(/\$\/gi$/g, '')}[\/]?$/i`; // Ensures the pattern allows an optional trailing slash
94
+ matchedQueryString = [
95
+ (0, regex_parser_1.default)(redirect.pattern).test(`${normalizedPath}${targetQS}`),
96
+ (0, regex_parser_1.default)(redirect.pattern).test(`/${locale}${normalizedPath}${targetQS}`),
97
+ ].some(Boolean)
98
+ ? targetQS
99
+ : undefined;
100
+ // Save the matched query string (if found) into the redirect object
101
+ redirect.matchedQueryString = matchedQueryString || '';
102
+ return (!!((0, regex_parser_1.default)(redirect.pattern).test(targetURL) ||
103
+ (0, regex_parser_1.default)(redirect.pattern).test(`/${req.nextUrl.locale}${targetURL}`) ||
104
+ matchedQueryString) && (redirect.locale ? redirect.locale.toLowerCase() === locale.toLowerCase() : true));
105
+ })
106
+ : undefined;
107
+ });
108
+ }
109
+ /**
110
+ * @param {NextRequest} req request
111
+ * @param {Response} res response
112
+ * @returns {Promise<NextResponse>} The redirect response.
113
+ */
114
+ processRedirectRequest(req, res) {
115
+ return __awaiter(this, void 0, void 0, function* () {
36
116
  const pathname = req.nextUrl.pathname;
37
117
  const language = this.getLanguage(req);
38
118
  const hostname = this.getHostHeader(req) || this.defaultHostname;
@@ -129,76 +209,6 @@ class RedirectsMiddleware extends middleware_1.MiddlewareBase {
129
209
  });
130
210
  return response;
131
211
  });
132
- // NOTE: we provide native fetch for compatibility on Next.js Edge Runtime
133
- // (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
134
- this.redirectsService = new site_1.GraphQLRedirectsService(Object.assign(Object.assign({}, config), { fetch: fetch }));
135
- this.locales = config.locales;
136
- }
137
- /**
138
- * Gets the Next.js middleware handler with error handling
139
- * @returns route handler
140
- */
141
- getHandler() {
142
- return (req, res) => __awaiter(this, void 0, void 0, function* () {
143
- try {
144
- return yield this.handler(req, res);
145
- }
146
- catch (error) {
147
- console.log('Redirect middleware failed:');
148
- console.log(error);
149
- return res || server_1.NextResponse.next();
150
- }
151
- });
152
- }
153
- /**
154
- * Method returns RedirectInfo when matches
155
- * @param {NextRequest} req request
156
- * @param {string} siteName site name
157
- * @returns Promise<RedirectInfo | undefined>
158
- * @private
159
- */
160
- getExistsRedirect(req, siteName) {
161
- return __awaiter(this, void 0, void 0, function* () {
162
- const { pathname: targetURL, search: targetQS = '', locale } = this.normalizeUrl(req.nextUrl.clone());
163
- const normalizedPath = targetURL.replace(/\/*$/gi, '');
164
- const redirects = yield this.redirectsService.fetchRedirects(siteName);
165
- const language = this.getLanguage(req);
166
- const modifyRedirects = structuredClone(redirects);
167
- let matchedQueryString;
168
- return modifyRedirects.length
169
- ? modifyRedirects.find((redirect) => {
170
- var _a;
171
- if ((0, utils_1.isRegexOrUrl)(redirect.pattern) === 'url') {
172
- const parseUrlPattern = redirect.pattern.endsWith('/')
173
- ? redirect.pattern.slice(0, -1).split('?')
174
- : redirect.pattern.split('?');
175
- return ((parseUrlPattern[0] === normalizedPath ||
176
- parseUrlPattern[0] === `/${locale}${normalizedPath}`) &&
177
- (0, utils_1.areURLSearchParamsEqual)(new URLSearchParams((_a = parseUrlPattern[1]) !== null && _a !== void 0 ? _a : ''), new URLSearchParams(targetQS)));
178
- }
179
- // Modify the redirect pattern to ignore the language prefix in the path
180
- // And escapes non-special "?" characters in a string or regex.
181
- redirect.pattern = (0, utils_1.escapeNonSpecialQuestionMarks)(redirect.pattern.replace(new RegExp(`^[^]?/${language}/`, 'gi'), ''));
182
- // Prepare the redirect pattern as a regular expression, making it more flexible for matching URLs
183
- redirect.pattern = `/^\/${redirect.pattern
184
- .replace(/^\/|\/$/g, '') // Removes leading and trailing slashes
185
- .replace(/^\^\/|\/\$$/g, '') // Removes unnecessary start (^) and end ($) anchors
186
- .replace(/^\^|\$$/g, '') // Further cleans up anchors
187
- .replace(/\$\/gi$/g, '')}[\/]?$/i`; // Ensures the pattern allows an optional trailing slash
188
- matchedQueryString = [
189
- (0, regex_parser_1.default)(redirect.pattern).test(`${normalizedPath}${targetQS}`),
190
- (0, regex_parser_1.default)(redirect.pattern).test(`/${locale}${normalizedPath}${targetQS}`),
191
- ].some(Boolean)
192
- ? targetQS
193
- : undefined;
194
- // Save the matched query string (if found) into the redirect object
195
- redirect.matchedQueryString = matchedQueryString || '';
196
- return (!!((0, regex_parser_1.default)(redirect.pattern).test(targetURL) ||
197
- (0, regex_parser_1.default)(redirect.pattern).test(`/${req.nextUrl.locale}${targetURL}`) ||
198
- matchedQueryString) && (redirect.locale ? redirect.locale.toLowerCase() === locale.toLowerCase() : true));
199
- })
200
- : undefined;
201
- });
202
212
  }
203
213
  /**
204
214
  * When a user clicks on a link generated by the Link component from next/link,
@@ -27,6 +27,86 @@ export class RedirectsMiddleware extends MiddlewareBase {
27
27
  super(config);
28
28
  this.config = config;
29
29
  this.handler = (req, res) => __awaiter(this, void 0, void 0, function* () {
30
+ return this.processRedirectRequest(req, res);
31
+ });
32
+ // NOTE: we provide native fetch for compatibility on Next.js Edge Runtime
33
+ // (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
34
+ this.redirectsService = new GraphQLRedirectsService(Object.assign(Object.assign({}, config), { fetch: fetch }));
35
+ this.locales = config.locales;
36
+ }
37
+ /**
38
+ * Gets the Next.js middleware handler with error handling
39
+ * @returns route handler
40
+ */
41
+ getHandler() {
42
+ return (req, res) => __awaiter(this, void 0, void 0, function* () {
43
+ try {
44
+ return yield this.handler(req, res);
45
+ }
46
+ catch (error) {
47
+ console.log('Redirect middleware failed:');
48
+ console.log(error);
49
+ return res || NextResponse.next();
50
+ }
51
+ });
52
+ }
53
+ /**
54
+ * Method returns RedirectInfo when matches
55
+ * @param {NextRequest} req request
56
+ * @param {string} siteName site name
57
+ * @returns Promise<RedirectInfo | undefined> The redirect info or undefined if no redirect is found
58
+ * @protected
59
+ */
60
+ getExistsRedirect(req, siteName) {
61
+ return __awaiter(this, void 0, void 0, function* () {
62
+ const { pathname: targetURL, search: targetQS = '', locale } = this.normalizeUrl(req.nextUrl.clone());
63
+ const normalizedPath = targetURL.replace(/\/*$/gi, '');
64
+ const redirects = yield this.redirectsService.fetchRedirects(siteName);
65
+ const language = this.getLanguage(req);
66
+ const modifyRedirects = structuredClone(redirects);
67
+ let matchedQueryString;
68
+ return modifyRedirects.length
69
+ ? modifyRedirects.find((redirect) => {
70
+ var _a;
71
+ if (isRegexOrUrl(redirect.pattern) === 'url') {
72
+ const parseUrlPattern = redirect.pattern.endsWith('/')
73
+ ? redirect.pattern.slice(0, -1).split('?')
74
+ : redirect.pattern.split('?');
75
+ return ((parseUrlPattern[0] === normalizedPath ||
76
+ parseUrlPattern[0] === `/${locale}${normalizedPath}`) &&
77
+ areURLSearchParamsEqual(new URLSearchParams((_a = parseUrlPattern[1]) !== null && _a !== void 0 ? _a : ''), new URLSearchParams(targetQS)));
78
+ }
79
+ // Modify the redirect pattern to ignore the language prefix in the path
80
+ // And escapes non-special "?" characters in a string or regex.
81
+ redirect.pattern = escapeNonSpecialQuestionMarks(redirect.pattern.replace(new RegExp(`^[^]?/${language}/`, 'gi'), ''));
82
+ // Prepare the redirect pattern as a regular expression, making it more flexible for matching URLs
83
+ redirect.pattern = `/^\/${redirect.pattern
84
+ .replace(/^\/|\/$/g, '') // Removes leading and trailing slashes
85
+ .replace(/^\^\/|\/\$$/g, '') // Removes unnecessary start (^) and end ($) anchors
86
+ .replace(/^\^|\$$/g, '') // Further cleans up anchors
87
+ .replace(/\$\/gi$/g, '')}[\/]?$/i`; // Ensures the pattern allows an optional trailing slash
88
+ matchedQueryString = [
89
+ regexParser(redirect.pattern).test(`${normalizedPath}${targetQS}`),
90
+ regexParser(redirect.pattern).test(`/${locale}${normalizedPath}${targetQS}`),
91
+ ].some(Boolean)
92
+ ? targetQS
93
+ : undefined;
94
+ // Save the matched query string (if found) into the redirect object
95
+ redirect.matchedQueryString = matchedQueryString || '';
96
+ return (!!(regexParser(redirect.pattern).test(targetURL) ||
97
+ regexParser(redirect.pattern).test(`/${req.nextUrl.locale}${targetURL}`) ||
98
+ matchedQueryString) && (redirect.locale ? redirect.locale.toLowerCase() === locale.toLowerCase() : true));
99
+ })
100
+ : undefined;
101
+ });
102
+ }
103
+ /**
104
+ * @param {NextRequest} req request
105
+ * @param {Response} res response
106
+ * @returns {Promise<NextResponse>} The redirect response.
107
+ */
108
+ processRedirectRequest(req, res) {
109
+ return __awaiter(this, void 0, void 0, function* () {
30
110
  const pathname = req.nextUrl.pathname;
31
111
  const language = this.getLanguage(req);
32
112
  const hostname = this.getHostHeader(req) || this.defaultHostname;
@@ -123,76 +203,6 @@ export class RedirectsMiddleware extends MiddlewareBase {
123
203
  });
124
204
  return response;
125
205
  });
126
- // NOTE: we provide native fetch for compatibility on Next.js Edge Runtime
127
- // (underlying default 'cross-fetch' is not currently compatible: https://github.com/lquixada/cross-fetch/issues/78)
128
- this.redirectsService = new GraphQLRedirectsService(Object.assign(Object.assign({}, config), { fetch: fetch }));
129
- this.locales = config.locales;
130
- }
131
- /**
132
- * Gets the Next.js middleware handler with error handling
133
- * @returns route handler
134
- */
135
- getHandler() {
136
- return (req, res) => __awaiter(this, void 0, void 0, function* () {
137
- try {
138
- return yield this.handler(req, res);
139
- }
140
- catch (error) {
141
- console.log('Redirect middleware failed:');
142
- console.log(error);
143
- return res || NextResponse.next();
144
- }
145
- });
146
- }
147
- /**
148
- * Method returns RedirectInfo when matches
149
- * @param {NextRequest} req request
150
- * @param {string} siteName site name
151
- * @returns Promise<RedirectInfo | undefined>
152
- * @private
153
- */
154
- getExistsRedirect(req, siteName) {
155
- return __awaiter(this, void 0, void 0, function* () {
156
- const { pathname: targetURL, search: targetQS = '', locale } = this.normalizeUrl(req.nextUrl.clone());
157
- const normalizedPath = targetURL.replace(/\/*$/gi, '');
158
- const redirects = yield this.redirectsService.fetchRedirects(siteName);
159
- const language = this.getLanguage(req);
160
- const modifyRedirects = structuredClone(redirects);
161
- let matchedQueryString;
162
- return modifyRedirects.length
163
- ? modifyRedirects.find((redirect) => {
164
- var _a;
165
- if (isRegexOrUrl(redirect.pattern) === 'url') {
166
- const parseUrlPattern = redirect.pattern.endsWith('/')
167
- ? redirect.pattern.slice(0, -1).split('?')
168
- : redirect.pattern.split('?');
169
- return ((parseUrlPattern[0] === normalizedPath ||
170
- parseUrlPattern[0] === `/${locale}${normalizedPath}`) &&
171
- areURLSearchParamsEqual(new URLSearchParams((_a = parseUrlPattern[1]) !== null && _a !== void 0 ? _a : ''), new URLSearchParams(targetQS)));
172
- }
173
- // Modify the redirect pattern to ignore the language prefix in the path
174
- // And escapes non-special "?" characters in a string or regex.
175
- redirect.pattern = escapeNonSpecialQuestionMarks(redirect.pattern.replace(new RegExp(`^[^]?/${language}/`, 'gi'), ''));
176
- // Prepare the redirect pattern as a regular expression, making it more flexible for matching URLs
177
- redirect.pattern = `/^\/${redirect.pattern
178
- .replace(/^\/|\/$/g, '') // Removes leading and trailing slashes
179
- .replace(/^\^\/|\/\$$/g, '') // Removes unnecessary start (^) and end ($) anchors
180
- .replace(/^\^|\$$/g, '') // Further cleans up anchors
181
- .replace(/\$\/gi$/g, '')}[\/]?$/i`; // Ensures the pattern allows an optional trailing slash
182
- matchedQueryString = [
183
- regexParser(redirect.pattern).test(`${normalizedPath}${targetQS}`),
184
- regexParser(redirect.pattern).test(`/${locale}${normalizedPath}${targetQS}`),
185
- ].some(Boolean)
186
- ? targetQS
187
- : undefined;
188
- // Save the matched query string (if found) into the redirect object
189
- redirect.matchedQueryString = matchedQueryString || '';
190
- return (!!(regexParser(redirect.pattern).test(targetURL) ||
191
- regexParser(redirect.pattern).test(`/${req.nextUrl.locale}${targetURL}`) ||
192
- matchedQueryString) && (redirect.locale ? redirect.locale.toLowerCase() === locale.toLowerCase() : true));
193
- })
194
- : undefined;
195
- });
196
206
  }
197
207
  /**
198
208
  * When a user clicks on a link generated by the Link component from next/link,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sitecore-jss/sitecore-jss-nextjs",
3
- "version": "22.6.0-canary.6",
3
+ "version": "22.6.0-canary.8",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "sideEffects": false,
@@ -73,9 +73,9 @@
73
73
  "react-dom": "^18.2.0"
74
74
  },
75
75
  "dependencies": {
76
- "@sitecore-jss/sitecore-jss": "^22.6.0-canary.6",
77
- "@sitecore-jss/sitecore-jss-dev-tools": "^22.6.0-canary.6",
78
- "@sitecore-jss/sitecore-jss-react": "^22.6.0-canary.6",
76
+ "@sitecore-jss/sitecore-jss": "^22.6.0-canary.8",
77
+ "@sitecore-jss/sitecore-jss-dev-tools": "^22.6.0-canary.8",
78
+ "@sitecore-jss/sitecore-jss-react": "^22.6.0-canary.8",
79
79
  "@vercel/kv": "^0.2.1",
80
80
  "prop-types": "^15.8.1",
81
81
  "regex-parser": "^2.2.11",
@@ -83,7 +83,7 @@
83
83
  },
84
84
  "description": "",
85
85
  "types": "types/index.d.ts",
86
- "gitHead": "0c0ae9af266a3f50b304bda295730c42eea38c12",
86
+ "gitHead": "207de802c73d93a7691a625d14cf097ee8861c70",
87
87
  "files": [
88
88
  "dist",
89
89
  "types",
@@ -9,7 +9,7 @@ export type LinkProps = ReactLinkProps & {
9
9
  */
10
10
  internalLinkMatcher?: RegExp;
11
11
  /**
12
- * Support next/link's prefetch prop.
12
+ * Next.js Link prefetch.
13
13
  */
14
14
  prefetch?: NextLinkProps['prefetch'];
15
15
  };
@@ -1,6 +1,9 @@
1
- import { GraphQLRedirectsServiceConfig } from '@sitecore-jss/sitecore-jss/site';
1
+ import { GraphQLRedirectsServiceConfig, RedirectInfo } from '@sitecore-jss/sitecore-jss/site';
2
2
  import { NextRequest, NextResponse } from 'next/server';
3
3
  import { MiddlewareBase, MiddlewareBaseConfig } from './middleware';
4
+ type RedirectResult = RedirectInfo & {
5
+ matchedQueryString?: string;
6
+ };
4
7
  /**
5
8
  * extended RedirectsMiddlewareConfig config type for RedirectsMiddleware
6
9
  */
@@ -28,15 +31,21 @@ export declare class RedirectsMiddleware extends MiddlewareBase {
28
31
  * @returns route handler
29
32
  */
30
33
  getHandler(): (req: NextRequest, res?: NextResponse) => Promise<NextResponse>;
31
- private handler;
32
34
  /**
33
35
  * Method returns RedirectInfo when matches
34
36
  * @param {NextRequest} req request
35
37
  * @param {string} siteName site name
36
- * @returns Promise<RedirectInfo | undefined>
37
- * @private
38
+ * @returns Promise<RedirectInfo | undefined> The redirect info or undefined if no redirect is found
39
+ * @protected
40
+ */
41
+ protected getExistsRedirect(req: NextRequest, siteName: string): Promise<RedirectResult | undefined>;
42
+ /**
43
+ * @param {NextRequest} req request
44
+ * @param {Response} res response
45
+ * @returns {Promise<NextResponse>} The redirect response.
38
46
  */
39
- private getExistsRedirect;
47
+ protected processRedirectRequest(req: NextRequest, res?: NextResponse): Promise<NextResponse>;
48
+ private handler;
40
49
  /**
41
50
  * When a user clicks on a link generated by the Link component from next/link,
42
51
  * Next.js adds special parameters in the route called path.
@@ -55,3 +64,4 @@ export declare class RedirectsMiddleware extends MiddlewareBase {
55
64
  */
56
65
  private createRedirectResponse;
57
66
  }
67
+ export {};