vike 0.4.259-commit-aa6fa94 → 0.4.259-commit-f6ecfb2
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/node/vite/shared/resolveVikeConfigInternal/crawlPlusFilePaths.js +1 -0
- package/dist/node/vite/shared/resolveVikeConfigInternal/getPlusFilesByLocationId.d.ts +3 -1
- package/dist/node/vite/shared/resolveVikeConfigInternal/getPlusFilesByLocationId.js +2 -0
- package/dist/node/vite/shared/resolveVikeConfigInternal/metaBuiltIn.js +5 -0
- package/dist/node/vite/shared/resolveVikeConfigInternal.js +102 -28
- package/dist/types/Config.d.ts +15 -2
- package/dist/utils/PROJECT_VERSION.d.ts +1 -1
- package/dist/utils/PROJECT_VERSION.js +1 -1
- package/package.json +1 -1
|
@@ -28,6 +28,7 @@ assertIsNotProductionRuntime();
|
|
|
28
28
|
const globalObject = getGlobalObject('getVikeConfig/crawlPlusFilePaths.ts', {
|
|
29
29
|
gitIsNotUsable: false,
|
|
30
30
|
});
|
|
31
|
+
// TODO/after-PR-merge rename crawlPlusFilePaths crawlPlusFiles
|
|
31
32
|
async function crawlPlusFilePaths(userRootDir) {
|
|
32
33
|
assertPosixPath(userRootDir);
|
|
33
34
|
assertFilePathAbsoluteFilesystem(userRootDir);
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export { getPlusFilesByLocationId };
|
|
2
|
+
export { getPlusFileFromConfigFile };
|
|
2
3
|
export type { PlusFileValue };
|
|
3
4
|
export type { PlusFile };
|
|
4
5
|
export type { PlusFilesByLocationId };
|
|
5
6
|
import { type LocationId } from './filesystemRouting.js';
|
|
6
7
|
import { type EsbuildCache } from './transpileAndExecuteFile.js';
|
|
7
|
-
import { PointerImportLoaded } from './loadFileAtConfigTime.js';
|
|
8
|
+
import { type ConfigFile, PointerImportLoaded } from './loadFileAtConfigTime.js';
|
|
8
9
|
import type { FilePathResolved } from '../../../../types/FilePath.js';
|
|
9
10
|
import '../../assertEnvVite.js';
|
|
10
11
|
type PlusFile = PlusFileConfig | PlusFileValue;
|
|
@@ -40,3 +41,4 @@ type PlusFileValue = PlusFileCommon & {
|
|
|
40
41
|
};
|
|
41
42
|
type PlusFilesByLocationId = Record<LocationId, PlusFile[]>;
|
|
42
43
|
declare function getPlusFilesByLocationId(userRootDir: string, esbuildCache: EsbuildCache): Promise<PlusFilesByLocationId>;
|
|
44
|
+
declare function getPlusFileFromConfigFile(configFile: ConfigFile, isExtensionConfig: boolean, locationId: LocationId, userRootDir: string): PlusFileConfig;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { getPlusFilesByLocationId };
|
|
2
|
+
export { getPlusFileFromConfigFile };
|
|
2
3
|
import { assert } from '../../../../utils/assert.js';
|
|
3
4
|
import { metaBuiltIn } from './metaBuiltIn.js';
|
|
4
5
|
import { getLocationId } from './filesystemRouting.js';
|
|
@@ -9,6 +10,7 @@ import { resolvePointerImport } from './resolvePointerImport.js';
|
|
|
9
10
|
import { getFilePathResolved } from '../getFilePath.js';
|
|
10
11
|
import { assertExtensionsConventions, assertExtensionsRequire } from './assertExtensions.js';
|
|
11
12
|
import '../../assertEnvVite.js';
|
|
13
|
+
// TODO/after-PR-merge rename getPlusFilesByLocationId getPlusFiles
|
|
12
14
|
async function getPlusFilesByLocationId(userRootDir, esbuildCache) {
|
|
13
15
|
const plusFilePaths = (await crawlPlusFilePaths(userRootDir)).map(({ filePathAbsoluteUserRootDir }) => getFilePathResolved({ filePathAbsoluteUserRootDir, userRootDir }));
|
|
14
16
|
const plusFilesByLocationId = {};
|
|
@@ -40,11 +40,13 @@ import pc from '@brillout/picocolors';
|
|
|
40
40
|
import { getConfigDefinedAt, getDefinedByString, } from '../../../shared-server-client/page-configs/getConfigDefinedAt.js';
|
|
41
41
|
import { loadPointerImport, loadValueFile } from './resolveVikeConfigInternal/loadFileAtConfigTime.js';
|
|
42
42
|
import { resolvePointerImport } from './resolveVikeConfigInternal/resolvePointerImport.js';
|
|
43
|
+
import { parsePointerImportData } from './resolveVikeConfigInternal/pointerImports.js';
|
|
43
44
|
import { getFilePathResolved } from './getFilePath.js';
|
|
44
45
|
import { getConfigValueBuildTime } from '../../../shared-server-client/page-configs/getConfigValueBuildTime.js';
|
|
45
46
|
import { resolveGlobalConfigPublic, } from '../../../shared-server-client/page-configs/resolveVikeConfigPublic.js';
|
|
46
47
|
import { getConfigValuesBase, isJsonValue, } from '../../../shared-server-client/page-configs/serialize/serializeConfigValues.js';
|
|
47
|
-
import { getPlusFilesByLocationId, } from './resolveVikeConfigInternal/getPlusFilesByLocationId.js';
|
|
48
|
+
import { getPlusFilesByLocationId, getPlusFileFromConfigFile, } from './resolveVikeConfigInternal/getPlusFilesByLocationId.js';
|
|
49
|
+
import { assertRouteString } from '../../../shared-server-client/route/resolveRouteString.js';
|
|
48
50
|
import { getExtensionName } from './resolveVikeConfigInternal/assertExtensions.js';
|
|
49
51
|
import { getEnvVarObject } from './getEnvVarObject.js';
|
|
50
52
|
import { getVikeApiOperation } from '../../../shared-server-node/api-context.js';
|
|
@@ -322,35 +324,94 @@ function getPageConfigsBuildTime(configDefinitionsResolved, plusFilesByLocationI
|
|
|
322
324
|
assertPageConfigGlobal(pageConfigGlobal, plusFilesByLocationId);
|
|
323
325
|
const pageConfigs = objectEntries(configDefinitionsResolved.configDefinitionsLocal)
|
|
324
326
|
.filter(([_locationId, { plusFiles }]) => isDefiningPage(plusFiles))
|
|
325
|
-
.map(([locationId, { configDefinitions, plusFilesRelevant }]) =>
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
objectEntries(configDefinitionsLocal)
|
|
329
|
-
.filter(([_configName, configDef]) => configDef.global !== true)
|
|
330
|
-
.forEach(([configName, configDef]) => {
|
|
331
|
-
const sources = resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, false, plusFilesByLocationId);
|
|
332
|
-
if (sources.length === 0)
|
|
333
|
-
return;
|
|
334
|
-
configValueSources[configName] = sources;
|
|
335
|
-
});
|
|
336
|
-
const pageConfigRoute = determineRouteFilesystem(locationId, configValueSources);
|
|
337
|
-
applyEffects(configValueSources, configDefinitionsLocal, plusFilesByLocationId);
|
|
338
|
-
sortConfigValueSources(configValueSources, locationId);
|
|
339
|
-
const pageConfig = {
|
|
340
|
-
pageId: locationId,
|
|
341
|
-
...pageConfigRoute,
|
|
342
|
-
configDefinitions: configDefinitionsLocal,
|
|
343
|
-
plusFiles: plusFilesRelevant,
|
|
344
|
-
configValueSources,
|
|
345
|
-
};
|
|
346
|
-
const configValuesComputed = getComputed(pageConfig);
|
|
347
|
-
objectAssign(pageConfig, { configValuesComputed });
|
|
348
|
-
checkType(pageConfig);
|
|
349
|
-
return pageConfig;
|
|
350
|
-
});
|
|
327
|
+
.map(([locationId, { configDefinitions, plusFilesRelevant }]) => resolvePageConfigBuildTime(locationId, locationId, plusFilesRelevant, configDefinitions, plusFilesByLocationId, userRootDir));
|
|
328
|
+
// Pages defined programmatically via +pages
|
|
329
|
+
pageConfigs.push(...getProgrammaticPageConfigs(configDefinitionsResolved, plusFilesByLocationId, userRootDir));
|
|
351
330
|
assertPageConfigs(pageConfigs);
|
|
352
331
|
return { pageConfigs, pageConfigGlobal };
|
|
353
332
|
}
|
|
333
|
+
function resolvePageConfigBuildTime(pageId, locationId, plusFilesRelevant, configDefinitionsLocal, plusFilesByLocationId, userRootDir) {
|
|
334
|
+
const configValueSources = {};
|
|
335
|
+
objectEntries(configDefinitionsLocal)
|
|
336
|
+
.filter(([_configName, configDef]) => configDef.global !== true)
|
|
337
|
+
.forEach(([configName, configDef]) => {
|
|
338
|
+
const sources = resolveConfigValueSources(configName, configDef, plusFilesRelevant, userRootDir, false, plusFilesByLocationId);
|
|
339
|
+
if (sources.length === 0)
|
|
340
|
+
return;
|
|
341
|
+
configValueSources[configName] = sources;
|
|
342
|
+
});
|
|
343
|
+
const pageConfigRoute = determineRouteFilesystem(locationId, configValueSources);
|
|
344
|
+
applyEffects(configValueSources, configDefinitionsLocal, plusFilesByLocationId);
|
|
345
|
+
sortConfigValueSources(configValueSources, locationId);
|
|
346
|
+
const pageConfig = {
|
|
347
|
+
pageId,
|
|
348
|
+
...pageConfigRoute,
|
|
349
|
+
configDefinitions: configDefinitionsLocal,
|
|
350
|
+
plusFiles: plusFilesRelevant,
|
|
351
|
+
configValueSources,
|
|
352
|
+
};
|
|
353
|
+
const configValuesComputed = getComputed(pageConfig);
|
|
354
|
+
objectAssign(pageConfig, { configValuesComputed });
|
|
355
|
+
checkType(pageConfig);
|
|
356
|
+
return pageConfig;
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Get the pages defined programmatically via +pages
|
|
360
|
+
*/
|
|
361
|
+
function getProgrammaticPageConfigs(configDefinitionsResolved, plusFilesByLocationId, userRootDir) {
|
|
362
|
+
const pageConfigs = [];
|
|
363
|
+
const entryIndexByLocationId = {};
|
|
364
|
+
// +pages can be set in a +config.js or +pages.js file — getConfVal() handles both
|
|
365
|
+
const plusFilesDefiningPages = Object.values(plusFilesByLocationId)
|
|
366
|
+
.flat()
|
|
367
|
+
.filter((plusFile) => {
|
|
368
|
+
const confVal = getConfVal(plusFile, 'pages');
|
|
369
|
+
return !!confVal && confVal.valueIsLoaded;
|
|
370
|
+
});
|
|
371
|
+
plusFilesDefiningPages.forEach((plusFileDefiningPages) => {
|
|
372
|
+
const locationIdAnchor = plusFileDefiningPages.locationId;
|
|
373
|
+
const local = configDefinitionsResolved.configDefinitionsLocal[locationIdAnchor];
|
|
374
|
+
assert(local);
|
|
375
|
+
const confVal = getConfVal(plusFileDefiningPages, 'pages');
|
|
376
|
+
assert(confVal?.valueIsLoaded);
|
|
377
|
+
const pages = confVal.value;
|
|
378
|
+
const definedAt = plusFileDefiningPages.filePath.filePathToShowToUser;
|
|
379
|
+
assertUsage(Array.isArray(pages), `${definedAt} sets ${pc.cyan('+pages')} to an invalid value: it should be an array`);
|
|
380
|
+
pages.forEach((entry, i) => {
|
|
381
|
+
const definedAtEntry = `${definedAt} > ${pc.cyan(`pages[${i}]`)}`;
|
|
382
|
+
assertUsage(isObject(entry), `${definedAtEntry} should be an object`);
|
|
383
|
+
assertUsage('route' in entry, `${definedAtEntry} should set ${pc.cyan('+route')}`);
|
|
384
|
+
// A Route Function can't be inlined (a function can't be serialized to the runtime): it must be a pointer import
|
|
385
|
+
assertUsage(!isCallable(entry.route), `${definedAtEntry} sets ${pc.cyan('+route')} to a function, but a Route Function can't be inlined — define the Route Function in a separate file and import it with ${pc.cyan("{ type: 'vike:pointer' }")} instead (so that Vike can load it at runtime)`);
|
|
386
|
+
assertUsage(typeof entry.route === 'string', `${definedAtEntry} should set ${pc.cyan('+route')} to a Route String or Route Function`);
|
|
387
|
+
// A Route String is validated now; a Route Function (pointer import) is validated at runtime.
|
|
388
|
+
if (!parsePointerImportData(entry.route))
|
|
389
|
+
assertRouteString(entry.route, `${definedAtEntry} sets an invalid`);
|
|
390
|
+
assertUsage(!('extends' in entry), `${definedAtEntry} sets ${pc.cyan('+extends')} which isn't supported for programmatically defined pages`);
|
|
391
|
+
const index = entryIndexByLocationId[locationIdAnchor] ?? 0;
|
|
392
|
+
entryIndexByLocationId[locationIdAnchor] = index + 1;
|
|
393
|
+
const base = locationIdAnchor === '/' ? '' : locationIdAnchor;
|
|
394
|
+
// The page's virtual locationId = its inheritance position (a child of the +config.js that defines +pages) so that:
|
|
395
|
+
// - The page's own values (`entry`) only apply to that page
|
|
396
|
+
// - The page inherits as usual
|
|
397
|
+
const locationIdVirtual = `${base}/(+pages)/entry:${index}`;
|
|
398
|
+
// Hack: treat `entry` as the page's own +config.js — getPlusFileFromConfigFile() makes pointer imports (e.g. +Page) resolve to runtime imports.
|
|
399
|
+
const plusFileVirtual = getPlusFileFromConfigFile({ fileExports: { default: entry }, filePath: plusFileDefiningPages.filePath, extendsFilePaths: [] }, false, locationIdVirtual, userRootDir);
|
|
400
|
+
getConfigNamesSetByPlusFile(plusFileVirtual).forEach((configName) => {
|
|
401
|
+
// Warn on unknown configs
|
|
402
|
+
isUnknownConfig(configName, local.configNamesKnownLocal, configDefinitionsResolved, locationIdAnchor, true, definedAtEntry);
|
|
403
|
+
// A global config (e.g. +onBeforeRoute) applies app-wide and can't be set on a single page. (We check `global === true` so conditionally-global configs such as +prerender, whose `global` is a function, are still allowed per-page.)
|
|
404
|
+
const configDefGlobal = configDefinitionsResolved.configDefinitionsGlobal[configName];
|
|
405
|
+
assertUsage(configDefGlobal?.global !== true, `${definedAtEntry} sets the global config ${pc.cyan(`+${configName}`)} which can't be set on a single page — set it at a global config file instead`);
|
|
406
|
+
});
|
|
407
|
+
// The page's own values (`entry`) first (most-specific), then the inherited configs
|
|
408
|
+
const plusFilesRelevant = [plusFileVirtual, ...local.plusFilesRelevant];
|
|
409
|
+
// Perf: resolvePageConfigBuildTime() re-resolves the inherited config per entry — fine for typical +pages array length. But for very large +pages arrays this might be too slow: consider resolving the inherited part once and re-use.
|
|
410
|
+
pageConfigs.push(resolvePageConfigBuildTime(locationIdVirtual, locationIdVirtual, plusFilesRelevant, local.configDefinitions, plusFilesByLocationId, userRootDir));
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
return pageConfigs;
|
|
414
|
+
}
|
|
354
415
|
function assertPageConfigGlobal(pageConfigGlobal, plusFilesByLocationId) {
|
|
355
416
|
Object.entries(pageConfigGlobal.configValueSources).forEach(([configName, sources]) => {
|
|
356
417
|
assertGlobalConfigLocation(configName, sources, plusFilesByLocationId, pageConfigGlobal.configDefinitions);
|
|
@@ -397,10 +458,18 @@ function assertGlobalConfigLocation(configName, sources, plusFilesByLocationId,
|
|
|
397
458
|
});
|
|
398
459
|
}
|
|
399
460
|
function assertPageConfigs(pageConfigs) {
|
|
461
|
+
assertNoDuplicatePageIds(pageConfigs);
|
|
400
462
|
pageConfigs.forEach((pageConfig) => {
|
|
401
463
|
assertOnBeforeRenderEnv(pageConfig);
|
|
402
464
|
});
|
|
403
465
|
}
|
|
466
|
+
function assertNoDuplicatePageIds(pageConfigs) {
|
|
467
|
+
const seen = new Set();
|
|
468
|
+
pageConfigs.forEach(({ pageId }) => {
|
|
469
|
+
assert(!seen.has(pageId));
|
|
470
|
+
seen.add(pageId);
|
|
471
|
+
});
|
|
472
|
+
}
|
|
404
473
|
function assertOnBeforeRenderEnv(pageConfig) {
|
|
405
474
|
const onBeforeRenderConfig = pageConfig.configValueSources.onBeforeRender?.[0];
|
|
406
475
|
if (!onBeforeRenderConfig)
|
|
@@ -812,6 +881,9 @@ function isDefiningPage(plusFiles) {
|
|
|
812
881
|
function isDefiningPageConfig(configName) {
|
|
813
882
|
return ['Page', 'route'].includes(configName);
|
|
814
883
|
}
|
|
884
|
+
function isDefiningProgrammaticPages(plusFiles) {
|
|
885
|
+
return plusFiles.some((plusFile) => getConfigNamesSetByPlusFile(plusFile).includes('pages'));
|
|
886
|
+
}
|
|
815
887
|
function resolveIsGlobalValue(configDefGlobal, source, plusFilesByLocationId) {
|
|
816
888
|
assert(source.valueIsLoaded);
|
|
817
889
|
let isGlobal;
|
|
@@ -1218,7 +1290,9 @@ function resolveConfigEnv(configEnv, filePath) {
|
|
|
1218
1290
|
/** Whether configs defined in `locationId` apply to every page */
|
|
1219
1291
|
function isGlobalLocation(locationId, plusFilesByLocationId) {
|
|
1220
1292
|
const locationIdsPage = objectEntries(plusFilesByLocationId)
|
|
1221
|
-
.filter(([_locationId, plusFiles]) => isDefiningPage(plusFiles)
|
|
1293
|
+
.filter(([_locationId, plusFiles]) => isDefiningPage(plusFiles) ||
|
|
1294
|
+
// Also add locationId if it defines +pages — programmatic pages are anchored there, so a config that doesn't cover them isn't global.
|
|
1295
|
+
isDefiningProgrammaticPages(plusFiles))
|
|
1222
1296
|
.map(([locationId]) => locationId);
|
|
1223
1297
|
return locationIdsPage.every((locId) => isInherited(locationId, locId));
|
|
1224
1298
|
}
|
package/dist/types/Config.d.ts
CHANGED
|
@@ -56,8 +56,8 @@ type HookName = HookNamePage | HookNameGlobal;
|
|
|
56
56
|
type HookNamePage = 'onHydrationEnd' | 'onBeforePrerenderStart' | 'onBeforeRender' | 'onPageTransitionStart' | 'onPageTransitionEnd' | 'onRenderHtml' | 'onRenderClient' | 'guard' | 'data' | 'onData' | 'route';
|
|
57
57
|
type HookNameGlobal = 'onBeforeRoute' | 'onPrerenderStart' | 'onCreatePageContext' | 'onCreateGlobalContext' | 'onError' | 'onHookCall';
|
|
58
58
|
type HookNameOldDesign = 'render' | 'prerender' | 'onBeforePrerender';
|
|
59
|
-
type ConfigNameBuiltIn = Exclude<keyof ConfigBuiltIn, keyof VikeVitePluginOptions | 'onBeforeRoute' | 'onPrerenderStart' | 'vite' | 'redirects'> | 'prerender' | 'hasServerOnlyHook' | 'isClientRuntimeLoaded' | 'onBeforeRenderEnv' | 'dataEnv' | 'guardEnv' | 'hooksTimeout' | 'clientHooks' | 'middleware' | 'server' | 'vercel';
|
|
60
|
-
type ConfigNameBuiltInGlobal = 'onPrerenderStart' | 'onBeforeRoute' | 'prerender' | 'disableAutoFullBuild' | 'includeAssetsImportedByServer' | 'baseAssets' | 'baseServer' | 'redirects' | 'trailingSlash' | 'disableUrlNormalization' | 'vite';
|
|
59
|
+
type ConfigNameBuiltIn = Exclude<keyof ConfigBuiltIn, keyof VikeVitePluginOptions | 'onBeforeRoute' | 'onPrerenderStart' | 'vite' | 'redirects' | 'pages'> | 'prerender' | 'hasServerOnlyHook' | 'isClientRuntimeLoaded' | 'onBeforeRenderEnv' | 'dataEnv' | 'guardEnv' | 'hooksTimeout' | 'clientHooks' | 'middleware' | 'server' | 'vercel';
|
|
60
|
+
type ConfigNameBuiltInGlobal = 'onPrerenderStart' | 'onBeforeRoute' | 'pages' | 'prerender' | 'disableAutoFullBuild' | 'includeAssetsImportedByServer' | 'baseAssets' | 'baseServer' | 'redirects' | 'trailingSlash' | 'disableUrlNormalization' | 'vite';
|
|
61
61
|
type Config = ConfigBuiltIn & Vike.Config;
|
|
62
62
|
/** @deprecated This type is deprecated, see:
|
|
63
63
|
* - https://vike.dev/migration/hook-types
|
|
@@ -255,6 +255,12 @@ type ConfigBuiltIn = {
|
|
|
255
255
|
* https://vike.dev/route
|
|
256
256
|
*/
|
|
257
257
|
route?: Route | ImportStringList;
|
|
258
|
+
/**
|
|
259
|
+
* @experimental
|
|
260
|
+
*
|
|
261
|
+
* Programmatically define pages.
|
|
262
|
+
*/
|
|
263
|
+
pages?: ConfigPageEntry[];
|
|
258
264
|
/** Protect page(s), e.g. forbid unauthorized access.
|
|
259
265
|
*
|
|
260
266
|
* https://vike.dev/guard
|
|
@@ -675,3 +681,10 @@ type ConfigBuiltInResolved = {
|
|
|
675
681
|
staticReplace?: StaticReplace[][];
|
|
676
682
|
};
|
|
677
683
|
type ConfigMeta = Record<string, ConfigDefinition>;
|
|
684
|
+
type ConfigPageEntry = Omit<Config, 'pages' | 'extends' | 'route'> & {
|
|
685
|
+
/** The page's URL — a Route String or a Route Function.
|
|
686
|
+
*
|
|
687
|
+
* https://vike.dev/route
|
|
688
|
+
*/
|
|
689
|
+
route: Route;
|
|
690
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const PROJECT_VERSION: "0.4.259-commit-
|
|
1
|
+
export declare const PROJECT_VERSION: "0.4.259-commit-f6ecfb2";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Automatically updated by @brillout/release-me
|
|
2
|
-
export const PROJECT_VERSION = '0.4.259-commit-
|
|
2
|
+
export const PROJECT_VERSION = '0.4.259-commit-f6ecfb2';
|