vike 0.4.248 → 0.4.249-commit-55681da
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/bin.js +3 -0
- package/dist/client/runtime-client-routing/getPageContext.js +0 -2
- package/dist/client/runtime-client-routing/getPageContextFromHooks.d.ts +8 -8
- package/dist/client/runtime-client-routing/renderPageClient.d.ts +4 -4
- package/dist/node/api/utils.d.ts +2 -2
- package/dist/node/api/utils.js +2 -2
- package/dist/node/vite/plugins/build/pluginBuildConfig.js +2 -2
- package/dist/node/vite/plugins/pluginVirtualFiles.js +71 -113
- package/dist/node/vite/shared/loggerDev.d.ts +3 -0
- package/dist/node/vite/shared/loggerDev.js +29 -13
- package/dist/node/vite/shared/loggerVite.js +3 -3
- package/dist/node/vite/shared/resolveVikeConfigInternal/assertExtensions.d.ts +1 -1
- package/dist/node/vite/shared/resolveVikeConfigInternal/{crawlPlusFiles.d.ts → crawlPlusFilePaths.d.ts} +2 -2
- package/dist/node/vite/shared/resolveVikeConfigInternal/{crawlPlusFiles.js → crawlPlusFilePaths.js} +4 -4
- package/dist/node/vite/shared/resolveVikeConfigInternal/{getPlusFilesAll.d.ts → getPlusFilesByLocationId.d.ts} +8 -6
- package/dist/node/vite/shared/resolveVikeConfigInternal/{getPlusFilesAll.js → getPlusFilesByLocationId.js} +47 -59
- package/dist/node/vite/shared/resolveVikeConfigInternal/loadFileAtConfigTime.d.ts +1 -1
- package/dist/node/vite/shared/resolveVikeConfigInternal.d.ts +1 -1
- package/dist/node/vite/shared/resolveVikeConfigInternal.js +66 -64
- package/dist/server/runtime/asyncHook.d.ts +2 -2
- package/dist/server/runtime/asyncHook.js +2 -2
- package/dist/server/runtime/renderPageServer/html/stream.js +12 -13
- package/dist/server/utils.d.ts +2 -2
- package/dist/server/utils.js +2 -2
- package/dist/types/Config.d.ts +3 -2
- package/dist/types/PageConfig.d.ts +1 -1
- package/dist/utils/PROJECT_VERSION.d.ts +1 -1
- package/dist/utils/PROJECT_VERSION.js +1 -1
- package/dist/utils/assert.d.ts +7 -4
- package/dist/utils/assert.js +65 -50
- package/dist/utils/colorsClient.d.ts +6 -0
- package/dist/utils/colorsClient.js +16 -0
- package/dist/utils/{colors.js → colorsServer.js} +2 -0
- package/dist/utils/formatHintLog.js +1 -1
- package/dist/utils/getBetterError.js +11 -7
- package/dist/utils/shallowClone.d.ts +2 -0
- package/dist/utils/shallowClone.js +11 -0
- package/dist/utils/trimWithAnsi.js +1 -1
- package/package.json +6 -6
- package/dist/utils/colorVike.d.ts +0 -2
- package/dist/utils/colorVike.js +0 -5
- package/node/cli/bin.js +0 -3
- /package/dist/node/vite/shared/resolveVikeConfigInternal/{crawlPlusFiles → crawlPlusFilePaths}/ignorePatternsBuiltIn.d.ts +0 -0
- /package/dist/node/vite/shared/resolveVikeConfigInternal/{crawlPlusFiles → crawlPlusFilePaths}/ignorePatternsBuiltIn.js +0 -0
- /package/dist/utils/{colors.d.ts → colorsServer.d.ts} +0 -0
|
@@ -1,61 +1,51 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { getPlusFilesByLocationId };
|
|
2
2
|
import { assert } from '../../utils.js';
|
|
3
3
|
import { configDefinitionsBuiltIn } from './configDefinitionsBuiltIn.js';
|
|
4
4
|
import { getLocationId } from './filesystemRouting.js';
|
|
5
|
-
import {
|
|
5
|
+
import { crawlPlusFilePaths, getPlusFileValueConfigName } from './crawlPlusFilePaths.js';
|
|
6
6
|
import { getConfigFileExport } from './getConfigFileExport.js';
|
|
7
7
|
import { loadConfigFile, loadValueFile } from './loadFileAtConfigTime.js';
|
|
8
8
|
import { resolvePointerImport } from './resolvePointerImport.js';
|
|
9
9
|
import { getFilePathResolved } from '../getFilePath.js';
|
|
10
10
|
import { assertExtensionsConventions, assertExtensionsRequire } from './assertExtensions.js';
|
|
11
|
-
async function
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
configFiles.push(f);
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
valueFiles.push(f);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
let plusFilesAll = {};
|
|
24
|
-
await Promise.all([
|
|
25
|
-
// Config files
|
|
26
|
-
...configFiles.map(async (filePath) => {
|
|
11
|
+
async function getPlusFilesByLocationId(userRootDir, esbuildCache) {
|
|
12
|
+
const plusFilePaths = (await crawlPlusFilePaths(userRootDir)).map(({ filePathAbsoluteUserRootDir }) => getFilePathResolved({ filePathAbsoluteUserRootDir, userRootDir }));
|
|
13
|
+
const plusFilesByLocationId = {};
|
|
14
|
+
await Promise.all(plusFilePaths.map(async (filePath) => {
|
|
15
|
+
if (getPlusFileValueConfigName(filePath.filePathAbsoluteFilesystem) === 'config') {
|
|
16
|
+
// +config.js files
|
|
27
17
|
const { filePathAbsoluteUserRootDir } = filePath;
|
|
28
18
|
assert(filePathAbsoluteUserRootDir);
|
|
29
19
|
const { configFile, extendsConfigs } = await loadConfigFile(filePath, userRootDir, [], false, esbuildCache);
|
|
30
20
|
assert(filePath.filePathAbsoluteUserRootDir);
|
|
31
21
|
const locationId = getLocationId(filePathAbsoluteUserRootDir);
|
|
32
22
|
const plusFile = getPlusFileFromConfigFile(configFile, false, locationId, userRootDir);
|
|
33
|
-
|
|
34
|
-
|
|
23
|
+
plusFilesByLocationId[locationId] = plusFilesByLocationId[locationId] ?? [];
|
|
24
|
+
plusFilesByLocationId[locationId].push(plusFile);
|
|
35
25
|
extendsConfigs.forEach((extendsConfig) => {
|
|
36
26
|
/* We purposely use the same locationId because the Vike extension's config should only apply to where it's being extended from, for example:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
27
|
+
```js
|
|
28
|
+
// /pages/admin/+config.js
|
|
29
|
+
|
|
30
|
+
import vikeVue from 'vike-vue/config'
|
|
31
|
+
// Should only apply to /pages/admin/**
|
|
32
|
+
export default { extends: [vikeVue] }
|
|
33
|
+
```
|
|
34
|
+
```js
|
|
35
|
+
// /pages/marketing/+config.js
|
|
36
|
+
|
|
37
|
+
import vikeReact from 'vike-react/config'
|
|
38
|
+
// Should only apply to /pages/marketing/**
|
|
39
|
+
export default { extends: [vikeReact] }
|
|
40
|
+
```
|
|
41
|
+
*/
|
|
52
42
|
const plusFile = getPlusFileFromConfigFile(extendsConfig, true, locationId, userRootDir);
|
|
53
43
|
assertExtensionsConventions(plusFile);
|
|
54
|
-
|
|
44
|
+
plusFilesByLocationId[locationId].push(plusFile);
|
|
55
45
|
});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
// +{configName}.js files
|
|
59
49
|
const { filePathAbsoluteUserRootDir } = filePath;
|
|
60
50
|
assert(filePathAbsoluteUserRootDir);
|
|
61
51
|
const configName = getPlusFileValueConfigName(filePathAbsoluteUserRootDir);
|
|
@@ -68,23 +58,23 @@ async function getPlusFilesAll(userRootDir, esbuildCache) {
|
|
|
68
58
|
isNotLoaded: true,
|
|
69
59
|
configName,
|
|
70
60
|
};
|
|
71
|
-
|
|
72
|
-
|
|
61
|
+
plusFilesByLocationId[locationId] = plusFilesByLocationId[locationId] ?? [];
|
|
62
|
+
plusFilesByLocationId[locationId].push(plusFile);
|
|
73
63
|
// We don't have access to the custom config definitions defined by the user yet.
|
|
74
64
|
// - If `configDef` is `undefined` => we load the file +{configName}.js later.
|
|
75
65
|
// - We already need to load +meta.js here (to get the custom config definitions defined by the user)
|
|
76
66
|
await loadValueFile(plusFile, configDefinitionsBuiltIn, userRootDir, esbuildCache);
|
|
77
|
-
}
|
|
78
|
-
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
79
69
|
// Make lists element order deterministic
|
|
80
|
-
Object.entries(
|
|
70
|
+
Object.entries(plusFilesByLocationId).forEach(([_locationId, plusFiles]) => {
|
|
81
71
|
plusFiles.sort(sortMakeDeterministic);
|
|
82
72
|
});
|
|
83
|
-
assertPlusFiles(
|
|
84
|
-
return
|
|
73
|
+
assertPlusFiles(plusFilesByLocationId);
|
|
74
|
+
return plusFilesByLocationId;
|
|
85
75
|
}
|
|
86
|
-
function assertPlusFiles(
|
|
87
|
-
const plusFiles = Object.values(
|
|
76
|
+
function assertPlusFiles(plusFilesByLocationId) {
|
|
77
|
+
const plusFiles = Object.values(plusFilesByLocationId).flat();
|
|
88
78
|
// The earlier we call it the better, so that +require can be used by Vike extensions to depend on new Vike features
|
|
89
79
|
assertExtensionsRequire(plusFiles);
|
|
90
80
|
}
|
|
@@ -95,12 +85,14 @@ function getPlusFileFromConfigFile(configFile, isExtensionConfig, locationId, us
|
|
|
95
85
|
const fileExport = getConfigFileExport(fileExports, filePath.filePathToShowToUser);
|
|
96
86
|
Object.entries(fileExport).forEach(([configName, configValue]) => {
|
|
97
87
|
fileExportsByConfigName[configName] = configValue;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
};
|
|
88
|
+
// Pointer imports
|
|
89
|
+
const values = Array.isArray(configValue) ? configValue : [configValue];
|
|
90
|
+
const pointerImports = values
|
|
91
|
+
.map((value) => resolvePointerImport(value, configFile.filePath, userRootDir, configName))
|
|
92
|
+
.filter((pointerImport) => pointerImport !== null)
|
|
93
|
+
.map((pointerImport) => ({ ...pointerImport, fileExportValueLoaded: false }));
|
|
94
|
+
if (pointerImports.length > 0) {
|
|
95
|
+
pointerImportsByConfigName[configName] = pointerImports;
|
|
104
96
|
}
|
|
105
97
|
});
|
|
106
98
|
const plusFile = {
|
|
@@ -116,10 +108,6 @@ function getPlusFileFromConfigFile(configFile, isExtensionConfig, locationId, us
|
|
|
116
108
|
}
|
|
117
109
|
// Make order deterministic (no other purpose)
|
|
118
110
|
function sortMakeDeterministic(plusFile1, plusFile2) {
|
|
111
|
+
// Sort by file path
|
|
119
112
|
return plusFile1.filePath.filePathAbsoluteVite < plusFile2.filePath.filePathAbsoluteVite ? -1 : 1;
|
|
120
113
|
}
|
|
121
|
-
async function findPlusFiles(userRootDir) {
|
|
122
|
-
const files = await crawlPlusFiles(userRootDir);
|
|
123
|
-
const plusFiles = files.map(({ filePathAbsoluteUserRootDir }) => getFilePathResolved({ filePathAbsoluteUserRootDir, userRootDir }));
|
|
124
|
-
return plusFiles;
|
|
125
|
-
}
|
|
@@ -5,7 +5,7 @@ export type { ConfigFile };
|
|
|
5
5
|
export type { PointerImportLoaded };
|
|
6
6
|
import type { FilePathResolved } from '../../../../types/FilePath.js';
|
|
7
7
|
import { type EsbuildCache } from './transpileAndExecuteFile.js';
|
|
8
|
-
import type { PlusFileValue } from './
|
|
8
|
+
import type { PlusFileValue } from './getPlusFilesByLocationId.js';
|
|
9
9
|
import { PointerImport } from './resolvePointerImport.js';
|
|
10
10
|
import type { ConfigDefinitionsInternal } from './configDefinitionsBuiltIn.js';
|
|
11
11
|
type ConfigFile = {
|
|
@@ -14,7 +14,7 @@ export type { PageConfigBuildTimeBeforeComputed };
|
|
|
14
14
|
import type { PageConfigGlobalBuildTime, PageConfigBuildTime } from '../../../types/PageConfig.js';
|
|
15
15
|
import { type ConfigDefinitionsInternal, type ConfigDefinitionInternal } from './resolveVikeConfigInternal/configDefinitionsBuiltIn.js';
|
|
16
16
|
import { type GlobalConfigPublic } from '../../../shared-server-client/page-configs/resolveVikeConfigPublic.js';
|
|
17
|
-
import { type PlusFile } from './resolveVikeConfigInternal/
|
|
17
|
+
import { type PlusFile } from './resolveVikeConfigInternal/getPlusFilesByLocationId.js';
|
|
18
18
|
import type { PrerenderContextPublic } from '../../prerender/runPrerender.js';
|
|
19
19
|
import type { ResolvedConfig, UserConfig } from 'vite';
|
|
20
20
|
import { type DangerouslyUseInternals } from '../../../shared-server-client/getProxyForPublicUsage.js';
|
|
@@ -25,7 +25,7 @@ import { getFilePathResolved } from './getFilePath.js';
|
|
|
25
25
|
import { getConfigValueBuildTime } from '../../../shared-server-client/page-configs/getConfigValueBuildTime.js';
|
|
26
26
|
import { resolveGlobalConfigPublic, } from '../../../shared-server-client/page-configs/resolveVikeConfigPublic.js';
|
|
27
27
|
import { getConfigValuesBase, isJsonValue, } from '../../../shared-server-client/page-configs/serialize/serializeConfigValues.js';
|
|
28
|
-
import {
|
|
28
|
+
import { getPlusFilesByLocationId, } from './resolveVikeConfigInternal/getPlusFilesByLocationId.js';
|
|
29
29
|
import { getEnvVarObject } from './getEnvVarObject.js';
|
|
30
30
|
import { getVikeApiOperation } from '../../../shared-server-node/api-context.js';
|
|
31
31
|
import { getCliOptions } from '../../cli/context.js';
|
|
@@ -169,9 +169,9 @@ async function resolveVikeConfigInternal_withErrorHandling(userRootDir, isDev, v
|
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
171
|
async function resolveVikeConfigInternal(userRootDir, vikeVitePluginOptions, esbuildCache) {
|
|
172
|
-
const
|
|
173
|
-
const configDefinitionsResolved = await resolveConfigDefinitions(
|
|
174
|
-
const { pageConfigGlobal, pageConfigs } = getPageConfigsBuildTime(configDefinitionsResolved,
|
|
172
|
+
const plusFilesByLocationId = await getPlusFilesByLocationId(userRootDir, esbuildCache);
|
|
173
|
+
const configDefinitionsResolved = await resolveConfigDefinitions(plusFilesByLocationId, userRootDir, esbuildCache);
|
|
174
|
+
const { pageConfigGlobal, pageConfigs } = getPageConfigsBuildTime(configDefinitionsResolved, plusFilesByLocationId, userRootDir);
|
|
175
175
|
if (!globalObject.isV1Design_)
|
|
176
176
|
globalObject.isV1Design_ = pageConfigs.length > 0;
|
|
177
177
|
// Backwards compatibility for vike(options) in vite.config.js
|
|
@@ -197,21 +197,21 @@ function resolveGlobalConfig(pageConfigGlobal, pageConfigs) {
|
|
|
197
197
|
const globalConfigPublic = resolveGlobalConfigPublic(pageConfigs, pageConfigGlobal, getConfigValues);
|
|
198
198
|
return globalConfigPublic;
|
|
199
199
|
}
|
|
200
|
-
async function resolveConfigDefinitions(
|
|
201
|
-
const
|
|
200
|
+
async function resolveConfigDefinitions(plusFilesByLocationId, userRootDir, esbuildCache) {
|
|
201
|
+
const plusFilesByLocationIdOrdered = Object.values(plusFilesByLocationId)
|
|
202
202
|
.flat()
|
|
203
|
-
.sort((plusFile1, plusFile2) => sortAfterInheritanceOrderGlobal(plusFile1, plusFile2,
|
|
203
|
+
.sort((plusFile1, plusFile2) => sortAfterInheritanceOrderGlobal(plusFile1, plusFile2, plusFilesByLocationId, null));
|
|
204
204
|
const configDefinitionsGlobal = getConfigDefinitions(
|
|
205
|
-
// We use `
|
|
206
|
-
|
|
207
|
-
await loadCustomConfigBuildTimeFiles(
|
|
208
|
-
const configDefinitionsAll = getConfigDefinitions(Object.values(
|
|
205
|
+
// We use `plusFilesByLocationId` 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
|
+
plusFilesByLocationIdOrdered, (configDef) => !!configDef.global);
|
|
207
|
+
await loadCustomConfigBuildTimeFiles(plusFilesByLocationId, configDefinitionsGlobal, userRootDir, esbuildCache);
|
|
208
|
+
const configDefinitionsAll = getConfigDefinitions(Object.values(plusFilesByLocationId).flat());
|
|
209
209
|
const configNamesKnownAll = Object.keys(configDefinitionsAll);
|
|
210
210
|
const configNamesKnownGlobal = Object.keys(configDefinitionsGlobal);
|
|
211
211
|
assert(configNamesKnownGlobal.every((configName) => configNamesKnownAll.includes(configName)));
|
|
212
212
|
const configDefinitionsLocal = {};
|
|
213
|
-
await Promise.all(objectEntries(
|
|
214
|
-
const plusFilesRelevant = objectEntries(
|
|
213
|
+
await Promise.all(objectEntries(plusFilesByLocationId).map(async ([locationIdPage, plusFiles]) => {
|
|
214
|
+
const plusFilesRelevant = objectEntries(plusFilesByLocationId)
|
|
215
215
|
.filter(([locationId]) => isInherited(locationId, locationIdPage))
|
|
216
216
|
.map(([, plusFiles]) => plusFiles)
|
|
217
217
|
.flat()
|
|
@@ -238,7 +238,7 @@ async function resolveConfigDefinitions(plusFilesAll, userRootDir, esbuildCache)
|
|
|
238
238
|
return configDefinitionsResolved;
|
|
239
239
|
}
|
|
240
240
|
// Load value files (with `env.config===true`) of *custom* configs.
|
|
241
|
-
// - The value files of *built-in* configs are already loaded at `
|
|
241
|
+
// - The value files of *built-in* configs are already loaded at `getPlusFilesByLocationId()`.
|
|
242
242
|
async function loadCustomConfigBuildTimeFiles(plusFiles, configDefinitions, userRootDir, esbuildCache) {
|
|
243
243
|
const plusFileList = Object.values(plusFiles).flat(1);
|
|
244
244
|
await Promise.all(plusFileList.map(async (plusFile) => {
|
|
@@ -246,28 +246,28 @@ async function loadCustomConfigBuildTimeFiles(plusFiles, configDefinitions, user
|
|
|
246
246
|
await loadValueFile(plusFile, configDefinitions, userRootDir, esbuildCache);
|
|
247
247
|
}
|
|
248
248
|
else {
|
|
249
|
-
await Promise.all(Object.entries(plusFile.pointerImportsByConfigName).map(async ([configName,
|
|
250
|
-
await loadPointerImport(pointerImport, userRootDir, configName, configDefinitions, esbuildCache);
|
|
249
|
+
await Promise.all(Object.entries(plusFile.pointerImportsByConfigName).map(async ([configName, pointerImports]) => {
|
|
250
|
+
await Promise.all(pointerImports.map((pointerImport) => loadPointerImport(pointerImport, userRootDir, configName, configDefinitions, esbuildCache)));
|
|
251
251
|
}));
|
|
252
252
|
}
|
|
253
253
|
}));
|
|
254
254
|
}
|
|
255
|
-
function getPageConfigsBuildTime(configDefinitionsResolved,
|
|
255
|
+
function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesByLocationId, userRootDir) {
|
|
256
256
|
const pageConfigGlobal = {
|
|
257
257
|
configDefinitions: configDefinitionsResolved.configDefinitionsGlobal,
|
|
258
258
|
configValueSources: {},
|
|
259
259
|
};
|
|
260
260
|
objectEntries(configDefinitionsResolved.configDefinitionsGlobal).forEach(([configName, configDef]) => {
|
|
261
261
|
const sources = resolveConfigValueSources(configName, configDef,
|
|
262
|
-
// We use `
|
|
263
|
-
Object.values(
|
|
262
|
+
// We use `plusFilesByLocationId` 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).
|
|
263
|
+
Object.values(plusFilesByLocationId).flat(), userRootDir, true, plusFilesByLocationId);
|
|
264
264
|
if (sources.length === 0)
|
|
265
265
|
return;
|
|
266
266
|
pageConfigGlobal.configValueSources[configName] = sources;
|
|
267
267
|
});
|
|
268
|
-
applyEffects(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal,
|
|
268
|
+
applyEffects(pageConfigGlobal.configValueSources, configDefinitionsResolved.configDefinitionsGlobal, plusFilesByLocationId);
|
|
269
269
|
sortConfigValueSources(pageConfigGlobal.configValueSources, null);
|
|
270
|
-
assertPageConfigGlobal(pageConfigGlobal,
|
|
270
|
+
assertPageConfigGlobal(pageConfigGlobal, plusFilesByLocationId);
|
|
271
271
|
const pageConfigs = objectEntries(configDefinitionsResolved.configDefinitionsLocal)
|
|
272
272
|
.filter(([_locationId, { plusFiles }]) => isDefiningPage(plusFiles))
|
|
273
273
|
.map(([locationId, { configDefinitions, plusFilesRelevant }]) => {
|
|
@@ -276,13 +276,13 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
|
|
|
276
276
|
objectEntries(configDefinitionsLocal)
|
|
277
277
|
.filter(([_configName, configDef]) => configDef.global !== true)
|
|
278
278
|
.forEach(([configName, configDef]) => {
|
|
279
|
-
const sources = resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, false,
|
|
279
|
+
const sources = resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, false, plusFilesByLocationId);
|
|
280
280
|
if (sources.length === 0)
|
|
281
281
|
return;
|
|
282
282
|
configValueSources[configName] = sources;
|
|
283
283
|
});
|
|
284
284
|
const pageConfigRoute = determineRouteFilesystem(locationId, configValueSources);
|
|
285
|
-
applyEffects(configValueSources, configDefinitionsLocal,
|
|
285
|
+
applyEffects(configValueSources, configDefinitionsLocal, plusFilesByLocationId);
|
|
286
286
|
sortConfigValueSources(configValueSources, locationId);
|
|
287
287
|
const pageConfig = {
|
|
288
288
|
pageId: locationId,
|
|
@@ -299,15 +299,15 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesAll, userRo
|
|
|
299
299
|
assertPageConfigs(pageConfigs);
|
|
300
300
|
return { pageConfigs, pageConfigGlobal };
|
|
301
301
|
}
|
|
302
|
-
function assertPageConfigGlobal(pageConfigGlobal,
|
|
302
|
+
function assertPageConfigGlobal(pageConfigGlobal, plusFilesByLocationId) {
|
|
303
303
|
Object.entries(pageConfigGlobal.configValueSources).forEach(([configName, sources]) => {
|
|
304
|
-
assertGlobalConfigLocation(configName, sources,
|
|
304
|
+
assertGlobalConfigLocation(configName, sources, plusFilesByLocationId, pageConfigGlobal.configDefinitions);
|
|
305
305
|
});
|
|
306
306
|
}
|
|
307
|
-
function assertGlobalConfigLocation(configName, sources,
|
|
307
|
+
function assertGlobalConfigLocation(configName, sources, plusFilesByLocationId, configDefinitionsGlobal) {
|
|
308
308
|
// Determine existing global +config.js files
|
|
309
309
|
const configFilePathsGlobal = [];
|
|
310
|
-
const plusFilesGlobal = Object.values(objectFromEntries(objectEntries(
|
|
310
|
+
const plusFilesGlobal = Object.values(objectFromEntries(objectEntries(plusFilesByLocationId).filter(([locationId]) => isGlobalLocation(locationId, plusFilesByLocationId)))).flat();
|
|
311
311
|
plusFilesGlobal
|
|
312
312
|
.filter((i) => i.isConfigFile)
|
|
313
313
|
.forEach((plusFile) => {
|
|
@@ -326,7 +326,7 @@ function assertGlobalConfigLocation(configName, sources, plusFilesAll, configDef
|
|
|
326
326
|
if (!filePathAbsoluteUserRootDir)
|
|
327
327
|
return;
|
|
328
328
|
assert(!plusFile.isExtensionConfig);
|
|
329
|
-
if (!isGlobalLocation(source.locationId,
|
|
329
|
+
if (!isGlobalLocation(source.locationId, plusFilesByLocationId)) {
|
|
330
330
|
const configDef = configDefinitionsGlobal[configName];
|
|
331
331
|
assert(configDef);
|
|
332
332
|
const isConditionallyGlobal = isCallable(configDef.global);
|
|
@@ -502,9 +502,9 @@ function sortAfterInheritanceOrderPage(plusFile1, plusFile2, locationIdPage, con
|
|
|
502
502
|
}
|
|
503
503
|
return 0;
|
|
504
504
|
}
|
|
505
|
-
function sortAfterInheritanceOrderGlobal(plusFile1, plusFile2,
|
|
506
|
-
if (
|
|
507
|
-
const ret = makeFirst((plusFile) => isGlobalLocation(plusFile.locationId,
|
|
505
|
+
function sortAfterInheritanceOrderGlobal(plusFile1, plusFile2, plusFilesByLocationId, configName) {
|
|
506
|
+
if (plusFilesByLocationId) {
|
|
507
|
+
const ret = makeFirst((plusFile) => isGlobalLocation(plusFile.locationId, plusFilesByLocationId))(plusFile1, plusFile2);
|
|
508
508
|
if (ret !== 0)
|
|
509
509
|
return ret;
|
|
510
510
|
}
|
|
@@ -552,13 +552,13 @@ function sortPlusFilesSameLocationId(plusFile1, plusFile2, configName) {
|
|
|
552
552
|
return ret;
|
|
553
553
|
}
|
|
554
554
|
// Config set by +{configName}.js (highest precedence)
|
|
555
|
-
// No need to make it deterministic: the overall order is already deterministic, see sortMakeDeterministic() at
|
|
555
|
+
// No need to make it deterministic: the overall order is already deterministic, see sortMakeDeterministic() at getPlusFilesByLocationId()
|
|
556
556
|
return 0;
|
|
557
557
|
}
|
|
558
|
-
function resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, isGlobal,
|
|
558
|
+
function resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, isGlobal, plusFilesByLocationId) {
|
|
559
559
|
let sources = plusFilesRelevant
|
|
560
560
|
.filter((plusFile) => isDefiningConfig(plusFile, configName))
|
|
561
|
-
.
|
|
561
|
+
.flatMap((plusFile) => getConfigValueSources(configName, plusFile, configDef, userRootDir));
|
|
562
562
|
// Filter hydrid global-local configs
|
|
563
563
|
if (!isCallable(configDef.global)) {
|
|
564
564
|
// Already filtered
|
|
@@ -570,7 +570,7 @@ function resolveConfigValueSources(configName, configDef, plusFilesRelevant, use
|
|
|
570
570
|
sources = sources.filter((source) => {
|
|
571
571
|
assert(source.configEnv.config);
|
|
572
572
|
assert(source.valueIsLoaded);
|
|
573
|
-
const valueIsGlobal = resolveIsGlobalValue(configDef.global, source,
|
|
573
|
+
const valueIsGlobal = resolveIsGlobalValue(configDef.global, source, plusFilesByLocationId);
|
|
574
574
|
return isGlobal ? valueIsGlobal : !valueIsGlobal;
|
|
575
575
|
});
|
|
576
576
|
}
|
|
@@ -579,7 +579,7 @@ function resolveConfigValueSources(configName, configDef, plusFilesRelevant, use
|
|
|
579
579
|
function isDefiningConfig(plusFile, configName) {
|
|
580
580
|
return getConfigNamesSetByPlusFile(plusFile).includes(configName);
|
|
581
581
|
}
|
|
582
|
-
function
|
|
582
|
+
function getConfigValueSources(configName, plusFile, configDef, userRootDir) {
|
|
583
583
|
const confVal = getConfVal(plusFile, configName);
|
|
584
584
|
assert(confVal);
|
|
585
585
|
const configValueSourceCommon = {
|
|
@@ -622,7 +622,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
|
|
|
622
622
|
valueIsDefinedByPlusValueFile: false,
|
|
623
623
|
definedAt: definedAtFilePath,
|
|
624
624
|
};
|
|
625
|
-
return configValueSource;
|
|
625
|
+
return [configValueSource];
|
|
626
626
|
}
|
|
627
627
|
// +config.js
|
|
628
628
|
if (plusFile.isConfigFile) {
|
|
@@ -630,23 +630,25 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
|
|
|
630
630
|
// Defined over pointer import
|
|
631
631
|
const pointerImport = plusFile.pointerImportsByConfigName[configName];
|
|
632
632
|
if (pointerImport) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
633
|
+
return pointerImport.map((pointerImport) => {
|
|
634
|
+
const value = pointerImport.fileExportValueLoaded
|
|
635
|
+
? {
|
|
636
|
+
valueIsLoaded: true,
|
|
637
|
+
value: pointerImport.fileExportValue,
|
|
638
|
+
}
|
|
639
|
+
: {
|
|
640
|
+
valueIsLoaded: false,
|
|
641
|
+
};
|
|
642
|
+
const configValueSource = {
|
|
643
|
+
...configValueSourceCommon,
|
|
644
|
+
...value,
|
|
645
|
+
configEnv: resolveConfigEnv(configDef.env, pointerImport.fileExportPath),
|
|
646
|
+
valueIsLoadedWithImport: true,
|
|
647
|
+
valueIsDefinedByPlusValueFile: false,
|
|
648
|
+
definedAt: pointerImport.fileExportPath,
|
|
640
649
|
};
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
...value,
|
|
644
|
-
configEnv: resolveConfigEnv(configDef.env, pointerImport.fileExportPath),
|
|
645
|
-
valueIsLoadedWithImport: true,
|
|
646
|
-
valueIsDefinedByPlusValueFile: false,
|
|
647
|
-
definedAt: pointerImport.fileExportPath,
|
|
648
|
-
};
|
|
649
|
-
return configValueSource;
|
|
650
|
+
return configValueSource;
|
|
651
|
+
});
|
|
650
652
|
}
|
|
651
653
|
// Defined inside +config.js
|
|
652
654
|
const configValueSource = {
|
|
@@ -658,7 +660,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
|
|
|
658
660
|
valueIsDefinedByPlusValueFile: false,
|
|
659
661
|
definedAt: definedAtFilePath_,
|
|
660
662
|
};
|
|
661
|
-
return configValueSource;
|
|
663
|
+
return [configValueSource];
|
|
662
664
|
}
|
|
663
665
|
// Defined by value file, i.e. +{configName}.js
|
|
664
666
|
if (!plusFile.isConfigFile) {
|
|
@@ -678,7 +680,7 @@ function getConfigValueSource(configName, plusFile, configDef, userRootDir) {
|
|
|
678
680
|
[configName],
|
|
679
681
|
},
|
|
680
682
|
};
|
|
681
|
-
return configValueSource;
|
|
683
|
+
return [configValueSource];
|
|
682
684
|
}
|
|
683
685
|
assert(false);
|
|
684
686
|
}
|
|
@@ -694,12 +696,12 @@ function isDefiningPage(plusFiles) {
|
|
|
694
696
|
function isDefiningPageConfig(configName) {
|
|
695
697
|
return ['Page', 'route'].includes(configName);
|
|
696
698
|
}
|
|
697
|
-
function resolveIsGlobalValue(configDefGlobal, source,
|
|
699
|
+
function resolveIsGlobalValue(configDefGlobal, source, plusFilesByLocationId) {
|
|
698
700
|
assert(source.valueIsLoaded);
|
|
699
701
|
let isGlobal;
|
|
700
702
|
if (isCallable(configDefGlobal))
|
|
701
703
|
isGlobal = configDefGlobal(source.value, {
|
|
702
|
-
isGlobalLocation: isGlobalLocation(source.locationId,
|
|
704
|
+
isGlobalLocation: isGlobalLocation(source.locationId, plusFilesByLocationId),
|
|
703
705
|
});
|
|
704
706
|
else
|
|
705
707
|
isGlobal = configDefGlobal ?? false;
|
|
@@ -802,7 +804,7 @@ function assertMetaUsage(metaVal, metaConfigDefinedAt) {
|
|
|
802
804
|
});
|
|
803
805
|
}
|
|
804
806
|
// Test: https://github.com/vikejs/vike/blob/871a111a77d637bbd156b07be5ae728c3d595501/test/playground/pages/config-meta/effect/e2e-test.ts
|
|
805
|
-
function applyEffects(configValueSources, configDefinitions,
|
|
807
|
+
function applyEffects(configValueSources, configDefinitions, plusFilesByLocationId) {
|
|
806
808
|
objectEntries(configDefinitions).forEach(([configNameEffect, configDefEffect]) => {
|
|
807
809
|
const sourceEffect = configValueSources[configNameEffect]?.[0];
|
|
808
810
|
if (!sourceEffect)
|
|
@@ -812,7 +814,7 @@ function applyEffects(configValueSources, configDefinitions, plusFilesAll) {
|
|
|
812
814
|
return;
|
|
813
815
|
const configModFromEffect = effect;
|
|
814
816
|
// Apply config value changes first to create sources, then meta.env changes to modify their env
|
|
815
|
-
applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions,
|
|
817
|
+
applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions, plusFilesByLocationId);
|
|
816
818
|
applyEffectMetaEnv(configModFromEffect, configValueSources, configDefEffect);
|
|
817
819
|
});
|
|
818
820
|
}
|
|
@@ -833,7 +835,7 @@ function runEffect(configName, configDef, source) {
|
|
|
833
835
|
return null;
|
|
834
836
|
return configModFromEffect;
|
|
835
837
|
}
|
|
836
|
-
function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions,
|
|
838
|
+
function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSources, configNameEffect, configDefEffect, configDefinitions, plusFilesByLocationId) {
|
|
837
839
|
objectEntries(configModFromEffect).forEach(([configNameTarget, configValue]) => {
|
|
838
840
|
if (configNameTarget === 'meta')
|
|
839
841
|
return;
|
|
@@ -851,8 +853,8 @@ function applyEffectConfVal(configModFromEffect, sourceEffect, configValueSource
|
|
|
851
853
|
value: configValue,
|
|
852
854
|
};
|
|
853
855
|
assert(sourceEffect.valueIsLoaded);
|
|
854
|
-
const isValueGlobalSource = resolveIsGlobalValue(configDefEffect.global, sourceEffect,
|
|
855
|
-
const isValueGlobalTarget = resolveIsGlobalValue(configDef.global, configValueSource,
|
|
856
|
+
const isValueGlobalSource = resolveIsGlobalValue(configDefEffect.global, sourceEffect, plusFilesByLocationId);
|
|
857
|
+
const isValueGlobalTarget = resolveIsGlobalValue(configDef.global, configValueSource, plusFilesByLocationId);
|
|
856
858
|
const isGlobalHumanReadable = (isGlobal) => `${isGlobal ? 'non-' : ''}global`;
|
|
857
859
|
// The error message make it sound like it's an inherent limitation, it actually isn't (both ways can make senses).
|
|
858
860
|
assertUsage(isValueGlobalSource === isValueGlobalTarget, `The configuration ${pc.cyan(configNameEffect)} is set to ${pc.cyan(JSON.stringify(sourceEffect.value))} which is considered ${isGlobalHumanReadable(isValueGlobalSource)}. However, it has a meta.effect that sets the configuration ${pc.cyan(configNameTarget)} to ${pc.cyan(JSON.stringify(configValue))} which is considered ${isGlobalHumanReadable(isValueGlobalTarget)}. This is contradictory: make sure the values are either both non-global or both global.`);
|
|
@@ -1084,8 +1086,8 @@ function resolveConfigEnv(configEnv, filePath) {
|
|
|
1084
1086
|
return configEnvResolved;
|
|
1085
1087
|
}
|
|
1086
1088
|
/** Whether configs defined in `locationId` apply to every page */
|
|
1087
|
-
function isGlobalLocation(locationId,
|
|
1088
|
-
const locationIdsPage = objectEntries(
|
|
1089
|
+
function isGlobalLocation(locationId, plusFilesByLocationId) {
|
|
1090
|
+
const locationIdsPage = objectEntries(plusFilesByLocationId)
|
|
1089
1091
|
.filter(([_locationId, plusFiles]) => isDefiningPage(plusFiles))
|
|
1090
1092
|
.map(([locationId]) => locationId);
|
|
1091
1093
|
return locationIdsPage.every((locId) => isInherited(locationId, locId));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { getPageContext_withAsyncHook };
|
|
2
|
-
export {
|
|
2
|
+
export { getRequestId_withAsyncHook };
|
|
3
3
|
export { getAsyncLocalStorage };
|
|
4
4
|
export type { AsyncStore };
|
|
5
5
|
import type { AsyncLocalStorage as AsyncLocalStorageType } from 'node:async_hooks';
|
|
@@ -8,5 +8,5 @@ type AsyncStore = null | {
|
|
|
8
8
|
pageContext?: Record<string, unknown>;
|
|
9
9
|
};
|
|
10
10
|
declare function getAsyncLocalStorage(): Promise<AsyncLocalStorageType<AsyncStore> | null>;
|
|
11
|
-
declare function
|
|
11
|
+
declare function getRequestId_withAsyncHook(): number | null;
|
|
12
12
|
declare function getPageContext_withAsyncHook(): any;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { getPageContext_withAsyncHook };
|
|
2
|
-
export {
|
|
2
|
+
export { getRequestId_withAsyncHook };
|
|
3
3
|
export { getAsyncLocalStorage };
|
|
4
4
|
import { preparePageContextForPublicUsageServer } from './renderPageServer/preparePageContextForPublicUsageServer.js';
|
|
5
5
|
import { assert, assertIsNotBrowser, getGlobalObject, isObject } from '../utils.js';
|
|
@@ -30,7 +30,7 @@ function getAsyncStore() {
|
|
|
30
30
|
assert(asyncStore === undefined || isObject(asyncStore));
|
|
31
31
|
return asyncStore ?? null;
|
|
32
32
|
}
|
|
33
|
-
function
|
|
33
|
+
function getRequestId_withAsyncHook() {
|
|
34
34
|
const asyncStore = getAsyncStore();
|
|
35
35
|
return asyncStore?.requestId ?? null;
|
|
36
36
|
}
|
|
@@ -242,7 +242,7 @@ async function processStream(streamOriginal, { injectStringAtBegin, injectString
|
|
|
242
242
|
writeStream(injectedChunk); // Adds injectedChunk to buffer
|
|
243
243
|
flushStream(); // Sets shouldFlushStream to true
|
|
244
244
|
}
|
|
245
|
-
// We call
|
|
245
|
+
// We call onStreamDataOrEnd() also when the stream ends in order to properly handle the situation when the stream didn't emit any data
|
|
246
246
|
const onStreamDataOrEnd = (cb) => {
|
|
247
247
|
assert(streamOriginalEnded === false);
|
|
248
248
|
streamOriginalHasStartedEmitting = true;
|
|
@@ -277,26 +277,23 @@ async function processStream(streamOriginal, { injectStringAtBegin, injectString
|
|
|
277
277
|
}
|
|
278
278
|
});
|
|
279
279
|
},
|
|
280
|
-
async onEnd(
|
|
281
|
-
/* Should we use this `isCancel`? Maybe we can skip `injectStringAtEnd()`?
|
|
282
|
-
isCancel,
|
|
283
|
-
//*/
|
|
284
|
-
) {
|
|
280
|
+
async onEnd(isCancel) {
|
|
285
281
|
try {
|
|
286
282
|
assert(!onEndWasCalled);
|
|
287
283
|
onEndWasCalled = true;
|
|
288
284
|
debug('stream end');
|
|
289
|
-
// We call
|
|
285
|
+
// We call onStreamDataOrEnd() also here in case the stream didn't emit any data
|
|
290
286
|
onStreamDataOrEnd(() => {
|
|
291
287
|
streamOriginalEnded = true;
|
|
292
288
|
});
|
|
293
|
-
if (injectStringAtEnd) {
|
|
289
|
+
if (injectStringAtEnd && !isCancel) {
|
|
294
290
|
const injectedChunk = await injectStringAtEnd();
|
|
295
291
|
writeStream(injectedChunk);
|
|
296
292
|
}
|
|
297
293
|
await promiseReadyToWrite; // E.g. if the user calls the pipe wrapper after the original writable has ended
|
|
298
294
|
assert(isReady());
|
|
299
|
-
|
|
295
|
+
if (!isCancel)
|
|
296
|
+
flushBuffer();
|
|
300
297
|
streamClosed = true;
|
|
301
298
|
debug('stream ended');
|
|
302
299
|
}
|
|
@@ -526,7 +523,8 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
|
|
|
526
523
|
return;
|
|
527
524
|
await onEnd(isCancel);
|
|
528
525
|
isClosed = true;
|
|
529
|
-
|
|
526
|
+
if (!isCancel)
|
|
527
|
+
controllerProxy.close();
|
|
530
528
|
};
|
|
531
529
|
let controllerProxy;
|
|
532
530
|
assertReadableStreamConstructor();
|
|
@@ -546,6 +544,7 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
|
|
|
546
544
|
});
|
|
547
545
|
},
|
|
548
546
|
async cancel(...args) {
|
|
547
|
+
debug('stream cancelled');
|
|
549
548
|
isCancel = true;
|
|
550
549
|
await readableOriginal.cancel(...args);
|
|
551
550
|
// If readableOriginal has implemented readableOriginal.cancel() then the onEnd() callback and therefore closeStream() may already have been called at this point
|
|
@@ -553,9 +552,9 @@ async function createStreamWrapper({ streamOriginal, onError, onData, onEnd, onF
|
|
|
553
552
|
},
|
|
554
553
|
});
|
|
555
554
|
const writeChunk = (chunk) => {
|
|
556
|
-
if (
|
|
557
|
-
|
|
558
|
-
|
|
555
|
+
if (!isCancel &&
|
|
556
|
+
// If readableOriginal doesn't implement readableOriginal.cancel() then it may still emit data after we close the stream. We therefore need to check whether the steam is closed.
|
|
557
|
+
!isClosed) {
|
|
559
558
|
controllerProxy.enqueue(encodeForWebStream(chunk));
|
|
560
559
|
debugWithChunk('data written (Web Readable)', chunk);
|
|
561
560
|
}
|
package/dist/server/utils.d.ts
CHANGED
|
@@ -42,8 +42,8 @@ export * from '../utils/assertSetup.js';
|
|
|
42
42
|
export * from '../utils/path.js';
|
|
43
43
|
export * from '../utils/isHtml.js';
|
|
44
44
|
export * from '../utils/virtualFileId.js';
|
|
45
|
-
export * from '../utils/
|
|
46
|
-
export * from '../utils/
|
|
45
|
+
export * from '../utils/colorsServer.js';
|
|
46
|
+
export * from '../utils/colorsClient.js';
|
|
47
47
|
export * from '../utils/getTerminalWidth.js';
|
|
48
48
|
export * from '../utils/truncateString.js';
|
|
49
49
|
export * from '../utils/formatHintLog.js';
|
package/dist/server/utils.js
CHANGED
|
@@ -46,8 +46,8 @@ export * from '../utils/assertSetup.js';
|
|
|
46
46
|
export * from '../utils/path.js';
|
|
47
47
|
export * from '../utils/isHtml.js';
|
|
48
48
|
export * from '../utils/virtualFileId.js';
|
|
49
|
-
export * from '../utils/
|
|
50
|
-
export * from '../utils/
|
|
49
|
+
export * from '../utils/colorsServer.js';
|
|
50
|
+
export * from '../utils/colorsClient.js';
|
|
51
51
|
export * from '../utils/getTerminalWidth.js';
|
|
52
52
|
export * from '../utils/truncateString.js';
|
|
53
53
|
export * from '../utils/formatHintLog.js';
|
package/dist/types/Config.d.ts
CHANGED
|
@@ -339,7 +339,7 @@ type ConfigBuiltIn = {
|
|
|
339
339
|
*
|
|
340
340
|
* https://vike.dev/extends
|
|
341
341
|
*/
|
|
342
|
-
extends?: Config |
|
|
342
|
+
extends?: Config | Config[] | ImportString;
|
|
343
343
|
/** Hook called before the page is rendered.
|
|
344
344
|
*
|
|
345
345
|
* https://vike.dev/onBeforeRender
|
|
@@ -596,4 +596,5 @@ type ConfigBuiltInResolved = {
|
|
|
596
596
|
headersResponse?: Exclude<Config['headersResponse'], ImportString | undefined>[];
|
|
597
597
|
};
|
|
598
598
|
type ConfigMeta = Record<string, ConfigDefinition>;
|
|
599
|
-
type ImportString =
|
|
599
|
+
type ImportString = ImportStringVal | ImportStringVal[];
|
|
600
|
+
type ImportStringVal = `import:${string}`;
|