vike 0.4.146-commit-701e2e5 → 0.4.147-commit-2fa53b2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/cjs/node/plugin/index.js +6 -4
  2. package/dist/cjs/node/plugin/plugins/devConfig/determineOptimizeDeps.js +3 -4
  3. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +76 -0
  4. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +61 -40
  5. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +104 -0
  6. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +62 -75
  7. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +43 -17
  8. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +12 -70
  9. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/isRuntimeEnvMatch.js +11 -8
  10. package/dist/cjs/node/plugin/shared/{getConfigValueSourcesRelevant.js → getConfigValueSourcesNotOverriden.js} +3 -3
  11. package/dist/cjs/node/plugin/utils.js +2 -0
  12. package/dist/cjs/node/prerender/runPrerender.js +75 -67
  13. package/dist/cjs/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
  14. package/dist/cjs/node/runtime/index-common.js +3 -1
  15. package/dist/cjs/node/runtime/renderPage/analyzePage.js +2 -2
  16. package/dist/cjs/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +12 -12
  17. package/dist/cjs/node/runtime/renderPage/createHttpResponseObject.js +3 -3
  18. package/dist/cjs/node/runtime/renderPage/executeOnRenderHtmlHook.js +1 -2
  19. package/dist/cjs/node/runtime/renderPage/getHttpResponseBody.js +1 -1
  20. package/dist/cjs/node/runtime/renderPage.js +8 -5
  21. package/dist/cjs/shared/getPageFiles/analyzePageClientSide/determineClientEntry.js +1 -0
  22. package/dist/cjs/shared/page-configs/loadConfigValues.js +12 -3
  23. package/dist/cjs/shared/page-configs/serialize/parseConfigValuesSerialized.js +19 -0
  24. package/dist/cjs/shared/page-configs/serialize/parsePageConfigs.js +3 -12
  25. package/dist/cjs/utils/assertKeys.js +28 -0
  26. package/dist/cjs/utils/joinEnglish.js +3 -3
  27. package/dist/cjs/utils/parseUrl.js +24 -16
  28. package/dist/cjs/utils/projectInfo.js +3 -2
  29. package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +25 -11
  30. package/dist/esm/client/client-routing-runtime/index.d.ts +1 -0
  31. package/dist/esm/client/client-routing-runtime/index.js +1 -0
  32. package/dist/esm/client/client-routing-runtime/onBrowserHistoryNavigation.js +2 -2
  33. package/dist/esm/client/shared/getPageContextSerializedInHtml.js +1 -1
  34. package/dist/esm/node/plugin/index.d.ts +1 -0
  35. package/dist/esm/node/plugin/index.js +1 -0
  36. package/dist/esm/node/plugin/plugins/devConfig/determineOptimizeDeps.js +3 -4
  37. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.d.ts +5 -0
  38. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +70 -0
  39. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +58 -37
  40. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.d.ts +5 -0
  41. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +98 -0
  42. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +63 -76
  43. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +43 -17
  44. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.d.ts +0 -3
  45. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +13 -68
  46. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/isRuntimeEnvMatch.js +11 -8
  47. package/dist/esm/node/plugin/shared/getConfigValueSourcesNotOverriden.d.ts +5 -0
  48. package/dist/esm/node/plugin/shared/{getConfigValueSourcesRelevant.js → getConfigValueSourcesNotOverriden.js} +2 -2
  49. package/dist/esm/node/plugin/utils.d.ts +2 -0
  50. package/dist/esm/node/plugin/utils.js +2 -0
  51. package/dist/esm/node/prerender/runPrerender.js +75 -67
  52. package/dist/esm/node/runtime/html/injectAssets/injectAssets__public.js +1 -1
  53. package/dist/esm/node/runtime/index-common.d.ts +1 -0
  54. package/dist/esm/node/runtime/index-common.js +1 -0
  55. package/dist/esm/node/runtime/renderPage/analyzePage.js +2 -2
  56. package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.d.ts +1 -1
  57. package/dist/esm/node/runtime/renderPage/createHttpResponseObject/assertNoInfiniteHttpRedirect.js +12 -12
  58. package/dist/esm/node/runtime/renderPage/createHttpResponseObject.d.ts +1 -1
  59. package/dist/esm/node/runtime/renderPage/createHttpResponseObject.js +3 -3
  60. package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.js +1 -2
  61. package/dist/esm/node/runtime/renderPage/getHttpResponseBody.js +1 -1
  62. package/dist/esm/node/runtime/renderPage.js +9 -6
  63. package/dist/esm/shared/getPageFiles/analyzePageClientSide/determineClientEntry.js +1 -0
  64. package/dist/esm/shared/page-configs/PageConfig.d.ts +14 -4
  65. package/dist/esm/shared/page-configs/loadConfigValues.js +12 -3
  66. package/dist/esm/shared/page-configs/serialize/parseConfigValuesSerialized.d.ts +4 -0
  67. package/dist/esm/shared/page-configs/serialize/parseConfigValuesSerialized.js +16 -0
  68. package/dist/esm/shared/page-configs/serialize/parsePageConfigs.js +4 -13
  69. package/dist/esm/utils/assertKeys.d.ts +4 -0
  70. package/dist/esm/utils/assertKeys.js +22 -0
  71. package/dist/esm/utils/joinEnglish.d.ts +1 -1
  72. package/dist/esm/utils/joinEnglish.js +3 -3
  73. package/dist/esm/utils/parseUrl.js +24 -16
  74. package/dist/esm/utils/projectInfo.d.ts +3 -1
  75. package/dist/esm/utils/projectInfo.js +2 -1
  76. package/package.json +3 -3
  77. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/helpers.js +0 -28
  78. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/helpers.d.ts +0 -5
  79. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/helpers.js +0 -25
  80. package/dist/esm/node/plugin/shared/getConfigValueSourcesRelevant.d.ts +0 -5
@@ -1,98 +1,119 @@
1
1
  export { configDefinitionsBuiltIn };
2
2
  export { configDefinitionsBuiltInGlobal };
3
- import { getConfigEnv, isConfigSet } from '../helpers.js';
3
+ import { assert } from '../../../../utils.js';
4
4
  const configDefinitionsBuiltIn = {
5
5
  onRenderHtml: {
6
- env: 'server-only'
6
+ env: { server: true }
7
7
  },
8
8
  onRenderClient: {
9
- env: 'client-only'
9
+ env: { client: true }
10
10
  },
11
11
  onHydrationEnd: {
12
- env: 'client-only'
12
+ env: { client: true }
13
13
  },
14
14
  onPageTransitionStart: {
15
- env: 'client-only'
15
+ env: { client: true }
16
16
  },
17
17
  onPageTransitionEnd: {
18
- env: 'client-only'
18
+ env: { client: true }
19
19
  },
20
20
  onBeforeRender: {
21
- env: 'server-only'
21
+ env: { server: true }
22
22
  },
23
23
  onBeforePrerenderStart: {
24
- env: 'server-only'
24
+ env: { server: true }
25
25
  },
26
26
  Page: {
27
- env: 'server-and-client'
27
+ env: { server: true, client: true }
28
28
  },
29
29
  passToClient: {
30
- env: 'server-only',
30
+ env: { server: true, config: true },
31
31
  cumulative: true
32
32
  },
33
33
  route: {
34
- env: '_routing-eager'
34
+ env: { server: true, client: 'if-client-routing', eager: true }
35
35
  },
36
36
  guard: {
37
- env: '_routing-lazy'
37
+ env: { server: true, client: 'if-client-routing' }
38
38
  },
39
39
  iKnowThePerformanceRisksOfAsyncRouteFunctions: {
40
- env: '_routing-eager'
40
+ env: { server: true, client: 'if-client-routing', eager: true }
41
41
  },
42
42
  filesystemRoutingRoot: {
43
- env: 'config-only'
43
+ env: { config: true }
44
44
  },
45
45
  client: {
46
46
  // The value of the client config is merely the file path to the client entry file, which is only needed on the sever-side
47
- env: 'server-only',
47
+ env: { server: true },
48
48
  _valueIsFilePath: true
49
49
  },
50
50
  clientRouting: {
51
- // We could make it 'server-only' (we don't yet because of some legacy V0.4 design code)
52
- env: 'server-and-client'
51
+ // We could make it { client: false } but we don't yet because of some legacy V0.4 design code
52
+ env: { server: true, client: true, config: true, eager: true }
53
53
  },
54
54
  prerender: {
55
- env: 'config-only'
55
+ env: { config: true }
56
56
  },
57
57
  hydrationCanBeAborted: {
58
- env: 'client-only'
58
+ env: { client: true }
59
59
  },
60
60
  prefetchStaticAssets: {
61
- env: 'client-only'
61
+ env: { client: true }
62
62
  },
63
63
  extends: {
64
- env: 'config-only'
64
+ env: { config: true }
65
65
  },
66
66
  meta: {
67
- env: 'config-only'
67
+ env: { config: true }
68
68
  },
69
69
  isClientSideRenderable: {
70
- env: 'server-and-client',
70
+ env: { server: true, client: true, eager: true },
71
71
  _computed: (configValueSources) => isConfigSet(configValueSources, 'onRenderClient') &&
72
72
  isConfigSet(configValueSources, 'Page') &&
73
- getConfigEnv(configValueSources, 'Page') !== 'server-only'
73
+ !!getConfigEnv(configValueSources, 'Page')?.client
74
74
  },
75
75
  onBeforeRenderEnv: {
76
- env: 'client-only',
76
+ env: { client: true },
77
77
  _computed: (configValueSources) => !isConfigSet(configValueSources, 'onBeforeRender') ? null : getConfigEnv(configValueSources, 'onBeforeRender')
78
78
  }
79
79
  };
80
80
  const configDefinitionsBuiltInGlobal = {
81
81
  onPrerenderStart: {
82
- env: 'server-only'
82
+ env: { server: true }
83
83
  },
84
84
  onBeforeRoute: {
85
- env: '_routing-eager'
85
+ env: { server: true, client: 'if-client-routing', eager: true }
86
86
  },
87
87
  prerender: {
88
- env: 'config-only'
89
- },
90
- extensions: { env: 'config-only' },
91
- disableAutoFullBuild: { env: 'config-only' },
92
- includeAssetsImportedByServer: { env: 'config-only' },
93
- baseAssets: { env: 'config-only' },
94
- baseServer: { env: 'config-only' },
95
- redirects: { env: 'server-only' },
96
- trailingSlash: { env: 'server-only' },
97
- disableUrlNormalization: { env: 'server-only' }
88
+ env: { config: true }
89
+ },
90
+ extensions: { env: { config: true } },
91
+ disableAutoFullBuild: { env: { config: true } },
92
+ includeAssetsImportedByServer: { env: { config: true } },
93
+ baseAssets: { env: { config: true } },
94
+ baseServer: { env: { config: true } },
95
+ redirects: { env: { server: true } },
96
+ trailingSlash: { env: { server: true } },
97
+ disableUrlNormalization: { env: { server: true } }
98
98
  };
99
+ function getConfigEnv(configValueSources, configName) {
100
+ const configValueSource = getConfigValueSource(configValueSources, configName);
101
+ if (!configValueSource)
102
+ return null;
103
+ return configValueSource.configEnv;
104
+ }
105
+ function isConfigSet(configValueSources, configName) {
106
+ const configValueSource = getConfigValueSource(configValueSources, configName);
107
+ // Enable users to suppress global config values by overriding the config's value to null
108
+ if (configValueSource?.value === null)
109
+ return false;
110
+ return !!configValueSource;
111
+ }
112
+ function getConfigValueSource(configValueSources, configName) {
113
+ const sources = configValueSources[configName];
114
+ if (!sources)
115
+ return null;
116
+ const configValueSource = sources[0];
117
+ assert(configValueSource);
118
+ return configValueSource;
119
+ }
@@ -0,0 +1,5 @@
1
+ export { crawlPlusFiles };
2
+ declare function crawlPlusFiles(userRootDir: string, outDirAbsoluteFilesystem: string, isDev: boolean): Promise<{
3
+ filePathRelativeToUserRootDir: string;
4
+ filePathAbsoluteFilesystem: string;
5
+ }[]>;
@@ -0,0 +1,98 @@
1
+ export { crawlPlusFiles };
2
+ import { assertPosixPath, assert, toPosixPath, assertWarning, scriptFileExtensionList, scriptFileExtensions } from '../../../../utils.js';
3
+ import path from 'path';
4
+ import glob from 'fast-glob';
5
+ import { exec } from 'child_process';
6
+ import { promisify } from 'util';
7
+ const execA = promisify(exec);
8
+ async function crawlPlusFiles(userRootDir, outDirAbsoluteFilesystem, isDev) {
9
+ assertPosixPath(userRootDir);
10
+ assertPosixPath(outDirAbsoluteFilesystem);
11
+ assert(outDirAbsoluteFilesystem.startsWith(userRootDir));
12
+ const outDir = path.posix.relative(userRootDir, outDirAbsoluteFilesystem);
13
+ assert(!outDir.startsWith('.'));
14
+ const timeBase = new Date().getTime();
15
+ let files = [];
16
+ const res = await gitLsFiles(userRootDir, outDir);
17
+ if (res &&
18
+ // Fallback to fast-glob for users that dynamically generate plus files (we assume generetad plus files to be skipped because they are usually included in .gitignore)
19
+ res.length > 0) {
20
+ files = res;
21
+ }
22
+ else {
23
+ files = await fastGlob(userRootDir, outDir);
24
+ }
25
+ {
26
+ const time = new Date().getTime() - timeBase;
27
+ if (isDev) {
28
+ // We only warn in dev, because while building it's expected to take a long time as fast-glob is competing for resources with other tasks
29
+ assertWarning(time < 2 * 1000, `Crawling your user files took an unexpected long time (${time}ms). Create a new issue on Vike's GitHub.`, {
30
+ onlyOnce: 'slow-page-files-search'
31
+ });
32
+ }
33
+ }
34
+ const plusFiles = files.map((p) => {
35
+ p = toPosixPath(p);
36
+ assert(!p.startsWith(userRootDir));
37
+ const filePathRelativeToUserRootDir = path.posix.join('/', p);
38
+ const filePathAbsoluteFilesystem = path.posix.join(userRootDir, p);
39
+ return {
40
+ filePathRelativeToUserRootDir,
41
+ filePathAbsoluteFilesystem
42
+ };
43
+ });
44
+ return plusFiles;
45
+ }
46
+ // Same as fastGlob() but using `$ git ls-files`
47
+ async function gitLsFiles(userRootDir, outDir) {
48
+ const cmd = [
49
+ 'git ls-files',
50
+ ...scriptFileExtensionList.map((ext) => `"**/+*.${ext}"`),
51
+ ...getIgnorePatterns(outDir).map((pattern) => `--exclude="${pattern}"`),
52
+ // --others lists untracked files only (but using .gitignore because --exclude-standard)
53
+ // --cached adds the tracked files to the output
54
+ '--others --cached --exclude-standard'
55
+ ].join(' ');
56
+ let stdout;
57
+ try {
58
+ const res = await execA(cmd, { cwd: userRootDir });
59
+ stdout = res.stdout;
60
+ }
61
+ catch (err) {
62
+ if (err.message.includes('not a git repository'))
63
+ return null;
64
+ throw err;
65
+ }
66
+ let files = stdout.split('\n').filter(Boolean);
67
+ assert(!outDir.startsWith('/'));
68
+ files = files.filter(
69
+ // We have to repeat the same exclusion logic here because the `git ls-files` option --exclude only applies to untracked files. (We use --exclude only to speed up the command.)
70
+ (file) => getIgnoreFilter(file, outDir));
71
+ return files;
72
+ }
73
+ // Same as gitLsFiles() but using fast-glob
74
+ async function fastGlob(userRootDir, outDir) {
75
+ const files = await glob(`**/+*.${scriptFileExtensions}`, {
76
+ ignore: getIgnorePatterns(outDir),
77
+ cwd: userRootDir,
78
+ dot: false
79
+ });
80
+ return files;
81
+ }
82
+ // Same as getIgnoreFilter() but as glob pattern
83
+ function getIgnorePatterns(outDir) {
84
+ return [
85
+ '**/node_modules/**',
86
+ `${outDir}/**`,
87
+ // Allow:
88
+ // ```
89
+ // +Page.js
90
+ // +Page.telefunc.js
91
+ // ```
92
+ '**/*.telefunc.*'
93
+ ];
94
+ }
95
+ // Same as getIgnorePatterns() but for Array.filter()
96
+ function getIgnoreFilter(file, outDir) {
97
+ return !file.includes('node_modules/') && !file.includes('.telefunc.') && !file.startsWith(`${outDir}/`);
98
+ }
@@ -2,10 +2,9 @@ export { getVikeConfig };
2
2
  export { reloadVikeConfig };
3
3
  export { vikeConfigDependencies };
4
4
  export { isVikeConfigFile };
5
- import { assertPosixPath, assert, isObject, assertUsage, toPosixPath, assertWarning, objectEntries, hasProp, arrayIncludes, assertIsNotProductionRuntime, getMostSimilar, isNpmPackageImport, joinEnglish, lowerFirst, scriptFileExtensions, mergeCumulativeValues, requireResolve, getOutDirs } from '../../../utils.js';
5
+ import { assertPosixPath, assert, isObject, assertUsage, assertWarning, objectEntries, hasProp, arrayIncludes, assertIsNotProductionRuntime, getMostSimilar, isNpmPackageImport, joinEnglish, lowerFirst, mergeCumulativeValues, requireResolve, getOutDirs, deepEqual, assertKeys } from '../../../utils.js';
6
6
  import path from 'path';
7
7
  import { configDefinitionsBuiltIn, configDefinitionsBuiltInGlobal } from './getVikeConfig/configDefinitionsBuiltIn.js';
8
- import glob from 'fast-glob';
9
8
  import { getLocationId, getFilesystemRouteString, getFilesystemRouteDefinedBy, isInherited, sortAfterInheritanceOrder, isGlobalLocation, applyFilesystemRoutingRootEffect } from './getVikeConfig/filesystemRouting.js';
10
9
  import { isTmpFile, transpileAndExecuteFile } from './transpileAndExecuteFile.js';
11
10
  import { parseImportData } from './replaceImportStatements.js';
@@ -16,8 +15,9 @@ import { removeSuperfluousViteLog_enable, removeSuperfluousViteLog_disable } fro
16
15
  import pc from '@brillout/picocolors';
17
16
  import { getConfigDefinedAtString } from '../../../../../shared/page-configs/helpers.js';
18
17
  import { assertExportsOfConfigFile, assertExportsOfValueFile } from '../../../../../shared/page-configs/assertExports.js';
19
- import { getConfigValueSerialized } from './getVirtualFilePageConfigs.js';
20
18
  import { getConfigVike } from '../../../../shared/getConfigVike.js';
19
+ import { assertConfigValueIsSerializable } from './getConfigValuesSerialized.js';
20
+ import { crawlPlusFiles } from './getVikeConfig/crawlPlusFiles.js';
21
21
  assertIsNotProductionRuntime();
22
22
  let devServerIsCorrupt = false;
23
23
  let wasConfigInvalid = null;
@@ -70,7 +70,7 @@ async function getVikeConfig(config, isDev, tolerateInvalidConfig = false, exten
70
70
  return await vikeConfigPromise;
71
71
  }
72
72
  async function loadInterfaceFiles(userRootDir, outDirRoot, isDev, extensions) {
73
- const plusFiles = await findPlusFiles(userRootDir, [outDirRoot], isDev, extensions);
73
+ const plusFiles = await findPlusFiles(userRootDir, outDirRoot, isDev, extensions);
74
74
  const configFiles = [];
75
75
  const valueFiles = [];
76
76
  plusFiles.forEach((f) => {
@@ -151,12 +151,12 @@ async function loadImportedFile(filePath, userRootDir, importedFilesLoaded) {
151
151
  return fileExports;
152
152
  }
153
153
  function isConfigEnv(configDef, configName) {
154
- if (configDef.cumulative)
155
- return true;
156
- if (configDef.env === 'config-only')
157
- return true;
158
- // TODO: replace with proper `env: { config: boolean }` implementation
159
- return configName === 'clientRouting';
154
+ const configEnv = configDef.env;
155
+ if (configDef.cumulative) {
156
+ // In principle we could lift that requirement (but it requires non-trivial modifications)
157
+ assertUsage(configEnv.config, `Config ${pc.cyan(configName)} needs its ${pc.cyan('env')} to have ${pc.cyan('{ config: true }')} (because ${pc.cyan(configName)} is a ${pc.cyan('cumulative')} config)`);
158
+ }
159
+ return !!configEnv.config;
160
160
  }
161
161
  function getInterfaceFileFromConfigFile(configFile, isConfigExtend) {
162
162
  const { fileExports, filePath, extendsFilePaths } = configFile;
@@ -509,6 +509,7 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
509
509
  }
510
510
  else if (interfaceFile.isValueFile) {
511
511
  const valueAlreadyLoaded = 'configValue' in conf;
512
+ assert(valueAlreadyLoaded === !!configEnv.config);
512
513
  const configValueSource = {
513
514
  configEnv,
514
515
  valueIsImportedAtRuntime: !valueAlreadyLoaded,
@@ -523,9 +524,6 @@ async function getConfigValueSource(configName, interfaceFile, configDef, userRo
523
524
  if (valueAlreadyLoaded) {
524
525
  configValueSource.value = conf.configValue;
525
526
  }
526
- else {
527
- assert(configEnv !== 'config-only');
528
- }
529
527
  return configValueSource;
530
528
  }
531
529
  assert(false);
@@ -537,12 +535,12 @@ function assertFileEnv(filePathForEnvCheck, configEnv, configName) {
537
535
  }
538
536
  const fileEnv = filesEnv.get(filePathForEnvCheck);
539
537
  fileEnv.push({ configEnv, configName });
540
- const configDifferentEnv = fileEnv.filter((c) => c.configEnv !== configEnv)[0];
538
+ const configDifferentEnv = fileEnv.filter((c) => !deepEqual(c.configEnv, configEnv))[0];
541
539
  if (configDifferentEnv) {
542
540
  assertUsage(false, [
543
541
  `${filePathForEnvCheck} defines the value of configs living in different environments:`,
544
- ...[configDifferentEnv, { configName, configEnv }].map((c) => ` - config ${pc.cyan(c.configName)} which value lives in environment ${pc.cyan(c.configEnv)}`),
545
- 'Defining config values in the same file is allowed only if they live in the same environment, see https://vike.dev/header-file/import-from-same-file'
542
+ ...[configDifferentEnv, { configName, configEnv }].map((c) => ` - config ${pc.cyan(c.configName)} which value lives in environment ${pc.cyan(JSON.stringify(c.configEnv))}`),
543
+ 'Defining config values in the same file is allowed only if they live in the same environment, see https://vike.dev/header-file'
546
544
  ].join('\n'));
547
545
  }
548
546
  }
@@ -678,30 +676,17 @@ function assertMetaValue(metaVal, configMetaDefinedAt) {
678
676
  assertUsage(false, `${configMetaDefinedAt} sets ${pc.cyan(`meta.${configName}`)} to a value with an invalid type ${pc.cyan(typeof def)}: it should be an object instead.`);
679
677
  }
680
678
  // env
679
+ let configEnv;
681
680
  {
682
- const envValues = [
683
- 'client-only',
684
- 'server-only',
685
- 'server-and-client',
686
- 'config-only'
687
- ];
688
- const fix = [
689
- `Set the value of ${pc.cyan(`meta.${configName}.env`)} to `,
690
- joinEnglish(envValues.map((s) => pc.cyan(`'${s}'`)), 'or'),
691
- '.'
692
- ].join('');
681
+ assert(configMetaDefinedAt); // We expect internal effects to return a valid meta value
693
682
  if (!('env' in def)) {
694
- assert(configMetaDefinedAt); // We expect internal effects to return a valid meta value
695
- assertUsage(false, `${configMetaDefinedAt} doesn't set ${pc.cyan(`meta.${configName}.env`)} but it's required. ${fix}`);
696
- }
697
- if (!hasProp(def, 'env', 'string')) {
698
- assert(configMetaDefinedAt); // We expect internal effects to return a valid meta value
699
- assertUsage(false, `${configMetaDefinedAt} sets ${pc.cyan(`meta.${configName}.env`)} to an invalid type ${pc.cyan(typeof def.env)}. ${fix}`);
700
- }
701
- if (!envValues.includes(def.env)) {
702
- assert(configMetaDefinedAt); // We expect internal effects to return a valid meta value
703
- assertUsage(false, `${configMetaDefinedAt} sets ${pc.cyan(`meta.${configName}.env`)} to an unknown value ${pc.cyan(`'${def.env}'`)}. ${fix}`);
683
+ assertUsage(false, `${configMetaDefinedAt} doesn't set ${pc.cyan(`meta.${configName}.env`)} but it's required.`);
704
684
  }
685
+ configEnv = getConfigEnvValue(def.env, `${configMetaDefinedAt} sets ${pc.cyan(`meta.${configName}.env`)} to`);
686
+ // Overwrite deprecated value with valid value
687
+ // TODO/v1-release: remove once support for the deprecated values is removed
688
+ if (typeof def.env === 'string')
689
+ def.env = configEnv;
705
690
  }
706
691
  // effect
707
692
  if ('effect' in def) {
@@ -709,9 +694,9 @@ function assertMetaValue(metaVal, configMetaDefinedAt) {
709
694
  assert(configMetaDefinedAt); // We expect internal effects to return a valid meta value
710
695
  assertUsage(false, `${configMetaDefinedAt} sets ${pc.cyan(`meta.${configName}.effect`)} to an invalid type ${pc.cyan(typeof def.effect)}: it should be a function instead`);
711
696
  }
712
- if (def.env !== 'config-only') {
697
+ if (!configEnv.config) {
713
698
  assert(configMetaDefinedAt); // We expect internal effects to return a valid meta value
714
- assertUsage(false, `${configMetaDefinedAt} sets ${pc.cyan(`meta.${configName}.effect`)} but it's only supported if meta.${configName}.env is ${pc.cyan('config-only')} (but it's ${pc.cyan(def.env)} instead)`);
699
+ assertUsage(false, `${configMetaDefinedAt} sets ${pc.cyan(`meta.${configName}.effect`)} but it's only supported if meta.${configName}.env has ${pc.cyan('{ config: true }')} (but it's ${pc.cyan(JSON.stringify(configEnv))} instead)`);
715
700
  }
716
701
  }
717
702
  });
@@ -722,8 +707,8 @@ function applyEffectsAll(configValueSources, configDefinitionsRelevant) {
722
707
  return;
723
708
  // The value needs to be loaded at config time, that's why we only support effect for configs that are config-only for now.
724
709
  // (We could support effect for non config-only by always loading its value at config time, regardless of the config's `env` value.)
725
- assertUsage(configDef.env === 'config-only', [
726
- `Cannot add effect to ${pc.cyan(configName)} because its ${pc.cyan('env')} is ${pc.cyan(configDef.env)}: effects can only be added to configs with an ${pc.cyan('env')} value of ${pc.cyan('config-only')}.`
710
+ assertUsage(configDef.env.config, [
711
+ `Cannot add effect to ${pc.cyan(configName)} because its ${pc.cyan('env')} is ${pc.cyan(JSON.stringify(configDef.env))}: effects can only be added to configs with an ${pc.cyan('env')} with ${pc.cyan('{ config: true }')}.`
727
712
  ].join(' '));
728
713
  const source = configValueSources[configName]?.[0];
729
714
  if (!source)
@@ -791,39 +776,9 @@ function getComputed(configValueSources, configDefinitionsRelevant) {
791
776
  });
792
777
  return configValuesComputed;
793
778
  }
794
- async function findPlusFiles(userRootDir, ignoreDirs, isDev, extensions) {
795
- const timeBase = new Date().getTime();
796
- assertPosixPath(userRootDir);
797
- const ignorePatterns = [];
798
- for (const dir of ignoreDirs) {
799
- assertPosixPath(dir);
800
- ignorePatterns.push(`${path.posix.relative(userRootDir, dir)}/**`);
801
- }
802
- const result = await glob(`**/+*.${scriptFileExtensions}`, {
803
- ignore: [
804
- '**/node_modules/**',
805
- // Allow:
806
- // ```
807
- // +Page.js
808
- // +Page.telefunc.js
809
- // ```
810
- '**/*.telefunc.*',
811
- ...ignorePatterns
812
- ],
813
- cwd: userRootDir,
814
- dot: false
815
- });
816
- const time = new Date().getTime() - timeBase;
817
- if (isDev) {
818
- // We only warn in dev, because while building it's expected to take a long time as fast-glob is competing for resources with other tasks
819
- assertWarning(time < 2 * 1000, `Crawling your user files took an unexpected long time (${time}ms). Create a new issue on Vike's GitHub.`, {
820
- onlyOnce: 'slow-page-files-search'
821
- });
822
- }
823
- const plusFiles = result.map((p) => {
824
- p = toPosixPath(p);
825
- const filePathRelativeToUserRootDir = path.posix.join('/', p);
826
- const filePathAbsoluteFilesystem = path.posix.join(userRootDir, p);
779
+ async function findPlusFiles(userRootDir, outDirRoot, isDev, extensions) {
780
+ const files = await crawlPlusFiles(userRootDir, outDirRoot, isDev);
781
+ const plusFiles = files.map(({ filePathRelativeToUserRootDir, filePathAbsoluteFilesystem }) => {
827
782
  return {
828
783
  filePathRelativeToUserRootDir,
829
784
  filePathAbsoluteVite: filePathRelativeToUserRootDir,
@@ -1041,7 +996,7 @@ function determineRouteFilesystem(locationId, configValueSources) {
1041
996
  return { routeFilesystem, isErrorPage: undefined };
1042
997
  }
1043
998
  function getFilesystemRoutingRootEffect(configFilesystemRoutingRoot, configName) {
1044
- assert(configFilesystemRoutingRoot.configEnv === 'config-only');
999
+ assert(configFilesystemRoutingRoot.configEnv.config);
1045
1000
  // Eagerly loaded since it's config-only
1046
1001
  assert('value' in configFilesystemRoutingRoot);
1047
1002
  const { value } = configFilesystemRoutingRoot;
@@ -1137,7 +1092,7 @@ function mergeCumulative(configName, configValueSources) {
1137
1092
  // We could, in principle, also support cumulative for values that aren't loaded at config-time but it isn't completely trivial to implement.
1138
1093
  assert('value' in configValueSource);
1139
1094
  // Make sure configValueSource.value is serializable
1140
- getConfigValueSerialized(configValueSource.value, configName, getDefinedAt(configValueSource));
1095
+ assertConfigValueIsSerializable(configValueSource.value, configName, getDefinedAt(configValueSource));
1141
1096
  const assertNoMixing = (isSet) => {
1142
1097
  const vals1 = isSet ? valuesSet : valuesArr;
1143
1098
  const t1 = isSet ? 'a Set' : 'an array';
@@ -1178,3 +1133,35 @@ function mergeCumulative(configName, configValueSources) {
1178
1133
  }
1179
1134
  assert(false);
1180
1135
  }
1136
+ function getConfigEnvValue(val, errMsgIntro) {
1137
+ const errInvalidValue = `${errMsgIntro} an invalid value ${pc.cyan(JSON.stringify(val))}`;
1138
+ // Legacy outdated values
1139
+ if (typeof val === 'string') {
1140
+ const valConverted = (() => {
1141
+ if (val === 'client-only')
1142
+ return { client: true };
1143
+ if (val === 'server-only')
1144
+ return { server: true };
1145
+ if (val === 'server-and-client')
1146
+ return { server: true, client: true };
1147
+ if (val === 'config-only')
1148
+ return { config: true };
1149
+ if (val === '_routing-lazy')
1150
+ return { server: true, client: 'if-client-routing' };
1151
+ if (val === '_routing-eager')
1152
+ return { server: true, client: 'if-client-routing', eager: true };
1153
+ assertUsage(false, errInvalidValue);
1154
+ })();
1155
+ assertWarning(false, `${errMsgIntro} ${pc.cyan(val)} which is deprecated and will be removed in the next major release`, { onlyOnce: true });
1156
+ return valConverted;
1157
+ }
1158
+ assertUsage(isObject(val), `${errMsgIntro} an invalid type ${pc.cyan(typeof val)}`);
1159
+ assertKeys(val, ['config', 'server', 'client'], `${errInvalidValue}:`);
1160
+ assertUsage(hasProp(val, 'config', 'undefined') || hasProp(val, 'config', 'boolean'), errInvalidValue);
1161
+ assertUsage(hasProp(val, 'server', 'undefined') || hasProp(val, 'server', 'boolean'), errInvalidValue);
1162
+ assertUsage(hasProp(val, 'client', 'undefined') || hasProp(val, 'client', 'boolean'), errInvalidValue);
1163
+ /* Uncomment to allow users to set an eager config. Same for `{ client: 'if-client-routing' }`.
1164
+ assertUsage(hasProp(val, 'eager', 'undefined') || hasProp(val, 'eager', 'boolean'), errInvalidValue)
1165
+ */
1166
+ return val;
1167
+ }
@@ -5,10 +5,11 @@ import { getVikeConfig } from './getVikeConfig.js';
5
5
  import { extractAssetsAddQuery } from '../../../../shared/extractAssetsQuery.js';
6
6
  import { debug } from './debug.js';
7
7
  import { getConfigValue } from '../../../../../shared/page-configs/helpers.js';
8
- import { getConfigValueSourcesRelevant } from '../../../shared/getConfigValueSourcesRelevant.js';
8
+ import { getConfigValueSourcesNotOverriden } from '../../../shared/getConfigValueSourcesNotOverriden.js';
9
9
  import { isRuntimeEnvMatch } from './isRuntimeEnvMatch.js';
10
10
  import { serializeConfigValueImported } from '../../../../../shared/page-configs/serialize/serializeConfigValue.js';
11
11
  import { getConfigVike } from '../../../../shared/getConfigVike.js';
12
+ import { getConfigValuesSerialized } from './getConfigValuesSerialized.js';
12
13
  async function getVirtualFilePageConfigValuesAll(id, isDev, config) {
13
14
  const result = isVirtualFileIdPageConfigValuesAll(id);
14
15
  assert(result);
@@ -28,27 +29,52 @@ async function getVirtualFilePageConfigValuesAll(id, isDev, config) {
28
29
  return code;
29
30
  }
30
31
  function getLoadConfigValuesAll(pageConfig, isForClientSide, pageId, includeAssetsImportedByServer, isDev) {
31
- const configValue = getConfigValue(pageConfig, 'clientRouting', 'boolean');
32
- const isClientRouting = configValue?.value ?? false;
33
32
  const lines = [];
34
33
  const importStatements = [];
35
- lines.push('export default [');
36
- const varCounterContainer = { varCounter: 0 };
37
- getConfigValueSourcesRelevant(pageConfig).forEach((configValueSource) => {
38
- const { valueIsImportedAtRuntime, configEnv, configName } = configValueSource;
39
- if (!valueIsImportedAtRuntime)
40
- return;
41
- if (configValueSource.valueIsFilePath)
42
- return;
43
- if (!isRuntimeEnvMatch(configEnv, { isForClientSide, isClientRouting, isEager: false }))
44
- return;
45
- const whitespace = ' ';
46
- lines.push(...serializeConfigValueImported(configValueSource, configName, whitespace, varCounterContainer, importStatements));
47
- });
34
+ const isClientRouting = getConfigValue(pageConfig, 'clientRouting', 'boolean')?.value ?? false;
35
+ lines.push('export const configValuesImported = [');
36
+ lines.push(getConfigValuesImported(pageConfig, isForClientSide, isClientRouting, importStatements));
48
37
  lines.push('];');
38
+ lines.push('export const configValuesSerialized = {');
39
+ lines.push(getConfigValuesSerialized(pageConfig, (configEnv, configValueSource) => isEnvMatch(configEnv, !configValueSource ? false : checkWhetherIsImport(configValueSource), {
40
+ isImport: false,
41
+ isForClientSide,
42
+ isClientRouting
43
+ })));
44
+ lines.push('};');
49
45
  if (includeAssetsImportedByServer && isForClientSide && !isDev) {
50
- lines.push(`import '${extractAssetsAddQuery(getVirtualFileIdPageConfigValuesAll(pageId, false))}'`);
46
+ importStatements.push(`import '${extractAssetsAddQuery(getVirtualFileIdPageConfigValuesAll(pageId, false))}'`);
51
47
  }
52
48
  const code = [...importStatements, ...lines].join('\n');
53
49
  return code;
54
50
  }
51
+ function getConfigValuesImported(pageConfig, isForClientSide, isClientRouting, importStatements) {
52
+ const lines = [];
53
+ const varCounterContainer = { varCounter: 0 };
54
+ getConfigValueSourcesNotOverriden(pageConfig).forEach((configValueSource) => {
55
+ if (!isEnvMatch(configValueSource.configEnv, checkWhetherIsImport(configValueSource), {
56
+ isImport: true,
57
+ isForClientSide,
58
+ isClientRouting
59
+ }))
60
+ return;
61
+ const whitespace = ' ';
62
+ lines.push(...serializeConfigValueImported(configValueSource, configValueSource.configName, whitespace, varCounterContainer, importStatements));
63
+ });
64
+ const code = lines.join('\n');
65
+ return code;
66
+ }
67
+ function checkWhetherIsImport(configValueSource) {
68
+ const { valueIsImportedAtRuntime, valueIsFilePath } = configValueSource;
69
+ return valueIsImportedAtRuntime && !valueIsFilePath;
70
+ }
71
+ function isEnvMatch(configEnv, isImport, runtime) {
72
+ // Whether config value is imported or serialized
73
+ if (isImport !== runtime.isImport)
74
+ return false;
75
+ // Runtime match
76
+ const { isForClientSide, isClientRouting } = runtime;
77
+ if (!isRuntimeEnvMatch(configEnv, { isForClientSide, isClientRouting, isEager: false }))
78
+ return false;
79
+ return true;
80
+ }
@@ -1,6 +1,3 @@
1
1
  export { getVirtualFilePageConfigs };
2
- export { getConfigValueSerialized };
3
- import type { DefinedAt } from '../../../../../shared/page-configs/PageConfig.js';
4
2
  import type { ResolvedConfig } from 'vite';
5
3
  declare function getVirtualFilePageConfigs(isForClientSide: boolean, isDev: boolean, id: string, isClientRouting: boolean, config: ResolvedConfig): Promise<string>;
6
- declare function getConfigValueSerialized(value: unknown, configName: string, definedAt: DefinedAt): string;