vike 0.4.225-commit-37a36a5 → 0.4.225-commit-2b7971f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/cjs/client/shared/getPageContextProxyForUser.js +3 -66
  2. package/dist/cjs/node/api/prepareViteApiCall.js +22 -12
  3. package/dist/cjs/node/plugin/plugins/commonConfig.js +0 -6
  4. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +1 -1
  5. package/dist/cjs/node/prerender/resolvePrerenderConfig.js +3 -3
  6. package/dist/cjs/node/prerender/runPrerender.js +6 -10
  7. package/dist/cjs/node/runtime/html/serializePageContextClientSide.js +67 -14
  8. package/dist/cjs/node/runtime/renderPage/preparePageContextForUserConsumptionServerSide.js +3 -0
  9. package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +18 -12
  10. package/dist/cjs/node/runtime/renderPage.js +13 -28
  11. package/dist/cjs/shared/NOT_SERIALIZABLE.js +5 -0
  12. package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
  13. package/dist/cjs/utils/assert.js +1 -1
  14. package/dist/cjs/utils/objectAssign.js +7 -2
  15. package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +2 -0
  16. package/dist/esm/client/client-routing-runtime/createPageContext.js +2 -1
  17. package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +1 -1
  18. package/dist/esm/client/server-routing-runtime/getPageContext.d.ts +6 -3
  19. package/dist/esm/client/server-routing-runtime/getPageContext.js +6 -3
  20. package/dist/esm/client/shared/getPageContextProxyForUser.d.ts +1 -11
  21. package/dist/esm/client/shared/getPageContextProxyForUser.js +4 -67
  22. package/dist/esm/client/shared/preparePageContextForUserConsumptionClientSide.d.ts +2 -2
  23. package/dist/esm/node/api/prepareViteApiCall.js +22 -12
  24. package/dist/esm/node/plugin/plugins/commonConfig.js +0 -6
  25. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +1 -1
  26. package/dist/esm/node/prerender/resolvePrerenderConfig.js +3 -3
  27. package/dist/esm/node/prerender/runPrerender.js +6 -10
  28. package/dist/esm/node/runtime/html/serializePageContextClientSide.d.ts +2 -0
  29. package/dist/esm/node/runtime/html/serializePageContextClientSide.js +69 -15
  30. package/dist/esm/node/runtime/renderPage/preparePageContextForUserConsumptionServerSide.js +3 -0
  31. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +27 -1
  32. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +18 -12
  33. package/dist/esm/node/runtime/renderPage.js +14 -29
  34. package/dist/esm/shared/NOT_SERIALIZABLE.d.ts +1 -0
  35. package/dist/esm/shared/NOT_SERIALIZABLE.js +2 -0
  36. package/dist/esm/shared/page-configs/Config.d.ts +5 -3
  37. package/dist/esm/shared/page-configs/PageConfig.d.ts +1 -1
  38. package/dist/esm/shared/route/abort.d.ts +2 -2
  39. package/dist/esm/shared/types.d.ts +34 -2
  40. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  41. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  42. package/dist/esm/utils/assert.js +1 -1
  43. package/dist/esm/utils/objectAssign.d.ts +1 -1
  44. package/dist/esm/utils/objectAssign.js +7 -2
  45. package/package.json +1 -1
  46. package/dist/cjs/shared/notSerializable.js +0 -5
  47. package/dist/esm/shared/notSerializable.d.ts +0 -1
  48. package/dist/esm/shared/notSerializable.js +0 -2
@@ -2,78 +2,15 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getPageContextProxyForUser = getPageContextProxyForUser;
4
4
  const utils_js_1 = require("../server-routing-runtime/utils.js");
5
- const notSerializable_js_1 = require("../../shared/notSerializable.js");
6
- const globalObject = (0, utils_js_1.getGlobalObject)('shared/getPageContextProxyForUser.ts', {});
7
- /**
8
- * Throw error when pageContext value isn't:
9
- * - serializable, or
10
- * - defined.
11
- */
5
+ const NOT_SERIALIZABLE_js_1 = require("../../shared/NOT_SERIALIZABLE.js");
6
+ // Throw error when pageContext value isn't serializable
12
7
  function getPageContextProxyForUser(pageContext) {
13
- (0, utils_js_1.assert)([true, false].includes(pageContext._hasPageContextFromServer));
14
- (0, utils_js_1.assert)([true, false].includes(pageContext._hasPageContextFromClient));
15
8
  return new Proxy(pageContext, {
16
9
  get(_, prop) {
17
10
  const val = pageContext[prop];
18
11
  const propName = (0, utils_js_1.getPropAccessNotation)(prop);
19
- (0, utils_js_1.assertUsage)(val !== notSerializable_js_1.notSerializable, `Can't access pageContext${propName} on the client side. Because it can't be serialized, see server logs.`);
20
- passToClientHint(pageContext, prop, propName);
12
+ (0, utils_js_1.assertUsage)(val !== NOT_SERIALIZABLE_js_1.NOT_SERIALIZABLE, `Can't access pageContext${propName} on the client side. Because it can't be serialized, see server logs.`);
21
13
  return val;
22
14
  }
23
15
  });
24
16
  }
25
- function passToClientHint(pageContext, prop, propName) {
26
- if (handleVueReactivity(prop))
27
- return;
28
- // `prop in pageContext` is the trick we use to know the passToClient value on the client-side, as we set a value to all passToClient props, even `undefined` ones:
29
- // ```html
30
- // <script id="vike_pageContext" type="application/json">{"pageProps":"!undefined"}</script>
31
- // ```
32
- if (prop in pageContext)
33
- return;
34
- if (isWhitelisted(prop))
35
- return;
36
- // The trick described above (`prop in pageContext`) doesn't work if Vike doesn't fetch any pageContext from the server.
37
- // - There would still be some value to show a warning, but it isn't worth it because of the confusion that the first recommendation (adding `prop` to `passToClient`) wouldn't actually remove the warning, and only the second recommendation (using `prop in pageContext` instead of `pageContext[prop]`) would work.
38
- if (!pageContext._hasPageContextFromServer)
39
- return;
40
- const errMsg = `pageContext${propName} isn't defined on the client-side, see https://vike.dev/passToClient#error`;
41
- if (
42
- // TODO/next-major-release always make it an error.
43
- // - Remove pageContext._hasPageContextFromClient logic (IIRC this is its only use case).
44
- pageContext._hasPageContextFromClient) {
45
- (0, utils_js_1.assertWarning)(false, errMsg, { onlyOnce: false, showStackTrace: true });
46
- }
47
- else {
48
- (0, utils_js_1.assertUsage)(false, errMsg);
49
- }
50
- }
51
- const WHITELIST = [
52
- 'then',
53
- // Vue calls toJSON()
54
- 'toJSON'
55
- ];
56
- function isWhitelisted(prop) {
57
- if (WHITELIST.includes(prop))
58
- return true;
59
- if (typeof prop === 'symbol')
60
- return true; // Vue tries to access some symbols
61
- if (typeof prop !== 'string')
62
- return true;
63
- if (prop.startsWith('__v_'))
64
- return true; // Vue internals upon `reactive(pageContext)`
65
- return false;
66
- }
67
- // Handle Vue's reactivity.
68
- // When changing a reactive object:
69
- // - Vue tries to read its old value first. This triggers a `assertIsDefined()` failure if e.g. `pageContextReactive.routeParams = pageContextNew.routeParams` and `pageContextReactive` has no `routeParams`.
70
- // - Vue seems to read __v_raw before reading the property.
71
- function handleVueReactivity(prop) {
72
- if (globalObject.prev === prop || globalObject.prev === '__v_raw')
73
- return true;
74
- globalObject.prev = prop;
75
- window.setTimeout(() => {
76
- globalObject.prev = undefined;
77
- }, 0);
78
- return false;
79
- }
@@ -47,6 +47,7 @@ const path_1 = __importDefault(require("path"));
47
47
  const utils_js_1 = require("./utils.js");
48
48
  const picocolors_1 = __importDefault(require("@brillout/picocolors"));
49
49
  const globalContext_js_1 = require("../runtime/globalContext.js");
50
+ const getEnvVarObject_js_1 = require("../plugin/shared/getEnvVarObject.js");
50
51
  const globalObject = (0, utils_js_1.getGlobalObject)('api/prepareViteApiCall.ts', {});
51
52
  async function prepareViteApiCall(options, operation) {
52
53
  clear();
@@ -60,7 +61,7 @@ function clear() {
60
61
  (0, globalContext_js_1.clearGlobalContext)();
61
62
  }
62
63
  async function enhanceViteConfig(viteConfigFromOptions, operation) {
63
- const viteInfo = await getInfoFromVite(viteConfigFromOptions, operation);
64
+ const viteInfo = await getViteInfo(viteConfigFromOptions, operation);
64
65
  await assertViteRoot2(viteInfo.root, viteInfo.viteConfigEnhanced, operation);
65
66
  const vikeConfig = await (0, getVikeConfig_js_1.getVikeConfig2)(viteInfo.root, operation === 'dev', viteInfo.vikeVitePluginOptions);
66
67
  const viteConfigEnhanced = addViteSettingsSetByVikeConfig(viteInfo.viteConfigEnhanced, vikeConfig);
@@ -82,21 +83,30 @@ function addViteSettingsSetByVikeConfig(viteConfigEnhanced, vikeConfig) {
82
83
  }
83
84
  async function getViteRoot(operation) {
84
85
  if (!globalObject.root)
85
- await getInfoFromVite(undefined, operation);
86
+ await getViteInfo(undefined, operation);
86
87
  (0, utils_js_1.assert)(globalObject.root);
87
88
  return globalObject.root;
88
89
  }
89
- async function getInfoFromVite(viteConfigFromOptions, operation) {
90
- const viteConfigFromUserViteFile = await loadViteConfigFile(viteConfigFromOptions, operation);
91
- const root = normalizeViteRoot(
92
- // `viteConfigFromOptions.root` before `viteConfigFromUserViteFile.root` replicates Vite's precedence:
90
+ async function getViteInfo(viteConfigFromOptions, operation) {
91
+ let viteConfigEnhanced = viteConfigFromOptions;
92
+ // Precedence:
93
+ // - viteConfigFromUserEnvVar (highest precendence)
94
+ // - viteConfigFromOptions
95
+ // - viteConfigFromUserViteFile (lowest precendence)
96
+ const viteConfigFromUserEnvVar = (0, getEnvVarObject_js_1.getEnvVarObject)('VITE_CONFIG');
97
+ if (viteConfigFromUserEnvVar)
98
+ viteConfigEnhanced = (0, vite_1.mergeConfig)(viteConfigEnhanced ?? {}, viteConfigFromUserEnvVar);
99
+ const viteConfigFromUserViteFile = await loadViteConfigFile(viteConfigEnhanced, operation);
100
+ // Correct precedence, replicates Vite:
93
101
  // https://github.com/vitejs/vite/blob/4f5845a3182fc950eb9cd76d7161698383113b18/packages/vite/src/node/config.ts#L1001
94
- viteConfigFromOptions?.root ?? viteConfigFromUserViteFile?.root ?? process.cwd());
102
+ const viteConfigResolved = (0, vite_1.mergeConfig)(viteConfigFromUserViteFile ?? {}, viteConfigEnhanced ?? {});
103
+ const root = normalizeViteRoot(viteConfigResolved.root ?? process.cwd());
95
104
  globalObject.root = root;
105
+ // - Find options `vike(options)` set in vite.config.js
106
+ // - TODO/next-major: remove
107
+ // - Add Vike's Vite plugin if missing
96
108
  let vikeVitePluginOptions;
97
- let viteConfigEnhanced = viteConfigFromOptions;
98
- // If Vike's Vite plugin is found in both viteConfigFromOptions and viteConfigFromUserViteFile then Vike will later throw an error
99
- const found = findVikeVitePlugin(viteConfigFromOptions) || findVikeVitePlugin(viteConfigFromUserViteFile);
109
+ const found = findVikeVitePlugin(viteConfigResolved);
100
110
  if (found) {
101
111
  vikeVitePluginOptions = found.vikeVitePluginOptions;
102
112
  }
@@ -105,8 +115,8 @@ async function getInfoFromVite(viteConfigFromOptions, operation) {
105
115
  // Using a dynamic import because the script calling the Vike API may not live in the same place as vite.config.js, thus vike/plugin may resolved to two different node_modules/vike directories.
106
116
  const { plugin: vikePlugin } = await Promise.resolve().then(() => __importStar(require('../plugin/index.js')));
107
117
  viteConfigEnhanced = {
108
- ...viteConfigFromOptions,
109
- plugins: [...(viteConfigFromOptions?.plugins ?? []), vikePlugin()]
118
+ ...viteConfigEnhanced,
119
+ plugins: [...(viteConfigEnhanced?.plugins ?? []), vikePlugin()]
110
120
  };
111
121
  const res = findVikeVitePlugin(viteConfigEnhanced);
112
122
  (0, utils_js_1.assert)(res);
@@ -5,14 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.commonConfig = commonConfig;
7
7
  exports.getVikeConfigPublic = getVikeConfigPublic;
8
- const vite_1 = require("vite");
9
8
  const utils_js_1 = require("../utils.js");
10
9
  const pluginBuildConfig_js_1 = require("./build/pluginBuildConfig.js");
11
10
  const require_shim_1 = require("@brillout/require-shim");
12
11
  const picocolors_1 = __importDefault(require("@brillout/picocolors"));
13
12
  const path_1 = __importDefault(require("path"));
14
13
  const assertResolveAlias_js_1 = require("./commonConfig/assertResolveAlias.js");
15
- const getEnvVarObject_js_1 = require("../shared/getEnvVarObject.js");
16
14
  const isViteCliCall_js_1 = require("../shared/isViteCliCall.js");
17
15
  const context_js_1 = require("../../api/context.js");
18
16
  const getVikeConfig_js_1 = require("./importUserCode/v1-design/getVikeConfig.js");
@@ -96,10 +94,6 @@ function commonConfig(vikeVitePluginOptions) {
96
94
  // Set `--host` for Docker/Podman
97
95
  setDefault('host', true, configFromUser, configFromVike);
98
96
  }
99
- // VITE_CONFIG
100
- const configFromEnvVar = (0, getEnvVarObject_js_1.getEnvVarObject)('VITE_CONFIG');
101
- if (configFromEnvVar)
102
- configFromVike = (0, vite_1.mergeConfig)(configFromVike, configFromEnvVar);
103
97
  return configFromVike;
104
98
  }
105
99
  }
@@ -310,7 +310,7 @@ function assertGlobalConfigLocation(configName, sources, plusFilesAll, configDef
310
310
  : 'to a value that is global';
311
311
  const what = isConditionallyGlobal ? 'global values' : picocolors_1.default.cyan(configName);
312
312
  const errEnd = configFilePathsGlobal.length > 0
313
- ? `define ${what} at a global config file such as ${(0, utils_js_1.joinEnglish)(configFilePathsGlobal, 'or')} instead`
313
+ ? `define ${what} at a global config file such as ${(0, utils_js_1.joinEnglish)(configFilePathsGlobal.map(picocolors_1.default.bold), 'or')} instead`
314
314
  : `create a global config file (e.g. /pages/+config.js) and define ${what} there instead`;
315
315
  // When updating this error message => also update error message at https://vike.dev/warning/global-config
316
316
  const errMsg = `${errBeg} ${errMid}: ${errEnd} (https://vike.dev/warning/global-config).`;
@@ -17,8 +17,8 @@ function resolvePrerenderConfigGlobal(vikeConfig) {
17
17
  };
18
18
  let defaultLocalValue = false;
19
19
  {
20
- const valueFirst = prerenderConfigs.filter((p) => !(0, utils_js_1.isObject)(p) || p.value !== null)[0];
21
- if (valueFirst === true || ((0, utils_js_1.isObject)(valueFirst) && (valueFirst.value ?? defaultValueForObject))) {
20
+ const valueFirst = prerenderConfigs.filter((p) => !(0, utils_js_1.isObject)(p) || p.enable !== null)[0];
21
+ if (valueFirst === true || ((0, utils_js_1.isObject)(valueFirst) && (valueFirst.enable ?? defaultValueForObject))) {
22
22
  defaultLocalValue = true;
23
23
  }
24
24
  }
@@ -49,7 +49,7 @@ function resolvePrerenderConfigLocal(pageConfig) {
49
49
  const values = configValue.value;
50
50
  (0, utils_js_1.assert)((0, utils_js_1.isArray)(values));
51
51
  const value = values[0];
52
- // TODO/now I believe this assert() can fail
52
+ // If it's set to an object in a local config then Vike considers it a global config and it's skipped from local inheritance, thus we can assume the value to be a boolean.
53
53
  (0, utils_js_1.assert)(typeof value === 'boolean');
54
54
  (0, utils_js_1.assert)((0, utils_js_1.isArray)(configValue.definedAtData));
55
55
  const prerenderConfigLocal = { value };
@@ -342,20 +342,16 @@ async function handlePagesWithStaticRoutes(prerenderContext, globalContext, doNo
342
342
  })));
343
343
  }
344
344
  async function createPageContext(urlOriginal, prerenderContext, globalContext) {
345
- const pageContext = {
345
+ const pageContextInit = { urlOriginal };
346
+ (0, utils_js_1.objectAssign)(pageContextInit, prerenderContext.pageContextInit);
347
+ const pageContext = await (0, renderPageAlreadyRouted_js_1.getPageContextInitEnhanced)(pageContextInit, globalContext, true, {});
348
+ (0, utils_js_1.assert)(pageContext.isPrerendering === true);
349
+ (0, utils_js_1.objectAssign)(pageContext, {
346
350
  _urlHandler: null,
347
351
  _urlRewrite: null,
348
352
  _noExtraDir: prerenderContext.noExtraDir,
349
353
  _prerenderContext: prerenderContext
350
- };
351
- const pageContextInit = {
352
- urlOriginal
353
- };
354
- (0, utils_js_1.objectAssign)(pageContextInit, prerenderContext.pageContextInit);
355
- {
356
- const pageContextInitEnhanced = await (0, renderPageAlreadyRouted_js_1.getPageContextInitEnhanced)(pageContextInit, globalContext);
357
- (0, utils_js_1.objectAssign)(pageContext, pageContextInitEnhanced);
358
- }
354
+ });
359
355
  return pageContext;
360
356
  }
361
357
  async function callOnPrerenderStartHook(prerenderContext, globalContext) {
@@ -5,12 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.serializePageContextClientSide = serializePageContextClientSide;
7
7
  exports.serializePageContextAbort = serializePageContextAbort;
8
+ exports.getPropKeys = getPropKeys;
8
9
  const stringify_1 = require("@brillout/json-serializer/stringify");
9
10
  const utils_js_1 = require("../utils.js");
10
11
  const error_page_js_1 = require("../../../shared/error-page.js");
11
12
  const addIs404ToPageProps_js_1 = require("../../../shared/addIs404ToPageProps.js");
12
13
  const picocolors_1 = __importDefault(require("@brillout/picocolors"));
13
- const notSerializable_js_1 = require("../../../shared/notSerializable.js");
14
+ const NOT_SERIALIZABLE_js_1 = require("../../../shared/NOT_SERIALIZABLE.js");
14
15
  const pageContextInitIsPassedToClient_js_1 = require("../../../shared/misc/pageContextInitIsPassedToClient.js");
15
16
  const isServerSideError_js_1 = require("../../../shared/misc/isServerSideError.js");
16
17
  const PASS_TO_CLIENT = [
@@ -30,12 +31,8 @@ const PASS_TO_CLIENT = [
30
31
  const PASS_TO_CLIENT_ERROR_PAGE = ['pageProps', 'is404', isServerSideError_js_1.isServerSideError];
31
32
  function serializePageContextClientSide(pageContext) {
32
33
  const passToClient = getPassToClient(pageContext);
33
- const pageContextClient = {};
34
- passToClient.forEach((prop) => {
35
- // We set non-existing props to `undefined`, in order to pass the list of passToClient values to the client-side
36
- pageContextClient[prop] = pageContext[prop];
37
- });
38
- if (Object.keys(pageContext._pageContextInit).some((p) => passToClient.includes(p))) {
34
+ const pageContextClient = applyPassToClient(passToClient, pageContext);
35
+ if (passToClient.some((prop) => getPropVal(pageContext._pageContextInit, prop))) {
39
36
  pageContextClient[pageContextInitIsPassedToClient_js_1.pageContextInitIsPassedToClient] = true;
40
37
  }
41
38
  let pageContextSerialized;
@@ -47,14 +44,15 @@ function serializePageContextClientSide(pageContext) {
47
44
  let hasWarned = false;
48
45
  const propsNonSerializable = [];
49
46
  passToClient.forEach((prop) => {
50
- const propName1 = (0, utils_js_1.getPropAccessNotation)(prop);
51
- const propName2 = JSON.stringify(prop);
52
- const varName = `pageContext${propName1}`;
47
+ const res = getPropVal(pageContext, prop);
48
+ if (!res)
49
+ return;
50
+ const { value } = res;
51
+ const varName = `pageContext${getPropKeys(prop).map(utils_js_1.getPropAccessNotation).join('')}`;
53
52
  try {
54
- serialize(pageContext[prop], varName);
53
+ serialize(value, varName);
55
54
  }
56
55
  catch (err) {
57
- hasWarned = true;
58
56
  propsNonSerializable.push(prop);
59
57
  // useConfig() wrong usage
60
58
  if (prop === '_configFromHook') {
@@ -67,7 +65,7 @@ function serializePageContextClientSide(pageContext) {
67
65
  // Non-serializable pageContext set by the user
68
66
  let msg = [
69
67
  `${h(varName)} can't be serialized and, therefore, can't be passed to the client side.`,
70
- `Make sure ${h(varName)} is serializable, or remove ${h(propName2)} from ${h('passToClient')}.`
68
+ `Make sure ${h(varName)} is serializable, or remove ${h(JSON.stringify(prop))} from ${h('passToClient')}.`
71
69
  ].join(' ');
72
70
  if ((0, stringify_1.isJsonSerializerError)(err)) {
73
71
  msg = `${msg} Serialization error: ${err.messageCore}.`;
@@ -80,11 +78,12 @@ function serializePageContextClientSide(pageContext) {
80
78
  }
81
79
  // We warn (instead of throwing an error) since Vike's client runtime throws an error (with `assertUsage()`) if the user's client code tries to access the property that cannot be serialized
82
80
  (0, utils_js_1.assertWarning)(false, msg, { onlyOnce: false });
81
+ hasWarned = true;
83
82
  }
84
83
  });
85
84
  (0, utils_js_1.assert)(hasWarned);
86
85
  propsNonSerializable.forEach((prop) => {
87
- pageContextClient[prop] = notSerializable_js_1.notSerializable;
86
+ pageContextClient[getPropKeys(prop)[0]] = NOT_SERIALIZABLE_js_1.NOT_SERIALIZABLE;
88
87
  });
89
88
  try {
90
89
  pageContextSerialized = serialize(pageContextClient);
@@ -143,3 +142,57 @@ function serializePageContextAbort(pageContext) {
143
142
  }
144
143
  return serialize(pageContext);
145
144
  }
145
+ function applyPassToClient(passToClient, pageContext) {
146
+ const pageContextClient = {};
147
+ passToClient.forEach((prop) => {
148
+ // Get value from pageContext
149
+ const res = getPropVal(pageContext, prop);
150
+ if (!res)
151
+ return;
152
+ const { value } = res;
153
+ // Set value to pageContextClient
154
+ setPropVal(pageContextClient, prop, value);
155
+ });
156
+ return pageContextClient;
157
+ }
158
+ // Get a nested property from an object using a dot-separated path such as 'user.id'
159
+ function getPropVal(obj, prop) {
160
+ const keys = getPropKeys(prop);
161
+ let value = obj;
162
+ for (const key of keys) {
163
+ if ((0, utils_js_1.isObject)(value) && key in value) {
164
+ value = value[key];
165
+ }
166
+ else {
167
+ return null; // Property or intermediate property doesn't exist
168
+ }
169
+ }
170
+ return { value };
171
+ }
172
+ // Set a nested property in an object using a dot-separated path such as 'user.id'
173
+ function setPropVal(obj, prop, val) {
174
+ const keys = getPropKeys(prop);
175
+ let currentObj = obj;
176
+ // Creating intermediate objects if necessary
177
+ for (let i = 0; i <= keys.length - 2; i++) {
178
+ const key = keys[i];
179
+ if (!(key in currentObj)) {
180
+ // Create intermediate object
181
+ currentObj[key] = {};
182
+ }
183
+ if (!(0, utils_js_1.isObject)(currentObj[key])) {
184
+ // Skip value upon data structure conflict
185
+ return;
186
+ }
187
+ currentObj = currentObj[key];
188
+ }
189
+ // Set the final key to the value
190
+ const finalKey = keys[keys.length - 1];
191
+ currentObj[finalKey] = val;
192
+ }
193
+ function getPropKeys(prop) {
194
+ // Like `prop.split('.')` but with added support for `\` escaping, see serializePageContextClientSide.spec.ts
195
+ return prop
196
+ .split(/(?<!\\)\./) // Split on unescaped dots
197
+ .map((key) => key.replace(/\\\./g, '.')); // Replace escaped dots with literal dots
198
+ }
@@ -9,5 +9,8 @@ function preparePageContextForUserConsumptionServerSide(pageContext) {
9
9
  (0, utils_js_1.assert)((0, utils_js_1.isPlainObject)(pageContext.routeParams));
10
10
  (0, utils_js_1.assert)('Page' in pageContext);
11
11
  (0, utils_js_1.assert)(typeof pageContext.isClientSideNavigation === 'boolean');
12
+ (0, utils_js_1.assert)(pageContext._isPageContextObject);
13
+ (0, utils_js_1.assert)(pageContext.isClientSide === false);
14
+ (0, utils_js_1.assert)(typeof pageContext.isPrerendering === 'boolean');
12
15
  (0, preparePageContextForUserConsumption_js_1.preparePageContextForUserConsumption)(pageContext);
13
16
  }
@@ -7,6 +7,7 @@ exports.renderPageAlreadyRouted = renderPageAlreadyRouted;
7
7
  exports.prerenderPage = prerenderPage;
8
8
  exports.prerender404Page = prerender404Page;
9
9
  exports.getPageContextInitEnhanced = getPageContextInitEnhanced;
10
+ exports.createPageContext = createPageContext;
10
11
  const error_page_js_1 = require("../../../shared/error-page.js");
11
12
  const renderHtml_js_1 = require("../html/renderHtml.js");
12
13
  const utils_js_1 = require("../utils.js");
@@ -89,7 +90,11 @@ async function prerender404Page(pageContextInit_, globalContext) {
89
90
  if (!errorPageId) {
90
91
  return null;
91
92
  }
92
- const pageContext = {
93
+ // A URL is required for `viteDevServer.transformIndexHtml(url,html)`
94
+ const pageContextInit = { urlOriginal: '/fake-404-url' };
95
+ (0, utils_js_1.objectAssign)(pageContextInit, pageContextInit_);
96
+ const pageContext = await getPageContextInitEnhanced(pageContextInit, globalContext, true);
97
+ (0, utils_js_1.objectAssign)(pageContext, {
93
98
  pageId: errorPageId,
94
99
  _httpRequestId: null,
95
100
  _urlRewrite: null,
@@ -98,25 +103,17 @@ async function prerender404Page(pageContextInit_, globalContext) {
98
103
  // `prerender404Page()` is about generating `dist/client/404.html` for static hosts; there is no Client Routing.
99
104
  _usesClientRouter: false,
100
105
  _debugRouteMatches: []
101
- };
102
- const pageContextInit = {
103
- urlOriginal: '/fake-404-url' // A URL is needed for `applyViteHtmlTransform`
104
- };
105
- (0, utils_js_1.objectAssign)(pageContextInit, pageContextInit_);
106
- {
107
- const pageContextInitEnhanced = await getPageContextInitEnhanced(pageContextInit, globalContext);
108
- (0, utils_js_1.objectAssign)(pageContext, pageContextInitEnhanced);
109
- }
106
+ });
110
107
  (0, utils_js_1.objectAssign)(pageContext, await (0, loadUserFilesServerSide_js_1.loadUserFilesServerSide)(pageContext));
111
108
  return prerenderPage(pageContext);
112
109
  }
113
- async function getPageContextInitEnhanced(pageContextInit, globalContext, { ssr: { urlRewrite, urlHandler, isClientSideNavigation } = {
110
+ async function getPageContextInitEnhanced(pageContextInit, globalContext, isPrerendering, { ssr: { urlRewrite, urlHandler, isClientSideNavigation } = {
114
111
  urlRewrite: null,
115
112
  urlHandler: null,
116
113
  isClientSideNavigation: false
117
114
  } } = {}) {
118
115
  (0, utils_js_1.assert)(pageContextInit.urlOriginal);
119
- const pageContextInitEnhanced = {};
116
+ const pageContextInitEnhanced = createPageContext(pageContextInit, isPrerendering);
120
117
  (0, utils_js_1.objectAssign)(pageContextInitEnhanced, pageContextInit);
121
118
  (0, utils_js_1.objectAssign)(pageContextInitEnhanced, {
122
119
  _objectCreatedByVike: true,
@@ -163,3 +160,12 @@ async function getPageContextInitEnhanced(pageContextInit, globalContext, { ssr:
163
160
  }
164
161
  return pageContextInitEnhanced;
165
162
  }
163
+ function createPageContext(pageContextInit, isPrerendering) {
164
+ const pageContext = {
165
+ _isPageContextObject: true,
166
+ isClientSide: false,
167
+ isPrerendering
168
+ };
169
+ (0, utils_js_1.objectAssign)(pageContext, pageContextInit);
170
+ return pageContext;
171
+ }
@@ -108,15 +108,9 @@ async function renderPageAlreadyPrepared(pageContextInit, globalContext, httpReq
108
108
  // https://stackoverflow.com/questions/9683007/detect-infinite-http-redirect-loop-on-server-side
109
109
  0);
110
110
  let pageContextNominalPageSuccess;
111
- let pageContextNominalPageInit = {};
112
- {
113
- const pageContextFromAllRewrites = (0, abort_js_1.getPageContextFromAllRewrites)(pageContextsFromRewrite);
114
- (0, utils_js_1.objectAssign)(pageContextNominalPageInit, pageContextFromAllRewrites);
115
- }
116
- {
117
- const pageContextInitEnhanced = await getPageContextInitEnhancedSSR(pageContextInit, globalContext, pageContextNominalPageInit._urlRewrite, httpRequestId);
118
- (0, utils_js_1.objectAssign)(pageContextNominalPageInit, pageContextInitEnhanced);
119
- }
111
+ const pageContextFromAllRewrites = (0, abort_js_1.getPageContextFromAllRewrites)(pageContextsFromRewrite);
112
+ const pageContextNominalPageInit = await getPageContextInitEnhancedSSR(pageContextInit, globalContext, pageContextFromAllRewrites._urlRewrite, httpRequestId);
113
+ (0, utils_js_1.objectAssign)(pageContextNominalPageInit, pageContextFromAllRewrites);
120
114
  let errNominalPage;
121
115
  {
122
116
  try {
@@ -247,7 +241,7 @@ function prettyUrl(url) {
247
241
  return picocolors_1.default.bold(decodeURI(url));
248
242
  }
249
243
  function getPageContextHttpResponseError(err, pageContextInit, pageContext) {
250
- const pageContextWithError = createPageContext(pageContextInit);
244
+ const pageContextWithError = (0, renderPageAlreadyRouted_js_1.createPageContext)(pageContextInit, false);
251
245
  const httpResponse = (0, createHttpResponse_js_1.createHttpResponseError)(pageContext);
252
246
  (0, utils_js_1.objectAssign)(pageContextWithError, {
253
247
  httpResponse,
@@ -255,13 +249,6 @@ function getPageContextHttpResponseError(err, pageContextInit, pageContext) {
255
249
  });
256
250
  return pageContextWithError;
257
251
  }
258
- function createPageContext(pageContextInit) {
259
- const pageContext = {
260
- _isPageContextObject: true
261
- };
262
- Object.assign(pageContext, pageContextInit);
263
- return pageContext;
264
- }
265
252
  async function renderPageNominal(pageContext) {
266
253
  (0, utils_js_1.objectAssign)(pageContext, { errorWhileRendering: null });
267
254
  // Route
@@ -286,10 +273,8 @@ async function renderPageNominal(pageContext) {
286
273
  return pageContextAfterRender;
287
274
  }
288
275
  async function getPageContextErrorPageInit(pageContextInit, globalContext, errNominalPage, pageContextNominalPagePartial, httpRequestId) {
289
- const pageContextInitEnhanced = await getPageContextInitEnhancedSSR(pageContextInit, globalContext, null, httpRequestId);
276
+ const pageContext = await getPageContextInitEnhancedSSR(pageContextInit, globalContext, null, httpRequestId);
290
277
  (0, utils_js_1.assert)(errNominalPage);
291
- const pageContext = {};
292
- (0, utils_js_1.objectAssign)(pageContext, pageContextInitEnhanced);
293
278
  (0, utils_js_1.objectAssign)(pageContext, {
294
279
  is404: false,
295
280
  errorWhileRendering: errNominalPage,
@@ -303,7 +288,7 @@ async function getPageContextErrorPageInit(pageContextInit, globalContext, errNo
303
288
  }
304
289
  async function getPageContextInitEnhancedSSR(pageContextInit, globalContext, urlRewrite, httpRequestId) {
305
290
  const { isClientSideNavigation, _urlHandler } = handlePageContextUrl(pageContextInit.urlOriginal);
306
- const pageContextInitEnhanced = await (0, renderPageAlreadyRouted_js_1.getPageContextInitEnhanced)(pageContextInit, globalContext, {
291
+ const pageContextInitEnhanced = await (0, renderPageAlreadyRouted_js_1.getPageContextInitEnhanced)(pageContextInit, globalContext, false, {
307
292
  ssr: {
308
293
  urlRewrite,
309
294
  urlHandler: _urlHandler,
@@ -347,7 +332,7 @@ async function normalizeUrl(pageContextInit, globalContext, httpRequestId) {
347
332
  return null;
348
333
  (0, loggerRuntime_js_1.logRuntimeInfo)?.(`URL normalized from ${picocolors_1.default.cyan(urlOriginal)} to ${picocolors_1.default.cyan(urlNormalized)} (https://vike.dev/url-normalization)`, httpRequestId, 'info');
349
334
  const httpResponse = (0, createHttpResponse_js_1.createHttpResponseRedirect)({ url: urlNormalized, statusCode: 301 }, pageContextInit);
350
- const pageContextHttpResponse = createPageContext(pageContextInit);
335
+ const pageContextHttpResponse = (0, renderPageAlreadyRouted_js_1.createPageContext)(pageContextInit, false);
351
336
  (0, utils_js_1.objectAssign)(pageContextHttpResponse, { httpResponse });
352
337
  return pageContextHttpResponse;
353
338
  }
@@ -389,7 +374,7 @@ async function getPermanentRedirect(pageContextInit, globalContext, httpRequestI
389
374
  }
390
375
  (0, loggerRuntime_js_1.logRuntimeInfo)?.(`Permanent redirection defined by config.redirects (https://vike.dev/redirects)`, httpRequestId, 'info');
391
376
  const httpResponse = (0, createHttpResponse_js_1.createHttpResponseRedirect)({ url: urlTarget, statusCode: 301 }, pageContextInit);
392
- const pageContextHttpResponse = createPageContext(pageContextInit);
377
+ const pageContextHttpResponse = (0, renderPageAlreadyRouted_js_1.createPageContext)(pageContextInit, false);
393
378
  (0, utils_js_1.objectAssign)(pageContextHttpResponse, { httpResponse });
394
379
  return pageContextHttpResponse;
395
380
  }
@@ -410,10 +395,10 @@ pageContextNominalPageInit, httpRequestId, pageContextErrorPageInit, globalConte
410
395
  const abortCall = pageContextAbort._abortCall;
411
396
  (0, utils_js_1.assert)(abortCall);
412
397
  (0, utils_js_1.assertUsage)(errorPageId, `You called ${picocolors_1.default.cyan(abortCall)} but you didn't define an error page, make sure to define one https://vike.dev/error-page`);
413
- const pageContext = createPageContext({});
398
+ const pageContext = (0, renderPageAlreadyRouted_js_1.createPageContext)({}, false);
414
399
  (0, utils_js_1.objectAssign)(pageContext, { pageId: errorPageId });
415
400
  (0, utils_js_1.objectAssign)(pageContext, pageContextAbort);
416
- (0, utils_js_1.objectAssign)(pageContext, pageContextErrorPageInit);
401
+ (0, utils_js_1.objectAssign)(pageContext, pageContextErrorPageInit, true);
417
402
  (0, utils_js_1.objectAssign)(pageContext, await (0, loadUserFilesServerSide_js_1.loadUserFilesServerSide)(pageContext));
418
403
  // We include pageContextInit: we don't only serialize pageContextAbort because the error page may need to access pageContextInit
419
404
  pageContextSerialized = (0, serializePageContextClientSide_js_1.serializePageContextClientSide)(pageContext);
@@ -434,7 +419,7 @@ pageContextNominalPageInit, httpRequestId, pageContextErrorPageInit, globalConte
434
419
  return { pageContextReturn };
435
420
  }
436
421
  if (pageContextAbort._urlRedirect) {
437
- const pageContextReturn = createPageContext(pageContextInit);
422
+ const pageContextReturn = (0, renderPageAlreadyRouted_js_1.createPageContext)(pageContextInit, false);
438
423
  (0, utils_js_1.objectAssign)(pageContextReturn, pageContextAbort);
439
424
  const httpResponse = (0, createHttpResponse_js_1.createHttpResponseRedirect)(pageContextAbort._urlRedirect, pageContextInit);
440
425
  (0, utils_js_1.objectAssign)(pageContextReturn, { httpResponse });
@@ -449,7 +434,7 @@ async function checkBaseUrl(pageContextInit, globalContext) {
449
434
  const { isBaseMissing } = (0, utils_js_1.parseUrl)(urlOriginal, baseServer);
450
435
  if (!isBaseMissing)
451
436
  return;
452
- const pageContext = createPageContext(pageContextInit);
437
+ const pageContext = (0, renderPageAlreadyRouted_js_1.createPageContext)(pageContextInit, false);
453
438
  const httpResponse = (0, createHttpResponse_js_1.createHttpResponseBaseIsMissing)(urlOriginal, baseServer);
454
439
  (0, utils_js_1.objectAssign)(pageContext, {
455
440
  httpResponse,
@@ -462,7 +447,7 @@ function renderInvalidRequest(pageContextInit) {
462
447
  const urlPathnameWithBase = (0, utils_js_1.parseUrl)(pageContextInit.urlOriginal, '/').pathname;
463
448
  assertIsNotViteRequest(urlPathnameWithBase, pageContextInit.urlOriginal);
464
449
  if (urlPathnameWithBase.endsWith('/favicon.ico')) {
465
- const pageContext = createPageContext(pageContextInit);
450
+ const pageContext = (0, renderPageAlreadyRouted_js_1.createPageContext)(pageContextInit, false);
466
451
  const httpResponse = (0, createHttpResponse_js_1.createHttpResponseFavicon404)();
467
452
  (0, utils_js_1.objectAssign)(pageContext, { httpResponse });
468
453
  (0, utils_js_1.checkType)(pageContext);
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NOT_SERIALIZABLE = void 0;
4
+ // TODO: move to ../node/runtime/html/NOT_SERIALIZABLE.ts once code is distributed as ESM
5
+ exports.NOT_SERIALIZABLE = '__VIKE__NOT_SERIALIZABLE__';
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PROJECT_VERSION = void 0;
4
4
  // Automatically updated by @brillout/release-me
5
- exports.PROJECT_VERSION = '0.4.225-commit-37a36a5';
5
+ exports.PROJECT_VERSION = '0.4.225-commit-2b7971f';
@@ -47,7 +47,7 @@ function assert(condition, debugInfo) {
47
47
  const debugInfoSerialized = typeof debugInfo === 'string' ? debugInfo : JSON.stringify(debugInfo);
48
48
  return picocolors_1.default.dim(`Debug info (for Vike maintainers; you can ignore this): ${debugInfoSerialized}`);
49
49
  })();
50
- const link = picocolors_1.default.blue('https://github.com/vikejs/vike/issues/new?template=bug.yml');
50
+ const link = picocolors_1.default.underline('https://github.com/vikejs/vike/issues/new?template=bug.yml');
51
51
  let errMsg = [
52
52
  `You stumbled upon a Vike bug. Go to ${link} and copy-paste this error. A maintainer will fix the bug (usually within 24 hours).`,
53
53
  debugStr
@@ -5,9 +5,14 @@ const assert_js_1 = require("./assert.js");
5
5
  // Same as Object.assign() but:
6
6
  // - With type inference
7
7
  // - Preserves property descriptors, which we need for preserving the getters added by getPageContextUrlComputed()
8
- function objectAssign(obj, objAddendum) {
8
+ function objectAssign(obj, objAddendum, objAddendumCanBePageContextObject) {
9
9
  if (objAddendum) {
10
- (0, assert_js_1.assert)(!('_isPageContextObject' in objAddendum));
10
+ if (!objAddendumCanBePageContextObject) {
11
+ // We only need this assert() in the rare case when the user is expected to mutate `pageContext` after the Vike hook was executed (and its promise resolved).
12
+ // - The only use case I can think of is the user mutating `pageContext` after the onRenderClient() promise resolved (which can happen when client-side rendering finishes after onRenderClient() resolves). In that case, having Vike await async Vike hooks isn't enough.
13
+ // - IIRC this assert() was mostly needed for preserving the getters added by getPageContextUrlComputed() but we don't need this anymore.
14
+ (0, assert_js_1.assert)(!('_isPageContextObject' in objAddendum));
15
+ }
11
16
  Object.defineProperties(obj, Object.getOwnPropertyDescriptors(objAddendum));
12
17
  }
13
18
  }
@@ -1,6 +1,8 @@
1
1
  export { createPageContext };
2
2
  declare function createPageContext(urlOriginal: string): Promise<{
3
3
  _isPageContextObject: boolean;
4
+ isClientSide: boolean;
5
+ isPrerendering: boolean;
4
6
  urlOriginal: string;
5
7
  _objectCreatedByVike: boolean;
6
8
  _urlHandler: null;
@@ -4,7 +4,6 @@ import { getPageContextUrlComputed } from '../../shared/getPageContextUrlCompute
4
4
  import { loadPageRoutes } from '../../shared/route/loadPageRoutes.js';
5
5
  import { getBaseServer } from './getBaseServer.js';
6
6
  import { assert, isBaseServer, objectAssign } from './utils.js';
7
- // TODO/now: can we avoid optimizeDeps.exclude of client runtime?
8
7
  // @ts-ignore
9
8
  import * as virtualFileExports from 'virtual:vike:importUserCode:client:client-routing';
10
9
  const { pageFilesAll, allPageIds, pageConfigs, pageConfigGlobal } = getPageConfigsRuntime(virtualFileExports);
@@ -14,6 +13,8 @@ async function createPageContext(urlOriginal) {
14
13
  assert(isBaseServer(baseServer));
15
14
  const pageContext = {
16
15
  _isPageContextObject: true,
16
+ isClientSide: true,
17
+ isPrerendering: false,
17
18
  urlOriginal,
18
19
  _objectCreatedByVike: true,
19
20
  _urlHandler: null,
@@ -276,7 +276,7 @@ async function renderPageClientSide(renderArgs) {
276
276
  if ('err' in args) {
277
277
  const { err } = args;
278
278
  assert(!('errorWhileRendering' in pageContext));
279
- pageContext.errorWhileRendering = err;
279
+ objectAssign(pageContext, { errorWhileRendering: err });
280
280
  if (isAbortError(err)) {
281
281
  const errAbort = err;
282
282
  logAbortErrorHandled(err, !import.meta.env.DEV, pageContext);