META-PROGRAMMING IN JAVASCRIPT WITH A BIT OF HELP FROM TYPESCRIPT
Orel Balilti
November 2018
Fullstack developer @Philips Healthcare
About Me
Meta-programming
Descriptor – what is it?
Descriptor object (common usage)
Descriptor object (common usage)
Descriptor object (meta usage)
Descriptor handling
Descriptor handling
Examples
Descriptor handling (Reflect way)
Descriptor handling (Reflect way)
Examples
Custom behavior change with Proxy
Overloading operators
Examples
Decorator – what is it?
Class decorator
function Decoration(targetConstructor: Function)
Property decorator
function PropertyDecorator(targetObject: any, property: string)
Method decorator
function MethodDecorator(targetObject: any, property: string, property: PropertyDescriptor)
Reflect-metadata
Examples
Usage example - SugoiJS
To transform this
export class IndexController{� get(req,res,next){� authorization(req,["admin","user"],["USER.CREATE"])� .then(()=>{� � })� }�� set(req,res,next){� authorization(req,["admin","user"],["USER.CREATE"])� .then(()=>{� const body = req.body;� if(!validateUserObject(body))� return res.status(400).json({message:"invalid body"})� })� .catch(err=>{� return res.status(401).json({message:"unauthorized"})� })� }�� update(req,res,next){� authorization(req,["admin","user"],["USER.CREATE"])� .then(()=>{� const id = req.param.id;� const body = req.body;� if(!validateUserObject(body) || !(!!id && typeof id === "string")� return res.status(400).json({message:"invalid params"})� User.updateById(id,body)� .then(response=>res.status(200).json(response))� .catch(err=>res.status(500).json(err));� })� .catch(err=>{� return res.status(401).json({message:"unauthorized"})� })� }�� remove(req,res,next){� authorization(req,["admin","user"],["USER.CREATE"])� .then(()=>{� � })� }�}
function validateUserObject(user){� if(!(!!user.name && typeof user.name === "string")){� return false;� }� if(!(user.age != null && typeof user.age === "number" && user.age>0)){� return false;� }� return true;�}��function authorization(req,roles,permissions){� return Authorization.isAuthorized(req)� .then(()=>Authorization.allowsTo(req,permissions))� .then(()=>Authorization.isInRole(req,roles)�}
app.get("/api",IndexController.get);�app.post("/api",IndexController.set);�app.put("/api/:id",IndexController.update);�app.delete("/api:id",IndexController.remove);
Into this
@Authorized(["admin","user"],"USER.CREATE")�@Controller("/api")�export class IndexController{� @HttpGet("")� get(){}�� @HttpPost("")� @RequestBodySchemaPolicy(UserSchema)� async set( @RequestBody() body:User){}�� @HttpPut("/:id")� @RequestSchemaPolicy({� id:ComparableSchema.ofType(SchemaTypes.STRING).setMandatory(true)� }, null,UserSchema)� async update(@RequestParam("id") id:string,
@RequestBody() body:User){� return await User.updateById(id,body);� }�� @HttpDelete("/:id")� @RequestParamsSchemaPolicy({� id:ComparableSchema.ofType(SchemaTypes.STRING).setMandatory(true)� })� async remove(@RequestParam("id") id:string){}�}
Examples
Summary
Questions?
Resources