/***************************************************************************************************
 * Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
 */ import '@angular/localize/init' ; import 'zone.js/node' ; import { renderModule } from '@angular/platform-server' ; import { join } from 'path' ; import { readFileSync , existsSync } from 'fs' ; import * as _url from 'url' ; import './server-polyfills' ; import { REQUEST , RESPONSE } from '@nguniversal/express-engine/tokens' ; import { TRANSLATIONS , TRANSLATIONS_FORMAT } from '@angular/core' ; import { NgxRequest , NgxResponse } from '@mindsorg/ngx-universal' ; import { EmbedServerModule } from './src/app/modules/embed/embed.server.module' ; import { AppServerModule } from './src/main.server' ; import * as express from 'express' ; import * as Sentry from '@sentry/node' ; import * as Tracing from '@sentry/tracing' ; import * as compression from 'compression' ; import * as cookieparser from 'cookie-parser' ; import isMobileOrTablet from './src/app/helpers/is-mobile-or-tablet' ; import { SENTRY } from './src/app/common/services/diagnostics/diagnostics.service' ; const browserDistFolder = join ( process . cwd ( ) , 'dist' , 'browser' ) ; const embedDistFolder = join ( process . cwd ( ) , 'dist' , 'embed' ) ; const PORT = process . env . PORT || 4200 ; export function app ( ) { const server = express ( ) ; server . use ( compression ( ) ) ; server . use ( cookieparser ( ) ) ; setupSentry ( server ) ; server . use ( '/embed-static' , express . static ( embedDistFolder ) ) ; server . get ( '*.*' , express . static ( browserDistFolder ) ) ; server . get ( '/socket.io' , ( req , res ) => { res . send ( 'You are using the wrong domain.' ) ; } ) ; server . get ( '/undefined' , ( req , res ) => { res . send ( 'There was problem' ) ; } ) ; const NodeCache = require ( 'node-cache' ) ; const myCache = new NodeCache ( { stdTTL : 5 * 60 , checkperiod : 120 } ) ; const cache = ( ) => { return ( req , res , next ) => { const sessKey = Object . entries ( req . cookies ) . filter ( kv => kv [ 0 ] !== 'mwa' && kv [ 0 ] !== 'XSRF-TOKEN' ) . join ( ':' ) || 'loggedout' ; const key = `__express__/${ sessKey }/` + `${ req . headers . host }` + ( req . originalUrl || req . url ) + `/${ req . headers [ 'x-minds-locale' ] }` + ( isMobileOrTablet ( ) ? '/mobile' : '/desktop' ) ; const exists = myCache . has ( key ) ; if ( exists ) { console . log ( `from cache: ${ key }` ) ; const cachedBody = myCache . get ( key ) ; res . send ( cachedBody ) ; res . end ( ) ; return ; } else { res . sendResponse = res . send ; res . send = body => { if ( res . status === 200 ) { myCache . set ( key , body ) ; } res . sendResponse ( body ) ; } ; next ( ) ; } } ; } ; const render = ( bootstrap , getDocument ? ) => async ( req , res ) => { const http = req . headers [ 'x-forwarded-proto' ] === undefined ? 'http' : req . headers [ 'x-forwarded-proto' ] ; const url = req . originalUrl ; const locale = getLocale ( req ) ; console . time ( `GET: ${ url }` ) ; const html = await renderModule ( bootstrap , { url : `${ req . protocol }://${ req . get ( 'host' ) || '' }${ req . originalUrl }` , document : getDocument ( locale ) , extraProviders : [ { provide : REQUEST , useValue : req , } , { provide : RESPONSE , useValue : res , } , { provide : NgxRequest , useValue : req , } , { provide : NgxResponse , useValue : res , } , { provide : 'ORIGIN_URL' , useValue : `${ http }://${ req . headers . host }` , } , { provide : 'QUERY_STRING' , useFactory : ( ) => _url . parse ( req . url , true ) . search || '' , deps : [ ] , } , { provide : TRANSLATIONS , useValue : getLocaleTranslations ( locale ) , } , { provide : TRANSLATIONS_FORMAT , useValue : 'xlf' } , { provide : SENTRY , useValue : Sentry } , ] , } ) ; res . send ( html ) ; console . timeEnd ( `GET: ${ url }` ) ; res . end ( ) ; } ; server . get ( `/embed/*` , cache ( ) , render ( EmbedServerModule , locale => readFileSync ( join ( embedDistFolder , `${ locale }/embed.html` ) ) . toString ( ) ) ) ; server . get ( '*' , cache ( ) , render ( AppServerModule , locale => readFileSync ( join ( browserDistFolder , `${ locale }/index.html` ) ) . toString ( ) ) ) ; server . use ( Sentry . Handlers . errorHandler ( ) ) ; return server ; } /**
 * Return a valid i18n locale
 */ function getLocale ( req ) { const defaultLocale = 'en' ; const hostLanguage = req . headers [ 'x-minds-locale' ] || defaultLocale ; if ( hostLanguage && hostLanguage . length === 2 ) { const path = join ( browserDistFolder , hostLanguage ) ; if ( existsSync ( path ) ) { return hostLanguage ; } } return defaultLocale ; } function getLocaleTranslations ( locale ) { let fileName ; if ( locale === 'en' ) { fileName = 'Base.xliff' ; } else { fileName = `Minds.${ locale }.xliff` ; } return require ( `raw-loader!./src/locale/${ fileName }` ) ; } function setupSentry ( server ) { Sentry . init ( { dsn : 'https://bbf22a249e89416884e8d6e82392324f@o293216.ingest.sentry.io/5729114' , integrations : [ new Sentry . Integrations . Http ( { tracing : true } ) , new Tracing . Integrations . Express ( { server } ) , ] , tracesSampleRate : 1.0 , } ) ; server . use ( Sentry . Handlers . requestHandler ( ) ) ; server . use ( Sentry . Handlers . tracingHandler ( ) ) ; } function run ( ) { const server = app ( ) ; server . listen ( PORT , ( ) => { console . log ( `Node Express server listening on http://localhost:${ PORT }` ) ; } ) ; } declare const __non_webpack_require__ ; const mainModule = __non_webpack_require__ . main ; const moduleFilename = ( mainModule && mainModule . filename ) || '' ; if ( moduleFilename === __filename || moduleFilename . includes ( 'iisnode' ) ) { run ( ) ; } export * from './src/main.server' ;