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
@@ -10,7 +10,7 @@ export type { Config, ConfigMeta as Meta, ImportString, DataAsync, DataSync, Gua
10
10
  export type { ConfigEnv } from '../shared/page-configs/PageConfig.js';
11
11
  export type { ConfigDefinition, ConfigEffect } from '../node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js';
12
12
  export type { ConfigEntries } from '../shared/getPageFiles/getExports.js';
13
- export type { Url } from '../shared/getPageContextUrlComputed.js';
13
+ export type { UrlPublic as Url } from '../utils/parseUrl.js';
14
14
  export type { InjectFilterEntry } from '../node/runtime/html/injectAssets/getHtmlTags.js';
15
15
  export { defineConfig } from './defineConfig.js';
16
16
  import type { ConfigEnv } from '../shared/page-configs/PageConfig.js';
@@ -0,0 +1 @@
1
+ export declare const PROJECT_VERSION: "0.4.181-commit-ddcbf7d";
@@ -0,0 +1 @@
1
+ export const PROJECT_VERSION = '0.4.181-commit-ddcbf7d';
@@ -1,24 +1,57 @@
1
1
  export { parseUrl };
2
- export { isParsable };
3
- export { assertUsageUrl };
2
+ export { assertUsageUrlPathname };
3
+ export { assertUsageUrlPathnameAbsolute };
4
+ export { assertUsageUrlRedirectTarget };
5
+ export { isUrl };
6
+ export { isUri };
7
+ export { isUrlRedirectTarget };
8
+ export { isUrlExternal };
4
9
  export { isBaseServer };
5
10
  export { assertUrlComponents };
6
11
  export { createUrlFromComponents };
7
- export { isUriWithProtocol };
8
- declare function isParsable(url: string): boolean;
9
- declare function assertUsageUrl(url: unknown, errPrefix: string): asserts url is string;
10
- declare function parseUrl(url: string, baseServer: string): {
12
+ export type { UrlPublic };
13
+ export type { UrlPrivate };
14
+ type UrlPublic = {
15
+ /** The full URL. */
16
+ href: string;
17
+ /** The URL protocol, e.g. `https://` in `https://example.com` */
18
+ protocol: null | string;
19
+ /** The URL hostname, e.g. `example.com` in `https://example.com/product` and `localhost` in `http://localhost:3000/product` */
20
+ hostname: null | string;
21
+ /** The URL host port, e.g. `3000` in `http://localhost:3000/product` */
22
+ port: null | number;
23
+ /** The URL origin, e.g. `https://example.com` in `https://example.com/product/42` */
11
24
  origin: null | string;
25
+ /** The URL pathname, e.g. `/product/42` in `https://example.com/product/42?details=yes#reviews` */
12
26
  pathname: string;
27
+ /** URL pathname including the Base URL, e.g. `/some-base-url/product/42` in `https://example.com/some-base-url/product/42` (whereas `pageContext.urlParsed.pathname` is `/product/42`) */
13
28
  pathnameOriginal: string;
14
- hasBaseServer: boolean;
29
+ /** The URL search parameters, e.g. `{ details: 'yes' }` for `https://example.com/product/42?details=yes#reviews` */
15
30
  search: Record<string, string>;
31
+ /** The URL search parameters array, e.g. `{ fruit: ['apple', 'orange'] }` for `https://example.com?fruit=apple&fruit=orange` **/
16
32
  searchAll: Record<string, string[]>;
33
+ /** The URL search parameterer string, e.g. `?details=yes` in `https://example.com/product/42?details=yes#reviews` */
17
34
  searchOriginal: null | string;
35
+ /** The URL hash, e.g. `reviews` in `https://example.com/product/42?details=yes#reviews` */
18
36
  hash: string;
37
+ /** The URL hash string, e.g. `#reviews` in `https://example.com/product/42?details=yes#reviews` */
19
38
  hashOriginal: null | string;
39
+ /** @deprecated */
40
+ hashString: null | string;
41
+ /** @deprecated */
42
+ searchString: null | string;
43
+ };
44
+ type UrlPrivate = Omit<UrlPublic, 'hashString' | 'searchString'> & {
45
+ hasBaseServer: boolean;
20
46
  };
47
+ declare function parseUrl(url: string, baseServer: string): UrlPrivate;
21
48
  declare function isBaseServer(baseServer: string): boolean;
22
- declare function assertUrlComponents(url: string, origin: string | null, pathname: string, searchOriginal: string | null, hashOriginal: string | null): void;
23
- declare function createUrlFromComponents(origin: string | null, pathname: string, searchOriginal: string | null, hashOriginal: string | null): string;
24
- declare function isUriWithProtocol(str: string): boolean;
49
+ declare function assertUrlComponents(url: string, origin: string | null, pathnameOriginal: string, searchOriginal: string | null, hashOriginal: string | null): void;
50
+ declare function createUrlFromComponents(origin: string | null, pathname: string, search: string | null, hash: string | null): string;
51
+ declare function isUrl(url: string): boolean;
52
+ declare function isUrlRedirectTarget(url: string): boolean;
53
+ declare function isUrlExternal(url: string): boolean;
54
+ declare function isUri(uri: string): boolean;
55
+ declare function assertUsageUrlPathname(url: string, errPrefix: string): void;
56
+ declare function assertUsageUrlPathnameAbsolute(url: string, errPrefix: string): void;
57
+ declare function assertUsageUrlRedirectTarget(url: string, errPrefix: string, isUnresolved?: true): void;
@@ -3,38 +3,21 @@
3
3
  // - It doesn't support the tauri:// protocol
4
4
  // Unit tests at ./parseUrl.spec.ts
5
5
  export { parseUrl };
6
- export { isParsable };
7
- export { assertUsageUrl };
6
+ export { assertUsageUrlPathname };
7
+ export { assertUsageUrlPathnameAbsolute };
8
+ export { assertUsageUrlRedirectTarget };
9
+ export { isUrl };
10
+ export { isUri };
11
+ export { isUrlRedirectTarget };
12
+ export { isUrlExternal };
8
13
  export { isBaseServer };
9
14
  export { assertUrlComponents };
10
15
  export { createUrlFromComponents };
11
- export { isUriWithProtocol };
12
16
  import { slice } from './slice.js';
13
17
  import { assert, assertUsage } from './assert.js';
14
18
  import pc from '@brillout/picocolors';
15
- function isParsable(url) {
16
- // `parseUrl()` works with these URLs
17
- return (isUrlWithProtocol(url) ||
18
- url.startsWith('/') ||
19
- url.startsWith('.') ||
20
- url.startsWith('?') ||
21
- url.startsWith('#') ||
22
- url === '');
23
- }
24
- function assertUsageUrl(url, errPrefix) {
25
- assert(errPrefix.includes(' but '));
26
- assertUsage(typeof url === 'string', `${errPrefix} should be a string`);
27
- if (isParsable(url))
28
- return;
29
- if (!url.startsWith('/') && !url.includes(':')) {
30
- assertUsage(false, `${errPrefix} is ${pc.cyan(url)} and it should be /${pc.cyan(url)} instead (URL pathnames should start with a leading slash)`);
31
- }
32
- else {
33
- assertUsage(false, `${errPrefix} isn't a valid URL`);
34
- }
35
- }
36
19
  function parseUrl(url, baseServer) {
37
- assert(isParsable(url));
20
+ assert(isUrl(url), url);
38
21
  assert(baseServer.startsWith('/'));
39
22
  // Hash
40
23
  const [urlWithoutHash, ...hashList] = url.split('#');
@@ -54,18 +37,24 @@ function parseUrl(url, baseServer) {
54
37
  searchAll[key] = [...(searchAll.hasOwnProperty(key) ? searchAll[key] : []), val];
55
38
  });
56
39
  // Origin + pathname
57
- const { origin, pathname: pathnameResolved } = getPathname(urlWithoutHashNorSearch, baseServer);
58
- assert(origin === null || origin === decodeSafe(origin)); // AFAICT decoding the origin is useless
59
- assert(pathnameResolved.startsWith('/'));
60
- assert(origin === null || url.startsWith(origin));
61
- // `pathnameOriginal`
40
+ let { protocol, origin, pathnameAbsoluteWithBase } = getPathnameAbsoluteWithBase(urlWithoutHashNorSearch, baseServer);
62
41
  const pathnameOriginal = urlWithoutHashNorSearch.slice((origin || '').length);
63
42
  assertUrlComponents(url, origin, pathnameOriginal, searchOriginal, hashOriginal);
64
43
  // Base URL
65
- let { pathname, hasBaseServer } = analyzeBaseServer(pathnameResolved, baseServer);
44
+ let { pathname, hasBaseServer } = removeBaseServer(pathnameAbsoluteWithBase, baseServer);
45
+ // pageContext.urlParsed.href
46
+ const href = createUrlFromComponents(origin, pathname, searchOriginal, hashOriginal);
47
+ // pageContext.urlParsed.{hostname, port}
48
+ const host = !origin ? null : origin.slice(protocol.length);
49
+ const { hostname, port } = parseHost(host, url);
50
+ // decode after setting href
66
51
  pathname = decodePathname(pathname);
67
52
  assert(pathname.startsWith('/'));
68
53
  return {
54
+ href,
55
+ protocol,
56
+ hostname,
57
+ port,
69
58
  origin,
70
59
  pathname,
71
60
  pathnameOriginal: pathnameOriginal,
@@ -96,20 +85,20 @@ function decodePathname(urlPathname) {
96
85
  .join('/');
97
86
  return urlPathname;
98
87
  }
99
- function getPathname(url, baseServer) {
88
+ function getPathnameAbsoluteWithBase(url, baseServer) {
100
89
  // Search and hash already extracted
101
90
  assert(!url.includes('?') && !url.includes('#'));
102
91
  // url has origin
103
92
  {
104
- const { origin, pathname } = parseOrigin(url);
93
+ const { protocol, origin, pathname } = parseOrigin(url);
105
94
  if (origin) {
106
- return { origin, pathname };
95
+ return { protocol, origin, pathnameAbsoluteWithBase: pathname };
107
96
  }
108
97
  assert(pathname === url);
109
98
  }
110
99
  // url doesn't have origin
111
100
  if (url.startsWith('/')) {
112
- return { origin: null, pathname: url };
101
+ return { protocol: null, origin: null, pathnameAbsoluteWithBase: url };
113
102
  }
114
103
  else {
115
104
  // url is a relative path
@@ -124,21 +113,70 @@ function getPathname(url, baseServer) {
124
113
  else {
125
114
  base = baseServer;
126
115
  }
127
- const pathname = resolveUrlPathnameRelative(url, base);
128
- return { origin: null, pathname };
116
+ const pathnameAbsoluteWithBase = resolveUrlPathnameRelative(url, base);
117
+ return { protocol: null, origin: null, pathnameAbsoluteWithBase: pathnameAbsoluteWithBase };
129
118
  }
130
119
  }
131
120
  function parseOrigin(url) {
132
121
  if (!isUrlWithProtocol(url)) {
133
- assert(!isUriWithProtocol(url));
134
- return { pathname: url, origin: null };
122
+ return { pathname: url, origin: null, protocol: null };
135
123
  }
136
124
  else {
137
- const [originPart1, originPart2, originPart3, ...pathnameParts] = url.split('/');
138
- const origin = [originPart1, originPart2, originPart3].join('/');
139
- const pathname = ['', ...pathnameParts].join('/') || '/';
140
- return { origin, pathname };
125
+ const { protocol, uriWithoutProtocol } = parseProtocol(url);
126
+ assert(protocol);
127
+ const [host, ...rest] = uriWithoutProtocol.split('/');
128
+ const origin = protocol + host;
129
+ const pathname = '/' + rest.join('/');
130
+ return { pathname, origin, protocol };
131
+ }
132
+ }
133
+ function parseHost(host, url) {
134
+ const ret = { hostname: null, port: null };
135
+ if (!host)
136
+ return ret;
137
+ // hostname
138
+ const [hostname, ...rest] = host.split(':');
139
+ ret.hostname = hostname;
140
+ // port
141
+ if (rest.length > 0) {
142
+ assert(rest.length === 1, url);
143
+ const portStr = rest[0];
144
+ const port = parseInt(portStr, 10);
145
+ assert(port || port === 0, url);
146
+ ret.port = port;
141
147
  }
148
+ return ret;
149
+ }
150
+ function parseProtocol(uri) {
151
+ const SEP = ':';
152
+ const [before, ...after] = uri.split(SEP);
153
+ if (after.length === 0 ||
154
+ // https://github.com/vikejs/vike/commit/886a99ff21e86a8ca699a25cee7edc184aa058e4#r143308934
155
+ // https://en.wikipedia.org/wiki/List_of_URI_schemes
156
+ // https://www.rfc-editor.org/rfc/rfc7595
157
+ !/^[a-z][a-z0-9\+\-]*$/i.test(before)) {
158
+ return { protocol: null, uriWithoutProtocol: uri };
159
+ }
160
+ let protocol = before + SEP;
161
+ let uriWithoutProtocol = after.join(SEP);
162
+ const SEP2 = '//';
163
+ if (uriWithoutProtocol.startsWith(SEP2)) {
164
+ protocol = protocol + SEP2;
165
+ uriWithoutProtocol = uriWithoutProtocol.slice(SEP2.length);
166
+ }
167
+ return { protocol, uriWithoutProtocol };
168
+ }
169
+ function isUrlProtocol(protocol) {
170
+ // Is there an altenrative to having a blacklist?
171
+ // - If the blacklist becomes too big, maybe use a whitelist instead ['tauri://', 'file://', 'capacitor://', 'http://', 'https://']
172
+ const blacklist = [
173
+ // https://docs.ipfs.tech/how-to/address-ipfs-on-web
174
+ 'ipfs://',
175
+ 'ipns://'
176
+ ];
177
+ if (blacklist.includes(protocol))
178
+ return false;
179
+ return protocol.endsWith('://');
142
180
  }
143
181
  // Adapted from https://stackoverflow.com/questions/14780350/convert-relative-path-to-absolute-using-javascript/14780463#14780463
144
182
  function resolveUrlPathnameRelative(pathnameRelative, base) {
@@ -169,34 +207,15 @@ function resolveUrlPathnameRelative(pathnameRelative, base) {
169
207
  pathnameAbsolute = '/' + pathnameAbsolute;
170
208
  return pathnameAbsolute;
171
209
  }
172
- /* Not needed anymore?
173
- function assertUsageBaseServer(baseServer: string, usageErrorMessagePrefix: string = '') {
174
- assertUsage(
175
- !baseServer.startsWith('http'),
176
- usageErrorMessagePrefix +
177
- '`base` is not allowed to start with `http`. Consider using `baseAssets` instead, see https://vike.dev/base-url'
178
- )
179
- assertUsage(
180
- baseServer.startsWith('/'),
181
- usageErrorMessagePrefix + 'Wrong `base` value `' + baseServer + '`; `base` should start with `/`.'
182
- )
183
- assert(isBaseServer(baseServer))
184
- }
185
- */
186
- function assertPathname(urlPathname) {
187
- assert(urlPathname.startsWith('/'));
188
- assert(!urlPathname.includes('?'));
189
- assert(!urlPathname.includes('#'));
190
- }
191
- function analyzeBaseServer(urlPathnameWithBase, baseServer) {
192
- assertPathname(urlPathnameWithBase);
210
+ function removeBaseServer(pathnameAbsoluteWithBase, baseServer) {
211
+ assert(pathnameAbsoluteWithBase.startsWith('/'));
193
212
  assert(isBaseServer(baseServer));
194
213
  // Mutable
195
- let urlPathname = urlPathnameWithBase;
214
+ let urlPathname = pathnameAbsoluteWithBase;
196
215
  assert(urlPathname.startsWith('/'));
197
216
  assert(baseServer.startsWith('/'));
198
217
  if (baseServer === '/') {
199
- const pathname = urlPathnameWithBase;
218
+ const pathname = pathnameAbsoluteWithBase;
200
219
  return { pathname, hasBaseServer: true };
201
220
  }
202
221
  // Support `url === '/some-base-url' && baseServer === '/some-base-url/'`
@@ -206,7 +225,7 @@ function analyzeBaseServer(urlPathnameWithBase, baseServer) {
206
225
  assert(urlPathname === baseServerNormalized);
207
226
  }
208
227
  if (!urlPathname.startsWith(baseServerNormalized)) {
209
- const pathname = urlPathnameWithBase;
228
+ const pathname = pathnameAbsoluteWithBase;
210
229
  return { pathname, hasBaseServer: false };
211
230
  }
212
231
  assert(urlPathname.startsWith('/') || urlPathname.startsWith('http'));
@@ -220,27 +239,89 @@ function analyzeBaseServer(urlPathnameWithBase, baseServer) {
220
239
  function isBaseServer(baseServer) {
221
240
  return baseServer.startsWith('/');
222
241
  }
223
- function assertUrlComponents(url, origin, pathname, searchOriginal, hashOriginal) {
224
- const urlRecreated = createUrlFromComponents(origin, pathname, searchOriginal, hashOriginal);
242
+ function assertUrlComponents(url, origin, pathnameOriginal, searchOriginal, hashOriginal) {
243
+ const urlRecreated = createUrlFromComponents(origin, pathnameOriginal, searchOriginal, hashOriginal);
225
244
  assert(url === urlRecreated);
226
245
  }
227
- function createUrlFromComponents(origin, pathname, searchOriginal, hashOriginal) {
228
- const urlRecreated = `${origin || ''}${pathname}${searchOriginal || ''}${hashOriginal || ''}`;
246
+ function createUrlFromComponents(origin, pathname, search, hash) {
247
+ const urlRecreated = `${origin || ''}${pathname}${search || ''}${hash || ''}`;
229
248
  return urlRecreated;
230
249
  }
231
- function isUriWithProtocol(str) {
232
- // https://en.wikipedia.org/wiki/List_of_URI_schemes
233
- // https://www.rfc-editor.org/rfc/rfc7595
234
- // https://github.com/vikejs/vike/commit/886a99ff21e86a8ca699a25cee7edc184aa058e4#r143308934
235
- // Examples:
236
- // http://
237
- // https://
238
- // tauri:// # [Tauri](https://tauri.app)
239
- // file:// # [Electron](https://github.com/vikejs/vike/issues/1557)
240
- // capacitor:// # [Capacitor](https://github.com/vikejs/vike/issues/1706)
241
- return /^[a-z][a-z0-9\+\-]*:/i.test(str);
242
- }
243
- // Same as isUriWithProtocol() but with trailing :// which is needed for parseOrigin()
244
- function isUrlWithProtocol(str) {
245
- return /^[a-z][a-z0-9\+\-]*:\/\//i.test(str);
250
+ function isUrl(url) {
251
+ // parseUrl() works with these URLs
252
+ return isUrlWithProtocol(url) || url.startsWith('/') || isUrlPathnameRelative(url);
253
+ }
254
+ function isUrlRedirectTarget(url) {
255
+ return url.startsWith('/') || isUri(url) || isUrlWithProtocol(url);
256
+ }
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
+ /*
264
+ URL with protocol.
265
+
266
+ http://example.com
267
+ https://exmaple.com
268
+ tauri://localhost
269
+ file://example.com
270
+ capacitor://localhost/assets/chunks/chunk-DJBYDrsP.js
271
+
272
+ [Tauri](https://github.com/vikejs/vike/issues/808)
273
+ [Electron (`file://`)](https://github.com/vikejs/vike/issues/1557)
274
+ [Capacitor](https://github.com/vikejs/vike/issues/1706)
275
+ */
276
+ function isUrlWithProtocol(url) {
277
+ const { protocol } = parseProtocol(url);
278
+ return !!protocol && isUrlProtocol(protocol);
279
+ }
280
+ /*
281
+ URIs that aren't URLs.
282
+
283
+ mailto:john@example.com
284
+
285
+ ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq/wiki/Vincent_van_Gogh.html
286
+
287
+ 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
288
+
289
+ We need to treat URIs differently than URLs.
290
+ - For example, we cannot parse URIs (their structure is unknown e.g. a `magnet:` URI is completely different than a `http://` URL).
291
+ - The protocols tauri:// file:// capacitor:// follow the same structure as http:// and https:// URLs.
292
+ - Thus we can parse them like http:// and https:// URLs.
293
+ */
294
+ function isUri(uri) {
295
+ const { protocol } = parseProtocol(uri);
296
+ return !!protocol && !isUrlProtocol(uri);
297
+ }
298
+ function assertUsageUrlPathname(url, errPrefix) {
299
+ assertUsageUrl(url, errPrefix, { allowRelative: true });
300
+ }
301
+ function assertUsageUrlPathnameAbsolute(url, errPrefix) {
302
+ assertUsageUrl(url, errPrefix);
303
+ }
304
+ function assertUsageUrlRedirectTarget(url, errPrefix, isUnresolved) {
305
+ assertUsageUrl(url, errPrefix, { isRedirectTarget: isUnresolved ? 'unresolved' : true });
306
+ }
307
+ function assertUsageUrl(url, errPrefix, { allowRelative, isRedirectTarget } = {}) {
308
+ if (url.startsWith('/'))
309
+ return;
310
+ let errMsg = `${errPrefix} is ${pc.string(url)} but it should start with ${pc.string('/')}`;
311
+ if (isRedirectTarget) {
312
+ if (isUrlRedirectTarget(url))
313
+ return;
314
+ errMsg += ` or a protocol (${pc.string('http://')}, ${pc.string('mailto:')}, ...)`;
315
+ if (isRedirectTarget === 'unresolved') {
316
+ if (url === '*')
317
+ return;
318
+ errMsg += `, or be ${pc.string('*')}`;
319
+ }
320
+ }
321
+ if (allowRelative) {
322
+ if (isUrlPathnameRelative(url))
323
+ return;
324
+ errMsg += ', or be a relative URL';
325
+ }
326
+ assertUsage(false, errMsg);
246
327
  }
@@ -1,7 +1,4 @@
1
- export { projectInfo };
2
- export { PROJECT_VERSION };
3
- declare const PROJECT_VERSION: "0.4.180";
4
- declare const projectInfo: {
1
+ export declare const projectInfo: {
5
2
  projectName: "Vike";
6
- projectVersion: "0.4.180";
3
+ projectVersion: "0.4.181-commit-ddcbf7d";
7
4
  };
@@ -1,7 +1,5 @@
1
- export { projectInfo };
2
- export { PROJECT_VERSION };
3
- const PROJECT_VERSION = '0.4.180';
4
- const projectInfo = {
1
+ import { PROJECT_VERSION } from './PROJECT_VERSION.js';
2
+ export const projectInfo = {
5
3
  projectName: 'Vike',
6
4
  projectVersion: PROJECT_VERSION
7
5
  };
@@ -0,0 +1 @@
1
+ export declare function redirectHard(url: string): void;
@@ -0,0 +1,3 @@
1
+ export function redirectHard(url) {
2
+ window.location.href = url;
3
+ }
@@ -4,7 +4,7 @@ import { assert } from './assert.js';
4
4
  import { parseUrl } from './parseUrl.js';
5
5
  import { slice } from './slice.js';
6
6
  // - When doing a `.pageContext.json` HTTP request, the base URL should be preserved. (The server-side will handle the base URL.)
7
- // - While prerendering there is no base URL
7
+ // - While pre-rendering there is no base URL
8
8
  const baseServer = '/';
9
9
  function urlToFile(url, fileExtension, doNotCreateExtraDirectory) {
10
10
  const { pathnameOriginal, searchOriginal, hashOriginal } = parseUrl(url, baseServer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.180",
3
+ "version": "0.4.181-commit-ddcbf7d",
4
4
  "scripts": {
5
5
  "dev": "tsc --watch",
6
6
  "build": "rimraf dist/ && pnpm run build:esm && pnpm run build:cjs",
@@ -15,7 +15,7 @@
15
15
  "dependencies": {
16
16
  "@brillout/import": "^0.2.3",
17
17
  "@brillout/json-serializer": "^0.5.13",
18
- "@brillout/picocolors": "^1.0.13",
18
+ "@brillout/picocolors": "^1.0.14",
19
19
  "@brillout/require-shim": "^0.1.2",
20
20
  "@brillout/vite-plugin-server-entry": "^0.4.5",
21
21
  "acorn": "^8.0.0",
@@ -116,6 +116,15 @@
116
116
  "types": "./dist/esm/shared/getPageContext.d.ts",
117
117
  "default": "./dist/esm/shared/getPageContext.js"
118
118
  },
119
+ "./modifyUrl": {
120
+ "worker": "./dist/esm/shared/modifyUrl.js",
121
+ "edge-light": "./dist/esm/shared/modifyUrl.js",
122
+ "require": "./dist/cjs/shared/modifyUrl.js",
123
+ "node": "./dist/esm/shared/modifyUrl.js",
124
+ "browser": "./dist/esm/shared/modifyUrl.js",
125
+ "types": "./dist/esm/shared/modifyUrl.d.ts",
126
+ "default": "./dist/esm/shared/modifyUrl.js"
127
+ },
119
128
  "./__internal": {
120
129
  "require": "./dist/cjs/__internal/index.js",
121
130
  "node": "./dist/esm/__internal/index.js",
@@ -180,6 +189,12 @@
180
189
  "abort": [
181
190
  "./dist/esm/shared/abort.d.ts"
182
191
  ],
192
+ "getPageContext": [
193
+ "./dist/esm/shared/getPageContext.d.ts"
194
+ ],
195
+ "modifyUrl": [
196
+ "./dist/esm/shared/modifyUrl.d.ts"
197
+ ],
183
198
  "__internal": [
184
199
  "./dist/esm/__internal/index.d.ts"
185
200
  ],
@@ -196,7 +211,7 @@
196
211
  "@brillout/import": "^0.2.3",
197
212
  "@brillout/json-serializer": "^0.5.8",
198
213
  "@brillout/picocolors": "^1.0.13",
199
- "@brillout/release-me": "^0.3.8",
214
+ "@brillout/release-me": "^0.4.0",
200
215
  "@brillout/require-shim": "^0.1.2",
201
216
  "@brillout/vite-plugin-server-entry": "^0.4.0",
202
217
  "@types/estree": "^1.0.5",
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isExternalLink = void 0;
4
- function isExternalLink(url) {
5
- return !url.startsWith('/') && !url.startsWith('.') && !url.startsWith('?') && url !== '';
6
- }
7
- exports.isExternalLink = isExternalLink;
@@ -1,7 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.serverSideRouteTo = void 0;
4
- function serverSideRouteTo(url) {
5
- window.location.href = url;
6
- }
7
- exports.serverSideRouteTo = serverSideRouteTo;
@@ -1,2 +0,0 @@
1
- export { isExternalLink };
2
- declare function isExternalLink(url: string): boolean;
@@ -1,4 +0,0 @@
1
- export { isExternalLink };
2
- function isExternalLink(url) {
3
- return !url.startsWith('/') && !url.startsWith('.') && !url.startsWith('?') && url !== '';
4
- }
@@ -1,2 +0,0 @@
1
- export { serverSideRouteTo };
2
- declare function serverSideRouteTo(url: string): void;
@@ -1,4 +0,0 @@
1
- export { serverSideRouteTo };
2
- function serverSideRouteTo(url) {
3
- window.location.href = url;
4
- }