I am learning Patterns in javascript I encountered Prototype Patterns which ideal for making default states in an object.
Example: I am creating Session with PrototypePattern. with some default states and methods like Jwt Sign and Check, getting user account detail's from a database, instance name, etc. so that after Object initialization you have some default handler's and thier configuration which only work's for given request or user.
Code:
'use strict'
/*
IMPORT'S.
*/
import _ from 'underscore' // npm; utility module.
import Jwt from 'jsonwebtoken' // npm: json webtoken library.
/*
PRISMA
*/
import { prisma } from '~prisma' // prisma: database library.
/*
DYNA
*/
import Cache from '~dyna_modules/Cache' // custom: redis cache library.
/*
OBJECT
*/
export default async function Session({ name, request }) {
// error handling.
try {
// properties.
this.name = name ? name.toUpperCase() : name
console.log(this, this.prototype)
// only proceed if request is defined
// else report failure.
if (!_.isEmpty(request) && _.isObject(request)) {
// only proceed if headers
// authorization is provided
// else report failure.
if (request.headers && request.headers.authorization) {
// local variable.
let _JwtCheck
// variable assignment.
_JwtCheck = this.Jwt.Verify(request.headers.authorization)
// verify given jwt if is
// valid token or not.
if (!_.isEmpty(_JwtCheck) && !(_JwtCheck instanceof Error)) {
// local variable.
let _Session
// variable assignment.
_Session = await this.Account({ '$exists': true }).Cache().includes(request.headers.authorization)
// if account with given authorization
// exist than get user details
if (_Session && !(_Session instanceof Error)) {
// update instance with
// session detail's.
this.account = _JwtCheck
this.chainValue = _Session
// report failure.
} else return _Session instanceof Error ? _Session : new Error('Auth token not found in Session. Please login again')
// report failure.
} else return _JwtCheck instanceof Error ? _JwtCheck : new Error('Expected account details but return undefined')
// report failure.
}
}
// return instance
return this
} catch (error) {
// report failure.
return error
}
}
/*
PROTOTYPE
*/
Session.prototype = {
// properties.
'name': 'SESSION',
'chainValue': null,
'account': null,
'configuration': {
'expireIn': '2 days'
},
// helper method's.
'includes': (__include) => { this.chainValue = this.chainValue.includes(__include); return this },
// jwt handler for handling jwt
// token's etc.
'Jwt': {
'Sign': async (__account) => {
// local variable.
let _SignedToken, _UserSessionCache
console.log(this) // undefined
// Please note that this is undefined here
// and we need some configuration values like
// this.name and this.configuration.expireIn
// but you can't because this is undefined for
// that i referenced them directly to prototype
// this.name 'became' Session.prototype.name
// this.configuration 'became' Session.protype.configuration
// sign toke and update cache.
_SignedToken = Jwt.sign(__account, process.env.TRUCKPE_SECRET, { 'expiresIn': Session.prototype.configuration.expireIn });
_UserSessionCache = await Cache({ _id: `${Session.prototype.name}::${__account._id}` })
_UserSessionCache = _UserSessionCache && _UserSessionCache.Cache && typeof _UserSessionCache.Cache === typeof [] ? _UserSessionCache.Cache : null
_UserSessionCache = _.isArray(_UserSessionCache) && !_UserSessionCache.includes(_SignedToken) ? [ ..._UserSessionCache, _SignedToken ] : [_SignedToken]
// run cache again.
_UserSessionCache = await Cache({ '_id': `SESSION::${__account._id}`, 'whatToCache': _UserSessionCache, 'options': { 'expireIn': Session.prototype.configuration.expireIn } })
// on successful cacheUpdate reply to
// client.
if(!_.isEmpty(_UserSessionCache) && !(_UserSessionCache instanceof Error)) {
// update chainValue.
Session.prototype.chainValue = Session.prototype.account = __account
// register jwt token and
// return.
return _SignedToken
// report failure.
} else return _UserSessionCache instanceof Error ? _UserSessionCache : new Error('Expected Cache update for session but return was undefined')
},
'Verify': async (__token) => {
// error handling.
try {
// local variable.
let _JwtVerify
// variable assingment.
_JwtVerify = await Jwt.verify(__token, process.env.TRUCKPE_SECRET);
// if _jwtVerify contain's error
// than report failure else return
// this.
if (!_.isEmpty(_JwtVerify) && !(_JwtVerify instanceof Error)) {
// update chain value.
Session.prototype.chainValue = Session.prototype.account = _JwtVerify
// return instance.
return Session.prototype
// report failure.
} else return _JwtVerify instanceof Error ? _JwtVerify : new Error(`Caught exception JwtVerify return undefined`)
} catch (error) {
// report failure.
return error
}
}
},
// account handler for handling
// user account in prisma
'Account': async (options) => {
// error handling.
try {
// local variable.
let _id, _getAccountDetail
// re-assingment.
_id = typeof this.chainValue === typeof {} ? this.chainValue['_id'] : typeof this.chainValue === typeof 'String' ? this.chainValue : this.account ? this.account['_id'] : null
// variable assingment.
_getAccountDetail = options && options.$exists ? await prisma.account({ _id }).$exists() : await prisma.account({ _id })
// if getting account detail
// contain's error than report
// failure else return account
// detail's.
if (_getAccountDetail && !(_getAccountDetail instanceof Error)) {
// update chainValue.
this.chainValue = _getAccountDetail
// return instance.
return this
} else return _getAccountDetail instanceof Error ? _getAccountDetail : new Error(`Caught exception while fetching account details from database`)
} catch (error) {
// report failure.
return error
}
},
// cache handler for caching session
// and other details.
'Cache': async (options) => {
// error handling.
try {
// local variable.
let _id, _getCache
// variable re-assingment.
_id = typeof this.chainValue === typeof {} ? this.chainValue['_id'] : typeof this.chainValue === typeof 'String' ? this.chainValue : this.account ? this.account['_id'] : null
// variable assingment.
_getCache = options && options.save ? await Cache({ '_id': `${this.name}::${_id}`, 'whatToCache': this.chainValue }) : await Cache({ '_id': `${this.name}::${_id}` });
// if getting cache contains' error
// than report failure.
if (!(_getCache instanceof Error)) {
// update chainValue.
this.chainValue = _getCache
// return instanceof
return this
// report failure
} else return _getCache
} catch (error) {
// report failure.
return error
}
}
}
Problem 1:
let _Session = new Session({ request })
console.log(_Session) // { account: null, name: undefined }
console.log(_Session.prototype) // undefined why ?
Problem 2.
_Session.Jwt.Sign({ username: 'bla', 'email': 'lost@stackoverflow.com' })
If you run above code and do console.log(this) inside Session.prototype.Jwt.Sign you will receive undefined I have commented Problem in code. all I want is my prototype properties and method to work as default properties but inside Jwt. Sign you always lost "this" ?
Aucun commentaire:
Enregistrer un commentaire