Skip to content

Commit

Permalink
joinedByLineFeed, ksort and queryStringLike funcs onto formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNorthMemory committed Sep 9, 2020
1 parent f81512f commit 91bffec
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 30 deletions.
37 changes: 35 additions & 2 deletions lib/formatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class Formatter {
* @returns {string} - The content for `Rsa.sign`
*/
static request(method, uri, timestamp, nonce, body = '') {
return `${method}\n${uri}\n${timestamp}\n${nonce}\n${body}\n`
return this.joinedByLineFeed(method, uri, timestamp, nonce, body)
}

/**
Expand All @@ -102,7 +102,40 @@ class Formatter {
* @returns {string} - The content for `Rsa.verify`
*/
static response(timestamp, nonce, body = '') {
return `${timestamp}\n${nonce}\n${body}\n`
return this.joinedByLineFeed(timestamp, nonce, body)
}

/**
* Joined this inputs by for `Line Feed`(LF) char.
*
* @param {string[]} pieces - The string(s) joined by line feed.
*
* @returns {string} - The joined string.
*/
static joinedByLineFeed(...pieces) {
return [...pieces, ``].join(`\n`)
}

/**
* Sorts an Object by key.
*
* @param {object} thing - The input object.
*
* @returns {object} - The sorted object.
*/
static ksort(thing) {
return Object.keys(thing).sort().reduce((des, key) => (des[key] = thing[key], des), {})
}

/**
* Like `queryString` does but without the `sign` and `empty value` entities.
*
* @param {object} thing - The input object.
*
* @returns {string} - The sorted object.
*/
static queryStringLike(thing) {
return Object.entries(thing).filter(([k, v]) => k != `sign` && v !== void 0 && v !== ``).map(i => i.join(`=`)).join(`&`)
}
}

Expand Down
40 changes: 20 additions & 20 deletions lib/wechatpay.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const axios = require('axios')
const interceptor = require('./interceptor')

/*eslint-disable-next-line*/
const CLIENT = Symbol('CLIENT')

/**
* A Wechatpay APIv3's amazing client.
*
Expand Down Expand Up @@ -46,14 +49,14 @@ class Wechatpay {
/**
* @property {AxiosInstance} client - The axios instance
*/
static get client() { return Wechatpay[CLIENT] }
static set client(target) { Wechatpay[CLIENT] = target }
static get client() { return this[CLIENT] }
static set client(target) { this[CLIENT] = target }

/**
* @property {RegExp} URI_ENTITY - The URI entity which's split by slash ask `uri_template`
* @property {RegExp} REGEXP_URI_ENTITY - The URI entity which's split by slash ask `uri_template`
*/
/*eslint-disable-next-line*/
static get URI_ENTITY() { return /^\{([^\}]+)\}$/ }
static get REGEXP_URI_ENTITY() { return /^\{([^\}]+)\}$/ }

/**
* Compose the `URL`.pathname based on the container's entities
Expand All @@ -76,13 +79,13 @@ class Wechatpay {
// `camelCase` to `camel-case`
.replace(/[A-Z]/g, w => `-${w.toLowerCase()}`)
// `$dynamic_variable$` to `{dynamic_variable}`
.replace(/^\$/, `{`).replace(/\$$/, `}`)
.replace(/^\$(.*)\$$/, `{$1}`)
}

/**
* @property {object} container - Client side the URIs' entity mapper
*/
static get container() { return {
static get container() { const that = this; return {
/**
* @property {string[]} entities - The URI entities
*/
Expand All @@ -95,8 +98,8 @@ class Wechatpay {
*/
withEntities: function(list) {
this.entities.forEach((one, index, src) => {
if (Wechatpay.URI_ENTITY.test(one)) {
const sign = one.replace(Wechatpay.URI_ENTITY, `$1`)
if (that.REGEXP_URI_ENTITY.test(one)) {
const sign = one.replace(that.REGEXP_URI_ENTITY, `$1`)
src[index] = list[sign] ? list[sign] : one
}
})
Expand All @@ -110,7 +113,7 @@ class Wechatpay {
* @returns {PromiseLike} - The `AxiosPromise`
*/
get: async function(...arg) {
return Wechatpay.client.get(Wechatpay.pathname(this.entities), ...arg)
return that.client.get(that.pathname(this.entities), ...arg)
},

/**
Expand All @@ -119,7 +122,7 @@ class Wechatpay {
* @returns {PromiseLike} - The `AxiosPromise`
*/
post: async function(...arg) {
return Wechatpay.client.post(Wechatpay.pathname(this.entities), ...arg)
return that.client.post(that.pathname(this.entities), ...arg)
},

/**
Expand All @@ -128,7 +131,7 @@ class Wechatpay {
* @returns {PromiseLike} - The `AxiosPromise`
*/
put: async function(...arg) {
return Wechatpay.client.put(Wechatpay.pathname(this.entities), ...arg)
return that.client.put(that.pathname(this.entities), ...arg)
},

/**
Expand All @@ -137,7 +140,7 @@ class Wechatpay {
* @returns {PromiseLike} - The `AxiosPromise`
*/
patch: async function(...arg) {
return Wechatpay.client.patch(Wechatpay.pathname(this.entities), ...arg)
return that.client.patch(that.pathname(this.entities), ...arg)
},

/**
Expand All @@ -146,7 +149,7 @@ class Wechatpay {
* @returns {PromiseLike} - The `AxiosPromise`
*/
delete: async function(...arg) {
return Wechatpay.client.delete(Wechatpay.pathname(this.entities), ...arg)
return that.client.delete(that.pathname(this.entities), ...arg)
},
} }

Expand All @@ -166,9 +169,9 @@ class Wechatpay {
}
if (!(property in target)) {
/*eslint-disable-next-line*/
target[property] = new Proxy({...Wechatpay.container}, Wechatpay.handler)
target[property] = new Proxy({...this.container}, this.handler)
if (`entities` in target) {
target[property].entities = [...target.entities, Wechatpay.normalize(property)]
target[property].entities = [...target.entities, this.normalize(property)]
}
}

Expand All @@ -184,15 +187,12 @@ class Wechatpay {
* @returns {Proxy} - The magic APIv3 container
*/
constructor(wxpayConfig = {}, axiosConfig = {baseURL: 'https://api.mch.weixin.qq.com'}) {
Wechatpay.client = Wechatpay.client || interceptor(axios.create(axiosConfig), wxpayConfig)
this.constructor.client = this.constructor.client || interceptor(axios.create(axiosConfig), wxpayConfig)

/*eslint-disable-next-line*/
return new Proxy({...Wechatpay.container}, Wechatpay.handler)
return new Proxy({...this.constructor.container}, this.constructor.handler)
}
}

/*eslint-disable-next-line*/
const CLIENT = Symbol('CLIENT')

module.exports = Wechatpay
module.exports.default = Wechatpay
44 changes: 44 additions & 0 deletions tests/lib/formatter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,48 @@ describe('lib/formatter', () => {
fmt.response(9,8).substr(-2).should.equal(`\n\n`)
})
})

describe('Formatter::joinedByLineFeed', () => {
it('method `joinedByLineFeed` should be static', () => {
should(fmt.joinedByLineFeed).be.a.Function()
should((new fmt).joinedByLineFeed).is.Undefined()
})

it('method `joinedByLineFeed` should returns a string which is end with LF(ASCII 10)', () => {
fmt.joinedByLineFeed('').should.be.a.String().endWith(`\n`)
fmt.joinedByLineFeed('').substr(-1).charCodeAt().should.equal(10)
})

it('method `joinedByLineFeed(a,b,c,d,e,f,g)` should returns a string, and filled as `aLFbLFcLFdLFeLFfLFgLF`', () => {
fmt.joinedByLineFeed('a', 'b', 'c', 'd', 'e', 'f', 'g').should.be.a.String()
/*eslint-disable-next-line quotes*/
.equal(`a\nb\nc\nd\ne\nf\ng\n`)
.and.startWith('a')
.and.endWith(`\n`)
})
})

describe('Formatter::ksort', () => {
it('method `ksort` should be static', () => {
should(fmt.ksort).be.a.Function()
should((new fmt).ksort).is.Undefined()
})

it('method `ksort({b: 1, a: 0})` should returns an object and deepEqual to {a: 0, b: 1}', () => {
fmt.ksort({b: 1, a: 0}).should.be.an.instanceOf(Object).and.have.properties([`a`, `b`])
fmt.ksort({b: 1, a: 0}).should.deepEqual({a: 0, b: 1})
})
})

describe('Formatter::queryStringLike', () => {
it('method `queryStringLike` should be static', () => {
should(fmt.queryStringLike).be.a.Function()
should((new fmt).queryStringLike).is.Undefined()
})

it('method `queryStringLike({appid: 3, mchid: 2, openid: \'\', sign: 0})` should returns a string and equal to `appid=3&mchid=2`', () => {
fmt.queryStringLike({appid: 3, mchid: 2, openid: '', sign: 0}).should.be.a.String()
fmt.queryStringLike({appid: 3, mchid: 2, openid: '', sign: 0}).should.equal(`appid=3&mchid=2`)
})
})
})
8 changes: 0 additions & 8 deletions tests/lib/rsa.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ describe('lib/rsa', () => {
rsa.encrypt()
}).throw(TypeError, {
code: 'ERR_INVALID_ARG_TYPE',
message: 'The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined',
stack: /at Function\.from \(buffer\.js/
})
})

Expand All @@ -30,8 +28,6 @@ describe('lib/rsa', () => {
rsa.encrypt('')
}).throw(TypeError, {
code: 'ERR_INVALID_ARG_TYPE',
message: 'The "key" argument must be of type string or an instance of Buffer, TypedArray, DataView, or KeyObject. Received an instance of Object',
stack: /at prepareAsymmetricKey \(internal\/crypto\/keys\.js/
})
})

Expand Down Expand Up @@ -72,8 +68,6 @@ describe('lib/rsa', () => {
rsa.decrypt()
}).throw(TypeError, {
code: 'ERR_INVALID_ARG_TYPE',
message: 'The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined',
stack: /at Function\.from \(buffer\.js/
})
})

Expand All @@ -82,8 +76,6 @@ describe('lib/rsa', () => {
rsa.decrypt('')
}).throw(TypeError, {
code: 'ERR_INVALID_ARG_TYPE',
message: 'The "key" argument must be of type string or an instance of Buffer, TypedArray, DataView, or KeyObject. Received an instance of Object',
stack: /at prepareAsymmetricKey \(internal\/crypto\/keys\.js/
})
})

Expand Down

0 comments on commit 91bffec

Please sign in to comment.