vike 0.4.241 → 0.4.242-commit-33026dc

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 (39) hide show
  1. package/dist/esm/node/api/build.js +6 -6
  2. package/dist/esm/node/api/dev.js +2 -2
  3. package/dist/esm/node/api/prepareViteApiCall.d.ts +2 -9
  4. package/dist/esm/node/api/prepareViteApiCall.js +4 -156
  5. package/dist/esm/node/api/prerender.js +2 -2
  6. package/dist/esm/node/api/preview.js +2 -2
  7. package/dist/esm/node/api/resolveViteConfigFromUser.d.ts +20 -0
  8. package/dist/esm/node/api/resolveViteConfigFromUser.js +207 -0
  9. package/dist/esm/node/prerender/runPrerenderEntry.js +4 -4
  10. package/dist/esm/node/runtime/logErrorServer.js +8 -1
  11. package/dist/esm/node/runtime-dev/createDevMiddleware.js +2 -2
  12. package/dist/esm/node/vite/index.d.ts +1 -1
  13. package/dist/esm/node/vite/index.js +52 -21
  14. package/dist/esm/node/vite/plugins/build/pluginBuildApp.js +6 -6
  15. package/dist/esm/node/vite/plugins/pluginCommon.d.ts +1 -1
  16. package/dist/esm/node/vite/plugins/pluginCommon.js +9 -7
  17. package/dist/esm/node/vite/plugins/pluginReplaceConstantsGlobalThis.d.ts +1 -0
  18. package/dist/esm/node/vite/plugins/pluginViteConfigVikeExtensions.d.ts +3 -0
  19. package/dist/esm/node/vite/plugins/pluginViteConfigVikeExtensions.js +32 -0
  20. package/dist/esm/node/vite/shared/isViteCli.d.ts +13 -0
  21. package/dist/esm/node/vite/shared/isViteCli.js +143 -0
  22. package/dist/esm/node/vite/shared/resolveVikeConfigInternal/transpileAndExecuteFile.js +11 -2
  23. package/dist/esm/node/vite/shared/resolveVikeConfigInternal.d.ts +2 -0
  24. package/dist/esm/node/vite/shared/resolveVikeConfigInternal.js +4 -0
  25. package/dist/esm/node/vite/utils.d.ts +1 -0
  26. package/dist/esm/node/vite/utils.js +1 -0
  27. package/dist/esm/shared/modifyUrlSameOrigin.js +2 -2
  28. package/dist/esm/shared/route/abort.js +2 -2
  29. package/dist/esm/shared/route/execHookOnBeforeRoute.js +3 -3
  30. package/dist/esm/types/index.d.ts +1 -0
  31. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  32. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  33. package/dist/esm/utils/isExactlyOneTruthy.d.ts +1 -0
  34. package/dist/esm/utils/isExactlyOneTruthy.js +4 -0
  35. package/dist/esm/utils/parseUrl.d.ts +4 -2
  36. package/dist/esm/utils/parseUrl.js +28 -25
  37. package/package.json +1 -1
  38. package/dist/esm/node/vite/shared/isViteCliCall.d.ts +0 -10
  39. package/dist/esm/node/vite/shared/isViteCliCall.js +0 -81
@@ -3,7 +3,7 @@ import { runPrerender_forceExit } from '../../../prerender/runPrerenderEntry.js'
3
3
  import { resolveOutDir } from '../../shared/getOutDirs.js';
4
4
  import { assert, assertWarning, getGlobalObject, onSetupBuild } from '../../utils.js';
5
5
  import { isPrerenderAutoRunEnabled, wasPrerenderRun } from '../../../prerender/context.js';
6
- import { isViteCliCall, getViteConfigFromCli } from '../../shared/isViteCliCall.js';
6
+ import { isViteCli, getViteConfigForBuildFromCli } from '../../shared/isViteCli.js';
7
7
  import pc from '@brillout/picocolors';
8
8
  import { logErrorHint } from '../../../runtime/renderPage/logErrorHint.js';
9
9
  import { getVikeConfigInternal } from '../../shared/resolveVikeConfigInternal.js';
@@ -142,7 +142,7 @@ async function triggerPrerendering(config, viteEnv, bundle) {
142
142
  }
143
143
  async function abortViteBuildSsr() {
144
144
  const vikeConfig = await getVikeConfigInternal();
145
- if (vikeConfig.config.disableAutoFullBuild !== true && isViteCliCall() && getViteConfigFromCli()?.build.ssr) {
145
+ if (vikeConfig.config.disableAutoFullBuild !== true && isViteCli() && getViteConfigForBuildFromCli()?.build.ssr) {
146
146
  assertWarning(false, `The CLI call ${pc.cyan('$ vite build --ssr')} is superfluous since ${pc.cyan('$ vite build')} also builds the server-side. If you want two separate build steps then use https://vike.dev/disableAutoFullBuild or use Vite's ${pc.cyan('build()')} API.`, { onlyOnce: true });
147
147
  process.exit(0);
148
148
  }
@@ -150,7 +150,7 @@ async function abortViteBuildSsr() {
150
150
  function isDisabled(vikeConfig) {
151
151
  const { disableAutoFullBuild } = vikeConfig.config;
152
152
  if (disableAutoFullBuild === undefined || disableAutoFullBuild === 'prerender') {
153
- const isUserUsingViteApi = !isViteCliCall() && !isVikeCliOrApi();
153
+ const isUserUsingViteApi = !isViteCli() && !isVikeCliOrApi();
154
154
  return isUserUsingViteApi;
155
155
  }
156
156
  else {
@@ -161,9 +161,9 @@ function isPrerenderForceExit() {
161
161
  return globalObject.forceExit;
162
162
  }
163
163
  function getFullBuildInlineConfig(config) {
164
- const configFromCli = !isViteCliCall() ? null : getViteConfigFromCli();
165
- if (config._viteConfigFromUserEnhanced) {
166
- return config._viteConfigFromUserEnhanced;
164
+ const configFromCli = !isViteCli() ? null : getViteConfigForBuildFromCli();
165
+ if (config._viteConfigFromUserResolved) {
166
+ return config._viteConfigFromUserResolved;
167
167
  }
168
168
  else {
169
169
  return {
@@ -7,7 +7,7 @@ declare module 'vite' {
7
7
  _isDev?: boolean;
8
8
  _rootResolvedEarly?: string;
9
9
  _baseViteOriginal?: string;
10
- _viteConfigFromUserEnhanced?: InlineConfig;
10
+ _viteConfigFromUserResolved?: InlineConfig;
11
11
  }
12
12
  }
13
13
  declare global {
@@ -1,13 +1,13 @@
1
1
  export { pluginCommon };
2
- import { assert, assertUsage, assertWarning, hasProp, isDevCheck, isDocker, isObject, isVitest } from '../utils.js';
2
+ import { assert, assertUsage, assertWarning, hasProp, isDevCheck, isDocker, isExactlyOneTruthy, isObject, isVitest, } from '../utils.js';
3
3
  import { assertRollupInput } from './build/pluginBuildConfig.js';
4
4
  import { installRequireShim_setUserRootDir } from '@brillout/require-shim';
5
5
  import pc from '@brillout/picocolors';
6
6
  import { assertResolveAlias } from './pluginCommon/assertResolveAlias.js';
7
- import { isViteCliCall } from '../shared/isViteCliCall.js';
7
+ import { isViteCli } from '../shared/isViteCli.js';
8
8
  import { isVikeCliOrApi } from '../../api/context.js';
9
9
  import { getVikeConfigInternal, setVikeConfigContext } from '../shared/resolveVikeConfigInternal.js';
10
- import { assertViteRoot, getViteRoot, normalizeViteRoot } from '../../api/prepareViteApiCall.js';
10
+ import { assertViteRoot, getViteRoot, normalizeViteRoot } from '../../api/resolveViteConfigFromUser.js';
11
11
  import { temp_disablePrerenderAutoRun } from '../../prerender/context.js';
12
12
  const pluginName = 'vike:pluginCommon';
13
13
  globalThis.__VIKE__IS_PROCESS_SHARED_WITH_VITE = true;
@@ -20,12 +20,14 @@ function pluginCommon(vikeVitePluginOptions) {
20
20
  order: 'pre',
21
21
  async handler(configFromUser, env) {
22
22
  const isDev = isDevCheck(env);
23
- const operation = env.command === 'build' ? 'build' : env.isPreview ? 'preview' : 'dev';
23
+ const isBuild = env.command === 'build';
24
+ const isPreview = env.isPreview;
25
+ assert(isExactlyOneTruthy(isDev, isBuild, isPreview));
26
+ const viteContext = isBuild ? 'build' : isPreview ? 'preview' : 'dev';
24
27
  const rootResolvedEarly = configFromUser.root
25
28
  ? normalizeViteRoot(configFromUser.root)
26
- : await getViteRoot(operation);
29
+ : await getViteRoot(viteContext);
27
30
  assert(rootResolvedEarly);
28
- // TO-DO/next-major-release: we can remove setVikeConfigContext() call here since with Vike's CLI it's already called at vike/node/api/prepareViteApiCall.ts
29
31
  setVikeConfigContext({ userRootDir: rootResolvedEarly, isDev, vikeVitePluginOptions });
30
32
  const vikeConfig = await getVikeConfigInternal();
31
33
  return {
@@ -132,7 +134,7 @@ function assertSingleInstance(config) {
132
134
  function assertVikeCliOrApi(config) {
133
135
  if (isVikeCliOrApi())
134
136
  return;
135
- if (isViteCliCall()) {
137
+ if (isViteCli()) {
136
138
  assert(!isVitest());
137
139
  return;
138
140
  }
@@ -1,4 +1,5 @@
1
1
  export { pluginReplaceConstantsGlobalThis };
2
+ export type _LoadDeclareGlobal__VIKE__IS = never;
2
3
  import type { Plugin } from 'vite';
3
4
  declare global {
4
5
  /** Like `import.meta.env.DEV` but works for `node_modules/` packages with `ssr.external` */
@@ -0,0 +1,3 @@
1
+ export { pluginViteConfigVikeExtensions };
2
+ import type { Plugin } from 'vite';
3
+ declare function pluginViteConfigVikeExtensions(): Promise<Plugin[]>;
@@ -0,0 +1,32 @@
1
+ export { pluginViteConfigVikeExtensions };
2
+ import { mergeConfig } from 'vite';
3
+ import { assertUsage, isObject } from '../utils.js';
4
+ import { getVikeConfigInternalEarly } from '../../api/resolveViteConfigFromUser.js';
5
+ // Apply +vite
6
+ // - For example, Vike extensions adding Vite plugins
7
+ async function pluginViteConfigVikeExtensions() {
8
+ const vikeConfig = await getVikeConfigInternalEarly();
9
+ if (vikeConfig === null)
10
+ return [];
11
+ let viteConfigFromExtensions = {};
12
+ const viteConfigsExtensions = vikeConfig._from.configsCumulative.vite;
13
+ if (!viteConfigsExtensions)
14
+ return [];
15
+ viteConfigsExtensions.values.forEach((v) => {
16
+ assertUsage(isObject(v.value), `${v.definedAt} should be an object`);
17
+ viteConfigFromExtensions = mergeConfig(viteConfigFromExtensions, v.value);
18
+ });
19
+ const pluginsFromExtensions = (viteConfigFromExtensions.plugins ?? []);
20
+ delete viteConfigFromExtensions.plugins;
21
+ return [
22
+ ...pluginsFromExtensions,
23
+ {
24
+ name: 'vike:pluginViteConfigVikeExtensions',
25
+ config: {
26
+ handler(_config) {
27
+ return viteConfigFromExtensions;
28
+ },
29
+ },
30
+ },
31
+ ];
32
+ }
@@ -0,0 +1,13 @@
1
+ export { isViteCli };
2
+ export { getViteConfigForBuildFromCli };
3
+ export { getViteCommandFromCli };
4
+ declare function isViteCli(): boolean;
5
+ type ConfigFromCli = {
6
+ root: undefined | string;
7
+ configFile: undefined | string;
8
+ } & Record<string, unknown> & {
9
+ build: Record<string, unknown>;
10
+ };
11
+ type ViteCommand = 'dev' | 'build' | 'optimize' | 'preview';
12
+ declare function getViteCommandFromCli(): ViteCommand | null;
13
+ declare function getViteConfigForBuildFromCli(): null | ConfigFromCli;
@@ -0,0 +1,143 @@
1
+ export { isViteCli };
2
+ export { getViteConfigForBuildFromCli };
3
+ export { getViteCommandFromCli };
4
+ import { assert, isObject, toPosixPath } from '../utils.js';
5
+ import { cac } from 'cac';
6
+ const desc = 'vike:vite-cli-simulation';
7
+ function isViteCli() {
8
+ let execPath = process.argv[1];
9
+ assert(execPath);
10
+ execPath = toPosixPath(execPath);
11
+ return (
12
+ // pnpm
13
+ execPath.endsWith('/bin/vite.js') ||
14
+ // npm & yarn
15
+ execPath.endsWith('/.bin/vite') ||
16
+ // Global install
17
+ execPath.endsWith('/bin/vite'));
18
+ }
19
+ function getViteCommandFromCli() {
20
+ if (!isViteCli())
21
+ return null;
22
+ let command;
23
+ const setCommand = (cmd) => {
24
+ assert(command === undefined);
25
+ command = cmd;
26
+ };
27
+ // Copied & adapted from Vite
28
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L186-L188
29
+ const cli = cac(desc);
30
+ // dev
31
+ cli
32
+ .command('[root]', desc)
33
+ .alias('serve')
34
+ .alias('dev')
35
+ .action(() => {
36
+ setCommand('dev');
37
+ });
38
+ // build
39
+ cli.command('build [root]', desc).action(() => {
40
+ setCommand('build');
41
+ });
42
+ // optimize
43
+ cli.command('optimize [root]', desc).action(() => {
44
+ setCommand('optimize');
45
+ });
46
+ // preview
47
+ cli.command('preview [root]', desc).action(() => {
48
+ setCommand('preview');
49
+ });
50
+ cli.parse();
51
+ assert(command);
52
+ return command;
53
+ }
54
+ function getViteConfigForBuildFromCli() {
55
+ if (!isViteCli())
56
+ return null;
57
+ // Copied & adapted from Vite
58
+ const cli = cac(desc);
59
+ // Common configs
60
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L169-L182
61
+ cli
62
+ .option('-c, --config <file>', desc)
63
+ .option('--base <path>', desc)
64
+ .option('-l, --logLevel <level>', desc)
65
+ .option('--clearScreen', desc)
66
+ .option('--configLoader <loader>', desc)
67
+ .option('-d, --debug [feat]', desc)
68
+ .option('-f, --filter <filter>', desc)
69
+ .option('-m, --mode <mode>', desc);
70
+ // Build configs
71
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L286-L322
72
+ cli
73
+ .command('build [root]', desc)
74
+ .option('--target <target>', desc)
75
+ .option('--outDir <dir>', desc)
76
+ .option('--assetsDir <dir>', desc)
77
+ .option('--assetsInlineLimit <number>', desc)
78
+ .option('--ssr [entry]', desc)
79
+ .option('--sourcemap', desc)
80
+ .option('--minify [minifier]', desc)
81
+ .option('--manifest [name]', desc)
82
+ .option('--ssrManifest [name]', desc)
83
+ .option('--emptyOutDir', desc)
84
+ .option('-w, --watch', desc)
85
+ .option('--app', desc)
86
+ .action((root, options) => {
87
+ assert(isObject(options));
88
+ assert(root === undefined || typeof root === 'string');
89
+ assert(options.config === undefined || typeof options.config === 'string');
90
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L331-L346
91
+ const buildOptions = cleanGlobalCLIOptions(cleanBuilderCLIOptions(options));
92
+ configFromCli = {
93
+ root,
94
+ base: options.base,
95
+ mode: options.mode,
96
+ configFile: options.config,
97
+ configLoader: options.configLoader,
98
+ logLevel: options.logLevel,
99
+ clearScreen: options.clearScreen,
100
+ build: buildOptions,
101
+ ...(options.app ? { builder: {} } : {}),
102
+ };
103
+ });
104
+ let configFromCli = null;
105
+ cli.parse();
106
+ return configFromCli;
107
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L99
108
+ function cleanGlobalCLIOptions(options) {
109
+ const ret = { ...options };
110
+ delete ret['--'];
111
+ delete ret.c;
112
+ delete ret.config;
113
+ delete ret.base;
114
+ delete ret.l;
115
+ delete ret.logLevel;
116
+ delete ret.clearScreen;
117
+ delete ret.configLoader;
118
+ delete ret.d;
119
+ delete ret.debug;
120
+ delete ret.f;
121
+ delete ret.filter;
122
+ delete ret.m;
123
+ delete ret.mode;
124
+ delete ret.force;
125
+ delete ret.w;
126
+ // convert the sourcemap option to a boolean if necessary
127
+ if ('sourcemap' in ret) {
128
+ const sourcemap = ret.sourcemap;
129
+ ret.sourcemap = sourcemap === 'true' ? true : sourcemap === 'false' ? false : ret.sourcemap;
130
+ }
131
+ if ('watch' in ret) {
132
+ const watch = ret.watch;
133
+ ret.watch = watch ? {} : undefined;
134
+ }
135
+ return ret;
136
+ }
137
+ // https://github.com/vitejs/vite/blob/d3e7eeefa91e1992f47694d16fe4dbe708c4d80e/packages/vite/src/node/cli.ts#L141
138
+ function cleanBuilderCLIOptions(options) {
139
+ const ret = { ...options };
140
+ delete ret.app;
141
+ return ret;
142
+ }
143
+ }
@@ -141,6 +141,15 @@ async function transpileWithEsbuild(filePath, userRootDir, transformImports, esb
141
141
  return resolved;
142
142
  }
143
143
  assert(resolved.path);
144
+ // Built-in modules e.g. node:fs
145
+ if (resolved.path === args.path) {
146
+ const isPointerImport = false;
147
+ pointerImports[args.path] = isPointerImport;
148
+ if (debug.isActivated)
149
+ debug('onResolve() [built-in module]', { args, resolved });
150
+ assert(resolved.external);
151
+ return resolved;
152
+ }
144
153
  const importPathResolved = toPosixPath(resolved.path);
145
154
  const importPathOriginal = args.path;
146
155
  // Esbuild resolves path aliases.
@@ -185,7 +194,7 @@ async function transpileWithEsbuild(filePath, userRootDir, transformImports, esb
185
194
  // User-land config code (i.e. not runtime code) => let esbuild transpile it
186
195
  assert(!isPointerImport && !isNpmPkgImport);
187
196
  if (debug.isActivated)
188
- debug('onResolved()', { args, resolved, isPointerImport, isExternal });
197
+ debug('onResolve() [non-external]', { args, resolved, isPointerImport, isExternal });
189
198
  return resolved;
190
199
  }
191
200
  let importPathTranspiled;
@@ -217,7 +226,7 @@ async function transpileWithEsbuild(filePath, userRootDir, transformImports, esb
217
226
  }
218
227
  }
219
228
  if (debug.isActivated)
220
- debug('onResolved()', { args, resolved, importPathTranspiled, isPointerImport, isExternal });
229
+ debug('onResolve() [external]', { args, resolved, importPathTranspiled, isPointerImport, isExternal });
221
230
  assert(isExternal);
222
231
  assert(
223
232
  // Import of runtime code => handled by Vike
@@ -4,6 +4,7 @@ export { getVikeConfigInternal };
4
4
  export { getVikeConfigInternalOptional };
5
5
  export { getVikeConfigInternalSync };
6
6
  export { setVikeConfigContext };
7
+ export { isVikeConfigContextSet };
7
8
  export { reloadVikeConfig };
8
9
  export { isV1Design };
9
10
  export { getConfVal };
@@ -45,6 +46,7 @@ declare function getVikeConfigInternalSync(): VikeConfigInternal;
45
46
  declare function getVikeConfig(config: ResolvedConfig | UserConfig): VikeConfig;
46
47
  type VikeConfig = Pick<VikeConfigInternal, 'config' | 'pages' | 'prerenderContext'>;
47
48
  declare function setVikeConfigContext(vikeConfigCtx_: VikeConfigContext): void;
49
+ declare function isVikeConfigContextSet(): boolean;
48
50
  declare function getVikeConfigInternalOptional(): Promise<null | VikeConfigInternal>;
49
51
  declare function isV1Design(): boolean;
50
52
  declare function getVikeConfigFromCliOrEnv(): {
@@ -5,6 +5,7 @@ export { getVikeConfigInternal };
5
5
  export { getVikeConfigInternalOptional };
6
6
  export { getVikeConfigInternalSync };
7
7
  export { setVikeConfigContext };
8
+ export { isVikeConfigContextSet };
8
9
  export { reloadVikeConfig };
9
10
  export { isV1Design };
10
11
  export { getConfVal };
@@ -83,6 +84,9 @@ function setVikeConfigContext(vikeConfigCtx_) {
83
84
  // If the user changes Vite's `config.root` => Vite completely reloads itself => setVikeConfigContext() is called again
84
85
  globalObject.vikeConfigCtx = vikeConfigCtx_;
85
86
  }
87
+ function isVikeConfigContextSet() {
88
+ return !!globalObject.vikeConfigCtx;
89
+ }
86
90
  async function getOrResolveVikeConfig(userRootDir, isDev, vikeVitePluginOptions, doNotRestartViteOnError) {
87
91
  if (!globalObject.vikeConfigPromise) {
88
92
  resolveVikeConfigInternal_withErrorHandling(userRootDir, isDev, vikeVitePluginOptions, doNotRestartViteOnError);
@@ -20,3 +20,4 @@ export * from '../../utils/isVitest.js';
20
20
  export * from '../../utils/rollupSourceMap.js';
21
21
  export * from '../../utils/isImportPath.js';
22
22
  export * from '../../utils/virtualFileId.js';
23
+ export * from '../../utils/isExactlyOneTruthy.js';
@@ -27,3 +27,4 @@ export * from '../../utils/isVitest.js';
27
27
  export * from '../../utils/rollupSourceMap.js';
28
28
  export * from '../../utils/isImportPath.js';
29
29
  export * from '../../utils/virtualFileId.js';
30
+ export * from '../../utils/isExactlyOneTruthy.js';
@@ -1,12 +1,12 @@
1
1
  export { modifyUrlSameOrigin };
2
2
  // We don't move modifyUrlSameOrigin() to the modifyUrl.ts file because we plan to use modifyUrlSameOrigin() on the client-side:
3
3
  // https://github.com/vikejs/vike/blob/c5a2de5e85262771f97851767c00ac35da69c64b/packages/vike/client/runtime-client-routing/navigate.ts#L4
4
- import { createUrlFromComponents, isNotNullish_keyVal, parseUrl, objectFilter, assertUsageUrlPathnameAbsolute, } from './utils.js';
4
+ import { createUrlFromComponents, isNotNullish_keyVal, parseUrl, objectFilter, assertUsageUrlPathAbsolute, } from './utils.js';
5
5
  function modifyUrlSameOrigin(url, modify) {
6
6
  const urlParsed = parseUrl(url, '/');
7
7
  // Pathname
8
8
  const pathname = modify.pathname ?? urlParsed.pathnameOriginal;
9
- assertUsageUrlPathnameAbsolute(pathname, 'modify.pathname');
9
+ assertUsageUrlPathAbsolute(pathname, 'modify.pathname');
10
10
  // Search
11
11
  let search = modify.search === null ? '' : !modify.search ? urlParsed.searchOriginal : resolveSearch(urlParsed, modify.search);
12
12
  if (search === '?')
@@ -8,7 +8,7 @@ export { getPageContextFromAllRewrites };
8
8
  export { AbortRender };
9
9
  export { assertNoInfiniteAbortLoop };
10
10
  import { isUserHookError } from '../hooks/execHook.js';
11
- import { assert, assertInfo, assertUsage, assertUsageUrlPathnameAbsolute, assertUsageUrlRedirectTarget, assertWarning, checkType, hasProp, isBrowser, joinEnglish, objectAssign, truncateString, } from './utils.js';
11
+ import { assert, assertInfo, assertUsage, assertUsageUrlPathAbsolute, assertUsageUrlRedirectTarget, assertWarning, checkType, hasProp, isBrowser, joinEnglish, objectAssign, truncateString, } from './utils.js';
12
12
  import pc from '@brillout/picocolors';
13
13
  /**
14
14
  * Abort the rendering of the current page, and redirect the user to another URL instead.
@@ -66,7 +66,7 @@ function render_(urlOrStatusCode, abortReason, abortCall, abortCaller, pageConte
66
66
  }
67
67
  if (typeof urlOrStatusCode === 'string') {
68
68
  const url = urlOrStatusCode;
69
- assertUsageUrlPathnameAbsolute(url, getErrPrefix(abortCaller));
69
+ assertUsageUrlPathAbsolute(url, getErrPrefix(abortCaller));
70
70
  objectAssign(pageContextAbort, {
71
71
  _urlRewrite: url,
72
72
  });
@@ -1,6 +1,6 @@
1
1
  export { execHookOnBeforeRoute };
2
2
  import { assertPageContextProvidedByUser } from '../assertPageContextProvidedByUser.js';
3
- import { assertUsage, hasProp, isObjectWithKeys, objectAssign, assertWarning, assertUsageUrlPathnameAbsolute, joinEnglish, assert, } from './utils.js';
3
+ import { assertUsage, hasProp, isObjectWithKeys, objectAssign, assertWarning, assertUsageUrlAbsolute, joinEnglish, assert, } from './utils.js';
4
4
  import { assertRouteParams, assertSyncRouting } from './resolveRouteFunction.js';
5
5
  import pc from '@brillout/picocolors';
6
6
  import { execHookDirectSync } from '../hooks/execHook.js';
@@ -65,8 +65,8 @@ async function getPageContextFromHook(onBeforeRouteHook, pageContext) {
65
65
  delete hookReturn.pageContext.urlOriginal;
66
66
  }
67
67
  if (hasProp(hookReturn.pageContext, 'urlLogical')) {
68
- assertUsageUrlPathnameAbsolute(
69
- // We skip validation and type-cast instead of assertUsage() in order to save client-side KBs
68
+ assertUsageUrlAbsolute(
69
+ // We type-cast instead of assertUsage() validation in order to save client-side KBs
70
70
  hookReturn.pageContext.urlLogical, `${errPrefix} returned ${pc.cyan('{ pageContext: { urlLogical } }')} and ${pc.cyan('urlLogical')}`);
71
71
  }
72
72
  assertPageContextProvidedByUser(hookReturn.pageContext, {
@@ -13,6 +13,7 @@ export type { VikeConfig } from '../node/vite/shared/resolveVikeConfigInternal.j
13
13
  export type { UrlPublic as Url } from '../utils/parseUrl.js';
14
14
  export type { InjectFilterEntry } from '../node/runtime/renderPage/html/injectAssets/getHtmlTags.js';
15
15
  export { defineConfig } from './defineConfig.js';
16
+ export type { _LoadDeclareGlobal__VIKE__IS } from '../node/vite/plugins/pluginReplaceConstantsGlobalThis.js';
16
17
  import type { ConfigEnv } from './PageConfig.js';
17
18
  /** @deprecated Replace:
18
19
  * `import type { Env } from 'vike/types'`
@@ -1 +1 @@
1
- export declare const PROJECT_VERSION: "0.4.241";
1
+ export declare const PROJECT_VERSION: "0.4.242-commit-33026dc";
@@ -1,2 +1,2 @@
1
1
  // Automatically updated by @brillout/release-me
2
- export const PROJECT_VERSION = '0.4.241';
2
+ export const PROJECT_VERSION = '0.4.242-commit-33026dc';
@@ -0,0 +1 @@
1
+ export declare function isExactlyOneTruthy(...values: unknown[]): boolean;
@@ -0,0 +1,4 @@
1
+ // Aka XOR
2
+ export function isExactlyOneTruthy(...values) {
3
+ return values.filter(Boolean).length === 1;
4
+ }
@@ -1,5 +1,6 @@
1
1
  export { parseUrl };
2
- export { assertUsageUrlPathnameAbsolute };
2
+ export { assertUsageUrlAbsolute };
3
+ export { assertUsageUrlPathAbsolute };
3
4
  export { assertUsageUrlRedirectTarget };
4
5
  export { isUrl };
5
6
  export { isUri };
@@ -52,5 +53,6 @@ declare function isUrlRedirectTarget(url: string): boolean;
52
53
  declare function isUrlRelative(url: string): boolean;
53
54
  declare function isUrlExternal(url: string): boolean;
54
55
  declare function isUri(uri: string): boolean;
55
- declare function assertUsageUrlPathnameAbsolute(url: string, errPrefix: string): void;
56
+ declare function assertUsageUrlAbsolute(url: string, errPrefix: string): void;
57
+ declare function assertUsageUrlPathAbsolute(url: string, errPrefix: string): void;
56
58
  declare function assertUsageUrlRedirectTarget(url: string, errPrefix: string, isUnresolved?: true): void;
@@ -3,7 +3,8 @@
3
3
  // - It doesn't support the tauri:// protocol
4
4
  // Unit tests at ./parseUrl.spec.ts
5
5
  export { parseUrl };
6
- export { assertUsageUrlPathnameAbsolute };
6
+ export { assertUsageUrlAbsolute };
7
+ export { assertUsageUrlPathAbsolute };
7
8
  export { assertUsageUrlRedirectTarget };
8
9
  export { isUrl };
9
10
  export { isUri };
@@ -135,7 +136,7 @@ function getBaseURI() {
135
136
  return baseURI;
136
137
  }
137
138
  function parseOrigin(url) {
138
- if (!isUrlWithProtocol(url)) {
139
+ if (!isUrlWithWebProtocol(url)) {
139
140
  return { pathname: url, origin: null, protocol: null };
140
141
  }
141
142
  else {
@@ -181,7 +182,7 @@ function parseProtocol(uri) {
181
182
  }
182
183
  return { protocol, uriWithoutProtocol };
183
184
  }
184
- function isUrlProtocol(protocol) {
185
+ function isWebUrlProtocol(protocol) {
185
186
  // Is there an alternative to having a blocklist?
186
187
  // - If the blocklist becomes too big, maybe use a allowlist instead ['tauri://', 'file://', 'capacitor://', 'http://', 'https://']
187
188
  const blocklist = [
@@ -264,10 +265,16 @@ function createUrlFromComponents(origin, pathname, search, hash) {
264
265
  }
265
266
  function isUrl(url) {
266
267
  // parseUrl() works with these URLs
267
- return isUrlWithProtocol(url) || url.startsWith('/') || isUrlRelative(url);
268
+ return isUrlAbsolute(url) || isUrlRelative(url);
268
269
  }
269
270
  function isUrlRedirectTarget(url) {
270
- return url.startsWith('/') || isUri(url) || isUrlWithProtocol(url);
271
+ return isUrlAbsolute(url) || isUri(url);
272
+ }
273
+ function isUrlAbsolute(url) {
274
+ return isUrlPathAbsolute(url) || isUrlWithWebProtocol(url);
275
+ }
276
+ function isUrlPathAbsolute(url) {
277
+ return url.startsWith('/');
271
278
  }
272
279
  function isUrlRelative(url) {
273
280
  return ['.', '?', '#'].some((c) => url.startsWith(c)) || url === '';
@@ -288,9 +295,9 @@ URL with protocol.
288
295
  [Electron (`file://`)](https://github.com/vikejs/vike/issues/1557)
289
296
  [Capacitor](https://github.com/vikejs/vike/issues/1706)
290
297
  */
291
- function isUrlWithProtocol(url) {
298
+ function isUrlWithWebProtocol(url) {
292
299
  const { protocol } = parseProtocol(url);
293
- return !!protocol && isUrlProtocol(protocol);
300
+ return !!protocol && isWebUrlProtocol(protocol);
294
301
  }
295
302
  /*
296
303
  URIs that aren't URLs.
@@ -308,27 +315,23 @@ We need to treat URIs differently than URLs.
308
315
  */
309
316
  function isUri(uri) {
310
317
  const { protocol } = parseProtocol(uri);
311
- return !!protocol && !isUrlProtocol(uri);
318
+ return !!protocol && !isWebUrlProtocol(protocol);
319
+ }
320
+ function assertUsageUrlAbsolute(url, errPrefix) {
321
+ assertUsage(isUrlAbsolute(url), getErrMsg(url, errPrefix, true));
312
322
  }
313
- function assertUsageUrlPathnameAbsolute(url, errPrefix) {
314
- assertUsageUrl(url, errPrefix);
323
+ function assertUsageUrlPathAbsolute(url, errPrefix) {
324
+ assertUsage(isUrlPathAbsolute(url), getErrMsg(url, errPrefix));
315
325
  }
316
326
  function assertUsageUrlRedirectTarget(url, errPrefix, isUnresolved) {
317
- assertUsageUrl(url, errPrefix, { isRedirectTarget: isUnresolved ? 'unresolved' : true });
327
+ const errMsg = getErrMsg(url, errPrefix, true, isUnresolved);
328
+ assertUsage(isUrlRedirectTarget(url) || (isUnresolved && url === '*'), errMsg);
318
329
  }
319
- function assertUsageUrl(url, errPrefix, { isRedirectTarget } = {}) {
320
- if (url.startsWith('/'))
321
- return;
330
+ function getErrMsg(url, errPrefix, allowProtocol, allowUri) {
322
331
  let errMsg = `${errPrefix} is ${pc.string(url)} but it should start with ${pc.string('/')}`;
323
- if (isRedirectTarget) {
324
- if (isUrlRedirectTarget(url))
325
- return;
326
- errMsg += ` or a protocol (${pc.string('http://')}, ${pc.string('mailto:')}, ...)`;
327
- if (isRedirectTarget === 'unresolved') {
328
- if (url === '*')
329
- return;
330
- errMsg += `, or be ${pc.string('*')}`;
331
- }
332
- }
333
- assertUsage(false, errMsg);
332
+ if (allowProtocol)
333
+ errMsg += ` or a protocol (e.g. ${pc.string('http://')})`;
334
+ if (allowUri)
335
+ errMsg += `, or be ${pc.string('*')}`;
336
+ return errMsg;
334
337
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.241",
3
+ "version": "0.4.242-commit-33026dc",
4
4
  "repository": "https://github.com/vikejs/vike",
5
5
  "exports": {
6
6
  "./server": {
@@ -1,10 +0,0 @@
1
- export { isViteCliCall };
2
- export { getViteConfigFromCli };
3
- declare function isViteCliCall(): boolean;
4
- type ConfigFromCli = {
5
- root: undefined | string;
6
- configFile: undefined | string;
7
- } & Record<string, unknown> & {
8
- build: Record<string, unknown>;
9
- };
10
- declare function getViteConfigFromCli(): null | ConfigFromCli;