vike 0.4.144-commit-f7ab002 → 0.4.144-commit-7f5e99a
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/__internal/index.js +6 -2
- package/dist/cjs/node/plugin/plugins/commonConfig.js +0 -3
- package/dist/cjs/node/plugin/plugins/devConfig/index.js +1 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +1 -0
- package/dist/cjs/node/plugin/plugins/previewConfig.js +5 -0
- package/dist/cjs/node/prerender/runPrerender.js +8 -9
- package/dist/cjs/node/prerender/utils.js +1 -1
- package/dist/cjs/node/runtime/html/serializePageContextClientSide.js +1 -0
- package/dist/cjs/node/runtime/renderPage.js +2 -2
- package/dist/cjs/node/runtime/utils.js +1 -1
- package/dist/cjs/shared/addUrlComputedProps.js +24 -12
- package/dist/cjs/shared/route/executeOnBeforeRouteHook.js +11 -13
- package/dist/cjs/shared/route/index.js +3 -3
- package/dist/cjs/shared/route/resolveRouteFunction.js +1 -1
- package/dist/cjs/shared/utils.js +1 -1
- package/dist/cjs/utils/{hasPropertyGetter.js → isPropertyGetter.js} +3 -3
- package/dist/cjs/utils/projectInfo.js +1 -1
- package/dist/esm/__internal/index.d.ts +6 -3
- package/dist/esm/__internal/index.js +8 -3
- package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +2 -3
- package/dist/esm/client/client-routing-runtime/createPageContext.js +3 -3
- package/dist/esm/client/client-routing-runtime/entry.js +2 -2
- package/dist/esm/client/client-routing-runtime/getPageContext.d.ts +0 -1
- package/dist/esm/client/client-routing-runtime/getPageContext.js +3 -6
- package/dist/esm/client/client-routing-runtime/getPageId.d.ts +1 -1
- package/dist/esm/client/client-routing-runtime/getPageId.js +4 -7
- package/dist/esm/client/client-routing-runtime/history.d.ts +3 -1
- package/dist/esm/client/client-routing-runtime/history.js +26 -8
- package/dist/esm/client/client-routing-runtime/installClientRouter.d.ts +21 -0
- package/dist/esm/client/client-routing-runtime/{useClientRouter.js → installClientRouter.js} +248 -242
- package/dist/esm/client/client-routing-runtime/isClientSideRoutable.d.ts +8 -0
- package/dist/esm/client/client-routing-runtime/isClientSideRoutable.js +15 -0
- package/dist/esm/client/client-routing-runtime/navigate.d.ts +0 -2
- package/dist/esm/client/client-routing-runtime/navigate.js +10 -8
- package/dist/esm/client/client-routing-runtime/prefetch.js +12 -5
- package/dist/esm/client/client-routing-runtime/skipLink.d.ts +0 -1
- package/dist/esm/client/client-routing-runtime/skipLink.js +1 -2
- package/dist/esm/client/shared/executeOnRenderClientHook.js +6 -5
- package/dist/esm/client/shared/getPageContextProxyForUser.js +13 -7
- package/dist/esm/node/plugin/plugins/commonConfig.js +0 -3
- package/dist/esm/node/plugin/plugins/devConfig/index.js +1 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +1 -0
- package/dist/esm/node/plugin/plugins/previewConfig.js +5 -0
- package/dist/esm/node/prerender/runPrerender.js +9 -10
- package/dist/esm/node/prerender/utils.d.ts +1 -1
- package/dist/esm/node/prerender/utils.js +1 -1
- package/dist/esm/node/runtime/html/serializePageContextClientSide.js +1 -0
- package/dist/esm/node/runtime/renderPage.js +2 -2
- package/dist/esm/node/runtime/utils.d.ts +1 -1
- package/dist/esm/node/runtime/utils.js +1 -1
- package/dist/esm/shared/addUrlComputedProps.d.ts +1 -0
- package/dist/esm/shared/addUrlComputedProps.js +25 -13
- package/dist/esm/shared/route/executeOnBeforeRouteHook.d.ts +1 -1
- package/dist/esm/shared/route/executeOnBeforeRouteHook.js +11 -13
- package/dist/esm/shared/route/index.d.ts +11 -9
- package/dist/esm/shared/route/index.js +3 -3
- package/dist/esm/shared/route/resolveRouteFunction.js +1 -1
- package/dist/esm/shared/utils.d.ts +1 -1
- package/dist/esm/shared/utils.js +1 -1
- package/dist/esm/utils/isPropertyGetter.d.ts +1 -0
- package/dist/esm/utils/{hasPropertyGetter.js → isPropertyGetter.js} +1 -1
- package/dist/esm/utils/projectInfo.d.ts +1 -1
- package/dist/esm/utils/projectInfo.js +1 -1
- package/package.json +1 -1
- package/dist/esm/client/client-routing-runtime/skipLink/isClientSideRoutable.d.ts +0 -2
- package/dist/esm/client/client-routing-runtime/skipLink/isClientSideRoutable.js +0 -15
- package/dist/esm/client/client-routing-runtime/useClientRouter.d.ts +0 -6
- package/dist/esm/utils/hasPropertyGetter.d.ts +0 -1
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
export { prefetch };
|
|
2
2
|
export { addLinkPrefetchHandlers };
|
|
3
|
-
import { assert, assertClientRouting, assertUsage, checkIfClientRouting } from './utils.js';
|
|
3
|
+
import { assert, assertClientRouting, assertUsage, checkIfClientRouting, objectAssign } from './utils.js';
|
|
4
4
|
import { isErrorFetchingStaticAssets, loadPageFilesClientSide } from '../shared/loadPageFilesClientSide.js';
|
|
5
|
-
import {
|
|
5
|
+
import { skipLink } from './skipLink.js';
|
|
6
6
|
import { getPageId } from './getPageId.js';
|
|
7
7
|
import { getPrefetchSettings } from './prefetch/getPrefetchSettings.js';
|
|
8
8
|
import { isAlreadyPrefetched, markAsAlreadyPrefetched } from './prefetch/alreadyPrefetched.js';
|
|
9
|
-
import { disableClientRouting } from './
|
|
9
|
+
import { disableClientRouting } from './installClientRouter.js';
|
|
10
10
|
import { isExternalLink } from './isExternalLink.js';
|
|
11
|
+
import { isClientSideRoutable } from './isClientSideRoutable.js';
|
|
12
|
+
import { createPageContext } from './createPageContext.js';
|
|
13
|
+
import { route } from '../../shared/route/index.js';
|
|
11
14
|
assertClientRouting();
|
|
12
15
|
const linkPrefetchHandlerAdded = new Map();
|
|
13
16
|
/**
|
|
@@ -79,13 +82,17 @@ function addLinkPrefetchHandlers(pageContext) {
|
|
|
79
82
|
});
|
|
80
83
|
}
|
|
81
84
|
async function prefetchIfClientSideRoutable(url) {
|
|
85
|
+
const pageContext = await createPageContext(url);
|
|
86
|
+
let pageContextFromRoute;
|
|
82
87
|
try {
|
|
83
|
-
|
|
84
|
-
return;
|
|
88
|
+
pageContextFromRoute = await route(pageContext);
|
|
85
89
|
}
|
|
86
90
|
catch {
|
|
87
91
|
// If a route() hook has a bug or `throw render()` / `throw redirect()`
|
|
88
92
|
return;
|
|
89
93
|
}
|
|
94
|
+
objectAssign(pageContext, pageContextFromRoute);
|
|
95
|
+
if (!(await isClientSideRoutable(pageContext)))
|
|
96
|
+
return;
|
|
90
97
|
await prefetch(url);
|
|
91
98
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export { skipLink };
|
|
2
|
-
export { isClientSideRoutable } from './skipLink/isClientSideRoutable.js';
|
|
3
2
|
import { getBaseServer } from './getBaseServer.js';
|
|
4
3
|
import { isExternalLink } from './isExternalLink.js';
|
|
5
4
|
import { assert, parseUrl, isBaseServer, isParsable } from './utils.js';
|
|
6
|
-
import { isDisableAutomaticLinkInterception } from './
|
|
5
|
+
import { isDisableAutomaticLinkInterception } from './installClientRouter.js';
|
|
7
6
|
function skipLink(linkTag) {
|
|
8
7
|
const url = linkTag.getAttribute('href');
|
|
9
8
|
if (url === null)
|
|
@@ -19,10 +19,11 @@ async function executeOnRenderClientHook(pageContext, isClientRouting) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
if (!hook) {
|
|
22
|
-
const
|
|
22
|
+
const urlToShowToUser = getUrlToShowToUser(pageContext);
|
|
23
|
+
assert(urlToShowToUser);
|
|
23
24
|
if (pageContext._pageConfigs.length > 0) {
|
|
24
25
|
// V1 design
|
|
25
|
-
assertUsage(false, `No onRenderClient() hook defined for URL '${
|
|
26
|
+
assertUsage(false, `No onRenderClient() hook defined for URL '${urlToShowToUser}', but it's needed, see https://vike.dev/onRenderClient`);
|
|
26
27
|
}
|
|
27
28
|
else {
|
|
28
29
|
// TODO/v1-release: remove
|
|
@@ -30,11 +31,11 @@ async function executeOnRenderClientHook(pageContext, isClientRouting) {
|
|
|
30
31
|
const pageClientsFilesLoaded = pageContext._pageFilesLoaded.filter((p) => p.fileType === '.page.client');
|
|
31
32
|
let errMsg;
|
|
32
33
|
if (pageClientsFilesLoaded.length === 0) {
|
|
33
|
-
errMsg = 'No file `*.page.client.*` found for URL ' +
|
|
34
|
+
errMsg = 'No file `*.page.client.*` found for URL ' + urlToShowToUser;
|
|
34
35
|
}
|
|
35
36
|
else {
|
|
36
37
|
errMsg =
|
|
37
|
-
'One of the following files should export a
|
|
38
|
+
'One of the following files should export a render() hook: ' +
|
|
38
39
|
pageClientsFilesLoaded.map((p) => p.filePath).join(' ');
|
|
39
40
|
}
|
|
40
41
|
assertUsage(false, errMsg);
|
|
@@ -47,7 +48,7 @@ async function executeOnRenderClientHook(pageContext, isClientRouting) {
|
|
|
47
48
|
const hookResult = await executeHook(() => renderHook(pageContextForUserConsumption), hookName, hook.hookFilePath);
|
|
48
49
|
assertUsage(hookResult === undefined, `The ${hookName}() hook defined by ${hook.hookFilePath} isn't allowed to return a value`);
|
|
49
50
|
}
|
|
50
|
-
function
|
|
51
|
+
function getUrlToShowToUser(pageContext) {
|
|
51
52
|
let url;
|
|
52
53
|
// try/catch to avoid passToClient assertUsage() (although: this may not be needed anymore, since we're now accessing pageContext and not pageContextForUserConsumption)
|
|
53
54
|
try {
|
|
@@ -14,14 +14,14 @@ function getPageContextProxyForUser(pageContext) {
|
|
|
14
14
|
const val = pageContext[prop];
|
|
15
15
|
const propName = JSON.stringify(prop);
|
|
16
16
|
assertUsage(val !== notSerializable, `pageContext[${propName}] couldn't be serialized and, therefore, is missing on the client-side. Check the server logs for more information.`);
|
|
17
|
-
|
|
17
|
+
assertIsDefined(pageContext, prop);
|
|
18
18
|
return val;
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
|
-
function
|
|
23
|
-
// We disable
|
|
24
|
-
// - Vue tries to read its old value first. This triggers a `
|
|
22
|
+
function assertIsDefined(pageContext, prop) {
|
|
23
|
+
// We disable assertIsDefined() for the next attempt to read `prop`, because of how Vue's reactivity work. When changing a reactive object:
|
|
24
|
+
// - Vue tries to read its old value first. This triggers a `assertIsDefined()` failure if e.g. `pageContextOldReactive.routeParams = pageContextNew.routeParams` and `pageContextOldReactive` has no `routeParams`.
|
|
25
25
|
// - Vue seems to read __v_raw before reading the property
|
|
26
26
|
if (globalObject.prev === prop || globalObject.prev === '__v_raw')
|
|
27
27
|
return;
|
|
@@ -30,17 +30,23 @@ function assertPassToClient(pageContext, prop, errMsg) {
|
|
|
30
30
|
return;
|
|
31
31
|
if (isExpected(prop))
|
|
32
32
|
return;
|
|
33
|
+
const propName = JSON.stringify(prop);
|
|
34
|
+
/* This handling would be the clearest but, unfortunately, it's fundamentally problematic:
|
|
35
|
+
* - It would force the pageContext value consumer to be synchronized with the pageContext value provider. For example, if vike-react wants to conditionally do something dependening on wehther some optional pageContext value was provided by some optional vike-react-* integration package.
|
|
36
|
+
* - If a pageContext value is set by an optional hook, then it's expected that the value is undefined if the hook doesn't exist.
|
|
37
|
+
const errMsg = `pageContext[${propName}] is \`undefined\` on the client-side. If it's defined on the server-side then add ${propName} to passToClient (https://vike.dev/passToClient), otherwise make sure your client-side hooks always define it (e.g. set it to \`null\` instead of \`undefined\`).`
|
|
38
|
+
assertUsage(false, errMsg)
|
|
39
|
+
*/
|
|
33
40
|
if (pageContext._hasPageContextFromServer && !pageContext._hasPageContextFromClient) {
|
|
34
41
|
// We can safely assume that the property is missing in passToClient, because the server-side defines all passToClient properties even if they have an undefined value:
|
|
35
42
|
// ```
|
|
36
43
|
// <script id="vike_pageContext" type="application/json">{"_pageId":"/pages/admin","user":"!undefined","pageProps":"!undefined","title":"!undefined","abortReason":"!undefined","_urlRewrite":null}</script>
|
|
37
44
|
// ```
|
|
38
45
|
// Note how properties have "!undefined" values => we can tell whether an undefined pageContext value exists in passToClient.
|
|
39
|
-
assertUsage(false,
|
|
46
|
+
assertUsage(false, `pageContext[${propName}] isn't available on the client-side because ${propName} is missing in passToClient, see https://vike.dev/passToClient`);
|
|
40
47
|
}
|
|
41
48
|
else {
|
|
42
|
-
// Do nothing, not even a warning.
|
|
43
|
-
// Because we don't know whether the user expects the pageContext value to be undefined. (E.g. a client-side onBeforeRender() hook conditionally setting a pageContext value.)
|
|
49
|
+
// Do nothing, not even a warning, because we don't know whether the user expects that the pageContext value can be undefined. (E.g. a pageContext value that is defined by an optional hook.)
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
const IGNORE_LIST = [
|
|
@@ -113,6 +113,7 @@ function getConfigValueSerialized(value, configName, definedAt) {
|
|
|
113
113
|
serializationErrMsg = err.messageCore;
|
|
114
114
|
}
|
|
115
115
|
else {
|
|
116
|
+
// When a property getter throws an error
|
|
116
117
|
console.error('Serialization error:');
|
|
117
118
|
console.error(err);
|
|
118
119
|
serializationErrMsg = 'see serialization error printed above';
|
|
@@ -13,6 +13,7 @@ function previewConfig() {
|
|
|
13
13
|
apply: 'serve',
|
|
14
14
|
config(config) {
|
|
15
15
|
return {
|
|
16
|
+
appType: 'custom',
|
|
16
17
|
build: {
|
|
17
18
|
outDir: resolveOutDir(config)
|
|
18
19
|
}
|
|
@@ -23,6 +24,10 @@ function previewConfig() {
|
|
|
23
24
|
configVike = await getConfigVike(config);
|
|
24
25
|
},
|
|
25
26
|
configurePreviewServer(server) {
|
|
27
|
+
/* - Couldn't make `appType: 'mpa'` work as of npm:@brillout/vite@5.0.0-beta.14.0426910c
|
|
28
|
+
- This ugly hack to set appType for preview won't be need once https://github.com/vitejs/vite/pull/14855 is merged.
|
|
29
|
+
config.appType = 'mpa'
|
|
30
|
+
*/
|
|
26
31
|
markEnvAsPreview();
|
|
27
32
|
return () => {
|
|
28
33
|
assertDist();
|
|
@@ -5,7 +5,7 @@ export { prerenderForceExit };
|
|
|
5
5
|
import '../runtime/page-files/setup.js';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import { route } from '../../shared/route/index.js';
|
|
8
|
-
import { assert, assertUsage, assertWarning, hasProp, projectInfo, objectAssign, isObjectWithKeys, isCallable, getOutDirs,
|
|
8
|
+
import { assert, assertUsage, assertWarning, hasProp, projectInfo, objectAssign, isObjectWithKeys, isCallable, getOutDirs, isPropertyGetter, assertPosixPath, urlToFile, executeHook, isPlainObject, setNodeEnvToProduction } from './utils.js';
|
|
9
9
|
import { pLimit } from '../../utils/pLimit.js';
|
|
10
10
|
import { prerenderPage, prerender404Page, getRenderContext, getPageContextInitEnhanced } from '../runtime/renderPage/renderPageAlreadyRouted.js';
|
|
11
11
|
import pc from '@brillout/picocolors';
|
|
@@ -343,7 +343,7 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
343
343
|
enumerable: false,
|
|
344
344
|
configurable: true
|
|
345
345
|
});
|
|
346
|
-
assert(
|
|
346
|
+
assert(isPropertyGetter(pageContext, 'url'));
|
|
347
347
|
assert(pageContext.urlOriginal);
|
|
348
348
|
pageContext._urlOriginalBeforeHook = pageContext.urlOriginal;
|
|
349
349
|
});
|
|
@@ -382,7 +382,7 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
382
382
|
prerenderContext.pageContexts = result.prerenderContext.pageContexts;
|
|
383
383
|
prerenderContext.pageContexts.forEach((pageContext) => {
|
|
384
384
|
// TODO/v1-release: remove
|
|
385
|
-
if (!
|
|
385
|
+
if (pageContext.url && !isPropertyGetter(pageContext, 'url')) {
|
|
386
386
|
assertWarning(false, msgPrefix +
|
|
387
387
|
' provided pageContext.url but it should provide pageContext.urlOriginal instead, see https://vike.dev/migration/0.4.23', { onlyOnce: true });
|
|
388
388
|
pageContext.urlOriginal = pageContext.url;
|
|
@@ -407,10 +407,9 @@ async function routeAndPrerender(prerenderContext, htmlFiles, prerenderPageIds,
|
|
|
407
407
|
await Promise.all(prerenderContext.pageContexts.map((pageContext) => concurrencyLimit(async () => {
|
|
408
408
|
const { urlOriginal } = pageContext;
|
|
409
409
|
assert(urlOriginal);
|
|
410
|
-
const
|
|
411
|
-
assert(hasProp(
|
|
412
|
-
|
|
413
|
-
if (routeResult.pageContextAddendum._pageId === null) {
|
|
410
|
+
const pageContextFromRoute = await route(pageContext);
|
|
411
|
+
assert(hasProp(pageContextFromRoute, '_pageId', 'null') || hasProp(pageContextFromRoute, '_pageId', 'string'));
|
|
412
|
+
if (pageContextFromRoute._pageId === null) {
|
|
414
413
|
let hookName;
|
|
415
414
|
let hookFilePath;
|
|
416
415
|
if (pageContext._providedByHook) {
|
|
@@ -427,13 +426,13 @@ async function routeAndPrerender(prerenderContext, htmlFiles, prerenderPageIds,
|
|
|
427
426
|
}
|
|
428
427
|
else {
|
|
429
428
|
// `prerenderHookFile` is `null` when the URL was deduced by the Filesytem Routing of `.page.js` files. The `onBeforeRoute()` can override Filesystem Routing; it is therefore expected that the deduced URL may not match any page.
|
|
430
|
-
assert(
|
|
429
|
+
assert(pageContextFromRoute._routingProvidedByOnBeforeRouteHook);
|
|
431
430
|
// Abort since the URL doesn't correspond to any page
|
|
432
431
|
return;
|
|
433
432
|
}
|
|
434
433
|
}
|
|
435
|
-
assert(
|
|
436
|
-
objectAssign(pageContext,
|
|
434
|
+
assert(pageContextFromRoute._pageId);
|
|
435
|
+
objectAssign(pageContext, pageContextFromRoute);
|
|
437
436
|
const { _pageId: pageId } = pageContext;
|
|
438
437
|
objectAssign(pageContext, await loadPageFilesServerSide(pageContext));
|
|
439
438
|
let usesClientRouter;
|
|
@@ -5,7 +5,7 @@ export * from '../../utils/objectAssign.js';
|
|
|
5
5
|
export * from '../../utils/isObjectWithKeys.js';
|
|
6
6
|
export * from '../../utils/isCallable.js';
|
|
7
7
|
export * from '../../utils/getOutDirs.js';
|
|
8
|
-
export * from '../../utils/
|
|
8
|
+
export * from '../../utils/isPropertyGetter.js';
|
|
9
9
|
export * from '../../utils/filesystemPathHandling.js';
|
|
10
10
|
export * from '../../utils/urlToFile.js';
|
|
11
11
|
export * from '../../shared/hooks/executeHook.js';
|
|
@@ -7,7 +7,7 @@ export * from '../../utils/objectAssign.js';
|
|
|
7
7
|
export * from '../../utils/isObjectWithKeys.js';
|
|
8
8
|
export * from '../../utils/isCallable.js';
|
|
9
9
|
export * from '../../utils/getOutDirs.js';
|
|
10
|
-
export * from '../../utils/
|
|
10
|
+
export * from '../../utils/isPropertyGetter.js';
|
|
11
11
|
export * from '../../utils/filesystemPathHandling.js';
|
|
12
12
|
export * from '../../utils/urlToFile.js';
|
|
13
13
|
export * from '../../shared/hooks/executeHook.js';
|
|
@@ -54,6 +54,7 @@ function serializePageContextClientSide(pageContext) {
|
|
|
54
54
|
msg = `${msg} Serialization error: ${err.messageCore}.`;
|
|
55
55
|
}
|
|
56
56
|
else {
|
|
57
|
+
// When a property getter throws an error
|
|
57
58
|
console.warn('Serialization error:');
|
|
58
59
|
console.warn(err);
|
|
59
60
|
msg = `${msg} The serialization failed because of the error printed above.`;
|
|
@@ -240,8 +240,8 @@ async function renderPageNominal(pageContext) {
|
|
|
240
240
|
}
|
|
241
241
|
// Route
|
|
242
242
|
{
|
|
243
|
-
const
|
|
244
|
-
objectAssign(pageContext,
|
|
243
|
+
const pageContextFromRoute = await route(pageContext);
|
|
244
|
+
objectAssign(pageContext, pageContextFromRoute);
|
|
245
245
|
objectAssign(pageContext, { is404: pageContext._pageId ? null : true });
|
|
246
246
|
if (pageContext._pageId === null) {
|
|
247
247
|
const errorPageId = getErrorPageId(pageContext._pageFilesAll, pageContext._pageConfigs);
|
|
@@ -25,7 +25,7 @@ export * from '../../utils/capitalizeFirstLetter.js';
|
|
|
25
25
|
export * from '../../utils/debugGlob.js';
|
|
26
26
|
export * from '../../utils/isEquivalentError.js';
|
|
27
27
|
export * from '../../utils/styleFileRE.js';
|
|
28
|
-
export * from '../../utils/
|
|
28
|
+
export * from '../../utils/isPropertyGetter.js';
|
|
29
29
|
export * from '../../utils/debug.js';
|
|
30
30
|
export * from '../../utils/urlToFile.js';
|
|
31
31
|
export * from '../../utils/getGlobalObject.js';
|
|
@@ -28,7 +28,7 @@ export * from '../../utils/capitalizeFirstLetter.js';
|
|
|
28
28
|
export * from '../../utils/debugGlob.js';
|
|
29
29
|
export * from '../../utils/isEquivalentError.js';
|
|
30
30
|
export * from '../../utils/styleFileRE.js';
|
|
31
|
-
export * from '../../utils/
|
|
31
|
+
export * from '../../utils/isPropertyGetter.js';
|
|
32
32
|
export * from '../../utils/debug.js';
|
|
33
33
|
export * from '../../utils/urlToFile.js';
|
|
34
34
|
export * from '../../utils/getGlobalObject.js';
|
|
@@ -55,6 +55,7 @@ type PageContextUrlComputedPropsServer = PageContextUrlComputedPropsClient & {
|
|
|
55
55
|
declare function addUrlComputedProps<PageContext extends Record<string, unknown> & PageContextUrlSources>(pageContext: PageContext, enumerable?: boolean): asserts pageContext is PageContext & PageContextUrlComputedPropsInternal;
|
|
56
56
|
type PageContextUrlSources = {
|
|
57
57
|
urlOriginal: string;
|
|
58
|
+
urlLogical?: string;
|
|
58
59
|
_urlRewrite: string | null;
|
|
59
60
|
_baseServer: string;
|
|
60
61
|
_urlHandler: null | ((url: string) => string);
|
|
@@ -1,28 +1,40 @@
|
|
|
1
1
|
// URLs props need to be computed props, because the user can modify the URL e.g. with onBeforeRoute() for i18n
|
|
2
2
|
export { addUrlComputedProps };
|
|
3
3
|
export { assertPageContextUrlComputedProps };
|
|
4
|
-
import { assert, parseUrl, assertWarning, isPlainObject,
|
|
4
|
+
import { assert, parseUrl, assertWarning, isPlainObject, isPropertyGetter, isBrowser } from './utils.js';
|
|
5
5
|
function addUrlComputedProps(pageContext, enumerable = true) {
|
|
6
6
|
assert(pageContext.urlOriginal);
|
|
7
7
|
if ('urlPathname' in pageContext) {
|
|
8
|
-
assert(
|
|
8
|
+
assert(typeof pageContext.urlPathname === 'string');
|
|
9
|
+
/* If this assert() fails then it's most likely because Object.assign() was used instead of objectAssign(), i.e.:
|
|
10
|
+
```js
|
|
11
|
+
// Add property getters such as pageContext.urlPathname to pageContext
|
|
12
|
+
addUrlComputedProps(pageContext)
|
|
13
|
+
// ❌ Breaks the property getters of pageContext set by addUrlComputedProps() such as pageContext.urlPathname
|
|
14
|
+
Object.assign(pageContext2, pageContext)
|
|
15
|
+
// ❌ Also breaks the property getters
|
|
16
|
+
const pageContext3 = { ...pageContext }
|
|
17
|
+
// ✅ Preserves property getters of pageContext (see objectAssign() implementation)
|
|
18
|
+
objectAssign(pageContext2, pageContext)
|
|
19
|
+
```
|
|
20
|
+
*/
|
|
21
|
+
assert(isPropertyGetter(pageContext, 'urlPathname'));
|
|
9
22
|
}
|
|
23
|
+
if ('urlParsed' in pageContext)
|
|
24
|
+
assert(isPropertyGetter(pageContext, 'urlParsed'));
|
|
25
|
+
// TODO/v1-release: move pageContext.urlParsed to pageContext.url
|
|
26
|
+
if ('url' in pageContext)
|
|
27
|
+
assert(isPropertyGetter(pageContext, 'url'));
|
|
10
28
|
Object.defineProperty(pageContext, 'urlPathname', {
|
|
11
29
|
get: urlPathnameGetter,
|
|
12
30
|
enumerable,
|
|
13
31
|
configurable: true
|
|
14
32
|
});
|
|
15
|
-
// TODO/v1-release: move pageContext.urlParsed to pageContext.url
|
|
16
|
-
if ('url' in pageContext)
|
|
17
|
-
assert(hasPropertyGetter(pageContext, 'url'));
|
|
18
33
|
Object.defineProperty(pageContext, 'url', {
|
|
19
34
|
get: urlGetter,
|
|
20
35
|
enumerable: false,
|
|
21
36
|
configurable: true
|
|
22
37
|
});
|
|
23
|
-
if ('urlParsed' in pageContext) {
|
|
24
|
-
assert(hasPropertyGetter(pageContext, 'urlParsed'));
|
|
25
|
-
}
|
|
26
38
|
Object.defineProperty(pageContext, 'urlParsed', {
|
|
27
39
|
get: urlParsedGetter,
|
|
28
40
|
enumerable,
|
|
@@ -30,17 +42,17 @@ function addUrlComputedProps(pageContext, enumerable = true) {
|
|
|
30
42
|
});
|
|
31
43
|
}
|
|
32
44
|
function getUrlParsed(pageContext) {
|
|
33
|
-
// We
|
|
45
|
+
// We need a url handler function because the onBeforeRoute() hook may set pageContext.urlLogical (typically for i18n)
|
|
34
46
|
let urlHandler = pageContext._urlHandler;
|
|
35
47
|
if (!urlHandler) {
|
|
36
48
|
urlHandler = (url) => url;
|
|
37
49
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const urlLogical = urlHandler(url);
|
|
50
|
+
let urlResolved = pageContext._urlRewrite ?? pageContext.urlLogical ?? pageContext.urlOriginal;
|
|
51
|
+
urlResolved = urlHandler(urlResolved);
|
|
41
52
|
const baseServer = pageContext._baseServer;
|
|
53
|
+
assert(urlResolved && typeof urlResolved === 'string');
|
|
42
54
|
assert(baseServer.startsWith('/'));
|
|
43
|
-
return parseUrl(
|
|
55
|
+
return parseUrl(urlResolved, baseServer);
|
|
44
56
|
}
|
|
45
57
|
function urlPathnameGetter() {
|
|
46
58
|
const { pathname } = getUrlParsed(this);
|
|
@@ -11,7 +11,7 @@ declare function executeOnBeforeRouteHook(onBeforeRouteHook: OnBeforeRouteHook,
|
|
|
11
11
|
_allPageIds: string[];
|
|
12
12
|
}): Promise<null | {
|
|
13
13
|
urlOriginal?: string;
|
|
14
|
-
|
|
14
|
+
urlLogical?: string;
|
|
15
15
|
_pageId?: string | null;
|
|
16
16
|
routeParams?: Record<string, string>;
|
|
17
17
|
}>;
|
|
@@ -6,6 +6,7 @@ export { executeOnBeforeRouteHook };
|
|
|
6
6
|
async function executeOnBeforeRouteHook(onBeforeRouteHook, pageContext) {
|
|
7
7
|
let hookReturn = onBeforeRouteHook.onBeforeRoute(pageContext);
|
|
8
8
|
assertSyncRouting(hookReturn, `The onBeforeRoute() hook ${onBeforeRouteHook.hookFilePath}`);
|
|
9
|
+
// TODO/v1-release: make executeOnBeforeRouteHook() and route() sync
|
|
9
10
|
hookReturn = await hookReturn;
|
|
10
11
|
const errPrefix = `The onBeforeRoute() hook defined by ${onBeforeRouteHook.hookFilePath}`;
|
|
11
12
|
assertUsage(hookReturn === null ||
|
|
@@ -23,28 +24,25 @@ async function executeOnBeforeRouteHook(onBeforeRouteHook, pageContext) {
|
|
|
23
24
|
if (hasProp(hookReturn.pageContext, 'routeParams')) {
|
|
24
25
|
assertRouteParams(hookReturn.pageContext, `${errPrefix} returned ${pc.cyan('{ pageContext: { routeParams } }')} but routeParams should`);
|
|
25
26
|
}
|
|
26
|
-
const
|
|
27
|
+
const deprecatedReturn = (prop) => `${errPrefix} returned ${pc.cyan(`{ pageContext: { ${prop} } }`)} which is deprecated. Return ${pc.cyan('{ pageContext: { urlLogical } }')} instead.`;
|
|
27
28
|
if (hasProp(hookReturn.pageContext, 'url')) {
|
|
28
|
-
assertWarning(false,
|
|
29
|
-
hookReturn.pageContext.
|
|
29
|
+
assertWarning(false, deprecatedReturn('url'), { onlyOnce: true });
|
|
30
|
+
hookReturn.pageContext.urlLogical = hookReturn.pageContext.url;
|
|
30
31
|
delete hookReturn.pageContext.url;
|
|
31
32
|
}
|
|
32
33
|
if (hasProp(hookReturn.pageContext, 'urlOriginal')) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// pageContext.urlReal / pageContext.urlModified
|
|
40
|
-
// VS
|
|
41
|
-
// pageContext.urlOriginal / pageContext.urlModified
|
|
42
|
-
objectAssign(pageContextAddendumHook, { _urlOriginalPristine: pageContext.urlOriginal });
|
|
34
|
+
assertWarning(false, deprecatedReturn('urlOriginal'), { onlyOnce: true });
|
|
35
|
+
hookReturn.pageContext.urlLogical = hookReturn.pageContext.urlOriginal;
|
|
36
|
+
delete hookReturn.pageContext.urlOriginal;
|
|
37
|
+
}
|
|
38
|
+
if (hasProp(hookReturn.pageContext, 'urlLogical')) {
|
|
39
|
+
assertUsageUrl(hookReturn.pageContext.urlLogical, `${errPrefix} returned ${pc.cyan('{ pageContext: { urlLogical } }')} but ${pc.cyan('urlLogical')}`);
|
|
43
40
|
}
|
|
44
41
|
assertPageContextProvidedByUser(hookReturn.pageContext, {
|
|
45
42
|
hookFilePath: onBeforeRouteHook.hookFilePath,
|
|
46
43
|
hookName: 'onBeforeRoute'
|
|
47
44
|
});
|
|
45
|
+
const pageContextAddendumHook = {};
|
|
48
46
|
objectAssign(pageContextAddendumHook, hookReturn.pageContext);
|
|
49
47
|
return pageContextAddendumHook;
|
|
50
48
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export { route };
|
|
2
|
-
export type {
|
|
2
|
+
export type { PageContextForRoute };
|
|
3
|
+
export type { PageContextFromRoute };
|
|
4
|
+
export type { PageRoutes };
|
|
5
|
+
export type { RouteMatches };
|
|
3
6
|
import type { PageFile } from '../getPageFiles.js';
|
|
4
7
|
import { PageContextUrlComputedPropsInternal, PageContextUrlSources } from '../addUrlComputedProps.js';
|
|
5
8
|
import { type OnBeforeRouteHook } from './executeOnBeforeRouteHook.js';
|
|
@@ -13,6 +16,12 @@ type PageContextForRoute = PageContextUrlComputedPropsInternal & {
|
|
|
13
16
|
_pageRoutes: PageRoutes;
|
|
14
17
|
_onBeforeRouteHook: OnBeforeRouteHook | null;
|
|
15
18
|
} & PageContextUrlSources;
|
|
19
|
+
type PageContextFromRoute = {
|
|
20
|
+
_pageId: string | null;
|
|
21
|
+
routeParams: Record<string, string>;
|
|
22
|
+
_routingProvidedByOnBeforeRouteHook: boolean;
|
|
23
|
+
_routeMatches: RouteMatches;
|
|
24
|
+
};
|
|
16
25
|
type RouteMatch = {
|
|
17
26
|
pageId: string;
|
|
18
27
|
routeString?: string;
|
|
@@ -21,11 +30,4 @@ type RouteMatch = {
|
|
|
21
30
|
routeParams: Record<string, string>;
|
|
22
31
|
};
|
|
23
32
|
type RouteMatches = 'CUSTOM_ROUTE' | RouteMatch[];
|
|
24
|
-
declare function route(pageContext: PageContextForRoute): Promise<
|
|
25
|
-
pageContextAddendum: {
|
|
26
|
-
_pageId: string | null;
|
|
27
|
-
routeParams: Record<string, string>;
|
|
28
|
-
_routingProvidedByOnBeforeRouteHook: boolean;
|
|
29
|
-
_routeMatches: RouteMatches;
|
|
30
|
-
} & Record<string, unknown>;
|
|
31
|
-
}>;
|
|
33
|
+
declare function route(pageContext: PageContextForRoute): Promise<PageContextFromRoute>;
|
|
@@ -33,7 +33,7 @@ async function route(pageContext) {
|
|
|
33
33
|
_routingProvidedByOnBeforeRouteHook: true,
|
|
34
34
|
_routeMatches: 'CUSTOM_ROUTE'
|
|
35
35
|
});
|
|
36
|
-
return
|
|
36
|
+
return pageContextAddendum;
|
|
37
37
|
}
|
|
38
38
|
// We already assign so that `pageContext.urlOriginal === pageContextAddendum.urlOriginal`; enabling the `onBeforeRoute()` hook to mutate `pageContext.urlOriginal` before routing.
|
|
39
39
|
objectAssign(pageContext, pageContextAddendum);
|
|
@@ -99,7 +99,7 @@ async function route(pageContext) {
|
|
|
99
99
|
_pageId: null,
|
|
100
100
|
routeParams: {}
|
|
101
101
|
});
|
|
102
|
-
return
|
|
102
|
+
return pageContextAddendum;
|
|
103
103
|
}
|
|
104
104
|
{
|
|
105
105
|
const { routeParams } = winner;
|
|
@@ -109,5 +109,5 @@ async function route(pageContext) {
|
|
|
109
109
|
routeParams: winner.routeParams
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
|
-
return
|
|
112
|
+
return pageContextAddendum;
|
|
113
113
|
}
|
|
@@ -9,7 +9,7 @@ async function resolveRouteFunction(routeFunction, pageContext, routeDefinedAt)
|
|
|
9
9
|
assertPageContextUrlComputedProps(pageContext);
|
|
10
10
|
let result = routeFunction(pageContext);
|
|
11
11
|
assertSyncRouting(result, `The Route Function ${routeDefinedAt}`);
|
|
12
|
-
// TODO/v1-release
|
|
12
|
+
// TODO/v1-release: make resolveRouteFunction() and route() sync
|
|
13
13
|
//* We disallow asynchronous routing, because we need to check whether a link is a Vike link in a synchronous fashion before calling ev.preventDefault() in the 'click' event listener
|
|
14
14
|
result = await result;
|
|
15
15
|
//*/
|
|
@@ -15,7 +15,7 @@ export * from '../utils/stringifyStringArray.js';
|
|
|
15
15
|
export * from '../utils/filesystemPathHandling.js';
|
|
16
16
|
export * from '../utils/cast.js';
|
|
17
17
|
export * from '../utils/projectInfo.js';
|
|
18
|
-
export * from '../utils/
|
|
18
|
+
export * from '../utils/isPropertyGetter.js';
|
|
19
19
|
export * from '../utils/isPromise.js';
|
|
20
20
|
export * from '../utils/checkType.js';
|
|
21
21
|
export * from '../utils/objectEntries.js';
|
package/dist/esm/shared/utils.js
CHANGED
|
@@ -19,7 +19,7 @@ export * from '../utils/stringifyStringArray.js';
|
|
|
19
19
|
export * from '../utils/filesystemPathHandling.js';
|
|
20
20
|
export * from '../utils/cast.js';
|
|
21
21
|
export * from '../utils/projectInfo.js';
|
|
22
|
-
export * from '../utils/
|
|
22
|
+
export * from '../utils/isPropertyGetter.js';
|
|
23
23
|
export * from '../utils/isPromise.js';
|
|
24
24
|
export * from '../utils/checkType.js';
|
|
25
25
|
export * from '../utils/objectEntries.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function isPropertyGetter(obj: Object, prop: string): boolean;
|
|
@@ -5,7 +5,7 @@ type ProjectVersion = typeof projectInfo.projectVersion;
|
|
|
5
5
|
type ProjectTag = `[${PackageName}]` | `[${PackageName}@${ProjectVersion}]`;
|
|
6
6
|
declare const projectInfo: {
|
|
7
7
|
projectName: "Vike";
|
|
8
|
-
projectVersion: "0.4.144-commit-
|
|
8
|
+
projectVersion: "0.4.144-commit-7f5e99a";
|
|
9
9
|
npmPackageName: "vike";
|
|
10
10
|
githubRepository: "https://github.com/vikejs/vike";
|
|
11
11
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { projectInfo };
|
|
2
2
|
import { onProjectInfo } from './assertSingleInstance.js';
|
|
3
|
-
const PROJECT_VERSION = '0.4.144-commit-
|
|
3
|
+
const PROJECT_VERSION = '0.4.144-commit-7f5e99a';
|
|
4
4
|
const projectInfo = {
|
|
5
5
|
projectName: 'Vike',
|
|
6
6
|
projectVersion: PROJECT_VERSION,
|
package/package.json
CHANGED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export { isClientSideRoutable };
|
|
2
|
-
import { getPageId } from '../getPageId.js';
|
|
3
|
-
import { analyzePageClientSideInit } from '../../../shared/getPageFiles/analyzePageClientSide.js';
|
|
4
|
-
import { findPageConfig } from '../../../shared/page-configs/findPageConfig.js';
|
|
5
|
-
import { analyzeClientSide } from '../../../shared/getPageFiles/analyzeClientSide.js';
|
|
6
|
-
async function isClientSideRoutable(url) {
|
|
7
|
-
const { pageId, pageFilesAll, pageConfigs } = await getPageId(url);
|
|
8
|
-
if (!pageId) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
await analyzePageClientSideInit(pageFilesAll, pageId, { sharedPageFilesAlreadyLoaded: false });
|
|
12
|
-
const pageConfig = findPageConfig(pageConfigs, pageId);
|
|
13
|
-
const { isClientSideRenderable, isClientRouting } = analyzeClientSide(pageConfig, pageFilesAll, pageId);
|
|
14
|
-
return isClientSideRenderable && isClientRouting;
|
|
15
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { useClientRouter };
|
|
2
|
-
export { disableClientRouting };
|
|
3
|
-
export { isDisableAutomaticLinkInterception };
|
|
4
|
-
declare function disableClientRouting(err: unknown, log: boolean): void;
|
|
5
|
-
declare function useClientRouter(): void;
|
|
6
|
-
declare function isDisableAutomaticLinkInterception(): boolean;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function hasPropertyGetter(obj: Object, prop: string): boolean;
|