nest-jsx-template-engine
Advanced tools
Comparing version 0.2.1 to 0.2.2
@@ -13,6 +13,6 @@ "use strict"; | ||
} | ||
if (child && typeof child.toString === 'function') { | ||
else if (child && typeof child.toString === 'function') { | ||
stringifiedChild = child.toString(); | ||
} | ||
if (!child) { | ||
if (!child && child !== null) { | ||
stringifiedChild = `${child}`; | ||
@@ -19,0 +19,0 @@ } |
@@ -21,6 +21,6 @@ interface ParamFunc { | ||
} | ||
interface RenderFunc<T extends RenderProps> { | ||
(props: T): string; | ||
interface RenderFunc<T> { | ||
(data: T, props: RenderProps): string; | ||
} | ||
} | ||
export {}; |
import { NestMiddleware } from '@nestjs/common'; | ||
import { Request, Response } from 'express'; | ||
export declare class RenderMiddleware implements NestMiddleware { | ||
use(req: Request, res: Response, next: Function): void; | ||
use(req: Request, res: Response, next: Function): any; | ||
private createLocalDecoration; | ||
protected applyStrictAcceptHtmlCheck(): boolean; | ||
protected decorateRenderProps(req: Request, res: Response): object; | ||
} |
@@ -13,2 +13,5 @@ "use strict"; | ||
use(req, res, next) { | ||
if (this.applyStrictAcceptHtmlCheck() && !req.accepts('html')) { | ||
return next(); | ||
} | ||
const oRender = res.render.bind(res); | ||
@@ -21,3 +24,3 @@ const createDecoration = this.createLocalDecoration.bind(this, req, res); | ||
try { | ||
res.send(template(Object.assign(Object.assign(Object.assign(Object.assign({}, this.app.locals || {}), this.locals || {}), createDecoration()), opt || {}))); | ||
res.send(template(opt, Object.assign(Object.assign(Object.assign({}, this.app.locals || {}), this.locals || {}), createDecoration()))); | ||
} | ||
@@ -31,4 +34,3 @@ catch (err) { | ||
createLocalDecoration(req, res) { | ||
return { | ||
$req: { | ||
return Object.assign(Object.assign({}, this.decorateRenderProps(req, res)), { $req: { | ||
path: req.path, | ||
@@ -45,5 +47,10 @@ method: req.method, | ||
body: req.body | ||
} | ||
}; | ||
} }); | ||
} | ||
applyStrictAcceptHtmlCheck() { | ||
return true; | ||
} | ||
decorateRenderProps(req, res) { | ||
return {}; | ||
} | ||
}; | ||
@@ -50,0 +57,0 @@ RenderMiddleware = __decorate([ |
import 'reflect-metadata'; | ||
import { JSXTemplate } from './interfaces/render'; | ||
export declare function Render<T extends JSXTemplate.RenderProps>(template: (props: T) => string): MethodDecorator; | ||
export declare function Render<T>(template: (data: T, props: JSXTemplate.RenderProps) => string): MethodDecorator; |
{ | ||
"name": "nest-jsx-template-engine", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"description": "JSX-based + typescript template engine for NestJS applications", | ||
@@ -30,3 +30,3 @@ "main": "dist/index.js", | ||
"express": "^4.17.1", | ||
"rxjs": "^6.5.5", | ||
"rxjs": "^6.6.0", | ||
"typescript": "^3.9.5" | ||
@@ -33,0 +33,0 @@ }, |
@@ -9,2 +9,6 @@ # nestjs-jsx-template-engine | ||
> :warning: **WIP**: this package is still in progress and that API is _extremely_ volatile. Suggest not using in production. | ||
## Installation | ||
@@ -49,2 +53,4 @@ | ||
> :warning: by default, the middleware will _not_ render the template for requests that do not expect HTML in the header (e.g., `Accept: 'text/html'`). It will merely return the value from the controller. You can modify this behavior by extending the middleware class. | ||
## Rendering | ||
@@ -66,3 +72,3 @@ | ||
@Render<IAppProps>(App) // pass the App view directly to the Render decorator | ||
getHello(): Partial<IAppProps> { | ||
getHello(): IAppProps { | ||
return this.appService.getHello(); | ||
@@ -77,12 +83,17 @@ } | ||
import { h, JSXTemplate } from 'nest-jsx-template-engine' | ||
import { AppViewTransferObject } from './app.vto' | ||
export interface IAppProps extends JSXTemplate.RenderProps { | ||
export interface IAppProps { | ||
name: string | ||
} | ||
export function App(props: IAppProps): string { | ||
/** | ||
* @param {any} data the value returned from the controller | ||
* @param {JSXTemplate.RenderProps} props framework provided props containing request. | ||
* | ||
* See below on extending the props passed | ||
*/ | ||
export function App(data: IAppProps, props: JSXTemplate.RenderProps): string { | ||
return <html> | ||
<body> | ||
<h1 class="foo">{props.name}</h1> | ||
<h1 class="foo">{data.name}</h1> | ||
<div>Request Path: {props.$req.path} from ip: {props.$req.ip} | ||
@@ -96,4 +107,39 @@ </body> | ||
## Extending Render behavior | ||
The Render behavior provided by the middleware can be overriden in two key ways by sub-classing the middleware. | ||
```typescript | ||
import { RenderMiddleware, JSXTemplate } from 'next-jsx-template-engine'; | ||
export interface CustomRenderProps extends JSXTemplate.RenderProps { | ||
$foo: boolean | ||
} | ||
export class CustomRenderMiddleware { | ||
// by default, the middleware will not render requests that do not expect HTML in the response. | ||
// returning false will disable this check. You can do this variably by introspecting the req object | ||
applyStrictAcceptHtmlCheck(req: Request): boolean { | ||
// returning false means that the template will be rendered for all requests, | ||
// regardless of client's accept headers. | ||
return false; | ||
} | ||
// apply additional request/response specific properties that will be passed as | ||
// the second parameter to the JSX template along with the data returned from | ||
// the controller. | ||
// | ||
// Common use-cases might be supplying session data, CSRF tokens, etc. | ||
decorateRenderProps(req: Request, res: Response): Partial<CustomRenderProps> { | ||
return { | ||
$foo: false | ||
} | ||
} | ||
} | ||
``` | ||
## A Note on React-Flavored JSX | ||
This package does not support React flavored JSX (e.g., `className`, `htmlFor`, etc). It expects basic HTML properties. |
@@ -22,5 +22,5 @@ interface ParamFunc { | ||
} | ||
export interface RenderFunc<T extends RenderProps> { | ||
(props: T): string | ||
export interface RenderFunc<T> { | ||
(data: T, props: RenderProps): string | ||
} | ||
} |
@@ -8,2 +8,8 @@ import { Injectable, NestMiddleware } from '@nestjs/common'; | ||
use(req: Request, res: Response, next: Function) { | ||
// abort HTML rendering if response doesn't want html | ||
if (this.applyStrictAcceptHtmlCheck(req) && !req.accepts('html')) { | ||
return next(); | ||
} | ||
const oRender = res.render.bind(res); | ||
@@ -13,3 +19,3 @@ const createDecoration = this.createLocalDecoration.bind(this, req, res); | ||
// apply overload to render method | ||
res.render = function(template, opt: any) { | ||
res.render = function (template: string | JSXTemplate.RenderFunc<any>, opt: any) { | ||
if (typeof template === 'string') { | ||
@@ -19,8 +25,12 @@ return oRender(template, opt); | ||
try { | ||
res.send(template({ | ||
...this.app.locals || {}, | ||
...this.locals || {}, | ||
...createDecoration(), | ||
...opt || {} | ||
}) as JSXTemplate.RenderFunc<JSXTemplate.RenderProps>); | ||
res.send( | ||
template( | ||
opt, | ||
{ | ||
...this.app.locals || {}, | ||
...this.locals || {}, | ||
...createDecoration(), | ||
} as JSXTemplate.RenderProps | ||
) | ||
); | ||
} catch (err) { | ||
@@ -33,5 +43,6 @@ this.req.next(err); | ||
} | ||
private createLocalDecoration(req: Request, res: Response): JSXTemplate.RenderProps { | ||
return { | ||
...this.decorateRenderProps(req, res), | ||
$req: { | ||
@@ -49,5 +60,20 @@ path: req.path, | ||
body: req.body | ||
} | ||
}, | ||
} | ||
} | ||
/** | ||
* Override this method to change the middleware behavior | ||
*/ | ||
protected applyStrictAcceptHtmlCheck(req: Request): boolean { | ||
return true | ||
} | ||
/** | ||
* Override this method to apply additional decorations to the RenderProps | ||
*/ | ||
protected decorateRenderProps(req: Request, res: Response): object { | ||
return {} | ||
} | ||
} |
@@ -14,3 +14,3 @@ import 'reflect-metadata'; | ||
*/ | ||
export function Render<T extends JSXTemplate.RenderProps>(template: (props: T) => string): MethodDecorator { | ||
export function Render<T>(template: (data: T, props: JSXTemplate.RenderProps) => string): MethodDecorator { | ||
return ( | ||
@@ -17,0 +17,0 @@ target: object, |
@@ -17,4 +17,4 @@ { | ||
"include": [ | ||
"src/**/*" | ||
"./src/**/*" | ||
] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
364215
334
140