vike 0.4.180 → 0.4.181-commit-ddcbf7d

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 (68) hide show
  1. package/dist/cjs/node/plugin/plugins/envVars.js +7 -12
  2. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +3 -0
  3. package/dist/cjs/node/plugin/utils.js +1 -0
  4. package/dist/cjs/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +1 -2
  5. package/dist/cjs/{shared/route → node/runtime/renderPage}/resolveRedirects.js +9 -11
  6. package/dist/cjs/node/runtime/renderPage.js +6 -9
  7. package/dist/cjs/node/runtime/utils.js +1 -0
  8. package/dist/cjs/shared/getPageContextUrlComputed.js +43 -37
  9. package/dist/cjs/shared/modifyUrl.js +31 -0
  10. package/dist/cjs/shared/route/abort.js +4 -10
  11. package/dist/cjs/shared/route/executeOnBeforeRouteHook.js +3 -1
  12. package/dist/cjs/shared/route/utils.js +0 -1
  13. package/dist/cjs/shared/utils.js +0 -1
  14. package/dist/cjs/utils/PROJECT_VERSION.js +4 -0
  15. package/dist/cjs/utils/parseUrl.js +168 -87
  16. package/dist/cjs/utils/projectInfo.js +4 -6
  17. package/dist/cjs/utils/redirectHard.js +7 -0
  18. package/dist/cjs/utils/urlToFile.js +1 -1
  19. package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +1 -1
  20. package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +2 -2
  21. package/dist/esm/client/client-routing-runtime/navigate.js +2 -1
  22. package/dist/esm/client/client-routing-runtime/prefetch.js +5 -4
  23. package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +23 -21
  24. package/dist/esm/client/client-routing-runtime/skipLink.js +11 -22
  25. package/dist/esm/client/client-routing-runtime/utils.d.ts +2 -3
  26. package/dist/esm/client/client-routing-runtime/utils.js +2 -3
  27. package/dist/esm/client/server-routing-runtime/utils.d.ts +0 -1
  28. package/dist/esm/client/server-routing-runtime/utils.js +0 -1
  29. package/dist/esm/node/plugin/plugins/envVars.d.ts +0 -2
  30. package/dist/esm/node/plugin/plugins/envVars.js +6 -12
  31. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +3 -0
  32. package/dist/esm/node/plugin/utils.d.ts +1 -0
  33. package/dist/esm/node/plugin/utils.js +1 -0
  34. package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +2 -3
  35. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +5 -5
  36. package/dist/esm/{shared/route → node/runtime/renderPage}/resolveRedirects.js +9 -11
  37. package/dist/esm/node/runtime/renderPage.d.ts +2 -2
  38. package/dist/esm/node/runtime/renderPage.js +7 -10
  39. package/dist/esm/node/runtime/utils.d.ts +1 -0
  40. package/dist/esm/node/runtime/utils.js +1 -0
  41. package/dist/esm/shared/getPageContextUrlComputed.d.ts +2 -24
  42. package/dist/esm/shared/getPageContextUrlComputed.js +43 -37
  43. package/dist/esm/shared/modifyUrl.d.ts +14 -0
  44. package/dist/esm/shared/modifyUrl.js +28 -0
  45. package/dist/esm/shared/route/abort.js +5 -11
  46. package/dist/esm/shared/route/executeOnBeforeRouteHook.js +4 -2
  47. package/dist/esm/shared/route/utils.d.ts +0 -1
  48. package/dist/esm/shared/route/utils.js +0 -1
  49. package/dist/esm/shared/utils.d.ts +0 -1
  50. package/dist/esm/shared/utils.js +0 -1
  51. package/dist/esm/types/index.d.ts +1 -1
  52. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -0
  53. package/dist/esm/utils/PROJECT_VERSION.js +1 -0
  54. package/dist/esm/utils/parseUrl.d.ts +43 -10
  55. package/dist/esm/utils/parseUrl.js +167 -86
  56. package/dist/esm/utils/projectInfo.d.ts +2 -5
  57. package/dist/esm/utils/projectInfo.js +2 -4
  58. package/dist/esm/utils/redirectHard.d.ts +1 -0
  59. package/dist/esm/utils/redirectHard.js +3 -0
  60. package/dist/esm/utils/urlToFile.js +1 -1
  61. package/package.json +18 -3
  62. package/dist/cjs/utils/isExternalLink.js +0 -7
  63. package/dist/cjs/utils/serverSideRouteTo.js +0 -7
  64. package/dist/esm/utils/isExternalLink.d.ts +0 -2
  65. package/dist/esm/utils/isExternalLink.js +0 -4
  66. package/dist/esm/utils/serverSideRouteTo.d.ts +0 -2
  67. package/dist/esm/utils/serverSideRouteTo.js +0 -4
  68. /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,10 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PROJECT_VERSION = exports.projectInfo = void 0;
4
- const PROJECT_VERSION = '0.4.180';
5
- exports.PROJECT_VERSION = PROJECT_VERSION;
6
- const projectInfo = {
3
+ exports.projectInfo = void 0;
4
+ const PROJECT_VERSION_js_1 = require("./PROJECT_VERSION.js");
5
+ exports.projectInfo = {
7
6
  projectName: 'Vike',
8
- projectVersion: PROJECT_VERSION
7
+ projectVersion: PROJECT_VERSION_js_1.PROJECT_VERSION
9
8
  };
10
- exports.projectInfo = projectInfo;
@@ -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';
@@ -20,12 +20,14 @@ import { getErrorPageId } from '../../shared/error-page.js';
20
20
  const globalObject = getGlobalObject('renderPageClientSide.ts', { renderCounter: 0 });
21
21
  async function renderPageClientSide(renderArgs) {
22
22
  const { scrollTarget, urlOriginal = getCurrentUrl(), overwriteLastHistoryEntry = false, isBackwardNavigation, pageContextsFromRewrite = [], redirectCount = 0, isUserLandPushStateNavigation, isClientSideNavigation = true } = renderArgs;
23
- // isHydrationRender <=> the first render attempt
24
- const { isRenderOutdated, setHydrationCanBeAborted, isHydrationRender } = getIsRenderOutdated();
25
- assert(isClientSideNavigation === !isHydrationRender); // isHydrationRender === (renderNumber === 1)
23
+ const { isRenderOutdated, setHydrationCanBeAborted, isFirstRender } = getIsRenderOutdated();
24
+ // Note that pageContext.isHydration isn't equivalent to isFirstRender
25
+ // - Thus pageContext.isHydration isn't equivalent to !pageContext.isClientSideNavigation
26
+ // - `pageContext.isHydration === !isFirstRender && !isErrorPage`
27
+ assert(isClientSideNavigation === !isFirstRender);
26
28
  assertNoInfiniteAbortLoop(pageContextsFromRewrite.length, redirectCount);
27
29
  if (globalObject.clientRoutingIsDisabled) {
28
- serverSideRouteTo(urlOriginal);
30
+ redirectHard(urlOriginal);
29
31
  return;
30
32
  }
31
33
  await renderPageNominal();
@@ -64,7 +66,7 @@ async function renderPageClientSide(renderArgs) {
64
66
  }
65
67
  // Route
66
68
  let pageContextRouted;
67
- if (isHydrationRender) {
69
+ if (isFirstRender) {
68
70
  const pageContextSerialized = getPageContextFromHooks_serialized();
69
71
  pageContextRouted = pageContextSerialized;
70
72
  }
@@ -89,7 +91,7 @@ async function renderPageClientSide(renderArgs) {
89
91
  return;
90
92
  }
91
93
  if (!isClientRoutable) {
92
- serverSideRouteTo(urlOriginal);
94
+ redirectHard(urlOriginal);
93
95
  return;
94
96
  }
95
97
  assert(hasProp(pageContextFromRoute, '_pageId', 'string')); // Help TS
@@ -108,7 +110,7 @@ async function renderPageClientSide(renderArgs) {
108
110
  objectAssign(pageContext, await loadUserFilesClientSide(pageContext._pageId, pageContext._pageFilesAll, pageContext._pageConfigs));
109
111
  }
110
112
  catch (err) {
111
- if (handleErrorFetchingStaticAssets(err, pageContext, isHydrationRender)) {
113
+ if (handleErrorFetchingStaticAssets(err, pageContext, isFirstRender)) {
112
114
  return;
113
115
  }
114
116
  else {
@@ -130,7 +132,7 @@ async function renderPageClientSide(renderArgs) {
130
132
  if (isRenderOutdated())
131
133
  return;
132
134
  // Get pageContext from hooks (fetched from server, and/or directly called on the client-side)
133
- if (isHydrationRender) {
135
+ if (isFirstRender) {
134
136
  assert(hasProp(pageContext, '_hasPageContextFromServer', 'true'));
135
137
  let pageContextAugmented;
136
138
  try {
@@ -183,7 +185,7 @@ async function renderPageClientSide(renderArgs) {
183
185
  /* When we can't render the error page, we prefer showing a blank page over letting the server-side try because otherwise:
184
186
  - We risk running into an infinite loop of reloads which would overload the server.
185
187
  - An infinite reloading page is a even worse UX than a blank page.
186
- serverSideRouteTo(urlOriginal)
188
+ redirectHard(urlOriginal)
187
189
  */
188
190
  console.error(err);
189
191
  }
@@ -228,9 +230,9 @@ async function renderPageClientSide(renderArgs) {
228
230
  // throw redirect('/some-url')
229
231
  if (pageContextAbort._urlRedirect) {
230
232
  const urlRedirect = pageContextAbort._urlRedirect.url;
231
- if (urlRedirect.startsWith('http')) {
233
+ if (!urlRedirect.startsWith('/')) {
232
234
  // External redirection
233
- window.location.href = urlRedirect;
235
+ redirectHard(urlRedirect);
234
236
  return;
235
237
  }
236
238
  else {
@@ -267,7 +269,7 @@ async function renderPageClientSide(renderArgs) {
267
269
  objectAssign(pageContext, await loadUserFilesClientSide(pageContext._pageId, pageContext._pageFilesAll, pageContext._pageConfigs));
268
270
  }
269
271
  catch (err) {
270
- if (handleErrorFetchingStaticAssets(err, pageContext, isHydrationRender)) {
272
+ if (handleErrorFetchingStaticAssets(err, pageContext, isFirstRender)) {
271
273
  return;
272
274
  }
273
275
  else {
@@ -341,7 +343,7 @@ async function renderPageClientSide(renderArgs) {
341
343
  */
342
344
  addLinkPrefetchHandlers(pageContext);
343
345
  // onHydrationEnd()
344
- if (isHydrationRender && !onRenderClientError) {
346
+ if (isFirstRender && !onRenderClientError) {
345
347
  assertHook(pageContext, 'onHydrationEnd');
346
348
  const hook = getHook(pageContext, 'onHydrationEnd');
347
349
  if (hook) {
@@ -395,11 +397,11 @@ function changeUrl(url, overwriteLastHistoryEntry) {
395
397
  pushHistory(url, overwriteLastHistoryEntry);
396
398
  updateState();
397
399
  }
398
- function handleErrorFetchingStaticAssets(err, pageContext, isHydrationRender) {
400
+ function handleErrorFetchingStaticAssets(err, pageContext, isFirstRender) {
399
401
  if (!isErrorFetchingStaticAssets(err)) {
400
402
  return false;
401
403
  }
402
- if (isHydrationRender) {
404
+ if (isFirstRender) {
403
405
  disableClientRouting(err, false);
404
406
  // This may happen if the frontend was newly deployed during hydration.
405
407
  // Ideally: re-try a couple of times by reloading the page (not entirely trivial to implement since `localStorage` is needed.)
@@ -408,7 +410,7 @@ function handleErrorFetchingStaticAssets(err, pageContext, isHydrationRender) {
408
410
  else {
409
411
  disableClientRouting(err, true);
410
412
  }
411
- serverSideRouteTo(pageContext.urlOriginal);
413
+ redirectHard(pageContext.urlOriginal);
412
414
  return true;
413
415
  }
414
416
  function disableClientRouting(err, log) {
@@ -438,10 +440,10 @@ function getIsRenderOutdated() {
438
440
  };
439
441
  /** Whether the rendering should be aborted because a new rendering has started. We should call this after each `await`. */
440
442
  const isRenderOutdated = (isRenderCleanup) => {
441
- // Never abort hydration if `hydrationCanBeAborted` isn't `true`
443
+ // Never abort first render if `hydrationCanBeAborted` isn't `true`
442
444
  {
443
- const isHydration = renderNumber === 1;
444
- if (isHydration && !hydrationCanBeAborted && !isRenderCleanup) {
445
+ const isFirstRender = renderNumber === 1;
446
+ if (isFirstRender && !hydrationCanBeAborted && !isRenderCleanup) {
445
447
  return false;
446
448
  }
447
449
  }
@@ -451,7 +453,7 @@ function getIsRenderOutdated() {
451
453
  return {
452
454
  isRenderOutdated,
453
455
  setHydrationCanBeAborted,
454
- isHydrationRender: renderNumber === 1
456
+ isFirstRender: renderNumber === 1
455
457
  };
456
458
  }
457
459
  function getRenderCount() {
@@ -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) {