@netlify/plugin-nextjs 4.2.1 → 4.2.5
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/lib/helpers/files.js +40 -30
- package/lib/helpers/redirects.js +128 -35
- package/lib/helpers/utils.js +19 -11
- package/package.json +9 -5
package/lib/helpers/files.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.movePublicFiles = exports.unpatchNextFiles = exports.patchNextFiles = exports.moveStaticPages = exports.matchesRewrite = exports.matchesRedirect = exports.matchMiddleware = exports.stripLocale = exports.isDynamicRoute = void 0;
|
|
6
|
+
exports.movePublicFiles = exports.unpatchNextFiles = exports.patchNextFiles = exports.moveStaticPages = exports.getMiddleware = exports.matchesRewrite = exports.matchesRedirect = exports.matchMiddleware = exports.stripLocale = exports.isDynamicRoute = void 0;
|
|
7
7
|
/* eslint-disable max-lines */
|
|
8
8
|
const os_1 = require("os");
|
|
9
9
|
const chalk_1 = require("chalk");
|
|
@@ -14,6 +14,7 @@ const p_limit_1 = __importDefault(require("p-limit"));
|
|
|
14
14
|
const pathe_1 = require("pathe");
|
|
15
15
|
const slash_1 = __importDefault(require("slash"));
|
|
16
16
|
const constants_1 = require("../constants");
|
|
17
|
+
const utils_1 = require("./utils");
|
|
17
18
|
const TEST_ROUTE = /(|\/)\[[^/]+?](\/|\.html|$)/;
|
|
18
19
|
const isDynamicRoute = (route) => TEST_ROUTE.test(route);
|
|
19
20
|
exports.isDynamicRoute = isDynamicRoute;
|
|
@@ -51,6 +52,16 @@ const matchesRewrite = (file, rewrites) => {
|
|
|
51
52
|
return (0, exports.matchesRedirect)(file, rewrites.beforeFiles);
|
|
52
53
|
};
|
|
53
54
|
exports.matchesRewrite = matchesRewrite;
|
|
55
|
+
const getMiddleware = async (publish) => {
|
|
56
|
+
var _a;
|
|
57
|
+
const manifestPath = (0, pathe_1.join)(publish, 'server', 'middleware-manifest.json');
|
|
58
|
+
if ((0, fs_extra_1.existsSync)(manifestPath)) {
|
|
59
|
+
const manifest = await (0, fs_extra_1.readJson)(manifestPath, { throws: false });
|
|
60
|
+
return (_a = manifest === null || manifest === void 0 ? void 0 : manifest.sortedMiddleware) !== null && _a !== void 0 ? _a : [];
|
|
61
|
+
}
|
|
62
|
+
return [];
|
|
63
|
+
};
|
|
64
|
+
exports.getMiddleware = getMiddleware;
|
|
54
65
|
// eslint-disable-next-line max-lines-per-function
|
|
55
66
|
const moveStaticPages = async ({ netlifyConfig, target, i18n, }) => {
|
|
56
67
|
console.log('Moving static page files to serve from CDN...');
|
|
@@ -60,14 +71,8 @@ const moveStaticPages = async ({ netlifyConfig, target, i18n, }) => {
|
|
|
60
71
|
const dataDir = (0, pathe_1.join)('_next', 'data', buildId);
|
|
61
72
|
await (0, fs_extra_1.ensureDir)(dataDir);
|
|
62
73
|
// Load the middleware manifest so we can check if a file matches it before moving
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
if ((0, fs_extra_1.existsSync)(manifestPath)) {
|
|
66
|
-
const manifest = await (0, fs_extra_1.readJson)(manifestPath);
|
|
67
|
-
if (manifest === null || manifest === void 0 ? void 0 : manifest.middleware) {
|
|
68
|
-
middleware = Object.keys(manifest.middleware).map((path) => path.slice(1));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
74
|
+
const middlewarePaths = await (0, exports.getMiddleware)(netlifyConfig.build.publish);
|
|
75
|
+
const middleware = middlewarePaths.map((path) => path.slice(1));
|
|
71
76
|
const prerenderManifest = await (0, fs_extra_1.readJson)((0, pathe_1.join)(netlifyConfig.build.publish, 'prerender-manifest.json'));
|
|
72
77
|
const { redirects, rewrites } = await (0, fs_extra_1.readJson)((0, pathe_1.join)(netlifyConfig.build.publish, 'routes-manifest.json'));
|
|
73
78
|
const isrFiles = new Set();
|
|
@@ -216,47 +221,52 @@ const moveStaticPages = async ({ netlifyConfig, target, i18n, }) => {
|
|
|
216
221
|
}
|
|
217
222
|
};
|
|
218
223
|
exports.moveStaticPages = moveStaticPages;
|
|
224
|
+
/**
|
|
225
|
+
* Attempt to patch a source file, preserving a backup
|
|
226
|
+
*/
|
|
219
227
|
const patchFile = async ({ file, from, to }) => {
|
|
220
228
|
if (!(0, fs_extra_1.existsSync)(file)) {
|
|
221
|
-
|
|
229
|
+
console.warn('File was not found');
|
|
230
|
+
return false;
|
|
222
231
|
}
|
|
223
232
|
const content = await (0, fs_extra_1.readFile)(file, 'utf8');
|
|
224
233
|
if (content.includes(to)) {
|
|
225
|
-
|
|
234
|
+
console.log('File already patched');
|
|
235
|
+
return false;
|
|
226
236
|
}
|
|
227
237
|
const newContent = content.replace(from, to);
|
|
238
|
+
if (newContent === content) {
|
|
239
|
+
console.warn('File was not changed');
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
228
242
|
await (0, fs_extra_1.writeFile)(`${file}.orig`, content);
|
|
229
243
|
await (0, fs_extra_1.writeFile)(file, newContent);
|
|
244
|
+
console.log('Done');
|
|
245
|
+
return true;
|
|
230
246
|
};
|
|
247
|
+
/**
|
|
248
|
+
* The file we need has moved around a bit over the past few versions,
|
|
249
|
+
* so we iterate through the options until we find it
|
|
250
|
+
*/
|
|
231
251
|
const getServerFile = (root) => {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
239
|
-
if (!serverFile) {
|
|
240
|
-
try {
|
|
241
|
-
// eslint-disable-next-line node/no-missing-require
|
|
242
|
-
serverFile = require.resolve('next/dist/next-server/server/next-server', { paths: [root] });
|
|
243
|
-
}
|
|
244
|
-
catch {
|
|
245
|
-
// Ignore
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
return serverFile;
|
|
252
|
+
const candidates = [
|
|
253
|
+
'next/dist/server/base-server',
|
|
254
|
+
'next/dist/server/next-server',
|
|
255
|
+
'next/dist/next-server/server/next-server',
|
|
256
|
+
];
|
|
257
|
+
return (0, utils_1.findModuleFromBase)({ candidates, paths: [root] });
|
|
249
258
|
};
|
|
250
|
-
const patchNextFiles =
|
|
259
|
+
const patchNextFiles = (root) => {
|
|
251
260
|
const serverFile = getServerFile(root);
|
|
252
261
|
console.log(`Patching ${serverFile}`);
|
|
253
262
|
if (serverFile) {
|
|
254
|
-
|
|
263
|
+
return patchFile({
|
|
255
264
|
file: serverFile,
|
|
256
265
|
from: `let ssgCacheKey = `,
|
|
257
266
|
to: `let ssgCacheKey = process.env._BYPASS_SSG || `,
|
|
258
267
|
});
|
|
259
268
|
}
|
|
269
|
+
return false;
|
|
260
270
|
};
|
|
261
271
|
exports.patchNextFiles = patchNextFiles;
|
|
262
272
|
const unpatchNextFiles = async (root) => {
|
package/lib/helpers/redirects.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateRedirects = exports.generateStaticRedirects = void 0;
|
|
4
|
+
const chalk_1 = require("chalk");
|
|
4
5
|
const fs_extra_1 = require("fs-extra");
|
|
6
|
+
const outdent_1 = require("outdent");
|
|
5
7
|
const pathe_1 = require("pathe");
|
|
6
8
|
const constants_1 = require("../constants");
|
|
9
|
+
const files_1 = require("./files");
|
|
7
10
|
const utils_1 = require("./utils");
|
|
11
|
+
const matchesMiddleware = (middleware, route) => middleware.some((middlewarePath) => route.startsWith(middlewarePath));
|
|
8
12
|
const generateLocaleRedirects = ({ i18n, basePath, trailingSlash, }) => {
|
|
9
13
|
const redirects = [];
|
|
10
14
|
// If the cookie is set, we need to redirect at the origin
|
|
@@ -41,27 +45,38 @@ const generateStaticRedirects = ({ netlifyConfig, nextConfig: { i18n, basePath }
|
|
|
41
45
|
}
|
|
42
46
|
};
|
|
43
47
|
exports.generateStaticRedirects = generateStaticRedirects;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Routes that match middleware need to always use the SSR function
|
|
50
|
+
* This generates a rewrite for every middleware in every locale, both with and without a splat
|
|
51
|
+
*/
|
|
52
|
+
const generateMiddlewareRewrites = ({ basePath, middleware, i18n, buildId }) => {
|
|
53
|
+
const handlerRewrite = (from) => ({
|
|
54
|
+
from: `${basePath}${from}`,
|
|
55
|
+
to: constants_1.HANDLER_FUNCTION_PATH,
|
|
56
|
+
status: 200,
|
|
57
|
+
});
|
|
58
|
+
return (middleware
|
|
59
|
+
.map((route) => {
|
|
60
|
+
var _a;
|
|
61
|
+
const unlocalized = [handlerRewrite(`${route}`), handlerRewrite(`${route}/*`)];
|
|
62
|
+
if (((_a = i18n === null || i18n === void 0 ? void 0 : i18n.locales) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
63
|
+
const localized = i18n.locales.map((locale) => [
|
|
64
|
+
handlerRewrite(`/${locale}${route}`),
|
|
65
|
+
handlerRewrite(`/${locale}${route}/*`),
|
|
66
|
+
handlerRewrite(`/_next/data/${buildId}/${locale}${route}/*`),
|
|
67
|
+
]);
|
|
68
|
+
// With i18n, all data routes are prefixed with the locale, but the HTML also has the unprefixed default
|
|
69
|
+
return [...unlocalized, ...localized];
|
|
70
|
+
}
|
|
71
|
+
return [...unlocalized, handlerRewrite(`/_next/data/${buildId}${route}/*`)];
|
|
72
|
+
})
|
|
73
|
+
// Flatten the array of arrays. Can't use flatMap as it might be 2 levels deep
|
|
74
|
+
.flat(2));
|
|
75
|
+
};
|
|
76
|
+
const generateStaticIsrRewrites = ({ staticRouteEntries, basePath, i18n, buildId, middleware, }) => {
|
|
77
|
+
const staticIsrRoutesThatMatchMiddleware = [];
|
|
63
78
|
const staticRoutePaths = new Set();
|
|
64
|
-
|
|
79
|
+
const staticIsrRewrites = [];
|
|
65
80
|
staticRouteEntries.forEach(([route, { initialRevalidateSeconds }]) => {
|
|
66
81
|
if ((0, utils_1.isApiRoute)(route)) {
|
|
67
82
|
return;
|
|
@@ -75,7 +90,10 @@ const generateRedirects = async ({ netlifyConfig, nextConfig: { i18n, basePath,
|
|
|
75
90
|
if ((i18n === null || i18n === void 0 ? void 0 : i18n.defaultLocale) && route.startsWith(`/${i18n.defaultLocale}/`)) {
|
|
76
91
|
route = route.slice(i18n.defaultLocale.length + 1);
|
|
77
92
|
staticRoutePaths.add(route);
|
|
78
|
-
|
|
93
|
+
if (matchesMiddleware(middleware, route)) {
|
|
94
|
+
staticIsrRoutesThatMatchMiddleware.push(route);
|
|
95
|
+
}
|
|
96
|
+
staticIsrRewrites.push(...(0, utils_1.redirectsForNextRouteWithData)({
|
|
79
97
|
route,
|
|
80
98
|
dataRoute: (0, utils_1.routeToDataRoute)(route, buildId, i18n.defaultLocale),
|
|
81
99
|
basePath,
|
|
@@ -83,41 +101,116 @@ const generateRedirects = async ({ netlifyConfig, nextConfig: { i18n, basePath,
|
|
|
83
101
|
force: true,
|
|
84
102
|
}));
|
|
85
103
|
}
|
|
104
|
+
else if (matchesMiddleware(middleware, route)) {
|
|
105
|
+
// Routes that match middleware can't use the ODB
|
|
106
|
+
staticIsrRoutesThatMatchMiddleware.push(route);
|
|
107
|
+
}
|
|
86
108
|
else {
|
|
87
109
|
// ISR routes use the ODB handler
|
|
88
|
-
|
|
110
|
+
staticIsrRewrites.push(
|
|
89
111
|
// No i18n, because the route is already localized
|
|
90
112
|
...(0, utils_1.redirectsForNextRoute)({ route, basePath, to: constants_1.ODB_FUNCTION_PATH, force: true, buildId, i18n: null }));
|
|
91
113
|
}
|
|
92
114
|
});
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
115
|
+
return {
|
|
116
|
+
staticRoutePaths,
|
|
117
|
+
staticIsrRoutesThatMatchMiddleware,
|
|
118
|
+
staticIsrRewrites,
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Generate rewrites for all dynamic routes
|
|
123
|
+
*/
|
|
124
|
+
const generateDynamicRewrites = ({ dynamicRoutes, prerenderedDynamicRoutes, middleware, basePath, buildId, i18n, }) => {
|
|
125
|
+
const dynamicRewrites = [];
|
|
126
|
+
const dynamicRoutesThatMatchMiddleware = [];
|
|
102
127
|
dynamicRoutes.forEach((route) => {
|
|
103
128
|
if ((0, utils_1.isApiRoute)(route.page)) {
|
|
104
129
|
return;
|
|
105
130
|
}
|
|
106
131
|
if (route.page in prerenderedDynamicRoutes) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
132
|
+
if (matchesMiddleware(middleware, route.page)) {
|
|
133
|
+
dynamicRoutesThatMatchMiddleware.push(route.page);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
dynamicRewrites.push(...(0, utils_1.redirectsForNextRoute)({ buildId, route: route.page, basePath, to: constants_1.ODB_FUNCTION_PATH, status: 200, i18n }));
|
|
137
|
+
}
|
|
110
138
|
}
|
|
111
139
|
else {
|
|
112
140
|
// If the route isn't prerendered, it's SSR
|
|
113
|
-
|
|
141
|
+
dynamicRewrites.push(...(0, utils_1.redirectsForNextRoute)({ route: route.page, buildId, basePath, to: constants_1.HANDLER_FUNCTION_PATH, i18n }));
|
|
114
142
|
}
|
|
115
143
|
});
|
|
144
|
+
return {
|
|
145
|
+
dynamicRoutesThatMatchMiddleware,
|
|
146
|
+
dynamicRewrites,
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
const generateRedirects = async ({ netlifyConfig, nextConfig: { i18n, basePath, trailingSlash, appDir }, buildId, }) => {
|
|
150
|
+
const { dynamicRoutes: prerenderedDynamicRoutes, routes: prerenderedStaticRoutes } = await (0, fs_extra_1.readJSON)((0, pathe_1.join)(netlifyConfig.build.publish, 'prerender-manifest.json'));
|
|
151
|
+
const { dynamicRoutes, staticRoutes } = await (0, fs_extra_1.readJSON)((0, pathe_1.join)(netlifyConfig.build.publish, 'routes-manifest.json'));
|
|
152
|
+
netlifyConfig.redirects.push(...constants_1.HIDDEN_PATHS.map((path) => ({
|
|
153
|
+
from: `${basePath}${path}`,
|
|
154
|
+
to: '/404.html',
|
|
155
|
+
status: 404,
|
|
156
|
+
force: true,
|
|
157
|
+
})));
|
|
158
|
+
if (i18n && i18n.localeDetection !== false) {
|
|
159
|
+
netlifyConfig.redirects.push(...generateLocaleRedirects({ i18n, basePath, trailingSlash }));
|
|
160
|
+
}
|
|
161
|
+
// This is only used in prod, so dev uses `next dev` directly
|
|
162
|
+
netlifyConfig.redirects.push(
|
|
163
|
+
// API routes always need to be served from the regular function
|
|
164
|
+
...(0, utils_1.getApiRewrites)(basePath),
|
|
165
|
+
// Preview mode gets forced to the function, to bypass pre-rendered pages, but static files need to be skipped
|
|
166
|
+
...(await (0, utils_1.getPreviewRewrites)({ basePath, appDir })));
|
|
167
|
+
const middleware = await (0, files_1.getMiddleware)(netlifyConfig.build.publish);
|
|
168
|
+
netlifyConfig.redirects.push(...generateMiddlewareRewrites({ basePath, i18n, middleware, buildId }));
|
|
169
|
+
const staticRouteEntries = Object.entries(prerenderedStaticRoutes);
|
|
170
|
+
const routesThatMatchMiddleware = [];
|
|
171
|
+
const { staticRoutePaths, staticIsrRewrites, staticIsrRoutesThatMatchMiddleware } = generateStaticIsrRewrites({
|
|
172
|
+
staticRouteEntries,
|
|
173
|
+
basePath,
|
|
174
|
+
i18n,
|
|
175
|
+
buildId,
|
|
176
|
+
middleware,
|
|
177
|
+
});
|
|
178
|
+
routesThatMatchMiddleware.push(...staticIsrRoutesThatMatchMiddleware);
|
|
179
|
+
netlifyConfig.redirects.push(...staticIsrRewrites);
|
|
180
|
+
// Add rewrites for all static SSR routes. This is Next 12+
|
|
181
|
+
staticRoutes === null || staticRoutes === void 0 ? void 0 : staticRoutes.forEach((route) => {
|
|
182
|
+
if (staticRoutePaths.has(route.page) || (0, utils_1.isApiRoute)(route.page)) {
|
|
183
|
+
// Prerendered static routes are either handled by the CDN or are ISR
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
netlifyConfig.redirects.push(...(0, utils_1.redirectsForNextRoute)({ route: route.page, buildId, basePath, to: constants_1.HANDLER_FUNCTION_PATH, i18n }));
|
|
187
|
+
});
|
|
188
|
+
// Add rewrites for all dynamic routes (both SSR and ISR)
|
|
189
|
+
const { dynamicRewrites, dynamicRoutesThatMatchMiddleware } = generateDynamicRewrites({
|
|
190
|
+
dynamicRoutes,
|
|
191
|
+
prerenderedDynamicRoutes,
|
|
192
|
+
middleware,
|
|
193
|
+
basePath,
|
|
194
|
+
buildId,
|
|
195
|
+
i18n,
|
|
196
|
+
});
|
|
197
|
+
netlifyConfig.redirects.push(...dynamicRewrites);
|
|
198
|
+
routesThatMatchMiddleware.push(...dynamicRoutesThatMatchMiddleware);
|
|
116
199
|
// Final fallback
|
|
117
200
|
netlifyConfig.redirects.push({
|
|
118
201
|
from: `${basePath}/*`,
|
|
119
202
|
to: constants_1.HANDLER_FUNCTION_PATH,
|
|
120
203
|
status: 200,
|
|
121
204
|
});
|
|
205
|
+
const middlewareMatches = new Set(routesThatMatchMiddleware).size;
|
|
206
|
+
if (middlewareMatches > 0) {
|
|
207
|
+
console.log((0, chalk_1.yellowBright)((0, outdent_1.outdent) `
|
|
208
|
+
There ${middlewareMatches === 1
|
|
209
|
+
? `is one statically-generated or ISR route that matches`
|
|
210
|
+
: `are ${middlewareMatches} statically-generated or ISR routes that match`} a middleware function. Matched routes will always be served from the SSR function and will not use ISR or be served from the CDN.
|
|
211
|
+
If this was not intended, ensure that your middleware only matches routes that you intend to use SSR.
|
|
212
|
+
`));
|
|
213
|
+
}
|
|
122
214
|
};
|
|
123
215
|
exports.generateRedirects = generateRedirects;
|
|
216
|
+
/* eslint-enable max-lines */
|
package/lib/helpers/utils.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.shouldSkip = exports.getPreviewRewrites = exports.getApiRewrites = exports.redirectsForNextRouteWithData = exports.redirectsForNextRoute = exports.
|
|
6
|
+
exports.findModuleFromBase = exports.shouldSkip = exports.getPreviewRewrites = exports.getApiRewrites = exports.redirectsForNextRouteWithData = exports.redirectsForNextRoute = exports.isApiRoute = exports.routeToDataRoute = exports.netlifyRoutesForNextRouteWithData = exports.toNetlifyRoute = void 0;
|
|
7
7
|
const globby_1 = __importDefault(require("globby"));
|
|
8
8
|
const pathe_1 = require("pathe");
|
|
9
9
|
const constants_1 = require("../constants");
|
|
@@ -63,16 +63,6 @@ const netlifyRoutesForNextRoute = (route, buildId, i18n) => {
|
|
|
63
63
|
};
|
|
64
64
|
const isApiRoute = (route) => route.startsWith('/api/') || route === '/api';
|
|
65
65
|
exports.isApiRoute = isApiRoute;
|
|
66
|
-
const targetForFallback = (fallback) => {
|
|
67
|
-
if (fallback === null || fallback === false) {
|
|
68
|
-
// fallback = null mean "blocking", which uses ODB. For fallback=false then anything prerendered should 404.
|
|
69
|
-
// However i18n pages may not have been prerendered, so we still need to hit the origin
|
|
70
|
-
return { to: constants_1.ODB_FUNCTION_PATH, status: 200 };
|
|
71
|
-
}
|
|
72
|
-
// fallback = true is also ODB
|
|
73
|
-
return { to: constants_1.ODB_FUNCTION_PATH, status: 200 };
|
|
74
|
-
};
|
|
75
|
-
exports.targetForFallback = targetForFallback;
|
|
76
66
|
const redirectsForNextRoute = ({ route, buildId, basePath, to, i18n, status = 200, force = false, }) => netlifyRoutesForNextRoute(route, buildId, i18n).map((redirect) => ({
|
|
77
67
|
from: `${basePath}${redirect}`,
|
|
78
68
|
to,
|
|
@@ -126,3 +116,21 @@ const shouldSkip = () => process.env.NEXT_PLUGIN_FORCE_RUN === 'false' ||
|
|
|
126
116
|
process.env.NETLIFY_NEXT_PLUGIN_SKIP === 'true' ||
|
|
127
117
|
process.env.NETLIFY_NEXT_PLUGIN_SKIP === '1';
|
|
128
118
|
exports.shouldSkip = shouldSkip;
|
|
119
|
+
/**
|
|
120
|
+
* Given an array of base paths and candidate modules, return the first one that exists
|
|
121
|
+
*/
|
|
122
|
+
const findModuleFromBase = ({ paths, candidates }) => {
|
|
123
|
+
for (const candidate of candidates) {
|
|
124
|
+
try {
|
|
125
|
+
const modulePath = require.resolve(candidate, { paths });
|
|
126
|
+
if (modulePath) {
|
|
127
|
+
return modulePath;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Ignore the error
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
};
|
|
136
|
+
exports.findModuleFromBase = findModuleFromBase;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/plugin-nextjs",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.5",
|
|
4
4
|
"description": "Run Next.js seamlessly on Netlify",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -54,12 +54,13 @@
|
|
|
54
54
|
"homepage": "https://github.com/netlify/netlify-plugin-nextjs#readme",
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@netlify/functions": "^0.11.0",
|
|
57
|
-
"@netlify/ipx": "^0.0.
|
|
57
|
+
"@netlify/ipx": "^0.0.9",
|
|
58
58
|
"@vercel/node-bridge": "^2.1.0",
|
|
59
59
|
"chalk": "^4.1.2",
|
|
60
60
|
"fs-extra": "^10.0.0",
|
|
61
61
|
"globby": "^11.0.4",
|
|
62
62
|
"moize": "^6.1.0",
|
|
63
|
+
"next": "^12.0.10",
|
|
63
64
|
"node-fetch": "^2.6.6",
|
|
64
65
|
"node-stream-zip": "^1.15.0",
|
|
65
66
|
"outdent": "^0.8.0",
|
|
@@ -74,13 +75,16 @@
|
|
|
74
75
|
"@babel/core": "^7.15.8",
|
|
75
76
|
"@babel/preset-env": "^7.15.8",
|
|
76
77
|
"@babel/preset-typescript": "^7.16.0",
|
|
77
|
-
"@netlify/build": "^26.2.
|
|
78
|
-
"@netlify/eslint-config-node": "^
|
|
78
|
+
"@netlify/build": "^26.2.3",
|
|
79
|
+
"@netlify/eslint-config-node": "^5.1.4",
|
|
80
|
+
"@reach/dialog": "^0.16.2",
|
|
81
|
+
"@reach/visually-hidden": "^0.16.0",
|
|
79
82
|
"@testing-library/cypress": "^8.0.1",
|
|
80
83
|
"@types/fs-extra": "^9.0.13",
|
|
81
84
|
"@types/jest": "^27.0.2",
|
|
82
85
|
"@types/mocha": "^9.0.0",
|
|
83
86
|
"@types/node": "^17.0.10",
|
|
87
|
+
"@types/react": "^17.0.38",
|
|
84
88
|
"babel-jest": "^27.2.5",
|
|
85
89
|
"cpy": "^8.1.2",
|
|
86
90
|
"cypress": "^9.0.0",
|
|
@@ -88,12 +92,12 @@
|
|
|
88
92
|
"husky": "^7.0.4",
|
|
89
93
|
"jest": "^27.0.0",
|
|
90
94
|
"netlify-plugin-cypress": "^2.2.0",
|
|
91
|
-
"next": "^12.0.8",
|
|
92
95
|
"npm-run-all": "^4.1.5",
|
|
93
96
|
"prettier": "^2.1.2",
|
|
94
97
|
"react": "^17.0.1",
|
|
95
98
|
"react-dom": "^17.0.1",
|
|
96
99
|
"rimraf": "^3.0.2",
|
|
100
|
+
"sass": "^1.49.0",
|
|
97
101
|
"tmp-promise": "^3.0.2",
|
|
98
102
|
"typescript": "^4.3.4"
|
|
99
103
|
},
|