vike 0.4.147-commit-f9a91f3 → 0.4.148-commit-7596dcd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +17 -12
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +3 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +12 -0
- package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +28 -10
- package/dist/cjs/node/prerender/runPrerender.js +20 -22
- package/dist/cjs/node/runtime/html/renderHtml.js +1 -1
- package/dist/cjs/node/runtime/renderPage/executeOnBeforeRenderHook.js +1 -1
- package/dist/cjs/node/runtime/renderPage/executeOnRenderHtmlHook.js +3 -3
- package/dist/cjs/node/runtime/renderPage/renderPageAlreadyRouted.js +21 -18
- package/dist/cjs/shared/getPageFiles/parseGlobResults.js +3 -3
- package/dist/cjs/shared/hooks/executeHook.js +18 -29
- package/dist/cjs/shared/hooks/getHook.js +104 -3
- package/dist/cjs/shared/page-configs/helpers/getConfigDefinedAtString.js +1 -1
- package/dist/cjs/shared/route/executeGuardHook.js +3 -2
- package/dist/cjs/shared/route/executeOnBeforeRouteHook.js +4 -4
- package/dist/cjs/shared/route/loadPageRoutes.js +10 -15
- package/dist/cjs/utils/projectInfo.js +1 -1
- package/dist/esm/client/client-routing-runtime/createPageContext.d.ts +1 -1
- package/dist/esm/client/client-routing-runtime/getPageContextFromHooks.js +1 -1
- package/dist/esm/client/client-routing-runtime/renderPageClientSide.js +18 -12
- package/dist/esm/client/shared/executeOnRenderClientHook.js +1 -1
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getConfigValuesSerialized.js +17 -12
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/configDefinitionsBuiltIn.js +3 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js +12 -0
- package/dist/esm/node/plugin/plugins/importUserCode/v1-design/getVikeConfig.js +28 -10
- package/dist/esm/node/prerender/runPrerender.js +22 -24
- package/dist/esm/node/runtime/html/renderHtml.js +1 -1
- package/dist/esm/node/runtime/renderPage/executeOnBeforeRenderHook.js +1 -1
- package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.d.ts +2 -2
- package/dist/esm/node/runtime/renderPage/executeOnRenderHtmlHook.js +3 -3
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.d.ts +7 -7
- package/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js +22 -19
- package/dist/esm/shared/getPageFiles/parseGlobResults.js +1 -1
- package/dist/esm/shared/hooks/executeHook.d.ts +2 -2
- package/dist/esm/shared/hooks/executeHook.js +18 -29
- package/dist/esm/shared/hooks/getHook.d.ts +17 -7
- package/dist/esm/shared/hooks/getHook.js +103 -3
- package/dist/esm/shared/page-configs/Config.d.ts +21 -13
- package/dist/esm/shared/page-configs/helpers/getConfigDefinedAtString.d.ts +1 -1
- package/dist/esm/shared/page-configs/helpers/getConfigDefinedAtString.js +1 -1
- package/dist/esm/shared/route/executeGuardHook.js +4 -3
- package/dist/esm/shared/route/executeOnBeforeRouteHook.d.ts +1 -8
- package/dist/esm/shared/route/executeOnBeforeRouteHook.js +6 -6
- package/dist/esm/shared/route/index.d.ts +2 -2
- package/dist/esm/shared/route/loadPageRoutes.d.ts +2 -2
- package/dist/esm/shared/route/loadPageRoutes.js +11 -16
- package/dist/esm/utils/projectInfo.d.ts +2 -2
- package/dist/esm/utils/projectInfo.js +1 -1
- package/package.json +1 -1
- /package/dist/cjs/shared/page-configs/serialize/{assertPageConfigs.js → assertPageConfigsSerialized.js} +0 -0
- /package/dist/esm/shared/page-configs/serialize/{assertPageConfigs.d.ts → assertPageConfigsSerialized.d.ts} +0 -0
- /package/dist/esm/shared/page-configs/serialize/{assertPageConfigs.js → assertPageConfigsSerialized.js} +0 -0
|
@@ -53,22 +53,27 @@ function getConfigValueSerialized(value, configName, definedAt) {
|
|
|
53
53
|
configValueSerialized = (0, stringify_1.stringify)(value, { valueName, forbidReactElements: true });
|
|
54
54
|
}
|
|
55
55
|
catch (err) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
else {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
/*
|
|
57
|
+
let serializationErrMsg = ''
|
|
58
|
+
if (isJsonSerializerError(err)) {
|
|
59
|
+
serializationErrMsg = err.messageCore
|
|
60
|
+
} else {
|
|
61
|
+
// When a property getter throws an error
|
|
62
|
+
console.error('Serialization error:')
|
|
63
|
+
console.error(err)
|
|
64
|
+
serializationErrMsg = 'see serialization error printed above'
|
|
65
65
|
}
|
|
66
|
+
*/
|
|
66
67
|
const configValueFilePathToShowToUser = (0, helpers_js_1.getConfigValueFilePathToShowToUser)({ definedAt });
|
|
67
68
|
(0, utils_js_1.assert)(configValueFilePathToShowToUser);
|
|
68
69
|
(0, utils_js_1.assertUsage)(false, [
|
|
69
|
-
`The
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
`The code of ${picocolors_1.default.cyan(configName)} cannot live inside ${configValueFilePathToShowToUser},`,
|
|
71
|
+
'see https://vike.dev/header-file#runtime-code'
|
|
72
|
+
/* I guess showing this is more confusing than adding value.
|
|
73
|
+
`(technically speaking: the value of ${pc.cyan(
|
|
74
|
+
configName
|
|
75
|
+
)} isn't serializable (${serializationErrMsg}) and it's therefore runtime code that needs to be imported).`
|
|
76
|
+
//*/
|
|
72
77
|
].join(' '));
|
|
73
78
|
}
|
|
74
79
|
configValueSerialized = JSON.stringify(configValueSerialized);
|
|
@@ -76,6 +76,9 @@ const configDefinitionsBuiltIn = {
|
|
|
76
76
|
onBeforeRenderEnv: {
|
|
77
77
|
env: { client: true },
|
|
78
78
|
_computed: (configValueSources) => !isConfigSet(configValueSources, 'onBeforeRender') ? null : getConfigEnv(configValueSources, 'onBeforeRender')
|
|
79
|
+
},
|
|
80
|
+
hooksTimeout: {
|
|
81
|
+
env: { server: true, client: true }
|
|
79
82
|
}
|
|
80
83
|
};
|
|
81
84
|
exports.configDefinitionsBuiltIn = configDefinitionsBuiltIn;
|
package/dist/cjs/node/plugin/plugins/importUserCode/v1-design/getVikeConfig/crawlPlusFiles.js
CHANGED
|
@@ -51,6 +51,18 @@ async function crawlPlusFiles(userRootDir, outDirAbsoluteFilesystem, isDev) {
|
|
|
51
51
|
exports.crawlPlusFiles = crawlPlusFiles;
|
|
52
52
|
// Same as fastGlob() but using `$ git ls-files`
|
|
53
53
|
async function gitLsFiles(userRootDir, outDir) {
|
|
54
|
+
// Test if Git is installed
|
|
55
|
+
{
|
|
56
|
+
let stdout;
|
|
57
|
+
try {
|
|
58
|
+
const res = await execA('git --version', { cwd: userRootDir });
|
|
59
|
+
stdout = res.stdout;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
(0, utils_js_1.assert)(stdout.startsWith('git version '));
|
|
65
|
+
}
|
|
54
66
|
const cmd = [
|
|
55
67
|
'git ls-files',
|
|
56
68
|
...utils_js_1.scriptFileExtensionList.map((ext) => `"**/+*.${ext}"`),
|
|
@@ -127,6 +127,7 @@ async function loadInterfaceFiles(userRootDir, outDirRoot, isDev, extensions) {
|
|
|
127
127
|
interfaceFilesByLocationId[locationId].push(interfaceFile);
|
|
128
128
|
}
|
|
129
129
|
}));
|
|
130
|
+
assertAllConfigsAreKnown(interfaceFilesByLocationId);
|
|
130
131
|
return interfaceFilesByLocationId;
|
|
131
132
|
}
|
|
132
133
|
function getConfigDefinition(configDefinitionsRelevant, configName, filePathToShowToUser) {
|
|
@@ -180,6 +181,18 @@ function getInterfaceFileFromConfigFile(configFile, isConfigExtend) {
|
|
|
180
181
|
});
|
|
181
182
|
return interfaceFile;
|
|
182
183
|
}
|
|
184
|
+
/** Show error message upon unknown config */
|
|
185
|
+
function assertAllConfigsAreKnown(interfaceFilesByLocationId) {
|
|
186
|
+
Object.entries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
|
|
187
|
+
const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesByLocationId, locationId);
|
|
188
|
+
const configDefinitionsRelevant = getConfigDefinitions(interfaceFilesRelevant);
|
|
189
|
+
interfaceFiles.forEach((interfaceFile) => {
|
|
190
|
+
Object.keys(interfaceFile.configMap).forEach((configName) => {
|
|
191
|
+
assertConfigExists(configName, Object.keys(configDefinitionsRelevant), interfaceFile.filePath.filePathToShowToUser);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
}
|
|
183
196
|
async function loadVikeConfig_withErrorHandling(userRootDir, outDirRoot, isDev, extensions, tolerateInvalidConfig) {
|
|
184
197
|
let hasError = false;
|
|
185
198
|
let ret;
|
|
@@ -270,18 +283,23 @@ async function loadVikeConfig(userRootDir, outDirRoot, isDev, extensions) {
|
|
|
270
283
|
};
|
|
271
284
|
return pageConfig;
|
|
272
285
|
}));
|
|
273
|
-
|
|
274
|
-
Object.entries(interfaceFilesByLocationId).forEach(([locationId, interfaceFiles]) => {
|
|
275
|
-
const interfaceFilesRelevant = getInterfaceFilesRelevant(interfaceFilesByLocationId, locationId);
|
|
276
|
-
const configDefinitionsRelevant = getConfigDefinitions(interfaceFilesRelevant);
|
|
277
|
-
interfaceFiles.forEach((interfaceFile) => {
|
|
278
|
-
Object.keys(interfaceFile.configMap).forEach((configName) => {
|
|
279
|
-
assertConfigExists(configName, Object.keys(configDefinitionsRelevant), interfaceFile.filePath.filePathToShowToUser);
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
});
|
|
286
|
+
assertPageConfigs(pageConfigs);
|
|
283
287
|
return { pageConfigs, pageConfigGlobal, globalVikeConfig };
|
|
284
288
|
}
|
|
289
|
+
function assertPageConfigs(pageConfigs) {
|
|
290
|
+
pageConfigs.forEach((pageConfig) => {
|
|
291
|
+
assertOnBeforeRenderEnv(pageConfig);
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
function assertOnBeforeRenderEnv(pageConfig) {
|
|
295
|
+
const onBeforeRenderConfig = pageConfig.configValueSources.onBeforeRender?.[0];
|
|
296
|
+
if (!onBeforeRenderConfig)
|
|
297
|
+
return;
|
|
298
|
+
const onBeforeRenderEnv = onBeforeRenderConfig.configEnv;
|
|
299
|
+
const isClientRouting = !!pageConfig.configValues.clientRouting?.value;
|
|
300
|
+
// When using Server Routing, loading a onBeforeRender() hook on the client-side hasn't any effect (the Server Routing's client runtime never calls it); it unnecessarily bloats client bundle sizes
|
|
301
|
+
(0, utils_js_1.assertUsage)(!(onBeforeRenderEnv.client && !isClientRouting), `Page ${pageConfig.pageId} has an onBeforeRender() hook with env ${picocolors_1.default.cyan(JSON.stringify(onBeforeRenderEnv))} which doesn't make sense because the page is using Server Routing: onBeforeRender() can be run in the client only when using Client Routing.`);
|
|
302
|
+
}
|
|
285
303
|
function interfacefileIsAlreaydLoaded(interfaceFile) {
|
|
286
304
|
const configMapValues = Object.values(interfaceFile.configMap);
|
|
287
305
|
const isAlreadyLoaded = configMapValues.some((conf) => 'configValue' in conf);
|
|
@@ -185,18 +185,16 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
|
|
|
185
185
|
await Promise.all(renderContext.pageConfigs.map((pageConfig) => concurrencyLimit(async () => {
|
|
186
186
|
const hookName = 'onBeforePrerenderStart';
|
|
187
187
|
const pageConfigLoaded = await (0, loadConfigValues_js_1.loadConfigValues)(pageConfig, false);
|
|
188
|
-
const
|
|
189
|
-
if (!
|
|
188
|
+
const hook = (0, getHook_js_1.getHookFromPageConfig)(pageConfigLoaded, hookName);
|
|
189
|
+
if (!hook)
|
|
190
190
|
return;
|
|
191
|
-
const hookFn =
|
|
192
|
-
const hookFilePath = (0, helpers_js_1.getHookFilePathToShowToUser)(configValue);
|
|
193
|
-
(0, utils_js_1.assert)(hookFilePath);
|
|
194
|
-
(0, getHook_js_1.assertHookFn)(hookFn, { hookName, hookFilePath });
|
|
191
|
+
const { hookFn, hookFilePath, hookTimeout } = hook;
|
|
195
192
|
onBeforePrerenderStartHooks.push({
|
|
196
193
|
hookFn,
|
|
197
194
|
hookName: 'onBeforePrerenderStart',
|
|
198
195
|
hookFilePath,
|
|
199
|
-
pageId: pageConfig.pageId
|
|
196
|
+
pageId: pageConfig.pageId,
|
|
197
|
+
hookTimeout
|
|
200
198
|
});
|
|
201
199
|
})));
|
|
202
200
|
// 0.4 design
|
|
@@ -220,14 +218,15 @@ async function callOnBeforePrerenderStartHooks(prerenderContext, renderContext,
|
|
|
220
218
|
hookFn,
|
|
221
219
|
hookName: 'prerender',
|
|
222
220
|
hookFilePath,
|
|
223
|
-
pageId: p.pageId
|
|
221
|
+
pageId: p.pageId,
|
|
222
|
+
hookTimeout: (0, getHook_js_1.getHookTimeoutDefault)('onBeforePrerenderStart')
|
|
224
223
|
});
|
|
225
224
|
})));
|
|
226
|
-
await Promise.all(onBeforePrerenderStartHooks.map(({ hookFn, hookName, hookFilePath, pageId }) => concurrencyLimit(async () => {
|
|
225
|
+
await Promise.all(onBeforePrerenderStartHooks.map(({ hookFn, hookName, hookFilePath, pageId, hookTimeout }) => concurrencyLimit(async () => {
|
|
227
226
|
if (doNotPrerenderList.find((p) => p.pageId === pageId)) {
|
|
228
227
|
return;
|
|
229
228
|
}
|
|
230
|
-
const prerenderResult = await hookFn();
|
|
229
|
+
const prerenderResult = await (0, utils_js_1.executeHook)(() => hookFn(), { hookName, hookFilePath, hookTimeout });
|
|
231
230
|
const result = normalizeOnPrerenderHookResult(prerenderResult, hookFilePath, hookName);
|
|
232
231
|
result.forEach(({ url, pageContext }) => {
|
|
233
232
|
{
|
|
@@ -326,23 +325,21 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
326
325
|
let onPrerenderStartHook;
|
|
327
326
|
// V1 design
|
|
328
327
|
if (renderContext.pageConfigs.length > 0) {
|
|
329
|
-
const
|
|
330
|
-
const
|
|
331
|
-
if (
|
|
332
|
-
|
|
333
|
-
// config.onPrerenderStart isn't a computed nor a cumulative config => definedAt should always be defined
|
|
334
|
-
const hookFilePath = (0, helpers_js_1.getHookFilePathToShowToUser)(configValue);
|
|
335
|
-
(0, utils_js_1.assert)(hookFilePath);
|
|
328
|
+
const hookName = 'onPrerenderStart';
|
|
329
|
+
const hook = (0, getHook_js_1.getHookFromPageConfigGlobal)(renderContext.pageConfigGlobal, hookName);
|
|
330
|
+
if (hook) {
|
|
331
|
+
(0, utils_js_1.assert)(hook.hookName === 'onPrerenderStart');
|
|
336
332
|
onPrerenderStartHook = {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
333
|
+
...hook,
|
|
334
|
+
// Make TypeScript happy
|
|
335
|
+
hookName
|
|
340
336
|
};
|
|
341
337
|
}
|
|
342
338
|
}
|
|
343
339
|
// Old design
|
|
344
340
|
// TODO/v1-release: remove
|
|
345
341
|
if (renderContext.pageConfigs.length === 0) {
|
|
342
|
+
const hookTimeout = (0, getHook_js_1.getHookTimeoutDefault)('onBeforePrerender');
|
|
346
343
|
const pageFilesWithOnBeforePrerenderHook = renderContext.pageFilesAll.filter((p) => {
|
|
347
344
|
assertExportNames(p);
|
|
348
345
|
if (!p.exportNames?.includes('onBeforePrerender'))
|
|
@@ -368,7 +365,8 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
368
365
|
onPrerenderStartHook = {
|
|
369
366
|
hookFn: hook.onBeforePrerender,
|
|
370
367
|
hookFilePath: hook.hookFilePath,
|
|
371
|
-
hookName: 'onBeforePrerender'
|
|
368
|
+
hookName: 'onBeforePrerender',
|
|
369
|
+
hookTimeout
|
|
372
370
|
};
|
|
373
371
|
}
|
|
374
372
|
if (!onPrerenderStartHook) {
|
|
@@ -403,7 +401,7 @@ async function callOnPrerenderStartHook(prerenderContext, renderContext) {
|
|
|
403
401
|
});
|
|
404
402
|
return prerenderContext.pageContexts;
|
|
405
403
|
}
|
|
406
|
-
}),
|
|
404
|
+
}), onPrerenderStartHook);
|
|
407
405
|
if (result === null || result === undefined) {
|
|
408
406
|
return;
|
|
409
407
|
}
|
|
@@ -179,7 +179,7 @@ async function renderTemplate(templateContent, pageContext) {
|
|
|
179
179
|
};
|
|
180
180
|
(0, utils_js_1.assertUsage)(!(0, utils_js_1.isPromise)(templateVar), getErrMsg('a promise', `Did you forget to ${picocolors_1.default.cyan('await')} the promise?`));
|
|
181
181
|
if (templateVar === undefined || templateVar === null) {
|
|
182
|
-
(0, utils_js_1.assertWarning)(false, getErrMsg(`${picocolors_1.default.cyan(String(templateVar))} which will be converted to an empty string`, `Pass
|
|
182
|
+
(0, utils_js_1.assertWarning)(false, getErrMsg(`${picocolors_1.default.cyan(String(templateVar))} which will be converted to an empty string`, `Pass the empty string ${picocolors_1.default.cyan("''")} instead of ${picocolors_1.default.cyan(String(templateVar))} to remove this warning.`), { onlyOnce: false });
|
|
183
183
|
templateVar = '';
|
|
184
184
|
}
|
|
185
185
|
{
|
|
@@ -15,7 +15,7 @@ async function executeOnBeforeRenderHooks(pageContext) {
|
|
|
15
15
|
}
|
|
16
16
|
const onBeforeRender = hook.hookFn;
|
|
17
17
|
(0, preparePageContextForUserConsumptionServerSide_js_1.preparePageContextForUserConsumptionServerSide)(pageContext);
|
|
18
|
-
const hookResult = await (0, utils_js_1.executeHook)(() => onBeforeRender(pageContext),
|
|
18
|
+
const hookResult = await (0, utils_js_1.executeHook)(() => onBeforeRender(pageContext), hook);
|
|
19
19
|
(0, assertOnBeforeRenderHookReturn_js_1.assertOnBeforeRenderHookReturn)(hookResult, hook.hookFilePath);
|
|
20
20
|
const pageContextFromHook = hookResult?.pageContext;
|
|
21
21
|
Object.assign(pageContext, pageContextFromHook);
|
|
@@ -17,7 +17,7 @@ async function executeOnRenderHtmlHook(pageContext) {
|
|
|
17
17
|
const { renderHook, hookFn } = getRenderHook(pageContext);
|
|
18
18
|
(0, utils_js_1.objectAssign)(pageContext, { _renderHook: renderHook });
|
|
19
19
|
(0, preparePageContextForUserConsumptionServerSide_js_1.preparePageContextForUserConsumptionServerSide)(pageContext);
|
|
20
|
-
const hookReturnValue = await (0, utils_js_1.executeHook)(() => hookFn(pageContext), renderHook
|
|
20
|
+
const hookReturnValue = await (0, utils_js_1.executeHook)(() => hookFn(pageContext), renderHook);
|
|
21
21
|
const { documentHtml, pageContextProvidedByRenderHook, pageContextPromise, injectFilter } = processHookReturnValue(hookReturnValue, renderHook);
|
|
22
22
|
Object.assign(pageContext, pageContextProvidedByRenderHook);
|
|
23
23
|
(0, utils_js_1.objectAssign)(pageContext, { _pageContextPromise: pageContextPromise });
|
|
@@ -56,10 +56,10 @@ function getRenderHook(pageContext) {
|
|
|
56
56
|
}
|
|
57
57
|
if (hook) {
|
|
58
58
|
(0, utils_js_1.assert)(hookName);
|
|
59
|
-
const { hookFilePath, hookFn } = hook;
|
|
59
|
+
const { hookFilePath, hookFn, hookTimeout } = hook;
|
|
60
60
|
hookFound = {
|
|
61
61
|
hookFn,
|
|
62
|
-
renderHook: { hookFilePath, hookName }
|
|
62
|
+
renderHook: { hookFn, hookFilePath, hookName, hookTimeout }
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -155,7 +155,7 @@ async function getRenderContext() {
|
|
|
155
155
|
const globalContext = (0, globalContext_js_1.getGlobalContext)();
|
|
156
156
|
const { pageFilesAll, allPageIds, pageConfigs, pageConfigGlobal } = await (0, getPageFiles_js_1.getPageFilesAll)(false, globalContext.isProduction);
|
|
157
157
|
const { pageRoutes, onBeforeRouteHook } = await (0, loadPageRoutes_js_1.loadPageRoutes)(pageFilesAll, pageConfigs, pageConfigGlobal, allPageIds);
|
|
158
|
-
|
|
158
|
+
assertV1Design(pageFilesAll, pageConfigs);
|
|
159
159
|
const renderContext = {
|
|
160
160
|
pageFilesAll: pageFilesAll,
|
|
161
161
|
pageConfigs,
|
|
@@ -167,21 +167,24 @@ async function getRenderContext() {
|
|
|
167
167
|
return renderContext;
|
|
168
168
|
}
|
|
169
169
|
exports.getRenderContext = getRenderContext;
|
|
170
|
-
function
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
170
|
+
function assertV1Design(pageFilesAll, pageConfigs) {
|
|
171
|
+
const isV1Design = pageConfigs.length !== 0;
|
|
172
|
+
const isDesignOld = pageFilesAll.length !== 0;
|
|
173
|
+
if (isV1Design && isDesignOld) {
|
|
174
|
+
const indent = '- ';
|
|
175
|
+
const v1Files = (0, utils_js_1.unique)(pageConfigs
|
|
176
|
+
.map((p) => Object.values(p.configValues)
|
|
177
|
+
.map(helpers_js_1.getConfigValueFilePathToShowToUser)
|
|
178
|
+
.filter(utils_js_1.isNotNullish)
|
|
179
|
+
.map((filePathToShowToUser) => indent + filePathToShowToUser))
|
|
180
|
+
.flat(2));
|
|
181
|
+
(0, utils_js_1.assertUsage)(false, [
|
|
182
|
+
'Mixing the new V1 design with the old V0.4 design is forbidden.',
|
|
183
|
+
'V1 files:',
|
|
184
|
+
...v1Files,
|
|
185
|
+
'V0.4 files:',
|
|
186
|
+
...pageFilesAll.map((p) => indent + p.filePath)
|
|
187
|
+
].join('\n'));
|
|
188
|
+
}
|
|
189
|
+
(0, utils_js_1.assertWarning)(!isDesignOld, 'You are using the old deprecated design, update to the new V1 design, see https://vike.dev/migration/v1-design', { onlyOnce: true });
|
|
187
190
|
}
|
|
@@ -5,7 +5,7 @@ const utils_js_1 = require("../utils.js");
|
|
|
5
5
|
const assert_exports_old_design_js_1 = require("./assert_exports_old_design.js");
|
|
6
6
|
const getPageFileObject_js_1 = require("./getPageFileObject.js");
|
|
7
7
|
const fileTypes_js_1 = require("./fileTypes.js");
|
|
8
|
-
const
|
|
8
|
+
const assertPageConfigsSerialized_js_1 = require("../page-configs/serialize/assertPageConfigsSerialized.js");
|
|
9
9
|
const parsePageConfigs_js_1 = require("../page-configs/serialize/parsePageConfigs.js");
|
|
10
10
|
function parseGlobResults(pageFilesExports) {
|
|
11
11
|
(0, utils_js_1.assert)((0, utils_js_1.hasProp)(pageFilesExports, 'isGeneratedFile'));
|
|
@@ -21,8 +21,8 @@ function parseGlobResults(pageFilesExports) {
|
|
|
21
21
|
(0, utils_js_1.assert)((0, utils_js_1.hasProp)(pageFilesExports, 'pageConfigsSerialized'));
|
|
22
22
|
(0, utils_js_1.assert)((0, utils_js_1.hasProp)(pageFilesExports, 'pageConfigGlobalSerialized'));
|
|
23
23
|
const { pageConfigsSerialized, pageConfigGlobalSerialized } = pageFilesExports;
|
|
24
|
-
(0,
|
|
25
|
-
(0,
|
|
24
|
+
(0, assertPageConfigsSerialized_js_1.assertPageConfigsSerialized)(pageConfigsSerialized);
|
|
25
|
+
(0, assertPageConfigsSerialized_js_1.assertPageConfigGlobalSerialized)(pageConfigGlobalSerialized);
|
|
26
26
|
const { pageConfigs, pageConfigGlobal } = (0, parsePageConfigs_js_1.parsePageConfigs)(pageConfigsSerialized, pageConfigGlobalSerialized);
|
|
27
27
|
const pageFilesMap = {};
|
|
28
28
|
parseGlobResult(pageFilesExports.pageFilesLazy).forEach(({ filePath, pageFile, globValue }) => {
|
|
@@ -14,8 +14,8 @@ function isUserHookError(err) {
|
|
|
14
14
|
return globalObject.userHookErrors.get(err) ?? false;
|
|
15
15
|
}
|
|
16
16
|
exports.isUserHookError = isUserHookError;
|
|
17
|
-
function executeHook(
|
|
18
|
-
const { timeoutErr, timeoutWarn } =
|
|
17
|
+
function executeHook(hookFnCaller, hook) {
|
|
18
|
+
const { hookName, hookFilePath, hookTimeout: { error: timeoutErr, warning: timeoutWarn } } = hook;
|
|
19
19
|
let resolve;
|
|
20
20
|
let reject;
|
|
21
21
|
const promise = new Promise((resolve_, reject_) => {
|
|
@@ -29,19 +29,23 @@ function executeHook(hookFn, hookName, hookFilePath) {
|
|
|
29
29
|
};
|
|
30
30
|
});
|
|
31
31
|
const clearTimeouts = () => {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
if (currentTimeoutWarn)
|
|
33
|
+
clearTimeout(currentTimeoutWarn);
|
|
34
|
+
if (currentTimeoutErr)
|
|
35
|
+
clearTimeout(currentTimeoutErr);
|
|
34
36
|
};
|
|
35
|
-
const
|
|
36
|
-
(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const currentTimeoutWarn = isNotDisabled(timeoutWarn) &&
|
|
38
|
+
setTimeout(() => {
|
|
39
|
+
(0, assert_js_1.assertWarning)(false, `The ${hookName}() hook defined by ${hookFilePath} is slow: it's taking more than ${(0, humanizeTime_js_1.humanizeTime)(timeoutWarn)} (https://vike.dev/hooksTimeout)`, { onlyOnce: false });
|
|
40
|
+
}, timeoutWarn);
|
|
41
|
+
const currentTimeoutErr = isNotDisabled(timeoutErr) &&
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
const err = (0, assert_js_1.getProjectError)(`The ${hookName}() hook defined by ${hookFilePath} timed out: it didn't finish after ${(0, humanizeTime_js_1.humanizeTime)(timeoutErr)} (https://vike.dev/hooksTimeout)`);
|
|
44
|
+
reject(err);
|
|
45
|
+
}, timeoutErr);
|
|
42
46
|
(async () => {
|
|
43
47
|
try {
|
|
44
|
-
const ret = await
|
|
48
|
+
const ret = await hookFnCaller();
|
|
45
49
|
resolve(ret);
|
|
46
50
|
}
|
|
47
51
|
catch (err) {
|
|
@@ -54,21 +58,6 @@ function executeHook(hookFn, hookName, hookFilePath) {
|
|
|
54
58
|
return promise;
|
|
55
59
|
}
|
|
56
60
|
exports.executeHook = executeHook;
|
|
57
|
-
function
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
timeoutErr: 5 * 1000,
|
|
61
|
-
timeoutWarn: 1 * 1000
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
if (hookName === 'onBeforePrerender') {
|
|
65
|
-
return {
|
|
66
|
-
timeoutErr: 10 * 60 * 1000,
|
|
67
|
-
timeoutWarn: 30 * 1000
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
return {
|
|
71
|
-
timeoutErr: 40 * 1000,
|
|
72
|
-
timeoutWarn: 4 * 1000
|
|
73
|
-
};
|
|
61
|
+
function isNotDisabled(timeout) {
|
|
62
|
+
return !!timeout && timeout !== Infinity;
|
|
74
63
|
}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
6
|
+
exports.getHookTimeoutDefault = exports.assertHook = exports.getHookFromPageConfigGlobal = exports.getHookFromPageConfig = exports.getHook = void 0;
|
|
7
|
+
const helpers_js_1 = require("../page-configs/helpers.js");
|
|
4
8
|
const utils_js_1 = require("../utils.js");
|
|
9
|
+
const picocolors_1 = __importDefault(require("@brillout/picocolors"));
|
|
5
10
|
function getHook(pageContext, hookName) {
|
|
6
11
|
if (!(hookName in pageContext.exports)) {
|
|
7
12
|
return null;
|
|
8
13
|
}
|
|
14
|
+
const { hooksTimeout } = pageContext.config;
|
|
15
|
+
const hookTimeout = getHookTimeout(hooksTimeout, hookName);
|
|
9
16
|
const hookFn = pageContext.exports[hookName];
|
|
10
17
|
const file = pageContext.exportsAll[hookName][0];
|
|
11
18
|
(0, utils_js_1.assert)(file.exportValue === hookFn);
|
|
@@ -15,9 +22,41 @@ function getHook(pageContext, hookName) {
|
|
|
15
22
|
(0, utils_js_1.assert)(hookFilePath);
|
|
16
23
|
(0, utils_js_1.assert)(!hookFilePath.endsWith(' '));
|
|
17
24
|
assertHookFn(hookFn, { hookName, hookFilePath });
|
|
18
|
-
return { hookFn, hookName, hookFilePath };
|
|
25
|
+
return { hookFn, hookName, hookFilePath, hookTimeout };
|
|
19
26
|
}
|
|
20
27
|
exports.getHook = getHook;
|
|
28
|
+
function getHookFromPageConfig(pageConfig, hookName) {
|
|
29
|
+
const configValue = (0, helpers_js_1.getConfigValue)(pageConfig, hookName);
|
|
30
|
+
const hooksTimeout = (0, helpers_js_1.getConfigValue)(pageConfig, 'hooksTimeout')?.value;
|
|
31
|
+
if (!configValue)
|
|
32
|
+
return null;
|
|
33
|
+
const hookFn = configValue.value;
|
|
34
|
+
if (!hookFn)
|
|
35
|
+
return null;
|
|
36
|
+
const hookFilePath = (0, helpers_js_1.getHookFilePathToShowToUser)(configValue);
|
|
37
|
+
// hook isn't a computed nor a cumulative config => definedAt should always be defined
|
|
38
|
+
(0, utils_js_1.assert)(hookFilePath);
|
|
39
|
+
assertHookFn(hookFn, { hookName, hookFilePath });
|
|
40
|
+
const hookTimeout = getHookTimeout(hooksTimeout, hookName);
|
|
41
|
+
return { hookFn, hookName, hookFilePath, hookTimeout };
|
|
42
|
+
}
|
|
43
|
+
exports.getHookFromPageConfig = getHookFromPageConfig;
|
|
44
|
+
function getHookFromPageConfigGlobal(pageConfigGlobal, hookName) {
|
|
45
|
+
const configValue = pageConfigGlobal.configValues[hookName];
|
|
46
|
+
if (!configValue)
|
|
47
|
+
return null;
|
|
48
|
+
const hookFn = configValue.value;
|
|
49
|
+
if (!hookFn)
|
|
50
|
+
return null;
|
|
51
|
+
const hookFilePath = (0, helpers_js_1.getHookFilePathToShowToUser)(configValue);
|
|
52
|
+
// hook isn't a computed nor a cumulative config => definedAt should always be defined
|
|
53
|
+
(0, utils_js_1.assert)(hookFilePath);
|
|
54
|
+
assertHookFn(hookFn, { hookName, hookFilePath });
|
|
55
|
+
// We could use the global value of config.hooksTimeout but it requires some non-trivial refactoring
|
|
56
|
+
const hookTimeout = getHookTimeoutDefault(hookName);
|
|
57
|
+
return { hookFn, hookName, hookFilePath, hookTimeout };
|
|
58
|
+
}
|
|
59
|
+
exports.getHookFromPageConfigGlobal = getHookFromPageConfigGlobal;
|
|
21
60
|
function assertHook(pageContext, hookName) {
|
|
22
61
|
getHook(pageContext, hookName);
|
|
23
62
|
}
|
|
@@ -28,4 +67,66 @@ function assertHookFn(hookFn, { hookName, hookFilePath }) {
|
|
|
28
67
|
(0, utils_js_1.assertUsage)((0, utils_js_1.isCallable)(hookFn), `Hook ${hookName}() defined by ${hookFilePath} should be a function`);
|
|
29
68
|
(0, utils_js_1.checkType)(hookFn);
|
|
30
69
|
}
|
|
31
|
-
|
|
70
|
+
function getHookTimeout(hooksTimeoutProvidedByUser, hookName) {
|
|
71
|
+
const hooksTimeoutProvidedbyUserNormalized = getHooksTimeoutProvidedByUserNormalized(hooksTimeoutProvidedByUser);
|
|
72
|
+
if (hooksTimeoutProvidedbyUserNormalized === false)
|
|
73
|
+
return { error: false, warning: false };
|
|
74
|
+
const providedbyUser = hooksTimeoutProvidedbyUserNormalized[hookName];
|
|
75
|
+
const hookTimeout = getHookTimeoutDefault(hookName);
|
|
76
|
+
if (providedbyUser?.error !== undefined)
|
|
77
|
+
hookTimeout.error = providedbyUser.error;
|
|
78
|
+
if (providedbyUser?.warning !== undefined)
|
|
79
|
+
hookTimeout.warning = providedbyUser.warning;
|
|
80
|
+
return hookTimeout;
|
|
81
|
+
}
|
|
82
|
+
// Ideally this should be called only once and at build-time (to avoid bloating the client-side bundle), but we didn't implement any mechanism to valide config values at build-time yet
|
|
83
|
+
function getHooksTimeoutProvidedByUserNormalized(hooksTimeoutProvidedByUser) {
|
|
84
|
+
if (hooksTimeoutProvidedByUser === undefined)
|
|
85
|
+
return {};
|
|
86
|
+
if (hooksTimeoutProvidedByUser === false)
|
|
87
|
+
return false;
|
|
88
|
+
(0, utils_js_1.assertUsage)((0, utils_js_1.isObject)(hooksTimeoutProvidedByUser), `Setting ${picocolors_1.default.cyan('hooksTimeout')} should be ${picocolors_1.default.cyan('false')} or an object`);
|
|
89
|
+
const hooksTimeoutProvidedByUserNormalized = {};
|
|
90
|
+
Object.entries(hooksTimeoutProvidedByUser).forEach(([hookName, hookTimeoutProvidedbyUser]) => {
|
|
91
|
+
if (hookTimeoutProvidedbyUser === false) {
|
|
92
|
+
hooksTimeoutProvidedByUserNormalized[hookName] = { error: false, warning: false };
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
(0, utils_js_1.assertUsage)((0, utils_js_1.isObject)(hookTimeoutProvidedbyUser), `Setting ${picocolors_1.default.cyan(`hooksTimeout.${hookName}`)} should be ${picocolors_1.default.cyan('false')} or an object`);
|
|
96
|
+
const [error, warning] = ['error', 'warning'].map((timeoutName) => {
|
|
97
|
+
const timeoutVal = hookTimeoutProvidedbyUser[timeoutName];
|
|
98
|
+
if (timeoutVal === undefined || timeoutVal === false)
|
|
99
|
+
return timeoutVal;
|
|
100
|
+
const errPrefix = `Setting ${picocolors_1.default.cyan(`hooksTimeout.${hookName}.${timeoutName}`)} should be`;
|
|
101
|
+
(0, utils_js_1.assertUsage)(typeof timeoutVal === 'number', `${errPrefix} ${picocolors_1.default.cyan('false')} or a number`);
|
|
102
|
+
(0, utils_js_1.assertUsage)(timeoutVal > 0, `${errPrefix} a positive number`);
|
|
103
|
+
return timeoutVal;
|
|
104
|
+
});
|
|
105
|
+
hooksTimeoutProvidedByUserNormalized[hookName] = { error, warning };
|
|
106
|
+
});
|
|
107
|
+
return hooksTimeoutProvidedByUserNormalized;
|
|
108
|
+
}
|
|
109
|
+
function getHookTimeoutDefault(hookName) {
|
|
110
|
+
if (hookName === 'onBeforeRoute') {
|
|
111
|
+
return {
|
|
112
|
+
error: 5 * 1000,
|
|
113
|
+
warning: 1 * 1000
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (hookName === 'onPrerenderStart' ||
|
|
117
|
+
hookName === 'onBeforePrerenderStart' ||
|
|
118
|
+
// TODO/v1-release: remove
|
|
119
|
+
// Old V0.4 design hooks (https://vike.dev/migration/v1-design#renamed-hooks)
|
|
120
|
+
hookName === 'onBeforePrerender' ||
|
|
121
|
+
hookName === 'prerender') {
|
|
122
|
+
return {
|
|
123
|
+
error: 10 * 60 * 1000,
|
|
124
|
+
warning: 30 * 1000
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
error: 30 * 1000,
|
|
129
|
+
warning: 4 * 1000
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
exports.getHookTimeoutDefault = getHookTimeoutDefault;
|
|
@@ -10,7 +10,7 @@ const getExportPath_js_1 = require("../getExportPath.js");
|
|
|
10
10
|
function getConfigDefinedAtString(sentenceBegin, configName, { definedAt }) {
|
|
11
11
|
const definedAtString = getDefinedAtString(definedAt, configName);
|
|
12
12
|
const definedAtStr = definedAtString === 'internally' ? definedAtString : `at ${definedAtString}`;
|
|
13
|
-
let configNameStr = `${configName}${sentenceBegin === 'Hook' ? '()'
|
|
13
|
+
let configNameStr = `${configName}${ /*sentenceBegin === 'Hook' ? '()' :*/''}`;
|
|
14
14
|
const configDefinedAt = `${sentenceBegin} ${picocolors_1.default.cyan(configNameStr)} defined ${definedAtStr}`;
|
|
15
15
|
return configDefinedAt;
|
|
16
16
|
}
|
|
@@ -21,7 +21,7 @@ async function executeGuardHook(pageContext, prepareForUserConsumption) {
|
|
|
21
21
|
const res = prepareForUserConsumption(pageContext);
|
|
22
22
|
if (res)
|
|
23
23
|
pageContextForUserConsumption = res;
|
|
24
|
-
const hookResult = await (0, utils_js_1.executeHook)(() => guard(pageContextForUserConsumption),
|
|
24
|
+
const hookResult = await (0, utils_js_1.executeHook)(() => guard(pageContextForUserConsumption), hook);
|
|
25
25
|
(0, utils_js_1.assertUsage)(hookResult === undefined, `The guard() hook of ${hook.hookFilePath} returns a value, but guard() doesn't accept any return value`);
|
|
26
26
|
}
|
|
27
27
|
exports.executeGuardHook = executeGuardHook;
|
|
@@ -35,6 +35,7 @@ function findPageGuard(pageId, pageFilesAll) {
|
|
|
35
35
|
if (!hookFn)
|
|
36
36
|
return null;
|
|
37
37
|
const hookFilePath = filePath;
|
|
38
|
+
const hookTimeout = (0, getHook_js_1.getHookTimeoutDefault)('guard');
|
|
38
39
|
(0, utils_js_1.assertUsage)((0, utils_js_1.isCallable)(hookFn), `guard() defined by ${hookFilePath} should be a function`);
|
|
39
|
-
return { hookFn, hookName: 'guard', hookFilePath };
|
|
40
|
+
return { hookFn, hookName: 'guard', hookFilePath, hookTimeout };
|
|
40
41
|
}
|
|
@@ -12,7 +12,7 @@ async function executeOnBeforeRouteHook(pageContext) {
|
|
|
12
12
|
const pageContextFromOnBeforeRouteHook = {};
|
|
13
13
|
if (!pageContext._onBeforeRouteHook)
|
|
14
14
|
return null;
|
|
15
|
-
const pageContextFromHook = await
|
|
15
|
+
const pageContextFromHook = await getPageContextFromHook(pageContext._onBeforeRouteHook, pageContext);
|
|
16
16
|
if (pageContextFromHook) {
|
|
17
17
|
(0, utils_js_1.objectAssign)(pageContextFromOnBeforeRouteHook, pageContextFromHook);
|
|
18
18
|
if ((0, utils_js_1.hasProp)(pageContextFromOnBeforeRouteHook, '_pageId', 'string') ||
|
|
@@ -37,11 +37,11 @@ async function executeOnBeforeRouteHook(pageContext) {
|
|
|
37
37
|
return pageContextFromOnBeforeRouteHook;
|
|
38
38
|
}
|
|
39
39
|
exports.executeOnBeforeRouteHook = executeOnBeforeRouteHook;
|
|
40
|
-
async function
|
|
41
|
-
let hookReturn = onBeforeRouteHook.
|
|
40
|
+
async function getPageContextFromHook(onBeforeRouteHook, pageContext) {
|
|
41
|
+
let hookReturn = onBeforeRouteHook.hookFn(pageContext);
|
|
42
42
|
(0, resolveRouteFunction_js_1.assertSyncRouting)(hookReturn, `The onBeforeRoute() hook ${onBeforeRouteHook.hookFilePath}`);
|
|
43
43
|
// TODO/v1-release: make executeOnBeforeRouteHook() and route() sync
|
|
44
|
-
hookReturn = await hookReturn;
|
|
44
|
+
hookReturn = await (0, utils_js_1.executeHook)(() => hookReturn, onBeforeRouteHook);
|
|
45
45
|
const errPrefix = `The onBeforeRoute() hook defined by ${onBeforeRouteHook.hookFilePath}`;
|
|
46
46
|
(0, utils_js_1.assertUsage)(hookReturn === null ||
|
|
47
47
|
hookReturn === undefined ||
|