vike 0.4.221 → 0.4.222-commit-207e079

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 (84) hide show
  1. package/dist/cjs/node/api/prepareViteApiCall.js +18 -16
  2. package/dist/cjs/node/plugin/index.js +1 -1
  3. package/dist/cjs/node/plugin/plugins/baseUrls.js +6 -1
  4. package/dist/cjs/node/plugin/plugins/buildConfig/fixServerAssets.js +8 -10
  5. package/dist/cjs/node/plugin/plugins/buildConfig.js +0 -1
  6. package/dist/cjs/node/plugin/plugins/commonConfig.js +4 -1
  7. package/dist/cjs/node/plugin/plugins/importUserCode/index.js +73 -39
  8. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +64 -14
  9. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.js +0 -5
  10. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/getPlusFilesAll.js +2 -40
  11. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +1 -1
  12. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +6 -3
  13. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +49 -18
  14. package/dist/cjs/node/runtime/globalContext.js +24 -8
  15. package/dist/cjs/node/runtime/renderPage/loadUserFilesServerSide.js +3 -3
  16. package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +2 -4
  17. package/dist/cjs/node/runtime/renderPage.js +4 -8
  18. package/dist/cjs/node/runtime-dev/createDevMiddleware.js +3 -3
  19. package/dist/cjs/node/shared/resolveBase.js +0 -13
  20. package/dist/cjs/shared/getPageConfigsRuntime.js +10 -1
  21. package/dist/cjs/shared/page-configs/getPageConfigUserFriendly.js +4 -2
  22. package/dist/cjs/shared/route/loadPageRoutes.js +1 -1
  23. package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
  24. package/dist/cjs/utils/assertSingleInstance.js +1 -1
  25. package/dist/cjs/utils/debug.js +9 -6
  26. package/dist/esm/client/client-routing-runtime/prefetch.js +1 -1
  27. package/dist/esm/client/client-routing-runtime/renderPageClientSide.d.ts +5 -0
  28. package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +9 -2
  29. package/dist/esm/client/server-routing-runtime/getPageContext.d.ts +1 -0
  30. package/dist/esm/client/server-routing-runtime/getPageContext.js +4 -3
  31. package/dist/esm/client/shared/loadUserFilesClientSide.d.ts +3 -2
  32. package/dist/esm/client/shared/loadUserFilesClientSide.js +2 -2
  33. package/dist/esm/node/api/prepareViteApiCall.d.ts +2 -2
  34. package/dist/esm/node/api/prepareViteApiCall.js +18 -16
  35. package/dist/esm/node/plugin/index.d.ts +4 -1
  36. package/dist/esm/node/plugin/index.js +1 -1
  37. package/dist/esm/node/plugin/plugins/baseUrls.js +6 -1
  38. package/dist/esm/node/plugin/plugins/buildConfig/fixServerAssets.d.ts +0 -2
  39. package/dist/esm/node/plugin/plugins/buildConfig/fixServerAssets.js +8 -10
  40. package/dist/esm/node/plugin/plugins/buildConfig.js +1 -2
  41. package/dist/esm/node/plugin/plugins/commonConfig.d.ts +1 -0
  42. package/dist/esm/node/plugin/plugins/commonConfig.js +4 -1
  43. package/dist/esm/node/plugin/plugins/importUserCode/index.js +73 -39
  44. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.d.ts +4 -0
  45. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +65 -15
  46. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.d.ts +0 -3
  47. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.js +0 -5
  48. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/getPlusFilesAll.d.ts +0 -2
  49. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/getPlusFilesAll.js +2 -37
  50. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +1 -1
  51. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.d.ts +1 -1
  52. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +6 -3
  53. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.d.ts +3 -2
  54. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +50 -19
  55. package/dist/esm/node/runtime/globalContext.d.ts +10 -7
  56. package/dist/esm/node/runtime/globalContext.js +24 -8
  57. package/dist/esm/node/runtime/html/injectAssets/getViteDevScript.d.ts +2 -2
  58. package/dist/esm/node/runtime/html/injectAssets.d.ts +2 -2
  59. package/dist/esm/node/runtime/renderPage/analyzePage.d.ts +2 -2
  60. package/dist/esm/node/runtime/renderPage/getPageAssets.d.ts +2 -2
  61. package/dist/esm/node/runtime/renderPage/handleErrorWithoutErrorPage.d.ts +2 -2
  62. package/dist/esm/node/runtime/renderPage/loadUserFilesServerSide.d.ts +2 -2
  63. package/dist/esm/node/runtime/renderPage/loadUserFilesServerSide.js +3 -3
  64. package/dist/esm/node/runtime/renderPage/log404/index.d.ts +2 -2
  65. package/dist/esm/node/runtime/renderPage/preparePageContextForUserConsumptionServerSide.d.ts +2 -2
  66. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +8 -8
  67. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +2 -4
  68. package/dist/esm/node/runtime/renderPage.js +4 -8
  69. package/dist/esm/node/runtime-dev/createDevMiddleware.js +3 -3
  70. package/dist/esm/node/shared/resolveBase.d.ts +1 -9
  71. package/dist/esm/node/shared/resolveBase.js +0 -13
  72. package/dist/esm/shared/getPageConfigsRuntime.d.ts +2 -1
  73. package/dist/esm/shared/getPageConfigsRuntime.js +10 -1
  74. package/dist/esm/shared/page-configs/getPageConfigUserFriendly.d.ts +8 -2
  75. package/dist/esm/shared/page-configs/getPageConfigUserFriendly.js +4 -2
  76. package/dist/esm/shared/route/loadPageRoutes.js +1 -1
  77. package/dist/esm/shared/types.d.ts +9 -0
  78. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  79. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  80. package/dist/esm/utils/assertSingleInstance.js +1 -1
  81. package/dist/esm/utils/debug.d.ts +1 -1
  82. package/dist/esm/utils/debug.js +9 -6
  83. package/dist/esm/utils/projectInfo.d.ts +1 -1
  84. package/package.json +1 -1
@@ -1,16 +1,13 @@
1
1
  export { getPlusFilesAll };
2
- export { getPlusFileValueConfigName };
3
- import { assert, assertPosixPath, assertUsage } from '../../../../utils.js';
2
+ import { assert } from '../../../../utils.js';
4
3
  import { configDefinitionsBuiltIn } from './configDefinitionsBuiltIn.js';
5
4
  import { getLocationId } from './filesystemRouting.js';
6
- import { isTemporaryBuildFile } from './transpileAndExecuteFile.js';
7
- import { crawlPlusFiles } from './crawlPlusFiles.js';
5
+ import { crawlPlusFiles, getPlusFileValueConfigName } from './crawlPlusFiles.js';
8
6
  import { getConfigFileExport } from './getConfigFileExport.js';
9
7
  import { loadConfigFile, loadValueFile } from './loadFileAtConfigTime.js';
10
8
  import { resolvePointerImport } from './resolvePointerImport.js';
11
9
  import { getFilePathResolved } from '../../../../shared/getFilePath.js';
12
10
  import { assertExtensionsConventions } from './assertExtensions.js';
13
- import path from 'node:path';
14
11
  async function getPlusFilesAll(userRootDir, esbuildCache) {
15
12
  const plusFiles = await findPlusFiles(userRootDir, null);
16
13
  const configFiles = [];
@@ -120,35 +117,3 @@ async function findPlusFiles(userRootDir, outDirRoot) {
120
117
  const plusFiles = files.map(({ filePathAbsoluteUserRootDir }) => getFilePathResolved({ filePathAbsoluteUserRootDir, userRootDir }));
121
118
  return plusFiles;
122
119
  }
123
- function getPlusFileValueConfigName(filePath) {
124
- assertPosixPath(filePath);
125
- if (isTemporaryBuildFile(filePath))
126
- return null;
127
- const fileName = path.posix.basename(filePath);
128
- // assertNoUnexpectedPlusSign(filePath, fileName)
129
- const basename = fileName.split('.')[0];
130
- if (!basename.startsWith('+')) {
131
- return null;
132
- }
133
- else {
134
- const configName = basename.slice(1);
135
- assertUsage(configName !== '', `${filePath} Invalid filename ${fileName}`);
136
- return configName;
137
- }
138
- }
139
- /* https://github.com/vikejs/vike/issues/1407
140
- function assertNoUnexpectedPlusSign(filePath: string, fileName: string) {
141
- const dirs = path.posix.dirname(filePath).split('/')
142
- dirs.forEach((dir, i) => {
143
- const dirPath = dirs.slice(0, i + 1).join('/')
144
- assertUsage(
145
- !dir.includes('+'),
146
- `Character '+' is a reserved character: remove '+' from the directory name ${dirPath}/`
147
- )
148
- })
149
- assertUsage(
150
- !fileName.slice(1).includes('+'),
151
- `Character '+' is only allowed at the beginning of filenames: make sure ${filePath} doesn't contain any '+' in its filename other than its first letter`
152
- )
153
- }
154
- */
@@ -51,7 +51,7 @@ async function loadValueFile(interfaceValueFile, configDefinitions, userRootDir,
51
51
  async function loadConfigFile(configFilePath, userRootDir, visited, isExtensionConfig, esbuildCache) {
52
52
  const { filePathAbsoluteFilesystem } = configFilePath;
53
53
  assertNoInfiniteLoop(visited, filePathAbsoluteFilesystem);
54
- const { fileExports } = await transpileAndExecuteFile(configFilePath, userRootDir, isExtensionConfig ? 'is-extension-config' : true, esbuildCache);
54
+ const { fileExports } = await transpileAndExecuteFile(configFilePath, userRootDir, isExtensionConfig, esbuildCache);
55
55
  const { extendsConfigs, extendsFilePaths } = await loadExtendsConfigs(fileExports, configFilePath, userRootDir, [...visited, filePathAbsoluteFilesystem], esbuildCache);
56
56
  const configFile = {
57
57
  fileExports,
@@ -10,7 +10,7 @@ type FileExports = {
10
10
  };
11
11
  type EsbuildCache = Record<string, // filePathAbsoluteFilesystem
12
12
  Promise<FileExports>>;
13
- declare function transpileAndExecuteFile(filePath: FilePathResolved, userRootDir: string, isConfigFile: boolean | 'is-extension-config', esbuildCache: EsbuildCache): Promise<FileExports>;
13
+ declare function transpileAndExecuteFile(filePath: FilePathResolved, userRootDir: string, isExtensionConfig: boolean, esbuildCache: EsbuildCache): Promise<FileExports>;
14
14
  declare function getConfigBuildErrorFormatted(err: unknown): null | string;
15
15
  declare function getConfigExecutionErrorIntroMsg(err: unknown): string | null;
16
16
  declare function isTemporaryBuildFile(filePath: string): boolean;
@@ -21,8 +21,9 @@ const debug = createDebugger('vike:pointer-imports');
21
21
  const debugEsbuildResolve = createDebugger('vike:esbuild-resolve');
22
22
  if (debugEsbuildResolve.isActivated)
23
23
  debugEsbuildResolve('esbuild version', version);
24
- async function transpileAndExecuteFile(filePath, userRootDir, isConfigFile, esbuildCache) {
24
+ async function transpileAndExecuteFile(filePath, userRootDir, isExtensionConfig, esbuildCache) {
25
25
  const { filePathAbsoluteFilesystem, filePathToShowToUserResolved } = filePath;
26
+ assert(filePathAbsoluteFilesystem);
26
27
  const fileExtension = getFileExtension(filePathAbsoluteFilesystem);
27
28
  if (esbuildCache[filePathAbsoluteFilesystem]) {
28
29
  return await esbuildCache[filePathAbsoluteFilesystem];
@@ -35,12 +36,12 @@ async function transpileAndExecuteFile(filePath, userRootDir, isConfigFile, esbu
35
36
  assertWarning(false, `${pc.cyan('.h.js')} files are deprecated: simply renaming ${filePathToShowToUserResolved} to ${removeHeaderFileExtension(filePathToShowToUserResolved)} is usually enough, although you may occasionally need to use ${pc.cyan("with { type: 'pointer' }")} as explained at https://vike.dev/config#pointer-imports`, { onlyOnce: true });
36
37
  }
37
38
  let fileExports;
38
- if (isConfigFile === 'is-extension-config' && !isHeader && fileExtension.endsWith('js')) {
39
+ if (isExtensionConfig && !isHeader && fileExtension.endsWith('js')) {
39
40
  // This doesn't track dependencies => we should never use this for user land configs
40
41
  fileExports = await executeFile(filePathAbsoluteFilesystem, filePath);
41
42
  }
42
43
  else {
43
- const transformImports = isConfigFile && (isHeader ? 'all' : true);
44
+ const transformImports = isHeader ? 'all' : true;
44
45
  const code = await transpileFile(filePath, transformImports, userRootDir);
45
46
  fileExports = await executeTranspiledFile(filePath, code);
46
47
  }
@@ -49,6 +50,7 @@ async function transpileAndExecuteFile(filePath, userRootDir, isConfigFile, esbu
49
50
  }
50
51
  async function transpileFile(filePath, transformImports, userRootDir) {
51
52
  const { filePathAbsoluteFilesystem, filePathToShowToUserResolved } = filePath;
53
+ assert(filePathAbsoluteFilesystem);
52
54
  assertPosixPath(filePathAbsoluteFilesystem);
53
55
  vikeConfigDependencies.add(filePathAbsoluteFilesystem);
54
56
  if (debug.isActivated)
@@ -333,6 +335,7 @@ function isTemporaryBuildFile(filePath) {
333
335
  const fileName = path.posix.basename(filePath);
334
336
  return /\.build-[a-z0-9]{12}\.mjs$/.test(fileName);
335
337
  }
338
+ // TODO/next-major: remove
336
339
  function isHeaderFile(filePath) {
337
340
  assertPosixPath(filePath);
338
341
  const fileExtensions = getFileExtensions(filePath);
@@ -9,12 +9,13 @@ export type { VikeConfigObject };
9
9
  import type { PageConfigGlobalBuildTime, PageConfigBuildTime } from '../../../../../shared/page-configs/PageConfig.js';
10
10
  import { type ConfigDefinitions, type ConfigDefinitionInternal } from './getVikeConfig/configDefinitionsBuiltIn.js';
11
11
  import type { ResolvedConfig } from 'vite';
12
- import { getPageConfigUserFriendlyNew } from '../../../../../shared/page-configs/getPageConfigUserFriendly.js';
12
+ import { type ConfigUserFriendly, type PageConfigsUserFriendly } from '../../../../../shared/page-configs/getPageConfigUserFriendly.js';
13
13
  import { type PlusFile } from './getVikeConfig/getPlusFilesAll.js';
14
14
  type VikeConfigObject = {
15
15
  pageConfigs: PageConfigBuildTime[];
16
16
  pageConfigGlobal: PageConfigGlobalBuildTime;
17
- global: ReturnType<typeof getPageConfigUserFriendlyNew>;
17
+ global: ConfigUserFriendly;
18
+ pages: PageConfigsUserFriendly;
18
19
  };
19
20
  declare const vikeConfigDependencies: Set<string>;
20
21
  declare function reloadVikeConfig(config: ResolvedConfig): void;
@@ -7,7 +7,7 @@ export { getConfVal };
7
7
  export { getConfigDefinitionOptional };
8
8
  import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, includes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, assertKeys, objectKeys, objectFromEntries, unique, isCallable, makeFirst, lowerFirst } from '../../../utils.js';
9
9
  import { configDefinitionsBuiltIn } from './getVikeConfig/configDefinitionsBuiltIn.js';
10
- import { getLocationId, getFilesystemRouteString, getFilesystemRouteDefinedBy, isInherited, sortAfterInheritanceOrder, isGlobalLocation, applyFilesystemRoutingRootEffect } from './getVikeConfig/filesystemRouting.js';
10
+ import { getLocationId, getFilesystemRouteString, getFilesystemRouteDefinedBy, isInherited, sortAfterInheritanceOrder, applyFilesystemRoutingRootEffect } from './getVikeConfig/filesystemRouting.js';
11
11
  import { isConfigInvalid, isConfigInvalid_set } from '../../../../runtime/renderPage/isConfigInvalid.js';
12
12
  import { getViteDevServer } from '../../../../runtime/globalContext.js';
13
13
  import { logConfigError, logConfigErrorRecover } from '../../../shared/loggerNotProd.js';
@@ -31,6 +31,7 @@ function reloadVikeConfig(config) {
31
31
  const userRootDir = config.root;
32
32
  const vikeVitePluginOptions = config._vikeVitePluginOptions;
33
33
  assert(vikeVitePluginOptions);
34
+ // TODO/now: unify with esbuildCache
34
35
  vikeConfigDependencies.clear();
35
36
  vikeConfigPromise = loadVikeConfig_withErrorHandling(userRootDir, true, vikeVitePluginOptions);
36
37
  handleReloadSideEffects();
@@ -126,7 +127,8 @@ async function loadVikeConfig_withErrorHandling(userRootDir, isDev, vikeVitePlug
126
127
  configDefinitions: {},
127
128
  configValueSources: {}
128
129
  },
129
- global: getPageConfigUserFriendlyNew({ configValues: {} })
130
+ global: getPageConfigUserFriendlyNew({ configValues: {} }),
131
+ pages: {}
130
132
  };
131
133
  return dummyData;
132
134
  }
@@ -135,15 +137,26 @@ async function loadVikeConfig_withErrorHandling(userRootDir, isDev, vikeVitePlug
135
137
  async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
136
138
  const esbuildCache = {};
137
139
  const plusFilesAll = await getPlusFilesAll(userRootDir, esbuildCache);
138
- assertKnownConfigs(plusFilesAll);
139
140
  const configDefinitionsResolved = await resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache);
141
+ assertKnownConfigs(configDefinitionsResolved, plusFilesAll);
140
142
  const { pageConfigGlobal, pageConfigs } = getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRootDir);
141
143
  // interop vike(options) in vite.config.js
142
144
  temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, userRootDir);
143
145
  // global
144
- const configValues = getConfigValues(pageConfigGlobal);
145
- const global = getPageConfigUserFriendlyNew({ configValues });
146
- return { pageConfigs, pageConfigGlobal, global };
146
+ const configValuesGlobal = getConfigValues(pageConfigGlobal);
147
+ const global = getPageConfigUserFriendlyNew({ configValues: configValuesGlobal });
148
+ // TODO/now DEDUPE
149
+ // pages
150
+ const pages = objectFromEntries(pageConfigs.map((pageConfig) => {
151
+ const configValuesLocal = getConfigValues(pageConfig, true);
152
+ const configValues = { ...configValuesGlobal, ...configValuesLocal };
153
+ const page = {
154
+ ...getPageConfigUserFriendlyNew({ configValues }),
155
+ route: pageConfig.routeFilesystem?.routeString ?? null
156
+ };
157
+ return [pageConfig.pageId, page];
158
+ }));
159
+ return { pageConfigs, pageConfigGlobal, global, pages };
147
160
  }
148
161
  async function resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache) {
149
162
  const configDefinitionsGlobal = getConfigDefinitions(
@@ -229,10 +242,9 @@ function assertPageConfigGlobal(pageConfigGlobal, plusFilesAll) {
229
242
  });
230
243
  }
231
244
  function assertGlobalConfigLocation(configName, sources, plusFilesAll, configDefinitionsGlobal) {
232
- const locationIdsAll = objectKeys(plusFilesAll);
233
245
  // Determine existing global +config.js files
234
246
  const configFilePathsGlobal = [];
235
- const plusFilesGlobal = Object.values(objectFromEntries(objectEntries(plusFilesAll).filter(([locationId]) => isGlobalLocation(locationId, locationIdsAll)))).flat();
247
+ const plusFilesGlobal = Object.values(objectFromEntries(objectEntries(plusFilesAll).filter(([locationId]) => isGlobalLocation(locationId, plusFilesAll)))).flat();
236
248
  plusFilesGlobal
237
249
  .filter((i) => i.isConfigFile)
238
250
  .forEach((plusFile) => {
@@ -251,7 +263,7 @@ function assertGlobalConfigLocation(configName, sources, plusFilesAll, configDef
251
263
  if (!filePathAbsoluteUserRootDir)
252
264
  return;
253
265
  assert(!plusFile.isExtensionConfig);
254
- if (!isGlobalLocation(source.locationId, locationIdsAll)) {
266
+ if (!isGlobalLocation(source.locationId, plusFilesAll)) {
255
267
  const configDef = configDefinitionsGlobal[configName];
256
268
  assert(configDef);
257
269
  const isConditionallyGlobal = isCallable(configDef.global);
@@ -284,7 +296,7 @@ function assertOnBeforeRenderEnv(pageConfig) {
284
296
  // When using Server Routing, loading a onBeforeRender() hook on the client-side hasn't any effect (the Server Routing's client runtime never calls it); it unnecessarily bloats client bundle sizes
285
297
  assertUsage(!(onBeforeRenderEnv.client && !isClientRouting), `Page ${pageConfig.pageId} has an onBeforeRender() hook with env ${pc.cyan(JSON.stringify(onBeforeRenderEnv))} which doesn't make sense because the page is using Server Routing: onBeforeRender() can be run in the client only when using Client Routing.`);
286
298
  }
287
- function getConfigValues(pageConfig) {
299
+ function getConfigValues(pageConfig, tolerateMissingValue) {
288
300
  const configValues = {};
289
301
  getConfigValuesBase(pageConfig, (configEnv) => !!configEnv.config, null).forEach((entry) => {
290
302
  if (entry.configValueBase.type === 'computed') {
@@ -295,7 +307,11 @@ function getConfigValues(pageConfig) {
295
307
  if (entry.configValueBase.type === 'standard') {
296
308
  assert('sourceRelevant' in entry); // Help TS
297
309
  const { configValueBase, sourceRelevant, configName } = entry;
298
- assert('value' in sourceRelevant);
310
+ if (!sourceRelevant.valueIsLoaded) {
311
+ if (tolerateMissingValue)
312
+ return;
313
+ assert(false);
314
+ }
299
315
  const { value } = sourceRelevant;
300
316
  configValues[configName] = { ...configValueBase, value };
301
317
  }
@@ -304,9 +320,18 @@ function getConfigValues(pageConfig) {
304
320
  const { configValueBase, sourcesRelevant, configName } = entry;
305
321
  const values = [];
306
322
  sourcesRelevant.forEach((source) => {
307
- assert('value' in source);
323
+ if (!source.valueIsLoaded) {
324
+ if (tolerateMissingValue)
325
+ return;
326
+ assert(false);
327
+ }
308
328
  values.push(source.value);
309
329
  });
330
+ if (values.length === 0) {
331
+ if (tolerateMissingValue)
332
+ return;
333
+ assert(false);
334
+ }
310
335
  configValues[configName] = { ...configValueBase, value: values };
311
336
  }
312
337
  });
@@ -351,10 +376,9 @@ function getPlusFilesRelevant(plusFilesAll, locationIdPage) {
351
376
  return plusFilesRelevant;
352
377
  }
353
378
  function sortForGlobal(plusFilesAll) {
354
- const locationIdsAll = objectKeys(plusFilesAll);
355
379
  const plusFilesAllSorted = Object.fromEntries(objectEntries(plusFilesAll)
356
380
  .sort(lowerFirst(([locationId]) => locationId.split('/').length))
357
- .sort(makeFirst(([locationId]) => isGlobalLocation(locationId, locationIdsAll))));
381
+ .sort(makeFirst(([locationId]) => isGlobalLocation(locationId, plusFilesAll))));
358
382
  return plusFilesAllSorted;
359
383
  }
360
384
  function resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, isGlobal) {
@@ -748,13 +772,13 @@ function getComputed(configValueSources, configDefinitions) {
748
772
  return configValuesComputed;
749
773
  }
750
774
  // Show error message upon unknown config
751
- function assertKnownConfigs(plusFilesAll) {
775
+ function assertKnownConfigs(configDefinitionsResolved, plusFilesAll) {
752
776
  const configDefinitionsAll = getConfigDefinitions(plusFilesAll);
753
777
  const configNamesKnownAll = Object.keys(configDefinitionsAll);
754
- objectEntries(plusFilesAll).forEach(([locationId, plusFiles]) => {
755
- const plusFilesRelevant = getPlusFilesRelevant(plusFilesAll, locationId);
756
- const configDefinitionsLocal = getConfigDefinitions(plusFilesRelevant);
757
- const configNamesKnownLocal = Object.keys(configDefinitionsLocal);
778
+ const configNamesGlobal = Object.keys(configDefinitionsResolved.configDefinitionsGlobal);
779
+ objectEntries(configDefinitionsResolved.configDefinitionsLocal).forEach(([_locationId, { configDefinitions, plusFiles }]) => {
780
+ const configDefinitionsLocal = configDefinitions;
781
+ const configNamesKnownLocal = [...Object.keys(configDefinitionsLocal), ...configNamesGlobal];
758
782
  plusFiles.forEach((plusFile) => {
759
783
  const configNames = getDefiningConfigNames(plusFile);
760
784
  configNames.forEach((configName) => {
@@ -926,3 +950,10 @@ function resolveConfigEnv(configEnv, filePath) {
926
950
  }
927
951
  return configEnvResolved;
928
952
  }
953
+ /** Whether configs defined in `locationId` apply to every page */
954
+ function isGlobalLocation(locationId, plusFilesAll) {
955
+ const locationIdsPage = objectEntries(plusFilesAll)
956
+ .filter(([_locationId, plusFiles]) => isDefiningPage(plusFiles))
957
+ .map(([locationId]) => locationId);
958
+ return locationIdsPage.every((locId) => isInherited(locationId, locId));
959
+ }
@@ -16,23 +16,25 @@ export { assertBuildInfo };
16
16
  export { getViteConfigRuntime };
17
17
  export { updateUserFiles };
18
18
  export type { BuildInfo };
19
- export type { GlobalContext };
19
+ export type { GlobalContextInternal };
20
20
  export type { GlobalContextPublic };
21
21
  import type { ViteManifest } from '../shared/ViteManifest.js';
22
22
  import type { ResolvedConfig, ViteDevServer } from 'vite';
23
- import type { ConfigUserFriendly } from '../../shared/page-configs/getPageConfigUserFriendly.js';
23
+ import type { ConfigUserFriendly, PageConfigsUserFriendly } from '../../shared/page-configs/getPageConfigUserFriendly.js';
24
24
  import type { ConfigVitePluginServerEntry } from '@brillout/vite-plugin-server-entry/plugin';
25
- type GlobalContextPublic = Pick<GlobalContext, 'assetsManifest' | 'config' | 'viteConfig'>;
25
+ import { type BaseUrlsResolved } from '../shared/resolveBase.js';
26
+ type GlobalContextPublic = Pick<GlobalContext, 'assetsManifest' | 'config' | 'viteConfig' | 'pages' | 'baseAssets' | 'baseServer'>;
26
27
  type PageRuntimeInfo = Awaited<ReturnType<typeof getUserFiles>>;
27
- type GlobalContext = GlobalContextWithoutPublicCopy & {
28
+ type GlobalContextInternal = GlobalContext & {
28
29
  globalContext_public: GlobalContextPublic;
29
30
  };
30
- type GlobalContextWithoutPublicCopy = {
31
+ type GlobalContext = {
31
32
  viteConfigRuntime: {
32
33
  _baseViteOriginal: null | string;
33
34
  };
34
35
  config: ConfigUserFriendly['config'];
35
- } & PageRuntimeInfo & ({
36
+ pages: PageConfigsUserFriendly;
37
+ } & BaseUrlsResolved & PageRuntimeInfo & ({
36
38
  isProduction: false;
37
39
  isPrerendering: false;
38
40
  viteConfig: ResolvedConfig;
@@ -50,7 +52,7 @@ type GlobalContextWithoutPublicCopy = {
50
52
  usesClientRouter: boolean;
51
53
  viteConfig: ResolvedConfig;
52
54
  })));
53
- declare function getGlobalContextInternal(): Promise<GlobalContext>;
55
+ declare function getGlobalContextInternal(): Promise<GlobalContextInternal>;
54
56
  /** @experimental https://vike.dev/getGlobalContext */
55
57
  declare function getGlobalContextSync(): GlobalContextPublic;
56
58
  /** @experimental https://vike.dev/getGlobalContext */
@@ -71,6 +73,7 @@ declare function getUserFiles(): Promise<{
71
73
  allPageIds: string[];
72
74
  pageRoutes: import("../../shared/route/loadPageRoutes.js").PageRoutes;
73
75
  onBeforeRouteHook: import("../../shared/hooks/getHook.js").Hook | null;
76
+ pages: PageConfigsUserFriendly;
74
77
  config: import("../../shared/page-configs/Config/PageContextConfig.js").ConfigResolved;
75
78
  }>;
76
79
  declare function setGlobalContext_buildEntry(buildEntry: unknown): Promise<void>;
@@ -18,7 +18,7 @@ export { assertBuildInfo };
18
18
  export { getViteConfigRuntime };
19
19
  export { updateUserFiles };
20
20
  // The core logic revolves around:
21
- // - globalObject.userFiles which is the main requirement for assembleGlobalContext()
21
+ // - globalObject.userFiles which is the main requirement for resolveGlobalContext()
22
22
  // - In production: globalObject.buildEntry which is the production entry set by @brillout/vite-plugin-server-entry
23
23
  // - loadBuildEntry() sets globalObject.buildEntry and then sets globalObject.userFiles
24
24
  // - With vike-server it's set at server start: @brillout/vite-plugin-server-entry injects `import './entry.mjs'` (the production entry generated by @brillout/vite-plugin-server-entry) as first line of code of dist/server/index.mjs while dist/server/entry.mjs calls setGlobalContext_buildEntry()
@@ -32,6 +32,7 @@ import pc from '@brillout/picocolors';
32
32
  import { loadPageRoutes } from '../../shared/route/loadPageRoutes.js';
33
33
  import { assertV1Design } from '../shared/assertV1Design.js';
34
34
  import { getPageConfigsRuntime } from '../../shared/getPageConfigsRuntime.js';
35
+ import { resolveBase } from '../shared/resolveBase.js';
35
36
  const debug = createDebugger('vike:globalContext');
36
37
  const globalObject = getGlobalObject('globalContext.ts', getInitialGlobalContext());
37
38
  async function getGlobalContextInternal() {
@@ -75,8 +76,14 @@ async function getGlobalContextAsync(isProduction) {
75
76
  return globalContext_public;
76
77
  }
77
78
  function makePublic(globalContext) {
78
- // TODO/soon: add `pages`
79
- const globalContextPublic = makePublicCopy(globalContext, 'globalContext', ['assetsManifest', 'config', 'viteConfig']);
79
+ const globalContextPublic = makePublicCopy(globalContext, 'globalContext', [
80
+ 'assetsManifest',
81
+ 'config',
82
+ 'viteConfig',
83
+ 'pages',
84
+ 'baseServer',
85
+ 'baseAssets'
86
+ ]);
80
87
  return globalContextPublic;
81
88
  }
82
89
  async function setGlobalContext_viteDevServer(viteDevServer) {
@@ -180,7 +187,7 @@ function setIsProduction(isProduction) {
180
187
  globalObject.isProduction = isProduction;
181
188
  }
182
189
  function defineGlobalContext() {
183
- const globalContext = assembleGlobalContext();
190
+ const globalContext = resolveGlobalContext();
184
191
  assertIsDefined(globalContext);
185
192
  const globalContext_public = makePublic(globalContext);
186
193
  objectAssign(globalContext, { globalContext_public });
@@ -189,7 +196,7 @@ function defineGlobalContext() {
189
196
  assertGlobalContextIsDefined();
190
197
  onSetupRuntime();
191
198
  }
192
- function assembleGlobalContext() {
199
+ function resolveGlobalContext() {
193
200
  const { viteDevServer, viteConfig, isPrerendering, isProduction, userFiles } = globalObject;
194
201
  assert(typeof isProduction === 'boolean');
195
202
  let globalContext;
@@ -208,7 +215,8 @@ function assembleGlobalContext() {
208
215
  viteDevServer,
209
216
  viteConfig,
210
217
  ...userFiles,
211
- viteConfigRuntime
218
+ viteConfigRuntime,
219
+ ...resolveBaseRuntime(viteConfigRuntime, userFiles.config)
212
220
  };
213
221
  }
214
222
  else {
@@ -225,7 +233,8 @@ function assembleGlobalContext() {
225
233
  ...userFiles,
226
234
  viteDevServer: null,
227
235
  viteConfigRuntime: buildInfo.viteConfigRuntime,
228
- usesClientRouter: buildInfo.usesClientRouter
236
+ usesClientRouter: buildInfo.usesClientRouter,
237
+ ...resolveBaseRuntime(buildInfo.viteConfigRuntime, userFiles.config)
229
238
  };
230
239
  if (isPrerendering) {
231
240
  assert(viteConfig);
@@ -250,7 +259,7 @@ async function getUserFiles() {
250
259
  const globalObject_ = globalObject;
251
260
  const { pageConfigsRuntime } = globalObject_;
252
261
  assert(pageConfigsRuntime);
253
- const { pageFilesAll, allPageIds, pageConfigs, pageConfigGlobal, globalConfig } = pageConfigsRuntime;
262
+ const { pageFilesAll, allPageIds, pageConfigs, pageConfigGlobal, globalConfig, pageConfigsUserFriendly } = pageConfigsRuntime;
254
263
  const { pageRoutes, onBeforeRouteHook } = await loadPageRoutes(pageFilesAll, pageConfigs, pageConfigGlobal, allPageIds);
255
264
  const userFiles = {
256
265
  pageFilesAll,
@@ -259,6 +268,7 @@ async function getUserFiles() {
259
268
  allPageIds,
260
269
  pageRoutes,
261
270
  onBeforeRouteHook,
271
+ pages: pageConfigsUserFriendly,
262
272
  config: globalConfig.config
263
273
  };
264
274
  assertV1Design(
@@ -393,3 +403,9 @@ function getInitialGlobalContext() {
393
403
  viteDevServerPromiseResolve
394
404
  };
395
405
  }
406
+ function resolveBaseRuntime(viteConfigRuntime, config) {
407
+ const baseViteOriginal = viteConfigRuntime._baseViteOriginal;
408
+ const baseServerUnresolved = config.baseServer ?? null;
409
+ const baseAssetsUnresolved = config.baseAssets ?? null;
410
+ return resolveBase(baseViteOriginal, baseServerUnresolved, baseAssetsUnresolved);
411
+ }
@@ -1,5 +1,5 @@
1
1
  export { getViteDevScript };
2
- import type { GlobalContext } from '../../globalContext.js';
2
+ import type { GlobalContextInternal } from '../../globalContext.js';
3
3
  declare function getViteDevScript(pageContext: {
4
- _globalContext: GlobalContext;
4
+ _globalContext: GlobalContextInternal;
5
5
  }): Promise<string>;
@@ -8,7 +8,7 @@ import { type PreloadFilter } from './injectAssets/getHtmlTags.js';
8
8
  import type { StreamFromReactStreamingPackage } from './stream/react-streaming.js';
9
9
  import type { PageConfigRuntime } from '../../../shared/page-configs/PageConfig.js';
10
10
  import type { PageContextSerialization } from './serializePageContextClientSide.js';
11
- import type { GlobalContext } from '../globalContext.js';
11
+ import type { GlobalContextInternal } from '../globalContext.js';
12
12
  type PageContextInjectAssets = {
13
13
  urlPathname: string;
14
14
  __getPageAssets: () => Promise<PageAsset[]>;
@@ -22,7 +22,7 @@ type PageContextInjectAssets = {
22
22
  _baseServer: string;
23
23
  _pageConfigs: PageConfigRuntime[];
24
24
  is404: null | boolean;
25
- _globalContext: GlobalContext;
25
+ _globalContext: GlobalContextInternal;
26
26
  } & PageContextSerialization;
27
27
  declare function injectHtmlTagsToString(htmlParts: HtmlPart[], pageContext: PageContextInjectAssets & {
28
28
  _isStream: false;
@@ -2,5 +2,5 @@ export { analyzePage };
2
2
  import type { PageFile } from '../../../shared/getPageFiles/getPageFileObject.js';
3
3
  import type { PageConfigRuntime } from '../../../shared/page-configs/PageConfig.js';
4
4
  import { type AnalysisResult } from '../../../shared/getPageFiles/analyzePageClientSide.js';
5
- import type { GlobalContext } from '../globalContext.js';
6
- declare function analyzePage(pageFilesAll: PageFile[], pageConfig: null | PageConfigRuntime, pageId: string, globalContext: GlobalContext): Promise<AnalysisResult>;
5
+ import type { GlobalContextInternal } from '../globalContext.js';
6
+ declare function analyzePage(pageFilesAll: PageFile[], pageConfig: null | PageConfigRuntime, pageId: string, globalContext: GlobalContextInternal): Promise<AnalysisResult>;
@@ -5,7 +5,7 @@ export type { GetPageAssets };
5
5
  export type { PageContextGetPageAssets };
6
6
  import { type MediaType } from './inferMediaType.js';
7
7
  import type { ClientDependency } from '../../../shared/getPageFiles/analyzePageClientSide/ClientDependency.js';
8
- import type { GlobalContext } from '../globalContext.js';
8
+ import type { GlobalContextInternal } from '../globalContext.js';
9
9
  import type { ResolveClientEntriesDev } from '../../plugin/shared/resolveClientEntriesDev.js';
10
10
  type PageAsset = {
11
11
  src: string;
@@ -18,7 +18,7 @@ type PageContextGetPageAssets = {
18
18
  _baseServer: string;
19
19
  _baseAssets: string | null;
20
20
  _includeAssetsImportedByServer: boolean;
21
- _globalContext: GlobalContext;
21
+ _globalContext: GlobalContextInternal;
22
22
  };
23
23
  declare function getPageAssets(pageContext: PageContextGetPageAssets, clientDependencies: ClientDependency[], clientEntries: string[]): Promise<PageAsset[]>;
24
24
  declare function setResolveClientEntriesDev(resolveClientEntriesDev: ResolveClientEntriesDev): void;
@@ -1,5 +1,5 @@
1
1
  export { handleErrorWithoutErrorPage };
2
- import type { GlobalContext } from '../globalContext.js';
2
+ import type { GlobalContextInternal } from '../globalContext.js';
3
3
  import type { PageContextAfterRender } from './renderPageAlreadyRouted.js';
4
4
  import type { PageConfigRuntime } from '../../../shared/page-configs/PageConfig.js';
5
5
  import type { PageFile } from '../../../shared/getPageFiles.js';
@@ -10,6 +10,6 @@ declare function handleErrorWithoutErrorPage<PageContext extends {
10
10
  pageId: null;
11
11
  _pageFilesAll: PageFile[];
12
12
  _pageConfigs: PageConfigRuntime[];
13
- _globalContext: GlobalContext;
13
+ _globalContext: GlobalContextInternal;
14
14
  urlOriginal: string;
15
15
  }>(pageContext: PageContext): Promise<PageContext & PageContextAfterRender>;
@@ -6,12 +6,12 @@ import { PromiseType } from '../utils.js';
6
6
  import { PageContextGetPageAssets, type PageAsset } from './getPageAssets.js';
7
7
  import { type PageContextDebugRouteMatches } from './debugPageFiles.js';
8
8
  import type { PageConfigRuntime } from '../../../shared/page-configs/PageConfig.js';
9
- import type { GlobalContext } from '../globalContext.js';
9
+ import type { GlobalContextInternal } from '../globalContext.js';
10
10
  type PageContext_loadUserFilesServerSide = PageContextGetPageAssets & PageContextDebugRouteMatches & {
11
11
  urlOriginal: string;
12
12
  _pageFilesAll: PageFile[];
13
13
  _pageConfigs: PageConfigRuntime[];
14
- _globalContext: GlobalContext;
14
+ _globalContext: GlobalContextInternal;
15
15
  };
16
16
  type PageFiles = PromiseType<ReturnType<typeof loadUserFilesServerSide>>;
17
17
  declare function loadUserFilesServerSide(pageContext: {
@@ -12,7 +12,7 @@ async function loadUserFilesServerSide(pageContext) {
12
12
  const pageConfig = findPageConfig(pageContext._pageConfigs, pageContext.pageId); // Make pageConfig globally available as pageContext._pageConfig?
13
13
  const globalContext = pageContext._globalContext;
14
14
  const [{ pageFilesLoaded, pageContextExports }] = await Promise.all([
15
- loadPageUserFiles(pageContext._pageFilesAll, pageConfig, pageContext.pageId, !globalContext.isProduction),
15
+ loadPageUserFiles(pageContext._pageFilesAll, pageConfig, globalContext.pageConfigGlobal, pageContext.pageId, !globalContext.isProduction),
16
16
  analyzePageClientSideInit(pageContext._pageFilesAll, pageContext.pageId, { sharedPageFilesAlreadyLoaded: true })
17
17
  ]);
18
18
  const { isHtmlOnly, isClientRouting, clientEntries, clientDependencies, pageFilesClientSide, pageFilesServerSide } = await analyzePage(pageContext._pageFilesAll, pageConfig, pageContext.pageId, globalContext);
@@ -96,11 +96,11 @@ async function loadUserFilesServerSide(pageContext) {
96
96
  }
97
97
  return pageContextAddendum;
98
98
  }
99
- async function loadPageUserFiles(pageFilesAll, pageConfig, pageId, isDev) {
99
+ async function loadPageUserFiles(pageFilesAll, pageConfig, pageConfigGlobal, pageId, isDev) {
100
100
  const pageFilesServerSide = getPageFilesServerSide(pageFilesAll, pageId);
101
101
  const pageConfigLoaded = !pageConfig ? null : await loadConfigValues(pageConfig, isDev);
102
102
  await Promise.all(pageFilesServerSide.map((p) => p.loadFile?.()));
103
- const pageContextExports = getPageConfigUserFriendlyOld(pageFilesServerSide, pageConfigLoaded);
103
+ const pageContextExports = getPageConfigUserFriendlyOld(pageFilesServerSide, pageConfigLoaded, pageConfigGlobal);
104
104
  return {
105
105
  pageContextExports,
106
106
  pageFilesLoaded: pageFilesServerSide
@@ -1,12 +1,12 @@
1
1
  export { log404 };
2
2
  export { getRoutesInfo };
3
3
  import type { PageRoutes } from '../../../../shared/route/index.js';
4
- import type { GlobalContext } from '../../globalContext.js';
4
+ import type { GlobalContextInternal } from '../../globalContext.js';
5
5
  declare function log404(pageContext: {
6
6
  urlPathname: string;
7
7
  errorWhileRendering: null | Error;
8
8
  isClientSideNavigation: boolean;
9
9
  _pageRoutes: PageRoutes;
10
- _globalContext: GlobalContext;
10
+ _globalContext: GlobalContextInternal;
11
11
  }): Promise<void>;
12
12
  declare function getRoutesInfo(pageRoutes: PageRoutes): string | null;
@@ -4,7 +4,7 @@ import { PageContextUrlInternal } from '../../../shared/getPageContextUrlCompute
4
4
  import type { PageConfigRuntime } from '../../../shared/page-configs/PageConfig.js';
5
5
  import type { PageConfigUserFriendly } from '../../../shared/page-configs/getPageConfigUserFriendly.js';
6
6
  import { PageContextBuiltInServerInternal } from '../../../shared/types.js';
7
- import type { GlobalContext, GlobalContextPublic } from '../globalContext.js';
7
+ import type { GlobalContextInternal, GlobalContextPublic } from '../globalContext.js';
8
8
  type PageContextForUserConsumptionServerSide = PageContextBuiltInServerInternal & PageConfigUserFriendly & {
9
9
  urlOriginal: string;
10
10
  /** @deprecated */
@@ -18,7 +18,7 @@ type PageContextForUserConsumptionServerSide = PageContextBuiltInServerInternal
18
18
  is404: null | boolean;
19
19
  isClientSideNavigation: boolean;
20
20
  pageProps?: Record<string, unknown>;
21
- _globalContext: GlobalContext;
21
+ _globalContext: GlobalContextInternal;
22
22
  globalContext: GlobalContextPublic;
23
23
  } & Record<string, unknown>;
24
24
  declare function preparePageContextForUserConsumptionServerSide(pageContext: PageContextForUserConsumptionServerSide): void;