@tramvai/module-router 2.70.0 → 2.72.0
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/lib/components/link.browser.js +55 -0
- package/lib/components/link.es.js +49 -0
- package/lib/components/link.js +53 -0
- package/lib/hooks/usePageService.browser.js +10 -0
- package/lib/hooks/usePageService.es.js +10 -0
- package/lib/hooks/usePageService.js +14 -0
- package/lib/hooks/usePrefetch.browser.browser.js +42 -0
- package/lib/index.browser.js +7 -906
- package/lib/index.es.js +6 -764
- package/lib/index.js +34 -788
- package/lib/modules/child-app.browser.js +31 -0
- package/lib/modules/child-app.es.js +31 -0
- package/lib/modules/child-app.js +33 -0
- package/lib/modules/clientCommon.browser.js +70 -0
- package/lib/modules/common.browser.js +137 -0
- package/lib/modules/common.es.js +137 -0
- package/lib/modules/common.js +145 -0
- package/lib/modules/fileSystemPages.browser.js +27 -0
- package/lib/modules/fileSystemPages.es.js +27 -0
- package/lib/modules/fileSystemPages.js +31 -0
- package/lib/modules/guards/common/index.browser.js +32 -0
- package/lib/modules/guards/common/index.es.js +32 -0
- package/lib/modules/guards/common/index.js +36 -0
- package/lib/modules/guards/common/internalError.browser.js +14 -0
- package/lib/modules/guards/common/internalError.es.js +14 -0
- package/lib/modules/guards/common/internalError.js +18 -0
- package/lib/modules/guards/common/loadBundle.browser.js +67 -0
- package/lib/modules/guards/common/loadBundle.es.js +67 -0
- package/lib/modules/guards/common/loadBundle.js +75 -0
- package/lib/modules/guards/server/httpMethod.es.js +20 -0
- package/lib/modules/guards/server/httpMethod.js +24 -0
- package/lib/modules/guards/server/index.es.js +18 -0
- package/lib/modules/guards/server/index.js +22 -0
- package/lib/modules/hooks/common/fillRouterStore.browser.js +9 -0
- package/lib/modules/hooks/common/fillRouterStore.es.js +9 -0
- package/lib/modules/hooks/common/fillRouterStore.js +13 -0
- package/lib/modules/hooks/common/index.browser.js +16 -0
- package/lib/modules/hooks/common/index.es.js +16 -0
- package/lib/modules/hooks/common/index.js +20 -0
- package/lib/modules/hooks/runActions.browser.js +34 -0
- package/lib/modules/hooks/runActions.es.js +34 -0
- package/lib/modules/hooks/runActions.js +42 -0
- package/lib/modules/hooks/server/httpStatus.es.js +7 -0
- package/lib/modules/hooks/server/httpStatus.js +11 -0
- package/lib/modules/hooks/server/index.es.js +17 -0
- package/lib/modules/hooks/server/index.js +21 -0
- package/lib/modules/hooks/spa/index.browser.js +70 -0
- package/lib/modules/hooks/spa/runCommands.browser.js +12 -0
- package/lib/modules/no-spa.browser.js +21 -0
- package/lib/modules/server.es.js +59 -0
- package/lib/modules/server.js +63 -0
- package/lib/modules/spa.browser.js +23 -0
- package/lib/modules/tokens/browser/index.browser.js +5 -0
- package/lib/modules/tokens/browser/prefetch.browser.js +112 -0
- package/lib/modules/tokens/common/index.browser.js +40 -0
- package/lib/modules/tokens/common/index.es.js +40 -0
- package/lib/modules/tokens/common/index.js +44 -0
- package/lib/modules/tokens/common/render.browser.js +14 -0
- package/lib/modules/tokens/common/render.es.js +14 -0
- package/lib/modules/tokens/common/render.js +18 -0
- package/lib/modules/tokens/common/routeNormalize.browser.js +10 -0
- package/lib/modules/tokens/common/routeNormalize.es.js +10 -0
- package/lib/modules/tokens/common/routeNormalize.js +18 -0
- package/lib/modules/tokens/common/routeSetDefaults.browser.js +13 -0
- package/lib/modules/tokens/common/routeSetDefaults.es.js +13 -0
- package/lib/modules/tokens/common/routeSetDefaults.js +17 -0
- package/lib/modules/tokens/common/routeTransform.browser.js +12 -0
- package/lib/modules/tokens/common/routeTransform.es.js +12 -0
- package/lib/modules/tokens/common/routeTransform.js +22 -0
- package/lib/modules/tokens/server/bundleInfo.es.js +35 -0
- package/lib/modules/tokens/server/bundleInfo.js +44 -0
- package/lib/modules/tokens/server/index.es.js +25 -0
- package/lib/modules/tokens/server/index.js +29 -0
- package/lib/modules/tokens/server/prefetch.es.js +15 -0
- package/lib/modules/tokens/server/prefetch.js +19 -0
- package/lib/modules/tokens/server/routerOptions.es.js +37 -0
- package/lib/modules/tokens/server/routerOptions.js +41 -0
- package/lib/modules/tokens.browser.js +22 -0
- package/lib/modules/tokens.es.js +22 -0
- package/lib/modules/tokens.js +35 -0
- package/lib/modules/utils/forRoot.browser.js +22 -0
- package/lib/modules/utils/forRoot.es.js +22 -0
- package/lib/modules/utils/forRoot.js +26 -0
- package/lib/services/page.browser.js +63 -0
- package/lib/services/page.es.js +63 -0
- package/lib/services/page.js +67 -0
- package/lib/stores/RouterStore.browser.js +29 -0
- package/lib/stores/RouterStore.es.js +29 -0
- package/lib/stores/RouterStore.js +35 -0
- package/lib/utils/requestIdleCallback.browser.js +10 -0
- package/package.json +22 -23
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { LOGGER_TOKEN, BUNDLE_MANAGER_TOKEN, ACTION_REGISTRY_TOKEN, RESPONSE_MANAGER_TOKEN, DISPATCHER_TOKEN, DISPATCHER_CONTEXT_TOKEN } from '@tramvai/tokens-common';
|
|
2
|
+
import { ROUTER_GUARD_TOKEN, PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
|
|
3
|
+
import { loadBundle } from './loadBundle.browser.js';
|
|
4
|
+
import { internalError } from './internalError.browser.js';
|
|
5
|
+
|
|
6
|
+
const commonGuards = [
|
|
7
|
+
{
|
|
8
|
+
provide: ROUTER_GUARD_TOKEN,
|
|
9
|
+
multi: true,
|
|
10
|
+
useFactory: loadBundle,
|
|
11
|
+
deps: {
|
|
12
|
+
logger: LOGGER_TOKEN,
|
|
13
|
+
bundleManager: BUNDLE_MANAGER_TOKEN,
|
|
14
|
+
actionRegistry: ACTION_REGISTRY_TOKEN,
|
|
15
|
+
responseManager: RESPONSE_MANAGER_TOKEN,
|
|
16
|
+
dispatcher: DISPATCHER_TOKEN,
|
|
17
|
+
dispatcherContext: DISPATCHER_CONTEXT_TOKEN,
|
|
18
|
+
pageService: PAGE_SERVICE_TOKEN,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
provide: ROUTER_GUARD_TOKEN,
|
|
23
|
+
multi: true,
|
|
24
|
+
useFactory: internalError,
|
|
25
|
+
deps: {
|
|
26
|
+
logger: LOGGER_TOKEN,
|
|
27
|
+
responseManager: RESPONSE_MANAGER_TOKEN,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
export { commonGuards };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { LOGGER_TOKEN, BUNDLE_MANAGER_TOKEN, ACTION_REGISTRY_TOKEN, RESPONSE_MANAGER_TOKEN, DISPATCHER_TOKEN, DISPATCHER_CONTEXT_TOKEN } from '@tramvai/tokens-common';
|
|
2
|
+
import { ROUTER_GUARD_TOKEN, PAGE_SERVICE_TOKEN } from '@tramvai/tokens-router';
|
|
3
|
+
import { loadBundle } from './loadBundle.es.js';
|
|
4
|
+
import { internalError } from './internalError.es.js';
|
|
5
|
+
|
|
6
|
+
const commonGuards = [
|
|
7
|
+
{
|
|
8
|
+
provide: ROUTER_GUARD_TOKEN,
|
|
9
|
+
multi: true,
|
|
10
|
+
useFactory: loadBundle,
|
|
11
|
+
deps: {
|
|
12
|
+
logger: LOGGER_TOKEN,
|
|
13
|
+
bundleManager: BUNDLE_MANAGER_TOKEN,
|
|
14
|
+
actionRegistry: ACTION_REGISTRY_TOKEN,
|
|
15
|
+
responseManager: RESPONSE_MANAGER_TOKEN,
|
|
16
|
+
dispatcher: DISPATCHER_TOKEN,
|
|
17
|
+
dispatcherContext: DISPATCHER_CONTEXT_TOKEN,
|
|
18
|
+
pageService: PAGE_SERVICE_TOKEN,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
provide: ROUTER_GUARD_TOKEN,
|
|
23
|
+
multi: true,
|
|
24
|
+
useFactory: internalError,
|
|
25
|
+
deps: {
|
|
26
|
+
logger: LOGGER_TOKEN,
|
|
27
|
+
responseManager: RESPONSE_MANAGER_TOKEN,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
export { commonGuards };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
6
|
+
var tokensRouter = require('@tramvai/tokens-router');
|
|
7
|
+
var loadBundle = require('./loadBundle.js');
|
|
8
|
+
var internalError = require('./internalError.js');
|
|
9
|
+
|
|
10
|
+
const commonGuards = [
|
|
11
|
+
{
|
|
12
|
+
provide: tokensRouter.ROUTER_GUARD_TOKEN,
|
|
13
|
+
multi: true,
|
|
14
|
+
useFactory: loadBundle.loadBundle,
|
|
15
|
+
deps: {
|
|
16
|
+
logger: tokensCommon.LOGGER_TOKEN,
|
|
17
|
+
bundleManager: tokensCommon.BUNDLE_MANAGER_TOKEN,
|
|
18
|
+
actionRegistry: tokensCommon.ACTION_REGISTRY_TOKEN,
|
|
19
|
+
responseManager: tokensCommon.RESPONSE_MANAGER_TOKEN,
|
|
20
|
+
dispatcher: tokensCommon.DISPATCHER_TOKEN,
|
|
21
|
+
dispatcherContext: tokensCommon.DISPATCHER_CONTEXT_TOKEN,
|
|
22
|
+
pageService: tokensRouter.PAGE_SERVICE_TOKEN,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
provide: tokensRouter.ROUTER_GUARD_TOKEN,
|
|
27
|
+
multi: true,
|
|
28
|
+
useFactory: internalError.internalError,
|
|
29
|
+
deps: {
|
|
30
|
+
logger: tokensCommon.LOGGER_TOKEN,
|
|
31
|
+
responseManager: tokensCommon.RESPONSE_MANAGER_TOKEN,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
exports.commonGuards = commonGuards;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const internalError = ({ responseManager, logger, }) => {
|
|
2
|
+
const log = logger('route:guard-check-error');
|
|
3
|
+
return async () => {
|
|
4
|
+
if (responseManager.getStatus() >= 500) {
|
|
5
|
+
log.error({
|
|
6
|
+
event: 'status-is-error',
|
|
7
|
+
status: responseManager.getStatus(),
|
|
8
|
+
});
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { internalError };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const internalError = ({ responseManager, logger, }) => {
|
|
2
|
+
const log = logger('route:guard-check-error');
|
|
3
|
+
return async () => {
|
|
4
|
+
if (responseManager.getStatus() >= 500) {
|
|
5
|
+
log.error({
|
|
6
|
+
event: 'status-is-error',
|
|
7
|
+
status: responseManager.getStatus(),
|
|
8
|
+
});
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { internalError };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const internalError = ({ responseManager, logger, }) => {
|
|
6
|
+
const log = logger('route:guard-check-error');
|
|
7
|
+
return async () => {
|
|
8
|
+
if (responseManager.getStatus() >= 500) {
|
|
9
|
+
log.error({
|
|
10
|
+
event: 'status-is-error',
|
|
11
|
+
status: responseManager.getStatus(),
|
|
12
|
+
});
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
exports.internalError = internalError;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import isArray from '@tinkoff/utils/is/array';
|
|
2
|
+
import { resolveLazyComponent } from '@tramvai/react';
|
|
3
|
+
|
|
4
|
+
const loadBundle = ({ bundleManager, logger, actionRegistry, responseManager, dispatcher, dispatcherContext, pageService, }) => {
|
|
5
|
+
const log = logger('route:load-bundles');
|
|
6
|
+
return async ({ to }) => {
|
|
7
|
+
var _a;
|
|
8
|
+
log.debug({
|
|
9
|
+
event: 'load-bundle',
|
|
10
|
+
route: to,
|
|
11
|
+
});
|
|
12
|
+
const { bundle, pageComponent, nestedLayoutComponent } = to.config;
|
|
13
|
+
if (!bundleManager.has(bundle, pageComponent)) {
|
|
14
|
+
log.info({
|
|
15
|
+
event: 'load-bundle-not-found',
|
|
16
|
+
bundle,
|
|
17
|
+
pageComponent,
|
|
18
|
+
});
|
|
19
|
+
// если бандл не найден, то всё ок и мы должны вернуть 404 на сервере,
|
|
20
|
+
// а на клиенте просто загрузить новую страницу
|
|
21
|
+
responseManager.setStatus(404);
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
// Пытаемся загрузить и в случае инициализации на клиенте, т.к.
|
|
25
|
+
// несмотря на наличие бандла в разметке, все равно мы должны дождаться
|
|
26
|
+
// его загрузки перед рендером
|
|
27
|
+
try {
|
|
28
|
+
const promises = [];
|
|
29
|
+
// for file-system pages bundle is virtual, so it will be loaded in parallel with nested layout
|
|
30
|
+
// for classic bundles, page component will be loaded after bundle loading
|
|
31
|
+
promises.push(bundleManager.get(bundle, pageComponent));
|
|
32
|
+
if (nestedLayoutComponent) {
|
|
33
|
+
promises.push(resolveLazyComponent(pageService.resolveComponentFromConfig('nestedLayout')));
|
|
34
|
+
}
|
|
35
|
+
const [resolvedBundle, resolvedLayout] = await Promise.all(promises);
|
|
36
|
+
const { components, reducers } = resolvedBundle;
|
|
37
|
+
const component = components[pageComponent];
|
|
38
|
+
// pageComponent should have required fields even if it is lazy,
|
|
39
|
+
// thanks to `git log 9466cb32bfb71ba49144ef839d3d5bce246e213c -L90,103:packages/modules/common/src/bundleManager/bundleManager.ts`
|
|
40
|
+
(_a = component === null || component === void 0 ? void 0 : component.reducers) === null || _a === void 0 ? void 0 : _a.forEach((reducer) => dispatcherContext.getStore(reducer));
|
|
41
|
+
reducers === null || reducers === void 0 ? void 0 : reducers.forEach((reducer) => dispatcherContext.getStore(reducer));
|
|
42
|
+
// @todo: reuse logic from bundleManager?
|
|
43
|
+
// register nested layout actions and reducers for current page
|
|
44
|
+
if (resolvedLayout) {
|
|
45
|
+
if ('actions' in resolvedLayout && isArray(resolvedLayout.actions)) {
|
|
46
|
+
actionRegistry.add(pageComponent, resolvedLayout.actions);
|
|
47
|
+
}
|
|
48
|
+
if ('reducers' in resolvedLayout && isArray(resolvedLayout.reducers)) {
|
|
49
|
+
resolvedLayout.reducers.forEach((reducer) => {
|
|
50
|
+
dispatcher.registerStore(reducer);
|
|
51
|
+
dispatcherContext.getStore(reducer);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
log.error({
|
|
58
|
+
event: 'load-bundle-failed',
|
|
59
|
+
error,
|
|
60
|
+
});
|
|
61
|
+
// блокируем переход если не удалось загрузить бандл
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export { loadBundle };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import isArray from '@tinkoff/utils/is/array';
|
|
2
|
+
import { resolveLazyComponent } from '@tramvai/react';
|
|
3
|
+
|
|
4
|
+
const loadBundle = ({ bundleManager, logger, actionRegistry, responseManager, dispatcher, dispatcherContext, pageService, }) => {
|
|
5
|
+
const log = logger('route:load-bundles');
|
|
6
|
+
return async ({ to }) => {
|
|
7
|
+
var _a;
|
|
8
|
+
log.debug({
|
|
9
|
+
event: 'load-bundle',
|
|
10
|
+
route: to,
|
|
11
|
+
});
|
|
12
|
+
const { bundle, pageComponent, nestedLayoutComponent } = to.config;
|
|
13
|
+
if (!bundleManager.has(bundle, pageComponent)) {
|
|
14
|
+
log.info({
|
|
15
|
+
event: 'load-bundle-not-found',
|
|
16
|
+
bundle,
|
|
17
|
+
pageComponent,
|
|
18
|
+
});
|
|
19
|
+
// если бандл не найден, то всё ок и мы должны вернуть 404 на сервере,
|
|
20
|
+
// а на клиенте просто загрузить новую страницу
|
|
21
|
+
responseManager.setStatus(404);
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
// Пытаемся загрузить и в случае инициализации на клиенте, т.к.
|
|
25
|
+
// несмотря на наличие бандла в разметке, все равно мы должны дождаться
|
|
26
|
+
// его загрузки перед рендером
|
|
27
|
+
try {
|
|
28
|
+
const promises = [];
|
|
29
|
+
// for file-system pages bundle is virtual, so it will be loaded in parallel with nested layout
|
|
30
|
+
// for classic bundles, page component will be loaded after bundle loading
|
|
31
|
+
promises.push(bundleManager.get(bundle, pageComponent));
|
|
32
|
+
if (nestedLayoutComponent) {
|
|
33
|
+
promises.push(resolveLazyComponent(pageService.resolveComponentFromConfig('nestedLayout')));
|
|
34
|
+
}
|
|
35
|
+
const [resolvedBundle, resolvedLayout] = await Promise.all(promises);
|
|
36
|
+
const { components, reducers } = resolvedBundle;
|
|
37
|
+
const component = components[pageComponent];
|
|
38
|
+
// pageComponent should have required fields even if it is lazy,
|
|
39
|
+
// thanks to `git log 9466cb32bfb71ba49144ef839d3d5bce246e213c -L90,103:packages/modules/common/src/bundleManager/bundleManager.ts`
|
|
40
|
+
(_a = component === null || component === void 0 ? void 0 : component.reducers) === null || _a === void 0 ? void 0 : _a.forEach((reducer) => dispatcherContext.getStore(reducer));
|
|
41
|
+
reducers === null || reducers === void 0 ? void 0 : reducers.forEach((reducer) => dispatcherContext.getStore(reducer));
|
|
42
|
+
// @todo: reuse logic from bundleManager?
|
|
43
|
+
// register nested layout actions and reducers for current page
|
|
44
|
+
if (resolvedLayout) {
|
|
45
|
+
if ('actions' in resolvedLayout && isArray(resolvedLayout.actions)) {
|
|
46
|
+
actionRegistry.add(pageComponent, resolvedLayout.actions);
|
|
47
|
+
}
|
|
48
|
+
if ('reducers' in resolvedLayout && isArray(resolvedLayout.reducers)) {
|
|
49
|
+
resolvedLayout.reducers.forEach((reducer) => {
|
|
50
|
+
dispatcher.registerStore(reducer);
|
|
51
|
+
dispatcherContext.getStore(reducer);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
log.error({
|
|
58
|
+
event: 'load-bundle-failed',
|
|
59
|
+
error,
|
|
60
|
+
});
|
|
61
|
+
// блокируем переход если не удалось загрузить бандл
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export { loadBundle };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var isArray = require('@tinkoff/utils/is/array');
|
|
6
|
+
var react = require('@tramvai/react');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
|
+
|
|
10
|
+
var isArray__default = /*#__PURE__*/_interopDefaultLegacy(isArray);
|
|
11
|
+
|
|
12
|
+
const loadBundle = ({ bundleManager, logger, actionRegistry, responseManager, dispatcher, dispatcherContext, pageService, }) => {
|
|
13
|
+
const log = logger('route:load-bundles');
|
|
14
|
+
return async ({ to }) => {
|
|
15
|
+
var _a;
|
|
16
|
+
log.debug({
|
|
17
|
+
event: 'load-bundle',
|
|
18
|
+
route: to,
|
|
19
|
+
});
|
|
20
|
+
const { bundle, pageComponent, nestedLayoutComponent } = to.config;
|
|
21
|
+
if (!bundleManager.has(bundle, pageComponent)) {
|
|
22
|
+
log.info({
|
|
23
|
+
event: 'load-bundle-not-found',
|
|
24
|
+
bundle,
|
|
25
|
+
pageComponent,
|
|
26
|
+
});
|
|
27
|
+
// если бандл не найден, то всё ок и мы должны вернуть 404 на сервере,
|
|
28
|
+
// а на клиенте просто загрузить новую страницу
|
|
29
|
+
responseManager.setStatus(404);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
// Пытаемся загрузить и в случае инициализации на клиенте, т.к.
|
|
33
|
+
// несмотря на наличие бандла в разметке, все равно мы должны дождаться
|
|
34
|
+
// его загрузки перед рендером
|
|
35
|
+
try {
|
|
36
|
+
const promises = [];
|
|
37
|
+
// for file-system pages bundle is virtual, so it will be loaded in parallel with nested layout
|
|
38
|
+
// for classic bundles, page component will be loaded after bundle loading
|
|
39
|
+
promises.push(bundleManager.get(bundle, pageComponent));
|
|
40
|
+
if (nestedLayoutComponent) {
|
|
41
|
+
promises.push(react.resolveLazyComponent(pageService.resolveComponentFromConfig('nestedLayout')));
|
|
42
|
+
}
|
|
43
|
+
const [resolvedBundle, resolvedLayout] = await Promise.all(promises);
|
|
44
|
+
const { components, reducers } = resolvedBundle;
|
|
45
|
+
const component = components[pageComponent];
|
|
46
|
+
// pageComponent should have required fields even if it is lazy,
|
|
47
|
+
// thanks to `git log 9466cb32bfb71ba49144ef839d3d5bce246e213c -L90,103:packages/modules/common/src/bundleManager/bundleManager.ts`
|
|
48
|
+
(_a = component === null || component === void 0 ? void 0 : component.reducers) === null || _a === void 0 ? void 0 : _a.forEach((reducer) => dispatcherContext.getStore(reducer));
|
|
49
|
+
reducers === null || reducers === void 0 ? void 0 : reducers.forEach((reducer) => dispatcherContext.getStore(reducer));
|
|
50
|
+
// @todo: reuse logic from bundleManager?
|
|
51
|
+
// register nested layout actions and reducers for current page
|
|
52
|
+
if (resolvedLayout) {
|
|
53
|
+
if ('actions' in resolvedLayout && isArray__default["default"](resolvedLayout.actions)) {
|
|
54
|
+
actionRegistry.add(pageComponent, resolvedLayout.actions);
|
|
55
|
+
}
|
|
56
|
+
if ('reducers' in resolvedLayout && isArray__default["default"](resolvedLayout.reducers)) {
|
|
57
|
+
resolvedLayout.reducers.forEach((reducer) => {
|
|
58
|
+
dispatcher.registerStore(reducer);
|
|
59
|
+
dispatcherContext.getStore(reducer);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
log.error({
|
|
66
|
+
event: 'load-bundle-failed',
|
|
67
|
+
error,
|
|
68
|
+
});
|
|
69
|
+
// блокируем переход если не удалось загрузить бандл
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
exports.loadBundle = loadBundle;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const httpMethod = ({ requestManager, responseManager, logger, }) => {
|
|
2
|
+
const log = logger('route:httpMethod');
|
|
3
|
+
return async ({ to }) => {
|
|
4
|
+
const { httpMethods } = to.config;
|
|
5
|
+
if (httpMethods) {
|
|
6
|
+
const currentMethod = requestManager.getMethod().toLowerCase();
|
|
7
|
+
if (!httpMethods.split(',').includes(currentMethod)) {
|
|
8
|
+
log.info({
|
|
9
|
+
event: 'check-failed',
|
|
10
|
+
currentMethod,
|
|
11
|
+
route: to,
|
|
12
|
+
});
|
|
13
|
+
responseManager.setStatus(405);
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export { httpMethod };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
const httpMethod = ({ requestManager, responseManager, logger, }) => {
|
|
6
|
+
const log = logger('route:httpMethod');
|
|
7
|
+
return async ({ to }) => {
|
|
8
|
+
const { httpMethods } = to.config;
|
|
9
|
+
if (httpMethods) {
|
|
10
|
+
const currentMethod = requestManager.getMethod().toLowerCase();
|
|
11
|
+
if (!httpMethods.split(',').includes(currentMethod)) {
|
|
12
|
+
log.info({
|
|
13
|
+
event: 'check-failed',
|
|
14
|
+
currentMethod,
|
|
15
|
+
route: to,
|
|
16
|
+
});
|
|
17
|
+
responseManager.setStatus(405);
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
exports.httpMethod = httpMethod;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ROUTER_GUARD_TOKEN } from '@tramvai/tokens-router';
|
|
2
|
+
import { REQUEST_MANAGER_TOKEN, RESPONSE_MANAGER_TOKEN, LOGGER_TOKEN } from '@tramvai/tokens-common';
|
|
3
|
+
import { httpMethod } from './httpMethod.es.js';
|
|
4
|
+
|
|
5
|
+
const serverGuards = [
|
|
6
|
+
{
|
|
7
|
+
provide: ROUTER_GUARD_TOKEN,
|
|
8
|
+
multi: true,
|
|
9
|
+
useFactory: httpMethod,
|
|
10
|
+
deps: {
|
|
11
|
+
requestManager: REQUEST_MANAGER_TOKEN,
|
|
12
|
+
responseManager: RESPONSE_MANAGER_TOKEN,
|
|
13
|
+
logger: LOGGER_TOKEN,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export { serverGuards };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tokensRouter = require('@tramvai/tokens-router');
|
|
6
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
7
|
+
var httpMethod = require('./httpMethod.js');
|
|
8
|
+
|
|
9
|
+
const serverGuards = [
|
|
10
|
+
{
|
|
11
|
+
provide: tokensRouter.ROUTER_GUARD_TOKEN,
|
|
12
|
+
multi: true,
|
|
13
|
+
useFactory: httpMethod.httpMethod,
|
|
14
|
+
deps: {
|
|
15
|
+
requestManager: tokensCommon.REQUEST_MANAGER_TOKEN,
|
|
16
|
+
responseManager: tokensCommon.RESPONSE_MANAGER_TOKEN,
|
|
17
|
+
logger: tokensCommon.LOGGER_TOKEN,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
exports.serverGuards = serverGuards;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var RouterStore = require('../../../stores/RouterStore.js');
|
|
6
|
+
|
|
7
|
+
const fillRouterStore = ({ context, }) => {
|
|
8
|
+
return (navigation) => {
|
|
9
|
+
context.dispatch(RouterStore.setCurrentNavigation(navigation));
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
exports.fillRouterStore = fillRouterStore;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CONTEXT_TOKEN } from '@tramvai/tokens-common';
|
|
2
|
+
import { onChangeHooksToken } from '../../tokens.browser.js';
|
|
3
|
+
import { fillRouterStore } from './fillRouterStore.browser.js';
|
|
4
|
+
|
|
5
|
+
const commonHooks = [
|
|
6
|
+
{
|
|
7
|
+
provide: onChangeHooksToken,
|
|
8
|
+
multi: true,
|
|
9
|
+
useFactory: fillRouterStore,
|
|
10
|
+
deps: {
|
|
11
|
+
context: CONTEXT_TOKEN,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export { commonHooks };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CONTEXT_TOKEN } from '@tramvai/tokens-common';
|
|
2
|
+
import { onChangeHooksToken } from '../../tokens.es.js';
|
|
3
|
+
import { fillRouterStore } from './fillRouterStore.es.js';
|
|
4
|
+
|
|
5
|
+
const commonHooks = [
|
|
6
|
+
{
|
|
7
|
+
provide: onChangeHooksToken,
|
|
8
|
+
multi: true,
|
|
9
|
+
useFactory: fillRouterStore,
|
|
10
|
+
deps: {
|
|
11
|
+
context: CONTEXT_TOKEN,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export { commonHooks };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var tokensCommon = require('@tramvai/tokens-common');
|
|
6
|
+
var tokens = require('../../tokens.js');
|
|
7
|
+
var fillRouterStore = require('./fillRouterStore.js');
|
|
8
|
+
|
|
9
|
+
const commonHooks = [
|
|
10
|
+
{
|
|
11
|
+
provide: tokens.onChangeHooksToken,
|
|
12
|
+
multi: true,
|
|
13
|
+
useFactory: fillRouterStore.fillRouterStore,
|
|
14
|
+
deps: {
|
|
15
|
+
context: tokensCommon.CONTEXT_TOKEN,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
exports.commonHooks = commonHooks;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import uniq from '@tinkoff/utils/array/uniq';
|
|
2
|
+
import { isRedirectFoundError, isNotFoundError } from '@tinkoff/errors';
|
|
3
|
+
|
|
4
|
+
const stopRunAtError = (error) => {
|
|
5
|
+
if (isNotFoundError(error) || isRedirectFoundError(error)) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
const runActionsFactory = ({ store, router, actionRegistry, actionPageRunner, }) => {
|
|
10
|
+
return function runActions() {
|
|
11
|
+
const route = router.getCurrentRoute();
|
|
12
|
+
const { config: { bundle, pageComponent } = {} } = route;
|
|
13
|
+
if (!bundle || !pageComponent) {
|
|
14
|
+
throw new Error(`bundle and pageComponent should be defined, but got ${route}`);
|
|
15
|
+
}
|
|
16
|
+
const actions = uniq([
|
|
17
|
+
...(actionRegistry.getGlobal() || []),
|
|
18
|
+
...(actionRegistry.get(bundle) || []),
|
|
19
|
+
...(actionRegistry.get(pageComponent) || []),
|
|
20
|
+
]);
|
|
21
|
+
return actionPageRunner.runActions(actions, stopRunAtError).catch((err) => {
|
|
22
|
+
if (isRedirectFoundError(err)) {
|
|
23
|
+
return router.navigate({
|
|
24
|
+
url: err.nextUrl,
|
|
25
|
+
replace: true,
|
|
26
|
+
code: err.httpStatus,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
throw err.error || err;
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { runActionsFactory };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import uniq from '@tinkoff/utils/array/uniq';
|
|
2
|
+
import { isRedirectFoundError, isNotFoundError } from '@tinkoff/errors';
|
|
3
|
+
|
|
4
|
+
const stopRunAtError = (error) => {
|
|
5
|
+
if (isNotFoundError(error) || isRedirectFoundError(error)) {
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
const runActionsFactory = ({ store, router, actionRegistry, actionPageRunner, }) => {
|
|
10
|
+
return function runActions() {
|
|
11
|
+
const route = router.getCurrentRoute();
|
|
12
|
+
const { config: { bundle, pageComponent } = {} } = route;
|
|
13
|
+
if (!bundle || !pageComponent) {
|
|
14
|
+
throw new Error(`bundle and pageComponent should be defined, but got ${route}`);
|
|
15
|
+
}
|
|
16
|
+
const actions = uniq([
|
|
17
|
+
...(actionRegistry.getGlobal() || []),
|
|
18
|
+
...(actionRegistry.get(bundle) || []),
|
|
19
|
+
...(actionRegistry.get(pageComponent) || []),
|
|
20
|
+
]);
|
|
21
|
+
return actionPageRunner.runActions(actions, stopRunAtError).catch((err) => {
|
|
22
|
+
if (isRedirectFoundError(err)) {
|
|
23
|
+
return router.navigate({
|
|
24
|
+
url: err.nextUrl,
|
|
25
|
+
replace: true,
|
|
26
|
+
code: err.httpStatus,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
throw err.error || err;
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { runActionsFactory };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var uniq = require('@tinkoff/utils/array/uniq');
|
|
6
|
+
var errors = require('@tinkoff/errors');
|
|
7
|
+
|
|
8
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
9
|
+
|
|
10
|
+
var uniq__default = /*#__PURE__*/_interopDefaultLegacy(uniq);
|
|
11
|
+
|
|
12
|
+
const stopRunAtError = (error) => {
|
|
13
|
+
if (errors.isNotFoundError(error) || errors.isRedirectFoundError(error)) {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const runActionsFactory = ({ store, router, actionRegistry, actionPageRunner, }) => {
|
|
18
|
+
return function runActions() {
|
|
19
|
+
const route = router.getCurrentRoute();
|
|
20
|
+
const { config: { bundle, pageComponent } = {} } = route;
|
|
21
|
+
if (!bundle || !pageComponent) {
|
|
22
|
+
throw new Error(`bundle and pageComponent should be defined, but got ${route}`);
|
|
23
|
+
}
|
|
24
|
+
const actions = uniq__default["default"]([
|
|
25
|
+
...(actionRegistry.getGlobal() || []),
|
|
26
|
+
...(actionRegistry.get(bundle) || []),
|
|
27
|
+
...(actionRegistry.get(pageComponent) || []),
|
|
28
|
+
]);
|
|
29
|
+
return actionPageRunner.runActions(actions, stopRunAtError).catch((err) => {
|
|
30
|
+
if (errors.isRedirectFoundError(err)) {
|
|
31
|
+
return router.navigate({
|
|
32
|
+
url: err.nextUrl,
|
|
33
|
+
replace: true,
|
|
34
|
+
code: err.httpStatus,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
throw err.error || err;
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
exports.runActionsFactory = runActionsFactory;
|