Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const async_middleware_1 = require("async-middleware");
const compression = require("compression");
const continuation_local_storage_1 = require("continuation-local-storage");
const express = require("express");
const HttpStatus = require("http-status-codes");
require("log-timestamp");
const Mustache = require("mustache");
const raynor_1 = require("raynor");
const React = require("react");
const ReactDOMServer = require("react-dom/server");
const react_helmet_1 = require("react-helmet");
const react_redux_1 = require("react-redux");
const react_router_dom_1 = require("react-router-dom");
const webpack = require("webpack");
const theWebpackDevMiddleware = require("webpack-dev-middleware");
const serializeJavascript = require("serialize-javascript");
const business_rules_js_1 = require("@truesparrow/business-rules-js");
const common_js_1 = require("@truesparrow/common-js");
const common_server_js_1 = require("@truesparrow/common-server-js");
const content_sdk_js_1 = require("@truesparrow/content-sdk-js");
const identity_sdk_js_1 = require("@truesparrow/identity-sdk-js");
const server_1 = require("@truesparrow/identity-sdk-js/server");
const bundles_1 = require("./bundles");
const app_frame_1 = require("../shared/app-frame");
const config = require("../shared/config");
const client_data_1 = require("../shared/client-data");
const store_1 = require("../shared/store");
function main() {
    return __awaiter(this, void 0, void 0, function* () {
        // Global setup, but hidden inside main()
        // ********************
        const webpackConfig = require('../../webpack.config.js');
        const clientConfigMarshaller = new (raynor_1.MarshalFrom(client_data_1.ClientConfig))();
        const clientInitialStateMarshaller = new (raynor_1.MarshalFrom(client_data_1.ClientInitialState))();
        const internalWebFetcher = new common_js_1.InternalWebFetcher();
        const identityClient = identity_sdk_js_1.newIdentityClient(config.INTERNAL_ORIGIN, `${config.IDENTITY_SERVICE_HOST}:${config.IDENTITY_SERVICE_PORT}`, internalWebFetcher);
        const contentPrivateClient = content_sdk_js_1.newContentPrivateClient(config.INTERNAL_ORIGIN, `${config.CONTENT_SERVICE_HOST}:${config.CONTENT_SERVICE_PORT}`, internalWebFetcher);
        const bundles = common_js_1.isLocal(config.ENV)
            ? new bundles_1.WebpackDevBundles(theWebpackDevMiddleware(webpack(webpackConfig), {
                //Different because we're mounting on /real/client to boot webpackConfig.output.publicPath,
                publicPath: '/',
                serverSideRender: false
            }))
            : new bundles_1.CompiledBundles();
        const namespace = continuation_local_storage_1.createNamespace(config.CLS_NAMESPACE_NAME);
        console.log('Starting up');
        function serverSideRender(url, session, clientInitialState) {
            const language = business_rules_js_1.inferLanguage(session);
            const store = store_1.createStoreFromInitialState(store_1.reducers, clientInitialState);
            const clientConfig = {
                allowedPaths: config.ALLOWED_PATHS,
                env: config.ENV,
                internalOrigin: config.INTERNAL_ORIGIN,
                externalOrigin: config.EXTERNAL_ORIGIN,
                contactEmail: config.CONTACT_EMAIL,
                styleApplicationName: config.STYLE_APPLICATION_NAME,
                styleLogoUri: config.STYLE_LOGO_URI,
                stylePrimaryColor: config.STYLE_PRIMARY_COLOR,
                siteFeExternalHost: config.SITEFE_EXTERNAL_HOST,
                contentServiceHost: config.CONTENT_SERVICE_HOST,
                contentServicePort: config.CONTENT_SERVICE_PORT,
                auth0ClientId: config.AUTH0_CLIENT_CONFIG.clientId,
                auth0Domain: config.AUTH0_CLIENT_CONFIG.domain,
                auth0LoginCallbackUri: config.AUTH0_CLIENT_CONFIG.loginCallbackUri,
                logoutRoutePath: config.LOGOUT_ROUTE_PATH,
                fileStackApiKey: config.FILESTACK_API_KEY,
                rollbarClientToken: null,
                session: session,
                language: language
            };
            namespace.set('SESSION', session);
            namespace.set('LANG', language);
            const staticContext = {};
            const appHtml = ReactDOMServer.renderToString(React.createElement(react_redux_1.Provider, { store: store },
                React.createElement(react_router_dom_1.StaticRouter, { location: url, context: staticContext },
                    React.createElement(app_frame_1.AppFrame, null))));
            const specialStatus = staticContext.status == HttpStatus.NOT_FOUND ? HttpStatus.NOT_FOUND : null;
            const helmetData = react_helmet_1.Helmet.renderStatic();
            return [Mustache.render(bundles.getHtmlIndexTemplate(), {
                    GOOGLE_MAPS_API_KEY: config.GOOGLE_MAPS_API_KEY,
                    PAGE_TITLE_HTML: helmetData.title,
                    PAGE_META_HTML: helmetData.meta,
                    PAGE_LINK_HTML: helmetData.link,
                    STYLE_PRIMARY_COLOR: config.STYLE_PRIMARY_COLOR,
                    STYLE_GRAY_COLOR: config.STYLE_GRAY_COLOR,
                    APP_HTML: appHtml,
                    CLIENT_CONFIG: serializeJavascript(clientConfigMarshaller.pack(clientConfig), { isJSON: true }),
                    CLIENT_INITIAL_STATE: serializeJavascript(clientInitialStateMarshaller.pack(clientInitialState), { isJSON: true }),
                    WEBPACK_MANIFEST_JS: bundles.getManifestJs(),
                }), specialStatus];
        }
        console.log('Starting web server');
        const app = express();
        // Setup global properties and behaviours of the application
        // ********************
        app.disable('x-powered-by');
        app.use(common_server_js_1.newNamespaceMiddleware(namespace));
        if (true || common_js_1.isNotOnServer(config.ENV)) {
            app.use(common_server_js_1.newLocalCommonServerMiddleware(config.NAME, config.ENV, false));
        }
        else {
            // app.use(newCommonServerMiddleware(
            //     config.NAME,
            //     config.ENV,
            //     config.LOGGLY_TOKEN as string,
            //     config.LOGGLY_SUBDOMAIN as string,
            //     config.ROLLBAR_SERVER_TOKEN as string));
        }
        app.use(common_server_js_1.newCommonFrontendServerMiddleware(config.ENV, ['/status/check']));
        app.use(compression({ threshold: 0 }));
        // Setup the /real portion of the path-space. Here are things which don't belong to the client-side
        // interaction, but rather to the server-side one, callbacks from other services etc.
        // ********************
        // Setup the auth0 authentication flow. Has a complex dance wrt sessions.
        app.use('/real/auth0-auth-flow', server_1.newAuth0AuthFlowRouter(config.ENV, config.ALLOWED_PATHS, config.AUTH0_SERVER_CONFIG, internalWebFetcher, identityClient));
        // An API gateway for the client side code. Needs session to exist in the request.
        app.use('/real/api-gateway', server_1.newApiGatewayRouter(config.INTERNAL_ORIGIN, internalWebFetcher));
        // Static serving of the client side code assets (index.html, vendor.js etc). No session. Derived
        // from the bundles.
        app.use('/real/client', bundles.getOtherBundlesRouter());
        // Still a service after all and this will allow health checks & metrics etc.
        app.use('/status', common_server_js_1.newHealthCheckRouter());
        // Setup serving of a bunch of files for interacting with the web at large, such as robots.txt,
        // sitemaps etc. These are derived from the bundles, with some extra data baked in. No session.
        // ********************
        const siteInfoRouter = express.Router();
        siteInfoRouter.get('/robots.txt', (_req, res) => {
            res.status(HttpStatus.OK);
            res.type('.txt');
            res.write(Mustache.render(bundles.getRobotsTxt(), { HOME_URI: config.EXTERNAL_ORIGIN }));
            res.end();
        });
        siteInfoRouter.get('/humans.txt', (_req, res) => {
            res.status(HttpStatus.OK);
            res.type('.txt');
            res.write(bundles.getHumansTxt());
            res.end();
        });
        siteInfoRouter.get('/sitemap.xml', (_req, res) => {
            res.status(HttpStatus.OK);
            res.type('application/xml; charset=utf-8');
            res.write(Mustache.render(bundles.getSitemapXml(), {
                HOME_URI: config.EXTERNAL_ORIGIN,
                HOME_LAST_MOD: new Date().toISOString()
            }));
            res.end();
        });
        siteInfoRouter.get('/browserconfig.xml', (_req, res) => {
            res.status(HttpStatus.OK);
            res.type('application/xml; charset=utf-8');
            res.write(Mustache.render(bundles.getBrowserConfigXml(), {
                STYLE_PRIMARY_COLOR: config.STYLE_PRIMARY_COLOR
            }));
            res.end();
        });
        siteInfoRouter.get('/site.webmanifest', (_req, res) => {
            res.status(HttpStatus.OK);
            res.type('.txt');
            res.write(Mustache.render(bundles.getSiteWebManifest(), {
                EXTERNAL_ORIGIN: config.EXTERNAL_ORIGIN,
                STYLE_APPLICATION_NAME: config.STYLE_APPLICATION_NAME,
                STYLE_PRIMARY_COLOR: config.STYLE_PRIMARY_COLOR
            }));
            res.end();
        });
        app.use('/', siteInfoRouter);
        // Setup serving for all all client application level routes. Any path a user enters, which
        // doesn't match the ones from above (so /real ones or standard web ones) will be handled
        // by serving the "client application". This translated to doing a server-side render of the
        // application and serving that embedded into {@link src/shared/static/index.html}, which
        // will reference /real/client/client.js and other static resources in order to boot it up.
        // ********************
        const appRouter = express.Router();
        appRouter.use(server_1.newSessionMiddleware(server_1.SessionLevel.None, server_1.SessionInfoSource.Cookie, config.ENV, identityClient));
        appRouter.get('*', async_middleware_1.wrap((req, res) => __awaiter(this, void 0, void 0, function* () {
            let event = null;
            if (req.session.hasUser()) {
                try {
                    event = yield contentPrivateClient.withContext(req.sessionToken).getEvent();
                }
                catch (e) {
                    if (e.name == 'EventNotFoundError') {
                        try {
                            event = yield contentPrivateClient.withContext(req.sessionToken).createEvent(req.session);
                        }
                        catch (e) {
                            // Nothing happens here. We'll try again on the client. But we do log the error.
                            req.log.warn(e);
                            req.errorLog.warn(e);
                        }
                    }
                    else {
                        // Nothing happens here. We'll try again on the client. But we do log the error.
                        req.log.warn(e);
                        req.errorLog.warn(e);
                    }
                }
            }
            const initialState = {
                event: event
            };
            const [content, specialStatus] = serverSideRender(req.url, req.session, initialState);
            res.status(specialStatus != null ? specialStatus : HttpStatus.OK);
            res.type('html');
            res.write(content);
            res.end();
        })));
        app.use('/', appRouter);
        // Start serving
        // ********************
        app.listen(config.PORT, '0.0.0.0', () => {
            console.log(`Started ${config.NAME} service on ${config.PORT}`);
        });
    });
}
main();
//# sourceMappingURL=index.js.map