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.
Files changed (74) hide show
  1. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +17 -12
  2. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +3 -0
  3. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +116 -0
  4. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +33 -45
  5. package/dist/cjs/node/prerender/runPrerender.js +85 -84
  6. package/dist/cjs/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
  7. package/dist/cjs/node/runtime/html/renderHtml.js +1 -1
  8. package/dist/cjs/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +12 -12
  9. package/dist/cjs/node/runtime/renderPage/createHttpResponseObject.js +3 -3
  10. package/dist/cjs/node/runtime/renderPage/executeOnBeforeRenderHook.js +1 -1
  11. package/dist/cjs/node/runtime/renderPage/executeOnRenderHtmlHook.js +3 -3
  12. package/dist/cjs/node/runtime/renderPage/getHttpResponseBody.js +1 -1
  13. package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +21 -18
  14. package/dist/cjs/node/runtime/renderPage.js +73 -49
  15. package/dist/cjs/shared/getPageFiles/parseGlobResults.js +3 -3
  16. package/dist/cjs/shared/hooks/executeHook.js +18 -29
  17. package/dist/cjs/shared/hooks/getHook.js +104 -3
  18. package/dist/cjs/shared/page-configs/helpers/getConfigDefinedAtString.js +1 -1
  19. package/dist/cjs/shared/route/executeGuardHook.js +3 -2
  20. package/dist/cjs/shared/route/executeOnBeforeRouteHook.js +4 -4
  21. package/dist/cjs/shared/route/loadPageRoutes.js +10 -15
  22. package/dist/cjs/shared/route/resolveRedirects.js +8 -5
  23. package/dist/cjs/utils/parseUrl-extras.js +6 -1
  24. package/dist/cjs/utils/parseUrl.js +24 -16
  25. package/dist/cjs/utils/projectInfo.js +1 -1
  26. package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +1 -1
  27. package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +20 -10
  28. package/dist/esm/client/client-routing-runtime/onBrowserHistoryNavigation.js +2 -2
  29. package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +18 -12
  30. package/dist/esm/client/shared/executeOnRenderClientHook.js +1 -1
  31. package/dist/esm/client/shared/getPageContextSerializedInHtml.js +1 -1
  32. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +17 -12
  33. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +3 -0
  34. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.d.ts +5 -0
  35. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +110 -0
  36. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +34 -46
  37. package/dist/esm/node/prerender/runPrerender.js +87 -86
  38. package/dist/esm/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
  39. package/dist/esm/node/runtime/html/renderHtml.js +1 -1
  40. package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.d.ts +1 -1
  41. package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +13 -13
  42. package/dist/esm/node/runtime/renderPage/createHttpResponseObject.d.ts +1 -1
  43. package/dist/esm/node/runtime/renderPage/createHttpResponseObject.js +3 -3
  44. package/dist/esm/node/runtime/renderPage/executeOnBeforeRenderHook.js +1 -1
  45. package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.d.ts +2 -2
  46. package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.js +3 -3
  47. package/dist/esm/node/runtime/renderPage/getHttpResponseBody.js +1 -1
  48. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +7 -7
  49. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +22 -19
  50. package/dist/esm/node/runtime/renderPage.js +74 -50
  51. package/dist/esm/shared/getPageFiles/parseGlobResults.js +1 -1
  52. package/dist/esm/shared/hooks/executeHook.d.ts +2 -2
  53. package/dist/esm/shared/hooks/executeHook.js +18 -29
  54. package/dist/esm/shared/hooks/getHook.d.ts +17 -7
  55. package/dist/esm/shared/hooks/getHook.js +103 -3
  56. package/dist/esm/shared/page-configs/Config.d.ts +21 -13
  57. package/dist/esm/shared/page-configs/helpers/getConfigDefinedAtString.d.ts +1 -1
  58. package/dist/esm/shared/page-configs/helpers/getConfigDefinedAtString.js +1 -1
  59. package/dist/esm/shared/route/executeGuardHook.js +4 -3
  60. package/dist/esm/shared/route/executeOnBeforeRouteHook.d.ts +1 -8
  61. package/dist/esm/shared/route/executeOnBeforeRouteHook.js +6 -6
  62. package/dist/esm/shared/route/index.d.ts +2 -2
  63. package/dist/esm/shared/route/loadPageRoutes.d.ts +2 -2
  64. package/dist/esm/shared/route/loadPageRoutes.js +11 -16
  65. package/dist/esm/shared/route/resolveRedirects.js +8 -5
  66. package/dist/esm/utils/parseUrl-extras.d.ts +2 -0
  67. package/dist/esm/utils/parseUrl-extras.js +5 -0
  68. package/dist/esm/utils/parseUrl.js +24 -16
  69. package/dist/esm/utils/projectInfo.d.ts +2 -2
  70. package/dist/esm/utils/projectInfo.js +1 -1
  71. package/package.json +3 -3
  72. /package/dist/cjs/shared/page-configs/serialize/{assertPageConfigs.js → assertPageConfigsSerialized.js} +0 -0
  73. /package/dist/esm/shared/page-configs/serialize/{assertPageConfigs.d.ts → assertPageConfigsSerialized.d.ts} +0 -0
  74. /package/dist/esm/shared/page-configs/serialize/{assertPageConfigs.js → assertPageConfigsSerialized.js} +0 -0
@@ -3,6 +3,8 @@ export type { ConfigBuiltIn };
3
3
  export type { ConfigNameBuiltIn };
4
4
  export type { ConfigMeta };
5
5
  export type { HookName };
6
+ export type { HookNamePage };
7
+ export type { HookNameGlobal };
6
8
  export type { GuardAsync };
7
9
  export type { GuardSync };
8
10
  export type { OnBeforePrerenderStartAsync };
@@ -30,9 +32,13 @@ import type { ConfigDefinition } from '../../node/plugin/plugins/importUserCode/
30
32
  import type { DocumentHtml } from '../../node/runtime/html/renderHtml.js';
31
33
  import type { ConfigVikeUserProvided } from '../ConfigVike.js';
32
34
  import type { Vike, VikePackages } from '../VikeNamespace.js';
35
+ import type { HooksTimeoutProvidedByUser } from '../hooks/getHook.js';
33
36
  import type { PageContextClient, PageContextServer } from '../types.js';
34
- type HookName = 'onHydrationEnd' | 'onBeforePrerender' | 'onBeforePrerenderStart' | 'onBeforeRender' | 'onBeforeRoute' | 'onPageTransitionStart' | 'onPageTransitionEnd' | 'onPrerenderStart' | 'onRenderHtml' | 'onRenderClient' | 'guard' | 'render';
35
- type ConfigNameBuiltIn = Exclude<keyof Config, keyof ConfigVikeUserProvided | 'onBeforeRoute' | 'onPrerenderStart'> | 'prerender' | 'isClientSideRenderable' | 'onBeforeRenderEnv';
37
+ type HookName = HookNamePage | HookNameGlobal | HookNameOldDesign;
38
+ type HookNamePage = 'onHydrationEnd' | 'onBeforePrerenderStart' | 'onBeforeRender' | 'onPageTransitionStart' | 'onPageTransitionEnd' | 'onRenderHtml' | 'onRenderClient' | 'guard';
39
+ type HookNameGlobal = 'onBeforePrerender' | 'onBeforeRoute' | 'onPrerenderStart';
40
+ type HookNameOldDesign = 'render' | 'prerender';
41
+ type ConfigNameBuiltIn = Exclude<keyof Config, keyof ConfigVikeUserProvided | 'onBeforeRoute' | 'onPrerenderStart'> | 'prerender' | 'isClientSideRenderable' | 'onBeforeRenderEnv' | 'hooksTimeout';
36
42
  type Config = ConfigBuiltIn & Vike.Config & (VikePackages.ConfigVikeReact | VikePackages.ConfigVikeVue | VikePackages.ConfigVikeSolid | VikePackages.ConfigVikeSvelte);
37
43
  /** Protect page(s), e.g. forbid unauthorized access.
38
44
  *
@@ -102,32 +108,32 @@ type OnBeforeRouteSync = (pageContext: PageContextServer) => {
102
108
  };
103
109
  /** Hook called after the page is hydrated.
104
110
  *
105
- * https://vike.dev/clientRouting
111
+ * https://vike.dev/onHydrationEnd
106
112
  */
107
113
  type OnHydrationEndAsync = (pageContext: PageContextClient) => Promise<void>;
108
114
  /** Hook called after the page is hydrated.
109
115
  *
110
- * https://vike.dev/clientRouting
116
+ * https://vike.dev/onHydrationEnd
111
117
  */
112
118
  type OnHydrationEndSync = (pageContext: PageContextClient) => void;
113
119
  /** Hook called after the user navigates to a new page.
114
120
  *
115
- * https://vike.dev/clientRouting
121
+ * https://vike.dev/onPageTransitionEnd
116
122
  */
117
123
  type OnPageTransitionEndAsync = (pageContext: PageContextClient) => Promise<void>;
118
124
  /** Hook called after the user navigates to a new page.
119
125
  *
120
- * https://vike.dev/clientRouting
126
+ * https://vike.dev/onPageTransitionEnd
121
127
  */
122
128
  type OnPageTransitionEndSync = (pageContext: PageContextClient) => void;
123
129
  /** Hook called before the user navigates to a new page.
124
130
  *
125
- * https://vike.dev/clientRouting
131
+ * https://vike.dev/onPageTransitionStart
126
132
  */
127
133
  type OnPageTransitionStartAsync = (pageContext: PageContextClient) => Promise<void>;
128
134
  /** Hook called before the user navigates to a new page.
129
135
  *
130
- * https://vike.dev/clientRouting
136
+ * https://vike.dev/onPageTransitionStart
131
137
  */
132
138
  type OnPageTransitionStartSync = (pageContext: PageContextClient) => void;
133
139
  /** Page Hook called when pre-rendering starts.
@@ -275,22 +281,22 @@ type ConfigBuiltIn = {
275
281
  onBeforeRoute?: OnBeforeRouteAsync | OnBeforeRouteSync | ImportString;
276
282
  /** Hook called after the page is hydrated.
277
283
  *
278
- * https://vike.dev/clientRouting
284
+ * https://vike.dev/onHydrationEnd
279
285
  */
280
286
  onHydrationEnd?: OnHydrationEndAsync | OnHydrationEndSync | ImportString;
281
287
  /** Hook called before the user navigates to a new page.
282
288
  *
283
- * https://vike.dev/clientRouting
289
+ * https://vike.dev/onPageTransitionStart
284
290
  */
285
291
  onPageTransitionStart?: OnPageTransitionStartAsync | OnPageTransitionStartSync | ImportString;
286
292
  /** Hook called after the user navigates to a new page.
287
293
  *
288
- * https://vike.dev/clientRouting
294
+ * https://vike.dev/onPageTransitionEnd
289
295
  */
290
296
  onPageTransitionEnd?: OnPageTransitionEndAsync | OnPageTransitionEndSync | ImportString;
291
297
  /** Whether the UI framework (React/Vue/Solid/...) allows the page's hydration to be aborted.
292
298
  *
293
- * https://vike.dev/clientRouting
299
+ * https://vike.dev/hydrationCanBeAborted
294
300
  */
295
301
  hydrationCanBeAborted?: boolean | ImportString;
296
302
  /** Additional client code.
@@ -310,9 +316,11 @@ type ConfigBuiltIn = {
310
316
  meta?: ConfigMeta | ImportString;
311
317
  /** Prefetch links.
312
318
  *
313
- * https://vike.dev/clientRouting#link-prefetching
319
+ * https://vike.dev/prefetchStaticAssets
314
320
  */
315
321
  prefetchStaticAssets?: PrefetchStaticAssets | ImportString;
322
+ /** Modify the tiemouts of hooks. */
323
+ hooksTimeout?: HooksTimeoutProvidedByUser;
316
324
  };
317
325
  type ConfigMeta = Record<string, ConfigDefinition>;
318
326
  type ImportString = `import:${string}`;
@@ -1,7 +1,7 @@
1
1
  export { getConfigDefinedAtString };
2
2
  export { getDefinedAtString };
3
3
  import type { DefinedAt } from '../PageConfig.js';
4
- declare function getConfigDefinedAtString<ConfigName extends string, SentenceBegin extends 'Config' | 'config' | 'Hook'>(sentenceBegin: SentenceBegin, configName: ConfigName, { definedAt }: {
4
+ declare function getConfigDefinedAtString<ConfigName extends string, SentenceBegin extends 'Config' | 'config'>(sentenceBegin: SentenceBegin, configName: ConfigName, { definedAt }: {
5
5
  definedAt: DefinedAt;
6
6
  }): `${SentenceBegin} ${ConfigName}${string} defined ${'internally' | `at ${string}`}`;
7
7
  declare function getDefinedAtString(definedAt: DefinedAt, configName: string): string;
@@ -6,7 +6,7 @@ import { getExportPath } from '../getExportPath.js';
6
6
  function getConfigDefinedAtString(sentenceBegin, configName, { definedAt }) {
7
7
  const definedAtString = getDefinedAtString(definedAt, configName);
8
8
  const definedAtStr = definedAtString === 'internally' ? definedAtString : `at ${definedAtString}`;
9
- let configNameStr = `${configName}${sentenceBegin === 'Hook' ? '()' : ''}`;
9
+ let configNameStr = `${configName}${ /*sentenceBegin === 'Hook' ? '()' :*/''}`;
10
10
  const configDefinedAt = `${sentenceBegin} ${pc.cyan(configNameStr)} defined ${definedAtStr}`;
11
11
  return configDefinedAt;
12
12
  }
@@ -1,5 +1,5 @@
1
1
  export { executeGuardHook };
2
- import { getHook } from '../hooks/getHook.js';
2
+ import { getHook, getHookTimeoutDefault } from '../hooks/getHook.js';
3
3
  import { assert, assertUsage, executeHook, isCallable } from './utils.js';
4
4
  async function executeGuardHook(pageContext, prepareForUserConsumption) {
5
5
  let hook;
@@ -19,7 +19,7 @@ async function executeGuardHook(pageContext, prepareForUserConsumption) {
19
19
  const res = prepareForUserConsumption(pageContext);
20
20
  if (res)
21
21
  pageContextForUserConsumption = res;
22
- const hookResult = await executeHook(() => guard(pageContextForUserConsumption), 'guard', hook.hookFilePath);
22
+ const hookResult = await executeHook(() => guard(pageContextForUserConsumption), hook);
23
23
  assertUsage(hookResult === undefined, `The guard() hook of ${hook.hookFilePath} returns a value, but guard() doesn't accept any return value`);
24
24
  }
25
25
  function findPageGuard(pageId, pageFilesAll) {
@@ -32,6 +32,7 @@ function findPageGuard(pageId, pageFilesAll) {
32
32
  if (!hookFn)
33
33
  return null;
34
34
  const hookFilePath = filePath;
35
+ const hookTimeout = getHookTimeoutDefault('guard');
35
36
  assertUsage(isCallable(hookFn), `guard() defined by ${hookFilePath} should be a function`);
36
- return { hookFn, hookName: 'guard', hookFilePath };
37
+ return { hookFn, hookName: 'guard', hookFilePath, hookTimeout };
37
38
  }
@@ -1,12 +1,5 @@
1
- import type { PageContextForRoute, PageContextFromRoute } from './index.js';
2
1
  export { executeOnBeforeRouteHook };
3
- export type { OnBeforeRouteHook };
4
- type OnBeforeRouteHook = {
5
- hookFilePath: string;
6
- onBeforeRoute: (pageContext: {
7
- urlOriginal: string;
8
- } & Record<string, unknown>) => unknown;
9
- };
2
+ import type { PageContextForRoute, PageContextFromRoute } from './index.js';
10
3
  declare function executeOnBeforeRouteHook(pageContext: PageContextForRoute): Promise<null | ({
11
4
  _routingProvidedByOnBeforeRouteHook: true;
12
5
  } & PageContextFromRoute) | {
@@ -1,13 +1,13 @@
1
+ export { executeOnBeforeRouteHook };
1
2
  import { assertPageContextProvidedByUser } from '../assertPageContextProvidedByUser.js';
2
- import { assertUsage, hasProp, isObjectWithKeys, objectAssign, assertWarning, assertUsageUrl, joinEnglish, assert } from './utils.js';
3
+ import { assertUsage, hasProp, isObjectWithKeys, objectAssign, assertWarning, assertUsageUrl, joinEnglish, assert, executeHook } from './utils.js';
3
4
  import { assertRouteParams, assertSyncRouting } from './resolveRouteFunction.js';
4
5
  import pc from '@brillout/picocolors';
5
- export { executeOnBeforeRouteHook };
6
6
  async function executeOnBeforeRouteHook(pageContext) {
7
7
  const pageContextFromOnBeforeRouteHook = {};
8
8
  if (!pageContext._onBeforeRouteHook)
9
9
  return null;
10
- const pageContextFromHook = await executeHook(pageContext._onBeforeRouteHook, pageContext);
10
+ const pageContextFromHook = await getPageContextFromHook(pageContext._onBeforeRouteHook, pageContext);
11
11
  if (pageContextFromHook) {
12
12
  objectAssign(pageContextFromOnBeforeRouteHook, pageContextFromHook);
13
13
  if (hasProp(pageContextFromOnBeforeRouteHook, '_pageId', 'string') ||
@@ -31,11 +31,11 @@ async function executeOnBeforeRouteHook(pageContext) {
31
31
  });
32
32
  return pageContextFromOnBeforeRouteHook;
33
33
  }
34
- async function executeHook(onBeforeRouteHook, pageContext) {
35
- let hookReturn = onBeforeRouteHook.onBeforeRoute(pageContext);
34
+ async function getPageContextFromHook(onBeforeRouteHook, pageContext) {
35
+ let hookReturn = onBeforeRouteHook.hookFn(pageContext);
36
36
  assertSyncRouting(hookReturn, `The onBeforeRoute() hook ${onBeforeRouteHook.hookFilePath}`);
37
37
  // TODO/v1-release: make executeOnBeforeRouteHook() and route() sync
38
- hookReturn = await hookReturn;
38
+ hookReturn = await executeHook(() => hookReturn, onBeforeRouteHook);
39
39
  const errPrefix = `The onBeforeRoute() hook defined by ${onBeforeRouteHook.hookFilePath}`;
40
40
  assertUsage(hookReturn === null ||
41
41
  hookReturn === undefined ||
@@ -5,16 +5,16 @@ export type { PageRoutes };
5
5
  export type { RouteMatches };
6
6
  import type { PageFile } from '../getPageFiles.js';
7
7
  import { PageContextUrlComputedPropsInternal, PageContextUrlSources } from '../addUrlComputedProps.js';
8
- import { type OnBeforeRouteHook } from './executeOnBeforeRouteHook.js';
9
8
  import type { PageRoutes, RouteType } from './loadPageRoutes.js';
10
9
  import type { PageConfigRuntime, PageConfigGlobalRuntime } from '../page-configs/PageConfig.js';
10
+ import type { Hook } from '../hooks/getHook.js';
11
11
  type PageContextForRoute = PageContextUrlComputedPropsInternal & {
12
12
  _pageFilesAll: PageFile[];
13
13
  _pageConfigs: PageConfigRuntime[];
14
14
  _allPageIds: string[];
15
15
  _pageConfigGlobal: PageConfigGlobalRuntime;
16
16
  _pageRoutes: PageRoutes;
17
- _onBeforeRouteHook: OnBeforeRouteHook | null;
17
+ _onBeforeRouteHook: Hook | null;
18
18
  } & PageContextUrlSources;
19
19
  type PageContextFromRoute = {
20
20
  _pageId: string | null;
@@ -2,8 +2,8 @@ export { loadPageRoutes };
2
2
  export type { PageRoutes };
3
3
  export type { RouteType };
4
4
  import type { PageFile } from '../getPageFiles.js';
5
- import type { OnBeforeRouteHook } from './executeOnBeforeRouteHook.js';
6
5
  import type { PageConfigRuntime, PageConfigGlobalRuntime } from '../page-configs/PageConfig.js';
6
+ import { type Hook } from '../hooks/getHook.js';
7
7
  type PageRoute = {
8
8
  pageId: string;
9
9
  comesFromV1PageConfig: boolean;
@@ -25,5 +25,5 @@ type PageRoutes = PageRoute[];
25
25
  type RouteType = 'STRING' | 'FUNCTION' | 'FILESYSTEM';
26
26
  declare function loadPageRoutes(pageFilesAll: PageFile[], pageConfigs: PageConfigRuntime[], pageConfigGlobal: PageConfigGlobalRuntime, allPageIds: string[]): Promise<{
27
27
  pageRoutes: PageRoutes;
28
- onBeforeRouteHook: null | OnBeforeRouteHook;
28
+ onBeforeRouteHook: null | Hook;
29
29
  }>;
@@ -3,8 +3,9 @@ import { isErrorPageId } from '../error-page.js';
3
3
  import { assert, assertUsage, hasProp, slice } from './utils.js';
4
4
  import { deduceRouteStringFromFilesystemPath } from './deduceRouteStringFromFilesystemPath.js';
5
5
  import { isCallable } from '../utils.js';
6
- import { getConfigDefinedAtString, getConfigValue, getDefinedAtString, getHookFilePathToShowToUser } from '../page-configs/helpers.js';
6
+ import { getConfigValue, getDefinedAtString } from '../page-configs/helpers.js';
7
7
  import { warnDeprecatedAllowKey } from './resolveRouteFunction.js';
8
+ import { getHookFromPageConfigGlobal, getHookTimeoutDefault } from '../hooks/getHook.js';
8
9
  async function loadPageRoutes(
9
10
  // Remove all arguments and use GlobalContext instead?
10
11
  pageFilesAll, pageConfigs, pageConfigGlobal, allPageIds) {
@@ -136,20 +137,8 @@ function getPageRoutes(filesystemRoots, pageFilesAll, pageConfigs, allPageIds) {
136
137
  function getGlobalHooks(pageFilesAll, pageConfigs, pageConfigGlobal) {
137
138
  // V1 Design
138
139
  if (pageConfigs.length > 0) {
139
- const hookName = 'onBeforeRoute';
140
- if (pageConfigGlobal.configValues[hookName]?.value) {
141
- const configValue = pageConfigGlobal.configValues[hookName];
142
- const { value: hookFn } = configValue;
143
- const hookFilePath = getHookFilePathToShowToUser(configValue);
144
- const hookDefinedAt = getConfigDefinedAtString('Hook', hookName, configValue);
145
- assertUsage(isCallable(hookFn), `${hookDefinedAt} should be a function.`);
146
- const onBeforeRouteHook = {
147
- hookFilePath: hookFilePath,
148
- onBeforeRoute: hookFn
149
- };
150
- return { onBeforeRouteHook, filesystemRoots: null };
151
- }
152
- return { onBeforeRouteHook: null, filesystemRoots: null };
140
+ const hook = getHookFromPageConfigGlobal(pageConfigGlobal, 'onBeforeRoute');
141
+ return { onBeforeRouteHook: hook, filesystemRoots: null };
153
142
  }
154
143
  // Old design
155
144
  // TODO/v1-release: remove
@@ -162,7 +151,13 @@ function getGlobalHooks(pageFilesAll, pageConfigs, pageConfigGlobal) {
162
151
  if ('onBeforeRoute' in fileExports) {
163
152
  assertUsage(hasProp(fileExports, 'onBeforeRoute', 'function'), `\`export { onBeforeRoute }\` of ${filePath} should be a function.`);
164
153
  const { onBeforeRoute } = fileExports;
165
- onBeforeRouteHook = { hookFilePath: `${filePath} > \`export { onBeforeRoute }\``, onBeforeRoute };
154
+ const hookName = 'onBeforeRoute';
155
+ onBeforeRouteHook = {
156
+ hookFilePath: filePath,
157
+ hookFn: onBeforeRoute,
158
+ hookName,
159
+ hookTimeout: getHookTimeoutDefault(hookName)
160
+ };
166
161
  }
167
162
  if ('filesystemRoutingRoot' in fileExports) {
168
163
  assertUsage(hasProp(fileExports, 'filesystemRoutingRoot', 'string'), `\`export { filesystemRoutingRoot }\` of ${filePath} should be a string.`);
@@ -2,6 +2,7 @@ export { resolveRedirects };
2
2
  // For ./resolveRedirects.spec.ts
3
3
  export { resolveRouteStringRedirect };
4
4
  import { assertIsNotBrowser } from '../../utils/assertIsNotBrowser.js';
5
+ import { isUriWithProtocol } from '../../utils/parseUrl-extras.js';
5
6
  import { assert, assertUsage } from '../utils.js';
6
7
  import { assertRouteString, resolveRouteString } from './resolveRouteString.js';
7
8
  import pc from '@brillout/picocolors';
@@ -19,9 +20,9 @@ function resolveRedirects(redirects, urlPathname) {
19
20
  function resolveRouteStringRedirect(urlSource, urlTarget, urlPathname) {
20
21
  assertRouteString(urlSource, `${configSrc} Invalid`);
21
22
  assertUsage(urlTarget.startsWith('/') ||
22
- urlTarget.startsWith('http://') ||
23
- urlTarget.startsWith('https://') ||
24
- urlTarget === '*', `${configSrc} Invalid redirection target URL ${pc.cyan(urlTarget)}: the target URL should start with ${pc.cyan('/')}, ${pc.cyan('http://')}, ${pc.cyan('https://')}, or be ${pc.cyan('*')}`);
23
+ // Is allowing any protocol a safety issue? https://github.com/vikejs/vike/pull/1292#issuecomment-1828043917
24
+ isUriWithProtocol(urlTarget) ||
25
+ urlTarget === '*', `${configSrc} Invalid redirection target URL ${pc.cyan(urlTarget)}: the target URL should start with ${pc.cyan('/')}, a valid protocol (${pc.cyan('https:')}, ${pc.cyan('http:')}, ${pc.cyan('ipfs:')}, ${pc.cyan('magnet:')}, ...), or be ${pc.cyan('*')}`);
25
26
  assertParams(urlSource, urlTarget);
26
27
  const match = resolveRouteString(urlSource, urlPathname);
27
28
  if (!match)
@@ -33,10 +34,12 @@ function resolveRouteStringRedirect(urlSource, urlTarget, urlPathname) {
33
34
  }
34
35
  urlResolved = urlResolved.replaceAll(key, val);
35
36
  });
36
- assert(!urlResolved.includes('@'));
37
+ if (!urlResolved.startsWith('mailto:')) {
38
+ assertUsage(!urlResolved.includes('@'), 'URL should not contain "@" unless it is a mailto link.');
39
+ }
37
40
  if (urlResolved === urlPathname)
38
41
  return null;
39
- assert(urlTarget.startsWith('/') || urlTarget.startsWith('http'));
42
+ assert(urlResolved.startsWith('/') || isUriWithProtocol(urlResolved));
40
43
  return urlResolved;
41
44
  }
42
45
  function assertParams(urlSource, urlTarget) {
@@ -5,6 +5,7 @@ export { removeBaseServer };
5
5
  export { modifyUrlPathname };
6
6
  export { removeUrlOrigin };
7
7
  export { addUrlOrigin };
8
+ export { isUriWithProtocol };
8
9
  declare function prependBase(url: string, baseServer: string): string;
9
10
  declare function removeBaseServer(url: string, baseServer: string): string;
10
11
  declare function isBaseAssets(base: string): boolean;
@@ -15,3 +16,4 @@ declare function removeUrlOrigin(url: string): {
15
16
  origin: string | null;
16
17
  };
17
18
  declare function addUrlOrigin(url: string, origin: string | null): string;
19
+ declare function isUriWithProtocol(uri: string): boolean;
@@ -5,6 +5,7 @@ export { removeBaseServer };
5
5
  export { modifyUrlPathname };
6
6
  export { removeUrlOrigin };
7
7
  export { addUrlOrigin };
8
+ export { isUriWithProtocol };
8
9
  import { assertUrlComponents, createUrlFromComponents, isBaseServer, parseUrl } from './parseUrl.js';
9
10
  import { assert } from './assert.js';
10
11
  import { slice } from './slice.js';
@@ -100,3 +101,7 @@ function addUrlOrigin(url, origin) {
100
101
  const urlModified = createUrlFromComponents(origin, pathnameOriginal, searchOriginal, hashOriginal);
101
102
  return urlModified;
102
103
  }
104
+ function isUriWithProtocol(uri) {
105
+ // https://en.wikipedia.org/wiki/List_of_URI_schemes
106
+ return /^[a-z0-9][a-z0-9\.\+\-]*:/i.test(uri);
107
+ }
@@ -54,7 +54,7 @@ function parseUrl(url, baseServer) {
54
54
  searchAll[key] = [...(searchAll.hasOwnProperty(key) ? searchAll[key] : []), val];
55
55
  });
56
56
  // Origin + pathname
57
- const { origin, pathname: pathnameResolved } = parsePathname(urlWithoutHashNorSearch, baseServer);
57
+ const { origin, pathname: pathnameResolved } = getPathname(urlWithoutHashNorSearch, baseServer);
58
58
  assert(origin === null || origin === decodeSafe(origin)); // AFAICT decoding the origin is useless
59
59
  assert(pathnameResolved.startsWith('/'));
60
60
  assert(origin === null || url.startsWith(origin));
@@ -89,35 +89,43 @@ function decodeSafe(urlComponent) {
89
89
  return urlComponent;
90
90
  }
91
91
  function decodePathname(urlPathname) {
92
+ urlPathname = urlPathname.replace(/\s+$/, '');
92
93
  urlPathname = urlPathname
93
94
  .split('/')
94
95
  .map((dir) => decodeSafe(dir).split('/').join('%2F'))
95
96
  .join('/');
96
- urlPathname = urlPathname.replace(/\s/g, '');
97
97
  return urlPathname;
98
98
  }
99
- function parsePathname(urlWithoutHashNorSearch, baseServer) {
99
+ function getPathname(url, baseServer) {
100
+ // Search and hash already extracted
101
+ assert(!url.includes('?') && !url.includes('#'));
102
+ // url has origin
100
103
  {
101
- const { origin, pathname } = parseOrigin(urlWithoutHashNorSearch);
104
+ const { origin, pathname } = parseOrigin(url);
102
105
  if (origin) {
103
106
  return { origin, pathname };
104
107
  }
105
- assert(pathname === urlWithoutHashNorSearch);
108
+ assert(pathname === url);
106
109
  }
107
- if (urlWithoutHashNorSearch.startsWith('/')) {
108
- return { origin: null, pathname: urlWithoutHashNorSearch };
110
+ // url doesn't have origin
111
+ if (url.startsWith('/')) {
112
+ return { origin: null, pathname: url };
109
113
  }
110
114
  else {
111
- // In the browser, this is the Base URL of the current URL
115
+ // url is a relative path
116
+ // In the browser, this is the Base URL of the current URL.
112
117
  // Safe access `window?.document?.baseURI` for users who shim `window` in Node.js
113
- let baseURI = typeof window !== 'undefined' && window?.document?.baseURI;
114
- if (baseURI)
115
- baseURI = parseOrigin(baseURI).pathname;
116
- const base = baseURI || baseServer;
117
- const pathname = resolveUrlPathnameRelative(urlWithoutHashNorSearch, base);
118
- // We need to parse the origin in case `base === window.document.baseURI`
119
- const parsed = parseOrigin(pathname);
120
- return parsed;
118
+ const baseURI = typeof window !== 'undefined' ? window?.document?.baseURI : undefined;
119
+ let base;
120
+ if (baseURI) {
121
+ const baseURIPathaname = parseOrigin(baseURI.split('?')[0]).pathname;
122
+ base = baseURIPathaname;
123
+ }
124
+ else {
125
+ base = baseServer;
126
+ }
127
+ const pathname = resolveUrlPathnameRelative(url, base);
128
+ return { origin: null, pathname };
121
129
  }
122
130
  }
123
131
  function parseOrigin(url) {
@@ -1,13 +1,13 @@
1
1
  export { projectInfo };
2
2
  export type { ProjectTag };
3
3
  export { PROJECT_VERSION };
4
- declare const PROJECT_VERSION: "0.4.147";
4
+ declare const PROJECT_VERSION: "0.4.148-commit-7596dcd";
5
5
  type PackageName = typeof projectInfo.npmPackageName;
6
6
  type ProjectVersion = typeof projectInfo.projectVersion;
7
7
  type ProjectTag = `[${PackageName}]` | `[${PackageName}@${ProjectVersion}]`;
8
8
  declare const projectInfo: {
9
9
  projectName: "Vike";
10
- projectVersion: "0.4.147";
10
+ projectVersion: "0.4.148-commit-7596dcd";
11
11
  npmPackageName: "vike";
12
12
  githubRepository: "https://github.com/vikejs/vike";
13
13
  };
@@ -1,7 +1,7 @@
1
1
  export { projectInfo };
2
2
  export { PROJECT_VERSION };
3
3
  import { onProjectInfo } from './assertSingleInstance.js';
4
- const PROJECT_VERSION = '0.4.147';
4
+ const PROJECT_VERSION = '0.4.148-commit-7596dcd';
5
5
  const projectInfo = {
6
6
  projectName: 'Vike',
7
7
  projectVersion: PROJECT_VERSION,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.147",
3
+ "version": "0.4.148-commit-7596dcd",
4
4
  "scripts": {
5
5
  "dev": "tsc --watch",
6
6
  "build": "rimraf dist/ && pnpm run build:esm && pnpm run build:cjs",
@@ -14,7 +14,7 @@
14
14
  "dependencies": {
15
15
  "@brillout/import": "0.2.3",
16
16
  "@brillout/json-serializer": "^0.5.8",
17
- "@brillout/picocolors": "^1.0.9",
17
+ "@brillout/picocolors": "^1.0.10",
18
18
  "@brillout/require-shim": "^0.1.2",
19
19
  "@brillout/vite-plugin-import-build": "^0.2.20",
20
20
  "acorn": "^8.8.2",
@@ -162,7 +162,7 @@
162
162
  "vike": "./node/cli/bin-entry.js"
163
163
  },
164
164
  "devDependencies": {
165
- "@brillout/release-me": "^0.1.8",
165
+ "@brillout/release-me": "^0.1.9",
166
166
  "@types/estree": "^1.0.0",
167
167
  "@types/jest": "^27.4.1",
168
168
  "@types/node": "^20.1.0",