vike 0.4.180 → 0.4.181

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 (48) hide show
  1. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +3 -0
  2. package/dist/cjs/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +1 -2
  3. package/dist/cjs/{shared/route → node/runtime/renderPage}/resolveRedirects.js +9 -11
  4. package/dist/cjs/node/runtime/renderPage.js +6 -9
  5. package/dist/cjs/shared/getPageContextUrlComputed.js +43 -37
  6. package/dist/cjs/shared/modifyUrl.js +31 -0
  7. package/dist/cjs/shared/route/abort.js +4 -10
  8. package/dist/cjs/shared/route/executeOnBeforeRouteHook.js +3 -1
  9. package/dist/cjs/utils/parseUrl.js +168 -87
  10. package/dist/cjs/utils/projectInfo.js +1 -1
  11. package/dist/cjs/utils/redirectHard.js +7 -0
  12. package/dist/cjs/utils/urlToFile.js +1 -1
  13. package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +1 -1
  14. package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +2 -2
  15. package/dist/esm/client/client-routing-runtime/navigate.js +2 -1
  16. package/dist/esm/client/client-routing-runtime/prefetch.js +5 -4
  17. package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +7 -7
  18. package/dist/esm/client/client-routing-runtime/skipLink.js +11 -22
  19. package/dist/esm/client/client-routing-runtime/utils.d.ts +1 -2
  20. package/dist/esm/client/client-routing-runtime/utils.js +1 -2
  21. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +3 -0
  22. package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +2 -3
  23. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +5 -5
  24. package/dist/esm/{shared/route → node/runtime/renderPage}/resolveRedirects.js +9 -11
  25. package/dist/esm/node/runtime/renderPage.d.ts +2 -2
  26. package/dist/esm/node/runtime/renderPage.js +7 -10
  27. package/dist/esm/shared/getPageContextUrlComputed.d.ts +2 -24
  28. package/dist/esm/shared/getPageContextUrlComputed.js +43 -37
  29. package/dist/esm/shared/modifyUrl.d.ts +14 -0
  30. package/dist/esm/shared/modifyUrl.js +28 -0
  31. package/dist/esm/shared/route/abort.js +5 -11
  32. package/dist/esm/shared/route/executeOnBeforeRouteHook.js +4 -2
  33. package/dist/esm/types/index.d.ts +1 -1
  34. package/dist/esm/utils/parseUrl.d.ts +43 -10
  35. package/dist/esm/utils/parseUrl.js +167 -86
  36. package/dist/esm/utils/projectInfo.d.ts +2 -2
  37. package/dist/esm/utils/projectInfo.js +1 -1
  38. package/dist/esm/utils/redirectHard.d.ts +1 -0
  39. package/dist/esm/utils/redirectHard.js +3 -0
  40. package/dist/esm/utils/urlToFile.js +1 -1
  41. package/package.json +17 -2
  42. package/dist/cjs/utils/isExternalLink.js +0 -7
  43. package/dist/cjs/utils/serverSideRouteTo.js +0 -7
  44. package/dist/esm/utils/isExternalLink.d.ts +0 -2
  45. package/dist/esm/utils/isExternalLink.js +0 -4
  46. package/dist/esm/utils/serverSideRouteTo.d.ts +0 -2
  47. package/dist/esm/utils/serverSideRouteTo.js +0 -4
  48. /package/dist/esm/{shared/route → node/runtime/renderPage}/resolveRedirects.d.ts +0 -0
@@ -6,35 +6,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6
6
  return (mod && mod.__esModule) ? mod : { "default": mod };
7
7
  };
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.isUriWithProtocol = exports.createUrlFromComponents = exports.assertUrlComponents = exports.isBaseServer = exports.assertUsageUrl = exports.isParsable = exports.parseUrl = void 0;
9
+ exports.createUrlFromComponents = exports.assertUrlComponents = exports.isBaseServer = exports.isUrlExternal = exports.isUrlRedirectTarget = exports.isUri = exports.isUrl = exports.assertUsageUrlRedirectTarget = exports.assertUsageUrlPathnameAbsolute = exports.assertUsageUrlPathname = exports.parseUrl = void 0;
10
10
  const slice_js_1 = require("./slice.js");
11
11
  const assert_js_1 = require("./assert.js");
12
12
  const picocolors_1 = __importDefault(require("@brillout/picocolors"));
13
- function isParsable(url) {
14
- // `parseUrl()` works with these URLs
15
- return (isUrlWithProtocol(url) ||
16
- url.startsWith('/') ||
17
- url.startsWith('.') ||
18
- url.startsWith('?') ||
19
- url.startsWith('#') ||
20
- url === '');
21
- }
22
- exports.isParsable = isParsable;
23
- function assertUsageUrl(url, errPrefix) {
24
- (0, assert_js_1.assert)(errPrefix.includes(' but '));
25
- (0, assert_js_1.assertUsage)(typeof url === 'string', `${errPrefix} should be a string`);
26
- if (isParsable(url))
27
- return;
28
- if (!url.startsWith('/') && !url.includes(':')) {
29
- (0, assert_js_1.assertUsage)(false, `${errPrefix} is ${picocolors_1.default.cyan(url)} and it should be /${picocolors_1.default.cyan(url)} instead (URL pathnames should start with a leading slash)`);
30
- }
31
- else {
32
- (0, assert_js_1.assertUsage)(false, `${errPrefix} isn't a valid URL`);
33
- }
34
- }
35
- exports.assertUsageUrl = assertUsageUrl;
36
13
  function parseUrl(url, baseServer) {
37
- (0, assert_js_1.assert)(isParsable(url));
14
+ (0, assert_js_1.assert)(isUrl(url), url);
38
15
  (0, assert_js_1.assert)(baseServer.startsWith('/'));
39
16
  // Hash
40
17
  const [urlWithoutHash, ...hashList] = url.split('#');
@@ -54,18 +31,24 @@ function parseUrl(url, baseServer) {
54
31
  searchAll[key] = [...(searchAll.hasOwnProperty(key) ? searchAll[key] : []), val];
55
32
  });
56
33
  // Origin + pathname
57
- const { origin, pathname: pathnameResolved } = getPathname(urlWithoutHashNorSearch, baseServer);
58
- (0, assert_js_1.assert)(origin === null || origin === decodeSafe(origin)); // AFAICT decoding the origin is useless
59
- (0, assert_js_1.assert)(pathnameResolved.startsWith('/'));
60
- (0, assert_js_1.assert)(origin === null || url.startsWith(origin));
61
- // `pathnameOriginal`
34
+ let { protocol, origin, pathnameAbsoluteWithBase } = getPathnameAbsoluteWithBase(urlWithoutHashNorSearch, baseServer);
62
35
  const pathnameOriginal = urlWithoutHashNorSearch.slice((origin || '').length);
63
36
  assertUrlComponents(url, origin, pathnameOriginal, searchOriginal, hashOriginal);
64
37
  // Base URL
65
- let { pathname, hasBaseServer } = analyzeBaseServer(pathnameResolved, baseServer);
38
+ let { pathname, hasBaseServer } = removeBaseServer(pathnameAbsoluteWithBase, baseServer);
39
+ // pageContext.urlParsed.href
40
+ const href = createUrlFromComponents(origin, pathname, searchOriginal, hashOriginal);
41
+ // pageContext.urlParsed.{hostname, port}
42
+ const host = !origin ? null : origin.slice(protocol.length);
43
+ const { hostname, port } = parseHost(host, url);
44
+ // decode after setting href
66
45
  pathname = decodePathname(pathname);
67
46
  (0, assert_js_1.assert)(pathname.startsWith('/'));
68
47
  return {
48
+ href,
49
+ protocol,
50
+ hostname,
51
+ port,
69
52
  origin,
70
53
  pathname,
71
54
  pathnameOriginal: pathnameOriginal,
@@ -97,20 +80,20 @@ function decodePathname(urlPathname) {
97
80
  .join('/');
98
81
  return urlPathname;
99
82
  }
100
- function getPathname(url, baseServer) {
83
+ function getPathnameAbsoluteWithBase(url, baseServer) {
101
84
  // Search and hash already extracted
102
85
  (0, assert_js_1.assert)(!url.includes('?') && !url.includes('#'));
103
86
  // url has origin
104
87
  {
105
- const { origin, pathname } = parseOrigin(url);
88
+ const { protocol, origin, pathname } = parseOrigin(url);
106
89
  if (origin) {
107
- return { origin, pathname };
90
+ return { protocol, origin, pathnameAbsoluteWithBase: pathname };
108
91
  }
109
92
  (0, assert_js_1.assert)(pathname === url);
110
93
  }
111
94
  // url doesn't have origin
112
95
  if (url.startsWith('/')) {
113
- return { origin: null, pathname: url };
96
+ return { protocol: null, origin: null, pathnameAbsoluteWithBase: url };
114
97
  }
115
98
  else {
116
99
  // url is a relative path
@@ -125,21 +108,70 @@ function getPathname(url, baseServer) {
125
108
  else {
126
109
  base = baseServer;
127
110
  }
128
- const pathname = resolveUrlPathnameRelative(url, base);
129
- return { origin: null, pathname };
111
+ const pathnameAbsoluteWithBase = resolveUrlPathnameRelative(url, base);
112
+ return { protocol: null, origin: null, pathnameAbsoluteWithBase: pathnameAbsoluteWithBase };
130
113
  }
131
114
  }
132
115
  function parseOrigin(url) {
133
116
  if (!isUrlWithProtocol(url)) {
134
- (0, assert_js_1.assert)(!isUriWithProtocol(url));
135
- return { pathname: url, origin: null };
117
+ return { pathname: url, origin: null, protocol: null };
136
118
  }
137
119
  else {
138
- const [originPart1, originPart2, originPart3, ...pathnameParts] = url.split('/');
139
- const origin = [originPart1, originPart2, originPart3].join('/');
140
- const pathname = ['', ...pathnameParts].join('/') || '/';
141
- return { origin, pathname };
120
+ const { protocol, uriWithoutProtocol } = parseProtocol(url);
121
+ (0, assert_js_1.assert)(protocol);
122
+ const [host, ...rest] = uriWithoutProtocol.split('/');
123
+ const origin = protocol + host;
124
+ const pathname = '/' + rest.join('/');
125
+ return { pathname, origin, protocol };
126
+ }
127
+ }
128
+ function parseHost(host, url) {
129
+ const ret = { hostname: null, port: null };
130
+ if (!host)
131
+ return ret;
132
+ // hostname
133
+ const [hostname, ...rest] = host.split(':');
134
+ ret.hostname = hostname;
135
+ // port
136
+ if (rest.length > 0) {
137
+ (0, assert_js_1.assert)(rest.length === 1, url);
138
+ const portStr = rest[0];
139
+ const port = parseInt(portStr, 10);
140
+ (0, assert_js_1.assert)(port || port === 0, url);
141
+ ret.port = port;
142
142
  }
143
+ return ret;
144
+ }
145
+ function parseProtocol(uri) {
146
+ const SEP = ':';
147
+ const [before, ...after] = uri.split(SEP);
148
+ if (after.length === 0 ||
149
+ // https://github.com/vikejs/vike/commit/886a99ff21e86a8ca699a25cee7edc184aa058e4#r143308934
150
+ // https://en.wikipedia.org/wiki/List_of_URI_schemes
151
+ // https://www.rfc-editor.org/rfc/rfc7595
152
+ !/^[a-z][a-z0-9\+\-]*$/i.test(before)) {
153
+ return { protocol: null, uriWithoutProtocol: uri };
154
+ }
155
+ let protocol = before + SEP;
156
+ let uriWithoutProtocol = after.join(SEP);
157
+ const SEP2 = '//';
158
+ if (uriWithoutProtocol.startsWith(SEP2)) {
159
+ protocol = protocol + SEP2;
160
+ uriWithoutProtocol = uriWithoutProtocol.slice(SEP2.length);
161
+ }
162
+ return { protocol, uriWithoutProtocol };
163
+ }
164
+ function isUrlProtocol(protocol) {
165
+ // Is there an altenrative to having a blacklist?
166
+ // - If the blacklist becomes too big, maybe use a whitelist instead ['tauri://', 'file://', 'capacitor://', 'http://', 'https://']
167
+ const blacklist = [
168
+ // https://docs.ipfs.tech/how-to/address-ipfs-on-web
169
+ 'ipfs://',
170
+ 'ipns://'
171
+ ];
172
+ if (blacklist.includes(protocol))
173
+ return false;
174
+ return protocol.endsWith('://');
143
175
  }
144
176
  // Adapted from https://stackoverflow.com/questions/14780350/convert-relative-path-to-absolute-using-javascript/14780463#14780463
145
177
  function resolveUrlPathnameRelative(pathnameRelative, base) {
@@ -170,34 +202,15 @@ function resolveUrlPathnameRelative(pathnameRelative, base) {
170
202
  pathnameAbsolute = '/' + pathnameAbsolute;
171
203
  return pathnameAbsolute;
172
204
  }
173
- /* Not needed anymore?
174
- function assertUsageBaseServer(baseServer: string, usageErrorMessagePrefix: string = '') {
175
- assertUsage(
176
- !baseServer.startsWith('http'),
177
- usageErrorMessagePrefix +
178
- '`base` is not allowed to start with `http`. Consider using `baseAssets` instead, see https://vike.dev/base-url'
179
- )
180
- assertUsage(
181
- baseServer.startsWith('/'),
182
- usageErrorMessagePrefix + 'Wrong `base` value `' + baseServer + '`; `base` should start with `/`.'
183
- )
184
- assert(isBaseServer(baseServer))
185
- }
186
- */
187
- function assertPathname(urlPathname) {
188
- (0, assert_js_1.assert)(urlPathname.startsWith('/'));
189
- (0, assert_js_1.assert)(!urlPathname.includes('?'));
190
- (0, assert_js_1.assert)(!urlPathname.includes('#'));
191
- }
192
- function analyzeBaseServer(urlPathnameWithBase, baseServer) {
193
- assertPathname(urlPathnameWithBase);
205
+ function removeBaseServer(pathnameAbsoluteWithBase, baseServer) {
206
+ (0, assert_js_1.assert)(pathnameAbsoluteWithBase.startsWith('/'));
194
207
  (0, assert_js_1.assert)(isBaseServer(baseServer));
195
208
  // Mutable
196
- let urlPathname = urlPathnameWithBase;
209
+ let urlPathname = pathnameAbsoluteWithBase;
197
210
  (0, assert_js_1.assert)(urlPathname.startsWith('/'));
198
211
  (0, assert_js_1.assert)(baseServer.startsWith('/'));
199
212
  if (baseServer === '/') {
200
- const pathname = urlPathnameWithBase;
213
+ const pathname = pathnameAbsoluteWithBase;
201
214
  return { pathname, hasBaseServer: true };
202
215
  }
203
216
  // Support `url === '/some-base-url' && baseServer === '/some-base-url/'`
@@ -207,7 +220,7 @@ function analyzeBaseServer(urlPathnameWithBase, baseServer) {
207
220
  (0, assert_js_1.assert)(urlPathname === baseServerNormalized);
208
221
  }
209
222
  if (!urlPathname.startsWith(baseServerNormalized)) {
210
- const pathname = urlPathnameWithBase;
223
+ const pathname = pathnameAbsoluteWithBase;
211
224
  return { pathname, hasBaseServer: false };
212
225
  }
213
226
  (0, assert_js_1.assert)(urlPathname.startsWith('/') || urlPathname.startsWith('http'));
@@ -222,30 +235,98 @@ function isBaseServer(baseServer) {
222
235
  return baseServer.startsWith('/');
223
236
  }
224
237
  exports.isBaseServer = isBaseServer;
225
- function assertUrlComponents(url, origin, pathname, searchOriginal, hashOriginal) {
226
- const urlRecreated = createUrlFromComponents(origin, pathname, searchOriginal, hashOriginal);
238
+ function assertUrlComponents(url, origin, pathnameOriginal, searchOriginal, hashOriginal) {
239
+ const urlRecreated = createUrlFromComponents(origin, pathnameOriginal, searchOriginal, hashOriginal);
227
240
  (0, assert_js_1.assert)(url === urlRecreated);
228
241
  }
229
242
  exports.assertUrlComponents = assertUrlComponents;
230
- function createUrlFromComponents(origin, pathname, searchOriginal, hashOriginal) {
231
- const urlRecreated = `${origin || ''}${pathname}${searchOriginal || ''}${hashOriginal || ''}`;
243
+ function createUrlFromComponents(origin, pathname, search, hash) {
244
+ const urlRecreated = `${origin || ''}${pathname}${search || ''}${hash || ''}`;
232
245
  return urlRecreated;
233
246
  }
234
247
  exports.createUrlFromComponents = createUrlFromComponents;
235
- function isUriWithProtocol(str) {
236
- // https://en.wikipedia.org/wiki/List_of_URI_schemes
237
- // https://www.rfc-editor.org/rfc/rfc7595
238
- // https://github.com/vikejs/vike/commit/886a99ff21e86a8ca699a25cee7edc184aa058e4#r143308934
239
- // Examples:
240
- // http://
241
- // https://
242
- // tauri:// # [Tauri](https://tauri.app)
243
- // file:// # [Electron](https://github.com/vikejs/vike/issues/1557)
244
- // capacitor:// # [Capacitor](https://github.com/vikejs/vike/issues/1706)
245
- return /^[a-z][a-z0-9\+\-]*:/i.test(str);
246
- }
247
- exports.isUriWithProtocol = isUriWithProtocol;
248
- // Same as isUriWithProtocol() but with trailing :// which is needed for parseOrigin()
249
- function isUrlWithProtocol(str) {
250
- return /^[a-z][a-z0-9\+\-]*:\/\//i.test(str);
248
+ function isUrl(url) {
249
+ // parseUrl() works with these URLs
250
+ return isUrlWithProtocol(url) || url.startsWith('/') || isUrlPathnameRelative(url);
251
+ }
252
+ exports.isUrl = isUrl;
253
+ function isUrlRedirectTarget(url) {
254
+ return url.startsWith('/') || isUri(url) || isUrlWithProtocol(url);
255
+ }
256
+ exports.isUrlRedirectTarget = isUrlRedirectTarget;
257
+ function isUrlPathnameRelative(url) {
258
+ return ['.', '?', '#'].some((c) => url.startsWith(c)) || url === '';
259
+ }
260
+ function isUrlExternal(url) {
261
+ return !url.startsWith('/') && !isUrlPathnameRelative(url);
262
+ }
263
+ exports.isUrlExternal = isUrlExternal;
264
+ /*
265
+ URL with protocol.
266
+
267
+ http://example.com
268
+ https://exmaple.com
269
+ tauri://localhost
270
+ file://example.com
271
+ capacitor://localhost/assets/chunks/chunk-DJBYDrsP.js
272
+
273
+ [Tauri](https://github.com/vikejs/vike/issues/808)
274
+ [Electron (`file://`)](https://github.com/vikejs/vike/issues/1557)
275
+ [Capacitor](https://github.com/vikejs/vike/issues/1706)
276
+ */
277
+ function isUrlWithProtocol(url) {
278
+ const { protocol } = parseProtocol(url);
279
+ return !!protocol && isUrlProtocol(protocol);
280
+ }
281
+ /*
282
+ URIs that aren't URLs.
283
+
284
+ mailto:john@example.com
285
+
286
+ ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/wiki/Vincent_van_Gogh.html
287
+
288
+ magnet:?xt=urn:btih:3a15e1ac49683d91b20c2ffc252ea612a6c01bd7&dn=The.Empire.Strikes.Back.1980.Remastered.1080p.BluRay.DDP.7.1.x265-EDGE2020.mkv&xl=3225443573&tr=udp://tracker.opentrackr.org:1337/announce&tr=udp://tracker.torrent.eu.org:451&tr=udp://open.stealth.si:80/announce&tr=udp://tracker.openbittorrent.com:6969&tr=udp://tracker.tiny-vps.com:6969/announce&tr=udp://open.demonii.com:1337
289
+
290
+ We need to treat URIs differently than URLs.
291
+ - For example, we cannot parse URIs (their structure is unknown e.g. a `magnet:` URI is completely different than a `http://` URL).
292
+ - The protocols tauri:// file:// capacitor:// follow the same structure as http:// and https:// URLs.
293
+ - Thus we can parse them like http:// and https:// URLs.
294
+ */
295
+ function isUri(uri) {
296
+ const { protocol } = parseProtocol(uri);
297
+ return !!protocol && !isUrlProtocol(uri);
298
+ }
299
+ exports.isUri = isUri;
300
+ function assertUsageUrlPathname(url, errPrefix) {
301
+ assertUsageUrl(url, errPrefix, { allowRelative: true });
302
+ }
303
+ exports.assertUsageUrlPathname = assertUsageUrlPathname;
304
+ function assertUsageUrlPathnameAbsolute(url, errPrefix) {
305
+ assertUsageUrl(url, errPrefix);
306
+ }
307
+ exports.assertUsageUrlPathnameAbsolute = assertUsageUrlPathnameAbsolute;
308
+ function assertUsageUrlRedirectTarget(url, errPrefix, isUnresolved) {
309
+ assertUsageUrl(url, errPrefix, { isRedirectTarget: isUnresolved ? 'unresolved' : true });
310
+ }
311
+ exports.assertUsageUrlRedirectTarget = assertUsageUrlRedirectTarget;
312
+ function assertUsageUrl(url, errPrefix, { allowRelative, isRedirectTarget } = {}) {
313
+ if (url.startsWith('/'))
314
+ return;
315
+ let errMsg = `${errPrefix} is ${picocolors_1.default.string(url)} but it should start with ${picocolors_1.default.string('/')}`;
316
+ if (isRedirectTarget) {
317
+ if (isUrlRedirectTarget(url))
318
+ return;
319
+ errMsg += ` or a protocol (${picocolors_1.default.string('http://')}, ${picocolors_1.default.string('mailto:')}, ...)`;
320
+ if (isRedirectTarget === 'unresolved') {
321
+ if (url === '*')
322
+ return;
323
+ errMsg += `, or be ${picocolors_1.default.string('*')}`;
324
+ }
325
+ }
326
+ if (allowRelative) {
327
+ if (isUrlPathnameRelative(url))
328
+ return;
329
+ errMsg += ', or be a relative URL';
330
+ }
331
+ (0, assert_js_1.assertUsage)(false, errMsg);
251
332
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PROJECT_VERSION = exports.projectInfo = void 0;
4
- const PROJECT_VERSION = '0.4.180';
4
+ const PROJECT_VERSION = '0.4.181';
5
5
  exports.PROJECT_VERSION = PROJECT_VERSION;
6
6
  const projectInfo = {
7
7
  projectName: 'Vike',
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.redirectHard = void 0;
4
+ function redirectHard(url) {
5
+ window.location.href = url;
6
+ }
7
+ exports.redirectHard = redirectHard;
@@ -5,7 +5,7 @@ const assert_js_1 = require("./assert.js");
5
5
  const parseUrl_js_1 = require("./parseUrl.js");
6
6
  const slice_js_1 = require("./slice.js");
7
7
  // - When doing a `.pageContext.json` HTTP request, the base URL should be preserved. (The server-side will handle the base URL.)
8
- // - While prerendering there is no base URL
8
+ // - While pre-rendering there is no base URL
9
9
  const baseServer = '/';
10
10
  exports.baseServer = baseServer;
11
11
  function urlToFile(url, fileExtension, doNotCreateExtraDirectory) {
@@ -13,7 +13,7 @@ declare function createPageContext(urlOriginal: string): Promise<{
13
13
  _onBeforeRouteHook: import("../../shared/hooks/getHook.js").Hook | null;
14
14
  _isPageContextObject: boolean;
15
15
  } & {
16
- urlParsed: import("../../shared/getPageContextUrlComputed.js").Url;
16
+ urlParsed: import("./utils.js").UrlPublic;
17
17
  urlPathname: string;
18
18
  url: string;
19
19
  }>;
@@ -1,7 +1,7 @@
1
1
  export { getPageContextFromHooks_isHydration };
2
2
  export { getPageContextFromHooks_isNotHydration };
3
3
  export { getPageContextFromHooks_serialized };
4
- import { assert, assertUsage, hasProp, objectAssign, getProjectError, serverSideRouteTo, executeHook, isObject, getGlobalObject } from './utils.js';
4
+ import { assert, assertUsage, hasProp, objectAssign, getProjectError, redirectHard, executeHook, isObject, getGlobalObject } from './utils.js';
5
5
  import { parse } from '@brillout/json-serializer/parse';
6
6
  import { getPageContextSerializedInHtml } from '../shared/getPageContextSerializedInHtml.js';
7
7
  import { analyzePageServerSide } from '../../shared/getPageFiles/analyzePageServerSide.js';
@@ -208,7 +208,7 @@ async function fetchPageContextFromServer(pageContext) {
208
208
  const isCorrect = contentType && contentType.includes(contentTypeCorrect);
209
209
  // Static hosts + page doesn't exist
210
210
  if (!isCorrect && response.status === 404) {
211
- serverSideRouteTo(pageContext.urlOriginal);
211
+ redirectHard(pageContext.urlOriginal);
212
212
  return { is404ServerSideRouted: true };
213
213
  }
214
214
  assertUsage(isCorrect, `Wrong Content-Type for ${pageContextUrl}: it should be ${contentTypeCorrect} but it's ${contentType} instead. Make sure to properly use pageContext.httpResponse.headers, see https://vike.dev/renderPage`);
@@ -1,7 +1,7 @@
1
1
  export { navigate };
2
2
  export { reload };
3
3
  import { renderPageClientSide } from './renderPageClientSide.js';
4
- import { assertClientRouting, getCurrentUrl } from './utils.js';
4
+ import { assertClientRouting, assertUsageUrlPathname, getCurrentUrl } from './utils.js';
5
5
  assertClientRouting();
6
6
  /** Programmatically navigate to a new page.
7
7
  *
@@ -12,6 +12,7 @@ assertClientRouting();
12
12
  * @param overwriteLastHistoryEntry - Don't create a new entry in the browser's history, instead let the new URL replace the current URL. (This effectively removes the current URL from the browser history).
13
13
  */
14
14
  async function navigate(url, { keepScrollPosition = false, overwriteLastHistoryEntry = false } = {}) {
15
+ assertUsageUrlPathname(url, '[navigate(url)] url');
15
16
  const scrollTarget = { preserveScroll: keepScrollPosition };
16
17
  await renderPageClientSide({
17
18
  scrollTarget,
@@ -1,6 +1,6 @@
1
1
  export { prefetch };
2
2
  export { addLinkPrefetchHandlers };
3
- import { assert, assertClientRouting, assertUsage, assertWarning, checkIfClientRouting, getGlobalObject, isExternalLink } from './utils.js';
3
+ import { assert, assertClientRouting, assertUsage, assertUsageUrlPathname, assertWarning, checkIfClientRouting, getGlobalObject } from './utils.js';
4
4
  import { isErrorFetchingStaticAssets, loadUserFilesClientSide } from '../shared/loadUserFilesClientSide.js';
5
5
  import { skipLink } from './skipLink.js';
6
6
  import { getPrefetchSettings } from './prefetch/getPrefetchSettings.js';
@@ -10,6 +10,7 @@ import { isClientSideRoutable } from './isClientSideRoutable.js';
10
10
  import { createPageContext } from './createPageContext.js';
11
11
  import { route } from '../../shared/route/index.js';
12
12
  import { noRouteMatch } from '../../shared/route/noRouteMatch.js';
13
+ import pc from '@brillout/picocolors';
13
14
  assertClientRouting();
14
15
  const globalObject = getGlobalObject('prefetch.ts', { linkPrefetchHandlerAdded: new WeakMap() });
15
16
  async function prefetchAssets(pageId, pageContext) {
@@ -36,8 +37,8 @@ async function prefetch(url) {
36
37
  assertUsage(checkIfClientRouting(), 'prefetch() only works with Client Routing, see https://vike.dev/prefetch', {
37
38
  showStackTrace: true
38
39
  });
39
- const errPrefix = `Cannot prefetch URL ${url} because it`;
40
- assertUsage(!isExternalLink(url), `${errPrefix} lives on another domain`, { showStackTrace: true });
40
+ const errPrefix = '[prefetch(url)] url';
41
+ assertUsageUrlPathname(url, errPrefix);
41
42
  if (isAlreadyPrefetched(url))
42
43
  return;
43
44
  markAsAlreadyPrefetched(url);
@@ -52,7 +53,7 @@ async function prefetch(url) {
52
53
  }
53
54
  const pageId = pageContextFromRoute._pageId;
54
55
  if (!pageId) {
55
- assertWarning(false, `${errPrefix} ${noRouteMatch}`, {
56
+ assertWarning(false, `${errPrefix} ${pc.string(url)} ${noRouteMatch}`, {
56
57
  showStackTrace: true,
57
58
  onlyOnce: false
58
59
  });
@@ -1,7 +1,7 @@
1
1
  export { renderPageClientSide };
2
2
  export { getRenderCount };
3
3
  export { disableClientRouting };
4
- import { assert, getCurrentUrl, isSameErrorMessage, objectAssign, serverSideRouteTo, getGlobalObject, executeHook, hasProp, augmentType } from './utils.js';
4
+ import { assert, getCurrentUrl, isSameErrorMessage, objectAssign, redirectHard, getGlobalObject, executeHook, hasProp, augmentType } from './utils.js';
5
5
  import { getPageContextFromHooks_isHydration, getPageContextFromHooks_isNotHydration, getPageContextFromHooks_serialized } from './getPageContextFromHooks.js';
6
6
  import { createPageContext } from './createPageContext.js';
7
7
  import { addLinkPrefetchHandlers } from './prefetch.js';
@@ -25,7 +25,7 @@ async function renderPageClientSide(renderArgs) {
25
25
  assert(isClientSideNavigation === !isHydrationRender); // isHydrationRender === (renderNumber === 1)
26
26
  assertNoInfiniteAbortLoop(pageContextsFromRewrite.length, redirectCount);
27
27
  if (globalObject.clientRoutingIsDisabled) {
28
- serverSideRouteTo(urlOriginal);
28
+ redirectHard(urlOriginal);
29
29
  return;
30
30
  }
31
31
  await renderPageNominal();
@@ -89,7 +89,7 @@ async function renderPageClientSide(renderArgs) {
89
89
  return;
90
90
  }
91
91
  if (!isClientRoutable) {
92
- serverSideRouteTo(urlOriginal);
92
+ redirectHard(urlOriginal);
93
93
  return;
94
94
  }
95
95
  assert(hasProp(pageContextFromRoute, '_pageId', 'string')); // Help TS
@@ -183,7 +183,7 @@ async function renderPageClientSide(renderArgs) {
183
183
  /* When we can't render the error page, we prefer showing a blank page over letting the server-side try because otherwise:
184
184
  - We risk running into an infinite loop of reloads which would overload the server.
185
185
  - An infinite reloading page is a even worse UX than a blank page.
186
- serverSideRouteTo(urlOriginal)
186
+ redirectHard(urlOriginal)
187
187
  */
188
188
  console.error(err);
189
189
  }
@@ -228,9 +228,9 @@ async function renderPageClientSide(renderArgs) {
228
228
  // throw redirect('/some-url')
229
229
  if (pageContextAbort._urlRedirect) {
230
230
  const urlRedirect = pageContextAbort._urlRedirect.url;
231
- if (urlRedirect.startsWith('http')) {
231
+ if (!urlRedirect.startsWith('/')) {
232
232
  // External redirection
233
- window.location.href = urlRedirect;
233
+ redirectHard(urlRedirect);
234
234
  return;
235
235
  }
236
236
  else {
@@ -408,7 +408,7 @@ function handleErrorFetchingStaticAssets(err, pageContext, isHydrationRender) {
408
408
  else {
409
409
  disableClientRouting(err, true);
410
410
  }
411
- serverSideRouteTo(pageContext.urlOriginal);
411
+ redirectHard(pageContext.urlOriginal);
412
412
  return true;
413
413
  }
414
414
  function disableClientRouting(err, log) {
@@ -1,30 +1,19 @@
1
1
  export { skipLink };
2
2
  import { getBaseServer } from './getBaseServer.js';
3
- import { assert, parseUrl, isBaseServer, isParsable, isExternalLink } from './utils.js';
3
+ import { assert, parseUrl, isBaseServer, isUrl, isUrlExternal } from './utils.js';
4
4
  function skipLink(linkTag) {
5
5
  const url = linkTag.getAttribute('href');
6
- if (url === null)
7
- return true;
8
- if (url === '')
9
- return true;
10
- if (isExternalLink(url))
11
- return true;
12
- if (isNewTabLink(linkTag))
13
- return true;
14
- if (isHashUrl(url))
15
- return true;
16
- if (!hasBaseServer(url)) {
17
- return true;
18
- }
19
- if (!isParsable(url)) {
20
- return true;
21
- }
22
- // Purposely last because disableAutomaticLinkInterception will be removed in the major release
23
- if (!isVikeLink(linkTag))
24
- return true;
25
- return false;
6
+ return (url === null ||
7
+ !isUrl(url) ||
8
+ url === '' ||
9
+ isUrlExternal(url) ||
10
+ isHashUrl(url) ||
11
+ isNewTabLink(linkTag) ||
12
+ !hasBaseServer(url) ||
13
+ // Purposely last because disableAutomaticLinkInterception will be removed in the next major release
14
+ !isVikeLink(linkTag));
26
15
  }
27
- // TODO/v1-release: remove this in favor of synchronously checking whether URL matches the route of a page (possible since Async Route Functions will be deprecated)
16
+ // TODO/next-major-release: remove this in favor of synchronously checking whether URL matches the route of a page (possible since Async Route Functions will be deprecated)
28
17
  function isVikeLink(linkTag) {
29
18
  const disableAutomaticLinkInterception = isDisableAutomaticLinkInterception();
30
19
  if (!disableAutomaticLinkInterception) {
@@ -15,11 +15,10 @@ export * from '../../utils/objectAssign.js';
15
15
  export * from '../../utils/parseUrl.js';
16
16
  export * from '../../utils/projectInfo.js';
17
17
  export * from '../../utils/PromiseType.js';
18
- export * from '../../utils/serverSideRouteTo.js';
18
+ export * from '../../utils/redirectHard.js';
19
19
  export * from '../../utils/sleep.js';
20
20
  export * from '../../utils/slice.js';
21
21
  export * from '../../utils/throttle.js';
22
22
  export * from '../../utils/assertRoutingType.js';
23
23
  export * from '../../utils/onPageVisibilityChange.js';
24
- export * from '../../utils/isExternalLink.js';
25
24
  export * from '../../utils/augmentType.js';
@@ -21,11 +21,10 @@ export * from '../../utils/objectAssign.js';
21
21
  export * from '../../utils/parseUrl.js';
22
22
  export * from '../../utils/projectInfo.js';
23
23
  export * from '../../utils/PromiseType.js';
24
- export * from '../../utils/serverSideRouteTo.js';
24
+ export * from '../../utils/redirectHard.js';
25
25
  export * from '../../utils/sleep.js';
26
26
  export * from '../../utils/slice.js';
27
27
  export * from '../../utils/throttle.js';
28
28
  export * from '../../utils/assertRoutingType.js';
29
29
  export * from '../../utils/onPageVisibilityChange.js';
30
- export * from '../../utils/isExternalLink.js';
31
30
  export * from '../../utils/augmentType.js';
@@ -153,6 +153,9 @@ async function fastGlob(userRootDir, outDirRelativeFromUserRootDir) {
153
153
  cwd: userRootDir,
154
154
  dot: false
155
155
  });
156
+ // Make build deterministic, in order to get a stable generated hash for dist/client/assets/entries/entry-client-routing.${hash}.js
157
+ // https://github.com/vikejs/vike/pull/1750
158
+ files.sort();
156
159
  return files;
157
160
  }
158
161
  // Same as getIgnoreAsFilterFn() but as glob pattern
@@ -1,11 +1,11 @@
1
1
  export { assertNoInfiniteHttpRedirect };
2
- import { assert, assertUsage, getGlobalObject, isUriWithProtocol } from '../../utils.js';
2
+ import { assert, assertUsage, getGlobalObject } from '../../utils.js';
3
3
  import pc from '@brillout/picocolors';
4
4
  const globalObject = getGlobalObject('assertNoInfiniteHttpRedirect.ts', {
5
5
  redirectGraph: {}
6
6
  });
7
7
  function assertNoInfiniteHttpRedirect(urlRedirectTarget, urlLogical) {
8
- if (isUriWithProtocol(urlRedirectTarget)) {
8
+ if (!urlRedirectTarget.startsWith('/')) {
9
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
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
@@ -14,7 +14,6 @@ function assertNoInfiniteHttpRedirect(urlRedirectTarget, urlLogical) {
14
14
  // ```
15
15
  return;
16
16
  }
17
- assert(urlRedirectTarget.startsWith('/'));
18
17
  assert(urlLogical.startsWith('/'));
19
18
  const graph = copy(globalObject.redirectGraph);
20
19
  graph[urlRedirectTarget] ?? (graph[urlRedirectTarget] = new Set());