catalyst-core 0.0.1-beta.2 → 0.0.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +26 -13
  2. package/bin/catalyst.js +2 -3
  3. package/config.json +0 -1
  4. package/{LICENSE → license} +2 -1
  5. package/{logger/index.js → logger.js} +10 -10
  6. package/package.json +17 -19
  7. package/packages/create-framework-app/templates/redux-js/node_modules/catalyst/src/router.js +1 -0
  8. package/router/ClientRouter.js +10 -6
  9. package/router/ServerRouter.js +2 -11
  10. package/scripts/build.js +10 -4
  11. package/scripts/checkVersion.js +5 -0
  12. package/scripts/loadEnvironmentVariables.js +8 -21
  13. package/scripts/loadScriptsBeforeServerStarts.js +12 -20
  14. package/scripts/serve.js +11 -4
  15. package/scripts/start.js +2 -4
  16. package/scripts/validator.js +40 -11
  17. package/server/expressServer.js +50 -0
  18. package/server/renderer/document/Body.js +17 -18
  19. package/server/renderer/document/Head.js +6 -7
  20. package/server/renderer/document/index.js +2 -0
  21. package/server/renderer/extract.js +25 -24
  22. package/server/renderer/handler.js +212 -188
  23. package/server/renderer/index.js +6 -7
  24. package/server/renderer/render.js +21 -19
  25. package/server/startServer.js +65 -0
  26. package/server/utils/userAgentUtil.js +55 -0
  27. package/server/utils/validator.js +40 -10
  28. package/webpack/babel-plugins/remove-client.plugin.js +1 -1
  29. package/webpack/babel-plugins/remove-ssr.plugin.js +1 -1
  30. package/webpack/babel.config.client.js +2 -2
  31. package/webpack/base.babel.js +29 -36
  32. package/webpack/development.client.babel.js +11 -8
  33. package/webpack/production.client.babel.js +1 -2
  34. package/webpack/production.ssr.babel.js +3 -3
  35. package/webpack/scssParams.js +19 -15
  36. package/.prettierignore +0 -2
  37. package/.prettierrc.json +0 -7
  38. package/checkVersion.js +0 -3
  39. package/config/config.js +0 -24
  40. package/packages/create-framework-app/node_modules/.package-lock.json +0 -249
  41. package/reducer/index.js +0 -88
  42. package/reducer/loadableConfigReducer.js +0 -19
  43. package/store/index.dev.js +0 -73
  44. package/store/index.js +0 -25
  45. package/store/index.prod.js +0 -66
@@ -3,148 +3,218 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.default = async function (req, res) {
6
+ exports.default = _default;
7
+ var _fs = _interopRequireDefault(require("fs"));
8
+ var _path = _interopRequireDefault(require("path"));
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _render = _interopRequireDefault(require("./render"));
11
+ var _App = _interopRequireDefault(require("@containers/App"));
12
+ var _extract = _interopRequireDefault(require("./extract"));
13
+ var _reactRedux = require("react-redux");
14
+ var _document = require("./document");
15
+ var _server = require("react-router-dom/server");
16
+ var _ServerRouter = _interopRequireDefault(require("../../router/ServerRouter.js"));
17
+ var _userAgentUtil = require("../utils/userAgentUtil");
18
+ var _router = require("@tata1mg/router");
19
+ var _server2 = require("@loadable/server");
20
+ var _server3 = require("react-dom/server");
21
+ var _validator = require("../utils/validator");
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
+ 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; }
24
+ 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; }
25
+ 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; }
26
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
27
+ 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); }
28
+ const {
29
+ getRoutes
30
+ } = require(`${process.env.src_path}/src/js/routes/utils.js`);
31
+ const {
32
+ default: CustomDocument
33
+ } = require(`${process.env.src_path}/server/document.js`);
34
+ const storePath = _path.default.resolve(`${process.env.src_path}/src/js/store/index.js`);
35
+ let createStore;
36
+ if (_fs.default.existsSync(storePath)) {
7
37
  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;
38
+ const {
39
+ default: configureStore
40
+ } = require(`${process.env.src_path}/src/js/store/index.js`);
41
+ createStore = configureStore;
42
+ } catch (error) {
43
+ createStore = () => {
44
+ return {
45
+ getState: () => {}
46
+ };
47
+ };
48
+ }
49
+ } else {
50
+ createStore = () => {
51
+ return {
52
+ getState: () => {}
53
+ };
54
+ };
55
+ }
56
+ const isProduction = process.env.NODE_ENV === "production";
57
+ let webStats = _path.default.join(__dirname, "../..", `loadable-stats.json`);
58
+ if (isProduction) {
59
+ webStats = _path.default.join(process.env.src_path, `${process.env.BUILD_OUTPUT_PATH}/public/loadable-stats.json`);
60
+ }
61
+ const webExtractor = new _server2.ChunkExtractor({
62
+ statsFile: webStats,
63
+ entrypoints: ["app"]
64
+ });
16
65
 
17
- // FRAMEWORK COMMENT GENERALISE THIS
18
- const store = (0, _validator.validateConfigureStore)(configureStore) ? configureStore({}, {}, req) : null;
66
+ // matches request route with routes defined in the application.
67
+ const getMatchRoutes = (routes, req, res, store, context, fetcherData) => {
68
+ return routes.reduce((matches, route) => {
69
+ const {
70
+ path
71
+ } = route;
72
+ const match = (0, _router.matchPath)({
73
+ path,
74
+ caseSensitive: false,
75
+ end: true
76
+ }, req.baseUrl || "/");
77
+ if (match) {
78
+ if (isProduction && !res.locals.pageCss && !res.locals.pageJS && !res.locals.routePath) {
79
+ (0, _extract.default)(res, route);
80
+ }
81
+ if (!res.locals.pageCss && !res.locals.pageJS && !res.locals.routePath) {
82
+ res.locals.routePath = path;
83
+ //moving routing logic outside of the App and using ServerRoutes for creating routes on server instead
84
+ (0, _server3.renderToString)( /*#__PURE__*/_react.default.createElement(_server2.ChunkExtractorManager, {
85
+ extractor: webExtractor
86
+ }, /*#__PURE__*/_react.default.createElement(_reactRedux.Provider, {
87
+ store: store
88
+ }, /*#__PURE__*/_react.default.createElement(_server.StaticRouter, {
89
+ context: context,
90
+ location: req.originalUrl
91
+ }, /*#__PURE__*/_react.default.createElement(_ServerRouter.default, {
92
+ store: store,
93
+ intialData: fetcherData
94
+ })))));
95
+ }
96
+ const wc = route.component;
97
+ matches.push({
98
+ route,
99
+ match,
100
+ serverSideFunction: wc && wc.serverSideFunction || (() => Promise.resolve()),
101
+ metaTagFunction: wc && wc.metaTagFunction || null,
102
+ serverFetcher: wc && wc.serverFetcher || (() => Promise.resolve())
103
+ });
104
+ }
105
+ if (!match && route.routes) {
106
+ // recursively try to match nested routes
107
+ const nested = getMatchRoutes(route.routes, req, res, store, context, fetcherData);
108
+ if (nested.length) {
109
+ matches = matches.concat(nested);
110
+ }
111
+ }
112
+ return matches;
113
+ }, []);
114
+ };
19
115
 
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)
116
+ // Preloads chunks required for rendering document
117
+ const getComponent = (store, context, req, fetcherData) => {
118
+ return /*#__PURE__*/_react.default.createElement("div", {
119
+ id: "app"
120
+ }, /*#__PURE__*/_react.default.createElement(_reactRedux.Provider, {
121
+ store: store
122
+ }, /*#__PURE__*/_react.default.createElement(_server.StaticRouter, {
123
+ context: context,
124
+ location: req.originalUrl
125
+ }, /*#__PURE__*/_react.default.createElement(_ServerRouter.default, {
126
+ store: store,
127
+ intialData: fetcherData
128
+ }))));
129
+ };
24
130
 
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
- // }
131
+ // sends document after rendering
132
+ const renderMarkUp = async (errorCode, req, res, metaTagFunction, fetcherData, store, matches, context) => {
133
+ const deviceDetails = (0, _userAgentUtil.getUserAgentDetails)(req.headers["user-agent"] || "");
134
+ const isBot = deviceDetails.googleBot ? true : false;
85
135
 
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
- }
136
+ // Transforms Head Props
137
+ const shellStart = await _render.default.renderStart(res.locals.pageCss, res.locals.pageJS, metaTagFunction, isBot, fetcherData);
138
+ let state = store.getState();
139
+ const jsx = webExtractor.collectChunks(getComponent(store, context, req, fetcherData));
140
+
141
+ // Transforms Body Props
142
+ const shellEnd = _render.default.renderEnd(webExtractor, state, res, jsx, errorCode, fetcherData);
143
+ const finalProps = _objectSpread(_objectSpread(_objectSpread({}, shellStart), shellEnd), {}, {
144
+ jsx: jsx,
145
+ req,
146
+ res
147
+ });
148
+ let CompleteDocument = () => {
149
+ if ((0, _validator.validateCustomDocument)(CustomDocument)) {
150
+ return CustomDocument(finalProps);
151
+ } else {
152
+ return /*#__PURE__*/_react.default.createElement("html", {
153
+ lang: finalProps.lang
154
+ }, /*#__PURE__*/_react.default.createElement(_document.Head, {
155
+ isBot: finalProps.isBot,
156
+ pageJS: finalProps.pageJS,
157
+ pageCss: finalProps.pageCss,
158
+ fetcherData: finalProps.fetcherData,
159
+ metaTagFunction: finalProps.metaTagFunction,
160
+ publicAssetPath: finalProps.publicAssetPath
161
+ }), /*#__PURE__*/_react.default.createElement(_document.Body, {
162
+ initialState: finalProps.initialState,
163
+ firstFoldCss: finalProps.firstFoldCss,
164
+ firstFoldJS: finalProps.firstFoldJS,
165
+ jsx: finalProps.jsx,
166
+ statusCode: finalProps.statusCode,
167
+ fetcherData: finalProps.fetcherData
168
+ }));
169
+ }
170
+ };
171
+ try {
172
+ let status = matches.length && matches[0].match.path === "*" ? 404 : 200;
173
+ res.set({
174
+ "content-type": "text/html; charset=utf-8"
175
+ });
176
+ res.status(status);
177
+ const {
178
+ pipe
179
+ } = (0, _server3.renderToPipeableStream)( /*#__PURE__*/_react.default.createElement(CompleteDocument, null), {
180
+ onShellReady() {
181
+ res.setHeader("content-type", "text/html");
182
+ pipe(res);
183
+ res.end();
184
+ },
185
+ onError(error) {
186
+ logger.error({
187
+ message: `\n Error while renderToPipeableStream : ${error.toString()}`
140
188
  });
141
- } catch (error) {
142
- logger.error("Error while rendering markup:" + error);
143
189
  }
144
- };
190
+ });
191
+ } catch (error) {
192
+ logger.error("Error in rendering document on server:" + error);
193
+ }
194
+ };
195
+
196
+ /**
197
+ * middleware for document handling
198
+ * @param {object} req - request object
199
+ * @param {object} res - response object
200
+ */
201
+ async function _default(req, res) {
202
+ try {
203
+ let context = {};
204
+ let fetcherData = {};
205
+ let metaTagFunction = null;
145
206
 
146
- // Server side function calling
147
- _App2.default.serverSideFunction({
207
+ // creates store
208
+ const store = (0, _validator.validateConfigureStore)(createStore) ? createStore({}, req) : null;
209
+
210
+ // user defined routes
211
+ const routes = (0, _validator.validateGetRoutes)(getRoutes) ? getRoutes() : [];
212
+
213
+ // Matches req url with routes
214
+ const matches = getMatchRoutes(routes, req, res, store, context, fetcherData);
215
+
216
+ // Executing app server side function
217
+ _App.default.serverSideFunction({
148
218
  store,
149
219
  req
150
220
  }).then(() => {
@@ -157,7 +227,7 @@ exports.default = async function (req, res) {
157
227
  });
158
228
  });
159
229
 
160
- // Api calling to fetch data
230
+ // Executing serverFetcher functions with serverDataFetcher provided by router and returning document
161
231
  Promise.all(serverSideFunction).then(() => {
162
232
  (0, _router.serverDataFetcher)({
163
233
  routes: routes,
@@ -167,62 +237,16 @@ exports.default = async function (req, res) {
167
237
  store
168
238
  }).then(res => {
169
239
  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);
240
+ }).then(async () => await renderMarkUp(null, req, res, metaTagFunction, fetcherData, store, matches, context)).catch(async error => {
241
+ logger.error("Error in executting serverFetcher functions: " + error);
242
+ await renderMarkUp(404, req, res, metaTagFunction, fetcherData, store, matches, context);
173
243
  });
174
244
  });
175
245
  }).catch(error => {
176
- logger.error("error in server side function is ====>" + error);
177
- renderMarkUp(error.status_code);
246
+ logger.error("Error in executing serverSideFunction inside App: " + error);
247
+ renderMarkUp(error.status_code, req, res, metaTagFunction, fetcherData, store, matches, context);
178
248
  });
179
249
  } catch (error) {
180
- logger.error("Error on server outer" + error.toString());
250
+ logger.error("Error in handling document request: " + error.toString());
181
251
  }
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
- */
252
+ }
@@ -3,11 +3,10 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- var _express = require("express");
7
- var _express2 = _interopRequireDefault(_express);
8
- var _handler = require("./handler");
9
- var _handler2 = _interopRequireDefault(_handler);
6
+ exports.default = void 0;
7
+ var _express = _interopRequireDefault(require("express"));
8
+ var _handler = _interopRequireDefault(require("./handler"));
10
9
  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;
10
+ const router = _express.default.Router();
11
+ router.use(_handler.default);
12
+ var _default = exports.default = router;
@@ -3,27 +3,23 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.default = void 0;
6
7
  var _extract = require("./extract");
7
8
  /**
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
9
+ * returns data which will be used in Head component for page rendering
10
+ * @param {string} pageCss - cached styles for page
11
+ * @param {string} pageJS - cached javscript elements for page
11
12
  * @param {function} metaTagFunction - user defined function which returns meta tags in array
12
13
  * @param {boolean} isBot - checks if request is made by bot
13
14
  * @param {object} fetcherData - router fetched data
14
15
  */
15
16
  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
17
  return {
22
18
  pageCss,
23
19
  pageJS,
24
20
  metaTagFunction,
25
21
  isBot,
26
- publicAssetPath,
22
+ publicAssetPath: `${process.env.PUBLIC_STATIC_ASSET_URL}${process.env.PUBLIC_STATIC_ASSET_PATH}`,
27
23
  fetcherData
28
24
  };
29
25
  };
@@ -34,27 +30,33 @@ const renderStart = (pageCss, pageJS, metaTagFunction, isBot, fetcherData) => {
34
30
  * @param {string} initialState - reducer initial state
35
31
  * @param {function} res - response object
36
32
  * @param {boolean} jsx - jsx which needs to be render on server side
37
- * @param {string|number|null} errorCode - error code
33
+ * @param {string|number|null} errorCode - error code
38
34
  * @param {object} fetcherData - router fetched data
39
35
  */
40
36
  const renderEnd = (webExtractor, initialState = {}, res, jsx, errorCode, fetcherData) => {
41
37
  // For bot first fold css and js would become complete page css and js
42
- let firstFoldCss = "",
43
- firstFoldJS = "",
44
- publicSWPath = "/assets";
38
+ let firstFoldCss = "";
39
+ let firstFoldJS = "";
45
40
  const isProd = process.env.NODE_ENV === "production";
46
41
  const {
47
42
  routePath,
48
43
  pageCss,
49
44
  pageJS
50
45
  } = res.locals;
51
- if (!isProd || routePath && (!pageCss || !pageJS)) {
46
+
47
+ // Development: Extracts styles and javascript elements for injecting in Body Component.
48
+ // NOTE: Caching of styles and javascript is not enabled in development.
49
+ if (!isProd) {
50
+ firstFoldCss = webExtractor.getStyleElements();
51
+ firstFoldJS = webExtractor.getScriptElements();
52
+ }
53
+
54
+ // Production: Extract styles and javscript elements if they are not found in cache and stores them in cache.
55
+ if (isProd && routePath && (!pageCss || !pageJS)) {
52
56
  firstFoldCss = webExtractor.getStyleElements();
53
57
  firstFoldJS = webExtractor.getScriptElements();
54
- if (isProd) {
55
- (0, _extract.cacheCSS)(routePath, webExtractor.getLinkElements());
56
- (0, _extract.cacheJS)(routePath, firstFoldJS);
57
- }
58
+ (0, _extract.cacheCSS)(routePath, webExtractor.getLinkElements());
59
+ (0, _extract.cacheJS)(routePath, webExtractor.getScriptElements());
58
60
  }
59
61
  return {
60
62
  initialState,
@@ -65,7 +67,7 @@ const renderEnd = (webExtractor, initialState = {}, res, jsx, errorCode, fetcher
65
67
  fetcherData
66
68
  };
67
69
  };
68
- exports.default = {
70
+ var _default = exports.default = {
69
71
  renderStart,
70
72
  renderEnd
71
73
  };
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+
3
+ var _expressServer = _interopRequireDefault(require("./expressServer.js"));
4
+ var _chokidar = _interopRequireDefault(require("chokidar"));
5
+ var _path = _interopRequireDefault(require("path"));
6
+ var _index = require("@server/index.js");
7
+ var _validator = require("./utils/validator.js");
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+ const env = process.env.NODE_ENV || "development";
10
+
11
+ // function defined by user which needs to run before server starts
12
+ if ((0, _validator.validatePreInitServer)(_index.preServerInit)) (0, _index.preServerInit)();
13
+ process.on("uncaughtException", (err, origin) => {
14
+ console.log(process.stderr.fd);
15
+ console.log(`Caught exception: ${err}\n` + `Exception origin: ${origin}`);
16
+ });
17
+ process.on("SIGINT", function (data) {
18
+ console.log("SIGINT");
19
+ console.log(data);
20
+ process.exit(0);
21
+ });
22
+ process.on("uncaughtExceptionMonitor", (err, origin) => {
23
+ console.log(err, origin);
24
+ });
25
+ process.on("message", function (msg) {
26
+ if (msg == "shutdown") {
27
+ console.log("Closing all connections...");
28
+ setTimeout(function () {
29
+ console.log("Finished closing connections");
30
+ process.exit(0);
31
+ }, 1500);
32
+ }
33
+ });
34
+ if (env === "development") {
35
+ // Add better stack tracing for promises in dev mode
36
+ process.on("unhandledRejection", r => console.debug(r));
37
+ }
38
+ const port = process.env.NODE_SERVER_PORT ?? 3005;
39
+ const host = process.env.NODE_SERVER_HOSTNAME ?? "localhost";
40
+ let statsPath = _path.default.join(__dirname, `../`, "loadable-stats.json");
41
+ if (env === "production") {
42
+ statsPath = _path.default.join(process.env.src_path, `${process.env.BUILD_OUTPUT_PATH}/public/loadable-stats.json`);
43
+ }
44
+ const watcher = _chokidar.default.watch(statsPath, {
45
+ persistent: true
46
+ });
47
+ console.log(`Waiting for chunks. Application server will be mounted when your assets are compiled.`);
48
+ watcher.on("all", (event, path) => {
49
+ if (event === "add") {
50
+ if (env == "production") {
51
+ watcher.close();
52
+ }
53
+ console.log("Starting Application Server...");
54
+ _expressServer.default.listen({
55
+ port,
56
+ host
57
+ }, error => {
58
+ if (error) {
59
+ console.log("An error occured while starting the Application server : ", error);
60
+ } else {
61
+ console.log(`Application server is mounted on http://${host}:${port}.`);
62
+ }
63
+ });
64
+ }
65
+ });
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getUserAgentDetails = void 0;
7
+ var _uaParserJs = _interopRequireDefault(require("ua-parser-js"));
8
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
9
+ 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; }
10
+ 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; }
11
+ 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; }
12
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
13
+ 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); }
14
+ const googleBots = {
15
+ "APIs-Google": "APIs-Google",
16
+ AdSense: "Mediapartners-Google",
17
+ "AdsBot Mobile Web Android": "AdsBot-Google-Mobile",
18
+ "AdsBot Mobile Web": "AdsBot-Google-Mobile",
19
+ AdsBot: "AdsBot-Google",
20
+ "Mobile AdSense": "Mediapartners-Google",
21
+ "Mobile Apps Android": "AdsBot-Google-Mobile-Apps",
22
+ Feedfetcher: "FeedFetcher-Google",
23
+ "Google Read Aloud": "Google-Read-Aloud",
24
+ "Duplex on the Web": "DuplexWeb-Google",
25
+ "Google Favicon": "Google Favicon",
26
+ "Web Light": "googleweblight",
27
+ "Amp crawler": "Google-AMPHTM",
28
+ Googlebot: "Googlebot"
29
+ };
30
+
31
+ /**
32
+ * check if user agent contains bot data
33
+ * @param {string} ua - user agent
34
+ * @return {string|null}
35
+ */
36
+ const getGoogleBot = ua => {
37
+ for (let key in googleBots) {
38
+ if (ua.includes(googleBots[key])) return key;
39
+ }
40
+ return null;
41
+ };
42
+
43
+ /**
44
+ * returns object which contains google bot and user-agent info
45
+ * @param {string} ua - user agent
46
+ * @return {object} - returns user agent
47
+ */
48
+ const getUserAgentDetails = ua => {
49
+ const agentDetails = (0, _uaParserJs.default)(ua);
50
+ const googleBot = getGoogleBot(ua);
51
+ return _objectSpread(_objectSpread({}, agentDetails), {}, {
52
+ googleBot
53
+ });
54
+ };
55
+ exports.getUserAgentDetails = getUserAgentDetails;