vike 0.4.147 → 0.4.148-commit-7596dcd
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/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +17 -12
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +3 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +116 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +33 -45
- package/dist/cjs/node/prerender/runPrerender.js +85 -84
- package/dist/cjs/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
- package/dist/cjs/node/runtime/html/renderHtml.js +1 -1
- package/dist/cjs/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +12 -12
- package/dist/cjs/node/runtime/renderPage/createHttpResponseObject.js +3 -3
- package/dist/cjs/node/runtime/renderPage/executeOnBeforeRenderHook.js +1 -1
- package/dist/cjs/node/runtime/renderPage/executeOnRenderHtmlHook.js +3 -3
- package/dist/cjs/node/runtime/renderPage/getHttpResponseBody.js +1 -1
- package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +21 -18
- package/dist/cjs/node/runtime/renderPage.js +73 -49
- package/dist/cjs/shared/getPageFiles/parseGlobResults.js +3 -3
- package/dist/cjs/shared/hooks/executeHook.js +18 -29
- package/dist/cjs/shared/hooks/getHook.js +104 -3
- package/dist/cjs/shared/page-configs/helpers/getConfigDefinedAtString.js +1 -1
- package/dist/cjs/shared/route/executeGuardHook.js +3 -2
- package/dist/cjs/shared/route/executeOnBeforeRouteHook.js +4 -4
- package/dist/cjs/shared/route/loadPageRoutes.js +10 -15
- package/dist/cjs/shared/route/resolveRedirects.js +8 -5
- package/dist/cjs/utils/parseUrl-extras.js +6 -1
- package/dist/cjs/utils/parseUrl.js +24 -16
- package/dist/cjs/utils/projectInfo.js +1 -1
- package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +1 -1
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +20 -10
- package/dist/esm/client/client-routing-runtime/onBrowserHistoryNavigation.js +2 -2
- package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +18 -12
- package/dist/esm/client/shared/executeOnRenderClientHook.js +1 -1
- package/dist/esm/client/shared/getPageContextSerializedInHtml.js +1 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +17 -12
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +3 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.d.ts +5 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +110 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +34 -46
- package/dist/esm/node/prerender/runPrerender.js +87 -86
- package/dist/esm/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
- package/dist/esm/node/runtime/html/renderHtml.js +1 -1
- package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +13 -13
- package/dist/esm/node/runtime/renderPage/createHttpResponseObject.d.ts +1 -1
- package/dist/esm/node/runtime/renderPage/createHttpResponseObject.js +3 -3
- package/dist/esm/node/runtime/renderPage/executeOnBeforeRenderHook.js +1 -1
- package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.d.ts +2 -2
- package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.js +3 -3
- package/dist/esm/node/runtime/renderPage/getHttpResponseBody.js +1 -1
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +7 -7
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +22 -19
- package/dist/esm/node/runtime/renderPage.js +74 -50
- package/dist/esm/shared/getPageFiles/parseGlobResults.js +1 -1
- package/dist/esm/shared/hooks/executeHook.d.ts +2 -2
- package/dist/esm/shared/hooks/executeHook.js +18 -29
- package/dist/esm/shared/hooks/getHook.d.ts +17 -7
- package/dist/esm/shared/hooks/getHook.js +103 -3
- package/dist/esm/shared/page-configs/Config.d.ts +21 -13
- package/dist/esm/shared/page-configs/helpers/getConfigDefinedAtString.d.ts +1 -1
- package/dist/esm/shared/page-configs/helpers/getConfigDefinedAtString.js +1 -1
- package/dist/esm/shared/route/executeGuardHook.js +4 -3
- package/dist/esm/shared/route/executeOnBeforeRouteHook.d.ts +1 -8
- package/dist/esm/shared/route/executeOnBeforeRouteHook.js +6 -6
- package/dist/esm/shared/route/index.d.ts +2 -2
- package/dist/esm/shared/route/loadPageRoutes.d.ts +2 -2
- package/dist/esm/shared/route/loadPageRoutes.js +11 -16
- package/dist/esm/shared/route/resolveRedirects.js +8 -5
- package/dist/esm/utils/parseUrl-extras.d.ts +2 -0
- package/dist/esm/utils/parseUrl-extras.js +5 -0
- package/dist/esm/utils/parseUrl.js +24 -16
- package/dist/esm/utils/projectInfo.d.ts +2 -2
- package/dist/esm/utils/projectInfo.js +1 -1
- package/package.json +3 -3
- /package/dist/cjs/shared/page-configs/serialize/{assertPageConfigs.js → assertPageConfigsSerialized.js} +0 -0
- /package/dist/esm/shared/page-configs/serialize/{assertPageConfigs.d.ts → assertPageConfigsSerialized.d.ts} +0 -0
- /package/dist/esm/shared/page-configs/serialize/{assertPageConfigs.js → assertPageConfigsSerialized.js} +0 -0
|
@@ -12,7 +12,7 @@ import { HttpResponse } from './createHttpResponseObject.js';
|
|
|
12
12
|
import { PageContext_loadPageFilesServerSide, type PageFiles } from './loadPageFilesServerSide.js';
|
|
13
13
|
import type { PageConfigRuntime, PageConfigGlobalRuntime } from '../../../shared/page-configs/PageConfig.js';
|
|
14
14
|
import { type PageRoutes } from '../../../shared/route/loadPageRoutes.js';
|
|
15
|
-
import type {
|
|
15
|
+
import type { Hook } from '../../../shared/hooks/getHook.js';
|
|
16
16
|
type PageContextAfterRender = {
|
|
17
17
|
httpResponse: null | HttpResponse;
|
|
18
18
|
errorWhileRendering: null | Error;
|
|
@@ -46,7 +46,7 @@ declare function prerenderPage(pageContext: PageContextInitEnhanced & PageFiles
|
|
|
46
46
|
_pageConfigGlobal: PageConfigGlobalRuntime;
|
|
47
47
|
_allPageIds: string[];
|
|
48
48
|
_pageRoutes: PageRoutes;
|
|
49
|
-
_onBeforeRouteHook:
|
|
49
|
+
_onBeforeRouteHook: Hook | null;
|
|
50
50
|
_pageContextInit: {
|
|
51
51
|
urlOriginal: string;
|
|
52
52
|
};
|
|
@@ -93,7 +93,7 @@ declare function prerenderPage(pageContext: PageContextInitEnhanced & PageFiles
|
|
|
93
93
|
_pageConfigGlobal: PageConfigGlobalRuntime;
|
|
94
94
|
_allPageIds: string[];
|
|
95
95
|
_pageRoutes: PageRoutes;
|
|
96
|
-
_onBeforeRouteHook:
|
|
96
|
+
_onBeforeRouteHook: Hook | null;
|
|
97
97
|
_pageContextInit: {
|
|
98
98
|
urlOriginal: string;
|
|
99
99
|
};
|
|
@@ -141,7 +141,7 @@ declare function prerender404Page(renderContext: RenderContext, pageContextInit_
|
|
|
141
141
|
_pageConfigGlobal: PageConfigGlobalRuntime;
|
|
142
142
|
_allPageIds: string[];
|
|
143
143
|
_pageRoutes: PageRoutes;
|
|
144
|
-
_onBeforeRouteHook:
|
|
144
|
+
_onBeforeRouteHook: Hook | null;
|
|
145
145
|
_pageContextInit: {
|
|
146
146
|
urlOriginal: string;
|
|
147
147
|
};
|
|
@@ -188,7 +188,7 @@ declare function prerender404Page(renderContext: RenderContext, pageContextInit_
|
|
|
188
188
|
_pageConfigGlobal: PageConfigGlobalRuntime;
|
|
189
189
|
_allPageIds: string[];
|
|
190
190
|
_pageRoutes: PageRoutes;
|
|
191
|
-
_onBeforeRouteHook:
|
|
191
|
+
_onBeforeRouteHook: Hook | null;
|
|
192
192
|
_pageContextInit: {
|
|
193
193
|
urlOriginal: string;
|
|
194
194
|
};
|
|
@@ -243,7 +243,7 @@ declare function getPageContextInitEnhanced(pageContextInit: {
|
|
|
243
243
|
_pageConfigGlobal: PageConfigGlobalRuntime;
|
|
244
244
|
_allPageIds: string[];
|
|
245
245
|
_pageRoutes: PageRoutes;
|
|
246
|
-
_onBeforeRouteHook:
|
|
246
|
+
_onBeforeRouteHook: Hook | null;
|
|
247
247
|
_pageContextInit: {
|
|
248
248
|
urlOriginal: string;
|
|
249
249
|
};
|
|
@@ -260,6 +260,6 @@ type RenderContext = {
|
|
|
260
260
|
pageConfigGlobal: PageConfigGlobalRuntime;
|
|
261
261
|
allPageIds: string[];
|
|
262
262
|
pageRoutes: PageRoutes;
|
|
263
|
-
onBeforeRouteHook:
|
|
263
|
+
onBeforeRouteHook: Hook | null;
|
|
264
264
|
};
|
|
265
265
|
declare function getRenderContext(): Promise<RenderContext>;
|
|
@@ -6,7 +6,7 @@ export { getRenderContext };
|
|
|
6
6
|
import { getErrorPageId } from '../../../shared/error-page.js';
|
|
7
7
|
import { getHtmlString } from '../html/renderHtml.js';
|
|
8
8
|
import { getPageFilesAll } from '../../../shared/getPageFiles.js';
|
|
9
|
-
import { assert, assertUsage, hasProp, isNotNullish, objectAssign, unique } from '../utils.js';
|
|
9
|
+
import { assert, assertUsage, assertWarning, hasProp, isNotNullish, objectAssign, unique } from '../utils.js';
|
|
10
10
|
import { serializePageContextClientSide } from '../html/serializePageContextClientSide.js';
|
|
11
11
|
import { addUrlComputedProps } from '../../../shared/addUrlComputedProps.js';
|
|
12
12
|
import { getGlobalContext } from '../globalContext.js';
|
|
@@ -150,7 +150,7 @@ async function getRenderContext() {
|
|
|
150
150
|
const globalContext = getGlobalContext();
|
|
151
151
|
const { pageFilesAll, allPageIds, pageConfigs, pageConfigGlobal } = await getPageFilesAll(false, globalContext.isProduction);
|
|
152
152
|
const { pageRoutes, onBeforeRouteHook } = await loadPageRoutes(pageFilesAll, pageConfigs, pageConfigGlobal, allPageIds);
|
|
153
|
-
|
|
153
|
+
assertV1Design(pageFilesAll, pageConfigs);
|
|
154
154
|
const renderContext = {
|
|
155
155
|
pageFilesAll: pageFilesAll,
|
|
156
156
|
pageConfigs,
|
|
@@ -161,21 +161,24 @@ async function getRenderContext() {
|
|
|
161
161
|
};
|
|
162
162
|
return renderContext;
|
|
163
163
|
}
|
|
164
|
-
function
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
164
|
+
function assertV1Design(pageFilesAll, pageConfigs) {
|
|
165
|
+
const isV1Design = pageConfigs.length !== 0;
|
|
166
|
+
const isDesignOld = pageFilesAll.length !== 0;
|
|
167
|
+
if (isV1Design && isDesignOld) {
|
|
168
|
+
const indent = '- ';
|
|
169
|
+
const v1Files = unique(pageConfigs
|
|
170
|
+
.map((p) => Object.values(p.configValues)
|
|
171
|
+
.map(getConfigValueFilePathToShowToUser)
|
|
172
|
+
.filter(isNotNullish)
|
|
173
|
+
.map((filePathToShowToUser) => indent + filePathToShowToUser))
|
|
174
|
+
.flat(2));
|
|
175
|
+
assertUsage(false, [
|
|
176
|
+
'Mixing the new V1 design with the old V0.4 design is forbidden.',
|
|
177
|
+
'V1 files:',
|
|
178
|
+
...v1Files,
|
|
179
|
+
'V0.4 files:',
|
|
180
|
+
...pageFilesAll.map((p) => indent + p.filePath)
|
|
181
|
+
].join('\n'));
|
|
182
|
+
}
|
|
183
|
+
assertWarning(!isDesignOld, 'You are using the old deprecated design, update to the new V1 design, see https://vike.dev/migration/v1-design', { onlyOnce: true });
|
|
181
184
|
}
|
|
@@ -2,7 +2,7 @@ export { renderPage };
|
|
|
2
2
|
export { renderPage_addWrapper };
|
|
3
3
|
import { getRenderContext, getPageContextInitEnhanced, renderPageAlreadyRouted } from './renderPage/renderPageAlreadyRouted.js';
|
|
4
4
|
import { route } from '../../shared/route/index.js';
|
|
5
|
-
import { assert, hasProp, objectAssign, isParsable, parseUrl, assertEnv, assertWarning, getGlobalObject, checkType, assertUsage, normalizeUrlPathname, removeBaseServer, modifyUrlPathname, prependBase, removeUrlOrigin, addUrlOrigin } from './utils.js';
|
|
5
|
+
import { assert, hasProp, objectAssign, isParsable, parseUrl, assertEnv, assertWarning, getGlobalObject, checkType, assertUsage, normalizeUrlPathname, removeBaseServer, modifyUrlPathname, prependBase, removeUrlOrigin, addUrlOrigin, createUrlFromComponents } from './utils.js';
|
|
6
6
|
import { assertNoInfiniteAbortLoop, getPageContextFromAllRewrites, isAbortError, logAbortErrorHandled } from '../../shared/route/abort.js';
|
|
7
7
|
import { getGlobalContext, initGlobalContext } from './globalContext.js';
|
|
8
8
|
import { handlePageContextRequestUrl } from './renderPage/handlePageContextRequestUrl.js';
|
|
@@ -34,17 +34,17 @@ async function renderPage(pageContextInit) {
|
|
|
34
34
|
assertArguments(...arguments);
|
|
35
35
|
assert(hasProp(pageContextInit, 'urlOriginal', 'string'));
|
|
36
36
|
assertEnv();
|
|
37
|
-
if (
|
|
38
|
-
const
|
|
39
|
-
checkType(
|
|
40
|
-
return
|
|
37
|
+
if (isIgnoredUrl(pageContextInit.urlOriginal)) {
|
|
38
|
+
const pageContextHttpResponseNull = getPageContextHttpResponseNull(pageContextInit);
|
|
39
|
+
checkType(pageContextHttpResponseNull);
|
|
40
|
+
return pageContextHttpResponseNull;
|
|
41
41
|
}
|
|
42
42
|
const httpRequestId = getRequestId();
|
|
43
|
-
const
|
|
44
|
-
logHttpRequest(
|
|
43
|
+
const { urlOriginal } = pageContextInit;
|
|
44
|
+
logHttpRequest(urlOriginal, httpRequestId);
|
|
45
45
|
globalObject.pendingRequestsCount++;
|
|
46
46
|
const { pageContextReturn, onRequestDone } = await renderPage_wrapper(httpRequestId, () => renderPageAndPrepare(pageContextInit, httpRequestId));
|
|
47
|
-
logHttpResponse(
|
|
47
|
+
logHttpResponse(urlOriginal, httpRequestId, pageContextReturn);
|
|
48
48
|
globalObject.pendingRequestsCount--;
|
|
49
49
|
onRequestDone();
|
|
50
50
|
checkType(pageContextReturn);
|
|
@@ -54,8 +54,8 @@ async function renderPageAndPrepare(pageContextInit, httpRequestId) {
|
|
|
54
54
|
// Invalid config
|
|
55
55
|
const handleInvalidConfig = () => {
|
|
56
56
|
logRuntimeInfo?.(pc.bold(pc.red("Couldn't load configuration: see error above.")), httpRequestId, 'error');
|
|
57
|
-
const
|
|
58
|
-
return
|
|
57
|
+
const pageContextHttpResponseNull = getPageContextHttpResponseNull(pageContextInit);
|
|
58
|
+
return pageContextHttpResponseNull;
|
|
59
59
|
};
|
|
60
60
|
if (isConfigInvalid) {
|
|
61
61
|
return handleInvalidConfig();
|
|
@@ -71,8 +71,8 @@ async function renderPageAndPrepare(pageContextInit, httpRequestId) {
|
|
|
71
71
|
// initGlobalContext() and getRenderContext() don't call any user hooks => err isn't thrown from user code
|
|
72
72
|
assert(!isAbortError(err));
|
|
73
73
|
logRuntimeError(err, httpRequestId);
|
|
74
|
-
const
|
|
75
|
-
return
|
|
74
|
+
const pageContextHttpResponseNull = getPageContextHttpResponseNullWithError(err, pageContextInit);
|
|
75
|
+
return pageContextHttpResponseNull;
|
|
76
76
|
}
|
|
77
77
|
if (isConfigInvalid) {
|
|
78
78
|
return handleInvalidConfig();
|
|
@@ -80,15 +80,23 @@ async function renderPageAndPrepare(pageContextInit, httpRequestId) {
|
|
|
80
80
|
else {
|
|
81
81
|
// From now on, renderContext.pageConfigs contains all the configuration data; getVikeConfig() isn't called anymore for this request
|
|
82
82
|
}
|
|
83
|
+
// Check Base URL
|
|
84
|
+
{
|
|
85
|
+
const pageContextHttpResponse = checkBaseUrl(pageContextInit, httpRequestId);
|
|
86
|
+
if (pageContextHttpResponse)
|
|
87
|
+
return pageContextHttpResponse;
|
|
88
|
+
}
|
|
89
|
+
// Normalize URL
|
|
83
90
|
{
|
|
84
|
-
const
|
|
85
|
-
if (
|
|
86
|
-
return
|
|
91
|
+
const pageContextHttpResponse = normalizeUrl(pageContextInit, httpRequestId);
|
|
92
|
+
if (pageContextHttpResponse)
|
|
93
|
+
return pageContextHttpResponse;
|
|
87
94
|
}
|
|
95
|
+
// Permanent redirects (HTTP status code `301`)
|
|
88
96
|
{
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
return
|
|
97
|
+
const pageContextHttpResponse = getPermanentRedirect(pageContextInit, httpRequestId);
|
|
98
|
+
if (pageContextHttpResponse)
|
|
99
|
+
return pageContextHttpResponse;
|
|
92
100
|
}
|
|
93
101
|
return await renderPageAlreadyPrepared(pageContextInit, httpRequestId, renderContext, []);
|
|
94
102
|
}
|
|
@@ -171,8 +179,8 @@ async function renderPageAlreadyPrepared(pageContextInit, httpRequestId, renderC
|
|
|
171
179
|
if (!handled.pageContextReturn) {
|
|
172
180
|
const pageContextAbort = errErrorPage._pageContextAbort;
|
|
173
181
|
assertWarning(false, `Failed to render error page because ${pc.cyan(pageContextAbort._abortCall)} was called: make sure ${pc.cyan(pageContextAbort._abortCaller)} doesn't occur while the error page is being rendered.`, { onlyOnce: false });
|
|
174
|
-
const
|
|
175
|
-
return
|
|
182
|
+
const pageContextHttpResponseNull = getPageContextHttpResponseNullWithError(errNominalPage, pageContextInit);
|
|
183
|
+
return pageContextHttpResponseNull;
|
|
176
184
|
}
|
|
177
185
|
// `throw redirect()` / `throw render(url)`
|
|
178
186
|
return handled.pageContextReturn;
|
|
@@ -180,18 +188,28 @@ async function renderPageAlreadyPrepared(pageContextInit, httpRequestId, renderC
|
|
|
180
188
|
if (isNewError(errErrorPage, errNominalPage)) {
|
|
181
189
|
logRuntimeError(errErrorPage, httpRequestId);
|
|
182
190
|
}
|
|
183
|
-
const
|
|
184
|
-
return
|
|
191
|
+
const pageContextHttpResponseNull = getPageContextHttpResponseNullWithError(errNominalPage, pageContextInit);
|
|
192
|
+
return pageContextHttpResponseNull;
|
|
185
193
|
}
|
|
186
194
|
return pageContextErrorPage;
|
|
187
195
|
}
|
|
188
196
|
}
|
|
189
|
-
function logHttpRequest(
|
|
197
|
+
function logHttpRequest(urlOriginal, httpRequestId) {
|
|
190
198
|
const clearErrors = globalObject.pendingRequestsCount === 0;
|
|
191
|
-
logRuntimeInfo?.(
|
|
199
|
+
logRuntimeInfo?.(getRequestInfoMessage(urlOriginal), httpRequestId, 'info', clearErrors);
|
|
192
200
|
}
|
|
193
|
-
function
|
|
201
|
+
function getRequestInfoMessage(urlOriginal) {
|
|
202
|
+
return `HTTP request: ${pc.bold(urlOriginal)}`;
|
|
203
|
+
}
|
|
204
|
+
function logHttpResponse(urlOriginal, httpRequestId, pageContextReturn) {
|
|
194
205
|
const statusCode = pageContextReturn.httpResponse?.statusCode ?? null;
|
|
206
|
+
{
|
|
207
|
+
// If URL doesn't include Base URL
|
|
208
|
+
const { errorWhileRendering } = pageContextReturn;
|
|
209
|
+
const isSkipped = statusCode === null && (errorWhileRendering === null || errorWhileRendering === undefined);
|
|
210
|
+
if (isSkipped)
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
195
213
|
const isSuccess = statusCode !== null && statusCode >= 200 && statusCode <= 399;
|
|
196
214
|
const isNominal = isSuccess || statusCode === 404;
|
|
197
215
|
const color = (s) => pc.bold(isSuccess ? pc.green(String(s)) : pc.red(String(s)));
|
|
@@ -205,39 +223,30 @@ function logHttpResponse(urlToShowToUser, httpRequestId, pageContextReturn) {
|
|
|
205
223
|
.find((header) => header[0] === 'Location');
|
|
206
224
|
assert(headerRedirect);
|
|
207
225
|
const urlRedirect = headerRedirect[1];
|
|
208
|
-
|
|
226
|
+
urlOriginal = urlRedirect;
|
|
209
227
|
}
|
|
210
|
-
logRuntimeInfo?.(`HTTP ${type} ${pc.bold(
|
|
228
|
+
logRuntimeInfo?.(`HTTP ${type} ${pc.bold(urlOriginal)} ${color(statusCode ?? 'ERR')}`, httpRequestId, isNominal ? 'info' : 'error');
|
|
211
229
|
}
|
|
212
230
|
function getPageContextHttpResponseNullWithError(err, pageContextInit) {
|
|
213
|
-
const
|
|
214
|
-
objectAssign(
|
|
215
|
-
objectAssign(
|
|
231
|
+
const pageContextHttpResponseNull = {};
|
|
232
|
+
objectAssign(pageContextHttpResponseNull, pageContextInit);
|
|
233
|
+
objectAssign(pageContextHttpResponseNull, {
|
|
216
234
|
httpResponse: null,
|
|
217
235
|
errorWhileRendering: err
|
|
218
236
|
});
|
|
219
|
-
return
|
|
237
|
+
return pageContextHttpResponseNull;
|
|
220
238
|
}
|
|
221
239
|
function getPageContextHttpResponseNull(pageContextInit) {
|
|
222
|
-
const
|
|
223
|
-
objectAssign(
|
|
224
|
-
objectAssign(
|
|
240
|
+
const pageContextHttpResponseNull = {};
|
|
241
|
+
objectAssign(pageContextHttpResponseNull, pageContextInit);
|
|
242
|
+
objectAssign(pageContextHttpResponseNull, {
|
|
225
243
|
httpResponse: null,
|
|
226
244
|
errorWhileRendering: null
|
|
227
245
|
});
|
|
228
|
-
return
|
|
246
|
+
return pageContextHttpResponseNull;
|
|
229
247
|
}
|
|
230
248
|
async function renderPageNominal(pageContext) {
|
|
231
249
|
objectAssign(pageContext, { errorWhileRendering: null });
|
|
232
|
-
// Check Base URL
|
|
233
|
-
{
|
|
234
|
-
const { urlWithoutPageContextRequestSuffix } = handlePageContextRequestUrl(pageContext.urlOriginal);
|
|
235
|
-
const hasBaseServer = parseUrl(urlWithoutPageContextRequestSuffix, pageContext._baseServer).hasBaseServer || !!pageContext._urlRewrite;
|
|
236
|
-
if (!hasBaseServer) {
|
|
237
|
-
objectAssign(pageContext, { httpResponse: null });
|
|
238
|
-
return pageContext;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
250
|
// Route
|
|
242
251
|
{
|
|
243
252
|
const pageContextFromRoute = await route(pageContext);
|
|
@@ -303,7 +312,7 @@ function getRequestId() {
|
|
|
303
312
|
assert(httpRequestId >= 1);
|
|
304
313
|
return httpRequestId;
|
|
305
314
|
}
|
|
306
|
-
function
|
|
315
|
+
function isIgnoredUrl(urlOriginal) {
|
|
307
316
|
const isViteClientRequest = urlOriginal.endsWith('/@vite/client') || urlOriginal.startsWith('/@fs/');
|
|
308
317
|
assertWarning(!isViteClientRequest, `The vike middleware renderPage() was called with the URL ${urlOriginal} which is unexpected because the HTTP request should have already been handled by Vite's development middleware. Make sure to 1. install Vite's development middleware and 2. add Vite's middleware *before* Vike's middleware, see https://vike.dev/renderPage`, { onlyOnce: true });
|
|
309
318
|
return (urlOriginal.endsWith('/__vite_ping') ||
|
|
@@ -327,10 +336,8 @@ function normalizeUrl(pageContextInit, httpRequestId) {
|
|
|
327
336
|
function getPermanentRedirect(pageContextInit, httpRequestId) {
|
|
328
337
|
const { redirects, baseServer } = getGlobalContext();
|
|
329
338
|
const urlWithoutBase = removeBaseServer(pageContextInit.urlOriginal, baseServer);
|
|
330
|
-
let urlOriginalPathnameWithouBase;
|
|
331
339
|
let origin = null;
|
|
332
340
|
let urlTarget = modifyUrlPathname(urlWithoutBase, (urlPathname) => {
|
|
333
|
-
urlOriginalPathnameWithouBase = urlPathname;
|
|
334
341
|
const urlTargetWithOrigin = resolveRedirects(redirects, urlPathname);
|
|
335
342
|
if (urlTargetWithOrigin === null)
|
|
336
343
|
return null;
|
|
@@ -340,13 +347,12 @@ function getPermanentRedirect(pageContextInit, httpRequestId) {
|
|
|
340
347
|
});
|
|
341
348
|
if (origin)
|
|
342
349
|
urlTarget = addUrlOrigin(urlTarget, origin);
|
|
343
|
-
assert(urlOriginalPathnameWithouBase);
|
|
344
350
|
if (urlTarget === urlWithoutBase)
|
|
345
351
|
return null;
|
|
346
352
|
logRuntimeInfo?.(`Permanent redirect defined by your config.redirects (https://vike.dev/redirects)`, httpRequestId, 'info');
|
|
347
353
|
urlTarget = prependBase(urlTarget, baseServer);
|
|
348
354
|
assert(urlTarget !== pageContextInit.urlOriginal);
|
|
349
|
-
const httpResponse = createHttpResponseObjectRedirect({ url: urlTarget, statusCode: 301 },
|
|
355
|
+
const httpResponse = createHttpResponseObjectRedirect({ url: urlTarget, statusCode: 301 }, urlWithoutBase);
|
|
350
356
|
const pageContextHttpResponse = { ...pageContextInit, httpResponse };
|
|
351
357
|
return pageContextHttpResponse;
|
|
352
358
|
}
|
|
@@ -390,10 +396,28 @@ async function handleAbortError(errAbort, pageContextsFromRewrite, pageContextIn
|
|
|
390
396
|
...pageContextInit,
|
|
391
397
|
...pageContextAbort
|
|
392
398
|
};
|
|
393
|
-
const httpResponse = createHttpResponseObjectRedirect(pageContextAbort._urlRedirect,
|
|
399
|
+
const httpResponse = createHttpResponseObjectRedirect(pageContextAbort._urlRedirect, (() => {
|
|
400
|
+
const { pathname, searchOriginal } = pageContextNominalPageInit.urlParsed;
|
|
401
|
+
const urlLogical = createUrlFromComponents(null, pathname, searchOriginal,
|
|
402
|
+
// The server-side doesn't have access to the hash
|
|
403
|
+
null);
|
|
404
|
+
return urlLogical;
|
|
405
|
+
})());
|
|
394
406
|
objectAssign(pageContextReturn, { httpResponse });
|
|
395
407
|
return { pageContextReturn };
|
|
396
408
|
}
|
|
397
409
|
assert(pageContextAbort.abortStatusCode);
|
|
398
410
|
return { pageContextAbort };
|
|
399
411
|
}
|
|
412
|
+
function checkBaseUrl(pageContextInit, httpRequestId) {
|
|
413
|
+
const { baseServer } = getGlobalContext();
|
|
414
|
+
const { urlOriginal } = pageContextInit;
|
|
415
|
+
const { urlWithoutPageContextRequestSuffix } = handlePageContextRequestUrl(urlOriginal);
|
|
416
|
+
const { hasBaseServer } = parseUrl(urlWithoutPageContextRequestSuffix, baseServer);
|
|
417
|
+
if (!hasBaseServer) {
|
|
418
|
+
logRuntimeInfo?.(`${getRequestInfoMessage(urlOriginal)} skipped because URL ${pc.bold(urlOriginal)} doesn't start with Base URL ${pc.bold(baseServer)} (https://vike.dev/base-url)`, httpRequestId, 'info');
|
|
419
|
+
const pageContextHttpResponseNull = getPageContextHttpResponseNull(pageContextInit);
|
|
420
|
+
return pageContextHttpResponseNull;
|
|
421
|
+
}
|
|
422
|
+
return null;
|
|
423
|
+
}
|
|
@@ -3,7 +3,7 @@ import { assert, hasProp, isCallable, isObject, cast, assertUsage } from '../uti
|
|
|
3
3
|
import { assertExportValues } from './assert_exports_old_design.js';
|
|
4
4
|
import { getPageFileObject } from './getPageFileObject.js';
|
|
5
5
|
import { fileTypes } from './fileTypes.js';
|
|
6
|
-
import { assertPageConfigGlobalSerialized, assertPageConfigsSerialized } from '../page-configs/serialize/
|
|
6
|
+
import { assertPageConfigGlobalSerialized, assertPageConfigsSerialized } from '../page-configs/serialize/assertPageConfigsSerialized.js';
|
|
7
7
|
import { parsePageConfigs } from '../page-configs/serialize/parsePageConfigs.js';
|
|
8
8
|
function parseGlobResults(pageFilesExports) {
|
|
9
9
|
assert(hasProp(pageFilesExports, 'isGeneratedFile'));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { executeHook };
|
|
2
2
|
export { isUserHookError };
|
|
3
|
-
import type {
|
|
3
|
+
import type { Hook, HookLoc } from './getHook.js';
|
|
4
4
|
declare function isUserHookError(err: unknown): false | HookLoc;
|
|
5
|
-
declare function executeHook<T = unknown>(
|
|
5
|
+
declare function executeHook<T = unknown>(hookFnCaller: () => T, hook: Omit<Hook, 'hookFn'>): Promise<T>;
|
|
@@ -12,8 +12,8 @@ function isUserHookError(err) {
|
|
|
12
12
|
return false;
|
|
13
13
|
return globalObject.userHookErrors.get(err) ?? false;
|
|
14
14
|
}
|
|
15
|
-
function executeHook(
|
|
16
|
-
const { timeoutErr, timeoutWarn } =
|
|
15
|
+
function executeHook(hookFnCaller, hook) {
|
|
16
|
+
const { hookName, hookFilePath, hookTimeout: { error: timeoutErr, warning: timeoutWarn } } = hook;
|
|
17
17
|
let resolve;
|
|
18
18
|
let reject;
|
|
19
19
|
const promise = new Promise((resolve_, reject_) => {
|
|
@@ -27,19 +27,23 @@ function executeHook(hookFn, hookName, hookFilePath) {
|
|
|
27
27
|
};
|
|
28
28
|
});
|
|
29
29
|
const clearTimeouts = () => {
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
if (currentTimeoutWarn)
|
|
31
|
+
clearTimeout(currentTimeoutWarn);
|
|
32
|
+
if (currentTimeoutErr)
|
|
33
|
+
clearTimeout(currentTimeoutErr);
|
|
32
34
|
};
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
const currentTimeoutWarn = isNotDisabled(timeoutWarn) &&
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
assertWarning(false, `The ${hookName}() hook defined by ${hookFilePath} is slow: it's taking more than ${humanizeTime(timeoutWarn)} (https://vike.dev/hooksTimeout)`, { onlyOnce: false });
|
|
38
|
+
}, timeoutWarn);
|
|
39
|
+
const currentTimeoutErr = isNotDisabled(timeoutErr) &&
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
const err = getProjectError(`The ${hookName}() hook defined by ${hookFilePath} timed out: it didn't finish after ${humanizeTime(timeoutErr)} (https://vike.dev/hooksTimeout)`);
|
|
42
|
+
reject(err);
|
|
43
|
+
}, timeoutErr);
|
|
40
44
|
(async () => {
|
|
41
45
|
try {
|
|
42
|
-
const ret = await
|
|
46
|
+
const ret = await hookFnCaller();
|
|
43
47
|
resolve(ret);
|
|
44
48
|
}
|
|
45
49
|
catch (err) {
|
|
@@ -51,21 +55,6 @@ function executeHook(hookFn, hookName, hookFilePath) {
|
|
|
51
55
|
})();
|
|
52
56
|
return promise;
|
|
53
57
|
}
|
|
54
|
-
function
|
|
55
|
-
|
|
56
|
-
return {
|
|
57
|
-
timeoutErr: 5 * 1000,
|
|
58
|
-
timeoutWarn: 1 * 1000
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
if (hookName === 'onBeforePrerender') {
|
|
62
|
-
return {
|
|
63
|
-
timeoutErr: 10 * 60 * 1000,
|
|
64
|
-
timeoutWarn: 30 * 1000
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
timeoutErr: 40 * 1000,
|
|
69
|
-
timeoutWarn: 4 * 1000
|
|
70
|
-
};
|
|
58
|
+
function isNotDisabled(timeout) {
|
|
59
|
+
return !!timeout && timeout !== Infinity;
|
|
71
60
|
}
|
|
@@ -1,24 +1,34 @@
|
|
|
1
1
|
export { getHook };
|
|
2
|
+
export { getHookFromPageConfig };
|
|
3
|
+
export { getHookFromPageConfigGlobal };
|
|
2
4
|
export { assertHook };
|
|
3
|
-
export { assertHookFn };
|
|
4
5
|
export type { Hook };
|
|
5
6
|
export type { HookName };
|
|
6
7
|
export type { HookLoc };
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
export type { HookTimeout };
|
|
9
|
+
export type { HooksTimeoutProvidedByUser };
|
|
10
|
+
export { getHookTimeoutDefault };
|
|
11
|
+
import type { PageContextExports } from '../getPageFiles.js';
|
|
12
|
+
import type { HookName, HookNamePage, HookNameGlobal } from '../page-configs/Config.js';
|
|
13
|
+
import type { PageConfigBuildTime, PageConfigGlobalRuntime, PageConfigRuntime } from '../page-configs/PageConfig.js';
|
|
9
14
|
type Hook = HookLoc & {
|
|
10
15
|
hookFn: HookFn;
|
|
16
|
+
hookTimeout: HookTimeout;
|
|
11
17
|
};
|
|
12
18
|
type HookLoc = {
|
|
13
19
|
hookName: HookName;
|
|
14
20
|
hookFilePath: string;
|
|
15
21
|
};
|
|
16
22
|
type HookFn = (arg: unknown) => unknown;
|
|
23
|
+
type HookTimeout = {
|
|
24
|
+
error: number | false;
|
|
25
|
+
warning: number | false;
|
|
26
|
+
};
|
|
27
|
+
type HooksTimeoutProvidedByUser = false | Partial<Record<HookName, false | Partial<HookTimeout>>>;
|
|
17
28
|
declare function getHook(pageContext: PageContextExports, hookName: HookName): null | Hook;
|
|
29
|
+
declare function getHookFromPageConfig(pageConfig: PageConfigRuntime | PageConfigBuildTime, hookName: HookNamePage): null | Hook;
|
|
30
|
+
declare function getHookFromPageConfigGlobal(pageConfigGlobal: PageConfigGlobalRuntime, hookName: HookNameGlobal): null | Hook;
|
|
18
31
|
declare function assertHook<TPageContext extends PageContextExports, THookName extends PropertyKey & HookName>(pageContext: TPageContext, hookName: THookName): asserts pageContext is TPageContext & {
|
|
19
32
|
exports: Record<THookName, Function | undefined>;
|
|
20
33
|
};
|
|
21
|
-
declare function
|
|
22
|
-
hookName: HookName;
|
|
23
|
-
hookFilePath: string;
|
|
24
|
-
}): asserts hookFn is HookFn;
|
|
34
|
+
declare function getHookTimeoutDefault(hookName: HookName): HookTimeout;
|
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
export { getHook };
|
|
2
|
+
export { getHookFromPageConfig };
|
|
3
|
+
export { getHookFromPageConfigGlobal };
|
|
2
4
|
export { assertHook };
|
|
3
|
-
|
|
4
|
-
|
|
5
|
+
// TODO/v1-release: remove
|
|
6
|
+
// We export for old V0.4 design which doesn't support config.hooksTimeout
|
|
7
|
+
export { getHookTimeoutDefault };
|
|
8
|
+
import { getConfigValue, getHookFilePathToShowToUser } from '../page-configs/helpers.js';
|
|
9
|
+
import { assert, assertUsage, checkType, isCallable, isObject } from '../utils.js';
|
|
10
|
+
import pc from '@brillout/picocolors';
|
|
5
11
|
function getHook(pageContext, hookName) {
|
|
6
12
|
if (!(hookName in pageContext.exports)) {
|
|
7
13
|
return null;
|
|
8
14
|
}
|
|
15
|
+
const { hooksTimeout } = pageContext.config;
|
|
16
|
+
const hookTimeout = getHookTimeout(hooksTimeout, hookName);
|
|
9
17
|
const hookFn = pageContext.exports[hookName];
|
|
10
18
|
const file = pageContext.exportsAll[hookName][0];
|
|
11
19
|
assert(file.exportValue === hookFn);
|
|
@@ -15,7 +23,37 @@ function getHook(pageContext, hookName) {
|
|
|
15
23
|
assert(hookFilePath);
|
|
16
24
|
assert(!hookFilePath.endsWith(' '));
|
|
17
25
|
assertHookFn(hookFn, { hookName, hookFilePath });
|
|
18
|
-
return { hookFn, hookName, hookFilePath };
|
|
26
|
+
return { hookFn, hookName, hookFilePath, hookTimeout };
|
|
27
|
+
}
|
|
28
|
+
function getHookFromPageConfig(pageConfig, hookName) {
|
|
29
|
+
const configValue = getConfigValue(pageConfig, hookName);
|
|
30
|
+
const hooksTimeout = getConfigValue(pageConfig, 'hooksTimeout')?.value;
|
|
31
|
+
if (!configValue)
|
|
32
|
+
return null;
|
|
33
|
+
const hookFn = configValue.value;
|
|
34
|
+
if (!hookFn)
|
|
35
|
+
return null;
|
|
36
|
+
const hookFilePath = getHookFilePathToShowToUser(configValue);
|
|
37
|
+
// hook isn't a computed nor a cumulative config => definedAt should always be defined
|
|
38
|
+
assert(hookFilePath);
|
|
39
|
+
assertHookFn(hookFn, { hookName, hookFilePath });
|
|
40
|
+
const hookTimeout = getHookTimeout(hooksTimeout, hookName);
|
|
41
|
+
return { hookFn, hookName, hookFilePath, hookTimeout };
|
|
42
|
+
}
|
|
43
|
+
function getHookFromPageConfigGlobal(pageConfigGlobal, hookName) {
|
|
44
|
+
const configValue = pageConfigGlobal.configValues[hookName];
|
|
45
|
+
if (!configValue)
|
|
46
|
+
return null;
|
|
47
|
+
const hookFn = configValue.value;
|
|
48
|
+
if (!hookFn)
|
|
49
|
+
return null;
|
|
50
|
+
const hookFilePath = getHookFilePathToShowToUser(configValue);
|
|
51
|
+
// hook isn't a computed nor a cumulative config => definedAt should always be defined
|
|
52
|
+
assert(hookFilePath);
|
|
53
|
+
assertHookFn(hookFn, { hookName, hookFilePath });
|
|
54
|
+
// We could use the global value of config.hooksTimeout but it requires some non-trivial refactoring
|
|
55
|
+
const hookTimeout = getHookTimeoutDefault(hookName);
|
|
56
|
+
return { hookFn, hookName, hookFilePath, hookTimeout };
|
|
19
57
|
}
|
|
20
58
|
function assertHook(pageContext, hookName) {
|
|
21
59
|
getHook(pageContext, hookName);
|
|
@@ -26,3 +64,65 @@ function assertHookFn(hookFn, { hookName, hookFilePath }) {
|
|
|
26
64
|
assertUsage(isCallable(hookFn), `Hook ${hookName}() defined by ${hookFilePath} should be a function`);
|
|
27
65
|
checkType(hookFn);
|
|
28
66
|
}
|
|
67
|
+
function getHookTimeout(hooksTimeoutProvidedByUser, hookName) {
|
|
68
|
+
const hooksTimeoutProvidedbyUserNormalized = getHooksTimeoutProvidedByUserNormalized(hooksTimeoutProvidedByUser);
|
|
69
|
+
if (hooksTimeoutProvidedbyUserNormalized === false)
|
|
70
|
+
return { error: false, warning: false };
|
|
71
|
+
const providedbyUser = hooksTimeoutProvidedbyUserNormalized[hookName];
|
|
72
|
+
const hookTimeout = getHookTimeoutDefault(hookName);
|
|
73
|
+
if (providedbyUser?.error !== undefined)
|
|
74
|
+
hookTimeout.error = providedbyUser.error;
|
|
75
|
+
if (providedbyUser?.warning !== undefined)
|
|
76
|
+
hookTimeout.warning = providedbyUser.warning;
|
|
77
|
+
return hookTimeout;
|
|
78
|
+
}
|
|
79
|
+
// Ideally this should be called only once and at build-time (to avoid bloating the client-side bundle), but we didn't implement any mechanism to valide config values at build-time yet
|
|
80
|
+
function getHooksTimeoutProvidedByUserNormalized(hooksTimeoutProvidedByUser) {
|
|
81
|
+
if (hooksTimeoutProvidedByUser === undefined)
|
|
82
|
+
return {};
|
|
83
|
+
if (hooksTimeoutProvidedByUser === false)
|
|
84
|
+
return false;
|
|
85
|
+
assertUsage(isObject(hooksTimeoutProvidedByUser), `Setting ${pc.cyan('hooksTimeout')} should be ${pc.cyan('false')} or an object`);
|
|
86
|
+
const hooksTimeoutProvidedByUserNormalized = {};
|
|
87
|
+
Object.entries(hooksTimeoutProvidedByUser).forEach(([hookName, hookTimeoutProvidedbyUser]) => {
|
|
88
|
+
if (hookTimeoutProvidedbyUser === false) {
|
|
89
|
+
hooksTimeoutProvidedByUserNormalized[hookName] = { error: false, warning: false };
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
assertUsage(isObject(hookTimeoutProvidedbyUser), `Setting ${pc.cyan(`hooksTimeout.${hookName}`)} should be ${pc.cyan('false')} or an object`);
|
|
93
|
+
const [error, warning] = ['error', 'warning'].map((timeoutName) => {
|
|
94
|
+
const timeoutVal = hookTimeoutProvidedbyUser[timeoutName];
|
|
95
|
+
if (timeoutVal === undefined || timeoutVal === false)
|
|
96
|
+
return timeoutVal;
|
|
97
|
+
const errPrefix = `Setting ${pc.cyan(`hooksTimeout.${hookName}.${timeoutName}`)} should be`;
|
|
98
|
+
assertUsage(typeof timeoutVal === 'number', `${errPrefix} ${pc.cyan('false')} or a number`);
|
|
99
|
+
assertUsage(timeoutVal > 0, `${errPrefix} a positive number`);
|
|
100
|
+
return timeoutVal;
|
|
101
|
+
});
|
|
102
|
+
hooksTimeoutProvidedByUserNormalized[hookName] = { error, warning };
|
|
103
|
+
});
|
|
104
|
+
return hooksTimeoutProvidedByUserNormalized;
|
|
105
|
+
}
|
|
106
|
+
function getHookTimeoutDefault(hookName) {
|
|
107
|
+
if (hookName === 'onBeforeRoute') {
|
|
108
|
+
return {
|
|
109
|
+
error: 5 * 1000,
|
|
110
|
+
warning: 1 * 1000
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (hookName === 'onPrerenderStart' ||
|
|
114
|
+
hookName === 'onBeforePrerenderStart' ||
|
|
115
|
+
// TODO/v1-release: remove
|
|
116
|
+
// Old V0.4 design hooks (https://vike.dev/migration/v1-design#renamed-hooks)
|
|
117
|
+
hookName === 'onBeforePrerender' ||
|
|
118
|
+
hookName === 'prerender') {
|
|
119
|
+
return {
|
|
120
|
+
error: 10 * 60 * 1000,
|
|
121
|
+
warning: 30 * 1000
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
error: 30 * 1000,
|
|
126
|
+
warning: 4 * 1000
|
|
127
|
+
};
|
|
128
|
+
}
|