vike 0.4.146 → 0.4.147-commit-f9a91f3
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/index.js +6 -4
- package/dist/cjs/node/plugin/plugins/devConfig/determineOptimizeDeps.js +3 -4
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +76 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +61 -40
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +104 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +62 -75
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +43 -17
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +12 -70
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/isRuntimeEnvMatch.js +11 -8
- package/dist/cjs/node/plugin/shared/{getConfigValueSourcesRelevant.js → getConfigValueSourcesNotOverriden.js} +3 -3
- package/dist/cjs/node/plugin/utils.js +2 -0
- package/dist/cjs/node/prerender/runPrerender.js +75 -67
- package/dist/cjs/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
- package/dist/cjs/node/runtime/index-common.js +3 -1
- package/dist/cjs/node/runtime/renderPage/analyzePage.js +2 -2
- 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/executeOnRenderHtmlHook.js +1 -2
- package/dist/cjs/node/runtime/renderPage/getHttpResponseBody.js +1 -1
- package/dist/cjs/node/runtime/renderPage.js +75 -51
- package/dist/cjs/shared/getPageFiles/analyzePageClientSide/determineClientEntry.js +1 -0
- package/dist/cjs/shared/page-configs/loadConfigValues.js +12 -3
- package/dist/cjs/shared/page-configs/serialize/parseConfigValuesSerialized.js +19 -0
- package/dist/cjs/shared/page-configs/serialize/parsePageConfigs.js +3 -12
- package/dist/cjs/shared/route/resolveRedirects.js +8 -5
- package/dist/cjs/utils/assertKeys.js +28 -0
- package/dist/cjs/utils/joinEnglish.js +3 -3
- package/dist/cjs/utils/parseUrl-extras.js +22 -8
- package/dist/cjs/utils/parseUrl.js +24 -16
- package/dist/cjs/utils/projectInfo.js +3 -2
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +25 -11
- package/dist/esm/client/client-routing-runtime/index.d.ts +1 -0
- package/dist/esm/client/client-routing-runtime/index.js +1 -0
- package/dist/esm/client/client-routing-runtime/onBrowserHistoryNavigation.js +2 -2
- package/dist/esm/client/shared/getPageContextSerializedInHtml.js +1 -1
- package/dist/esm/node/plugin/index.d.ts +1 -0
- package/dist/esm/node/plugin/index.js +1 -0
- package/dist/esm/node/plugin/plugins/devConfig/determineOptimizeDeps.js +3 -4
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.d.ts +5 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +70 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +58 -37
- 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 +98 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +63 -76
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +43 -17
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.d.ts +0 -3
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +13 -68
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/isRuntimeEnvMatch.js +11 -8
- package/dist/esm/node/plugin/shared/getConfigValueSourcesNotOverriden.d.ts +5 -0
- package/dist/esm/node/plugin/shared/{getConfigValueSourcesRelevant.js → getConfigValueSourcesNotOverriden.js} +2 -2
- package/dist/esm/node/plugin/utils.d.ts +2 -0
- package/dist/esm/node/plugin/utils.js +2 -0
- package/dist/esm/node/prerender/runPrerender.js +75 -67
- package/dist/esm/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
- package/dist/esm/node/runtime/index-common.d.ts +1 -0
- package/dist/esm/node/runtime/index-common.js +1 -0
- package/dist/esm/node/runtime/renderPage/analyzePage.js +2 -2
- 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/executeOnRenderHtmlHook.js +1 -2
- package/dist/esm/node/runtime/renderPage/getHttpResponseBody.js +1 -1
- package/dist/esm/node/runtime/renderPage.js +76 -52
- package/dist/esm/shared/getPageFiles/analyzePageClientSide/determineClientEntry.js +1 -0
- package/dist/esm/shared/page-configs/PageConfig.d.ts +14 -4
- package/dist/esm/shared/page-configs/loadConfigValues.js +12 -3
- package/dist/esm/shared/page-configs/serialize/parseConfigValuesSerialized.d.ts +4 -0
- package/dist/esm/shared/page-configs/serialize/parseConfigValuesSerialized.js +16 -0
- package/dist/esm/shared/page-configs/serialize/parsePageConfigs.js +4 -13
- package/dist/esm/shared/route/resolveRedirects.js +8 -5
- package/dist/esm/utils/assertKeys.d.ts +4 -0
- package/dist/esm/utils/assertKeys.js +22 -0
- package/dist/esm/utils/joinEnglish.d.ts +1 -1
- package/dist/esm/utils/joinEnglish.js +3 -3
- package/dist/esm/utils/parseUrl-extras.d.ts +3 -1
- package/dist/esm/utils/parseUrl-extras.js +21 -7
- package/dist/esm/utils/parseUrl.js +24 -16
- package/dist/esm/utils/projectInfo.d.ts +3 -1
- package/dist/esm/utils/projectInfo.js +2 -1
- package/package.json +3 -3
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/helpers.js +0 -28
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/helpers.d.ts +0 -5
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/helpers.js +0 -25
- package/dist/esm/node/plugin/shared/getConfigValueSourcesRelevant.d.ts +0 -5
|
@@ -71,19 +71,25 @@ async function runPrerender(options, manuallyTriggered) {
|
|
|
71
71
|
const doNotPrerenderList = [];
|
|
72
72
|
const vikeConfig = await getVikeConfig(viteConfig, false);
|
|
73
73
|
await collectDoNoPrerenderList(renderContext, vikeConfig.pageConfigs, doNotPrerenderList, concurrencyLimit);
|
|
74
|
-
await callOnBeforePrerenderStartHooks(prerenderContext, renderContext, concurrencyLimit);
|
|
74
|
+
await callOnBeforePrerenderStartHooks(prerenderContext, renderContext, concurrencyLimit, doNotPrerenderList);
|
|
75
75
|
await handlePagesWithStaticRoutes(prerenderContext, renderContext, doNotPrerenderList, concurrencyLimit);
|
|
76
76
|
await callOnPrerenderStartHook(prerenderContext, renderContext);
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
const prerenderedPageContexts = {};
|
|
78
|
+
let prerenderedCount = 0;
|
|
79
|
+
const onComplete = async (htmlFile) => {
|
|
80
|
+
prerenderedCount++;
|
|
81
|
+
if (htmlFile.pageId) {
|
|
82
|
+
prerenderedPageContexts[htmlFile.pageId] = htmlFile.pageContext;
|
|
83
|
+
}
|
|
84
|
+
await writeFiles(htmlFile, root, outDirClient, options.onPagePrerender, logLevel);
|
|
85
|
+
};
|
|
86
|
+
await routeAndPrerender(prerenderContext, concurrencyLimit, onComplete);
|
|
87
|
+
warnContradictoryNoPrerenderList(prerenderedPageContexts, doNotPrerenderList);
|
|
88
|
+
await prerender404(prerenderedPageContexts, renderContext, prerenderContext, onComplete);
|
|
82
89
|
if (logLevel === 'info') {
|
|
83
|
-
console.log(`${pc.green(`✓`)} ${
|
|
90
|
+
console.log(`${pc.green(`✓`)} ${prerenderedCount} HTML documents pre-rendered.`);
|
|
84
91
|
}
|
|
85
|
-
|
|
86
|
-
warnMissingPages(prerenderPageIds, doNotPrerenderList, renderContext, partial);
|
|
92
|
+
warnMissingPages(prerenderedPageContexts, doNotPrerenderList, renderContext, partial);
|
|
87
93
|
}
|
|
88
94
|
async function collectDoNoPrerenderList(renderContext, pageConfigs, doNotPrerenderList, concurrencyLimit) {
|
|
89
95
|
// V1 design
|
|
@@ -145,7 +151,7 @@ function assertExportNames(pageFile) {
|
|
|
145
151
|
const { exportNames, fileType } = pageFile;
|
|
146
152
|
assert(exportNames || fileType === '.page.route' || fileType === '.css', pageFile.filePath);
|
|
147
153
|
}
|
|
148
|
-
async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext, concurrencyLimit) {
|
|
154
|
+
async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext, concurrencyLimit, doNotPrerenderList) {
|
|
149
155
|
const onBeforePrerenderStartHooks = [];
|
|
150
156
|
// V1 design
|
|
151
157
|
await Promise.all(renderContext.pageConfigs.map((pageConfig) => concurrencyLimit(async () => {
|
|
@@ -161,7 +167,8 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
|
|
|
161
167
|
onBeforePrerenderStartHooks.push({
|
|
162
168
|
hookFn,
|
|
163
169
|
hookName: 'onBeforePrerenderStart',
|
|
164
|
-
hookFilePath
|
|
170
|
+
hookFilePath,
|
|
171
|
+
pageId: pageConfig.pageId
|
|
165
172
|
});
|
|
166
173
|
})));
|
|
167
174
|
// 0.4 design
|
|
@@ -184,10 +191,14 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
|
|
|
184
191
|
onBeforePrerenderStartHooks.push({
|
|
185
192
|
hookFn,
|
|
186
193
|
hookName: 'prerender',
|
|
187
|
-
hookFilePath
|
|
194
|
+
hookFilePath,
|
|
195
|
+
pageId: p.pageId
|
|
188
196
|
});
|
|
189
197
|
})));
|
|
190
|
-
await Promise.all(onBeforePrerenderStartHooks.map(({ hookFn, hookName, hookFilePath }) => concurrencyLimit(async () => {
|
|
198
|
+
await Promise.all(onBeforePrerenderStartHooks.map(({ hookFn, hookName, hookFilePath, pageId }) => concurrencyLimit(async () => {
|
|
199
|
+
if (doNotPrerenderList.find((p) => p.pageId === pageId)) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
191
202
|
const prerenderResult = await hookFn();
|
|
192
203
|
const result = normalizeOnPrerenderHookResult(prerenderResult, hookFilePath, hookName);
|
|
193
204
|
result.forEach(({ url, pageContext }) => {
|
|
@@ -406,7 +417,7 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
406
417
|
addUrlComputedProps(pageContext);
|
|
407
418
|
});
|
|
408
419
|
}
|
|
409
|
-
async function routeAndPrerender(prerenderContext,
|
|
420
|
+
async function routeAndPrerender(prerenderContext, concurrencyLimit, onComplete) {
|
|
410
421
|
const globalContext = getGlobalContext();
|
|
411
422
|
assert(globalContext.isPrerendering);
|
|
412
423
|
// Route all URLs
|
|
@@ -466,7 +477,7 @@ async function routeAndPrerender(prerenderContext, htmlFiles, prerenderPageIds,
|
|
|
466
477
|
throw err;
|
|
467
478
|
}
|
|
468
479
|
const { documentHtml, pageContextSerialized } = res;
|
|
469
|
-
|
|
480
|
+
await onComplete({
|
|
470
481
|
urlOriginal,
|
|
471
482
|
pageContext,
|
|
472
483
|
htmlString: documentHtml,
|
|
@@ -474,11 +485,10 @@ async function routeAndPrerender(prerenderContext, htmlFiles, prerenderPageIds,
|
|
|
474
485
|
doNotCreateExtraDirectory: prerenderContext._noExtraDir,
|
|
475
486
|
pageId
|
|
476
487
|
});
|
|
477
|
-
prerenderPageIds[pageId] = pageContext;
|
|
478
488
|
})));
|
|
479
489
|
}
|
|
480
|
-
function warnContradictoryNoPrerenderList(
|
|
481
|
-
Object.entries(
|
|
490
|
+
function warnContradictoryNoPrerenderList(prerenderedPageContexts, doNotPrerenderList) {
|
|
491
|
+
Object.entries(prerenderedPageContexts).forEach(([pageId, pageContext]) => {
|
|
482
492
|
const doNotPrerenderListEntry = doNotPrerenderList.find((p) => p.pageId === pageId);
|
|
483
493
|
const { urlOriginal, _providedByHook: providedByHook } = pageContext;
|
|
484
494
|
{
|
|
@@ -490,7 +500,7 @@ function warnContradictoryNoPrerenderList(prerenderPageIds, doNotPrerenderList)
|
|
|
490
500
|
assertWarning(false, `The ${providedByHook.hookName}() hook defined by ${providedByHook.hookFilePath} returns the URL ${pc.cyan(urlOriginal)}, while ${setByConfigFile} sets the config ${pc.cyan(setByConfigName)} to ${pc.cyan(String(setByConfigValue))}. This is contradictory: either don't set the config ${pc.cyan(setByConfigName)} to ${pc.cyan(String(setByConfigValue))} or remove the URL ${pc.cyan(urlOriginal)} from the list of URLs to be pre-rendered.`, { onlyOnce: true });
|
|
491
501
|
});
|
|
492
502
|
}
|
|
493
|
-
function warnMissingPages(
|
|
503
|
+
function warnMissingPages(prerenderedPageContexts, doNotPrerenderList, renderContext, partial) {
|
|
494
504
|
const isV1 = renderContext.pageConfigs.length > 0;
|
|
495
505
|
const hookName = isV1 ? 'onBeforePrerenderStart' : 'prerender';
|
|
496
506
|
/* TODO/after-v1-design-release: document setting `prerender: false` as an alternative to using prerender.partial (both in the warnings and the docs)
|
|
@@ -498,7 +508,7 @@ function warnMissingPages(prerenderPageIds, doNotPrerenderList, renderContext, p
|
|
|
498
508
|
const msgAddendum = `Explicitly opt-out by setting the config ${optOutName} to ${isV1 ? 'false' : 'true'} or use the option prerender.partial`
|
|
499
509
|
*/
|
|
500
510
|
renderContext.allPageIds
|
|
501
|
-
.filter((pageId) => !
|
|
511
|
+
.filter((pageId) => !prerenderedPageContexts[pageId])
|
|
502
512
|
.filter((pageId) => !doNotPrerenderList.find((p) => p.pageId === pageId))
|
|
503
513
|
.filter((pageId) => !isErrorPage(pageId, renderContext.pageConfigs))
|
|
504
514
|
.forEach((pageId) => {
|
|
@@ -506,8 +516,8 @@ function warnMissingPages(prerenderPageIds, doNotPrerenderList, renderContext, p
|
|
|
506
516
|
assertWarning(partial, `Cannot pre-render page ${pageAt} because it has a non-static route, while no ${hookName}() hook returned any URL matching the page's route. You need to use a ${hookName}() hook (https://vike.dev/${hookName}) providing a list of URLs for ${pageAt} that should be pre-rendered. If you don't want to pre-render ${pageAt} then use the option prerender.partial (https://vike.dev/prerender-config#partial) to suppress this warning.`, { onlyOnce: true });
|
|
507
517
|
});
|
|
508
518
|
}
|
|
509
|
-
async function prerender404(
|
|
510
|
-
if (!
|
|
519
|
+
async function prerender404(prerenderedPageContexts, renderContext, prerenderContext, onComplete) {
|
|
520
|
+
if (!Object.values(prerenderedPageContexts).find(({ urlOriginal }) => urlOriginal === '/404')) {
|
|
511
521
|
let result;
|
|
512
522
|
try {
|
|
513
523
|
result = await prerender404Page(renderContext, prerenderContext.pageContextInit);
|
|
@@ -519,7 +529,7 @@ async function prerender404(htmlFiles, renderContext, prerenderContext) {
|
|
|
519
529
|
if (result) {
|
|
520
530
|
const urlOriginal = '/404';
|
|
521
531
|
const { documentHtml, pageContext } = result;
|
|
522
|
-
|
|
532
|
+
await onComplete({
|
|
523
533
|
urlOriginal,
|
|
524
534
|
pageContext,
|
|
525
535
|
htmlString: documentHtml,
|
|
@@ -530,59 +540,57 @@ async function prerender404(htmlFiles, renderContext, prerenderContext) {
|
|
|
530
540
|
}
|
|
531
541
|
}
|
|
532
542
|
}
|
|
533
|
-
async function
|
|
543
|
+
async function writeFiles({ urlOriginal, pageContext, htmlString, pageContextSerialized, doNotCreateExtraDirectory }, root, outDirClient, onPagePrerender, logLevel) {
|
|
534
544
|
assert(urlOriginal.startsWith('/'));
|
|
535
545
|
const writeJobs = [
|
|
536
|
-
write(urlOriginal, pageContext, '.html', htmlString, root, outDirClient, doNotCreateExtraDirectory,
|
|
546
|
+
write(urlOriginal, pageContext, '.html', htmlString, root, outDirClient, doNotCreateExtraDirectory, onPagePrerender, logLevel)
|
|
537
547
|
];
|
|
538
548
|
if (pageContextSerialized !== null) {
|
|
539
|
-
writeJobs.push(write(urlOriginal, pageContext, '.pageContext.json', pageContextSerialized, root, outDirClient, doNotCreateExtraDirectory,
|
|
549
|
+
writeJobs.push(write(urlOriginal, pageContext, '.pageContext.json', pageContextSerialized, root, outDirClient, doNotCreateExtraDirectory, onPagePrerender, logLevel));
|
|
540
550
|
}
|
|
541
551
|
await Promise.all(writeJobs);
|
|
542
552
|
}
|
|
543
|
-
function write(urlOriginal, pageContext, fileExtension, fileContent, root, outDirClient, doNotCreateExtraDirectory,
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
fileContent
|
|
566
|
-
}
|
|
567
|
-
});
|
|
568
|
-
await onPagePrerender(prerenderPageContext);
|
|
569
|
-
}
|
|
570
|
-
else {
|
|
571
|
-
const { promises } = await import('fs');
|
|
572
|
-
const { writeFile, mkdir } = promises;
|
|
573
|
-
await mkdir(path.posix.dirname(filePath), { recursive: true });
|
|
574
|
-
await writeFile(filePath, fileContent);
|
|
575
|
-
if (logLevel === 'info') {
|
|
576
|
-
assertPosixPath(root);
|
|
577
|
-
assertPosixPath(outDirClient);
|
|
578
|
-
let outDirClientRelative = path.posix.relative(root, outDirClient);
|
|
579
|
-
if (!outDirClientRelative.endsWith('/')) {
|
|
580
|
-
outDirClientRelative = outDirClientRelative + '/';
|
|
581
|
-
}
|
|
582
|
-
console.log(`${pc.dim(outDirClientRelative)}${pc.blue(filePathRelative)}`);
|
|
553
|
+
async function write(urlOriginal, pageContext, fileExtension, fileContent, root, outDirClient, doNotCreateExtraDirectory, onPagePrerender, logLevel) {
|
|
554
|
+
let fileUrl;
|
|
555
|
+
if (fileExtension === '.html') {
|
|
556
|
+
fileUrl = urlToFile(urlOriginal, '.html', doNotCreateExtraDirectory);
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
fileUrl = getPageContextRequestUrl(urlOriginal);
|
|
560
|
+
}
|
|
561
|
+
assertPosixPath(fileUrl);
|
|
562
|
+
assert(fileUrl.startsWith('/'));
|
|
563
|
+
const filePathRelative = fileUrl.slice(1);
|
|
564
|
+
assert(!filePathRelative.startsWith('/'));
|
|
565
|
+
assertPosixPath(outDirClient);
|
|
566
|
+
assertPosixPath(filePathRelative);
|
|
567
|
+
const filePath = path.posix.join(outDirClient, filePathRelative);
|
|
568
|
+
if (onPagePrerender) {
|
|
569
|
+
const prerenderPageContext = {};
|
|
570
|
+
objectAssign(prerenderPageContext, pageContext);
|
|
571
|
+
objectAssign(prerenderPageContext, {
|
|
572
|
+
_prerenderResult: {
|
|
573
|
+
filePath,
|
|
574
|
+
fileContent
|
|
583
575
|
}
|
|
576
|
+
});
|
|
577
|
+
await onPagePrerender(prerenderPageContext);
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
const { promises } = await import('fs');
|
|
581
|
+
const { writeFile, mkdir } = promises;
|
|
582
|
+
await mkdir(path.posix.dirname(filePath), { recursive: true });
|
|
583
|
+
await writeFile(filePath, fileContent);
|
|
584
|
+
if (logLevel === 'info') {
|
|
585
|
+
assertPosixPath(root);
|
|
586
|
+
assertPosixPath(outDirClient);
|
|
587
|
+
let outDirClientRelative = path.posix.relative(root, outDirClient);
|
|
588
|
+
if (!outDirClientRelative.endsWith('/')) {
|
|
589
|
+
outDirClientRelative = outDirClientRelative + '/';
|
|
590
|
+
}
|
|
591
|
+
console.log(`${pc.dim(outDirClientRelative)}${pc.blue(filePathRelative)}`);
|
|
584
592
|
}
|
|
585
|
-
}
|
|
593
|
+
}
|
|
586
594
|
}
|
|
587
595
|
function normalizeOnPrerenderHookResult(prerenderResult, prerenderHookFile, hookName) {
|
|
588
596
|
if (Array.isArray(prerenderResult)) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { injectAssets__public };
|
|
2
2
|
import { assertUsage, assertWarning, castProp, hasProp } from '../../utils.js';
|
|
3
3
|
import { injectHtmlTagsToString } from '../injectAssets.js';
|
|
4
|
-
// TODO: remove
|
|
4
|
+
// TODO/v1-release: remove
|
|
5
5
|
async function injectAssets__public(htmlString, pageContext) {
|
|
6
6
|
assertWarning(false, '`_injectAssets()` is deprecated and will be removed.', { onlyOnce: true, showStackTrace: true });
|
|
7
7
|
assertUsage(typeof htmlString === 'string', '[injectAssets(htmlString, pageContext)]: Argument `htmlString` should be a string.', { showStackTrace: true });
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { renderPage } from './renderPage.js';
|
|
2
2
|
export { escapeInject, dangerouslySkipEscape } from './html/renderHtml.js';
|
|
3
3
|
export { pipeWebStream, pipeNodeStream, pipeStream, stampPipe } from './html/stream.js';
|
|
4
|
+
export { PROJECT_VERSION as version } from './utils.js';
|
|
4
5
|
export { injectAssets__public as _injectAssets } from './html/injectAssets/injectAssets__public.js';
|
|
5
6
|
export { createPageRenderer } from '../createPageRenderer.js';
|
|
6
7
|
declare global {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { renderPage } from './renderPage.js';
|
|
2
2
|
export { escapeInject, dangerouslySkipEscape } from './html/renderHtml.js';
|
|
3
3
|
export { pipeWebStream, pipeNodeStream, pipeStream, stampPipe } from './html/stream.js';
|
|
4
|
+
export { PROJECT_VERSION as version } from './utils.js';
|
|
4
5
|
// TODO/v1-release: remove
|
|
5
6
|
export { injectAssets__public as _injectAssets } from './html/injectAssets/injectAssets__public.js';
|
|
6
7
|
// TODO/v1-release: remove
|
|
@@ -29,8 +29,8 @@ function analyzePage(pageFilesAll, pageConfig, pageId) {
|
|
|
29
29
|
if (configElement.importPath) {
|
|
30
30
|
const { env } = configElement
|
|
31
31
|
assert(env)
|
|
32
|
-
const onlyAssets = env ===
|
|
33
|
-
const eagerlyImported = env === '
|
|
32
|
+
const onlyAssets = env === { server: true }
|
|
33
|
+
const eagerlyImported = env === { server: true, client: 'if-client-routing', eager: true }
|
|
34
34
|
if (onlyAssets || eagerlyImported) {
|
|
35
35
|
clientDependencies.push({
|
|
36
36
|
id: configElement.importPath,
|
package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { assertNoInfiniteHttpRedirect };
|
|
2
|
-
declare function assertNoInfiniteHttpRedirect(
|
|
2
|
+
declare function assertNoInfiniteHttpRedirect(urlRedirectTarget: string, urlLogical: string): void;
|
package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
export { assertNoInfiniteHttpRedirect };
|
|
2
|
-
import { assert, assertUsage, getGlobalObject } from '../../utils.js';
|
|
2
|
+
import { assert, assertUsage, getGlobalObject, isUriWithProtocol } from '../../utils.js';
|
|
3
3
|
import pc from '@brillout/picocolors';
|
|
4
4
|
const globalObject = getGlobalObject('assertNoInfiniteHttpRedirect.ts', {
|
|
5
5
|
redirectGraph: {}
|
|
6
6
|
});
|
|
7
|
-
function assertNoInfiniteHttpRedirect(
|
|
8
|
-
if (
|
|
9
|
-
// We assume that
|
|
10
|
-
// - There isn't a reliable way to check whether the redirect points to an external origin or the same origin
|
|
7
|
+
function assertNoInfiniteHttpRedirect(urlRedirectTarget, urlLogical) {
|
|
8
|
+
if (isUriWithProtocol(urlRedirectTarget)) {
|
|
9
|
+
// We assume that urlRedirectTarget points to an origin that is external (not the same origin), and we can therefore assume that the app doesn't define an infinite loop (in itself).
|
|
10
|
+
// - There isn't a reliable way to check whether the redirect points to an external origin or the same origin. For same origins, we assume/hope the user to pass the URL without origin.
|
|
11
11
|
// ```js
|
|
12
|
-
// //
|
|
12
|
+
// // For same-origin, the user usually/hopefully passes a URL without origin
|
|
13
13
|
// renderPage({ urlOriginal: '/some/pathname' })
|
|
14
14
|
// ```
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
assert(
|
|
18
|
-
assert(
|
|
17
|
+
assert(urlRedirectTarget.startsWith('/'));
|
|
18
|
+
assert(urlLogical.startsWith('/'));
|
|
19
19
|
const graph = copy(globalObject.redirectGraph);
|
|
20
|
-
graph[
|
|
21
|
-
graph[
|
|
20
|
+
graph[urlRedirectTarget] ?? (graph[urlRedirectTarget] = new Set());
|
|
21
|
+
graph[urlRedirectTarget].add(urlLogical);
|
|
22
22
|
validate(graph);
|
|
23
23
|
globalObject.redirectGraph = graph;
|
|
24
24
|
}
|
|
@@ -26,6 +26,9 @@ function copy(G) {
|
|
|
26
26
|
return Object.fromEntries(Object.entries(G).map(([key, val]) => [key, new Set(val)]));
|
|
27
27
|
}
|
|
28
28
|
// Adapted from: https://stackoverflow.com/questions/60904464/detect-cycle-in-directed-graph/60907076#60907076
|
|
29
|
+
function validate(G) {
|
|
30
|
+
Object.keys(G).forEach((n) => check(G, n, []));
|
|
31
|
+
}
|
|
29
32
|
function check(G, n, path) {
|
|
30
33
|
if (path.includes(n)) {
|
|
31
34
|
const cycle = path.slice(path.indexOf(n)).concat(n);
|
|
@@ -33,6 +36,3 @@ function check(G, n, path) {
|
|
|
33
36
|
}
|
|
34
37
|
G[n]?.forEach((node) => check(G, node, [...path, n]));
|
|
35
38
|
}
|
|
36
|
-
function validate(G) {
|
|
37
|
-
Object.keys(G).forEach((n) => check(G, n, []));
|
|
38
|
-
}
|
|
@@ -25,4 +25,4 @@ declare function createHttpResponseObject(htmlRender: null | HtmlRender, renderH
|
|
|
25
25
|
abortStatusCode?: AbortStatusCode;
|
|
26
26
|
}): Promise<HttpResponse | null>;
|
|
27
27
|
declare function createHttpResponsePageContextJson(pageContextSerialized: string): Promise<HttpResponse>;
|
|
28
|
-
declare function createHttpResponseObjectRedirect({ url, statusCode }: UrlRedirect,
|
|
28
|
+
declare function createHttpResponseObjectRedirect({ url, statusCode }: UrlRedirect, urlLogical: string): HttpResponse;
|
|
@@ -33,9 +33,9 @@ async function createHttpResponsePageContextJson(pageContextSerialized) {
|
|
|
33
33
|
return httpResponse;
|
|
34
34
|
}
|
|
35
35
|
function createHttpResponseObjectRedirect({ url, statusCode },
|
|
36
|
-
// The URL
|
|
37
|
-
|
|
38
|
-
assertNoInfiniteHttpRedirect(url,
|
|
36
|
+
// The URL we assume the redirect to be logically based on
|
|
37
|
+
urlLogical) {
|
|
38
|
+
assertNoInfiniteHttpRedirect(url, urlLogical);
|
|
39
39
|
assert(url);
|
|
40
40
|
assert(statusCode);
|
|
41
41
|
assert(300 <= statusCode && statusCode <= 399);
|
|
@@ -9,8 +9,7 @@ import { assertHookReturnedObject } from '../../../shared/assertHookReturnedObje
|
|
|
9
9
|
import { logRuntimeError } from './loggerRuntime.js';
|
|
10
10
|
import pc from '@brillout/picocolors';
|
|
11
11
|
async function executeOnRenderHtmlHook(pageContext) {
|
|
12
|
-
const
|
|
13
|
-
const { renderHook, hookFn } = hookFound;
|
|
12
|
+
const { renderHook, hookFn } = getRenderHook(pageContext);
|
|
14
13
|
objectAssign(pageContext, { _renderHook: renderHook });
|
|
15
14
|
preparePageContextForUserConsumptionServerSide(pageContext);
|
|
16
15
|
const hookReturnValue = await executeHook(() => hookFn(pageContext), renderHook.hookName, renderHook.hookFilePath);
|
|
@@ -7,7 +7,7 @@ import pc from '@brillout/picocolors';
|
|
|
7
7
|
const streamDocs = 'See https://vike.dev/stream for more information.';
|
|
8
8
|
function getHttpResponseBody(htmlRender, renderHook) {
|
|
9
9
|
if (typeof htmlRender !== 'string') {
|
|
10
|
-
assertUsage(false, getErrMsg(htmlRender, renderHook, 'body', `Use ${pc.cyan('pageContext.httpResponse.pipe()')}
|
|
10
|
+
assertUsage(false, getErrMsg(htmlRender, renderHook, 'body', `Use ${pc.cyan('pageContext.httpResponse.pipe()')} instead`));
|
|
11
11
|
}
|
|
12
12
|
const body = htmlRender;
|
|
13
13
|
return body;
|
|
@@ -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') ||
|
|
@@ -312,11 +321,11 @@ function skipRequest(urlOriginal) {
|
|
|
312
321
|
isViteClientRequest);
|
|
313
322
|
}
|
|
314
323
|
function normalizeUrl(pageContextInit, httpRequestId) {
|
|
315
|
-
const { trailingSlash, disableUrlNormalization } = getGlobalContext();
|
|
324
|
+
const { trailingSlash, disableUrlNormalization, baseServer } = getGlobalContext();
|
|
316
325
|
if (disableUrlNormalization)
|
|
317
326
|
return null;
|
|
318
327
|
const { urlOriginal } = pageContextInit;
|
|
319
|
-
const urlNormalized = normalizeUrlPathname(urlOriginal, trailingSlash);
|
|
328
|
+
const urlNormalized = normalizeUrlPathname(urlOriginal, trailingSlash, baseServer);
|
|
320
329
|
if (!urlNormalized)
|
|
321
330
|
return null;
|
|
322
331
|
logRuntimeInfo?.(`URL normalized from ${pc.cyan(urlOriginal)} to ${pc.cyan(urlNormalized)} (https://vike.dev/url-normalization)`, httpRequestId, 'info');
|
|
@@ -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
|
+
}
|