catalyst-core 0.0.1-beta.2
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/.prettierignore +2 -0
- package/.prettierrc.json +7 -0
- package/LICENSE +9 -0
- package/README.md +132 -0
- package/babel.config.json +24 -0
- package/bin/catalyst.js +41 -0
- package/caching.js +16 -0
- package/checkVersion.js +3 -0
- package/config/config.js +24 -0
- package/config.json +8 -0
- package/index.js +16 -0
- package/logger/index.js +96 -0
- package/package.json +87 -0
- package/packages/create-framework-app/node_modules/.package-lock.json +249 -0
- package/packages/create-framework-app/templates/redux-js/node_modules/@babel/core/lib/config/caching.js +261 -0
- package/packages/create-framework-app/templates/redux-js/node_modules/@remix-run/router/dist/router.js +4327 -0
- package/packages/create-framework-app/templates/redux-js/node_modules/catalyst/router.js +15 -0
- package/packages/create-framework-app/templates/redux-js/node_modules/http-proxy-middleware/dist/router.js +46 -0
- package/reducer/index.js +88 -0
- package/reducer/loadableConfigReducer.js +19 -0
- package/router/ClientRouter.js +15 -0
- package/router/ServerRouter.js +28 -0
- package/router/index.js +32 -0
- package/router.js +16 -0
- package/scripts/build.js +27 -0
- package/scripts/loadEnvironmentVariables.js +37 -0
- package/scripts/loadScriptsBeforeServerStarts.js +55 -0
- package/scripts/prepare.js +19 -0
- package/scripts/registerAliases.js +30 -0
- package/scripts/serve.js +27 -0
- package/scripts/start.js +28 -0
- package/scripts/validator.js +99 -0
- package/server/mainIndex.js +65 -0
- package/server/mainServer.js +70 -0
- package/server/renderer/document/Body.js +37 -0
- package/server/renderer/document/Head.js +44 -0
- package/server/renderer/document/index.js +25 -0
- package/server/renderer/extract.js +86 -0
- package/server/renderer/handler.js +228 -0
- package/server/renderer/index.js +13 -0
- package/server/renderer/render.js +71 -0
- package/server/renderer/userAgentUtil.js +55 -0
- package/server/utils/validator.js +98 -0
- package/store/index.dev.js +73 -0
- package/store/index.js +25 -0
- package/store/index.prod.js +66 -0
- package/tsconfig.json +110 -0
- package/types/caching.d.ts +1 -0
- package/types/config/config.d.ts +19 -0
- package/types/index.d.ts +1 -0
- package/types/logger/index.d.ts +14 -0
- package/types/reducer/index.d.ts +22 -0
- package/types/reducer/loadableConfigReducer.d.ts +9 -0
- package/types/router/ClientRouter.d.ts +5 -0
- package/types/router/ServerRouter.d.ts +7 -0
- package/types/router/index.d.ts +8 -0
- package/types/router.d.ts +1 -0
- package/types/scripts/build.d.ts +1 -0
- package/types/scripts/loadEnvironmentVariables.d.ts +5 -0
- package/types/scripts/loadScriptsBeforeServerStarts.d.ts +1 -0
- package/types/scripts/prepare.d.ts +1 -0
- package/types/scripts/registerAliases.d.ts +1 -0
- package/types/scripts/serve.d.ts +1 -0
- package/types/scripts/start.d.ts +1 -0
- package/types/scripts/validator.d.ts +9 -0
- package/types/scripts/verifyConfig.d.ts +1 -0
- package/types/server/mainIndex.d.ts +1 -0
- package/types/server/mainServer.d.ts +2 -0
- package/types/server/renderer/document/Body.d.ts +11 -0
- package/types/server/renderer/document/Head.d.ts +11 -0
- package/types/server/renderer/document/index.d.ts +2 -0
- package/types/server/renderer/extract.d.ts +18 -0
- package/types/server/renderer/handler.d.ts +6 -0
- package/types/server/renderer/index.d.ts +2 -0
- package/types/server/renderer/render.d.ts +38 -0
- package/types/server/renderer/userAgentUtil.d.ts +1 -0
- package/types/store/index.d.ts +11 -0
- package/types/store/index.dev.d.ts +8 -0
- package/types/store/index.prod.d.ts +8 -0
- package/types/webpack/babel-plugins/remove-client.plugin.d.ts +10 -0
- package/types/webpack/babel-plugins/remove-ssr.plugin.d.ts +10 -0
- package/types/webpack/babel.config.client.d.ts +21 -0
- package/types/webpack/babel.config.d.ts +16 -0
- package/types/webpack/babel.config.ssr.d.ts +21 -0
- package/types/webpack/base.babel.d.ts +184 -0
- package/types/webpack/development.client.babel.d.ts +1 -0
- package/types/webpack/plugins/mime-types.d.ts +78 -0
- package/types/webpack/plugins/route-manifest-plugin.d.ts +1 -0
- package/types/webpack/plugins/upload-assets-plugin.d.ts +1 -0
- package/types/webpack/production.client.babel.d.ts +174 -0
- package/types/webpack/production.ssr.babel.d.ts +2 -0
- package/types/webpack/scssParams.d.ts +2 -0
- package/webpack/babel-plugins/remove-client.plugin.js +31 -0
- package/webpack/babel-plugins/remove-ssr.plugin.js +21 -0
- package/webpack/babel.config.client.js +24 -0
- package/webpack/babel.config.js +20 -0
- package/webpack/babel.config.ssr.js +24 -0
- package/webpack/base.babel.js +174 -0
- package/webpack/development.client.babel.js +82 -0
- package/webpack/plugins/mime-types.js +82 -0
- package/webpack/plugins/route-manifest-copy.js +122 -0
- package/webpack/plugins/route-manifest-plugin.js +122 -0
- package/webpack/plugins/upload-assets-plugin.js +181 -0
- package/webpack/production.client.babel.js +79 -0
- package/webpack/production.ssr.babel.js +61 -0
- package/webpack/scssParams.js +31 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _path = require("path");
|
|
7
|
+
var _path2 = _interopRequireDefault(_path);
|
|
8
|
+
var _express = require("express");
|
|
9
|
+
var _express2 = _interopRequireDefault(_express);
|
|
10
|
+
var _bodyParser = require("body-parser");
|
|
11
|
+
var _bodyParser2 = _interopRequireDefault(_bodyParser);
|
|
12
|
+
var _compression = require("compression");
|
|
13
|
+
var _compression2 = _interopRequireDefault(_compression);
|
|
14
|
+
var _cookieParser = require("cookie-parser");
|
|
15
|
+
var _cookieParser2 = _interopRequireDefault(_cookieParser);
|
|
16
|
+
var _expressStaticGzip = require("express-static-gzip");
|
|
17
|
+
var _expressStaticGzip2 = _interopRequireDefault(_expressStaticGzip);
|
|
18
|
+
var _renderer = require("./renderer");
|
|
19
|
+
var _renderer2 = _interopRequireDefault(_renderer);
|
|
20
|
+
var _server = require("$server/server.js");
|
|
21
|
+
var _validator = require("./utils/validator");
|
|
22
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
|
+
const env = process.env.NODE_ENV || "development";
|
|
24
|
+
const app = (0, _express2.default)();
|
|
25
|
+
|
|
26
|
+
//Use-case: We are using body-parser here for widget-factory,
|
|
27
|
+
//we need to extract the body of request which Native will hit at our end.
|
|
28
|
+
app.use(_bodyParser2.default.json());
|
|
29
|
+
|
|
30
|
+
// This change is added to accommodate “byetstream array”
|
|
31
|
+
// which is octet-stream format coming from android!
|
|
32
|
+
app.use(_bodyParser2.default.raw({
|
|
33
|
+
type: "application/*"
|
|
34
|
+
}));
|
|
35
|
+
|
|
36
|
+
// parse cookies!
|
|
37
|
+
app.use((0, _cookieParser2.default)());
|
|
38
|
+
|
|
39
|
+
// Apply custom midlewares
|
|
40
|
+
if ((0, _validator.validateMiddleware)(_server.addMiddlewares)) (0, _server.addMiddlewares)(app);
|
|
41
|
+
|
|
42
|
+
// gzip
|
|
43
|
+
app.use((0, _compression2.default)());
|
|
44
|
+
|
|
45
|
+
// We upload the assets on our s3 bucket and serve them through our CDN.
|
|
46
|
+
// However if our CDN is down all we have to do is change the PUBLIC_ASSET_PATH in basecamp
|
|
47
|
+
// to "node_server_ip/assets" (Example: http://13.127.237.229:8443/assets) to serve the assets from our node server.
|
|
48
|
+
// When we make production builds on our local system we change the PUBLIC_ASSET_PATH to "http://localhost:3005/assets/".
|
|
49
|
+
// In this case all the asset requests are made to the node server running on our local system and are served locally.
|
|
50
|
+
if (env === "production") {
|
|
51
|
+
app.use("/assets", (0, _expressStaticGzip2.default)(_path2.default.join(__dirname, "../" + process.env.PUBLIC_OUTPUT_PATH), {
|
|
52
|
+
enableBrotli: true,
|
|
53
|
+
orderPreference: ["br", "gzip", "deflate"]
|
|
54
|
+
}), (0, _expressStaticGzip2.default)(_path2.default.join(__dirname, "../src/static/images"), {
|
|
55
|
+
enableBrotli: true,
|
|
56
|
+
orderPreference: ["br", "gzip", "deflate"]
|
|
57
|
+
}), (0, _expressStaticGzip2.default)(_path2.default.join(__dirname, "../src/static/fonts"), {
|
|
58
|
+
enableBrotli: true,
|
|
59
|
+
orderPreference: ["br", "gzip", "deflate"]
|
|
60
|
+
}), (0, _expressStaticGzip2.default)(_path2.default.join(__dirname, "../src/js/lib"), {
|
|
61
|
+
enableBrotli: true,
|
|
62
|
+
orderPreference: ["br", "gzip", "deflate"]
|
|
63
|
+
}));
|
|
64
|
+
} else {
|
|
65
|
+
app.use("/assets", _express2.default.static(_path2.default.join(__dirname, "../" + process.env.PUBLIC_OUTPUT_PATH)), _express2.default.static(_path2.default.join(__dirname, `../${process.env.APPLICATION}/src/static/images`)), _express2.default.static(_path2.default.join(__dirname, `../${process.env.APPLICATION}/src/static/fonts`)), _express2.default.static(_path2.default.join(__dirname, `../${process.env.APPLICATION}/src/js/lib`)));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// handles document request
|
|
69
|
+
app.use("*", _renderer2.default);
|
|
70
|
+
exports.default = app;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Body = Body;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _react2 = _interopRequireDefault(_react);
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
/**
|
|
11
|
+
* Body component which will be used in page component
|
|
12
|
+
* @param {object} initialState - redux store state
|
|
13
|
+
* @param {object} statusCode - api config present in cache list
|
|
14
|
+
* @param {object} firstFoldCss - user defined components for meta tags input
|
|
15
|
+
* @param {object} firstFoldJS - user defined components for meta tags input
|
|
16
|
+
* @param {object} jsx - user defined components for meta tags input
|
|
17
|
+
* @param {object} fetcherData - router fetched data
|
|
18
|
+
*/
|
|
19
|
+
function Body(props) {
|
|
20
|
+
const {
|
|
21
|
+
initialState,
|
|
22
|
+
statusCode,
|
|
23
|
+
firstFoldCss,
|
|
24
|
+
firstFoldJS,
|
|
25
|
+
jsx,
|
|
26
|
+
fetcherData
|
|
27
|
+
} = props;
|
|
28
|
+
return /*#__PURE__*/_react2.default.createElement("body", null, firstFoldCss, firstFoldJS, jsx, /*#__PURE__*/_react2.default.createElement("script", {
|
|
29
|
+
dangerouslySetInnerHTML: {
|
|
30
|
+
__html: `
|
|
31
|
+
window.__INITIAL_STATE__ = ${JSON.stringify(initialState)};
|
|
32
|
+
window.__STATUS_CODE__ = ${statusCode};
|
|
33
|
+
window.__ROUTER_INITIAL_DATA__ = ${JSON.stringify(fetcherData)};
|
|
34
|
+
`
|
|
35
|
+
}
|
|
36
|
+
}), props.children);
|
|
37
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Head = Head;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _react2 = _interopRequireDefault(_react);
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
/**
|
|
11
|
+
* Head component which will be used in page rendering
|
|
12
|
+
* @param {string} pageCss - includes all styles for page css
|
|
13
|
+
* @param {object} pageJS - async scripts for loading chunks
|
|
14
|
+
* @param {function} metaTagFunction - user defined function which returns meta tags in array
|
|
15
|
+
* @param {boolean} isBot - checks if request is made by bot
|
|
16
|
+
* @param {string} publicAssetPath - public asset path for assets
|
|
17
|
+
* @param {object} fetcherData - router fetched data
|
|
18
|
+
*/
|
|
19
|
+
function Head(props) {
|
|
20
|
+
const {
|
|
21
|
+
pageCss,
|
|
22
|
+
pageJS,
|
|
23
|
+
metaTagFunction,
|
|
24
|
+
isBot,
|
|
25
|
+
publicAssetPath,
|
|
26
|
+
fetcherData
|
|
27
|
+
} = props;
|
|
28
|
+
return /*#__PURE__*/_react2.default.createElement("head", null, /*#__PURE__*/_react2.default.createElement("meta", {
|
|
29
|
+
charSet: "utf-8"
|
|
30
|
+
}), /*#__PURE__*/_react2.default.createElement("meta", {
|
|
31
|
+
name: "viewport",
|
|
32
|
+
content: "width=device-width, initial-scale=1"
|
|
33
|
+
}), publicAssetPath && /*#__PURE__*/_react2.default.createElement("link", {
|
|
34
|
+
rel: "preconnect",
|
|
35
|
+
href: publicAssetPath
|
|
36
|
+
}), publicAssetPath && /*#__PURE__*/_react2.default.createElement("link", {
|
|
37
|
+
rel: "dns-prefetch",
|
|
38
|
+
href: publicAssetPath
|
|
39
|
+
}), metaTagFunction && metaTagFunction(fetcherData), !isBot && pageJS, !isBot && /*#__PURE__*/_react2.default.createElement("style", {
|
|
40
|
+
dangerouslySetInnerHTML: {
|
|
41
|
+
__html: pageCss
|
|
42
|
+
}
|
|
43
|
+
}), props.children);
|
|
44
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _Head = require("./Head");
|
|
7
|
+
Object.keys(_Head).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
Object.defineProperty(exports, key, {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
get: function () {
|
|
12
|
+
return _Head[key];
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
var _Body = require("./Body");
|
|
17
|
+
Object.keys(_Body).forEach(function (key) {
|
|
18
|
+
if (key === "default" || key === "__esModule") return;
|
|
19
|
+
Object.defineProperty(exports, key, {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () {
|
|
22
|
+
return _Body[key];
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.cacheCSS = cacheCSS;
|
|
7
|
+
exports.cacheJS = cacheJS;
|
|
8
|
+
exports.default = function (res, route) {
|
|
9
|
+
try {
|
|
10
|
+
const requestPath = route.path;
|
|
11
|
+
const cachedCss = fetchCachedCSS(requestPath);
|
|
12
|
+
const cachedJS = fetchCachedJS(requestPath);
|
|
13
|
+
if (cachedCss || cachedJS) {
|
|
14
|
+
res.locals.pageJS = cachedJS;
|
|
15
|
+
res.locals.pageCss = cachedCss;
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
} catch (error) {
|
|
19
|
+
console.log("Error while reading lodable stats:");
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var _path = require("path");
|
|
23
|
+
var _path2 = _interopRequireDefault(_path);
|
|
24
|
+
var _fs = require("fs");
|
|
25
|
+
var _fs2 = _interopRequireDefault(_fs);
|
|
26
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
27
|
+
/**
|
|
28
|
+
* Stores css chunks styles into cache in string format
|
|
29
|
+
* @param {string} key - router path
|
|
30
|
+
* @param {object} data - css elements array extracted through loadable chunk extracter
|
|
31
|
+
*/
|
|
32
|
+
function cacheCSS(key, data) {
|
|
33
|
+
if (!process.cssCache) {
|
|
34
|
+
process.cssCache = {};
|
|
35
|
+
}
|
|
36
|
+
let pageCss = "";
|
|
37
|
+
if (Array.isArray(data)) {
|
|
38
|
+
try {
|
|
39
|
+
data.map(assetChunk => {
|
|
40
|
+
const assetPathArr = assetChunk.key.split("/");
|
|
41
|
+
const assetName = assetPathArr[assetPathArr.length - 1];
|
|
42
|
+
const ext = _path2.default.extname(assetName);
|
|
43
|
+
if (ext === ".css") pageCss += _fs2.default.readFileSync(_path2.default.resolve(process.env.src_path, `${process.env.OUTPUT_PATH}/public/`, assetName));
|
|
44
|
+
});
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.log("=====> Error While Extracting The Chunk:");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
process.cssCache[key] = pageCss;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Stores javascript into cache
|
|
54
|
+
* @param {string} key - router path
|
|
55
|
+
* @param {object} data - js elements array extracted through loadable chunk extracter
|
|
56
|
+
*/
|
|
57
|
+
function cacheJS(key, data) {
|
|
58
|
+
if (!process.jsCache) {
|
|
59
|
+
process.jsCache = {};
|
|
60
|
+
}
|
|
61
|
+
process.jsCache[key] = data;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* returns cached css
|
|
66
|
+
* @param {string} key - router path
|
|
67
|
+
* @return {string} - cached css
|
|
68
|
+
*/
|
|
69
|
+
function fetchCachedCSS(key) {
|
|
70
|
+
return process.cssCache && process.cssCache[key] ? process.cssCache[key] : null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* returns cached js
|
|
75
|
+
* @param {string} key - router path
|
|
76
|
+
* @return {string} - cached js
|
|
77
|
+
*/
|
|
78
|
+
function fetchCachedJS(key) {
|
|
79
|
+
return process.jsCache && process.jsCache[key] ? process.jsCache[key] : null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* stores css and js in cache
|
|
84
|
+
* @param {object} res - response object
|
|
85
|
+
* @param {string} route - route path
|
|
86
|
+
*/
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = async function (req, res) {
|
|
7
|
+
try {
|
|
8
|
+
let context = {};
|
|
9
|
+
let fetcherData = {};
|
|
10
|
+
const webExtractor = new _server3.ChunkExtractor({
|
|
11
|
+
statsFile: webStats,
|
|
12
|
+
entrypoints: ["app"]
|
|
13
|
+
});
|
|
14
|
+
const deviceDetails = (0, _userAgentUtil.getUserAgentDetails)(req.headers["user-agent"] || "");
|
|
15
|
+
const isBot = deviceDetails.googleBot || req.get("user-agent") === STATUS_CAKE_USER_AGENT_MOBILE ? true : false;
|
|
16
|
+
|
|
17
|
+
// FRAMEWORK COMMENT GENERALISE THIS
|
|
18
|
+
const store = (0, _validator.validateConfigureStore)(configureStore) ? configureStore({}, {}, req) : null;
|
|
19
|
+
|
|
20
|
+
//TODO: Currently passing 4th arguement as whole request to bypass x-authorization to BE
|
|
21
|
+
// Need to store the auth_token and user information locally too
|
|
22
|
+
// Create a new Redux store instance
|
|
23
|
+
// const store = configureStore({}, requestCookies, req, customHeaders)
|
|
24
|
+
|
|
25
|
+
//get csrf token from client request
|
|
26
|
+
// const csrf = typeof req.csrfToken === "function" && req.csrfToken()
|
|
27
|
+
// See react-router's Server Rendering section:
|
|
28
|
+
// https://reacttraining.com/react-router/web/guides/server-rendering
|
|
29
|
+
const matchRoutes = routes => {
|
|
30
|
+
return routes.reduce((matches, route) => {
|
|
31
|
+
const {
|
|
32
|
+
path
|
|
33
|
+
} = route;
|
|
34
|
+
const match = (0, _router.matchPath)({
|
|
35
|
+
path,
|
|
36
|
+
caseSensitive: false,
|
|
37
|
+
end: true
|
|
38
|
+
}, req.baseUrl || "/");
|
|
39
|
+
if (match) {
|
|
40
|
+
if (isProduction && !res.locals.pageCss && !res.locals.pageJS && !res.locals.routePath) {
|
|
41
|
+
(0, _extract2.default)(res, route);
|
|
42
|
+
}
|
|
43
|
+
if (!res.locals.pageCss && !res.locals.pageJS && !res.locals.routePath) {
|
|
44
|
+
res.locals.routePath = path;
|
|
45
|
+
//moving routing logic outside of the App and using ServerRoutes for creating routes on server instead
|
|
46
|
+
(0, _server2.renderToString)( /*#__PURE__*/_react2.default.createElement(_server3.ChunkExtractorManager, {
|
|
47
|
+
extractor: webExtractor
|
|
48
|
+
}, /*#__PURE__*/_react2.default.createElement(_reactRedux.Provider, {
|
|
49
|
+
store: store
|
|
50
|
+
}, /*#__PURE__*/_react2.default.createElement(_server.StaticRouter, {
|
|
51
|
+
context: context,
|
|
52
|
+
location: req.originalUrl
|
|
53
|
+
}, /*#__PURE__*/_react2.default.createElement(_ServerRouter2.default, {
|
|
54
|
+
store: store,
|
|
55
|
+
intialData: fetcherData
|
|
56
|
+
})))));
|
|
57
|
+
}
|
|
58
|
+
const wc = route.component;
|
|
59
|
+
matches.push({
|
|
60
|
+
route,
|
|
61
|
+
match,
|
|
62
|
+
serverSideFunction: wc && wc.serverSideFunction || (() => Promise.resolve()),
|
|
63
|
+
metaTagFunction: wc && wc.metaTagFunction || null,
|
|
64
|
+
serverFetcher: wc && wc.serverFetcher || (() => Promise.resolve()),
|
|
65
|
+
callServerFetcher: wc && wc.serverFetcher ? true : false
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (!match && route.routes) {
|
|
69
|
+
// recursively try to match nested routes
|
|
70
|
+
const nested = matchRoutes(route.routes);
|
|
71
|
+
if (nested.length) {
|
|
72
|
+
matches = matches.concat(nested);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return matches;
|
|
76
|
+
}, []);
|
|
77
|
+
};
|
|
78
|
+
const routes = (0, _validator.validateGetRoutes)(getRoutes) ? getRoutes() : [];
|
|
79
|
+
const matches = matchRoutes(routes);
|
|
80
|
+
// No matched route, send an error.
|
|
81
|
+
// if (!matches.length) {
|
|
82
|
+
// // res.status(404)
|
|
83
|
+
// return res.redirect(301, process.env.EXTERNAL_BASE_URL + "/404")
|
|
84
|
+
// }
|
|
85
|
+
|
|
86
|
+
const getComponent = () => {
|
|
87
|
+
//moving routing logic outside of the App and using ServerRouter for creating routes on server instead
|
|
88
|
+
return /*#__PURE__*/_react2.default.createElement("div", {
|
|
89
|
+
id: "app"
|
|
90
|
+
}, /*#__PURE__*/_react2.default.createElement(_reactRedux.Provider, {
|
|
91
|
+
store: store
|
|
92
|
+
}, /*#__PURE__*/_react2.default.createElement(_server.StaticRouter, {
|
|
93
|
+
context: context,
|
|
94
|
+
location: req.originalUrl
|
|
95
|
+
}, /*#__PURE__*/_react2.default.createElement(_ServerRouter2.default, {
|
|
96
|
+
store: store,
|
|
97
|
+
intialData: fetcherData
|
|
98
|
+
}))));
|
|
99
|
+
};
|
|
100
|
+
let metaTagFunction = null;
|
|
101
|
+
const renderMarkUp = async errorCode => {
|
|
102
|
+
const shellStart = await _render2.default.renderStart(res.locals.pageCss, res.locals.pageJS, metaTagFunction, isBot, fetcherData);
|
|
103
|
+
const jsx = webExtractor.collectChunks(getComponent());
|
|
104
|
+
let state = store.getState();
|
|
105
|
+
const shellEnd = _render2.default.renderEnd(webExtractor, state, res, jsx, errorCode, fetcherData);
|
|
106
|
+
const finalProps = _objectSpread(_objectSpread(_objectSpread({}, shellStart), shellEnd), {}, {
|
|
107
|
+
jsx: jsx,
|
|
108
|
+
req,
|
|
109
|
+
res
|
|
110
|
+
});
|
|
111
|
+
let CompleteDocument = () => {
|
|
112
|
+
if ((0, _validator.validateCustomDocument)(CustomDocument)) {
|
|
113
|
+
return CustomDocument(finalProps);
|
|
114
|
+
} else {
|
|
115
|
+
return /*#__PURE__*/_react2.default.createElement("html", {
|
|
116
|
+
lang: finalProps.lang
|
|
117
|
+
}, /*#__PURE__*/_react2.default.createElement(_document.Head, finalProps), /*#__PURE__*/_react2.default.createElement(_document.Body, finalProps));
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
try {
|
|
121
|
+
let status = matches.length && matches[0].match.path === "*" ? 404 : 200;
|
|
122
|
+
res.set({
|
|
123
|
+
"content-type": "text/html; charset=utf-8"
|
|
124
|
+
});
|
|
125
|
+
res.status(status);
|
|
126
|
+
const {
|
|
127
|
+
pipe
|
|
128
|
+
} = (0, _server2.renderToPipeableStream)( /*#__PURE__*/_react2.default.createElement(CompleteDocument, null), {
|
|
129
|
+
onShellReady() {
|
|
130
|
+
res.setHeader("content-type", "text/html");
|
|
131
|
+
pipe(res);
|
|
132
|
+
res.end();
|
|
133
|
+
},
|
|
134
|
+
onError(error) {
|
|
135
|
+
//transformed to new log format
|
|
136
|
+
logger.error({
|
|
137
|
+
message: `\n====> Error while renderToPipeableStream : ${error.toString()}`
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
} catch (error) {
|
|
142
|
+
logger.error("Error while rendering markup:" + error);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// Server side function calling
|
|
147
|
+
_App2.default.serverSideFunction({
|
|
148
|
+
store,
|
|
149
|
+
req
|
|
150
|
+
}).then(() => {
|
|
151
|
+
const serverSideFunction = matches.map(match => {
|
|
152
|
+
if (match?.metaTagFunction) {
|
|
153
|
+
metaTagFunction = match.metaTagFunction;
|
|
154
|
+
}
|
|
155
|
+
return match.serverSideFunction({
|
|
156
|
+
store
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Api calling to fetch data
|
|
161
|
+
Promise.all(serverSideFunction).then(() => {
|
|
162
|
+
(0, _router.serverDataFetcher)({
|
|
163
|
+
routes: routes,
|
|
164
|
+
req,
|
|
165
|
+
url: req.originalUrl
|
|
166
|
+
}, {
|
|
167
|
+
store
|
|
168
|
+
}).then(res => {
|
|
169
|
+
fetcherData = res;
|
|
170
|
+
}).then(async () => await renderMarkUp(null)).catch(async error => {
|
|
171
|
+
logger.error("error in calling server fetcher is ====>" + error);
|
|
172
|
+
await renderMarkUp(404);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
}).catch(error => {
|
|
176
|
+
logger.error("error in server side function is ====>" + error);
|
|
177
|
+
renderMarkUp(error.status_code);
|
|
178
|
+
});
|
|
179
|
+
} catch (error) {
|
|
180
|
+
logger.error("Error on server outer" + error.toString());
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
var _react = require("react");
|
|
184
|
+
var _react2 = _interopRequireDefault(_react);
|
|
185
|
+
var _path = require("path");
|
|
186
|
+
var _path2 = _interopRequireDefault(_path);
|
|
187
|
+
var _reactRedux = require("react-redux");
|
|
188
|
+
var _router = require("@tata1mg/router");
|
|
189
|
+
var _server = require("react-router-dom/server");
|
|
190
|
+
var _server2 = require("react-dom/server");
|
|
191
|
+
var _server3 = require("@loadable/server");
|
|
192
|
+
var _App = require("@containers/App");
|
|
193
|
+
var _App2 = _interopRequireDefault(_App);
|
|
194
|
+
var _render = require("./render");
|
|
195
|
+
var _render2 = _interopRequireDefault(_render);
|
|
196
|
+
var _extract = require("./extract");
|
|
197
|
+
var _extract2 = _interopRequireDefault(_extract);
|
|
198
|
+
var _userAgentUtil = require("./userAgentUtil.js");
|
|
199
|
+
var _document = require("./document");
|
|
200
|
+
var _validator = require("../utils/validator");
|
|
201
|
+
var _ServerRouter = require("../../router/ServerRouter.js");
|
|
202
|
+
var _ServerRouter2 = _interopRequireDefault(_ServerRouter);
|
|
203
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
204
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
205
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
206
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
207
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
208
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
209
|
+
const {
|
|
210
|
+
default: configureStore
|
|
211
|
+
} = require(`${process.env.src_path}/src/js/store/index.js`);
|
|
212
|
+
const {
|
|
213
|
+
default: getRoutes
|
|
214
|
+
} = require(`${process.env.src_path}/src/js/routes/index.js`);
|
|
215
|
+
const {
|
|
216
|
+
default: CustomDocument
|
|
217
|
+
} = require(`${process.env.src_path}/server/document.js`);
|
|
218
|
+
const STATUS_CAKE_USER_AGENT_MOBILE = "StatusCake/Pretest (statuscake.com)";
|
|
219
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
220
|
+
let webStats = null;
|
|
221
|
+
webStats = _path2.default.join(__dirname, "../..", `loadable-stats.json`);
|
|
222
|
+
if (isProduction) webStats = _path2.default.join(__dirname, "../..", process.env.PUBLIC_OUTPUT_PATH, `loadable-stats.json`);
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* middleware for document handling
|
|
226
|
+
* @param {object} req - router path
|
|
227
|
+
* @param {object} res - css elements array extracted through loadable chunk extracter
|
|
228
|
+
*/
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _express = require("express");
|
|
7
|
+
var _express2 = _interopRequireDefault(_express);
|
|
8
|
+
var _handler = require("./handler");
|
|
9
|
+
var _handler2 = _interopRequireDefault(_handler);
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
const router = _express2.default.Router();
|
|
12
|
+
router.use(_handler2.default);
|
|
13
|
+
exports.default = router;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _extract = require("./extract");
|
|
7
|
+
/**
|
|
8
|
+
* returns data which will be used in head component for page rendering
|
|
9
|
+
* @param {string} pageCss - includes all styles for page css
|
|
10
|
+
* @param {string} pageJS - async scripts for loading chunks
|
|
11
|
+
* @param {function} metaTagFunction - user defined function which returns meta tags in array
|
|
12
|
+
* @param {boolean} isBot - checks if request is made by bot
|
|
13
|
+
* @param {object} fetcherData - router fetched data
|
|
14
|
+
*/
|
|
15
|
+
const renderStart = (pageCss, pageJS, metaTagFunction, isBot, fetcherData) => {
|
|
16
|
+
let publicAssetPath = "/assets";
|
|
17
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
18
|
+
if (isProd) {
|
|
19
|
+
publicAssetPath = `${process.env.CDN_ASSET_PATH}/${process.env.S3_FOLDER}/${process.env.BUILD_ENV}/${process.env.BUILD_NUMBER}/static/images`;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
pageCss,
|
|
23
|
+
pageJS,
|
|
24
|
+
metaTagFunction,
|
|
25
|
+
isBot,
|
|
26
|
+
publicAssetPath,
|
|
27
|
+
fetcherData
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* returns data which will be used in body component for page rendering
|
|
33
|
+
* @param {object} webExtractor - loadable object which holds chunking function
|
|
34
|
+
* @param {string} initialState - reducer initial state
|
|
35
|
+
* @param {function} res - response object
|
|
36
|
+
* @param {boolean} jsx - jsx which needs to be render on server side
|
|
37
|
+
* @param {string|number|null} errorCode - error code
|
|
38
|
+
* @param {object} fetcherData - router fetched data
|
|
39
|
+
*/
|
|
40
|
+
const renderEnd = (webExtractor, initialState = {}, res, jsx, errorCode, fetcherData) => {
|
|
41
|
+
// For bot first fold css and js would become complete page css and js
|
|
42
|
+
let firstFoldCss = "",
|
|
43
|
+
firstFoldJS = "",
|
|
44
|
+
publicSWPath = "/assets";
|
|
45
|
+
const isProd = process.env.NODE_ENV === "production";
|
|
46
|
+
const {
|
|
47
|
+
routePath,
|
|
48
|
+
pageCss,
|
|
49
|
+
pageJS
|
|
50
|
+
} = res.locals;
|
|
51
|
+
if (!isProd || routePath && (!pageCss || !pageJS)) {
|
|
52
|
+
firstFoldCss = webExtractor.getStyleElements();
|
|
53
|
+
firstFoldJS = webExtractor.getScriptElements();
|
|
54
|
+
if (isProd) {
|
|
55
|
+
(0, _extract.cacheCSS)(routePath, webExtractor.getLinkElements());
|
|
56
|
+
(0, _extract.cacheJS)(routePath, firstFoldJS);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
initialState,
|
|
61
|
+
firstFoldCss,
|
|
62
|
+
firstFoldJS,
|
|
63
|
+
jsx,
|
|
64
|
+
errorCode,
|
|
65
|
+
fetcherData
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
exports.default = {
|
|
69
|
+
renderStart,
|
|
70
|
+
renderEnd
|
|
71
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getUserAgentDetails = undefined;
|
|
7
|
+
var _uaParserJs = require("ua-parser-js");
|
|
8
|
+
var _uaParserJs2 = _interopRequireDefault(_uaParserJs);
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
11
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
12
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
13
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
14
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
15
|
+
const googleBots = {
|
|
16
|
+
"APIs-Google": "APIs-Google",
|
|
17
|
+
AdSense: "Mediapartners-Google",
|
|
18
|
+
"AdsBot Mobile Web Android": "AdsBot-Google-Mobile",
|
|
19
|
+
"AdsBot Mobile Web": "AdsBot-Google-Mobile",
|
|
20
|
+
AdsBot: "AdsBot-Google",
|
|
21
|
+
"Mobile AdSense": "Mediapartners-Google",
|
|
22
|
+
"Mobile Apps Android": "AdsBot-Google-Mobile-Apps",
|
|
23
|
+
Feedfetcher: "FeedFetcher-Google",
|
|
24
|
+
"Google Read Aloud": "Google-Read-Aloud",
|
|
25
|
+
"Duplex on the Web": "DuplexWeb-Google",
|
|
26
|
+
"Google Favicon": "Google Favicon",
|
|
27
|
+
"Web Light": "googleweblight",
|
|
28
|
+
"Amp crawler": "Google-AMPHTM",
|
|
29
|
+
Googlebot: "Googlebot"
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* check if user agent contains bot data
|
|
34
|
+
* @param {string} ua - user agent
|
|
35
|
+
* @return {string|null}
|
|
36
|
+
*/
|
|
37
|
+
const getGoogleBot = ua => {
|
|
38
|
+
for (let key in googleBots) {
|
|
39
|
+
if (ua.includes(googleBots[key])) return key;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* returns object which contains google bot and user-agent info
|
|
46
|
+
* @param {string} ua - user agent
|
|
47
|
+
* @return {object} - returns user agent
|
|
48
|
+
*/
|
|
49
|
+
const getUserAgentDetails = exports.getUserAgentDetails = ua => {
|
|
50
|
+
const agentDetails = (0, _uaParserJs2.default)(ua);
|
|
51
|
+
const googleBot = getGoogleBot(ua);
|
|
52
|
+
return _objectSpread(_objectSpread({}, agentDetails), {}, {
|
|
53
|
+
googleBot
|
|
54
|
+
});
|
|
55
|
+
};
|