vike 0.4.143-commit-dc6fea0 → 0.4.143-commit-fa295e1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/cjs/node/plugin/plugins/devConfig/determineOptimizeDeps.js +30 -27
  2. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +107 -54
  3. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +11 -10
  4. package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +11 -11
  5. package/dist/cjs/node/prerender/runPrerender.js +9 -8
  6. package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +3 -2
  7. package/dist/cjs/node/shared/getClientEntryFilePath.js +1 -7
  8. package/dist/cjs/shared/getPageFiles/getExports.js +2 -5
  9. package/dist/cjs/shared/getPageFiles/parsePageConfigsSerialized.js +9 -6
  10. package/dist/cjs/shared/hooks/getHook.js +3 -1
  11. package/dist/cjs/shared/page-configs/getExportPath.js +2 -2
  12. package/dist/cjs/shared/page-configs/parseConfigValuesImported.js +8 -5
  13. package/dist/cjs/shared/page-configs/utils.js +66 -42
  14. package/dist/cjs/shared/route/loadPageRoutes.js +5 -6
  15. package/dist/cjs/utils/projectInfo.js +1 -1
  16. package/dist/esm/node/plugin/plugins/devConfig/determineOptimizeDeps.js +30 -27
  17. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +107 -54
  18. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigValuesAll.js +11 -10
  19. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.d.ts +2 -2
  20. package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVirtualFilePageConfigs.js +11 -11
  21. package/dist/esm/node/prerender/runPrerender.js +10 -9
  22. package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +3 -2
  23. package/dist/esm/node/shared/getClientEntryFilePath.js +2 -8
  24. package/dist/esm/shared/getPageFiles/getExports.d.ts +1 -2
  25. package/dist/esm/shared/getPageFiles/getExports.js +3 -6
  26. package/dist/esm/shared/getPageFiles/parsePageConfigsSerialized.js +9 -6
  27. package/dist/esm/shared/hooks/getHook.js +3 -1
  28. package/dist/esm/shared/page-configs/PageConfig.d.ts +34 -10
  29. package/dist/esm/shared/page-configs/getExportPath.d.ts +1 -1
  30. package/dist/esm/shared/page-configs/getExportPath.js +2 -2
  31. package/dist/esm/shared/page-configs/parseConfigValuesImported.js +8 -5
  32. package/dist/esm/shared/page-configs/utils.d.ts +19 -13
  33. package/dist/esm/shared/page-configs/utils.js +65 -41
  34. package/dist/esm/shared/route/loadPageRoutes.js +6 -7
  35. package/dist/esm/utils/projectInfo.d.ts +1 -1
  36. package/dist/esm/utils/projectInfo.js +1 -1
  37. package/package.json +1 -1
@@ -53,30 +53,31 @@ function getLoadConfigValuesAll(pageConfig, isForClientSide, pageId, includeAsse
53
53
  return code;
54
54
  }
55
55
  function serializeConfigValueImported(configValueSource, configName, whitespace, varCounterContainer, importStatements) {
56
+ assert(!configValueSource.valueIsFilePath);
56
57
  assert(whitespace.replaceAll(' ', '').length === 0);
57
58
  const { valueIsImportedAtRuntime, definedAtInfo } = configValueSource;
58
59
  assert(valueIsImportedAtRuntime);
59
- const { filePath, fileExportPath } = definedAtInfo;
60
- assertPosixPath(filePath);
61
- const fileName = path.posix.basename(filePath);
60
+ const { filePathRelativeToUserRootDir, importPathAbsolute, exportName } = definedAtInfo;
61
+ const importPath = filePathRelativeToUserRootDir ?? importPathAbsolute;
62
+ assertPosixPath(importPath);
63
+ const fileName = path.posix.basename(importPath);
62
64
  const isValueFile = fileName.startsWith('+');
63
- const fileExportName = fileExportPath[0];
64
- assert(!configValueSource.valueIsFilePath);
65
- assert(fileExportName);
66
- const { importName, importStatement } = generateEagerImport(filePath, varCounterContainer.varCounter++, isValueFile ? undefined : fileExportName);
65
+ if (isValueFile)
66
+ assert(exportName === undefined);
67
+ const { importName, importStatement } = generateEagerImport(importPath, varCounterContainer.varCounter++, exportName);
67
68
  importStatements.push(importStatement);
68
69
  const lines = [];
69
70
  lines.push(` {`);
70
71
  lines.push(` configName: '${configName}',`);
71
- lines.push(` importPath: '${filePath}',`);
72
+ lines.push(` importPath: '${importPath}',`);
72
73
  lines.push(` isValueFile: ${JSON.stringify(isValueFile)},`);
73
74
  if (isValueFile) {
74
75
  lines.push(` importFileExports: ${importName},`);
75
76
  }
76
77
  else {
77
78
  lines.push(` importFileExportValue: ${importName},`);
78
- assert(fileExportName);
79
- lines.push(` exportName: ${JSON.stringify(fileExportName)},`);
79
+ assert(exportName);
80
+ lines.push(` exportName: ${JSON.stringify(exportName)},`);
80
81
  }
81
82
  lines.push(` },`);
82
83
  return lines;
@@ -1,6 +1,6 @@
1
1
  export { getVirtualFilePageConfigs };
2
2
  export { getConfigValueSerialized };
3
- import type { DefinedAtInfo } from '../../../../../shared/page-configs/PageConfig.js';
3
+ import type { DefinedAt } from '../../../../../shared/page-configs/PageConfig.js';
4
4
  import type { ConfigVikeResolved } from '../../../../../shared/ConfigVike.js';
5
5
  declare function getVirtualFilePageConfigs(userRootDir: string, isForClientSide: boolean, isDev: boolean, id: string, configVike: ConfigVikeResolved, isClientRouting: boolean): Promise<string>;
6
- declare function getConfigValueSerialized(value: unknown, configName: string, definedAtInfo: null | DefinedAtInfo): string;
6
+ declare function getConfigValueSerialized(value: unknown, configName: string, definedAt: DefinedAt): string;
@@ -9,6 +9,7 @@ import pc from '@brillout/picocolors';
9
9
  import { getVikeConfig } from './getVikeConfig.js';
10
10
  import { isConfigEnvMatch } from './isConfigEnvMatch.js';
11
11
  import { serializeConfigValueImported } from './getVirtualFilePageConfigValuesAll.js';
12
+ import { getConfigValueFilePathToShowToUser } from '../../../../../shared/page-configs/utils.js';
12
13
  async function getVirtualFilePageConfigs(userRootDir, isForClientSide, isDev, id, configVike, isClientRouting) {
13
14
  const { pageConfigs, pageConfigGlobal } = await getVikeConfig(userRootDir, isDev, configVike.extensions, true);
14
15
  return getContent(pageConfigs, pageConfigGlobal, isForClientSide, isDev, id, isClientRouting);
@@ -34,9 +35,9 @@ function getContent(pageConfigs, pageConfigGlobal, isForClientSide, isDev, id, i
34
35
  assert(configEnv, configName);
35
36
  if (!isConfigEnvMatch(configEnv, isForClientSide, isClientRouting))
36
37
  return;
37
- const { value, definedAtInfo } = configValue;
38
- const valueSerialized = getConfigValueSerialized(value, configName, definedAtInfo);
39
- serializeConfigValue(lines, configName, { definedAtInfo, valueSerialized });
38
+ const { value, definedAt } = configValue;
39
+ const valueSerialized = getConfigValueSerialized(value, configName, definedAt);
40
+ serializeConfigValue(lines, configName, { definedAt, valueSerialized });
40
41
  }
41
42
  });
42
43
  lines.push(` },`);
@@ -93,13 +94,13 @@ function serializeConfigValue(lines, configName, configValueSerialized) {
93
94
  lines.push(`${whitespace}['${configName}']: {`);
94
95
  whitespace += ' ';
95
96
  Object.entries(configValueSerialized).forEach(([key, val]) => {
96
- const valSerialized = key === 'definedAtInfo' ? JSON.stringify(val) : val;
97
+ const valSerialized = key === 'definedAt' ? JSON.stringify(val) : val;
97
98
  lines.push(`${whitespace} ${key}: ${valSerialized},`);
98
99
  });
99
100
  whitespace = whitespace.slice(2);
100
101
  lines.push(`${whitespace}},`);
101
102
  }
102
- function getConfigValueSerialized(value, configName, definedAtInfo) {
103
+ function getConfigValueSerialized(value, configName, definedAt) {
103
104
  let configValueSerialized;
104
105
  const valueName = `config${getPropAccessNotation(configName)}`;
105
106
  try {
@@ -107,15 +108,14 @@ function getConfigValueSerialized(value, configName, definedAtInfo) {
107
108
  }
108
109
  catch (err) {
109
110
  assert(hasProp(err, 'messageCore', 'string'));
110
- // definedAtInfo is null when config value is:
111
+ const configValueFilePathToShowToUser = getConfigValueFilePathToShowToUser({ definedAt });
112
+ // definedAt is null when config value is:
111
113
  // - computed => all computed values defined by Vike can are serializable
112
114
  // - cumulative => the values are already ensured to be serializable
113
- assert(definedAtInfo);
114
- const configDefinedByFile = definedAtInfo.filePath;
115
- assert(configDefinedByFile);
115
+ assert(configValueFilePathToShowToUser);
116
116
  assertUsage(false, [
117
- `The value of the config ${pc.cyan(configName)} cannot be defined inside the file ${configDefinedByFile}:`,
118
- `its value must be defined in an another file and then imported by ${configDefinedByFile}. (Because the value isn't serializable: ${err.messageCore}.)`,
117
+ `The value of the config ${pc.cyan(configName)} cannot be defined inside the file ${configValueFilePathToShowToUser}:`,
118
+ `its value must be defined in an another file and then imported by ${configValueFilePathToShowToUser}. (Because the value isn't serializable: ${err.messageCore}.)`,
119
119
  `Only serializable config values can be defined inside +config.h.js files, see https://vike.dev/header-file.`
120
120
  ].join(' '));
121
121
  }
@@ -16,7 +16,7 @@ import { getConfigVike } from '../shared/getConfigVike.js';
16
16
  import { getPageFilesServerSide } from '../../shared/getPageFiles.js';
17
17
  import { getPageContextRequestUrl } from '../../shared/getPageContextRequestUrl.js';
18
18
  import { getUrlFromRouteString } from '../../shared/route/resolveRouteString.js';
19
- import { getConfigDefinedAtInfo, getConfigValue } from '../../shared/page-configs/utils.js';
19
+ import { getConfigValue, getConfigValueFilePathToShowToUser, getHookFilePathToShowToUser } from '../../shared/page-configs/utils.js';
20
20
  import { loadConfigValues } from '../../shared/page-configs/loadConfigValues.js';
21
21
  import { isErrorPage } from '../../shared/error-page.js';
22
22
  import { addUrlComputedProps } from '../../shared/addUrlComputedProps.js';
@@ -87,12 +87,13 @@ async function collectDoNoPrerenderList(renderContext, doNotPrerenderList, concu
87
87
  const configName = 'prerender';
88
88
  const configValue = getConfigValue(pageConfig, configName, 'boolean');
89
89
  if (configValue?.value === false) {
90
- const definedAtInfo = getConfigDefinedAtInfo(pageConfig, configName);
90
+ const filePath = getConfigValueFilePathToShowToUser(configValue);
91
+ assert(filePath);
91
92
  doNotPrerenderList.push({
92
93
  pageId: pageConfig.pageId,
93
94
  setByConfigName: 'prerender',
94
95
  setByConfigValue: false,
95
- setByConfigFile: definedAtInfo.filePath
96
+ setByConfigFile: filePath
96
97
  });
97
98
  }
98
99
  });
@@ -148,8 +149,7 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
148
149
  if (!configValue)
149
150
  return;
150
151
  const hookFn = configValue.value;
151
- const definedAtInfo = getConfigDefinedAtInfo(pageConfigLoaded, hookName);
152
- const hookFilePath = definedAtInfo.filePath;
152
+ const hookFilePath = getHookFilePathToShowToUser(configValue);
153
153
  assert(hookFilePath);
154
154
  assertHookFn(hookFn, { hookName, hookFilePath });
155
155
  onBeforePrerenderStartHooks.push({
@@ -282,11 +282,12 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
282
282
  // V1 design
283
283
  if (renderContext.pageConfigs.length > 0) {
284
284
  const { pageConfigGlobal } = renderContext;
285
- if (pageConfigGlobal.configValues.onPrerenderStart?.value) {
286
- const { value: hookFn, definedAtInfo } = pageConfigGlobal.configValues.onPrerenderStart;
285
+ const configValue = pageConfigGlobal.configValues.onPrerenderStart;
286
+ if (configValue?.value) {
287
+ const { value: hookFn } = configValue;
287
288
  // config.onPrerenderStart isn't a computed nor a cumulative config => definedAtInfo should always be defined
288
- assert(definedAtInfo);
289
- const hookFilePath = definedAtInfo.filePath;
289
+ const hookFilePath = getHookFilePathToShowToUser(configValue);
290
+ assert(hookFilePath);
290
291
  onPrerenderStartHook = {
291
292
  hookFn,
292
293
  hookName: 'onPrerenderStart',
@@ -20,6 +20,7 @@ import { preparePageContextForUserConsumptionServerSide } from './preparePageCon
20
20
  import { executeGuardHook } from '../../../shared/route/executeGuardHook.js';
21
21
  import { loadPageRoutes } from '../../../shared/route/loadPageRoutes.js';
22
22
  import pc from '@brillout/picocolors';
23
+ import { getConfigValueFilePathToShowToUser } from '../../../shared/page-configs/utils.js';
23
24
  async function renderPageAlreadyRouted(pageContext) {
24
25
  // pageContext._pageId can either be the:
25
26
  // - ID of the page matching the routing, or the
@@ -166,9 +167,9 @@ function assertNonMixedDesign(pageFilesAll, pageConfigs) {
166
167
  const indent = '- ';
167
168
  const v1Files = unique(pageConfigs
168
169
  .map((p) => Object.values(p.configValues)
169
- .map(({ definedAtInfo }) => definedAtInfo)
170
+ .map(getConfigValueFilePathToShowToUser)
170
171
  .filter(isNotNullish)
171
- .map((definedAtInfo) => indent + definedAtInfo.filePath))
172
+ .map((filePathToShowToUser) => indent + filePathToShowToUser))
172
173
  .flat(2));
173
174
  assertUsage(false, [
174
175
  'Mixing the new V1 design with the old V0.4 design is forbidden.',
@@ -1,15 +1,9 @@
1
1
  export { getClientEntryFilePath };
2
- import { getConfigDefinedAtInfo, getConfigValue } from '../../shared/page-configs/utils.js';
3
- import { assert } from './utils.js';
2
+ import { getConfigValue } from '../../shared/page-configs/utils.js';
4
3
  function getClientEntryFilePath(pageConfig) {
5
4
  const configName = 'client';
6
5
  const configValue = getConfigValue(pageConfig, configName, 'string');
7
6
  if (!configValue)
8
7
  return null;
9
- const definedAtInfo = getConfigDefinedAtInfo(pageConfig, configName);
10
- const { value } = configValue;
11
- // Users should be able to suppress client entry by setting its value to null
12
- assert(value !== null);
13
- const clientEntryFilePath = definedAtInfo.filePath;
14
- return clientEntryFilePath;
8
+ return configValue.value;
15
9
  }
@@ -9,13 +9,12 @@ import type { PageFile } from './getPageFileObject.js';
9
9
  type ExportsAll = Record<string, {
10
10
  exportValue: unknown;
11
11
  exportSource: string;
12
+ filePath: string | null;
12
13
  /** @deprecated */
13
14
  _fileType: FileType | null;
14
15
  /** @deprecated */
15
16
  _isFromDefaultExport: boolean | null;
16
17
  /** @deprecated */
17
- filePath: string | null;
18
- /** @deprecated */
19
18
  _filePath: string | null;
20
19
  }[]>;
21
20
  /** All the config's values (including overriden ones) and where they come from.
@@ -3,7 +3,7 @@ export { getExports };
3
3
  import { isScriptFile, isTemplateFile } from '../../utils/isScriptFile.js';
4
4
  import { assert, hasProp, isObject, assertWarning, assertUsage, makeLast, isBrowser } from '../utils.js';
5
5
  import { assertDefaultExports, forbiddenDefaultExports } from './assert_exports_old_design.js';
6
- import { getConfigDefinedAtString } from '../page-configs/utils.js';
6
+ import { getConfigDefinedAtString, getConfigValueFilePathToShowToUser } from '../page-configs/utils.js';
7
7
  import pc from '@brillout/picocolors';
8
8
  function getExports(pageFiles, pageConfig) {
9
9
  const configEntries = {};
@@ -29,11 +29,8 @@ function getExports(pageFiles, pageConfig) {
29
29
  // V1 design
30
30
  if (pageConfig) {
31
31
  Object.entries(pageConfig.configValues).forEach(([configName, configValue]) => {
32
- const { value, definedAtInfo } = configValue;
33
- let filePath = null;
34
- if (definedAtInfo) {
35
- filePath = definedAtInfo.filePath;
36
- }
32
+ const { value } = configValue;
33
+ const filePath = getConfigValueFilePathToShowToUser(configValue);
37
34
  const configDefinedAt = getConfigDefinedAtString(configName, configValue, true);
38
35
  config[configName] = config[configName] ?? value;
39
36
  configEntries[configName] = configEntries[configName] ?? [];
@@ -2,6 +2,7 @@ export { parsePageConfigsSerialized };
2
2
  import { parse } from '@brillout/json-serializer/parse';
3
3
  import { parseConfigValuesImported } from '../page-configs/parseConfigValuesImported.js';
4
4
  import { assert, assertUsage, isCallable } from '../utils.js';
5
+ import { getConfigDefinedAtString } from '../page-configs/utils.js';
5
6
  function parsePageConfigsSerialized(pageConfigsSerialized, pageConfigGlobalSerialized) {
6
7
  const pageConfigs = pageConfigsSerialized.map((pageConfigSerialized) => {
7
8
  const configValues = {};
@@ -9,12 +10,12 @@ function parsePageConfigsSerialized(pageConfigsSerialized, pageConfigGlobalSeria
9
10
  const { configValuesSerialized } = pageConfigSerialized;
10
11
  Object.entries(configValuesSerialized).forEach(([configName, configValueSeriliazed]) => {
11
12
  {
12
- const { valueSerialized, definedAtInfo } = configValueSeriliazed;
13
+ const { valueSerialized, definedAt } = configValueSeriliazed;
13
14
  assert(valueSerialized);
14
15
  assert(!configValues[configName]);
15
16
  configValues[configName] = {
16
17
  value: parse(valueSerialized),
17
- definedAtInfo
18
+ definedAt
18
19
  };
19
20
  }
20
21
  });
@@ -42,12 +43,14 @@ function parsePageConfigsSerialized(pageConfigsSerialized, pageConfigGlobalSeria
42
43
  return { pageConfigs, pageConfigGlobal };
43
44
  }
44
45
  function assertRouteConfigValue(configValues) {
45
- if (!configValues.route)
46
+ const configName = 'route';
47
+ const configValue = configValues[configName];
48
+ if (!configValue)
46
49
  return;
47
- const { value, definedAtInfo } = configValues.route;
50
+ const { value } = configValue;
48
51
  const configValueType = typeof value;
49
- assert(definedAtInfo);
50
- assertUsage(configValueType === 'string' || isCallable(value), `${definedAtInfo.filePath} has an invalid type '${configValueType}': it should be a string or a function instead, see https://vike.dev/route`);
52
+ const configDefinedAt = getConfigDefinedAtString(configName, configValue, true);
53
+ assertUsage(configValueType === 'string' || isCallable(value), `${configDefinedAt} has an invalid type '${configValueType}': it should be a string or a function instead, see https://vike.dev/route`);
51
54
  /* We don't use assertRouteString() in order to avoid unnecessarily bloating the client-side bundle when using Server Routing:
52
55
  * - When using Server Routing, this file is loaded => loading assertRouteString() would bloat the client bundle.
53
56
  * - assertRouteString() is already called on the server-side
@@ -11,7 +11,9 @@ function getHook(pageContext, hookName) {
11
11
  assert(file.exportValue === hookFn);
12
12
  if (hookFn === null)
13
13
  return null;
14
- const hookFilePath = file.exportSource;
14
+ const hookFilePath = file.filePath;
15
+ assert(hookFilePath);
16
+ assert(!hookFilePath.endsWith(' '));
15
17
  assertHookFn(hookFn, { hookName, hookFilePath });
16
18
  return { hookFn, hookName, hookFilePath };
17
19
  }
@@ -14,8 +14,10 @@ export type { ConfigValueImported };
14
14
  export type { ConfigValues };
15
15
  export type { ConfigValueSource };
16
16
  export type { ConfigValueSources };
17
- export type { DefinedAtInfo };
17
+ export type { DefinedAt };
18
+ export type { DefinedAtInfoNew };
18
19
  export type { DefinedAtInfoFull };
20
+ export type { DefinedAtInfoFull as DefinedAtInfo };
19
21
  type PageConfigBase = {
20
22
  pageId: string;
21
23
  isErrorPage?: true;
@@ -70,7 +72,7 @@ type ConfigValueSource = {
70
72
  valueIsFilePath?: true;
71
73
  } & ({
72
74
  isComputed: false;
73
- definedAtInfo: DefinedAtInfo;
75
+ definedAtInfo: DefinedAtInfoFull;
74
76
  } | {
75
77
  isComputed: true;
76
78
  definedAtInfo: null;
@@ -79,21 +81,43 @@ type ConfigValueSource = {
79
81
  type ConfigValueSources = Record<string, ConfigValueSource[]>;
80
82
  type ConfigValue = {
81
83
  value: unknown;
82
- definedAtInfo: null | DefinedAtInfo;
84
+ definedAt: DefinedAt;
83
85
  };
84
86
  type ConfigValueSerialized = {
85
87
  valueSerialized: string;
86
- definedAtInfo: null | DefinedAtInfo;
88
+ definedAt: DefinedAt;
87
89
  };
88
90
  type ConfigValues = Record<string, ConfigValue>;
89
- type DefinedAtInfo = {
90
- filePath: string;
91
- fileExportPath: string[];
91
+ type DefinedAt = {
92
+ source: DefinedAtInfoNew;
93
+ isEffect?: true;
94
+ isComputed?: undefined;
95
+ isCumulative?: undefined;
96
+ } | {
97
+ isCumulative: true;
98
+ sources: DefinedAtInfoNew[];
99
+ isEffect?: undefined;
100
+ isComputed?: undefined;
101
+ } | {
102
+ isComputed: true;
103
+ isEffect?: undefined;
104
+ isCumulative?: undefined;
92
105
  };
93
- type DefinedAtInfoFull = {
94
- filePathRelativeToUserRootDir?: string;
106
+ type DefinedAtInfoNew = {
107
+ filePathToShowToUser: string;
108
+ fileExportPath: null | string[];
109
+ };
110
+ type DefinedAtInfoFull = ({
111
+ filePathRelativeToUserRootDir: string;
95
112
  filePathAbsolute: string;
96
- fileExportPath: string[];
113
+ importPathAbsolute: null;
114
+ } | {
115
+ filePathRelativeToUserRootDir: null;
116
+ filePathAbsolute: string | null;
117
+ importPathAbsolute: string;
118
+ }) & {
119
+ exportName?: string;
120
+ fileExportPath: null | string[];
97
121
  };
98
122
  type ConfigSource = {
99
123
  configSourceFile: string;
@@ -1,2 +1,2 @@
1
1
  export { getExportPath };
2
- declare function getExportPath(fileExportPath: string[]): null | string;
2
+ declare function getExportPath(fileExportPath: null | string[]): null | string;
@@ -1,8 +1,8 @@
1
1
  export { getExportPath };
2
2
  import { assert } from '../utils.js';
3
- // TODO: return null instead of 'export default'
4
- // - Also return null insead of 'export *'?
5
3
  function getExportPath(fileExportPath) {
4
+ if (!fileExportPath)
5
+ return null;
6
6
  let prefix = '';
7
7
  let suffix = '';
8
8
  let [exportName, ...exportObjectPath] = fileExportPath;
@@ -4,15 +4,18 @@ import { assertExportsOfValueFile } from './assertExports.js';
4
4
  import pc from '@brillout/picocolors';
5
5
  function parseConfigValuesImported(configValuesImported) {
6
6
  const configValues = {};
7
- const addConfigValue = (configName, value, filePath, exportName) => {
7
+ const addConfigValue = (configName, value, importPath, exportName) => {
8
8
  configValues[configName] = {
9
9
  value,
10
- definedAtInfo: {
11
- filePath,
12
- fileExportPath: [exportName]
10
+ definedAt: {
11
+ source: {
12
+ // importPath is always relative the user's root directory (it cannot be relative to the current file since the current file is a virtual file)
13
+ filePathToShowToUser: importPath,
14
+ fileExportPath: [exportName]
15
+ }
13
16
  }
14
17
  };
15
- assertIsNotNull(value, configName, filePath);
18
+ assertIsNotNull(value, configName, importPath);
16
19
  };
17
20
  configValuesImported.forEach((configValueLoaded) => {
18
21
  if (configValueLoaded.isValueFile) {
@@ -1,29 +1,35 @@
1
1
  export { getConfigValue };
2
2
  export { getPageConfig };
3
3
  export { getConfigDefinedAtString };
4
- export { getConfigDefinedAtInfo };
5
4
  export { getDefinedAtString };
6
- import type { DefinedAtInfo, PageConfigRuntime, PageConfigBuildTime } from './PageConfig.js';
5
+ export { getConfigValueFilePathToShowToUser };
6
+ export { getHookFilePathToShowToUser };
7
+ import type { PageConfigRuntime, PageConfigBuildTime, ConfigValue, DefinedAt } from './PageConfig.js';
7
8
  import type { ConfigNameBuiltIn } from './Config.js';
8
9
  type PageConfigCommon = PageConfigRuntime | PageConfigBuildTime;
9
10
  type ConfigName = ConfigNameBuiltIn;
10
- declare function getConfigValue(pageConfig: PageConfigCommon, configName: ConfigName, type: 'string'): null | {
11
+ declare function getConfigValue(pageConfig: PageConfigCommon, configName: ConfigName, type: 'string'): null | ConfigValue & {
11
12
  value: string;
12
13
  };
13
- declare function getConfigValue(pageConfig: PageConfigCommon, configName: ConfigName, type: 'boolean'): null | {
14
+ declare function getConfigValue(pageConfig: PageConfigCommon, configName: ConfigName, type: 'boolean'): null | ConfigValue & {
14
15
  value: boolean;
15
16
  };
16
- declare function getConfigValue(pageConfig: PageConfigCommon, configName: ConfigName): null | {
17
+ declare function getConfigValue(pageConfig: PageConfigCommon, configName: ConfigName): null | ConfigValue & {
17
18
  value: unknown;
18
19
  };
19
- declare function getConfigDefinedAtInfo(pageConfig: PageConfigCommon, configName: ConfigName): DefinedAtInfo;
20
20
  declare function getPageConfig(pageId: string, pageConfigs: PageConfigRuntime[]): PageConfigRuntime;
21
- type ConfigDefinedAtUppercase<ConfigName extends string> = `Config ${ConfigName}${string}`;
22
- type ConfigDefinedAtLowercase<ConfigName extends string> = `config ${ConfigName}${string}`;
23
- declare function getConfigDefinedAtString<ConfigName extends string>(configName: ConfigName, { definedAtInfo }: {
24
- definedAtInfo: null | DefinedAtInfo;
21
+ type ConfigDefinedAtUppercase<ConfigName extends string> = `Config ${ConfigName} defined ${string}`;
22
+ type ConfigDefinedAtLowercase<ConfigName extends string> = `config ${ConfigName} defined ${string}`;
23
+ declare function getConfigDefinedAtString<ConfigName extends string>(configName: ConfigName, { definedAt }: {
24
+ definedAt: DefinedAt;
25
25
  }, sentenceBegin: true, append?: 'effect'): ConfigDefinedAtUppercase<ConfigName>;
26
- declare function getConfigDefinedAtString<ConfigName extends string>(configName: ConfigName, { definedAtInfo }: {
27
- definedAtInfo: null | DefinedAtInfo;
26
+ declare function getConfigDefinedAtString<ConfigName extends string>(configName: ConfigName, { definedAt }: {
27
+ definedAt: DefinedAt;
28
28
  }, sentenceBegin: false, append?: 'effect'): ConfigDefinedAtLowercase<ConfigName>;
29
- declare function getDefinedAtString(definedAtInfo: DefinedAtInfo, append?: 'effect'): string;
29
+ declare function getDefinedAtString(configValue: ConfigValue): string;
30
+ declare function getConfigValueFilePathToShowToUser({ definedAt }: {
31
+ definedAt: DefinedAt;
32
+ }): null | string;
33
+ declare function getHookFilePathToShowToUser({ definedAt }: {
34
+ definedAt: DefinedAt;
35
+ }): string;
@@ -1,8 +1,9 @@
1
1
  export { getConfigValue };
2
2
  export { getPageConfig };
3
3
  export { getConfigDefinedAtString };
4
- export { getConfigDefinedAtInfo };
5
4
  export { getDefinedAtString };
5
+ export { getConfigValueFilePathToShowToUser };
6
+ export { getHookFilePathToShowToUser };
6
7
  import { assert, assertUsage, getValuePrintable } from '../utils.js';
7
8
  import pc from '@brillout/picocolors';
8
9
  import { getExportPath } from './getExportPath.js';
@@ -11,31 +12,29 @@ function getConfigValue(pageConfig, configName, type) {
11
12
  const configValue = getConfigValueEntry(pageConfig, configName);
12
13
  if (configValue === null)
13
14
  return null;
14
- const { value, definedAtInfo } = configValue;
15
+ const { value, definedAt } = configValue;
15
16
  if (type)
16
- assertConfigValueType(value, type, configName, definedAtInfo);
17
- return { value };
17
+ assertConfigValueType(value, type, configName, definedAt);
18
+ return configValue;
18
19
  }
19
- function getConfigDefinedAtInfo(pageConfig, configName) {
20
- const configValue = getConfigValueEntry(pageConfig, configName);
21
- // We assume the caller to have ensured that the config value exists prior to calling getConfigDefinedAtInfo()
22
- assert(configValue);
23
- const { definedAtInfo } = configValue;
24
- // definedAtInfo is available only for config values that aren't:
25
- // - computed, nor
26
- // - cumulative
27
- assert(definedAtInfo);
28
- return definedAtInfo;
20
+ function assertConfigValueType(value, type, configName, definedAt) {
21
+ assert(value !== null);
22
+ const typeActual = typeof value;
23
+ if (typeActual === type)
24
+ return;
25
+ const valuePrintable = getValuePrintable(value);
26
+ const problem = valuePrintable !== null ? `value ${pc.cyan(valuePrintable)}` : `type ${pc.cyan(typeActual)}`;
27
+ const configDefinedAt = getConfigDefinedAtString(configName, { definedAt }, true);
28
+ assertUsage(false, `${configDefinedAt} has an invalid ${problem}: it should be a ${pc.cyan(type)} instead`);
29
29
  }
30
30
  function getConfigValueEntry(pageConfig, configName) {
31
31
  const configValue = pageConfig.configValues[configName];
32
32
  if (!configValue)
33
33
  return null;
34
- const { value, definedAtInfo } = configValue;
35
34
  // Enable users to suppress global config values by setting the local config value to null
36
- if (value === null)
35
+ if (configValue.value === null)
37
36
  return null;
38
- return { value, definedAtInfo };
37
+ return configValue;
39
38
  }
40
39
  function getPageConfig(pageId, pageConfigs) {
41
40
  const pageConfig = pageConfigs.find((p) => p.pageId === pageId);
@@ -43,32 +42,57 @@ function getPageConfig(pageId, pageConfigs) {
43
42
  assert(pageConfig);
44
43
  return pageConfig;
45
44
  }
46
- function assertConfigValueType(value, type, configName, definedAtInfo) {
47
- assert(value !== null);
48
- const typeActual = typeof value;
49
- if (typeActual === type)
50
- return;
51
- const valuePrintable = getValuePrintable(value);
52
- const problem = valuePrintable !== null ? `value ${pc.cyan(valuePrintable)}` : `type ${pc.cyan(typeActual)}`;
53
- const configDefinedAt = getConfigDefinedAtString(configName, { definedAtInfo }, true);
54
- assertUsage(false, `${configDefinedAt} has an invalid ${problem}: it should be a ${pc.cyan(type)} instead`);
55
- }
56
- function getConfigDefinedAtString(configName, { definedAtInfo }, sentenceBegin, append) {
57
- let configDefinedAt = `${sentenceBegin ? `Config` : `config`} ${pc.cyan(configName)}`;
58
- if (definedAtInfo !== null) {
59
- configDefinedAt = `${configDefinedAt} defined at ${getDefinedAtString(definedAtInfo, append)}`;
60
- }
45
+ function getConfigDefinedAtString(configName, { definedAt }, sentenceBegin) {
46
+ const configDefinedAt = `${sentenceBegin ? `Config` : `config`} ${pc.cyan(configName)} defined ${getSourceString(definedAt)}`;
61
47
  return configDefinedAt;
62
48
  }
63
- function getDefinedAtString(definedAtInfo, append) {
64
- const { filePath, fileExportPath } = definedAtInfo;
65
- let definedAt = filePath;
66
- const exportPath = getExportPath(fileExportPath);
67
- if (exportPath) {
68
- definedAt = `${definedAt} > ${pc.cyan(exportPath)}`;
49
+ function getSourceString(definedAt) {
50
+ if (definedAt.isComputed) {
51
+ return 'internally';
69
52
  }
70
- if (append) {
71
- definedAt = `${definedAt} > (${pc.blue(append)})`;
53
+ let sources;
54
+ if (definedAt.isCumulative) {
55
+ sources = definedAt.sources;
72
56
  }
73
- return definedAt;
57
+ else {
58
+ sources = [definedAt.source];
59
+ }
60
+ assert(sources.length >= 1);
61
+ const sourceString = sources
62
+ .map((source) => {
63
+ const { filePathToShowToUser, fileExportPath } = source;
64
+ let s = filePathToShowToUser;
65
+ const exportPath = getExportPath(fileExportPath);
66
+ if (exportPath) {
67
+ s = `${s} > ${pc.cyan(exportPath)}`;
68
+ }
69
+ if (definedAt.isEffect) {
70
+ s = `${s} > (${pc.blue('effect')})`;
71
+ }
72
+ return s;
73
+ })
74
+ .join(' / ');
75
+ return `at ${sourceString}`;
76
+ }
77
+ function getDefinedAtString(configValue) {
78
+ let sourceString = getSourceString(configValue.definedAt);
79
+ if (sourceString.startsWith('at '))
80
+ sourceString = sourceString.slice('at '.length);
81
+ return sourceString;
82
+ }
83
+ function getConfigValueFilePathToShowToUser({ definedAt }) {
84
+ // A unique file path only exists if the config value isn't cumulative nor computed:
85
+ // - cumulative config values have multiple file paths
86
+ // - computed values don't have any file path
87
+ if (definedAt.isComputed || definedAt.isCumulative)
88
+ return null;
89
+ const { source } = definedAt;
90
+ const { filePathToShowToUser } = source;
91
+ assert(filePathToShowToUser);
92
+ return filePathToShowToUser;
93
+ }
94
+ function getHookFilePathToShowToUser({ definedAt }) {
95
+ const filePathToShowToUser = getConfigValueFilePathToShowToUser({ definedAt });
96
+ assert(filePathToShowToUser);
97
+ return filePathToShowToUser;
74
98
  }
@@ -3,7 +3,7 @@ import { isErrorPageId } from '../error-page.js';
3
3
  import { assert, assertUsage, hasProp, slice } from './utils.js';
4
4
  import { deduceRouteStringFromFilesystemPath } from './deduceRouteStringFromFilesystemPath.js';
5
5
  import { isCallable } from '../utils.js';
6
- import { getConfigDefinedAtInfo, getConfigValue, getDefinedAtString } from '../page-configs/utils.js';
6
+ import { getConfigValue, getDefinedAtString, getHookFilePathToShowToUser } from '../page-configs/utils.js';
7
7
  import { warnDeprecatedAllowKey } from './resolveRouteFunction.js';
8
8
  async function loadPageRoutes(
9
9
  // TODO: remove all arguments and use GlobalContext instead
@@ -30,9 +30,8 @@ function getPageRoutes(filesystemRoots, pageFilesAll, pageConfigs, allPageIds) {
30
30
  const configName = 'route';
31
31
  const configValue = getConfigValue(pageConfig, configName);
32
32
  if (configValue) {
33
- const definedAtInfo = getConfigDefinedAtInfo(pageConfig, configName);
34
33
  const route = configValue.value;
35
- const definedAt = getDefinedAtString(definedAtInfo);
34
+ const definedAt = getDefinedAtString(configValue);
36
35
  if (typeof route === 'string') {
37
36
  pageRoute = {
38
37
  pageId,
@@ -138,10 +137,10 @@ function getGlobalHooks(pageFilesAll, pageConfigs, pageConfigGlobal) {
138
137
  // V1 Design
139
138
  if (pageConfigs.length > 0) {
140
139
  if (pageConfigGlobal.configValues.onBeforeRoute?.value) {
141
- const { value: hookFn, definedAtInfo } = pageConfigGlobal.configValues.onBeforeRoute;
142
- // config.onBeforeRoute isn't a computed nor a cumulative config => definedAtInfo should always be defined
143
- assert(definedAtInfo);
144
- const hookFilePath = definedAtInfo.filePath;
140
+ const configValue = pageConfigGlobal.configValues.onBeforeRoute;
141
+ const { value: hookFn } = configValue;
142
+ const hookFilePath = getHookFilePathToShowToUser(configValue);
143
+ // TODO: use getConfigDefinedAtString()
145
144
  assertUsage(isCallable(hookFn), `The hook onBeforeRoute() defined by ${hookFilePath} should be a function.`);
146
145
  const onBeforeRouteHook = {
147
146
  hookFilePath: hookFilePath,