Decorators (#42)

Adds decorator functionality to BaseService
This commit is contained in:
Sebastian Rindom
2020-04-30 21:39:30 +02:00
committed by GitHub
parent 2273cc519a
commit feda00d2d1
12 changed files with 2428 additions and 45 deletions

View File

@@ -22,6 +22,7 @@
"@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-env": "^7.7.5",
"cross-env": "^5.2.1",
"jest": "^25.5.2",
"eslint": "^6.8.0"
},
"dependencies": {

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,7 @@
"@babel/preset-env": "^7.7.5",
"client-sessions": "^0.8.0",
"cross-env": "^5.2.1",
"jest": "^25.5.2",
"eslint": "^6.8.0"
},
"scripts": {

View File

@@ -0,0 +1,9 @@
{
"plugins": ["prettier"],
"extends": ["prettier"],
"rules": {
"prettier/prettier": "error",
"semi": "error",
"no-unused-expressions": "true"
}
}

View File

@@ -0,0 +1,7 @@
{
"endOfLine": "lf",
"semi": false,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5"
}

View File

@@ -11,7 +11,8 @@
"scripts": {
"build": "babel src --out-dir dist/ --ignore **/__tests__",
"prepare": "cross-env NODE_ENV=production npm run build",
"watch": "babel -w src --out-dir dist/ --ignore **/__tests__"
"watch": "babel -w src --out-dir dist/ --ignore **/__tests__",
"test": "jest"
},
"author": "Sebastian Rindom",
"license": "AGPL-3.0-or-later",
@@ -22,7 +23,9 @@
"@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-env": "^7.7.5",
"cross-env": "^5.2.1",
"eslint": "^6.8.0"
"eslint": "^6.8.0",
"jest": "^25.5.2",
"prettier": "^1.19.1"
},
"dependencies": {
"mongoose": "^5.8.0"

View File

@@ -0,0 +1,66 @@
import BaseService from "../base-service"
describe("BaseService", () => {
describe("addDecorator", () => {
const baseService = new BaseService()
it("successfully adds decorator", () => {
baseService.addDecorator(obj => {
return (obj.decorator1 = true)
})
expect(baseService.decorators_.length).toEqual(1)
})
it("throws if decorator is not a function", () => {
expect(() => baseService.addDecorator("not a function")).toThrow(
"Decorators must be of type function"
)
})
})
describe("runDecorators_", () => {
it("returns success when passwords match", async () => {
const baseService = new BaseService()
baseService.addDecorator(obj => {
obj.decorator1 = true
return obj
})
baseService.addDecorator(obj => {
obj.decorator2 = true
return obj
})
const result = await baseService.runDecorators_({ data: "initial" })
expect(result).toEqual({
data: "initial",
decorator1: true,
decorator2: true,
})
})
it("skips failing decorator", async () => {
const baseService = new BaseService()
baseService.addDecorator(obj => {
obj.decorator1 = true
return obj
})
baseService.addDecorator(obj => {
return Promise.reject("fail")
})
baseService.addDecorator(obj => {
obj.decorator3 = true
return Promise.resolve(obj)
})
const result = await baseService.runDecorators_({ data: "initial" })
expect(result).toEqual({
data: "initial",
decorator1: true,
decorator3: true,
})
})
})
})

View File

@@ -2,5 +2,35 @@
* Common functionality for Services
* @interface
*/
class BaseService {}
class BaseService {
constructor() {
this.decorators_ = []
}
/**
* Adds a decorator to a service. The decorator must be a function and should
* return a decorated object.
* @param {function} fn - the decorator to add to the service
*/
addDecorator(fn) {
if (typeof fn !== "function") {
throw Error("Decorators must be of type function")
}
this.decorators_.push(fn)
}
/**
* Runs the decorators registered on the service. The decorators are run in
* the order they have been registered in. Failing decorators will be skipped
* in order to ensure deliverability in spite of breaking code.
* @param {object} obj - the object to decorate.
* @return {object} the decorated object.
*/
runDecorators_(obj) {
return this.decorators_.reduce(async (acc, next) => {
return acc.then(res => next(res)).catch(() => acc)
}, Promise.resolve(obj))
}
}
export default BaseService

View File

@@ -18,6 +18,7 @@
"@babel/preset-env": "^7.7.5",
"client-sessions": "^0.8.0",
"cross-env": "^5.2.1",
"jest": "^25.5.2",
"eslint": "^6.8.0"
},
"scripts": {

View File

@@ -24,12 +24,12 @@
"@babel/preset-env": "^7.7.5",
"@babel/runtime": "^7.7.6",
"cross-env": "^5.2.1",
"jest": "^24.9.0"
"jest": "^25.5.2"
},
"dependencies": {
"mongoose": "^5.8.0",
"medusa-test-utils": "^1.0.0",
"medusa-core-utils": "^1.0.0",
"medusa-interfaces": "^1.0.0"
"medusa-interfaces": "^1.0.0",
"medusa-test-utils": "^1.0.0",
"mongoose": "^5.8.0"
}
}
}

View File

@@ -22,6 +22,7 @@
"@babel/plugin-transform-runtime": "^7.7.6",
"@babel/preset-env": "^7.7.5",
"cross-env": "^5.2.1",
"jest": "^25.5.2",
"eslint": "^6.8.0"
},
"dependencies": {

View File

@@ -24,7 +24,7 @@
"@babel/runtime": "^7.7.6",
"cross-env": "^5.2.1",
"eslint": "^6.8.0",
"jest": "^24.9.0",
"jest": "^25.5.2",
"nodemon": "^2.0.1",
"prettier": "^1.19.1",
"supertest": "^4.0.2"