import React from 'react' ; import ReactDOMServer from 'react-dom/server' ; import { StaticRouter , matchPath } from 'react-router' ; import { Provider } from 'react-redux' ; import MetaTagsServer from 'react-meta-tags/server' ; import { MetaTagsContext } from 'react-meta-tags' ; import createStore from '../app/redux' ; import createRouter from '../app/router' ; import initData from '../app/init-data' ; import { authCookieName } from '@config' ; type Resolve = { code : number ; redirect ? : string ; html : string ; meta : string ; reduxState : string ; user : any ; } ; export default ( req , res ) => { return new Promise < Resolve > ( async ( resolve ) => { let params = { code : 200 , redirect : '' , html : '' , meta : '' , reduxState : '{}' , user : null } ; let store = createStore ( ) ; let [ err , user = null ] = await initData ( store , req . cookies [ authCookieName ] || '' ) ; params . user = user ; if ( err && err . blocked ) { res . clearCookie ( authCookieName ) ; params . code = 403 ; params . redirect = '/notice?notice=block_account' ; resolve ( params ) ; return ; } if ( err && err . message && err . message == 'invalid token' ) { res . clearCookie ( authCookieName ) ; params . code = 403 ; params . redirect = '/notice?notice=invalid_token' ; resolve ( params ) ; return ; } let router = createRouter ( { user } ) ; let route = null , match = null ; router . list . some ( ( _route ) => { let _match = matchPath ( req . path , _route ) ; if ( _match ) { _match . search = req . _parsedOriginalUrl . search || '' ; route = _route ; match = _match ; } return _match ; } ) ; if ( route . enter == 'tourists' && user ) { params . code = 403 ; params . redirect = '/' ; resolve ( params ) ; return ; } if ( route . enter == 'member' && ! user ) { params . code = 403 ; params . redirect = '/' ; resolve ( params ) ; return ; } if ( route . loadData ) { let { code , redirect } = await route . loadData ( { store , match , res , req , user } ) ; params . code = code ; params . redirect = redirect ; } const Page = router . dom ; let _p = await route . body . preload ( ) ; if ( _p . default . loadDataOnServer ) { let { code , redirect } = await _p . default . loadDataOnServer ( { store , match , res , req , user } ) ; params . code = code ; params . redirect = redirect ; } let metaTagsInstance = MetaTagsServer ( ) ; params . html = ReactDOMServer . renderToString ( < Provider store = { store } > < MetaTagsContext extract = { metaTagsInstance . extract } > < StaticRouter location = { req . url } > < Page /> < /StaticRouter> < /MetaTagsContext> < /Provider>); params . meta = metaTagsInstance . renderToString ( ) ; params . reduxState = JSON . stringify ( store . getState ( ) ) . replace ( /</g , '\\x3c' ) ; store = null ; router = null ; resolve ( params ) ; } ) ; } ;