Skip to content

Commit

Permalink
feat(server/render): apply Flow's typing
Browse files Browse the repository at this point in the history
create getAssets to reducer boilerplate
  • Loading branch information
aneurysmjs committed May 26, 2019
1 parent 548ea26 commit 9c320fd
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 40 deletions.
15 changes: 1 addition & 14 deletions config/paths.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
// @flow strict
const path = require('path');
const fs = require('fs');

const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath);

type PathsType = {
clientBuild: string,
serverBuild: string,
dotenv: string,
src: string,
srcClient: string,
srcServer: string,
srcApp: string,
publicPath: string,
resolveModules?: Array<string>
};

const paths: PathsType = {
const paths = {
clientBuild: resolveApp('build/client'),
serverBuild: resolveApp('build/server'),
dotenv: resolveApp('.env'),
Expand Down
46 changes: 46 additions & 0 deletions flow-typed/npm/body-parser_v1.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// flow-typed signature: bac0ee66e0653772d037dc47b51a5e1f
// flow-typed version: da30fe6876/body-parser_v1.x.x/flow_>=v0.25.x

import type { Middleware, $Request, $Response } from "express";

declare type bodyParser$Options = {
inflate?: boolean,
limit?: number | string,
type?: string | string[] | ((req: $Request) => any),
verify?: (
req: $Request,
res: $Response,
buf: Buffer,
encoding: string
) => void
};

declare type bodyParser$OptionsText = bodyParser$Options & {
reviver?: (key: string, value: any) => any,
strict?: boolean
};

declare type bodyParser$OptionsJson = bodyParser$Options & {
reviver?: (key: string, value: any) => any,
strict?: boolean
};

declare type bodyParser$OptionsUrlencoded = bodyParser$Options & {
extended?: boolean,
parameterLimit?: number
};

declare module "body-parser" {
declare type Options = bodyParser$Options;
declare type OptionsText = bodyParser$OptionsText;
declare type OptionsJson = bodyParser$OptionsJson;
declare type OptionsUrlencoded = bodyParser$OptionsUrlencoded;

declare function json(options?: OptionsJson): Middleware;

declare function raw(options?: Options): Middleware;

declare function text(options?: OptionsText): Middleware;

declare function urlencoded(options?: OptionsUrlencoded): Middleware;
}
98 changes: 98 additions & 0 deletions flow-typed/npm/chalk_v2.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// flow-typed signature: db5b2cdde8db39d47e27cc8ab84f89bf
// flow-typed version: d662d43161/chalk_v2.x.x/flow_>=v0.25.x

// From: https://github.com/chalk/chalk/blob/master/index.js.flow

declare module "chalk" {
declare type TemplateStringsArray = $ReadOnlyArray<string>;

declare type Level = $Values<{
None: 0,
Basic: 1,
Ansi256: 2,
TrueColor: 3
}>;

declare type ChalkOptions = {|
enabled?: boolean,
level?: Level
|};

declare type ColorSupport = {|
level: Level,
hasBasic: boolean,
has256: boolean,
has16m: boolean
|};

declare interface Chalk {
(...text: string[]): string,
(text: TemplateStringsArray, ...placeholders: string[]): string,
constructor(options?: ChalkOptions): Chalk,
enabled: boolean,
level: Level,
rgb(r: number, g: number, b: number): Chalk,
hsl(h: number, s: number, l: number): Chalk,
hsv(h: number, s: number, v: number): Chalk,
hwb(h: number, w: number, b: number): Chalk,
bgHex(color: string): Chalk,
bgKeyword(color: string): Chalk,
bgRgb(r: number, g: number, b: number): Chalk,
bgHsl(h: number, s: number, l: number): Chalk,
bgHsv(h: number, s: number, v: number): Chalk,
bgHwb(h: number, w: number, b: number): Chalk,
hex(color: string): Chalk,
keyword(color: string): Chalk,

+reset: Chalk,
+bold: Chalk,
+dim: Chalk,
+italic: Chalk,
+underline: Chalk,
+inverse: Chalk,
+hidden: Chalk,
+strikethrough: Chalk,

+visible: Chalk,

+black: Chalk,
+red: Chalk,
+green: Chalk,
+yellow: Chalk,
+blue: Chalk,
+magenta: Chalk,
+cyan: Chalk,
+white: Chalk,
+gray: Chalk,
+grey: Chalk,
+blackBright: Chalk,
+redBright: Chalk,
+greenBright: Chalk,
+yellowBright: Chalk,
+blueBright: Chalk,
+magentaBright: Chalk,
+cyanBright: Chalk,
+whiteBright: Chalk,

+bgBlack: Chalk,
+bgRed: Chalk,
+bgGreen: Chalk,
+bgYellow: Chalk,
+bgBlue: Chalk,
+bgMagenta: Chalk,
+bgCyan: Chalk,
+bgWhite: Chalk,
+bgBlackBright: Chalk,
+bgRedBright: Chalk,
+bgGreenBright: Chalk,
+bgYellowBright: Chalk,
+bgBlueBright: Chalk,
+bgMagentaBright: Chalk,
+bgCyanBright: Chalk,
+bgWhiteBrigh: Chalk,

supportsColor: ColorSupport
}

declare module.exports: Chalk;
}
29 changes: 29 additions & 0 deletions flow-typed/npm/cors_v2.x.x.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// flow-typed signature: 8069c2f3f8822651cee2364cb0f777b5
// flow-typed version: 606c536da0/cors_v2.x.x/flow_>=v0.53.x

// @flow
import type { $Request as Request, $Response as Response, NextFunction } from "express";

interface RequestHandler {
(req: Request, res: Response, next?: NextFunction): mixed;
}

type CustomOrigin = (
requestOrigin: string,
callback: (err: Error | null, allow?: boolean) => void
) => void;

type CorsOptions = {
origin?: boolean | string | RegExp | string[] | RegExp[] | CustomOrigin;
methods?: string | string[];
allowedHeaders?: string | string[];
exposedHeaders?: string | string[];
credentials?: boolean;
maxAge?: number;
preflightContinue?: boolean;
optionsSuccessStatus?: number;
}

declare module "cors" {
declare module.exports: (options?: CorsOptions) => RequestHandler;
}
20 changes: 0 additions & 20 deletions src/app/store/actions/getProducts.js

This file was deleted.

2 changes: 1 addition & 1 deletion src/app/store/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import * as types from '../ActionTypes';

import makeActionCreator from './makeActionCreator';

export { default as getProducts } from './getProducts';
export { default as fetchProducts } from './fetchProducts';

export const setSelectedCountry = makeActionCreator(types.SET_SELECTED_PRODUCT, 'selectedCountry');
28 changes: 23 additions & 5 deletions src/server/render.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,52 @@
// @flow strict
import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter as Router } from 'react-router-dom';
// $FlowFixMe
import { Provider } from 'react-redux';

import type {
$Request,
$Response,
Middleware,
} from 'express';
import App from '@/App';

import Html from './components/HTML';

const serverRenderer = () => (req, res) => {
type GetAssetsType = ((string) => string) => (Array<string>) => Array<string>;

const getAssets: GetAssetsType = (fn) => (assets) => assets.map(fn);

const serverRenderer = (): Middleware => (req: $Request, res: $Response): $Response => {

const { assetPath } = res.locals;
// 'assetPath' doesn't match Express's mixed value, so we can ignore it
// $FlowIgnoreMe
const getAssetPath = getAssets(assetPath);

const content = renderToString(
/* $FlowIgnoreMe */
<Provider store={req.store}>
<Router location={req.url} context={{}}>
<App />
</Router>
</Provider>
);

const css = getAssetPath(['bundle.css', 'vendor.css']);
const scripts = getAssetPath(['bundle.js', 'vendor.js']);

return res.send(
'<!doctype html>' +
renderToString(
<Html
css={[res.locals.assetPath('bundle.css'), res.locals.assetPath('vendor.css')]}
scripts={[res.locals.assetPath('bundle.js'), res.locals.assetPath('vendor.js')]}
css={css}
scripts={scripts}
>
{content}
</Html>
)
);

};

export default serverRenderer;

0 comments on commit 9c320fd

Please sign in to comment.