vike 0.4.220-commit-5c7810f → 0.4.220-commit-af5c91f

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 (120) hide show
  1. package/dist/cjs/node/api/utils.js +1 -1
  2. package/dist/cjs/node/plugin/index.js +1 -1
  3. package/dist/cjs/node/plugin/onLoad.js +1 -1
  4. package/dist/cjs/node/plugin/plugins/buildConfig/fixServerAssets.js +5 -3
  5. package/dist/cjs/node/plugin/plugins/buildConfig.js +7 -5
  6. package/dist/cjs/node/plugin/plugins/buildEntry/index.js +2 -1
  7. package/dist/cjs/node/plugin/plugins/commonConfig.js +1 -2
  8. package/dist/cjs/node/plugin/plugins/extractAssetsPlugin.js +3 -2
  9. package/dist/cjs/node/plugin/plugins/extractExportNamesPlugin.js +2 -1
  10. package/dist/cjs/node/plugin/plugins/importUserCode/getVirtualFileImportUserCode.js +10 -8
  11. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +32 -41
  12. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolvePointerImport.js +9 -64
  13. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +11 -5
  14. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +281 -313
  15. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +2 -1
  16. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +7 -6
  17. package/dist/cjs/node/plugin/plugins/packageJsonFile.js +2 -2
  18. package/dist/cjs/node/plugin/plugins/previewConfig.js +4 -3
  19. package/dist/cjs/node/plugin/plugins/setGlobalContext.js +2 -1
  20. package/dist/cjs/node/plugin/shared/findPageFiles.js +2 -1
  21. package/dist/cjs/node/plugin/{getOutDirs.js → shared/getOutDirs.js} +24 -27
  22. package/dist/cjs/node/plugin/{resolveClientEntriesDev.js → shared/resolveClientEntriesDev.js} +5 -8
  23. package/dist/cjs/{utils → node/plugin/shared}/viteIsSSR.js +2 -2
  24. package/dist/cjs/node/plugin/utils.js +0 -1
  25. package/dist/cjs/node/prerender/context.js +8 -3
  26. package/dist/cjs/node/prerender/resolvePrerenderConfig.js +26 -5
  27. package/dist/cjs/node/prerender/runPrerender.js +6 -11
  28. package/dist/cjs/node/prerender/utils.js +1 -2
  29. package/dist/cjs/node/runtime/html/injectAssets/getHtmlTags.js +9 -4
  30. package/dist/cjs/node/runtime/renderPage/getEarlyHints.js +2 -27
  31. package/dist/cjs/node/runtime/renderPage/isFontFallback.js +29 -0
  32. package/dist/cjs/node/runtime/utils.js +1 -3
  33. package/dist/cjs/shared/getPageFiles/fileTypes.js +0 -1
  34. package/dist/cjs/shared/getPageFiles/getAllPageIdFiles.js +0 -3
  35. package/dist/cjs/shared/getPageFiles/getPageFileObject.js +0 -5
  36. package/dist/cjs/shared/page-configs/serialize/serializeConfigValues.js +69 -18
  37. package/dist/cjs/shared/utils.js +0 -1
  38. package/dist/cjs/utils/PROJECT_VERSION.js +1 -1
  39. package/dist/cjs/utils/findFile.js +3 -3
  40. package/dist/cjs/utils/isDev.js +2 -5
  41. package/dist/cjs/utils/isFilePathAbsoluteFilesystem.js +2 -2
  42. package/dist/cjs/utils/path.js +48 -0
  43. package/dist/cjs/utils/requireResolve.js +3 -3
  44. package/dist/esm/node/api/utils.d.ts +1 -1
  45. package/dist/esm/node/api/utils.js +1 -1
  46. package/dist/esm/node/plugin/index.js +1 -1
  47. package/dist/esm/node/plugin/onLoad.js +1 -1
  48. package/dist/esm/node/plugin/plugins/buildConfig/fixServerAssets.js +3 -1
  49. package/dist/esm/node/plugin/plugins/buildConfig.js +3 -1
  50. package/dist/esm/node/plugin/plugins/buildEntry/index.js +2 -1
  51. package/dist/esm/node/plugin/plugins/commonConfig.js +2 -3
  52. package/dist/esm/node/plugin/plugins/extractAssetsPlugin.js +2 -1
  53. package/dist/esm/node/plugin/plugins/extractExportNamesPlugin.js +2 -1
  54. package/dist/esm/node/plugin/plugins/importUserCode/getVirtualFileImportUserCode.js +9 -7
  55. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.d.ts +14 -11
  56. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/loadFileAtConfigTime.js +35 -44
  57. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolvePointerImport.d.ts +8 -18
  58. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/resolvePointerImport.js +10 -65
  59. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.d.ts +6 -2
  60. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/transpileAndExecuteFile.js +12 -6
  61. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.d.ts +8 -6
  62. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +284 -316
  63. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +2 -1
  64. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +7 -6
  65. package/dist/esm/node/plugin/plugins/packageJsonFile.js +1 -1
  66. package/dist/esm/node/plugin/plugins/previewConfig.js +2 -1
  67. package/dist/esm/node/plugin/plugins/setGlobalContext.js +2 -1
  68. package/dist/esm/node/plugin/shared/findPageFiles.js +2 -1
  69. package/dist/esm/node/plugin/{getOutDirs.js → shared/getOutDirs.js} +2 -5
  70. package/dist/esm/node/plugin/{resolveClientEntriesDev.js → shared/resolveClientEntriesDev.js} +5 -8
  71. package/dist/esm/{utils → node/plugin/shared}/viteIsSSR.js +2 -2
  72. package/dist/esm/node/plugin/utils.d.ts +0 -1
  73. package/dist/esm/node/plugin/utils.js +0 -1
  74. package/dist/esm/node/prerender/context.d.ts +2 -0
  75. package/dist/esm/node/prerender/context.js +8 -3
  76. package/dist/esm/node/prerender/resolvePrerenderConfig.d.ts +8 -1
  77. package/dist/esm/node/prerender/resolvePrerenderConfig.js +26 -5
  78. package/dist/esm/node/prerender/runPrerender.js +7 -12
  79. package/dist/esm/node/prerender/utils.d.ts +1 -2
  80. package/dist/esm/node/prerender/utils.js +1 -2
  81. package/dist/esm/node/runtime/html/injectAssets/getHtmlTags.js +9 -4
  82. package/dist/esm/node/runtime/renderPage/getEarlyHints.js +1 -26
  83. package/dist/esm/node/runtime/renderPage/getPageAssets.d.ts +1 -1
  84. package/dist/esm/node/runtime/renderPage/isFontFallback.d.ts +3 -0
  85. package/dist/esm/node/runtime/renderPage/isFontFallback.js +27 -0
  86. package/dist/esm/node/runtime/utils.d.ts +1 -3
  87. package/dist/esm/node/runtime/utils.js +1 -3
  88. package/dist/esm/shared/getPageFiles/fileTypes.js +1 -2
  89. package/dist/esm/shared/getPageFiles/getAllPageIdFiles.js +0 -3
  90. package/dist/esm/shared/getPageFiles/getPageFileObject.js +0 -5
  91. package/dist/esm/shared/page-configs/PageConfig.d.ts +0 -1
  92. package/dist/esm/shared/page-configs/serialize/serializeConfigValues.d.ts +7 -1
  93. package/dist/esm/shared/page-configs/serialize/serializeConfigValues.js +70 -19
  94. package/dist/esm/shared/utils.d.ts +0 -1
  95. package/dist/esm/shared/utils.js +0 -1
  96. package/dist/esm/utils/PROJECT_VERSION.d.ts +1 -1
  97. package/dist/esm/utils/PROJECT_VERSION.js +1 -1
  98. package/dist/esm/utils/findFile.js +1 -1
  99. package/dist/esm/utils/isDev.js +3 -6
  100. package/dist/esm/utils/isFilePathAbsoluteFilesystem.js +1 -1
  101. package/dist/esm/utils/path.d.ts +14 -0
  102. package/dist/esm/utils/path.js +46 -0
  103. package/dist/esm/utils/projectInfo.d.ts +1 -1
  104. package/dist/esm/utils/requireResolve.js +1 -1
  105. package/package.json +1 -1
  106. package/dist/cjs/node/plugin/plugins/importUserCode/addImportStatement.js +0 -29
  107. package/dist/cjs/shared/assertPageFilePath.js +0 -11
  108. package/dist/cjs/utils/path-shim.js +0 -19
  109. package/dist/cjs/utils/toPosixPath.js +0 -18
  110. package/dist/esm/node/plugin/plugins/importUserCode/addImportStatement.d.ts +0 -14
  111. package/dist/esm/node/plugin/plugins/importUserCode/addImportStatement.js +0 -27
  112. package/dist/esm/shared/assertPageFilePath.d.ts +0 -2
  113. package/dist/esm/shared/assertPageFilePath.js +0 -9
  114. package/dist/esm/utils/path-shim.d.ts +0 -2
  115. package/dist/esm/utils/path-shim.js +0 -17
  116. package/dist/esm/utils/toPosixPath.d.ts +0 -4
  117. package/dist/esm/utils/toPosixPath.js +0 -16
  118. /package/dist/esm/node/plugin/{getOutDirs.d.ts → shared/getOutDirs.d.ts} +0 -0
  119. /package/dist/esm/node/plugin/{resolveClientEntriesDev.d.ts → shared/resolveClientEntriesDev.d.ts} +0 -0
  120. /package/dist/esm/{utils → node/plugin/shared}/viteIsSSR.d.ts +0 -0
@@ -6,8 +6,7 @@ export { isVikeConfigFile };
6
6
  export { isV1Design };
7
7
  export { getConfVal };
8
8
  export { getConfigDefinitionOptional };
9
- export { shouldBeLoadableAtBuildTime };
10
- import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, includes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, lowerFirst, assertKeys, objectKeys, objectFromEntries, makeFirst, isNpmPackageImport, reverse, unique } from '../../../utils.js';
9
+ import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, includes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, lowerFirst, assertKeys, objectKeys, objectFromEntries, makeFirst, isNpmPackageImport, reverse, unique, isCallable } from '../../../utils.js';
11
10
  import path from 'path';
12
11
  import { configDefinitionsBuiltInAll } from './getVikeConfig/configDefinitionsBuiltIn.js';
13
12
  import { getLocationId, getFilesystemRouteString, getFilesystemRouteDefinedBy, isInherited, sortAfterInheritanceOrder, isGlobalLocation, applyFilesystemRoutingRootEffect } from './getVikeConfig/filesystemRouting.js';
@@ -20,15 +19,13 @@ import pc from '@brillout/picocolors';
20
19
  import { getConfigDefinedAt } from '../../../../../shared/page-configs/getConfigDefinedAt.js';
21
20
  import { crawlPlusFiles } from './getVikeConfig/crawlPlusFiles.js';
22
21
  import { getConfigFileExport } from './getConfigFileExport.js';
23
- import { loadConfigFile, loadImportedFile, loadValueFile, loadValueFiles } from './getVikeConfig/loadFileAtConfigTime.js';
24
- import { clearFilesEnvMap, resolveConfigEnvWithFileName, resolvePointerImportOfConfig } from './getVikeConfig/resolvePointerImport.js';
22
+ import { loadConfigFile, loadPointerImport, loadValueFile } from './getVikeConfig/loadFileAtConfigTime.js';
23
+ import { resolvePointerImport } from './getVikeConfig/resolvePointerImport.js';
25
24
  import { getFilePathResolved } from '../../../shared/getFilePath.js';
26
25
  import { getConfigValueBuildTime } from '../../../../../shared/page-configs/getConfigValueBuildTime.js';
27
26
  import { assertExtensionsRequire, assertExtensionsConventions } from './assertExtensions.js';
28
27
  import { getPageConfigUserFriendlyNew } from '../../../../../shared/page-configs/getPageConfigUserFriendly.js';
29
28
  import { getConfigValuesBase } from '../../../../../shared/page-configs/serialize/serializeConfigValues.js';
30
- const configDefinitionsBuiltIn = getConfigDefinitionsBuiltIn();
31
- const configDefinitionsBuiltInGlobal = getConfigDefinitionsBuiltInGlobal();
32
29
  assertIsNotProductionRuntime();
33
30
  let restartVite = false;
34
31
  let wasConfigInvalid = null;
@@ -39,7 +36,6 @@ function reloadVikeConfig(config) {
39
36
  const vikeVitePluginOptions = config._vikeVitePluginOptions;
40
37
  assert(vikeVitePluginOptions);
41
38
  vikeConfigDependencies.clear();
42
- clearFilesEnvMap();
43
39
  vikeConfigPromise = loadVikeConfig_withErrorHandling(userRootDir, true, vikeVitePluginOptions);
44
40
  handleReloadSideEffects();
45
41
  }
@@ -98,7 +94,7 @@ async function isV1Design(config) {
98
94
  const isV1Design = pageConfigs.length > 0;
99
95
  return isV1Design;
100
96
  }
101
- async function loadInterfaceFiles(userRootDir) {
97
+ async function loadInterfaceFiles(userRootDir, esbuildCache) {
102
98
  const plusFiles = await findPlusFiles(userRootDir, null);
103
99
  const configFiles = [];
104
100
  const valueFiles = [];
@@ -116,10 +112,10 @@ async function loadInterfaceFiles(userRootDir) {
116
112
  ...configFiles.map(async (filePath) => {
117
113
  const { filePathAbsoluteUserRootDir } = filePath;
118
114
  assert(filePathAbsoluteUserRootDir);
119
- const { configFile, extendsConfigs } = await loadConfigFile(filePath, userRootDir, [], false);
115
+ const { configFile, extendsConfigs } = await loadConfigFile(filePath, userRootDir, [], false, esbuildCache);
120
116
  assert(filePath.filePathAbsoluteUserRootDir);
121
117
  const locationId = getLocationId(filePathAbsoluteUserRootDir);
122
- const interfaceFile = getInterfaceFileFromConfigFile(configFile, false, locationId);
118
+ const interfaceFile = getInterfaceFileFromConfigFile(configFile, false, locationId, userRootDir);
123
119
  interfaceFilesAll[locationId] = interfaceFilesAll[locationId] ?? [];
124
120
  interfaceFilesAll[locationId].push(interfaceFile);
125
121
  extendsConfigs.forEach((extendsConfig) => {
@@ -139,7 +135,7 @@ async function loadInterfaceFiles(userRootDir) {
139
135
  export default { extends: [vikeReact] }
140
136
  ```
141
137
  */
142
- const interfaceFile = getInterfaceFileFromConfigFile(extendsConfig, true, locationId);
138
+ const interfaceFile = getInterfaceFileFromConfigFile(extendsConfig, true, locationId, userRootDir);
143
139
  assertExtensionsConventions(interfaceFile);
144
140
  interfaceFilesAll[locationId].push(interfaceFile);
145
141
  });
@@ -156,7 +152,7 @@ async function loadInterfaceFiles(userRootDir) {
156
152
  filePath,
157
153
  isConfigFile: false,
158
154
  isValueFile: true,
159
- isValueLoaded: false,
155
+ isValueFileLoaded: false,
160
156
  configName
161
157
  };
162
158
  interfaceFilesAll[locationId] = interfaceFilesAll[locationId] ?? [];
@@ -164,45 +160,40 @@ async function loadInterfaceFiles(userRootDir) {
164
160
  // We don't have access to the custom config definitions defined by the user yet.
165
161
  // - If `configDef` is `undefined` => we load the file +{configName}.js later.
166
162
  // - We already need to load +meta.js here (to get the custom config definitions defined by the user)
167
- await loadValueFile(interfaceFile, configDefinitionsBuiltIn, userRootDir);
163
+ await loadValueFile(interfaceFile, configDefinitionsBuiltInAll, userRootDir, esbuildCache);
168
164
  })
169
165
  ]);
170
- assertAllConfigsAreKnown(interfaceFilesAll);
166
+ assertKnownConfigs(interfaceFilesAll);
171
167
  return interfaceFilesAll;
172
168
  }
173
- function getInterfaceFileFromConfigFile(configFile, isConfigExtend, locationId) {
169
+ function getInterfaceFileFromConfigFile(configFile, isConfigExtension, locationId, userRootDir) {
174
170
  const { fileExports, filePath, extendsFilePaths } = configFile;
171
+ const fileExportsByConfigName = {};
172
+ const pointerImportsByConfigName = {};
173
+ const fileExport = getConfigFileExport(fileExports, filePath.filePathToShowToUser);
174
+ Object.entries(fileExport).forEach(([configName, configValue]) => {
175
+ fileExportsByConfigName[configName] = configValue;
176
+ const pointerImport = resolvePointerImport(configValue, configFile.filePath, userRootDir, configName);
177
+ if (pointerImport) {
178
+ pointerImportsByConfigName[configName] = {
179
+ ...pointerImport,
180
+ fileExportValueLoaded: false
181
+ };
182
+ }
183
+ });
175
184
  const interfaceFile = {
176
185
  locationId,
177
186
  filePath,
178
- fileExportsByConfigName: {},
187
+ fileExportsByConfigName,
188
+ pointerImportsByConfigName,
179
189
  isConfigFile: true,
180
190
  isValueFile: false,
181
- isValueLoaded: true,
182
- isConfigExtend,
191
+ isValueFileLoaded: true,
192
+ isConfigExtension,
183
193
  extendsFilePaths
184
194
  };
185
- const fileExport = getConfigFileExport(fileExports, filePath.filePathToShowToUser);
186
- Object.entries(fileExport).forEach(([configName, configValue]) => {
187
- interfaceFile.fileExportsByConfigName[configName] = configValue;
188
- });
189
195
  return interfaceFile;
190
196
  }
191
- /** Show error message upon unknown config */
192
- function assertAllConfigsAreKnown(interfaceFilesAll) {
193
- objectEntries(interfaceFilesAll).forEach(([locationId, interfaceFiles]) => {
194
- const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesAll, locationId);
195
- const configDefinitions = getConfigDefinitions(interfaceFilesRelevant);
196
- interfaceFiles.forEach((interfaceFile) => {
197
- const configNamesKnown = Object.keys(configDefinitions);
198
- const { filePathToShowToUser } = interfaceFile.filePath;
199
- const configNames = getDefiningConfigNames(interfaceFile);
200
- configNames.forEach((configName) => {
201
- assertConfigExists(configName, configNamesKnown, filePathToShowToUser);
202
- });
203
- });
204
- });
205
- }
206
197
  async function loadVikeConfig_withErrorHandling(userRootDir, isDev, vikeVitePluginOptions, doNotRestartViteOnError) {
207
198
  let hasError = false;
208
199
  let ret;
@@ -237,7 +228,6 @@ async function loadVikeConfig_withErrorHandling(userRootDir, isDev, vikeVitePlug
237
228
  pageConfigs: [],
238
229
  pageConfigGlobal: {
239
230
  configDefinitions: {},
240
- interfaceFiles: {},
241
231
  configValueSources: {}
242
232
  },
243
233
  global: getPageConfigUserFriendlyNew({ configValues: {} })
@@ -247,9 +237,10 @@ async function loadVikeConfig_withErrorHandling(userRootDir, isDev, vikeVitePlug
247
237
  }
248
238
  }
249
239
  async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
250
- const interfaceFilesAll = await loadInterfaceFiles(userRootDir);
251
- const importedFilesLoaded = {};
252
- const { pageConfigGlobal, pageConfigs } = await getPageConfigs(interfaceFilesAll, userRootDir, importedFilesLoaded);
240
+ const esbuildCache = {};
241
+ const interfaceFilesAll = await loadInterfaceFiles(userRootDir, esbuildCache);
242
+ const configDefinitionsResolved = await resolveConfigDefinitions(interfaceFilesAll, userRootDir, esbuildCache);
243
+ const { pageConfigGlobal, pageConfigs } = getPageConfigs(configDefinitionsResolved, interfaceFilesAll, userRootDir);
253
244
  // interop vike(options) in vite.config.js
254
245
  temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, userRootDir);
255
246
  // global
@@ -257,183 +248,140 @@ async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
257
248
  const global = getPageConfigUserFriendlyNew({ configValues });
258
249
  return { pageConfigs, pageConfigGlobal, global };
259
250
  }
260
- async function getGlobalConfigs(interfaceFilesAll, userRootDir, importedFilesLoaded) {
261
- /* TODO/now: dedupe
262
- // Validate that global configs live in global interface files
263
- {
264
- const interfaceFilesGlobalPaths: string[] = []
265
- objectEntries(interfaceFilesGlobal).forEach(([locationId, interfaceFiles]) => {
266
- assert(isGlobalLocation(locationId, locationIds))
267
- interfaceFiles.forEach(({ filePath: { filePathAbsoluteUserRootDir } }) => {
268
- if (filePathAbsoluteUserRootDir) {
269
- interfaceFilesGlobalPaths.push(filePathAbsoluteUserRootDir)
270
- }
271
- })
272
- })
273
- const globalPaths = Array.from(new Set(interfaceFilesGlobalPaths.map((p) => path.posix.dirname(p))))
274
- objectEntries(interfaceFilesAll).forEach(([locationId, interfaceFiles]) => {
275
- interfaceFiles.forEach((interfaceFile) => {
276
- Object.keys(interfaceFile.fileExportsByConfigName).forEach((configName) => {
277
- if (!isGlobalLocation(locationId, locationIds) && isGlobalConfigOld(configName)) {
278
- assertUsage(
279
- false,
280
- [
281
- `${interfaceFile.filePath.filePathToShowToUser} defines the config ${pc.cyan(
282
- configName
283
- )} which is global:`,
284
- globalPaths.length
285
- ? `define ${pc.cyan(configName)} in ${joinEnglish(globalPaths, 'or')} instead`
286
- : `create a global config (e.g. /pages/+config.js) and define ${pc.cyan(configName)} there instead`
287
- ].join(' ')
288
- )
289
- }
290
- })
291
- })
292
- })
293
- }
294
- //*/
295
- }
296
- function temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, userRootDir) {
297
- assert(isObject(vikeVitePluginOptions));
298
- assertWarning(Object.keys(vikeVitePluginOptions).length === 0, `Define Vike settings in +config.js instead of vite.config.js ${pc.underline('https://vike.dev/migration/settings')}`, { onlyOnce: true });
299
- Object.entries(vikeVitePluginOptions).forEach(([configName, value]) => {
300
- var _a;
301
- assert(includes(objectKeys(configDefinitionsBuiltInGlobal), configName));
302
- const configDef = configDefinitionsBuiltInGlobal[configName];
303
- const sources = ((_a = pageConfigGlobal.configValueSources)[configName] ?? (_a[configName] = []));
304
- sources.push({
305
- value,
306
- configEnv: configDef.env,
307
- definedAtFilePath: {
308
- ...getFilePathResolved({
309
- userRootDir,
310
- filePathAbsoluteUserRootDir: '/vite.config.js'
311
- }),
312
- fileExportPathToShowToUser: null
313
- },
314
- locationId: '/',
315
- interfaceFile: null,
316
- isOverriden: configDef.cumulative ? false : sources.length > 0,
317
- valueIsImportedAtRuntime: false,
318
- valueIsDefinedByPlusFile: false
319
- });
320
- });
251
+ async function resolveConfigDefinitions(interfaceFilesAll, userRootDir, esbuildCache) {
252
+ const configDefinitionsGlobal = getConfigDefinitions(
253
+ // We use `interfaceFilesAll` in order to allow local Vike extensions to create global configs.
254
+ interfaceFilesAll, // TODO/now sort
255
+ (configDef) => !!configDef.global);
256
+ await loadCustomConfigBuildTimeFiles(interfaceFilesAll, configDefinitionsGlobal, userRootDir, esbuildCache);
257
+ const configDefinitionsLocal = {};
258
+ await Promise.all(objectEntries(interfaceFilesAll).map(async ([locationId, interfaceFiles]) => {
259
+ const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesAll, locationId);
260
+ // configDefinitions = getConfigDefinitions(interfaceFilesRelevant, (configDef) => configDef.global !== true) // TODO/now
261
+ const configDefinitions = getConfigDefinitions(interfaceFilesRelevant);
262
+ await loadCustomConfigBuildTimeFiles(interfaceFiles, configDefinitions, userRootDir, esbuildCache);
263
+ configDefinitionsLocal[locationId] = { configDefinitions, interfaceFiles, interfaceFilesRelevant };
264
+ }));
265
+ const configDefinitionsResolved = {
266
+ configDefinitionsGlobal,
267
+ configDefinitionsLocal
268
+ };
269
+ return configDefinitionsResolved;
321
270
  }
322
- async function getPageConfigs(interfaceFilesAll, userRootDir, importedFilesLoaded) {
323
- const locationIds = objectKeys(interfaceFilesAll);
324
- const interfaceFilesGlobal = objectFromEntries(objectEntries(interfaceFilesAll).filter(([locationId]) => {
325
- return isGlobalLocation(locationId, locationIds);
271
+ // Load value files (with `env.config===true`) of *custom* configs.
272
+ // - The value files of *built-in* configs are already loaded at `loadInterfaceFiles()`.
273
+ async function loadCustomConfigBuildTimeFiles(interfaceFiles, configDefinitions, userRootDir, esbuildCache) {
274
+ const interfaceFileList = Object.values(interfaceFiles).flat(1);
275
+ await Promise.all(interfaceFileList.map(async (interfaceFile) => {
276
+ if (interfaceFile.isValueFile) {
277
+ await loadValueFile(interfaceFile, configDefinitions, userRootDir, esbuildCache);
278
+ }
279
+ else {
280
+ await Promise.all(Object.entries(interfaceFile.pointerImportsByConfigName).map(async ([configName, pointerImport]) => {
281
+ await loadPointerImport(pointerImport, userRootDir, configName, configDefinitions, esbuildCache);
282
+ }));
283
+ }
326
284
  }));
285
+ }
286
+ function getPageConfigs(configDefinitionsResolved, interfaceFilesAll, userRootDir) {
327
287
  const pageConfigGlobal = {
328
- configDefinitions: configDefinitionsBuiltInGlobal,
329
- interfaceFiles: interfaceFilesGlobal,
288
+ configDefinitions: configDefinitionsResolved.configDefinitionsGlobal,
330
289
  configValueSources: {}
331
290
  };
332
- await Promise.all(objectEntries(configDefinitionsBuiltInGlobal).map(async ([configName, configDef]) => {
333
- const sources = await resolveConfigValueSources(configName, configDef, interfaceFilesGlobal, userRootDir, importedFilesLoaded);
334
- const configValueSource = sources[0];
335
- if (!configValueSource)
291
+ objectEntries(configDefinitionsResolved.configDefinitionsGlobal).forEach(([configName, configDef]) => {
292
+ const sources = resolveConfigValueSources(configName, configDef,
293
+ // We use `interfaceFilesAll` in order to allow local Vike extensions to set the value of global configs (e.g. `vite`).
294
+ interfaceFilesAll, // TODO/now check sort order
295
+ userRootDir, true);
296
+ if (sources.length === 0)
336
297
  return;
337
298
  pageConfigGlobal.configValueSources[configName] = sources;
338
- }));
339
- const pageConfigs = [];
340
- await Promise.all(getPageLocationIds(interfaceFilesAll).map(async (locationId) => {
341
- const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesAll, locationId);
342
- const configDefinitions = getConfigDefinitions(interfaceFilesRelevant);
343
- // Load value files (with `env.config===true`) of *custom* configs.
344
- // - The value files of *built-in* configs are already loaded at `loadInterfaceFiles()`.
345
- await loadValueFiles(interfaceFilesRelevant, configDefinitions, userRootDir);
299
+ });
300
+ assertPageConfigGlobal(pageConfigGlobal, interfaceFilesAll);
301
+ const pageConfigs = objectEntries(configDefinitionsResolved.configDefinitionsLocal)
302
+ .filter(([_locationId, { interfaceFiles }]) => isDefiningPage(interfaceFiles))
303
+ .map(([locationId, { configDefinitions, interfaceFilesRelevant }]) => {
304
+ const configDefinitionsLocal = configDefinitions;
346
305
  let configValueSources = {};
347
- await Promise.all(objectEntries(configDefinitions)
348
- .filter(([configName]) => !isGlobalConfigOld(configName))
349
- .map(async ([configName, configDef]) => {
350
- const sources = await resolveConfigValueSources(configName, configDef, interfaceFilesRelevant, userRootDir, importedFilesLoaded);
306
+ objectEntries(configDefinitionsLocal)
307
+ .filter(([_configName, configDef]) => configDef.global !== true)
308
+ .forEach(([configName, configDef]) => {
309
+ const sources = resolveConfigValueSources(configName, configDef, interfaceFilesRelevant, userRootDir, false);
351
310
  if (sources.length === 0)
352
311
  return;
312
+ // assertUsage(!isGlobalConfig(configName, configDefinitionsLocal, sources), 'TODO') // TODO/now
353
313
  configValueSources[configName] = sources;
354
- }));
314
+ });
355
315
  configValueSources = sortConfigValueSources(configValueSources, locationId);
356
316
  const { routeFilesystem, isErrorPage } = determineRouteFilesystem(locationId, configValueSources);
357
- applyEffectsAll(configValueSources, configDefinitions);
358
- const configValuesComputed = getComputed(configValueSources, configDefinitions);
317
+ applyEffectsAll(configValueSources, configDefinitionsLocal);
318
+ const configValuesComputed = getComputed(configValueSources, configDefinitionsLocal);
359
319
  const pageConfig = {
360
320
  pageId: locationId,
361
321
  isErrorPage,
362
322
  routeFilesystem,
363
- configDefinitions,
323
+ configDefinitions: configDefinitionsLocal,
364
324
  interfaceFiles: interfaceFilesRelevant,
365
325
  configValueSources,
366
326
  configValuesComputed
367
327
  };
368
- pageConfigs.push(pageConfig);
369
- }));
370
- assertPageConfigs(pageConfigs, interfaceFilesAll);
328
+ return pageConfig;
329
+ });
330
+ assertPageConfigs(pageConfigs);
371
331
  return { pageConfigs, pageConfigGlobal };
372
332
  }
373
- function getPageLocationIds(interfaceFilesAll) {
374
- const locationIds = new Set();
375
- objectEntries(interfaceFilesAll).forEach(([locationId, interfaceFiles]) => {
376
- if (isDefiningPage(interfaceFiles)) {
377
- locationIds.add(locationId);
333
+ function assertPageConfigGlobal(pageConfigGlobal, interfaceFilesAll) {
334
+ Object.entries(pageConfigGlobal.configValueSources).forEach(([configName, sources]) => {
335
+ assertGlobalConfigLocation(configName, sources, interfaceFilesAll, pageConfigGlobal.configDefinitions);
336
+ });
337
+ }
338
+ function assertGlobalConfigLocation(configName, sources, interfaceFilesAll, configDefinitionsGlobal) {
339
+ const locationIdsAll = objectKeys(interfaceFilesAll);
340
+ // Determine existing global +config.js files
341
+ const configFilePathsGlobal = [];
342
+ const interfaceFilesGlobal = Object.values(objectFromEntries(objectEntries(interfaceFilesAll).filter(([locationId]) => isGlobalLocation(locationId, locationIdsAll)))).flat();
343
+ interfaceFilesGlobal
344
+ .filter((i) => i.isConfigFile)
345
+ .forEach((interfaceFile) => {
346
+ const { filePathAbsoluteUserRootDir } = interfaceFile.filePath;
347
+ if (filePathAbsoluteUserRootDir) {
348
+ configFilePathsGlobal.push(filePathAbsoluteUserRootDir);
349
+ }
350
+ });
351
+ // Call assertWarning()
352
+ sources.forEach((source) => {
353
+ const { interfaceFile } = source;
354
+ // It's `null` when the config is defined by `vike(options)` in vite.config.js
355
+ assert(interfaceFile);
356
+ const { filePathAbsoluteUserRootDir } = interfaceFile.filePath;
357
+ // Allow local Vike extensions to set gloabl configs (`filePathAbsoluteUserRootDir===null` for Vike extension)
358
+ if (!filePathAbsoluteUserRootDir)
359
+ return;
360
+ assert(!interfaceFile.isConfigExtension);
361
+ if (!isGlobalLocation(source.locationId, locationIdsAll)) {
362
+ const configDef = configDefinitionsGlobal[configName];
363
+ assert(configDef);
364
+ const isConditionallyGlobal = isCallable(configDef.global);
365
+ const errBeg = `${filePathAbsoluteUserRootDir} (which is a local config file) sets the config ${pc.cyan(configName)}`;
366
+ const errMid = !isConditionallyGlobal
367
+ ? "but it's a global config"
368
+ : 'to a value that is global';
369
+ const what = isConditionallyGlobal ? 'global values' : pc.cyan(configName);
370
+ const errEnd = configFilePathsGlobal.length > 0
371
+ ? `define ${what} at a global config file such as ${joinEnglish(configFilePathsGlobal, 'or')} instead`
372
+ : `create a global config file (e.g. /pages/+config.js) and define ${what} there instead`;
373
+ // When updating this error message => also update error message at https://vike.dev/warning/global-config
374
+ const errMsg = `${errBeg} ${errMid}: ${errEnd} (https://vike.dev/warning/global-config).`;
375
+ assertWarning(false, errMsg, { onlyOnce: true });
378
376
  }
379
377
  });
380
- return Array.from(locationIds);
381
378
  }
382
- function assertPageConfigs(pageConfigs, interfaceFilesAll) {
379
+ function assertPageConfigs(pageConfigs) {
383
380
  pageConfigs.forEach((pageConfig) => {
384
- assertGlobalConfigs(pageConfig, interfaceFilesAll);
385
381
  assertExtensionsRequire(pageConfig);
386
382
  assertOnBeforeRenderEnv(pageConfig);
387
383
  });
388
384
  }
389
- // TODO/now: refactor
390
- // - Dedupe: most of the assertGlobalConfigs() code below is a copy-paste of the assertUsage() logic inside getGlobalConfigs()
391
- // - This assertUsage() message is slightly better: use this one for getGlobalConfigs()
392
- // Global configs should be defined at global locations
393
- function assertGlobalConfigs(pageConfig, interfaceFilesAll) {
394
- const interfaceFilesRelevantList = Object.values(pageConfig.interfaceFiles).flat(1);
395
- const { configDefinitions } = pageConfig;
396
- interfaceFilesRelevantList.forEach((interfaceFile) => {
397
- const configNames = [];
398
- if (interfaceFile.isValueFile) {
399
- configNames.push(interfaceFile.configName);
400
- }
401
- else {
402
- configNames.push(...Object.keys(interfaceFile.fileExportsByConfigName));
403
- }
404
- configNames.forEach((configName) => {
405
- if (isGlobalConfigOld(configName))
406
- return;
407
- const configDef = getConfigDefinition(configDefinitions, configName, interfaceFile.filePath.filePathToShowToUser);
408
- if (configDef.global === true) {
409
- const locationIds = objectKeys(interfaceFilesAll);
410
- if (!isGlobalLocation(interfaceFile.locationId, locationIds)) {
411
- const interfaceFilesGlobal = objectFromEntries(objectEntries(interfaceFilesAll).filter(([locationId]) => {
412
- return isGlobalLocation(locationId, locationIds);
413
- }));
414
- const configFilesGlobal = [];
415
- objectEntries(interfaceFilesGlobal).forEach(([locationId, interfaceFiles]) => {
416
- assert(isGlobalLocation(locationId, locationIds));
417
- interfaceFiles.forEach((interfaceFile) => {
418
- if (!interfaceFile.isConfigFile)
419
- return;
420
- const { filePath: { filePathAbsoluteUserRootDir } } = interfaceFile;
421
- if (filePathAbsoluteUserRootDir) {
422
- configFilesGlobal.push(filePathAbsoluteUserRootDir);
423
- }
424
- });
425
- });
426
- assertUsage(false, [
427
- `${interfaceFile.filePath.filePathToShowToUser} sets the config ${pc.cyan(configName)} but it's a global config:`,
428
- configFilesGlobal.length > 0
429
- ? `define ${pc.cyan(configName)} at ${joinEnglish(configFilesGlobal, 'or')} instead.`
430
- : `create a global config (e.g. /pages/+config.js) and define ${pc.cyan(configName)} there instead.`
431
- ].join(' '));
432
- }
433
- }
434
- });
435
- });
436
- }
437
385
  function assertOnBeforeRenderEnv(pageConfig) {
438
386
  const onBeforeRenderConfig = pageConfig.configValueSources.onBeforeRender?.[0];
439
387
  if (!onBeforeRenderConfig)
@@ -471,6 +419,32 @@ function getConfigValues(pageConfig) {
471
419
  });
472
420
  return configValues;
473
421
  }
422
+ function temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, userRootDir) {
423
+ assert(isObject(vikeVitePluginOptions));
424
+ assertWarning(Object.keys(vikeVitePluginOptions).length === 0, `Define Vike settings in +config.js instead of vite.config.js ${pc.underline('https://vike.dev/migration/settings')}`, { onlyOnce: true });
425
+ Object.entries(vikeVitePluginOptions).forEach(([configName, value]) => {
426
+ var _a;
427
+ assert(includes(objectKeys(configDefinitionsBuiltInAll), configName));
428
+ const configDef = configDefinitionsBuiltInAll[configName];
429
+ const sources = ((_a = pageConfigGlobal.configValueSources)[configName] ?? (_a[configName] = []));
430
+ sources.push({
431
+ value,
432
+ configEnv: configDef.env,
433
+ definedAtFilePath: {
434
+ ...getFilePathResolved({
435
+ userRootDir,
436
+ filePathAbsoluteUserRootDir: '/vite.config.js'
437
+ }),
438
+ fileExportPathToShowToUser: null
439
+ },
440
+ locationId: '/',
441
+ interfaceFile: null,
442
+ isOverriden: configDef.cumulative ? false : sources.length > 0,
443
+ valueIsImportedAtRuntime: false,
444
+ valueIsDefinedByPlusFile: false
445
+ });
446
+ });
447
+ }
474
448
  function getInterfaceFilesRelevant(interfaceFilesAll, locationIdPage) {
475
449
  const interfaceFilesRelevant = Object.fromEntries(objectEntries(interfaceFilesAll)
476
450
  .filter(([locationId]) => {
@@ -479,8 +453,8 @@ function getInterfaceFilesRelevant(interfaceFilesAll, locationIdPage) {
479
453
  .sort(([locationId1], [locationId2]) => sortAfterInheritanceOrder(locationId1, locationId2, locationIdPage)));
480
454
  return interfaceFilesRelevant;
481
455
  }
482
- async function resolveConfigValueSources(configName, configDef, interfaceFilesRelevant, userRootDir, importedFilesLoaded) {
483
- const sourcesInfo = [];
456
+ function resolveConfigValueSources(configName, configDef, interfaceFilesRelevant, userRootDir, isGlobal) {
457
+ const interfaceFilesSource = [];
484
458
  // interfaceFilesRelevant is sorted by sortAfterInheritanceOrder()
485
459
  for (const interfaceFiles of Object.values(interfaceFilesRelevant)) {
486
460
  const interfaceFilesDefiningConfig = interfaceFiles.filter((interfaceFile) => getDefiningConfigNames(interfaceFile).includes(configName));
@@ -490,15 +464,8 @@ async function resolveConfigValueSources(configName, configDef, interfaceFilesRe
490
464
  const add = (interfaceFile) => {
491
465
  assert(!visited.has(interfaceFile));
492
466
  visited.add(interfaceFile);
493
- const isHighestInheritancePrecedence = sourcesInfo.length === 0;
494
- sourcesInfo.push([
495
- configName,
496
- interfaceFile,
497
- configDef,
498
- userRootDir,
499
- importedFilesLoaded,
500
- isHighestInheritancePrecedence
501
- ]);
467
+ const isHighestInheritancePrecedence = interfaceFilesSource.length === 0;
468
+ interfaceFilesSource.push({ interfaceFile, isHighestInheritancePrecedence });
502
469
  };
503
470
  // Main resolution logic
504
471
  {
@@ -509,8 +476,8 @@ async function resolveConfigValueSources(configName, configDef, interfaceFilesRe
509
476
  .sort(makeOrderDeterministic);
510
477
  const interfaceConfigFiles = interfaceFilesDefiningConfig
511
478
  .filter((interfaceFile) => interfaceFile.isConfigFile &&
512
- // We consider value from extended configs (e.g. vike-react) later (i.e. with less priority)
513
- !interfaceFile.isConfigExtend)
479
+ // We consider values from extensions (e.g. vike-react) later (i.e. with less priority)
480
+ !interfaceFile.isConfigExtension)
514
481
  .sort(makeOrderDeterministic);
515
482
  const interfaceValueFile = interfaceValueFiles[0];
516
483
  const interfaceConfigFile = interfaceConfigFiles[0];
@@ -538,8 +505,8 @@ async function resolveConfigValueSources(configName, configDef, interfaceFilesRe
538
505
  });
539
506
  // extends
540
507
  interfaceFilesDefiningConfig
541
- .filter((interfaceFile) => interfaceFile.isConfigFile && interfaceFile.isConfigExtend)
542
- // extended config files are already sorted by inheritance order
508
+ .filter((interfaceFile) => interfaceFile.isConfigFile && interfaceFile.isConfigExtension)
509
+ // Extension config files are already sorted by inheritance order
543
510
  .forEach((interfaceFile) => {
544
511
  add(interfaceFile);
545
512
  });
@@ -547,29 +514,24 @@ async function resolveConfigValueSources(configName, configDef, interfaceFilesRe
547
514
  assert(visited.has(interfaceFile));
548
515
  });
549
516
  }
550
- const sources = await Promise.all(sourcesInfo.map(async (args) => await getConfigValueSource(...args)));
551
- return sources;
552
- }
553
- function makeOrderDeterministic(interfaceFile1, interfaceFile2) {
554
- return lowerFirst((interfaceFile) => {
555
- const { filePathAbsoluteUserRootDir } = interfaceFile.filePath;
556
- assert(isInterfaceFileUserLand(interfaceFile));
557
- assert(filePathAbsoluteUserRootDir);
558
- return filePathAbsoluteUserRootDir.length;
559
- })(interfaceFile1, interfaceFile2);
560
- }
561
- function warnOverridenConfigValues(interfaceFileWinner, interfaceFilesOverriden, configName) {
562
- interfaceFilesOverriden.forEach((interfaceFileLoser) => {
563
- const loserFilePath = interfaceFileLoser.filePath.filePathToShowToUser;
564
- const winnerFilePath = interfaceFileWinner.filePath.filePathToShowToUser;
565
- const confName = pc.cyan(configName);
566
- assertWarning(false, `The value of the config ${confName} defined at ${loserFilePath} is always overwritten by the value defined at ${winnerFilePath}, remove the superfluous value defined at ${loserFilePath}`, { onlyOnce: true });
517
+ let sources = interfaceFilesSource.map(({ interfaceFile, isHighestInheritancePrecedence }) => {
518
+ const configValueSource = getConfigValueSource(configName, interfaceFile, configDef, userRootDir, isHighestInheritancePrecedence);
519
+ return configValueSource;
567
520
  });
521
+ if (isCallable(configDef.global)) {
522
+ const isGlobalValue = configDef.global;
523
+ assert(configDef.env.config);
524
+ sources = sources.filter((source) => {
525
+ assert(source.configEnv.config);
526
+ // TODO/now: source.valueIsDefined
527
+ assert('value' in source);
528
+ const valueIsGlobal = isGlobalValue(source.value);
529
+ return isGlobal ? valueIsGlobal : !valueIsGlobal;
530
+ });
531
+ }
532
+ return sources;
568
533
  }
569
- function isInterfaceFileUserLand(interfaceFile) {
570
- return (interfaceFile.isConfigFile && !interfaceFile.isConfigExtend) || interfaceFile.isValueFile;
571
- }
572
- async function getConfigValueSource(configName, interfaceFile, configDef, userRootDir, importedFilesLoaded, isHighestInheritancePrecedence) {
534
+ function getConfigValueSource(configName, interfaceFile, configDef, userRootDir, isHighestInheritancePrecedence) {
573
535
  const confVal = getConfVal(interfaceFile, configName);
574
536
  assert(confVal);
575
537
  const configValueSourceCommon = {
@@ -588,11 +550,11 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
588
550
  if (interfaceFile.isConfigFile) {
589
551
  // Defined over pointer import
590
552
  assert(confVal.configValueLoaded);
591
- const resolved = resolvePointerImportOfConfig(confVal.configValue, interfaceFile.filePath, userRootDir, configDef.env, configName);
553
+ const pointerImport = resolvePointerImport(confVal.configValue, interfaceFile.filePath, userRootDir, configName);
592
554
  const configDefinedAt = getConfigDefinedAt('Config', configName, definedAtFilePath_);
593
- assertUsage(resolved, `${configDefinedAt} should be an import`);
594
- valueFilePath = resolved.pointerImport.filePathAbsoluteVite;
595
- definedAtFilePath = resolved.pointerImport;
555
+ assertUsage(pointerImport, `${configDefinedAt} should be an import`);
556
+ valueFilePath = pointerImport.fileExportPath.filePathAbsoluteVite;
557
+ definedAtFilePath = pointerImport.fileExportPath;
596
558
  }
597
559
  else {
598
560
  // Defined by value file, i.e. +{configName}.js
@@ -620,28 +582,19 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
620
582
  assert(confVal.configValueLoaded);
621
583
  const { configValue } = confVal;
622
584
  // Defined over pointer import
623
- const resolved = resolvePointerImportOfConfig(configValue, interfaceFile.filePath, userRootDir, configDef.env, configName);
624
- if (resolved) {
585
+ const pointerImport = interfaceFile.pointerImportsByConfigName[configName];
586
+ if (pointerImport) {
625
587
  const configValueSource = {
626
588
  ...configValueSourceCommon,
627
- configEnv: resolved.configEnvResolved,
589
+ configEnv: resolveConfigEnv(configDef.env, pointerImport.fileExportPath),
628
590
  valueIsImportedAtRuntime: true,
629
591
  valueIsDefinedByPlusFile: false,
630
592
  isOverriden,
631
- definedAtFilePath: resolved.pointerImport
593
+ definedAtFilePath: pointerImport.fileExportPath
632
594
  };
633
- // Load pointer import
634
- if (shouldBeLoadableAtBuildTime(configDef) &&
635
- // The value of `extends` was already loaded and already used: we don't need the value of `extends` anymore
636
- configName !== 'extends') {
637
- if (resolved.pointerImport.filePathAbsoluteFilesystem) {
638
- const fileExport = await loadImportedFile(resolved.pointerImport, userRootDir, importedFilesLoaded);
639
- configValueSource.value = fileExport;
640
- }
641
- else {
642
- const configDefinedAt = getConfigDefinedAt('Config', configName, configValueSource.definedAtFilePath);
643
- assertUsage(!configDef.cumulative, `${configDefinedAt} cannot be defined over an aliased import`);
644
- }
595
+ if (pointerImport.fileExportValueLoaded) {
596
+ configValueSource.value = pointerImport.fileExportValue;
597
+ assert('fileExportValue' in pointerImport);
645
598
  }
646
599
  return configValueSource;
647
600
  }
@@ -659,7 +612,7 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
659
612
  }
660
613
  // Defined by value file, i.e. +{configName}.js
661
614
  if (interfaceFile.isValueFile) {
662
- const configEnvResolved = resolveConfigEnvWithFileName(configDef.env, interfaceFile.filePath);
615
+ const configEnvResolved = resolveConfigEnv(configDef.env, interfaceFile.filePath);
663
616
  const valueAlreadyLoaded = confVal.configValueLoaded;
664
617
  assert(valueAlreadyLoaded === !!configEnvResolved.config);
665
618
  const configValueSource = {
@@ -683,6 +636,25 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
683
636
  }
684
637
  assert(false);
685
638
  }
639
+ function makeOrderDeterministic(interfaceFile1, interfaceFile2) {
640
+ return lowerFirst((interfaceFile) => {
641
+ const { filePathAbsoluteUserRootDir } = interfaceFile.filePath;
642
+ assert(isInterfaceFileUserLand(interfaceFile));
643
+ assert(filePathAbsoluteUserRootDir);
644
+ return filePathAbsoluteUserRootDir.length;
645
+ })(interfaceFile1, interfaceFile2);
646
+ }
647
+ function warnOverridenConfigValues(interfaceFileWinner, interfaceFilesOverriden, configName) {
648
+ interfaceFilesOverriden.forEach((interfaceFileLoser) => {
649
+ const loserFilePath = interfaceFileLoser.filePath.filePathToShowToUser;
650
+ const winnerFilePath = interfaceFileWinner.filePath.filePathToShowToUser;
651
+ const confName = pc.cyan(configName);
652
+ assertWarning(false, `The value of the config ${confName} defined at ${loserFilePath} is always overwritten by the value defined at ${winnerFilePath}, remove the superfluous value defined at ${loserFilePath}`, { onlyOnce: true });
653
+ });
654
+ }
655
+ function isInterfaceFileUserLand(interfaceFile) {
656
+ return (interfaceFile.isConfigFile && !interfaceFile.isConfigExtension) || interfaceFile.isValueFile;
657
+ }
686
658
  function isDefiningPage(interfaceFiles) {
687
659
  for (const interfaceFile of interfaceFiles) {
688
660
  const configNames = getDefiningConfigNames(interfaceFile);
@@ -700,14 +672,15 @@ function getDefiningConfigNames(interfaceFile) {
700
672
  if (interfaceFile.isValueFile) {
701
673
  configNames.push(interfaceFile.configName);
702
674
  }
703
- if (interfaceFile.isValueLoaded) {
675
+ if (interfaceFile.isValueFileLoaded) {
704
676
  configNames.push(...Object.keys(interfaceFile.fileExportsByConfigName));
705
677
  }
706
678
  configNames = unique(configNames);
707
679
  return configNames;
708
680
  }
709
- function getConfigDefinitions(interfaceFilesRelevant) {
710
- const configDefinitionsMerged = { ...configDefinitionsBuiltIn };
681
+ function getConfigDefinitions(interfaceFilesRelevant, filter) {
682
+ let configDefinitions = { ...configDefinitionsBuiltInAll };
683
+ // Add user-land meta configs
711
684
  Object.entries(interfaceFilesRelevant)
712
685
  .reverse()
713
686
  .forEach(([_locationId, interfaceFiles]) => {
@@ -728,16 +701,18 @@ function getConfigDefinitions(interfaceFilesRelevant) {
728
701
  fileExportPathToShowToUser: ['default', 'meta', configName, 'effect']
729
702
  };
730
703
  });
731
- objectEntries(meta).forEach(([configName, configDefinition]) => {
704
+ objectEntries(meta).forEach(([configName, configDefinitionUserLand]) => {
732
705
  // User can override an existing config definition
733
- configDefinitionsMerged[configName] = {
734
- ...configDefinitionsMerged[configName],
735
- ...configDefinition
706
+ configDefinitions[configName] = {
707
+ ...configDefinitions[configName],
708
+ ...configDefinitionUserLand
736
709
  };
737
710
  });
738
711
  });
739
712
  });
740
- const configDefinitions = configDefinitionsMerged;
713
+ if (filter) {
714
+ configDefinitions = Object.fromEntries(Object.entries(configDefinitions).filter(([_configName, configDef]) => filter(configDef)));
715
+ }
741
716
  return configDefinitions;
742
717
  }
743
718
  function assertMetaUsage(metaVal, metaConfigDefinedAt) {
@@ -891,10 +866,35 @@ function assertNoUnexpectedPlusSign(filePath: string, fileName: string) {
891
866
  )
892
867
  }
893
868
  */
894
- function handleUnknownConfig(configName, configNames, filePathToShowToUser) {
869
+ // Show error message upon unknown config
870
+ function assertKnownConfigs(interfaceFilesAll) {
871
+ const configDefinitionsAll = getConfigDefinitions(interfaceFilesAll);
872
+ const configNamesKnownAll = Object.keys(configDefinitionsAll);
873
+ objectEntries(interfaceFilesAll).forEach(([locationId, interfaceFiles]) => {
874
+ const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesAll, locationId);
875
+ const configDefinitionsLocal = getConfigDefinitions(interfaceFilesRelevant);
876
+ const configNamesKnownLocal = Object.keys(configDefinitionsLocal);
877
+ interfaceFiles.forEach((interfaceFile) => {
878
+ const configNames = getDefiningConfigNames(interfaceFile);
879
+ configNames.forEach((configName) => {
880
+ assertKnownConfig(configName, configNamesKnownAll, configNamesKnownLocal, interfaceFile);
881
+ assert(configNamesKnownLocal.includes(configName));
882
+ assert(configNamesKnownAll.includes(configName));
883
+ });
884
+ });
885
+ });
886
+ }
887
+ function assertKnownConfig(configName, configNamesKnownAll, configNamesKnownLocal, interfaceFile) {
888
+ if (configNamesKnownLocal.includes(configName))
889
+ return;
895
890
  const configNameColored = pc.cyan(configName);
896
- let errMsg = `${filePathToShowToUser} sets an unknown config ${configNameColored}.`;
897
- // vike-{react,vue,solid} hint
891
+ const { locationId, filePath: { filePathToShowToUser } } = interfaceFile;
892
+ const errMsg = `${filePathToShowToUser} sets an unknown config ${configNameColored}`;
893
+ // Inheritance issue: config is known but isn't defined at `locationId`
894
+ if (configNamesKnownAll.includes(configName)) {
895
+ assertUsage(false, `${filePathToShowToUser} sets the value of the config ${configNameColored} which is a custom config that is defined with ${pc.underline('https://vike.dev/meta')} at a path that doesn't apply to ${locationId} — see ${pc.underline('https://vike.dev/config#inheritance')}`);
896
+ }
897
+ // Missing vike-{react,vue,solid} installation
898
898
  {
899
899
  const ui = ['vike-react', 'vike-vue', 'vike-solid'];
900
900
  const knownVikeExntensionConfigs = {
@@ -909,15 +909,11 @@ function handleUnknownConfig(configName, configNames, filePathToShowToUser) {
909
909
  Wrapper: ui
910
910
  };
911
911
  if (configName in knownVikeExntensionConfigs) {
912
- const requiredVikeExtension = knownVikeExntensionConfigs[configName];
913
- assertUsage(false, [
914
- errMsg,
915
- `If you want to use the configuration documented at https://vike.dev/${configName} then make sure to install the Vike extension ${requiredVikeExtension
916
- .map((e) => pc.bold(e))
917
- .join('/')}.`,
918
- `Also make sure it applies to ${filePathToShowToUser} (see https://vike.dev/extends#inheritance).`,
919
- `Alternatively, if you don't want to use the aforementioned Vike extension, define it yourself by using ${pc.cyan('meta')} (https://vike.dev/meta).`
920
- ].join(' '));
912
+ const requiredVikeExtension = knownVikeExntensionConfigs[configName]
913
+ .map((e) => pc.bold(e))
914
+ .join('/');
915
+ const errMsgEnhanced = `${errMsg}. If you want to use the configuration ${configNameColored} documented at ${pc.underline(`https://vike.dev/${configName}`)} then make sure to install ${requiredVikeExtension}. (Alternatively, you can define ${configNameColored} yourself by using ${pc.cyan('meta')}, see ${pc.underline('https://vike.dev/meta')} for more information.)`;
916
+ assertUsage(false, errMsgEnhanced);
921
917
  }
922
918
  }
923
919
  // Similarity hint
@@ -926,18 +922,15 @@ function handleUnknownConfig(configName, configNames, filePathToShowToUser) {
926
922
  configNameSimilar = 'Page';
927
923
  }
928
924
  else {
929
- configNameSimilar = getMostSimilar(configName, configNames);
925
+ configNameSimilar = getMostSimilar(configName, configNamesKnownAll);
930
926
  }
931
927
  if (configNameSimilar) {
932
928
  assert(configNameSimilar !== configName);
933
- errMsg += ` Did you mean to set ${pc.cyan(configNameSimilar)} instead?`;
929
+ let errMsgEnhanced = `${errMsg}. Did you mean ${pc.cyan(configNameSimilar)} instead?`;
934
930
  if (configName === 'page') {
935
- errMsg += ` (The name of the config ${pc.cyan('Page')} starts with a capital letter ${pc.cyan('P')} because it defines a UI component: a ubiquitous JavaScript convention is that the name of UI components start with a capital letter.)`;
931
+ errMsgEnhanced += ` (The name of the config ${pc.cyan('Page')} starts with a capital letter ${pc.cyan('P')} because it defines a UI component: a ubiquitous JavaScript convention is that the name of UI components start with a capital letter.)`;
936
932
  }
937
- }
938
- // `meta` hint
939
- if (!configNameSimilar) {
940
- errMsg += ` Make sure to define ${configNameColored} by using ${pc.cyan('meta')} (https://vike.dev/meta), and also make sure the meta configuration applies to ${filePathToShowToUser} (see https://vike.dev/config#inheritance).`;
933
+ assertUsage(false, errMsgEnhanced);
941
934
  }
942
935
  assertUsage(false, errMsg);
943
936
  }
@@ -1024,53 +1017,9 @@ function getConfigEnvValue(val, errMsgIntro) {
1024
1017
  */
1025
1018
  return val;
1026
1019
  }
1027
- function getConfigDefinition(configDefinitions, configName, filePathToShowToUser) {
1028
- const configDef = configDefinitions[configName];
1029
- assertConfigExists(configName, Object.keys(configDefinitions), filePathToShowToUser);
1030
- assert(configDef);
1031
- return configDef;
1032
- }
1033
1020
  function getConfigDefinitionOptional(configDefinitions, configName) {
1034
1021
  return configDefinitions[configName] ?? null;
1035
1022
  }
1036
- function shouldBeLoadableAtBuildTime(configDef) {
1037
- return !!configDef.env.config && !configDef._valueIsFilePath;
1038
- }
1039
- // TODO/now: remove
1040
- function isGlobalConfigOld(configName) {
1041
- // TODO/now
1042
- if (configName === 'prerender')
1043
- return false;
1044
- const configNamesGlobal = getConfigNamesGlobal();
1045
- return includes(configNamesGlobal, configName);
1046
- }
1047
- // TODO/now
1048
- function isGlobalConfig(configName, configDefinitions, value) {
1049
- const configSpec = configDefinitions[configName];
1050
- assert(configSpec);
1051
- const globalValue = configSpec.global;
1052
- if (!globalValue)
1053
- return false;
1054
- if (globalValue === true)
1055
- return true;
1056
- return globalValue(value);
1057
- }
1058
- function getConfigNamesGlobal() {
1059
- return Object.keys(configDefinitionsBuiltInGlobal);
1060
- }
1061
- function getConfigDefinitionsBuiltInGlobal() {
1062
- return objectFromEntries(objectEntries(configDefinitionsBuiltInAll).filter(([_configName, configDef]) => configDef.global !== undefined));
1063
- }
1064
- function getConfigDefinitionsBuiltIn() {
1065
- return objectFromEntries(objectEntries(configDefinitionsBuiltInAll).filter(([_configName, configDef]) => configDef.global !== true));
1066
- }
1067
- function assertConfigExists(configName, configNamesRelevant, filePathToShowToUser) {
1068
- const configNames = [...configNamesRelevant, ...getConfigNamesGlobal()];
1069
- if (configNames.includes(configName))
1070
- return;
1071
- handleUnknownConfig(configName, configNames, filePathToShowToUser);
1072
- assert(false);
1073
- }
1074
1023
  function sortConfigValueSources(configValueSources, locationIdPage) {
1075
1024
  return Object.fromEntries(Object.entries(configValueSources)
1076
1025
  // Make order deterministic (no other purpose)
@@ -1091,8 +1040,27 @@ function getConfVal(interfaceFile, configName) {
1091
1040
  const configNames = getDefiningConfigNames(interfaceFile);
1092
1041
  if (!configNames.includes(configName))
1093
1042
  return null;
1094
- if (!interfaceFile.isValueLoaded)
1043
+ if (!interfaceFile.isValueFileLoaded)
1095
1044
  return { configValueLoaded: false };
1096
1045
  const confVal = { configValue: interfaceFile.fileExportsByConfigName[configName], configValueLoaded: true };
1097
1046
  return confVal;
1098
1047
  }
1048
+ function resolveConfigEnv(configEnv, filePath) {
1049
+ const configEnvResolved = { ...configEnv };
1050
+ if (filePath.filePathAbsoluteFilesystem) {
1051
+ const { fileName } = filePath;
1052
+ if (fileName.includes('.server.')) {
1053
+ configEnvResolved.server = true;
1054
+ configEnvResolved.client = false;
1055
+ }
1056
+ else if (fileName.includes('.client.')) {
1057
+ configEnvResolved.client = true;
1058
+ configEnvResolved.server = false;
1059
+ }
1060
+ else if (fileName.includes('.shared.')) {
1061
+ configEnvResolved.server = true;
1062
+ configEnvResolved.client = true;
1063
+ }
1064
+ }
1065
+ return configEnvResolved;
1066
+ }