node-easywechat 3.0.0-alpha.2 → 3.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +30 -0
- package/README.md +156 -19
- package/dist/Core/Contracts/AccessTokenInterface.d.ts +1 -1
- package/dist/Core/Contracts/CacheInterface.d.ts +3 -0
- package/dist/Core/Contracts/CacheInterface.js +3 -0
- package/dist/Core/Contracts/ServerInterface.d.ts +6 -0
- package/dist/Core/Contracts/ServerInterface.js +12 -0
- package/dist/Core/Http/ServerRequest.d.ts +3 -0
- package/dist/Core/Http/ServerRequest.js +3 -0
- package/dist/Core/HttpClient/AccessTokenAwareClient.d.ts +5 -3
- package/dist/Core/HttpClient/AccessTokenAwareClient.js +9 -3
- package/dist/Core/HttpClient/Contracts/HttpClientInterface.d.ts +5 -0
- package/dist/Core/HttpClient/Contracts/HttpClientInterface.js +4 -0
- package/dist/Core/HttpClient/HttpClient.d.ts +10 -1
- package/dist/Core/HttpClient/HttpClient.js +20 -0
- package/dist/Core/HttpClient/HttpClientResponse.d.ts +3 -3
- package/dist/Core/HttpClient/HttpClientResponse.js +5 -4
- package/dist/Core/HttpClient/Mixins/PresetMixin.d.ts +79 -0
- package/dist/Core/HttpClient/Mixins/PresetMixin.js +155 -0
- package/dist/Core/Message.d.ts +3 -0
- package/dist/Core/Message.js +3 -0
- package/dist/Core/Mixins/ClientMixin.d.ts +6 -1
- package/dist/Core/Mixins/ClientMixin.js +3 -0
- package/dist/Core/Mixins/ServerRequestMixin.js +3 -0
- package/dist/Core/Support/Utils.d.ts +6 -0
- package/dist/Core/Support/Utils.js +10 -1
- package/dist/MiniApp/AccessToken.d.ts +5 -0
- package/dist/MiniApp/AccessToken.js +10 -0
- package/dist/MiniApp/Application.d.ts +3 -0
- package/dist/MiniApp/Application.js +5 -2
- package/dist/OfficialAccount/Application.d.ts +3 -0
- package/dist/OfficialAccount/Application.js +6 -3
- package/dist/OfficialAccount/Server.d.ts +1 -6
- package/dist/OfficialAccount/Server.js +3 -8
- package/dist/OfficialAccount/Utils.d.ts +8 -0
- package/dist/OfficialAccount/Utils.js +8 -0
- package/dist/Types/global.d.ts +46 -67
- package/dist/index.d.ts +14 -0
- package/dist/index.js +18 -0
- package/package.json +1 -1
- package/official_account.access_token.mock-access_token-appid.cache +0 -1
- package/official_account.jsapi_ticket.mock-ticket-appid.cache +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,38 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v3.0.0-beta.3 (2022-06-22)
|
|
5
|
+
|
|
6
|
+
- Fix: 修复获取js ticket时无法自动获取access_token的问题
|
|
7
|
+
- Fix: 修复日志处理回调函数的参数提示异常的问题
|
|
8
|
+
|
|
9
|
+
## v3.0.0-beta.2 (2022-06-21)
|
|
10
|
+
|
|
11
|
+
- Feat: 统一调用入口增加一些常用的类
|
|
12
|
+
|
|
13
|
+
- Fix: 修复获取的服务端实例没有代码提示的问题
|
|
14
|
+
|
|
15
|
+
## v3.0.0-beta.1 (2022-06-21)
|
|
16
|
+
|
|
17
|
+
- Feat: 新增设置预置参数相关方法
|
|
18
|
+
- Feat: 增加设置日志处理器的方法
|
|
19
|
+
- Feat: 增加统一的对象调用入口
|
|
20
|
+
|
|
21
|
+
- Fix: 调整获取响应内容时的返回类型
|
|
22
|
+
- Fix: 修复微信小程序access_token键名前缀与公众号相同的问题
|
|
23
|
+
- Fix: 优化并导出配置项声明
|
|
24
|
+
- Fix: 修复请求响应结果非字符串类型时转化数据格式报错的问题
|
|
25
|
+
- Fix: 未设置ServerRequest实例就调用getRequest时提示异常
|
|
26
|
+
- Fix: 修复未自动创建客户端实例的问题
|
|
27
|
+
|
|
28
|
+
- Perf: 调整接口请求返回的HttpResponse对象toObject时的数据类型
|
|
29
|
+
|
|
4
30
|
## v3.0.0-alpha.2 (2022-06-08)
|
|
5
31
|
|
|
32
|
+
- Feat: 新增小程序相关接口
|
|
33
|
+
|
|
34
|
+
- Fix: 修复content-type非json时,错误判断不正确问题
|
|
35
|
+
|
|
6
36
|
- Perf: 优化消息对象的提示信息
|
|
7
37
|
|
|
8
38
|
- Refactor: 简化构造函数的写法
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
**注:3.x分支针对 EasyWechat 的 6.x版本。**
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
若您需要 EasyWechat 的 5.x版本,请切换到 [2.x](https://github.com/hpyer/node-easywechat/tree/2.x) 分支。
|
|
9
9
|
|
|
10
10
|
[EasyWechat](https://github.com/w7corp/easywechat) 是一个由 `安正超` 大神用 PHP 开发的开源的微信非官方 SDK(现由微擎团队团队维护)。其功能强大,使用方便,个人一直很喜欢,所以近日将其在 Node.js 上实现。本人会尽量还原其配置项以及接口的调用方式,但毕竟语言环境不同,具体的实现方式会有些许差别,还请各位开发者见谅。
|
|
11
11
|
|
|
@@ -20,16 +20,25 @@
|
|
|
20
20
|
|
|
21
21
|
绝大部分API都可以根据 [EasyWechat 的文档](https://www.easywechat.com/5.x/) 来使用。小部分(如获取请求相关数据、返回响应数据、支付证书等)的操作,由于语言环境的不同,会有不同处理。具体可以查看 [node-easywechat-demo](https://github.com/hpyer/node-easywechat-demo/) 以及下方的[自定义模块说明](#自定义模块模块替换使用方法) 。如果仍有疑问,请提issue,谢谢~
|
|
22
22
|
|
|
23
|
+
从 `3.x` 起 SDK 中不再内置具体业务的接口,仅封装底层基础部分,如认证、授权和 API 客户端。至于为什么不再封装业务接口,可以查看 [EasyWechat 给出说明](https://easywechat.com/6.x/introduction.html#不再封装业务接口)。
|
|
24
|
+
|
|
23
25
|
```js
|
|
24
|
-
// 按需引入所需要的模块
|
|
25
26
|
// 公众号
|
|
26
|
-
const
|
|
27
|
+
const { OfficialAccount } = require('node-easywechat');
|
|
28
|
+
// 实例化应用
|
|
29
|
+
let app = new OfficialAccount({
|
|
30
|
+
// 配置项
|
|
31
|
+
});
|
|
27
32
|
|
|
33
|
+
// 小程序
|
|
34
|
+
const { MiniApp } = require('node-easywechat');
|
|
28
35
|
// 实例化应用
|
|
29
|
-
let app = new
|
|
30
|
-
//
|
|
36
|
+
let app = new MiniApp({
|
|
37
|
+
// 配置项
|
|
31
38
|
});
|
|
32
39
|
|
|
40
|
+
// ----- 以下为通用的 api 调用方法 -----
|
|
41
|
+
|
|
33
42
|
// 获取 api 调用客户端
|
|
34
43
|
let client = app.getClient();
|
|
35
44
|
|
|
@@ -43,26 +52,32 @@ let response = await client.post('/cgi-bin/user/info/updateremark', {
|
|
|
43
52
|
### 配置项示例
|
|
44
53
|
|
|
45
54
|
``` js
|
|
46
|
-
//
|
|
55
|
+
// 通用配置,即所有模块都可以设置
|
|
47
56
|
{
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
secret: '',
|
|
52
|
-
// 微信公众号的 token
|
|
53
|
-
token: '',
|
|
54
|
-
// EncodingAESKey
|
|
55
|
-
aes_key: '',
|
|
57
|
+
// axios 请求参数
|
|
58
|
+
// 详见:https://github.com/axios/axios#request-config
|
|
59
|
+
http: {},
|
|
56
60
|
|
|
57
61
|
// 缓存以文件(默认设置)存储时,需要的配置项
|
|
58
62
|
file_cache: {
|
|
59
63
|
path: './cache/', // 文件存储目录(请确保该目录有读写权限)
|
|
60
64
|
fileMode: 0o666, // 文件权限
|
|
61
65
|
ext: '.cache' // 文件扩展名
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
``` js
|
|
71
|
+
// 公众号配置
|
|
72
|
+
{
|
|
73
|
+
// 公众号的 app key
|
|
74
|
+
app_id: '',
|
|
75
|
+
// 公众号的 app secret
|
|
76
|
+
secret: '',
|
|
77
|
+
// 公众号的 token
|
|
78
|
+
token: '',
|
|
79
|
+
// EncodingAESKey
|
|
80
|
+
aes_key: '',
|
|
66
81
|
|
|
67
82
|
// 网页授权认证
|
|
68
83
|
oauth: {
|
|
@@ -74,11 +89,133 @@ let response = await client.post('/cgi-bin/user/info/updateremark', {
|
|
|
74
89
|
}
|
|
75
90
|
```
|
|
76
91
|
|
|
92
|
+
``` js
|
|
93
|
+
// 小程序配置
|
|
94
|
+
{
|
|
95
|
+
// 小程序的 app key
|
|
96
|
+
app_id: '',
|
|
97
|
+
// 小程序的 app secret
|
|
98
|
+
secret: '',
|
|
99
|
+
// 小程序的 token
|
|
100
|
+
token: '',
|
|
101
|
+
// EncodingAESKey
|
|
102
|
+
aes_key: ''
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 自定义模块(模块替换)使用方法
|
|
107
|
+
|
|
108
|
+
#### 日志模块
|
|
109
|
+
|
|
110
|
+
框架默认不记录任何日志。如果需要,可以通过 `client` 实例的 `setLogger` 方法设置日志处理回调方法。
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
// 以公众号为例
|
|
114
|
+
const { OfficialAccount } = require('node-easywechat');
|
|
115
|
+
// 实例化应用
|
|
116
|
+
let app = new OfficialAccount({
|
|
117
|
+
// ...
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// 获取 api 调用客户端
|
|
121
|
+
let client = app.getClient();
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* 该回调方法会接收两种日志信息
|
|
125
|
+
* 1、接口请求调用前的参数:
|
|
126
|
+
* string 固定值,'before'
|
|
127
|
+
* object 请求参数
|
|
128
|
+
* 2、接口请求调用后的参数:
|
|
129
|
+
* string 固定值,'after'
|
|
130
|
+
* object 请求参数
|
|
131
|
+
* number 请求耗时(ms)
|
|
132
|
+
* Response 请求响应对象
|
|
133
|
+
*/
|
|
134
|
+
client.setLogger((...args) => {
|
|
135
|
+
console.log(args)
|
|
136
|
+
});
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
#### 缓存模块
|
|
140
|
+
|
|
141
|
+
框架默认使用文件缓存读取到的 `access_token` 等值,如需要改用其他缓存方式(如:redis),请实现接口 `CacheInterface` 并通过 `app.setCacher` 方法进行模块替换。
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
const { OfficialAccount, CacheInterface } = require('node-easywechat');
|
|
145
|
+
const Redis = require("ioredis");
|
|
146
|
+
|
|
147
|
+
class RedisCacher extends CacheInterface {
|
|
148
|
+
constructor(redis) {
|
|
149
|
+
this.redis = redis;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
get(id)
|
|
153
|
+
{
|
|
154
|
+
return this.redis.get(id);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
async has(id)
|
|
158
|
+
{
|
|
159
|
+
return (await this.redis.exists(id)) > 0;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async set(id, data = null, lifeTime = 0)
|
|
163
|
+
{
|
|
164
|
+
if (lifeTime > 0) {
|
|
165
|
+
await this.redis.set(id, data, 'EX', lifeTime);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
await this.redis.set(id, data);
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
async delete(id)
|
|
174
|
+
{
|
|
175
|
+
await this.redis.del(id);
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// 实例化应用
|
|
181
|
+
let app = new OfficialAccount({
|
|
182
|
+
// ...
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// 替换缓存实例
|
|
186
|
+
app.setCacher(new RedisCacher(new Redis));
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### 请求模块
|
|
190
|
+
|
|
191
|
+
通常,如果你的应用不需要处理服务端回调、支付回调等逻辑的话,是不需要传递请求对象的。
|
|
192
|
+
|
|
193
|
+
```js
|
|
194
|
+
const { OfficialAccount, ServerRequest } = require('node-easywechat');
|
|
195
|
+
|
|
196
|
+
// 实例化应用
|
|
197
|
+
let app = new OfficialAccount({
|
|
198
|
+
// ...
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
// 根据 IncomingMessage 实例(即 Node.js 原始请求对象)创建 ServerRequest 实例
|
|
202
|
+
//
|
|
203
|
+
// 由于 IncomingMessage 的 body 流的特殊性,某些框架(目前已知:fastify)
|
|
204
|
+
// 可能会自动读取后挂载到上下文中,从而导致 node-easywechat 去尝试读取时报错。
|
|
205
|
+
// 这时可以选择传入第二个参数,即 body 的内容
|
|
206
|
+
//
|
|
207
|
+
// 如果此方法 不能解决你的问题,可以选择继承 ServerRequest,重写相关方法
|
|
208
|
+
let request = ServerRequest.createFromIncomingMessage(req);
|
|
209
|
+
|
|
210
|
+
// 设置请求实例
|
|
211
|
+
app.setRequest(request);
|
|
212
|
+
```
|
|
213
|
+
|
|
77
214
|
### 模块支持情况
|
|
78
215
|
|
|
79
216
|
- [x] 公众号模块
|
|
80
217
|
- [ ] 微信支付
|
|
81
|
-
- [
|
|
218
|
+
- [x] 小程序
|
|
82
219
|
- [ ] 开放平台
|
|
83
220
|
- [ ] 企业微信
|
|
84
221
|
- [ ] 企业微信开放平台
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import ResponseInterface from "../Http/Contracts/ResponseInterface";
|
|
2
|
+
import DecryptXmlMessageMixin from "../Mixins/DecryptXmlMessageMixin";
|
|
3
|
+
import HandlersMixin from "../Mixins/HandlersMixin";
|
|
4
|
+
import ResponseXmlMessageMixin from "../Mixins/ResponseXmlMessageMixin";
|
|
2
5
|
declare abstract class ServerInterface {
|
|
6
|
+
constructor();
|
|
3
7
|
/**
|
|
4
8
|
* 处理消息
|
|
5
9
|
*/
|
|
6
10
|
serve(): Promise<ResponseInterface>;
|
|
7
11
|
}
|
|
12
|
+
interface ServerInterface extends HandlersMixin, DecryptXmlMessageMixin, ResponseXmlMessageMixin {
|
|
13
|
+
}
|
|
8
14
|
export = ServerInterface;
|
|
@@ -8,7 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
const DecryptXmlMessageMixin_1 = __importDefault(require("../Mixins/DecryptXmlMessageMixin"));
|
|
15
|
+
const HandlersMixin_1 = __importDefault(require("../Mixins/HandlersMixin"));
|
|
16
|
+
const ResponseXmlMessageMixin_1 = __importDefault(require("../Mixins/ResponseXmlMessageMixin"));
|
|
17
|
+
const Utils_1 = require("../Support/Utils");
|
|
11
18
|
class ServerInterface {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.handlers = [];
|
|
21
|
+
}
|
|
12
22
|
/**
|
|
13
23
|
* 处理消息
|
|
14
24
|
*/
|
|
@@ -17,4 +27,6 @@ class ServerInterface {
|
|
|
17
27
|
}
|
|
18
28
|
}
|
|
19
29
|
;
|
|
30
|
+
;
|
|
31
|
+
(0, Utils_1.applyMixins)(ServerInterface, [HandlersMixin_1.default, DecryptXmlMessageMixin_1.default, ResponseXmlMessageMixin_1.default]);
|
|
20
32
|
module.exports = ServerInterface;
|
|
@@ -3,6 +3,9 @@ import { IncomingMessage } from "http";
|
|
|
3
3
|
import ServerRequestInterface from "./Contracts/ServerRequestInterface";
|
|
4
4
|
import MessageMixin from "./Minxins/MessageMixin";
|
|
5
5
|
import RequestMixin from "./Minxins/RequestMixin";
|
|
6
|
+
/**
|
|
7
|
+
* 服务器收到的请求对象
|
|
8
|
+
*/
|
|
6
9
|
declare class ServerRequest implements ServerRequestInterface {
|
|
7
10
|
protected attributes: Record<string, any>;
|
|
8
11
|
protected cookieParams: Record<string, any>;
|
|
@@ -8,6 +8,9 @@ const url_1 = require("url");
|
|
|
8
8
|
const Utils_1 = require("../Support/Utils");
|
|
9
9
|
const MessageMixin_1 = __importDefault(require("./Minxins/MessageMixin"));
|
|
10
10
|
const RequestMixin_1 = __importDefault(require("./Minxins/RequestMixin"));
|
|
11
|
+
/**
|
|
12
|
+
* 服务器收到的请求对象
|
|
13
|
+
*/
|
|
11
14
|
class ServerRequest {
|
|
12
15
|
constructor(method, url, headers = {}, body = null, version = 'v1.1', serverParams = {}) {
|
|
13
16
|
this.attributes = {};
|
|
@@ -3,17 +3,19 @@ import AccessTokenAwareHttpClientInterface from "./Contracts/AccessTokenAwareHtt
|
|
|
3
3
|
import AccessTokenInterface from "../Contracts/AccessTokenInterface";
|
|
4
4
|
import HttpClientInterface from "./Contracts/HttpClientInterface";
|
|
5
5
|
import HttpClientMethodsMixin from './Mixins/HttpClientMethodsMixin';
|
|
6
|
-
import { HttpClientFailureJudgeClosure } from '../../Types/global';
|
|
6
|
+
import { HttpClientFailureJudgeClosure, LogHandler } from '../../Types/global';
|
|
7
7
|
import HttpClientResponse from './HttpClientResponse';
|
|
8
|
+
import PresetMixin from './Mixins/PresetMixin';
|
|
8
9
|
declare class AccessTokenAwareClient implements AccessTokenAwareHttpClientInterface, HttpClientInterface {
|
|
9
10
|
protected client: HttpClientInterface;
|
|
10
11
|
protected accessToken: AccessTokenInterface;
|
|
11
|
-
constructor(client: HttpClientInterface, accessToken
|
|
12
|
+
constructor(client: HttpClientInterface, accessToken?: AccessTokenInterface, failureJudge?: HttpClientFailureJudgeClosure, throwError?: boolean);
|
|
12
13
|
withAccessToken(accessToken: AccessTokenInterface): this;
|
|
13
14
|
getInstance(): AxiosInstance;
|
|
14
15
|
setInstance(instance: AxiosInstance): this;
|
|
16
|
+
setLogger(logger: LogHandler): this;
|
|
15
17
|
request(method: Method, url: string, payload?: AxiosRequestConfig<any>): Promise<HttpClientResponse>;
|
|
16
18
|
}
|
|
17
|
-
interface AccessTokenAwareClient extends HttpClientMethodsMixin {
|
|
19
|
+
interface AccessTokenAwareClient extends HttpClientMethodsMixin, PresetMixin {
|
|
18
20
|
}
|
|
19
21
|
export = AccessTokenAwareClient;
|
|
@@ -15,8 +15,9 @@ const merge_1 = __importDefault(require("merge"));
|
|
|
15
15
|
const Utils_1 = require("../Support/Utils");
|
|
16
16
|
const HttpClient_1 = __importDefault(require("./HttpClient"));
|
|
17
17
|
const HttpClientMethodsMixin_1 = __importDefault(require("./Mixins/HttpClientMethodsMixin"));
|
|
18
|
+
const PresetMixin_1 = __importDefault(require("./Mixins/PresetMixin"));
|
|
18
19
|
class AccessTokenAwareClient {
|
|
19
|
-
constructor(client, accessToken, failureJudge = null, throwError = true) {
|
|
20
|
+
constructor(client, accessToken = null, failureJudge = null, throwError = true) {
|
|
20
21
|
this.client = null;
|
|
21
22
|
this.accessToken = null;
|
|
22
23
|
this.client = client || HttpClient_1.default.create(null, failureJudge, throwError);
|
|
@@ -33,15 +34,20 @@ class AccessTokenAwareClient {
|
|
|
33
34
|
this.client.setInstance(instance);
|
|
34
35
|
return this;
|
|
35
36
|
}
|
|
37
|
+
setLogger(logger) {
|
|
38
|
+
this.client.setLogger(logger);
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
36
41
|
request(method, url, payload = {}) {
|
|
37
42
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
43
|
if (this.accessToken) {
|
|
39
44
|
payload.params = (0, merge_1.default)(true, payload.params || {}, yield this.accessToken.toQuery());
|
|
40
45
|
}
|
|
41
|
-
|
|
46
|
+
let options = this.mergeThenResetPrepends(payload, method);
|
|
47
|
+
return this.client.request(method, (0, Utils_1.ltrim)(url, '\\/+'), options);
|
|
42
48
|
});
|
|
43
49
|
}
|
|
44
50
|
}
|
|
45
51
|
;
|
|
46
|
-
(0, Utils_1.applyMixins)(AccessTokenAwareClient, [HttpClientMethodsMixin_1.default]);
|
|
52
|
+
(0, Utils_1.applyMixins)(AccessTokenAwareClient, [HttpClientMethodsMixin_1.default, PresetMixin_1.default]);
|
|
47
53
|
module.exports = AccessTokenAwareClient;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Method, AxiosRequestConfig, AxiosInstance } from 'axios';
|
|
2
|
+
import { LogHandler } from '../../../Types/global';
|
|
2
3
|
import HttpClientResponse from '../HttpClientResponse';
|
|
3
4
|
declare abstract class HttpClientInterface {
|
|
4
5
|
/**
|
|
@@ -10,6 +11,10 @@ declare abstract class HttpClientInterface {
|
|
|
10
11
|
* 设置axios实例
|
|
11
12
|
*/
|
|
12
13
|
setInstance(instance: AxiosInstance): this;
|
|
14
|
+
/**
|
|
15
|
+
* 设置日志方法
|
|
16
|
+
*/
|
|
17
|
+
setLogger(logger: LogHandler): this;
|
|
13
18
|
/**
|
|
14
19
|
* 发起http请求
|
|
15
20
|
*/
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { AxiosInstance, AxiosRequestConfig, Method } from 'axios';
|
|
2
2
|
import HttpClientInterface from './Contracts/HttpClientInterface';
|
|
3
3
|
import HttpClientResponse from './HttpClientResponse';
|
|
4
|
-
import { HttpClientFailureJudgeClosure } from '../../Types/global';
|
|
4
|
+
import { HttpClientFailureJudgeClosure, LogHandler } from '../../Types/global';
|
|
5
5
|
declare class HttpClient implements HttpClientInterface {
|
|
6
6
|
protected axios: AxiosInstance;
|
|
7
7
|
protected failureJudge: HttpClientFailureJudgeClosure;
|
|
8
8
|
protected throwError: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* 日志处理方法
|
|
11
|
+
*/
|
|
12
|
+
protected logger: LogHandler;
|
|
9
13
|
constructor(axios: AxiosInstance, failureJudge?: HttpClientFailureJudgeClosure, throwError?: boolean);
|
|
14
|
+
/**
|
|
15
|
+
* 设置日志处理方法
|
|
16
|
+
* @param logger
|
|
17
|
+
*/
|
|
18
|
+
setLogger(logger: LogHandler): this;
|
|
10
19
|
request(method: Method, url: string, payload?: AxiosRequestConfig<any>): Promise<HttpClientResponse>;
|
|
11
20
|
getInstance(): AxiosInstance;
|
|
12
21
|
setInstance(instance: AxiosInstance): this;
|
|
@@ -20,6 +20,18 @@ class HttpClient {
|
|
|
20
20
|
this.axios = axios;
|
|
21
21
|
this.failureJudge = failureJudge;
|
|
22
22
|
this.throwError = throwError;
|
|
23
|
+
/**
|
|
24
|
+
* 日志处理方法
|
|
25
|
+
*/
|
|
26
|
+
this.logger = null;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 设置日志处理方法
|
|
30
|
+
* @param logger
|
|
31
|
+
*/
|
|
32
|
+
setLogger(logger) {
|
|
33
|
+
this.logger = logger;
|
|
34
|
+
return this;
|
|
23
35
|
}
|
|
24
36
|
request(method, url, payload = {}) {
|
|
25
37
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -66,7 +78,15 @@ class HttpClient {
|
|
|
66
78
|
options['json'] = undefined;
|
|
67
79
|
delete options['json'];
|
|
68
80
|
}
|
|
81
|
+
let starttime = Date.now();
|
|
82
|
+
if (typeof this.logger === 'function') {
|
|
83
|
+
yield this.logger('before', options);
|
|
84
|
+
}
|
|
69
85
|
let response = yield this.axios.request(options);
|
|
86
|
+
if (typeof this.logger === 'function') {
|
|
87
|
+
let usedTime = Date.now() - starttime;
|
|
88
|
+
yield this.logger('after', options, usedTime, response);
|
|
89
|
+
}
|
|
70
90
|
return new HttpClientResponse_1.default(response, this.failureJudge, this.throwError);
|
|
71
91
|
});
|
|
72
92
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AxiosResponse } from "axios";
|
|
2
|
-
import { HttpClientFailureJudgeClosure } from "../../Types/global";
|
|
2
|
+
import { HttpClientFailureJudgeClosure, WeixinResponse } from "../../Types/global";
|
|
3
3
|
import HttpClientResponseInterface from "./Contracts/HttpClientResponseInterface";
|
|
4
4
|
declare class HttpClientResponse implements HttpClientResponseInterface {
|
|
5
5
|
protected response: AxiosResponse;
|
|
@@ -30,7 +30,7 @@ declare class HttpClientResponse implements HttpClientResponseInterface {
|
|
|
30
30
|
* @param throwError
|
|
31
31
|
* @returns
|
|
32
32
|
*/
|
|
33
|
-
toObject(throwError?: boolean): Promise<
|
|
33
|
+
toObject<T = WeixinResponse>(throwError?: boolean): Promise<T>;
|
|
34
34
|
/**
|
|
35
35
|
* 返回json字符串
|
|
36
36
|
* @param throwError
|
|
@@ -73,7 +73,7 @@ declare class HttpClientResponse implements HttpClientResponseInterface {
|
|
|
73
73
|
getHeader(key: string): any;
|
|
74
74
|
getStatusCode(): number;
|
|
75
75
|
getHeaders(throwError?: boolean): Record<string, any>;
|
|
76
|
-
getContent(throwError?: boolean):
|
|
76
|
+
getContent(throwError?: boolean): any;
|
|
77
77
|
cancel(): void;
|
|
78
78
|
getInfo(type?: string): import("axios").AxiosRequestConfig<any>;
|
|
79
79
|
offsetExists(key: any): Promise<boolean>;
|
|
@@ -73,9 +73,10 @@ class HttpClientResponse {
|
|
|
73
73
|
if (!content) {
|
|
74
74
|
throw new Error('Response body is empty.');
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
76
|
+
if (typeof content === 'string') {
|
|
77
|
+
if (this.is('xml') && content.indexOf('<xml>') > -1) {
|
|
78
|
+
return (0, Utils_1.parseXml)(content);
|
|
79
|
+
}
|
|
79
80
|
}
|
|
80
81
|
return content;
|
|
81
82
|
});
|
|
@@ -116,7 +117,7 @@ class HttpClientResponse {
|
|
|
116
117
|
* @returns
|
|
117
118
|
*/
|
|
118
119
|
toDataUrl() {
|
|
119
|
-
return 'data:' + this.getHeader('content-type') + ';base64,' + this.response.data;
|
|
120
|
+
return 'data:' + this.getHeader('content-type') + ';base64,' + this.response.data.toString('base64');
|
|
120
121
|
}
|
|
121
122
|
/**
|
|
122
123
|
* 判断 content-type 是否指定类型
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { AxiosRequestConfig, Method } from "axios";
|
|
2
|
+
declare class PresetMixin {
|
|
3
|
+
/**
|
|
4
|
+
* 存储预置参数
|
|
5
|
+
*/
|
|
6
|
+
protected presets: Record<string, any>;
|
|
7
|
+
/**
|
|
8
|
+
* 存储预置headers数据
|
|
9
|
+
*/
|
|
10
|
+
protected prependHeaders: Record<string, any>;
|
|
11
|
+
/**
|
|
12
|
+
* 存储预置数据
|
|
13
|
+
*/
|
|
14
|
+
protected prependData: Record<string, any>;
|
|
15
|
+
/**
|
|
16
|
+
* 设置预置参数
|
|
17
|
+
* @param presets
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
20
|
+
setPresets(presets: Record<string, any>): this;
|
|
21
|
+
/**
|
|
22
|
+
* 设置单个预置header
|
|
23
|
+
* @param key
|
|
24
|
+
* @param value
|
|
25
|
+
* @returns
|
|
26
|
+
*/
|
|
27
|
+
withHeader(key: string, value: any): this;
|
|
28
|
+
/**
|
|
29
|
+
* 批量设置预置headers
|
|
30
|
+
* @param headers
|
|
31
|
+
* @returns
|
|
32
|
+
*/
|
|
33
|
+
withHeaders(headers: Record<string, any>): this;
|
|
34
|
+
/**
|
|
35
|
+
* 设置预置数据
|
|
36
|
+
* @param key 参数名
|
|
37
|
+
* @param value 参数值,不设置则尝试从预置参数中获取
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
with(key: string | string[] | Record<string, any>, value?: string): this;
|
|
41
|
+
/**
|
|
42
|
+
* 预设置app_id(因nodejs不支持魔术方法,只好预先设置几个常用的方法)
|
|
43
|
+
* @param new_appid
|
|
44
|
+
* @returns
|
|
45
|
+
*/
|
|
46
|
+
withAppId(new_appid?: string): this;
|
|
47
|
+
/**
|
|
48
|
+
* 预设置app_id的别名(因nodejs不支持魔术方法,只好预先设置几个常用的方法)
|
|
49
|
+
* @param new_alias
|
|
50
|
+
* @returns
|
|
51
|
+
*/
|
|
52
|
+
withAppIdAs(new_alias: string): this;
|
|
53
|
+
/**
|
|
54
|
+
* 预设置secret(因nodejs不支持魔术方法,只好预先设置几个常用的方法)
|
|
55
|
+
* @param new_secret
|
|
56
|
+
* @returns
|
|
57
|
+
*/
|
|
58
|
+
withSecret(new_secret?: string): this;
|
|
59
|
+
/**
|
|
60
|
+
* 预设置mch_id(因nodejs不支持魔术方法,只好预先设置几个常用的方法)
|
|
61
|
+
* @param new_mch_id
|
|
62
|
+
* @returns
|
|
63
|
+
*/
|
|
64
|
+
withMchId(new_mch_id?: string): this;
|
|
65
|
+
/**
|
|
66
|
+
* 预设置mch_id别名(因nodejs不支持魔术方法,只好预先设置几个常用的方法)
|
|
67
|
+
* @param new_alias
|
|
68
|
+
* @returns
|
|
69
|
+
*/
|
|
70
|
+
withMchIdAs(new_alias?: string): this;
|
|
71
|
+
/**
|
|
72
|
+
* 合并预置参数并清空预置数据
|
|
73
|
+
* @param payload
|
|
74
|
+
* @param method
|
|
75
|
+
* @returns
|
|
76
|
+
*/
|
|
77
|
+
mergeThenResetPrepends(payload: AxiosRequestConfig, method?: Method): any;
|
|
78
|
+
}
|
|
79
|
+
export = PresetMixin;
|