vike 0.4.223-commit-32cd543 → 0.4.223-commit-81afe1f

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.
@@ -46,9 +46,9 @@ async function getPageDeps(config, pageConfigs) {
46
46
  // V1 design
47
47
  {
48
48
  pageConfigs.forEach((pageConfig) => {
49
- Object.values(pageConfig.configValueSources).forEach((sources) => {
49
+ Object.entries(pageConfig.configValueSources).forEach(([configName, sources]) => {
50
50
  sources
51
- .filter((c) => !c.isOverriden)
51
+ .filter((source) => !(0, getVikeConfig_js_1.isOverriden)(source, configName, pageConfig))
52
52
  .forEach((configValueSource) => {
53
53
  if (!configValueSource.valueIsLoadedWithImport && !configValueSource.valueIsFilePath)
54
54
  return;
@@ -34,7 +34,7 @@ function assertExtensionName(plusFile) {
34
34
  (0, utils_js_1.assertUsage)(name, `Vike extension name missing: the config ${filePathToShowToUser} must define the setting ${picocolors_1.default.cyan('name')}`);
35
35
  }
36
36
  function assertExtensionsRequire(pageConfig) {
37
- const plusFilesRelevantList = Object.values(pageConfig.plusFiles).flat(1);
37
+ const plusFilesRelevantList = pageConfig.plusFiles;
38
38
  // Collect extensions
39
39
  const extensions = {};
40
40
  plusFilesRelevantList.forEach((plusFile) => {
@@ -10,6 +10,7 @@ exports.reloadVikeConfig = reloadVikeConfig;
10
10
  exports.isV1Design = isV1Design;
11
11
  exports.getConfVal = getConfVal;
12
12
  exports.getConfigDefinitionOptional = getConfigDefinitionOptional;
13
+ exports.isOverriden = isOverriden;
13
14
  const utils_js_1 = require("../../../utils.js");
14
15
  const configDefinitionsBuiltIn_js_1 = require("./getVikeConfig/configDefinitionsBuiltIn.js");
15
16
  const filesystemRouting_js_1 = require("./getVikeConfig/filesystemRouting.js");
@@ -161,14 +162,23 @@ async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
161
162
  return { pageConfigs, pageConfigGlobal, global, pages };
162
163
  }
163
164
  async function resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache) {
164
- const configDefinitionsGlobal = getConfigDefinitions(sortAfterInheritanceOrderGlobal(plusFilesAll), (configDef) => !!configDef.global);
165
+ const plusFilesAllOrdered = Object.values(plusFilesAll)
166
+ .flat()
167
+ .sort((plusFile1, plusFile2) => sortAfterInheritanceOrderGlobal(plusFile1, plusFile2, plusFilesAll, null));
168
+ const configDefinitionsGlobal = getConfigDefinitions(
169
+ // We use `plusFilesAll` in order to allow local Vike extensions to create global configs, and to set the value of global configs such as `+vite` (enabling Vike extensions to add Vite plugins).
170
+ plusFilesAllOrdered, (configDef) => !!configDef.global);
165
171
  await loadCustomConfigBuildTimeFiles(plusFilesAll, configDefinitionsGlobal, userRootDir, esbuildCache);
166
172
  const configDefinitionsLocal = {};
167
- await Promise.all((0, utils_js_1.objectEntries)(plusFilesAll).map(async ([locationId, plusFiles]) => {
168
- const plusFilesRelevant = getPlusFilesRelevant(plusFilesAll, locationId);
173
+ await Promise.all((0, utils_js_1.objectEntries)(plusFilesAll).map(async ([locationIdPage, plusFiles]) => {
174
+ const plusFilesRelevant = (0, utils_js_1.objectEntries)(plusFilesAll)
175
+ .filter(([locationId]) => (0, filesystemRouting_js_1.isInherited)(locationId, locationIdPage))
176
+ .map(([, plusFiles]) => plusFiles)
177
+ .flat()
178
+ .sort((plusFile1, plusFile2) => sortAfterInheritanceOrderPage(plusFile1, plusFile2, locationIdPage, null));
169
179
  const configDefinitions = getConfigDefinitions(plusFilesRelevant, (configDef) => configDef.global !== true);
170
180
  await loadCustomConfigBuildTimeFiles(plusFiles, configDefinitions, userRootDir, esbuildCache);
171
- configDefinitionsLocal[locationId] = { configDefinitions, plusFiles, plusFilesRelevant };
181
+ configDefinitionsLocal[locationIdPage] = { configDefinitions, plusFiles, plusFilesRelevant };
172
182
  }));
173
183
  const configDefinitionsResolved = {
174
184
  configDefinitionsGlobal,
@@ -197,13 +207,16 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
197
207
  configValueSources: {}
198
208
  };
199
209
  (0, utils_js_1.objectEntries)(configDefinitionsResolved.configDefinitionsGlobal).forEach(([configName, configDef]) => {
200
- const sources = resolveConfigValueSources(configName, configDef, sortAfterInheritanceOrderGlobal(plusFilesAll), userRootDir, true);
210
+ const sources = resolveConfigValueSources(configName, configDef,
211
+ // We use `plusFilesAll` in order to allow local Vike extensions to create global configs, and to set the value of global configs such as `+vite` (enabling Vike extensions to add Vite plugins).
212
+ Object.values(plusFilesAll).flat(), userRootDir, true);
201
213
  if (sources.length === 0)
202
214
  return;
203
215
  pageConfigGlobal.configValueSources[configName] = sources;
204
216
  });
205
217
  applyEffectsMetaEnv(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal);
206
218
  applyEffectsConfVal(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal);
219
+ sortConfigValueSources(pageConfigGlobal.configValueSources, null);
207
220
  assertPageConfigGlobal(pageConfigGlobal, plusFilesAll);
208
221
  const pageConfigs = (0, utils_js_1.objectEntries)(configDefinitionsResolved.configDefinitionsLocal)
209
222
  .filter(([_locationId, { plusFiles }]) => isDefiningPage(plusFiles))
@@ -214,7 +227,6 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
214
227
  .filter(([_configName, configDef]) => configDef.global !== true)
215
228
  .forEach(([configName, configDef]) => {
216
229
  const sources = resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, false);
217
- // sortConfigValueSources(sources, locationId)
218
230
  if (sources.length === 0)
219
231
  return;
220
232
  configValueSources[configName] = sources;
@@ -222,6 +234,7 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
222
234
  const pageConfigRoute = determineRouteFilesystem(locationId, configValueSources);
223
235
  applyEffectsMetaEnv(configValueSources, configDefinitionsLocal);
224
236
  applyEffectsConfVal(configValueSources, configDefinitionsLocal);
237
+ sortConfigValueSources(configValueSources, locationId);
225
238
  const configValuesComputed = getComputed(configValueSources, configDefinitionsLocal);
226
239
  const pageConfig = {
227
240
  pageId: locationId,
@@ -358,37 +371,108 @@ function temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, use
358
371
  },
359
372
  locationId: '/',
360
373
  plusFile: null,
361
- isOverriden: configDef.cumulative ? false : sources.length > 0,
362
374
  valueIsLoadedWithImport: false,
363
375
  valueIsDefinedByPlusValueFile: false
364
376
  });
365
377
  });
366
378
  }
367
- // Together with getPlusFilesOrdered() this implements the whole config inheritance ordering for non-global configs. See sortAfterInheritanceOrderGlobal() for global configs.
368
- function getPlusFilesRelevant(plusFilesAll, locationIdPage) {
369
- const plusFilesRelevant = Object.fromEntries((0, utils_js_1.objectEntries)(plusFilesAll)
370
- .filter(([locationId]) => {
371
- return (0, filesystemRouting_js_1.isInherited)(locationId, locationIdPage);
372
- })
373
- .sort(([locationId1], [locationId2]) => (0, filesystemRouting_js_1.sortAfterInheritanceOrder)(locationId1, locationId2, locationIdPage)));
374
- return plusFilesRelevant;
375
- }
376
- // This implements the whole config inheritance ordering for global configs.
377
- // We use `plusFilesAll` in order to allow local Vike extensions to create global configs, and to set the value of global configs such as `+vite` (enabling Vike extensions to add Vite plugins).
378
- function sortAfterInheritanceOrderGlobal(plusFilesAll) {
379
- const plusFilesAllSorted = Object.fromEntries((0, utils_js_1.objectEntries)(plusFilesAll)
380
- .sort((0, utils_js_1.lowerFirst)(([locationId]) => locationId.split('/').length))
381
- .sort((0, utils_js_1.makeFirst)(([locationId]) => isGlobalLocation(locationId, plusFilesAll))));
382
- return plusFilesAllSorted;
379
+ function sortConfigValueSources(configValueSources, locationIdPage) {
380
+ Object.entries(configValueSources).forEach(([configName, sources]) => {
381
+ sources
382
+ .sort((source1, source2) => {
383
+ if (!source1.plusFile || !source2.plusFile)
384
+ return 0;
385
+ const isGlobal = !locationIdPage;
386
+ if (isGlobal) {
387
+ return sortAfterInheritanceOrderGlobal(source1.plusFile, source2.plusFile, null, configName);
388
+ }
389
+ else {
390
+ return sortAfterInheritanceOrderPage(source1.plusFile, source2.plusFile, locationIdPage, configName);
391
+ }
392
+ })
393
+ // TODO/next-major: remove
394
+ // Interop with vike(options) in vite.config.js — make it least precedence.
395
+ .sort((0, utils_js_1.makeLast)((source) => !source.plusFile));
396
+ });
397
+ }
398
+ function sortAfterInheritanceOrderPage(plusFile1, plusFile2, locationIdPage, configName) {
399
+ {
400
+ const ret = (0, filesystemRouting_js_1.sortAfterInheritanceOrder)(plusFile1.locationId, plusFile2.locationId, locationIdPage);
401
+ if (ret !== 0)
402
+ return ret;
403
+ (0, utils_js_1.assert)(plusFile1.locationId === plusFile2.locationId);
404
+ }
405
+ if (configName) {
406
+ const ret = sortPlusFilesSameLocationId(plusFile1, plusFile2, configName);
407
+ if (ret !== 0)
408
+ return ret;
409
+ }
410
+ return 0;
411
+ }
412
+ function sortAfterInheritanceOrderGlobal(plusFile1, plusFile2, plusFilesAll, configName) {
413
+ if (plusFilesAll) {
414
+ const ret = (0, utils_js_1.makeFirst)((plusFile) => isGlobalLocation(plusFile.locationId, plusFilesAll))(plusFile1, plusFile2);
415
+ if (ret !== 0)
416
+ return ret;
417
+ }
418
+ {
419
+ const ret = (0, utils_js_1.lowerFirst)((plusFile) => plusFile.locationId.split('/').length)(plusFile1, plusFile2);
420
+ if (ret !== 0)
421
+ return ret;
422
+ }
423
+ if (plusFile1.locationId !== plusFile2.locationId) {
424
+ // Same as `sort()` in `['some', 'string', 'array'].sort()`
425
+ return plusFile1.locationId > plusFile2.locationId ? 1 : -1;
426
+ }
427
+ if (configName) {
428
+ (0, utils_js_1.assert)(plusFile1.locationId === plusFile2.locationId);
429
+ const ret = sortPlusFilesSameLocationId(plusFile1, plusFile2, configName);
430
+ if (ret !== 0)
431
+ return ret;
432
+ }
433
+ return 0;
434
+ }
435
+ function sortPlusFilesSameLocationId(plusFile1, plusFile2, configName) {
436
+ (0, utils_js_1.assert)(plusFile1.locationId === plusFile2.locationId);
437
+ (0, utils_js_1.assert)(isDefiningConfig(plusFile1, configName));
438
+ (0, utils_js_1.assert)(isDefiningConfig(plusFile2, configName));
439
+ // Config set by extensions (lowest precedence)
440
+ {
441
+ const ret = (0, utils_js_1.makeLast)((plusFile) => !!plusFile.isExtensionConfig)(plusFile1, plusFile2);
442
+ if (ret !== 0)
443
+ return ret;
444
+ }
445
+ // Config set by side-export (lower precedence)
446
+ {
447
+ // - For example `export { frontmatter }` of `.mdx` files.
448
+ // - This only considers side-export configs that are already loaded at build-time. (E.g. it actually doesn't consider `export { frontmatter }` of .mdx files since .mdx files are loaded only at runtime.)
449
+ const ret = (0, utils_js_1.makeLast)((plusFile) => !plusFile.isConfigFile &&
450
+ // Is side-export
451
+ plusFile.configName !== configName)(plusFile1, plusFile2);
452
+ if (ret !== 0)
453
+ return ret;
454
+ }
455
+ // Config set by +config.js
456
+ {
457
+ const ret = (0, utils_js_1.makeLast)((plusFile) => plusFile.isConfigFile)(plusFile1, plusFile2);
458
+ if (ret !== 0)
459
+ return ret;
460
+ }
461
+ // Config set by +{configName}.js (highest precedence)
462
+ // No need to make it deterministic: the overall order is arleady deterministic, see sortMakeDeterministic() at getPlusFilesAll()
463
+ return 0;
383
464
  }
384
465
  function resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, isGlobal) {
385
- const plusFilesOrdered = getPlusFilesOrdered(configName, plusFilesRelevant);
386
- let sources = plusFilesOrdered.map((plusFile, i) => {
387
- const isHighestInheritancePrecedence = i === 0;
388
- const configValueSource = getConfigValueSource(configName, plusFile, configDef, userRootDir, isHighestInheritancePrecedence);
389
- return configValueSource;
390
- });
391
- if ((0, utils_js_1.isCallable)(configDef.global)) {
466
+ let sources = plusFilesRelevant
467
+ .filter((plusFile) => isDefiningConfig(plusFile, configName))
468
+ .map((plusFile) => getConfigValueSource(configName, plusFile, configDef, userRootDir));
469
+ // Filter hydrid global-local configs
470
+ if (!(0, utils_js_1.isCallable)(configDef.global)) {
471
+ // Already filtered
472
+ (0, utils_js_1.assert)((configDef.global ?? false) === isGlobal);
473
+ }
474
+ else {
475
+ // We cannot filter earlier
392
476
  (0, utils_js_1.assert)(configDef.env.config);
393
477
  sources = sources.filter((source) => {
394
478
  (0, utils_js_1.assert)(source.configEnv.config);
@@ -399,67 +483,10 @@ function resolveConfigValueSources(configName, configDef, plusFilesRelevant, use
399
483
  }
400
484
  return sources;
401
485
  }
402
- // Together with getPlusFilesRelevant() this implements the whole config inheritance ordering.
403
- function getPlusFilesOrdered(configName, plusFilesRelevant) {
404
- const plusFilesOrdered = [];
405
- // `plusFilesRelevant` is already deterministic, see sortMakeDeterministic() at getPlusFilesAll()
406
- for (const plusFilesAtLocationId of Object.values(plusFilesRelevant)) {
407
- const plusFilesForConfigName = plusFilesAtLocationId.filter((plusFile) => getDefiningConfigNames(plusFile).includes(configName));
408
- // We populate `plusFilesOrdered` with inheritance order.
409
- const populate = (plusFile) => {
410
- (0, utils_js_1.assert)(!visited.has(plusFile));
411
- visited.add(plusFile);
412
- plusFilesOrdered.push(plusFile);
413
- };
414
- const visited = new WeakSet();
415
- // ========================
416
- // User-land config (first)
417
- // ========================
418
- {
419
- const plusFilesValue = plusFilesForConfigName.filter((plusFile) => !plusFile.isConfigFile &&
420
- // We consider side-effect configs (e.g. `export { frontmatter }` of .mdx files) later (i.e. with less priority)
421
- plusFile.configName === configName);
422
- const plusFilesConfig = plusFilesForConfigName.filter((plusFile) => plusFile.isConfigFile &&
423
- // We consider extensions (e.g. vike-react) later (i.e. with less priority)
424
- !plusFile.isExtensionConfig);
425
- [...plusFilesValue, ...plusFilesConfig].forEach((plusFile) => {
426
- (0, utils_js_1.assert)(plusFile.filePath.filePathAbsoluteUserRootDir); // ensure it's a user-land plus file
427
- populate(plusFile);
428
- });
429
- }
430
- // ==========================
431
- // Side-effect configs (next)
432
- // ==========================
433
- // - For example `export { frontmatter }` of `.mdx` files.
434
- // - This only considers side-effect configs that are already loaded at build-time. (E.g. it actually doesn't consider `export { frontmatter }` of .mdx files since .mdx files are loaded only at runtime.)
435
- plusFilesForConfigName
436
- .filter((plusFile) => !plusFile.isConfigFile &&
437
- // Is side-effect config
438
- plusFile.configName !== configName)
439
- .forEach((plusFile) => {
440
- (0, utils_js_1.assert)(plusFile.filePath.filePathAbsoluteUserRootDir); // ensure it's a user-land plus file
441
- populate(plusFile);
442
- });
443
- // ========================
444
- // Extensions config (last)
445
- // ========================
446
- plusFilesForConfigName
447
- .filter((plusFile) => plusFile.isConfigFile && plusFile.isExtensionConfig)
448
- // Extension config files are already sorted by inheritance order
449
- .forEach((plusFile) => {
450
- (0, utils_js_1.assert)(!plusFile.filePath.filePathAbsoluteUserRootDir); // ensure it isn't a user-land plus file
451
- populate(plusFile);
452
- });
453
- // ======
454
- // Assert we didn't miss any config.
455
- // ======
456
- plusFilesForConfigName.forEach((plusFile) => {
457
- (0, utils_js_1.assert)(visited.has(plusFile));
458
- });
459
- }
460
- return plusFilesOrdered;
486
+ function isDefiningConfig(plusFile, configName) {
487
+ return getDefiningConfigNames(plusFile).includes(configName);
461
488
  }
462
- function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHighestInheritancePrecedence) {
489
+ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
463
490
  const confVal = getConfVal(plusFile, configName);
464
491
  (0, utils_js_1.assert)(confVal);
465
492
  const configValueSourceCommon = {
@@ -470,7 +497,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
470
497
  ...plusFile.filePath,
471
498
  fileExportPathToShowToUser: ['default', configName]
472
499
  };
473
- const isOverriden = configDef.cumulative ? false : !isHighestInheritancePrecedence;
474
500
  // +client.js
475
501
  if (configDef._valueIsFilePath) {
476
502
  let definedAtFilePath;
@@ -501,7 +527,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
501
527
  configEnv: configDef.env,
502
528
  valueIsLoadedWithImport: false,
503
529
  valueIsDefinedByPlusValueFile: false,
504
- isOverriden,
505
530
  definedAtFilePath
506
531
  };
507
532
  return configValueSource;
@@ -526,7 +551,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
526
551
  configEnv: resolveConfigEnv(configDef.env, pointerImport.fileExportPath),
527
552
  valueIsLoadedWithImport: true,
528
553
  valueIsDefinedByPlusValueFile: false,
529
- isOverriden,
530
554
  definedAtFilePath: pointerImport.fileExportPath
531
555
  };
532
556
  return configValueSource;
@@ -539,7 +563,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
539
563
  configEnv: configDef.env,
540
564
  valueIsLoadedWithImport: false,
541
565
  valueIsDefinedByPlusValueFile: false,
542
- isOverriden,
543
566
  definedAtFilePath: definedAtFilePath_
544
567
  };
545
568
  return configValueSource;
@@ -554,7 +577,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
554
577
  configEnv: configEnvResolved,
555
578
  valueIsLoadedWithImport: !confVal.valueIsLoaded || !(0, serializeConfigValues_js_1.isJsonValue)(confVal.value),
556
579
  valueIsDefinedByPlusValueFile: true,
557
- isOverriden,
558
580
  definedAtFilePath: {
559
581
  ...plusFile.filePath,
560
582
  fileExportPathToShowToUser: configName === plusFile.configName
@@ -602,33 +624,32 @@ function getDefiningConfigNames(plusFile) {
602
624
  function getConfigDefinitions(plusFilesRelevant, filter) {
603
625
  let configDefinitions = { ...configDefinitionsBuiltIn_js_1.configDefinitionsBuiltIn };
604
626
  // Add user-land meta configs
605
- Object.entries(plusFilesRelevant)
627
+ plusFilesRelevant
628
+ .slice()
606
629
  .reverse()
607
- .forEach(([_locationId, plusFiles]) => {
608
- plusFiles.forEach((plusFile) => {
609
- const confVal = getConfVal(plusFile, 'meta');
610
- if (!confVal)
630
+ .forEach((plusFile) => {
631
+ const confVal = getConfVal(plusFile, 'meta');
632
+ if (!confVal)
633
+ return;
634
+ (0, utils_js_1.assert)(confVal.valueIsLoaded);
635
+ const meta = confVal.value;
636
+ assertMetaUsage(meta, `Config ${picocolors_1.default.cyan('meta')} defined at ${plusFile.filePath.filePathToShowToUser}`);
637
+ // Set configDef._userEffectDefinedAtFilePath
638
+ Object.entries(meta).forEach(([configName, configDef]) => {
639
+ if (!configDef.effect)
611
640
  return;
612
- (0, utils_js_1.assert)(confVal.valueIsLoaded);
613
- const meta = confVal.value;
614
- assertMetaUsage(meta, `Config ${picocolors_1.default.cyan('meta')} defined at ${plusFile.filePath.filePathToShowToUser}`);
615
- // Set configDef._userEffectDefinedAtFilePath
616
- Object.entries(meta).forEach(([configName, configDef]) => {
617
- if (!configDef.effect)
618
- return;
619
- (0, utils_js_1.assert)(plusFile.isConfigFile);
620
- configDef._userEffectDefinedAtFilePath = {
621
- ...plusFile.filePath,
622
- fileExportPathToShowToUser: ['default', 'meta', configName, 'effect']
623
- };
624
- });
625
- (0, utils_js_1.objectEntries)(meta).forEach(([configName, configDefinitionUserLand]) => {
626
- // User can override an existing config definition
627
- configDefinitions[configName] = {
628
- ...configDefinitions[configName],
629
- ...configDefinitionUserLand
630
- };
631
- });
641
+ (0, utils_js_1.assert)(plusFile.isConfigFile);
642
+ configDef._userEffectDefinedAtFilePath = {
643
+ ...plusFile.filePath,
644
+ fileExportPathToShowToUser: ['default', 'meta', configName, 'effect']
645
+ };
646
+ });
647
+ (0, utils_js_1.objectEntries)(meta).forEach(([configName, configDefinitionUserLand]) => {
648
+ // User can override an existing config definition
649
+ configDefinitions[configName] = {
650
+ ...configDefinitions[configName],
651
+ ...configDefinitionUserLand
652
+ };
632
653
  });
633
654
  });
634
655
  if (filter) {
@@ -728,7 +749,6 @@ function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSource
728
749
  plusFile: sourceEffect.plusFile,
729
750
  locationId: sourceEffect.locationId,
730
751
  configEnv: configDef.env,
731
- isOverriden: false, // TODO/now check
732
752
  valueIsLoadedWithImport: false,
733
753
  valueIsDefinedByPlusValueFile: false,
734
754
  valueIsLoaded: true,
@@ -788,7 +808,7 @@ function getComputed(configValueSources, configDefinitions) {
788
808
  }
789
809
  // Show error message upon unknown config
790
810
  function assertKnownConfigs(configDefinitionsResolved, plusFilesAll) {
791
- const configDefinitionsAll = getConfigDefinitions(plusFilesAll);
811
+ const configDefinitionsAll = getConfigDefinitions(Object.values(plusFilesAll).flat());
792
812
  const configNamesKnownAll = Object.keys(configDefinitionsAll);
793
813
  const configNamesGlobal = Object.keys(configDefinitionsResolved.configDefinitionsGlobal);
794
814
  (0, utils_js_1.objectEntries)(configDefinitionsResolved.configDefinitionsLocal).forEach(([_locationId, { configDefinitions, plusFiles }]) => {
@@ -972,3 +992,14 @@ function isGlobalLocation(locationId, plusFilesAll) {
972
992
  .map(([locationId]) => locationId);
973
993
  return locationIdsPage.every((locId) => (0, filesystemRouting_js_1.isInherited)(locationId, locId));
974
994
  }
995
+ function isOverriden(source, configName, pageConfig) {
996
+ const configDef = pageConfig.configDefinitions[configName];
997
+ (0, utils_js_1.assert)(configDef);
998
+ if (configDef.cumulative)
999
+ return false;
1000
+ const sources = pageConfig.configValueSources[configName];
1001
+ (0, utils_js_1.assert)(sources);
1002
+ const idx = sources.indexOf(source);
1003
+ (0, utils_js_1.assert)(idx >= 0);
1004
+ return idx > 0;
1005
+ }
@@ -29,8 +29,6 @@ function getConfigValue(pageConfig, configName) {
29
29
  if (!configDef.cumulative) {
30
30
  const configValueSource = sources[0];
31
31
  (0, utils_js_1.assert)(configValueSource);
32
- (0, utils_js_1.assert)(configValueSource.isOverriden === false);
33
- (0, utils_js_1.assert)(sources.slice(1).every((s) => s.isOverriden === true));
34
32
  (0, utils_js_1.assert)(configValueSource.valueIsLoaded);
35
33
  return {
36
34
  type: 'standard',
@@ -52,7 +50,6 @@ function mergeCumulative(configValueSources) {
52
50
  const value = [];
53
51
  const definedAtData = [];
54
52
  configValueSources.forEach((configValueSource) => {
55
- (0, utils_js_1.assert)(configValueSource.isOverriden === false);
56
53
  (0, utils_js_1.assert)(configValueSource.configEnv.config === true);
57
54
  (0, utils_js_1.assert)(configValueSource.valueIsLoaded);
58
55
  value.push(configValueSource.value);
@@ -12,6 +12,7 @@ const transformPointerImports_js_1 = require("../../../node/plugin/plugins/impor
12
12
  const helpers_js_1 = require("../helpers.js");
13
13
  const stringify_1 = require("@brillout/json-serializer/stringify");
14
14
  const picocolors_1 = __importDefault(require("@brillout/picocolors"));
15
+ const getVikeConfig_js_1 = require("../../../node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js");
15
16
  const stringifyOptions = { forbidReactElements: true };
16
17
  const REPLACE_ME_BEFORE = '__VIKE__REPLACE_ME_BEFORE__';
17
18
  const REPLACE_ME_AFTER = '__VIKE__REPLACE_ME_AFTER__';
@@ -49,7 +50,6 @@ function serializeConfigValues(pageConfig, importStatements, filesEnv, isEnvMatc
49
50
  return lines;
50
51
  }
51
52
  function getValueSerializedFromSource(configValueSource, configName, importStatements, filesEnv) {
52
- (0, utils_js_1.assert)(configValueSource.isOverriden === false);
53
53
  let valueData;
54
54
  if (configValueSource.valueIsLoaded && !configValueSource.valueIsLoadedWithImport) {
55
55
  valueData = getValueSerializedWithJson(configValueSource.value, configName, configValueSource.definedAtFilePath, importStatements, filesEnv, configValueSource.configEnv);
@@ -201,7 +201,6 @@ function getConfigValuesBase(pageConfig, isEnvMatch, isEager) {
201
201
  if (!configDef.cumulative) {
202
202
  const source = sources[0];
203
203
  (0, utils_js_1.assert)(source);
204
- (0, utils_js_1.assert)(sources.slice(1).every((s) => s.isOverriden === true));
205
204
  if (!isEnvMatch(source.configEnv))
206
205
  return 'SKIP';
207
206
  const definedAtFile = getDefinedAtFileSource(source);
@@ -212,7 +211,9 @@ function getConfigValuesBase(pageConfig, isEnvMatch, isEager) {
212
211
  return { configValueBase, sourceRelevant: source, configName };
213
212
  }
214
213
  else {
215
- const sourcesRelevant = sources.filter((source) => !source.isOverriden && isEnvMatch(source.configEnv));
214
+ const sourcesRelevant = sources
215
+ .filter((source) => !(0, getVikeConfig_js_1.isOverriden)(source, configName, pageConfig))
216
+ .filter((source) => isEnvMatch(source.configEnv));
216
217
  if (sourcesRelevant.length === 0)
217
218
  return 'SKIP';
218
219
  const definedAtData = [];
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PROJECT_VERSION = void 0;
4
4
  // Automatically updated by @brillout/release-me
5
- exports.PROJECT_VERSION = '0.4.223-commit-32cd543';
5
+ exports.PROJECT_VERSION = '0.4.223-commit-81afe1f';
@@ -6,9 +6,6 @@ exports.makeFirst = makeFirst;
6
6
  exports.makeLast = makeLast;
7
7
  exports.reverse = reverse;
8
8
  const assert_js_1 = require("./assert.js");
9
- // -1 => element1 first (i.e. `indexOf(element1) < indexOf(element2)`)
10
- // +1 => element2 first (i.e. `indexOf(element2) < indexOf(element1)`)
11
- // 0 => keep original order of element1 and element2
12
9
  /**
13
10
  * ```js
14
11
  * let arr = [
@@ -1,7 +1,7 @@
1
1
  export { determineOptimizeDeps };
2
2
  import { findPageFiles } from '../../shared/findPageFiles.js';
3
3
  import { assert, assertIsNpmPackageImport, createDebugger, isArray, unique } from '../../utils.js';
4
- import { getVikeConfig } from '../importUserCode/v1-design/getVikeConfig.js';
4
+ import { getVikeConfig, isOverriden } from '../importUserCode/v1-design/getVikeConfig.js';
5
5
  import { analyzeClientEntries } from '../build/pluginBuildConfig.js';
6
6
  import { virtualFileIdImportUserCodeClientCR, virtualFileIdImportUserCodeClientSR } from '../../../shared/virtual-files/virtualFileImportUserCode.js';
7
7
  import { getFilePathResolved } from '../../shared/getFilePath.js';
@@ -44,9 +44,9 @@ async function getPageDeps(config, pageConfigs) {
44
44
  // V1 design
45
45
  {
46
46
  pageConfigs.forEach((pageConfig) => {
47
- Object.values(pageConfig.configValueSources).forEach((sources) => {
47
+ Object.entries(pageConfig.configValueSources).forEach(([configName, sources]) => {
48
48
  sources
49
- .filter((c) => !c.isOverriden)
49
+ .filter((source) => !isOverriden(source, configName, pageConfig))
50
50
  .forEach((configValueSource) => {
51
51
  if (!configValueSource.valueIsLoadedWithImport && !configValueSource.valueIsFilePath)
52
52
  return;
@@ -29,7 +29,7 @@ function assertExtensionName(plusFile) {
29
29
  assertUsage(name, `Vike extension name missing: the config ${filePathToShowToUser} must define the setting ${pc.cyan('name')}`);
30
30
  }
31
31
  function assertExtensionsRequire(pageConfig) {
32
- const plusFilesRelevantList = Object.values(pageConfig.plusFiles).flat(1);
32
+ const plusFilesRelevantList = pageConfig.plusFiles;
33
33
  // Collect extensions
34
34
  const extensions = {};
35
35
  plusFilesRelevantList.forEach((plusFile) => {
@@ -5,8 +5,9 @@ export { vikeConfigDependencies };
5
5
  export { isV1Design };
6
6
  export { getConfVal };
7
7
  export { getConfigDefinitionOptional };
8
+ export { isOverriden };
8
9
  export type { VikeConfigObject };
9
- import type { PageConfigGlobalBuildTime, PageConfigBuildTime } from '../../../../../shared/page-configs/PageConfig.js';
10
+ import type { PageConfigGlobalBuildTime, ConfigValueSource, PageConfigBuildTime } from '../../../../../shared/page-configs/PageConfig.js';
10
11
  import { type ConfigDefinitions, type ConfigDefinitionInternal } from './getVikeConfig/configDefinitionsBuiltIn.js';
11
12
  import type { ResolvedConfig, UserConfig } from 'vite';
12
13
  import { type PageConfigUserFriendly, type PageConfigsUserFriendly } from '../../../../../shared/page-configs/getPageConfigUserFriendly.js';
@@ -31,3 +32,4 @@ declare function getConfVal(plusFile: PlusFile, configName: string): null | {
31
32
  } | {
32
33
  valueIsLoaded: false;
33
34
  };
35
+ declare function isOverriden(source: ConfigValueSource, configName: string, pageConfig: PageConfigBuildTime | PageConfigGlobalBuildTime): boolean;
@@ -5,7 +5,8 @@ export { vikeConfigDependencies };
5
5
  export { isV1Design };
6
6
  export { getConfVal };
7
7
  export { getConfigDefinitionOptional };
8
- import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, includes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, assertKeys, objectKeys, objectFromEntries, unique, isCallable, makeFirst, lowerFirst } from '../../../utils.js';
8
+ export { isOverriden };
9
+ import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, includes, assertIsNotProductionRuntime, getMostSimilar, joinEnglish, assertKeys, objectKeys, objectFromEntries, unique, isCallable, makeFirst, lowerFirst, makeLast } from '../../../utils.js';
9
10
  import { configDefinitionsBuiltIn } from './getVikeConfig/configDefinitionsBuiltIn.js';
10
11
  import { getLocationId, getFilesystemRouteString, getFilesystemRouteDefinedBy, isInherited, sortAfterInheritanceOrder, applyFilesystemRoutingRootEffect } from './getVikeConfig/filesystemRouting.js';
11
12
  import { isVikeConfigInvalid, isVikeConfigInvalid_set } from '../../../../runtime/renderPage/isVikeConfigInvalid.js';
@@ -155,14 +156,23 @@ async function loadVikeConfig(userRootDir, vikeVitePluginOptions) {
155
156
  return { pageConfigs, pageConfigGlobal, global, pages };
156
157
  }
157
158
  async function resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache) {
158
- const configDefinitionsGlobal = getConfigDefinitions(sortAfterInheritanceOrderGlobal(plusFilesAll), (configDef) => !!configDef.global);
159
+ const plusFilesAllOrdered = Object.values(plusFilesAll)
160
+ .flat()
161
+ .sort((plusFile1, plusFile2) => sortAfterInheritanceOrderGlobal(plusFile1, plusFile2, plusFilesAll, null));
162
+ const configDefinitionsGlobal = getConfigDefinitions(
163
+ // We use `plusFilesAll` in order to allow local Vike extensions to create global configs, and to set the value of global configs such as `+vite` (enabling Vike extensions to add Vite plugins).
164
+ plusFilesAllOrdered, (configDef) => !!configDef.global);
159
165
  await loadCustomConfigBuildTimeFiles(plusFilesAll, configDefinitionsGlobal, userRootDir, esbuildCache);
160
166
  const configDefinitionsLocal = {};
161
- await Promise.all(objectEntries(plusFilesAll).map(async ([locationId, plusFiles]) => {
162
- const plusFilesRelevant = getPlusFilesRelevant(plusFilesAll, locationId);
167
+ await Promise.all(objectEntries(plusFilesAll).map(async ([locationIdPage, plusFiles]) => {
168
+ const plusFilesRelevant = objectEntries(plusFilesAll)
169
+ .filter(([locationId]) => isInherited(locationId, locationIdPage))
170
+ .map(([, plusFiles]) => plusFiles)
171
+ .flat()
172
+ .sort((plusFile1, plusFile2) => sortAfterInheritanceOrderPage(plusFile1, plusFile2, locationIdPage, null));
163
173
  const configDefinitions = getConfigDefinitions(plusFilesRelevant, (configDef) => configDef.global !== true);
164
174
  await loadCustomConfigBuildTimeFiles(plusFiles, configDefinitions, userRootDir, esbuildCache);
165
- configDefinitionsLocal[locationId] = { configDefinitions, plusFiles, plusFilesRelevant };
175
+ configDefinitionsLocal[locationIdPage] = { configDefinitions, plusFiles, plusFilesRelevant };
166
176
  }));
167
177
  const configDefinitionsResolved = {
168
178
  configDefinitionsGlobal,
@@ -191,13 +201,16 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
191
201
  configValueSources: {}
192
202
  };
193
203
  objectEntries(configDefinitionsResolved.configDefinitionsGlobal).forEach(([configName, configDef]) => {
194
- const sources = resolveConfigValueSources(configName, configDef, sortAfterInheritanceOrderGlobal(plusFilesAll), userRootDir, true);
204
+ const sources = resolveConfigValueSources(configName, configDef,
205
+ // We use `plusFilesAll` in order to allow local Vike extensions to create global configs, and to set the value of global configs such as `+vite` (enabling Vike extensions to add Vite plugins).
206
+ Object.values(plusFilesAll).flat(), userRootDir, true);
195
207
  if (sources.length === 0)
196
208
  return;
197
209
  pageConfigGlobal.configValueSources[configName] = sources;
198
210
  });
199
211
  applyEffectsMetaEnv(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal);
200
212
  applyEffectsConfVal(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal);
213
+ sortConfigValueSources(pageConfigGlobal.configValueSources, null);
201
214
  assertPageConfigGlobal(pageConfigGlobal, plusFilesAll);
202
215
  const pageConfigs = objectEntries(configDefinitionsResolved.configDefinitionsLocal)
203
216
  .filter(([_locationId, { plusFiles }]) => isDefiningPage(plusFiles))
@@ -208,7 +221,6 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
208
221
  .filter(([_configName, configDef]) => configDef.global !== true)
209
222
  .forEach(([configName, configDef]) => {
210
223
  const sources = resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, false);
211
- // sortConfigValueSources(sources, locationId)
212
224
  if (sources.length === 0)
213
225
  return;
214
226
  configValueSources[configName] = sources;
@@ -216,6 +228,7 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
216
228
  const pageConfigRoute = determineRouteFilesystem(locationId, configValueSources);
217
229
  applyEffectsMetaEnv(configValueSources, configDefinitionsLocal);
218
230
  applyEffectsConfVal(configValueSources, configDefinitionsLocal);
231
+ sortConfigValueSources(configValueSources, locationId);
219
232
  const configValuesComputed = getComputed(configValueSources, configDefinitionsLocal);
220
233
  const pageConfig = {
221
234
  pageId: locationId,
@@ -352,37 +365,108 @@ function temp_interopVikeVitePlugin(pageConfigGlobal, vikeVitePluginOptions, use
352
365
  },
353
366
  locationId: '/',
354
367
  plusFile: null,
355
- isOverriden: configDef.cumulative ? false : sources.length > 0,
356
368
  valueIsLoadedWithImport: false,
357
369
  valueIsDefinedByPlusValueFile: false
358
370
  });
359
371
  });
360
372
  }
361
- // Together with getPlusFilesOrdered() this implements the whole config inheritance ordering for non-global configs. See sortAfterInheritanceOrderGlobal() for global configs.
362
- function getPlusFilesRelevant(plusFilesAll, locationIdPage) {
363
- const plusFilesRelevant = Object.fromEntries(objectEntries(plusFilesAll)
364
- .filter(([locationId]) => {
365
- return isInherited(locationId, locationIdPage);
366
- })
367
- .sort(([locationId1], [locationId2]) => sortAfterInheritanceOrder(locationId1, locationId2, locationIdPage)));
368
- return plusFilesRelevant;
369
- }
370
- // This implements the whole config inheritance ordering for global configs.
371
- // We use `plusFilesAll` in order to allow local Vike extensions to create global configs, and to set the value of global configs such as `+vite` (enabling Vike extensions to add Vite plugins).
372
- function sortAfterInheritanceOrderGlobal(plusFilesAll) {
373
- const plusFilesAllSorted = Object.fromEntries(objectEntries(plusFilesAll)
374
- .sort(lowerFirst(([locationId]) => locationId.split('/').length))
375
- .sort(makeFirst(([locationId]) => isGlobalLocation(locationId, plusFilesAll))));
376
- return plusFilesAllSorted;
373
+ function sortConfigValueSources(configValueSources, locationIdPage) {
374
+ Object.entries(configValueSources).forEach(([configName, sources]) => {
375
+ sources
376
+ .sort((source1, source2) => {
377
+ if (!source1.plusFile || !source2.plusFile)
378
+ return 0;
379
+ const isGlobal = !locationIdPage;
380
+ if (isGlobal) {
381
+ return sortAfterInheritanceOrderGlobal(source1.plusFile, source2.plusFile, null, configName);
382
+ }
383
+ else {
384
+ return sortAfterInheritanceOrderPage(source1.plusFile, source2.plusFile, locationIdPage, configName);
385
+ }
386
+ })
387
+ // TODO/next-major: remove
388
+ // Interop with vike(options) in vite.config.js — make it least precedence.
389
+ .sort(makeLast((source) => !source.plusFile));
390
+ });
391
+ }
392
+ function sortAfterInheritanceOrderPage(plusFile1, plusFile2, locationIdPage, configName) {
393
+ {
394
+ const ret = sortAfterInheritanceOrder(plusFile1.locationId, plusFile2.locationId, locationIdPage);
395
+ if (ret !== 0)
396
+ return ret;
397
+ assert(plusFile1.locationId === plusFile2.locationId);
398
+ }
399
+ if (configName) {
400
+ const ret = sortPlusFilesSameLocationId(plusFile1, plusFile2, configName);
401
+ if (ret !== 0)
402
+ return ret;
403
+ }
404
+ return 0;
405
+ }
406
+ function sortAfterInheritanceOrderGlobal(plusFile1, plusFile2, plusFilesAll, configName) {
407
+ if (plusFilesAll) {
408
+ const ret = makeFirst((plusFile) => isGlobalLocation(plusFile.locationId, plusFilesAll))(plusFile1, plusFile2);
409
+ if (ret !== 0)
410
+ return ret;
411
+ }
412
+ {
413
+ const ret = lowerFirst((plusFile) => plusFile.locationId.split('/').length)(plusFile1, plusFile2);
414
+ if (ret !== 0)
415
+ return ret;
416
+ }
417
+ if (plusFile1.locationId !== plusFile2.locationId) {
418
+ // Same as `sort()` in `['some', 'string', 'array'].sort()`
419
+ return plusFile1.locationId > plusFile2.locationId ? 1 : -1;
420
+ }
421
+ if (configName) {
422
+ assert(plusFile1.locationId === plusFile2.locationId);
423
+ const ret = sortPlusFilesSameLocationId(plusFile1, plusFile2, configName);
424
+ if (ret !== 0)
425
+ return ret;
426
+ }
427
+ return 0;
428
+ }
429
+ function sortPlusFilesSameLocationId(plusFile1, plusFile2, configName) {
430
+ assert(plusFile1.locationId === plusFile2.locationId);
431
+ assert(isDefiningConfig(plusFile1, configName));
432
+ assert(isDefiningConfig(plusFile2, configName));
433
+ // Config set by extensions (lowest precedence)
434
+ {
435
+ const ret = makeLast((plusFile) => !!plusFile.isExtensionConfig)(plusFile1, plusFile2);
436
+ if (ret !== 0)
437
+ return ret;
438
+ }
439
+ // Config set by side-export (lower precedence)
440
+ {
441
+ // - For example `export { frontmatter }` of `.mdx` files.
442
+ // - This only considers side-export configs that are already loaded at build-time. (E.g. it actually doesn't consider `export { frontmatter }` of .mdx files since .mdx files are loaded only at runtime.)
443
+ const ret = makeLast((plusFile) => !plusFile.isConfigFile &&
444
+ // Is side-export
445
+ plusFile.configName !== configName)(plusFile1, plusFile2);
446
+ if (ret !== 0)
447
+ return ret;
448
+ }
449
+ // Config set by +config.js
450
+ {
451
+ const ret = makeLast((plusFile) => plusFile.isConfigFile)(plusFile1, plusFile2);
452
+ if (ret !== 0)
453
+ return ret;
454
+ }
455
+ // Config set by +{configName}.js (highest precedence)
456
+ // No need to make it deterministic: the overall order is arleady deterministic, see sortMakeDeterministic() at getPlusFilesAll()
457
+ return 0;
377
458
  }
378
459
  function resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, isGlobal) {
379
- const plusFilesOrdered = getPlusFilesOrdered(configName, plusFilesRelevant);
380
- let sources = plusFilesOrdered.map((plusFile, i) => {
381
- const isHighestInheritancePrecedence = i === 0;
382
- const configValueSource = getConfigValueSource(configName, plusFile, configDef, userRootDir, isHighestInheritancePrecedence);
383
- return configValueSource;
384
- });
385
- if (isCallable(configDef.global)) {
460
+ let sources = plusFilesRelevant
461
+ .filter((plusFile) => isDefiningConfig(plusFile, configName))
462
+ .map((plusFile) => getConfigValueSource(configName, plusFile, configDef, userRootDir));
463
+ // Filter hydrid global-local configs
464
+ if (!isCallable(configDef.global)) {
465
+ // Already filtered
466
+ assert((configDef.global ?? false) === isGlobal);
467
+ }
468
+ else {
469
+ // We cannot filter earlier
386
470
  assert(configDef.env.config);
387
471
  sources = sources.filter((source) => {
388
472
  assert(source.configEnv.config);
@@ -393,67 +477,10 @@ function resolveConfigValueSources(configName, configDef, plusFilesRelevant, use
393
477
  }
394
478
  return sources;
395
479
  }
396
- // Together with getPlusFilesRelevant() this implements the whole config inheritance ordering.
397
- function getPlusFilesOrdered(configName, plusFilesRelevant) {
398
- const plusFilesOrdered = [];
399
- // `plusFilesRelevant` is already deterministic, see sortMakeDeterministic() at getPlusFilesAll()
400
- for (const plusFilesAtLocationId of Object.values(plusFilesRelevant)) {
401
- const plusFilesForConfigName = plusFilesAtLocationId.filter((plusFile) => getDefiningConfigNames(plusFile).includes(configName));
402
- // We populate `plusFilesOrdered` with inheritance order.
403
- const populate = (plusFile) => {
404
- assert(!visited.has(plusFile));
405
- visited.add(plusFile);
406
- plusFilesOrdered.push(plusFile);
407
- };
408
- const visited = new WeakSet();
409
- // ========================
410
- // User-land config (first)
411
- // ========================
412
- {
413
- const plusFilesValue = plusFilesForConfigName.filter((plusFile) => !plusFile.isConfigFile &&
414
- // We consider side-effect configs (e.g. `export { frontmatter }` of .mdx files) later (i.e. with less priority)
415
- plusFile.configName === configName);
416
- const plusFilesConfig = plusFilesForConfigName.filter((plusFile) => plusFile.isConfigFile &&
417
- // We consider extensions (e.g. vike-react) later (i.e. with less priority)
418
- !plusFile.isExtensionConfig);
419
- [...plusFilesValue, ...plusFilesConfig].forEach((plusFile) => {
420
- assert(plusFile.filePath.filePathAbsoluteUserRootDir); // ensure it's a user-land plus file
421
- populate(plusFile);
422
- });
423
- }
424
- // ==========================
425
- // Side-effect configs (next)
426
- // ==========================
427
- // - For example `export { frontmatter }` of `.mdx` files.
428
- // - This only considers side-effect configs that are already loaded at build-time. (E.g. it actually doesn't consider `export { frontmatter }` of .mdx files since .mdx files are loaded only at runtime.)
429
- plusFilesForConfigName
430
- .filter((plusFile) => !plusFile.isConfigFile &&
431
- // Is side-effect config
432
- plusFile.configName !== configName)
433
- .forEach((plusFile) => {
434
- assert(plusFile.filePath.filePathAbsoluteUserRootDir); // ensure it's a user-land plus file
435
- populate(plusFile);
436
- });
437
- // ========================
438
- // Extensions config (last)
439
- // ========================
440
- plusFilesForConfigName
441
- .filter((plusFile) => plusFile.isConfigFile && plusFile.isExtensionConfig)
442
- // Extension config files are already sorted by inheritance order
443
- .forEach((plusFile) => {
444
- assert(!plusFile.filePath.filePathAbsoluteUserRootDir); // ensure it isn't a user-land plus file
445
- populate(plusFile);
446
- });
447
- // ======
448
- // Assert we didn't miss any config.
449
- // ======
450
- plusFilesForConfigName.forEach((plusFile) => {
451
- assert(visited.has(plusFile));
452
- });
453
- }
454
- return plusFilesOrdered;
480
+ function isDefiningConfig(plusFile, configName) {
481
+ return getDefiningConfigNames(plusFile).includes(configName);
455
482
  }
456
- function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHighestInheritancePrecedence) {
483
+ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
457
484
  const confVal = getConfVal(plusFile, configName);
458
485
  assert(confVal);
459
486
  const configValueSourceCommon = {
@@ -464,7 +491,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
464
491
  ...plusFile.filePath,
465
492
  fileExportPathToShowToUser: ['default', configName]
466
493
  };
467
- const isOverriden = configDef.cumulative ? false : !isHighestInheritancePrecedence;
468
494
  // +client.js
469
495
  if (configDef._valueIsFilePath) {
470
496
  let definedAtFilePath;
@@ -495,7 +521,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
495
521
  configEnv: configDef.env,
496
522
  valueIsLoadedWithImport: false,
497
523
  valueIsDefinedByPlusValueFile: false,
498
- isOverriden,
499
524
  definedAtFilePath
500
525
  };
501
526
  return configValueSource;
@@ -520,7 +545,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
520
545
  configEnv: resolveConfigEnv(configDef.env, pointerImport.fileExportPath),
521
546
  valueIsLoadedWithImport: true,
522
547
  valueIsDefinedByPlusValueFile: false,
523
- isOverriden,
524
548
  definedAtFilePath: pointerImport.fileExportPath
525
549
  };
526
550
  return configValueSource;
@@ -533,7 +557,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
533
557
  configEnv: configDef.env,
534
558
  valueIsLoadedWithImport: false,
535
559
  valueIsDefinedByPlusValueFile: false,
536
- isOverriden,
537
560
  definedAtFilePath: definedAtFilePath_
538
561
  };
539
562
  return configValueSource;
@@ -548,7 +571,6 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir, isHi
548
571
  configEnv: configEnvResolved,
549
572
  valueIsLoadedWithImport: !confVal.valueIsLoaded || !isJsonValue(confVal.value),
550
573
  valueIsDefinedByPlusValueFile: true,
551
- isOverriden,
552
574
  definedAtFilePath: {
553
575
  ...plusFile.filePath,
554
576
  fileExportPathToShowToUser: configName === plusFile.configName
@@ -596,33 +618,32 @@ function getDefiningConfigNames(plusFile) {
596
618
  function getConfigDefinitions(plusFilesRelevant, filter) {
597
619
  let configDefinitions = { ...configDefinitionsBuiltIn };
598
620
  // Add user-land meta configs
599
- Object.entries(plusFilesRelevant)
621
+ plusFilesRelevant
622
+ .slice()
600
623
  .reverse()
601
- .forEach(([_locationId, plusFiles]) => {
602
- plusFiles.forEach((plusFile) => {
603
- const confVal = getConfVal(plusFile, 'meta');
604
- if (!confVal)
624
+ .forEach((plusFile) => {
625
+ const confVal = getConfVal(plusFile, 'meta');
626
+ if (!confVal)
627
+ return;
628
+ assert(confVal.valueIsLoaded);
629
+ const meta = confVal.value;
630
+ assertMetaUsage(meta, `Config ${pc.cyan('meta')} defined at ${plusFile.filePath.filePathToShowToUser}`);
631
+ // Set configDef._userEffectDefinedAtFilePath
632
+ Object.entries(meta).forEach(([configName, configDef]) => {
633
+ if (!configDef.effect)
605
634
  return;
606
- assert(confVal.valueIsLoaded);
607
- const meta = confVal.value;
608
- assertMetaUsage(meta, `Config ${pc.cyan('meta')} defined at ${plusFile.filePath.filePathToShowToUser}`);
609
- // Set configDef._userEffectDefinedAtFilePath
610
- Object.entries(meta).forEach(([configName, configDef]) => {
611
- if (!configDef.effect)
612
- return;
613
- assert(plusFile.isConfigFile);
614
- configDef._userEffectDefinedAtFilePath = {
615
- ...plusFile.filePath,
616
- fileExportPathToShowToUser: ['default', 'meta', configName, 'effect']
617
- };
618
- });
619
- objectEntries(meta).forEach(([configName, configDefinitionUserLand]) => {
620
- // User can override an existing config definition
621
- configDefinitions[configName] = {
622
- ...configDefinitions[configName],
623
- ...configDefinitionUserLand
624
- };
625
- });
635
+ assert(plusFile.isConfigFile);
636
+ configDef._userEffectDefinedAtFilePath = {
637
+ ...plusFile.filePath,
638
+ fileExportPathToShowToUser: ['default', 'meta', configName, 'effect']
639
+ };
640
+ });
641
+ objectEntries(meta).forEach(([configName, configDefinitionUserLand]) => {
642
+ // User can override an existing config definition
643
+ configDefinitions[configName] = {
644
+ ...configDefinitions[configName],
645
+ ...configDefinitionUserLand
646
+ };
626
647
  });
627
648
  });
628
649
  if (filter) {
@@ -722,7 +743,6 @@ function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSource
722
743
  plusFile: sourceEffect.plusFile,
723
744
  locationId: sourceEffect.locationId,
724
745
  configEnv: configDef.env,
725
- isOverriden: false, // TODO/now check
726
746
  valueIsLoadedWithImport: false,
727
747
  valueIsDefinedByPlusValueFile: false,
728
748
  valueIsLoaded: true,
@@ -782,7 +802,7 @@ function getComputed(configValueSources, configDefinitions) {
782
802
  }
783
803
  // Show error message upon unknown config
784
804
  function assertKnownConfigs(configDefinitionsResolved, plusFilesAll) {
785
- const configDefinitionsAll = getConfigDefinitions(plusFilesAll);
805
+ const configDefinitionsAll = getConfigDefinitions(Object.values(plusFilesAll).flat());
786
806
  const configNamesKnownAll = Object.keys(configDefinitionsAll);
787
807
  const configNamesGlobal = Object.keys(configDefinitionsResolved.configDefinitionsGlobal);
788
808
  objectEntries(configDefinitionsResolved.configDefinitionsLocal).forEach(([_locationId, { configDefinitions, plusFiles }]) => {
@@ -966,3 +986,14 @@ function isGlobalLocation(locationId, plusFilesAll) {
966
986
  .map(([locationId]) => locationId);
967
987
  return locationIdsPage.every((locId) => isInherited(locationId, locId));
968
988
  }
989
+ function isOverriden(source, configName, pageConfig) {
990
+ const configDef = pageConfig.configDefinitions[configName];
991
+ assert(configDef);
992
+ if (configDef.cumulative)
993
+ return false;
994
+ const sources = pageConfig.configValueSources[configName];
995
+ assert(sources);
996
+ const idx = sources.indexOf(source);
997
+ assert(idx >= 0);
998
+ return idx > 0;
999
+ }
@@ -22,7 +22,7 @@ import type { ConfigValueSerialized } from './serialize/PageConfigSerialized.js'
22
22
  import type { LocationId } from '../../node/plugin/plugins/importUserCode/v1-design/getVikeConfig/filesystemRouting.js';
23
23
  import type { FilePath } from './FilePath.js';
24
24
  import type { ConfigDefinitions } from '../../node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js';
25
- import type { PlusFile, PlusFilesByLocationId } from '../../node/plugin/plugins/importUserCode/v1-design/getVikeConfig/getPlusFilesAll.js';
25
+ import type { PlusFile } from '../../node/plugin/plugins/importUserCode/v1-design/getVikeConfig/getPlusFilesAll.js';
26
26
  type PageConfigCommon = {
27
27
  pageId: string;
28
28
  } & PageConfigRoute;
@@ -49,7 +49,7 @@ type PageConfigGlobalRuntime = {
49
49
  /** Page config, build-time data structure */
50
50
  type PageConfigBuildTime = PageConfigCommon & {
51
51
  configDefinitions: ConfigDefinitions;
52
- plusFiles: PlusFilesByLocationId;
52
+ plusFiles: PlusFile[];
53
53
  configValueSources: ConfigValueSources;
54
54
  configValuesComputed: ConfigValuesComputed;
55
55
  };
@@ -92,7 +92,6 @@ type ConfigValueSource = {
92
92
  definedAtFilePath: DefinedAtFilePath;
93
93
  plusFile: PlusFile | null;
94
94
  locationId: LocationId;
95
- isOverriden: boolean;
96
95
  /** Wether the config value is loaded at runtime, for example config.Page or config.onBeforeRender */
97
96
  valueIsLoadedWithImport: boolean;
98
97
  /** Whether the config value is a file path, for example config.client */
@@ -27,8 +27,6 @@ function getConfigValue(pageConfig, configName) {
27
27
  if (!configDef.cumulative) {
28
28
  const configValueSource = sources[0];
29
29
  assert(configValueSource);
30
- assert(configValueSource.isOverriden === false);
31
- assert(sources.slice(1).every((s) => s.isOverriden === true));
32
30
  assert(configValueSource.valueIsLoaded);
33
31
  return {
34
32
  type: 'standard',
@@ -50,7 +48,6 @@ function mergeCumulative(configValueSources) {
50
48
  const value = [];
51
49
  const definedAtData = [];
52
50
  configValueSources.forEach((configValueSource) => {
53
- assert(configValueSource.isOverriden === false);
54
51
  assert(configValueSource.configEnv.config === true);
55
52
  assert(configValueSource.valueIsLoaded);
56
53
  value.push(configValueSource.value);
@@ -7,6 +7,7 @@ import { parsePointerImportData } from '../../../node/plugin/plugins/importUserC
7
7
  import { getConfigValueFilePathToShowToUser } from '../helpers.js';
8
8
  import { stringify } from '@brillout/json-serializer/stringify';
9
9
  import pc from '@brillout/picocolors';
10
+ import { isOverriden } from '../../../node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js';
10
11
  const stringifyOptions = { forbidReactElements: true };
11
12
  const REPLACE_ME_BEFORE = '__VIKE__REPLACE_ME_BEFORE__';
12
13
  const REPLACE_ME_AFTER = '__VIKE__REPLACE_ME_AFTER__';
@@ -44,7 +45,6 @@ function serializeConfigValues(pageConfig, importStatements, filesEnv, isEnvMatc
44
45
  return lines;
45
46
  }
46
47
  function getValueSerializedFromSource(configValueSource, configName, importStatements, filesEnv) {
47
- assert(configValueSource.isOverriden === false);
48
48
  let valueData;
49
49
  if (configValueSource.valueIsLoaded && !configValueSource.valueIsLoadedWithImport) {
50
50
  valueData = getValueSerializedWithJson(configValueSource.value, configName, configValueSource.definedAtFilePath, importStatements, filesEnv, configValueSource.configEnv);
@@ -196,7 +196,6 @@ function getConfigValuesBase(pageConfig, isEnvMatch, isEager) {
196
196
  if (!configDef.cumulative) {
197
197
  const source = sources[0];
198
198
  assert(source);
199
- assert(sources.slice(1).every((s) => s.isOverriden === true));
200
199
  if (!isEnvMatch(source.configEnv))
201
200
  return 'SKIP';
202
201
  const definedAtFile = getDefinedAtFileSource(source);
@@ -207,7 +206,9 @@ function getConfigValuesBase(pageConfig, isEnvMatch, isEager) {
207
206
  return { configValueBase, sourceRelevant: source, configName };
208
207
  }
209
208
  else {
210
- const sourcesRelevant = sources.filter((source) => !source.isOverriden && isEnvMatch(source.configEnv));
209
+ const sourcesRelevant = sources
210
+ .filter((source) => !isOverriden(source, configName, pageConfig))
211
+ .filter((source) => isEnvMatch(source.configEnv));
211
212
  if (sourcesRelevant.length === 0)
212
213
  return 'SKIP';
213
214
  const definedAtData = [];
@@ -1 +1 @@
1
- export declare const PROJECT_VERSION: "0.4.223-commit-32cd543";
1
+ export declare const PROJECT_VERSION: "0.4.223-commit-81afe1f";
@@ -1,2 +1,2 @@
1
1
  // Automatically updated by @brillout/release-me
2
- export const PROJECT_VERSION = '0.4.223-commit-32cd543';
2
+ export const PROJECT_VERSION = '0.4.223-commit-81afe1f';
@@ -1,4 +1,4 @@
1
1
  export declare const projectInfo: {
2
2
  projectName: "Vike";
3
- projectVersion: "0.4.223-commit-32cd543";
3
+ projectVersion: "0.4.223-commit-81afe1f";
4
4
  };
@@ -3,6 +3,19 @@ export { lowerFirst };
3
3
  export { makeFirst };
4
4
  export { makeLast };
5
5
  export { reverse };
6
+ export type { SortReturn };
7
+ /**
8
+ * # How to use `Array.prototype.sort()`
9
+ *
10
+ * ```js
11
+ * elements.sort(sorter);
12
+ * function sorter(element1: unknown, element2: unknown): -1 | 0 | 1
13
+ * ```
14
+ * -1 => element1 first: `elements.indexOf(element1) < elements.indexOf(element2)`
15
+ * +1 => element2 first: `elements.indexOf(element2) < elements.indexOf(element1)`
16
+ * 0 => keep original order of element1 and element2
17
+ */
18
+ type SortReturn = -1 | 0 | 1;
6
19
  /**
7
20
  * ```js
8
21
  * let arr = [
@@ -18,7 +31,7 @@ export { reverse };
18
31
  * ])
19
32
  * ```
20
33
  */
21
- declare function higherFirst<T>(getValue: (element: T) => number): (element1: T, element2: T) => 0 | 1 | -1;
34
+ declare function higherFirst<T>(getValue: (element: T) => number): (element1: T, element2: T) => SortReturn;
22
35
  /**
23
36
  * ```js
24
37
  * let arr = [
@@ -34,7 +47,7 @@ declare function higherFirst<T>(getValue: (element: T) => number): (element1: T,
34
47
  * ])
35
48
  * ```
36
49
  */
37
- declare function lowerFirst<T>(getValue: (element: T) => number): (element1: T, element2: T) => 0 | 1 | -1;
50
+ declare function lowerFirst<T>(getValue: (element: T) => number): (element1: T, element2: T) => SortReturn;
38
51
  /**
39
52
  * ```js
40
53
  * let arr = [
@@ -48,7 +61,7 @@ declare function lowerFirst<T>(getValue: (element: T) => number): (element1: T,
48
61
  * ])
49
62
  * ```
50
63
  */
51
- declare function makeFirst<T>(getValue: (element: T) => boolean | null): (element1: T, element2: T) => 0 | 1 | -1;
64
+ declare function makeFirst<T>(getValue: (element: T) => boolean | null): (element1: T, element2: T) => SortReturn;
52
65
  /**
53
66
  * ```js
54
67
  * let arr = [
@@ -62,6 +75,6 @@ declare function makeFirst<T>(getValue: (element: T) => boolean | null): (elemen
62
75
  * ])
63
76
  * ```
64
77
  */
65
- declare function makeLast<T>(getValue: (element: T) => boolean | null): (element1: T, element2: T) => 0 | 1 | -1;
78
+ declare function makeLast<T>(getValue: (element: T) => boolean | null): (element1: T, element2: T) => SortReturn;
66
79
  /** Reverse order result. */
67
- declare function reverse(sortKey: 0 | 1 | -1): 0 | 1 | -1;
80
+ declare function reverse(sortKey: SortReturn): SortReturn;
@@ -4,9 +4,6 @@ export { lowerFirst };
4
4
  export { makeFirst };
5
5
  export { makeLast };
6
6
  export { reverse };
7
- // -1 => element1 first (i.e. `indexOf(element1) < indexOf(element2)`)
8
- // +1 => element2 first (i.e. `indexOf(element2) < indexOf(element1)`)
9
- // 0 => keep original order of element1 and element2
10
7
  /**
11
8
  * ```js
12
9
  * let arr = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.223-commit-32cd543",
3
+ "version": "0.4.223-commit-81afe1f",
4
4
  "repository": "https://github.com/vikejs/vike",
5
5
  "exports": {
6
6
  "./server": {