vike 0.4.143-commit-f03b42d → 0.4.143-commit-fa295e1
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.
- package/dist/cjs/node/plugin/plugins/devConfig/determineOptimizeDeps.js +30 -27
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getFilePathToShowToUser.js +6 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +119 -64
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +11 -10
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +11 -11
- package/dist/cjs/node/prerender/runPrerender.js +9 -8
- package/dist/cjs/node/runtime/html/injectAssets/getHtmlTags.js +1 -1
- package/dist/cjs/node/runtime/renderPage/log404/index.js +10 -5
- package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +3 -2
- package/dist/cjs/node/shared/getClientEntryFilePath.js +1 -7
- package/dist/cjs/shared/getPageFiles/getExports.js +2 -5
- package/dist/cjs/shared/getPageFiles/parsePageConfigsSerialized.js +9 -6
- package/dist/cjs/shared/hooks/getHook.js +3 -1
- package/dist/cjs/shared/page-configs/getExportPath.js +2 -2
- package/dist/cjs/shared/page-configs/parseConfigValuesImported.js +8 -5
- package/dist/cjs/shared/page-configs/utils.js +66 -42
- package/dist/cjs/shared/route/loadPageRoutes.js +5 -6
- package/dist/cjs/utils/projectInfo.js +1 -1
- package/dist/esm/node/plugin/plugins/devConfig/determineOptimizeDeps.js +30 -27
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getFilePathToShowToUser.d.ts +11 -2
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getFilePathToShowToUser.js +6 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.d.ts +3 -2
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +119 -64
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +11 -10
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.d.ts +2 -2
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +11 -11
- package/dist/esm/node/prerender/runPrerender.js +10 -9
- package/dist/esm/node/runtime/html/injectAssets/getHtmlTags.js +1 -1
- package/dist/esm/node/runtime/renderPage/log404/index.js +10 -5
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +3 -2
- package/dist/esm/node/shared/getClientEntryFilePath.js +2 -8
- package/dist/esm/shared/addUrlComputedProps.d.ts +4 -2
- package/dist/esm/shared/getPageFiles/getExports.d.ts +1 -2
- package/dist/esm/shared/getPageFiles/getExports.js +3 -6
- package/dist/esm/shared/getPageFiles/parsePageConfigsSerialized.js +9 -6
- package/dist/esm/shared/hooks/getHook.js +3 -1
- package/dist/esm/shared/page-configs/Config.d.ts +1 -3
- package/dist/esm/shared/page-configs/PageConfig.d.ts +35 -10
- package/dist/esm/shared/page-configs/getExportPath.d.ts +1 -1
- package/dist/esm/shared/page-configs/getExportPath.js +2 -2
- package/dist/esm/shared/page-configs/parseConfigValuesImported.js +8 -5
- package/dist/esm/shared/page-configs/utils.d.ts +19 -13
- package/dist/esm/shared/page-configs/utils.js +65 -41
- package/dist/esm/shared/route/loadPageRoutes.js +6 -7
- package/dist/esm/shared/types.d.ts +1 -0
- package/dist/esm/types/index.d.ts +1 -0
- package/dist/esm/utils/projectInfo.d.ts +1 -1
- package/dist/esm/utils/projectInfo.js +1 -1
- package/package.json +1 -1
|
@@ -84,7 +84,8 @@ async function loadInterfaceFiles(userRootDir, isDev, extensions) {
|
|
|
84
84
|
await Promise.all(configFiles.map(async ({ filePathAbsolute, filePathRelativeToUserRootDir }) => {
|
|
85
85
|
const configFilePath = {
|
|
86
86
|
filePathAbsolute: filePathAbsolute,
|
|
87
|
-
filePathRelativeToUserRootDir: filePathRelativeToUserRootDir
|
|
87
|
+
filePathRelativeToUserRootDir: filePathRelativeToUserRootDir,
|
|
88
|
+
importPathAbsolute: null
|
|
88
89
|
};
|
|
89
90
|
const { configFile, extendsConfigs } = await loadConfigFile(configFilePath, userRootDir, []);
|
|
90
91
|
const interfaceFile = getInterfaceFileFromConfigFile(configFile, false);
|
|
@@ -103,7 +104,8 @@ async function loadInterfaceFiles(userRootDir, isDev, extensions) {
|
|
|
103
104
|
const interfaceFile = {
|
|
104
105
|
filePath: {
|
|
105
106
|
filePathRelativeToUserRootDir,
|
|
106
|
-
filePathAbsolute
|
|
107
|
+
filePathAbsolute,
|
|
108
|
+
importPathAbsolute: null
|
|
107
109
|
},
|
|
108
110
|
configMap: {
|
|
109
111
|
[configName]: {}
|
|
@@ -338,7 +340,9 @@ function getGlobalConfigs(interfaceFilesByLocationId, userRootDir) {
|
|
|
338
340
|
if (configName === 'prerender' && typeof configValueSource.value === 'boolean')
|
|
339
341
|
return;
|
|
340
342
|
assert(!configValueSource.isComputed);
|
|
341
|
-
|
|
343
|
+
const sourceFilePath = getFilePathToShowToUser2(configValueSource.definedAtInfo);
|
|
344
|
+
assert(sourceFilePath);
|
|
345
|
+
assertWarning(false, `Being able to define config ${pc.cyan(configName)} in ${sourceFilePath} is experimental and will likely be removed. Define the config ${pc.cyan(configName)} in vike's Vite plugin options instead.`, { onlyOnce: true });
|
|
342
346
|
globalVikeConfig[configName] = configValueSource.value;
|
|
343
347
|
}
|
|
344
348
|
});
|
|
@@ -421,48 +425,48 @@ function warnOverridenConfigValues(interfaceFileWinner, interfaceFilesOverriden,
|
|
|
421
425
|
interfaceFilesOverriden.forEach((interfaceFileLoser) => {
|
|
422
426
|
const configValueSourceWinner = getConfigValueSource(configName, interfaceFileWinner, configDef, userRootDir);
|
|
423
427
|
const configValueSourceLoser = getConfigValueSource(configName, interfaceFileLoser, configDef, userRootDir);
|
|
424
|
-
|
|
428
|
+
assert(!configValueSourceLoser.isComputed);
|
|
429
|
+
assert(!configValueSourceWinner.isComputed);
|
|
430
|
+
assertWarning(false, `${getConfigSourceDefinedAtString(configName, configValueSourceLoser, undefined, true)} overriden by another ${getConfigSourceDefinedAtString(configName, configValueSourceWinner, undefined, false)}, remove one of the two`, { onlyOnce: false });
|
|
425
431
|
});
|
|
426
432
|
}
|
|
427
433
|
function isInterfaceFileUserLand(interfaceFile) {
|
|
428
434
|
return (interfaceFile.isConfigFile && !interfaceFile.isConfigExtend) || interfaceFile.isValueFile;
|
|
429
435
|
}
|
|
430
436
|
function getConfigValueSource(configName, interfaceFile, configDef, userRootDir) {
|
|
431
|
-
// TODO: rethink file paths of ConfigElement
|
|
432
|
-
const filePathToShowToUser = interfaceFile.filePath.filePathRelativeToUserRootDir ?? interfaceFile.filePath.filePathAbsolute;
|
|
433
437
|
const conf = interfaceFile.configMap[configName];
|
|
434
438
|
assert(conf);
|
|
435
439
|
const configEnv = configDef.env;
|
|
436
|
-
const
|
|
437
|
-
filePath
|
|
440
|
+
const definedAtConfigFile = {
|
|
441
|
+
...interfaceFile.filePath,
|
|
438
442
|
fileExportPath: ['default', configName]
|
|
439
443
|
};
|
|
440
444
|
if (configDef._valueIsFilePath) {
|
|
441
|
-
let
|
|
445
|
+
let definedAtInfo;
|
|
446
|
+
let valueFilePath;
|
|
442
447
|
if (interfaceFile.isConfigFile) {
|
|
443
448
|
const { configValue } = conf;
|
|
444
449
|
const import_ = resolveImport(configValue, interfaceFile.filePath, userRootDir, configEnv, configName);
|
|
445
|
-
const configDefinedAt =
|
|
450
|
+
const configDefinedAt = getConfigSourceDefinedAtString(configName, { definedAtInfo: definedAtConfigFile });
|
|
446
451
|
assertUsage(import_, `${configDefinedAt} should be an import`);
|
|
447
|
-
|
|
452
|
+
valueFilePath = import_.filePathRelativeToUserRootDir ?? import_.importPathAbsolute;
|
|
453
|
+
definedAtInfo = import_;
|
|
448
454
|
}
|
|
449
455
|
else {
|
|
450
456
|
assert(interfaceFile.isValueFile);
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
457
|
+
valueFilePath = interfaceFile.filePath.filePathRelativeToUserRootDir;
|
|
458
|
+
definedAtInfo = {
|
|
459
|
+
...interfaceFile.filePath,
|
|
460
|
+
fileExportPath: []
|
|
461
|
+
};
|
|
455
462
|
}
|
|
456
463
|
const configValueSource = {
|
|
457
|
-
value:
|
|
464
|
+
value: valueFilePath,
|
|
458
465
|
valueIsFilePath: true,
|
|
459
466
|
configEnv,
|
|
460
467
|
valueIsImportedAtRuntime: true,
|
|
461
468
|
isComputed: false,
|
|
462
|
-
definedAtInfo
|
|
463
|
-
filePath,
|
|
464
|
-
fileExportPath: []
|
|
465
|
-
}
|
|
469
|
+
definedAtInfo
|
|
466
470
|
};
|
|
467
471
|
return configValueSource;
|
|
468
472
|
}
|
|
@@ -471,15 +475,11 @@ function getConfigValueSource(configName, interfaceFile, configDef, userRootDir)
|
|
|
471
475
|
const { configValue } = conf;
|
|
472
476
|
const import_ = resolveImport(configValue, interfaceFile.filePath, userRootDir, configEnv, configName);
|
|
473
477
|
if (import_) {
|
|
474
|
-
const { filePathToShowToUser, fileExportName: exportName } = import_;
|
|
475
478
|
const configValueSource = {
|
|
476
479
|
configEnv,
|
|
477
480
|
valueIsImportedAtRuntime: true,
|
|
478
481
|
isComputed: false,
|
|
479
|
-
definedAtInfo:
|
|
480
|
-
filePath: filePathToShowToUser,
|
|
481
|
-
fileExportPath: [exportName]
|
|
482
|
-
}
|
|
482
|
+
definedAtInfo: import_
|
|
483
483
|
};
|
|
484
484
|
return configValueSource;
|
|
485
485
|
}
|
|
@@ -489,23 +489,21 @@ function getConfigValueSource(configName, interfaceFile, configDef, userRootDir)
|
|
|
489
489
|
configEnv,
|
|
490
490
|
valueIsImportedAtRuntime: false,
|
|
491
491
|
isComputed: false,
|
|
492
|
-
definedAtInfo:
|
|
492
|
+
definedAtInfo: definedAtConfigFile
|
|
493
493
|
};
|
|
494
494
|
return configValueSource;
|
|
495
495
|
}
|
|
496
496
|
}
|
|
497
497
|
else if (interfaceFile.isValueFile) {
|
|
498
498
|
// TODO: rethink file paths of ConfigElement
|
|
499
|
-
const importPath = interfaceFile.filePath.filePathRelativeToUserRootDir ?? interfaceFile.filePath.filePathAbsolute;
|
|
500
|
-
const exportName = configName === interfaceFile.configName ? 'default' : configName;
|
|
501
499
|
const valueAlreadyLoaded = 'configValue' in conf;
|
|
502
500
|
const configValueSource = {
|
|
503
501
|
configEnv,
|
|
504
502
|
valueIsImportedAtRuntime: !valueAlreadyLoaded,
|
|
505
503
|
isComputed: false,
|
|
506
504
|
definedAtInfo: {
|
|
507
|
-
filePath
|
|
508
|
-
fileExportPath: [
|
|
505
|
+
...interfaceFile.filePath,
|
|
506
|
+
fileExportPath: configName === interfaceFile.configName ? [] : [configName]
|
|
509
507
|
}
|
|
510
508
|
};
|
|
511
509
|
if (valueAlreadyLoaded) {
|
|
@@ -554,7 +552,8 @@ function resolveImport(configValue, importerFilePath, userRootDir, configEnv, co
|
|
|
554
552
|
return null;
|
|
555
553
|
const { importPath, exportName } = importData;
|
|
556
554
|
const filePathAbsolute = resolveImportPath(importData, importerFilePath);
|
|
557
|
-
|
|
555
|
+
assertFileEnv(filePathAbsolute ?? importPath, configEnv, configName);
|
|
556
|
+
const fileExportPath = exportName === 'default' || exportName === configName ? [] : [exportName];
|
|
558
557
|
if (importPath.startsWith('.')) {
|
|
559
558
|
// We need to resolve relative paths into absolute paths. Because the import paths are included in virtual files:
|
|
560
559
|
// ```
|
|
@@ -562,22 +561,26 @@ function resolveImport(configValue, importerFilePath, userRootDir, configEnv, co
|
|
|
562
561
|
// ```
|
|
563
562
|
assertImportPath(filePathAbsolute, importData, importerFilePath);
|
|
564
563
|
const filePathRelativeToUserRootDir = resolveImportPath_relativeToUserRootDir(filePathAbsolute, importData, importerFilePath, userRootDir);
|
|
565
|
-
|
|
564
|
+
return {
|
|
565
|
+
exportName,
|
|
566
|
+
fileExportPath,
|
|
567
|
+
filePathAbsolute,
|
|
568
|
+
filePathRelativeToUserRootDir,
|
|
569
|
+
importPathAbsolute: null
|
|
570
|
+
};
|
|
566
571
|
}
|
|
567
572
|
else {
|
|
568
573
|
// importPath can be:
|
|
569
574
|
// - an npm package import
|
|
570
575
|
// - a path alias
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
+
return {
|
|
577
|
+
exportName,
|
|
578
|
+
fileExportPath,
|
|
579
|
+
filePathAbsolute,
|
|
580
|
+
filePathRelativeToUserRootDir: null,
|
|
581
|
+
importPathAbsolute: importPath
|
|
582
|
+
};
|
|
576
583
|
}
|
|
577
|
-
return {
|
|
578
|
-
filePathToShowToUser,
|
|
579
|
-
fileExportName: exportName
|
|
580
|
-
};
|
|
581
584
|
}
|
|
582
585
|
function resolveImportPath_relativeToUserRootDir(filePathAbsolute, importData, configFilePath, userRootDir) {
|
|
583
586
|
assertPosixPath(userRootDir);
|
|
@@ -670,24 +673,26 @@ function applyEffects(pageConfig, configDefinitionsRelevant) {
|
|
|
670
673
|
`Adding an effect to ${pc.cyan(configName)} may not work as expected because ${pc.cyan(configName)} has an ${pc.cyan('env')} that is different than ${pc.cyan('config-only')} (its env is ${pc.cyan(configDef.env)}).`,
|
|
671
674
|
'Reach out to a maintainer if you want to use this in production.'
|
|
672
675
|
].join(' '), { onlyOnce: true });
|
|
673
|
-
const
|
|
674
|
-
if (!
|
|
676
|
+
const source = pageConfig.configValueSources[configName]?.[0];
|
|
677
|
+
if (!source)
|
|
675
678
|
return;
|
|
679
|
+
assert(!source.isComputed);
|
|
676
680
|
const configModFromEffect = configDef.effect({
|
|
677
|
-
configValue:
|
|
678
|
-
configDefinedAt:
|
|
681
|
+
configValue: source.value,
|
|
682
|
+
configDefinedAt: getConfigSourceDefinedAtString(configName, source)
|
|
679
683
|
});
|
|
680
684
|
if (!configModFromEffect)
|
|
681
685
|
return;
|
|
682
|
-
assert(hasProp(
|
|
683
|
-
applyEffect(configModFromEffect,
|
|
686
|
+
assert(hasProp(source, 'value')); // We need to assume that the config value is loaded at build-time
|
|
687
|
+
applyEffect(configModFromEffect, source, pageConfig.configValueSources);
|
|
684
688
|
});
|
|
685
689
|
}
|
|
686
690
|
function applyEffect(configModFromEffect, configValueEffectSource, configValueSources) {
|
|
687
691
|
const notSupported = `config.meta[configName].effect currently only supports modifying the the ${pc.cyan('env')} of a config. Reach out to a maintainer if you need more capabilities.`;
|
|
688
692
|
objectEntries(configModFromEffect).forEach(([configName, configValue]) => {
|
|
689
693
|
if (configName === 'meta') {
|
|
690
|
-
|
|
694
|
+
assert(!configValueEffectSource.isComputed);
|
|
695
|
+
assertMetaValue(configValue, getConfigSourceDefinedAtString(configName, configValueEffectSource, true));
|
|
691
696
|
objectEntries(configValue).forEach(([configTargetName, configTargetDef]) => {
|
|
692
697
|
{
|
|
693
698
|
const keys = Object.keys(configTargetDef);
|
|
@@ -797,7 +802,7 @@ function assertNoUnexpectedPlusSign(filePath, fileName) {
|
|
|
797
802
|
assertUsage(!fileName.slice(1).includes('+'), `Character '+' is only allowed at the beginning of filenames: make sure ${filePath} doesn't contain any '+' in its filename other than its first letter`);
|
|
798
803
|
}
|
|
799
804
|
async function loadConfigFile(configFilePath, userRootDir, visited) {
|
|
800
|
-
const { filePathAbsolute
|
|
805
|
+
const { filePathAbsolute } = configFilePath;
|
|
801
806
|
assertNoInfiniteLoop(visited, filePathAbsolute);
|
|
802
807
|
const { fileExports } = await transpileAndExecuteFile(configFilePath, false, userRootDir);
|
|
803
808
|
const { extendsConfigs, extendsFilePaths } = await loadExtendsConfigs(fileExports, configFilePath, userRootDir, [
|
|
@@ -806,10 +811,7 @@ async function loadConfigFile(configFilePath, userRootDir, visited) {
|
|
|
806
811
|
]);
|
|
807
812
|
const configFile = {
|
|
808
813
|
fileExports,
|
|
809
|
-
filePath:
|
|
810
|
-
filePathRelativeToUserRootDir,
|
|
811
|
-
filePathAbsolute
|
|
812
|
-
},
|
|
814
|
+
filePath: configFilePath,
|
|
813
815
|
extendsFilePaths
|
|
814
816
|
};
|
|
815
817
|
return { configFile, extendsConfigs };
|
|
@@ -832,11 +834,14 @@ async function loadExtendsConfigs(configFileExports, configFilePath, userRootDir
|
|
|
832
834
|
const filePathAbsolute = resolveImportPath(importData, configFilePath);
|
|
833
835
|
assertImportPath(filePathAbsolute, importData, configFilePath);
|
|
834
836
|
assertExtendsImportPath(importPath, filePathAbsolute, configFilePath);
|
|
837
|
+
// - filePathRelativeToUserRootDir has no functionality beyond nicer error messages for user
|
|
838
|
+
// - Using importPath would be visually nicer but it's ambigous => we rather pick filePathAbsolute for added clarity
|
|
839
|
+
const filePathRelativeToUserRootDir = determineFilePathRelativeToUserDir(filePathAbsolute, userRootDir);
|
|
835
840
|
extendsConfigFiles.push({
|
|
836
841
|
filePathAbsolute,
|
|
837
|
-
//
|
|
838
|
-
|
|
839
|
-
|
|
842
|
+
// TODO: fix type cast
|
|
843
|
+
filePathRelativeToUserRootDir: filePathRelativeToUserRootDir,
|
|
844
|
+
importPathAbsolute: importPath
|
|
840
845
|
});
|
|
841
846
|
});
|
|
842
847
|
const extendsConfigs = [];
|
|
@@ -999,11 +1004,13 @@ function getFilesystemRoutingRootEffect(configFilesystemRoutingRoot, configName)
|
|
|
999
1004
|
// Eagerly loaded since it's config-only
|
|
1000
1005
|
assert('value' in configFilesystemRoutingRoot);
|
|
1001
1006
|
const { value } = configFilesystemRoutingRoot;
|
|
1002
|
-
|
|
1007
|
+
assert(!configFilesystemRoutingRoot.isComputed);
|
|
1008
|
+
const configDefinedAt = getConfigSourceDefinedAtString(configName, configFilesystemRoutingRoot);
|
|
1003
1009
|
assertUsage(typeof value === 'string', `${configDefinedAt} should be a string`);
|
|
1004
1010
|
assertUsage(value.startsWith('/'), `${configDefinedAt} is ${pc.cyan(value)} but it should start with a leading slash ${pc.cyan('/')}`);
|
|
1005
1011
|
assert(!configFilesystemRoutingRoot.isComputed);
|
|
1006
|
-
|
|
1012
|
+
assert(configFilesystemRoutingRoot.definedAtInfo.filePathRelativeToUserRootDir);
|
|
1013
|
+
const before = getFilesystemRouteString(getLocationId(configFilesystemRoutingRoot.definedAtInfo.filePathRelativeToUserRootDir));
|
|
1007
1014
|
const after = value;
|
|
1008
1015
|
const filesystemRoutingRootEffect = { before, after };
|
|
1009
1016
|
return { filesystemRoutingRootEffect, filesystemRoutingRootDefinedAt: configDefinedAt };
|
|
@@ -1048,10 +1055,11 @@ function getConfigValues(configValueSources, configDefinitionsRelevant) {
|
|
|
1048
1055
|
if (!configDef.cumulative) {
|
|
1049
1056
|
const configValueSource = sources[0];
|
|
1050
1057
|
if ('value' in configValueSource) {
|
|
1051
|
-
const { value
|
|
1058
|
+
const { value } = configValueSource;
|
|
1059
|
+
const definedAt = configValueSource.isComputed ? { isComputed: true } : getDefinedAt(configValueSource);
|
|
1052
1060
|
configValues[configName] = {
|
|
1053
1061
|
value,
|
|
1054
|
-
|
|
1062
|
+
definedAt
|
|
1055
1063
|
};
|
|
1056
1064
|
}
|
|
1057
1065
|
}
|
|
@@ -1059,7 +1067,10 @@ function getConfigValues(configValueSources, configDefinitionsRelevant) {
|
|
|
1059
1067
|
const value = mergeCumulative(configName, sources);
|
|
1060
1068
|
configValues[configName] = {
|
|
1061
1069
|
value,
|
|
1062
|
-
|
|
1070
|
+
definedAt: {
|
|
1071
|
+
isCumulative: true,
|
|
1072
|
+
sources: sources.map((source) => getSourceDefinedAt(source))
|
|
1073
|
+
}
|
|
1063
1074
|
};
|
|
1064
1075
|
}
|
|
1065
1076
|
});
|
|
@@ -1071,7 +1082,7 @@ function mergeCumulative(configName, configValueSources) {
|
|
|
1071
1082
|
let configValueSourcePrevious = null;
|
|
1072
1083
|
configValueSources.forEach((configValueSource) => {
|
|
1073
1084
|
assert(!configValueSource.isComputed);
|
|
1074
|
-
const configDefinedAt =
|
|
1085
|
+
const configDefinedAt = getConfigSourceDefinedAtString(configName, configValueSource);
|
|
1075
1086
|
const configNameColored = pc.cyan(configName);
|
|
1076
1087
|
// We could, in principle, also support cumulative values to be defined in +${configName}.js but it ins't completely trivial to implement
|
|
1077
1088
|
assertUsage('value' in configValueSource, `${configDefinedAt} is only allowed to be defined in a +config.h.js file. (Because the values of ${configNameColored} are cumulative.)`);
|
|
@@ -1079,7 +1090,7 @@ function mergeCumulative(configName, configValueSources) {
|
|
|
1079
1090
|
const explanation = `(Because the values of ${configNameColored} are cumulative and therefore merged together.)` as const
|
|
1080
1091
|
*/
|
|
1081
1092
|
// Make sure configValueSource.value is serializable
|
|
1082
|
-
getConfigValueSerialized(configValueSource.value, configName, configValueSource
|
|
1093
|
+
getConfigValueSerialized(configValueSource.value, configName, getDefinedAt(configValueSource));
|
|
1083
1094
|
const assertNoMixing = (isSet) => {
|
|
1084
1095
|
const vals1 = isSet ? valuesSet : valuesArr;
|
|
1085
1096
|
const t1 = isSet ? 'a Set' : 'an array';
|
|
@@ -1089,7 +1100,8 @@ function mergeCumulative(configName, configValueSources) {
|
|
|
1089
1100
|
if (vals2.length === 0)
|
|
1090
1101
|
return;
|
|
1091
1102
|
assert(configValueSourcePrevious);
|
|
1092
|
-
|
|
1103
|
+
assert(!configValueSourcePrevious.isComputed);
|
|
1104
|
+
const configPreviousDefinedAt = getConfigSourceDefinedAtString(configName, configValueSourcePrevious, undefined, true);
|
|
1093
1105
|
assertUsage(false, `${configDefinedAt} sets ${t1} but another ${configPreviousDefinedAt} sets ${t2} which is forbidden: the values must be all arrays or all sets (you cannot mix).`);
|
|
1094
1106
|
};
|
|
1095
1107
|
const { value } = configValueSource;
|
|
@@ -1120,3 +1132,46 @@ function mergeCumulative(configName, configValueSources) {
|
|
|
1120
1132
|
}
|
|
1121
1133
|
assert(false);
|
|
1122
1134
|
}
|
|
1135
|
+
// TODO: rename
|
|
1136
|
+
// TODO: refactor
|
|
1137
|
+
function getConfigSourceDefinedAtString(configName, { definedAtInfo }, isEffect = undefined, sentenceBegin = true) {
|
|
1138
|
+
return getConfigDefinedAtString(configName, {
|
|
1139
|
+
definedAt: {
|
|
1140
|
+
isEffect,
|
|
1141
|
+
source: {
|
|
1142
|
+
filePathToShowToUser: getFilePathToShowToUser2(definedAtInfo),
|
|
1143
|
+
fileExportPath: definedAtInfo.fileExportPath
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
}, sentenceBegin);
|
|
1147
|
+
}
|
|
1148
|
+
// TODO: rename
|
|
1149
|
+
function getFilePathToShowToUser2(definedAtInfo) {
|
|
1150
|
+
return definedAtInfo.filePathRelativeToUserRootDir ?? definedAtInfo.importPathAbsolute;
|
|
1151
|
+
/*
|
|
1152
|
+
if (definedAtInfo.filePathRelativeToUserRootDir !== null) {
|
|
1153
|
+
return definedAtInfo.filePathRelativeToUserRootDir
|
|
1154
|
+
}
|
|
1155
|
+
if (definedAtInfo.importPathAbsolute !== null) {
|
|
1156
|
+
return definedAtInfo.importPathAbsolute
|
|
1157
|
+
} else {
|
|
1158
|
+
const filePathToShowToUser = definedAtInfo.filePathAbsolute
|
|
1159
|
+
// TypeScript failes to infer that definedAtInfo.filePathAbsolute cannot be null
|
|
1160
|
+
assert(filePathToShowToUser)
|
|
1161
|
+
return filePathToShowToUser
|
|
1162
|
+
}
|
|
1163
|
+
*/
|
|
1164
|
+
}
|
|
1165
|
+
// TODO: rename
|
|
1166
|
+
function getSourceDefinedAt(source) {
|
|
1167
|
+
assert(!source.isComputed);
|
|
1168
|
+
return {
|
|
1169
|
+
filePathToShowToUser: getFilePathToShowToUser2(source.definedAtInfo),
|
|
1170
|
+
fileExportPath: source.definedAtInfo.fileExportPath
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
function getDefinedAt(configValueSource) {
|
|
1174
|
+
return {
|
|
1175
|
+
source: getSourceDefinedAt(configValueSource)
|
|
1176
|
+
};
|
|
1177
|
+
}
|
package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js
CHANGED
|
@@ -53,30 +53,31 @@ function getLoadConfigValuesAll(pageConfig, isForClientSide, pageId, includeAsse
|
|
|
53
53
|
return code;
|
|
54
54
|
}
|
|
55
55
|
function serializeConfigValueImported(configValueSource, configName, whitespace, varCounterContainer, importStatements) {
|
|
56
|
+
assert(!configValueSource.valueIsFilePath);
|
|
56
57
|
assert(whitespace.replaceAll(' ', '').length === 0);
|
|
57
58
|
const { valueIsImportedAtRuntime, definedAtInfo } = configValueSource;
|
|
58
59
|
assert(valueIsImportedAtRuntime);
|
|
59
|
-
const {
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
const { filePathRelativeToUserRootDir, importPathAbsolute, exportName } = definedAtInfo;
|
|
61
|
+
const importPath = filePathRelativeToUserRootDir ?? importPathAbsolute;
|
|
62
|
+
assertPosixPath(importPath);
|
|
63
|
+
const fileName = path.posix.basename(importPath);
|
|
62
64
|
const isValueFile = fileName.startsWith('+');
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const { importName, importStatement } = generateEagerImport(filePath, varCounterContainer.varCounter++, isValueFile ? undefined : fileExportName);
|
|
65
|
+
if (isValueFile)
|
|
66
|
+
assert(exportName === undefined);
|
|
67
|
+
const { importName, importStatement } = generateEagerImport(importPath, varCounterContainer.varCounter++, exportName);
|
|
67
68
|
importStatements.push(importStatement);
|
|
68
69
|
const lines = [];
|
|
69
70
|
lines.push(` {`);
|
|
70
71
|
lines.push(` configName: '${configName}',`);
|
|
71
|
-
lines.push(` importPath: '${
|
|
72
|
+
lines.push(` importPath: '${importPath}',`);
|
|
72
73
|
lines.push(` isValueFile: ${JSON.stringify(isValueFile)},`);
|
|
73
74
|
if (isValueFile) {
|
|
74
75
|
lines.push(` importFileExports: ${importName},`);
|
|
75
76
|
}
|
|
76
77
|
else {
|
|
77
78
|
lines.push(` importFileExportValue: ${importName},`);
|
|
78
|
-
assert(
|
|
79
|
-
lines.push(` exportName: ${JSON.stringify(
|
|
79
|
+
assert(exportName);
|
|
80
|
+
lines.push(` exportName: ${JSON.stringify(exportName)},`);
|
|
80
81
|
}
|
|
81
82
|
lines.push(` },`);
|
|
82
83
|
return lines;
|
package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { getVirtualFilePageConfigs };
|
|
2
2
|
export { getConfigValueSerialized };
|
|
3
|
-
import type {
|
|
3
|
+
import type { DefinedAt } from '../../../../../shared/page-configs/PageConfig.js';
|
|
4
4
|
import type { ConfigVikeResolved } from '../../../../../shared/ConfigVike.js';
|
|
5
5
|
declare function getVirtualFilePageConfigs(userRootDir: string, isForClientSide: boolean, isDev: boolean, id: string, configVike: ConfigVikeResolved, isClientRouting: boolean): Promise<string>;
|
|
6
|
-
declare function getConfigValueSerialized(value: unknown, configName: string,
|
|
6
|
+
declare function getConfigValueSerialized(value: unknown, configName: string, definedAt: DefinedAt): string;
|
|
@@ -9,6 +9,7 @@ import pc from '@brillout/picocolors';
|
|
|
9
9
|
import { getVikeConfig } from './getVikeConfig.js';
|
|
10
10
|
import { isConfigEnvMatch } from './isConfigEnvMatch.js';
|
|
11
11
|
import { serializeConfigValueImported } from './getVirtualFilePageConfigValuesAll.js';
|
|
12
|
+
import { getConfigValueFilePathToShowToUser } from '../../../../../shared/page-configs/utils.js';
|
|
12
13
|
async function getVirtualFilePageConfigs(userRootDir, isForClientSide, isDev, id, configVike, isClientRouting) {
|
|
13
14
|
const { pageConfigs, pageConfigGlobal } = await getVikeConfig(userRootDir, isDev, configVike.extensions, true);
|
|
14
15
|
return getContent(pageConfigs, pageConfigGlobal, isForClientSide, isDev, id, isClientRouting);
|
|
@@ -34,9 +35,9 @@ function getContent(pageConfigs, pageConfigGlobal, isForClientSide, isDev, id, i
|
|
|
34
35
|
assert(configEnv, configName);
|
|
35
36
|
if (!isConfigEnvMatch(configEnv, isForClientSide, isClientRouting))
|
|
36
37
|
return;
|
|
37
|
-
const { value,
|
|
38
|
-
const valueSerialized = getConfigValueSerialized(value, configName,
|
|
39
|
-
serializeConfigValue(lines, configName, {
|
|
38
|
+
const { value, definedAt } = configValue;
|
|
39
|
+
const valueSerialized = getConfigValueSerialized(value, configName, definedAt);
|
|
40
|
+
serializeConfigValue(lines, configName, { definedAt, valueSerialized });
|
|
40
41
|
}
|
|
41
42
|
});
|
|
42
43
|
lines.push(` },`);
|
|
@@ -93,13 +94,13 @@ function serializeConfigValue(lines, configName, configValueSerialized) {
|
|
|
93
94
|
lines.push(`${whitespace}['${configName}']: {`);
|
|
94
95
|
whitespace += ' ';
|
|
95
96
|
Object.entries(configValueSerialized).forEach(([key, val]) => {
|
|
96
|
-
const valSerialized = key === '
|
|
97
|
+
const valSerialized = key === 'definedAt' ? JSON.stringify(val) : val;
|
|
97
98
|
lines.push(`${whitespace} ${key}: ${valSerialized},`);
|
|
98
99
|
});
|
|
99
100
|
whitespace = whitespace.slice(2);
|
|
100
101
|
lines.push(`${whitespace}},`);
|
|
101
102
|
}
|
|
102
|
-
function getConfigValueSerialized(value, configName,
|
|
103
|
+
function getConfigValueSerialized(value, configName, definedAt) {
|
|
103
104
|
let configValueSerialized;
|
|
104
105
|
const valueName = `config${getPropAccessNotation(configName)}`;
|
|
105
106
|
try {
|
|
@@ -107,15 +108,14 @@ function getConfigValueSerialized(value, configName, definedAtInfo) {
|
|
|
107
108
|
}
|
|
108
109
|
catch (err) {
|
|
109
110
|
assert(hasProp(err, 'messageCore', 'string'));
|
|
110
|
-
|
|
111
|
+
const configValueFilePathToShowToUser = getConfigValueFilePathToShowToUser({ definedAt });
|
|
112
|
+
// definedAt is null when config value is:
|
|
111
113
|
// - computed => all computed values defined by Vike can are serializable
|
|
112
114
|
// - cumulative => the values are already ensured to be serializable
|
|
113
|
-
assert(
|
|
114
|
-
const configDefinedByFile = definedAtInfo.filePath;
|
|
115
|
-
assert(configDefinedByFile);
|
|
115
|
+
assert(configValueFilePathToShowToUser);
|
|
116
116
|
assertUsage(false, [
|
|
117
|
-
`The value of the config ${pc.cyan(configName)} cannot be defined inside the file ${
|
|
118
|
-
`its value must be defined in an another file and then imported by ${
|
|
117
|
+
`The value of the config ${pc.cyan(configName)} cannot be defined inside the file ${configValueFilePathToShowToUser}:`,
|
|
118
|
+
`its value must be defined in an another file and then imported by ${configValueFilePathToShowToUser}. (Because the value isn't serializable: ${err.messageCore}.)`,
|
|
119
119
|
`Only serializable config values can be defined inside +config.h.js files, see https://vike.dev/header-file.`
|
|
120
120
|
].join(' '));
|
|
121
121
|
}
|
|
@@ -16,7 +16,7 @@ import { getConfigVike } from '../shared/getConfigVike.js';
|
|
|
16
16
|
import { getPageFilesServerSide } from '../../shared/getPageFiles.js';
|
|
17
17
|
import { getPageContextRequestUrl } from '../../shared/getPageContextRequestUrl.js';
|
|
18
18
|
import { getUrlFromRouteString } from '../../shared/route/resolveRouteString.js';
|
|
19
|
-
import {
|
|
19
|
+
import { getConfigValue, getConfigValueFilePathToShowToUser, getHookFilePathToShowToUser } from '../../shared/page-configs/utils.js';
|
|
20
20
|
import { loadConfigValues } from '../../shared/page-configs/loadConfigValues.js';
|
|
21
21
|
import { isErrorPage } from '../../shared/error-page.js';
|
|
22
22
|
import { addUrlComputedProps } from '../../shared/addUrlComputedProps.js';
|
|
@@ -87,12 +87,13 @@ async function collectDoNoPrerenderList(renderContext, doNotPrerenderList, concu
|
|
|
87
87
|
const configName = 'prerender';
|
|
88
88
|
const configValue = getConfigValue(pageConfig, configName, 'boolean');
|
|
89
89
|
if (configValue?.value === false) {
|
|
90
|
-
const
|
|
90
|
+
const filePath = getConfigValueFilePathToShowToUser(configValue);
|
|
91
|
+
assert(filePath);
|
|
91
92
|
doNotPrerenderList.push({
|
|
92
93
|
pageId: pageConfig.pageId,
|
|
93
94
|
setByConfigName: 'prerender',
|
|
94
95
|
setByConfigValue: false,
|
|
95
|
-
setByConfigFile:
|
|
96
|
+
setByConfigFile: filePath
|
|
96
97
|
});
|
|
97
98
|
}
|
|
98
99
|
});
|
|
@@ -148,8 +149,7 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
|
|
|
148
149
|
if (!configValue)
|
|
149
150
|
return;
|
|
150
151
|
const hookFn = configValue.value;
|
|
151
|
-
const
|
|
152
|
-
const hookFilePath = definedAtInfo.filePath;
|
|
152
|
+
const hookFilePath = getHookFilePathToShowToUser(configValue);
|
|
153
153
|
assert(hookFilePath);
|
|
154
154
|
assertHookFn(hookFn, { hookName, hookFilePath });
|
|
155
155
|
onBeforePrerenderStartHooks.push({
|
|
@@ -282,11 +282,12 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
282
282
|
// V1 design
|
|
283
283
|
if (renderContext.pageConfigs.length > 0) {
|
|
284
284
|
const { pageConfigGlobal } = renderContext;
|
|
285
|
-
|
|
286
|
-
|
|
285
|
+
const configValue = pageConfigGlobal.configValues.onPrerenderStart;
|
|
286
|
+
if (configValue?.value) {
|
|
287
|
+
const { value: hookFn } = configValue;
|
|
287
288
|
// config.onPrerenderStart isn't a computed nor a cumulative config => definedAtInfo should always be defined
|
|
288
|
-
|
|
289
|
-
|
|
289
|
+
const hookFilePath = getHookFilePathToShowToUser(configValue);
|
|
290
|
+
assert(hookFilePath);
|
|
290
291
|
onPrerenderStartHook = {
|
|
291
292
|
hookFn,
|
|
292
293
|
hookName: 'onPrerenderStart',
|
|
@@ -106,7 +106,7 @@ async function getHtmlTags(pageContext, injectToStream, injectFilter) {
|
|
|
106
106
|
if (!isHtmlOnly) {
|
|
107
107
|
// Don't allow the user to manipulate with injectFilter(): injecting <script type="application/json"> before the stream can break the app when:
|
|
108
108
|
// - using https://vike.dev/stream#initial-data-after-stream-end
|
|
109
|
-
// - `pageContext` is modified during the stream, e.g. /
|
|
109
|
+
// - `pageContext` is modified during the stream, e.g. https://github.com/brillout/vike-with-pinia which uses https://vuejs.org/api/composition-api-lifecycle.html#onserverprefetch
|
|
110
110
|
// The <script> tags are handled separately by vike down below.
|
|
111
111
|
htmlTags.push({
|
|
112
112
|
// Needs to be called after `resolvePageContextPromise()`
|
|
@@ -67,8 +67,8 @@ function getPagesAndRoutesInfo(pageRoutes) {
|
|
|
67
67
|
...entries
|
|
68
68
|
];
|
|
69
69
|
const terminalWidth = getTerminalWidth() || 134;
|
|
70
|
-
let width2 = Math.max(...linesContent.map(({ routeTypeSrc }) => routeTypeSrc.length));
|
|
71
|
-
let width3 = Math.max(...linesContent.map(({ routeDefinedBy }) => routeDefinedBy.length));
|
|
70
|
+
let width2 = Math.max(...linesContent.map(({ routeTypeSrc }) => stripAnsi(routeTypeSrc).length));
|
|
71
|
+
let width3 = Math.max(...linesContent.map(({ routeDefinedBy }) => stripAnsi(routeDefinedBy).length));
|
|
72
72
|
let width1 = terminalWidth - width3 - width2 - 10;
|
|
73
73
|
linesContent.forEach((lineContent) => {
|
|
74
74
|
let { routeStr } = lineContent;
|
|
@@ -83,9 +83,9 @@ function getPagesAndRoutesInfo(pageRoutes) {
|
|
|
83
83
|
});
|
|
84
84
|
width1 = Math.max(...linesContent.map(({ routeStr }) => stripAnsi(routeStr).length));
|
|
85
85
|
let lines = linesContent.map(({ routeStr, routeTypeSrc, routeDefinedBy }, i) => {
|
|
86
|
-
let cell1 =
|
|
87
|
-
let cell2 =
|
|
88
|
-
let cell3 =
|
|
86
|
+
let cell1 = padEnd(routeStr, width1 + (stripAnsi(routeStr).length - stripAnsi(routeStr).length));
|
|
87
|
+
let cell2 = padEnd(routeTypeSrc, width2);
|
|
88
|
+
let cell3 = padEnd(routeDefinedBy, width3);
|
|
89
89
|
const isHeader = i === 0;
|
|
90
90
|
if (isHeader) {
|
|
91
91
|
cell1 = pc.dim(cell1);
|
|
@@ -119,6 +119,11 @@ function truncateRouteFunction(routeStr, lenMax) {
|
|
|
119
119
|
routeStr = truncateString(routeStr, lenMax, (s) => pc.dim(s));
|
|
120
120
|
return routeStr;
|
|
121
121
|
}
|
|
122
|
+
/** Same as String.prototype.padEnd but with stripAnsi() */
|
|
123
|
+
function padEnd(str, width) {
|
|
124
|
+
const padWidth = Math.max(0, width - stripAnsi(str).length);
|
|
125
|
+
return str + ''.padEnd(padWidth, ' ');
|
|
126
|
+
}
|
|
122
127
|
function removeNonAscii(str) {
|
|
123
128
|
// https://stackoverflow.com/questions/20856197/remove-non-ascii-character-in-string/20856346#20856346
|
|
124
129
|
return str.replace(/[^\x00-\x7F]/g, '');
|
|
@@ -20,6 +20,7 @@ import { preparePageContextForUserConsumptionServerSide } from './preparePageCon
|
|
|
20
20
|
import { executeGuardHook } from '../../../shared/route/executeGuardHook.js';
|
|
21
21
|
import { loadPageRoutes } from '../../../shared/route/loadPageRoutes.js';
|
|
22
22
|
import pc from '@brillout/picocolors';
|
|
23
|
+
import { getConfigValueFilePathToShowToUser } from '../../../shared/page-configs/utils.js';
|
|
23
24
|
async function renderPageAlreadyRouted(pageContext) {
|
|
24
25
|
// pageContext._pageId can either be the:
|
|
25
26
|
// - ID of the page matching the routing, or the
|
|
@@ -166,9 +167,9 @@ function assertNonMixedDesign(pageFilesAll, pageConfigs) {
|
|
|
166
167
|
const indent = '- ';
|
|
167
168
|
const v1Files = unique(pageConfigs
|
|
168
169
|
.map((p) => Object.values(p.configValues)
|
|
169
|
-
.map(
|
|
170
|
+
.map(getConfigValueFilePathToShowToUser)
|
|
170
171
|
.filter(isNotNullish)
|
|
171
|
-
.map((
|
|
172
|
+
.map((filePathToShowToUser) => indent + filePathToShowToUser))
|
|
172
173
|
.flat(2));
|
|
173
174
|
assertUsage(false, [
|
|
174
175
|
'Mixing the new V1 design with the old V0.4 design is forbidden.',
|
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
export { getClientEntryFilePath };
|
|
2
|
-
import {
|
|
3
|
-
import { assert } from './utils.js';
|
|
2
|
+
import { getConfigValue } from '../../shared/page-configs/utils.js';
|
|
4
3
|
function getClientEntryFilePath(pageConfig) {
|
|
5
4
|
const configName = 'client';
|
|
6
5
|
const configValue = getConfigValue(pageConfig, configName, 'string');
|
|
7
6
|
if (!configValue)
|
|
8
7
|
return null;
|
|
9
|
-
|
|
10
|
-
const { value } = configValue;
|
|
11
|
-
// Users should be able to suppress client entry by setting its value to null
|
|
12
|
-
assert(value !== null);
|
|
13
|
-
const clientEntryFilePath = definedAtInfo.filePath;
|
|
14
|
-
return clientEntryFilePath;
|
|
8
|
+
return configValue.value;
|
|
15
9
|
}
|
|
@@ -4,7 +4,8 @@ export type { PageContextUrlComputedPropsInternal };
|
|
|
4
4
|
export type { PageContextUrlComputedPropsClient };
|
|
5
5
|
export type { PageContextUrlComputedPropsServer };
|
|
6
6
|
export type { PageContextUrlSources };
|
|
7
|
-
type
|
|
7
|
+
export type { Url };
|
|
8
|
+
type Url = {
|
|
8
9
|
/** The URL origin, e.g. `https://example.com` of `https://example.com/product/42?details=yes#reviews` */
|
|
9
10
|
origin: null | string;
|
|
10
11
|
/** The URL pathname, e.g. `/product/42` of `https://example.com/product/42?details=yes#reviews` */
|
|
@@ -34,8 +35,9 @@ type PageContextUrlComputedPropsClient = {
|
|
|
34
35
|
/** The URL pathname, e.g. `/product/42` of `https://example.com/product/42?details=yes#reviews` */
|
|
35
36
|
urlPathname: string;
|
|
36
37
|
/** Parsed information about the current URL */
|
|
37
|
-
urlParsed:
|
|
38
|
+
urlParsed: Url;
|
|
38
39
|
};
|
|
40
|
+
/** For Vike internal use */
|
|
39
41
|
type PageContextUrlComputedPropsInternal = PageContextUrlComputedPropsClient & {
|
|
40
42
|
_urlRewrite: string | null;
|
|
41
43
|
};
|