axios-annotations 1.0.0
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/LICENSE +21 -0
- package/README.md +456 -0
- package/core/config.js +1 -0
- package/core/parser.js +1 -0
- package/core/service.js +1 -0
- package/decorator/delete-mapping.js +1 -0
- package/decorator/get-mapping.js +1 -0
- package/decorator/patch-mapping.js +1 -0
- package/decorator/post-mapping.js +1 -0
- package/decorator/put-mapping.js +1 -0
- package/decorator/request-body.js +1 -0
- package/decorator/request-config.js +1 -0
- package/decorator/request-header.js +1 -0
- package/decorator/request-mapping.js +1 -0
- package/decorator/request-param.js +1 -0
- package/lib/core/common.js +1 -0
- package/lib/core/config.d.ts +23 -0
- package/lib/core/config.js +1 -0
- package/lib/core/parser.d.ts +15 -0
- package/lib/core/parser.js +1 -0
- package/lib/core/service.d.ts +26 -0
- package/lib/core/service.js +1 -0
- package/lib/decorator/delete-mapping.d.ts +3 -0
- package/lib/decorator/delete-mapping.js +1 -0
- package/lib/decorator/get-mapping.d.ts +3 -0
- package/lib/decorator/get-mapping.js +1 -0
- package/lib/decorator/patch-mapping.d.ts +3 -0
- package/lib/decorator/patch-mapping.js +1 -0
- package/lib/decorator/post-mapping.d.ts +3 -0
- package/lib/decorator/post-mapping.js +1 -0
- package/lib/decorator/put-mapping.d.ts +3 -0
- package/lib/decorator/put-mapping.js +1 -0
- package/lib/decorator/request-body.d.ts +3 -0
- package/lib/decorator/request-body.js +1 -0
- package/lib/decorator/request-config.d.ts +7 -0
- package/lib/decorator/request-config.js +1 -0
- package/lib/decorator/request-header.d.ts +5 -0
- package/lib/decorator/request-header.js +1 -0
- package/lib/decorator/request-mapping.d.ts +6 -0
- package/lib/decorator/request-mapping.js +1 -0
- package/lib/decorator/request-param.d.ts +3 -0
- package/lib/decorator/request-param.js +1 -0
- package/lib/plugins/auth/authorizer.d.ts +49 -0
- package/lib/plugins/auth/authorizer.js +1 -0
- package/lib/plugins/auth/history.d.ts +15 -0
- package/lib/plugins/auth/history.js +1 -0
- package/lib/plugins/auth/index.d.ts +4 -0
- package/lib/plugins/auth/index.js +1 -0
- package/lib/plugins/auth/queue.d.ts +16 -0
- package/lib/plugins/auth/queue.js +1 -0
- package/lib/plugins/auth/storage.d.ts +7 -0
- package/lib/plugins/auth/storage.js +1 -0
- package/package.json +16 -0
- package/plugins/auth/authorizer.js +1 -0
- package/plugins/auth/history.js +1 -0
- package/plugins/auth/index.js +1 -0
- package/plugins/auth/queue.js +1 -0
- package/plugins/auth/storage.js +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 sitorhy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# Axios Annotations
|
|
2
|
+
|
|
3
|
+
HTTP client library uses Axios without Typescript.
|
|
4
|
+
|
|
5
|
+
## Quick Overview
|
|
6
|
+
|
|
7
|
+
### Basic Usage
|
|
8
|
+
|
|
9
|
+
开发环境不支持装饰器。
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
import Service from "axios-annotations/core/service";
|
|
13
|
+
import {config} from "axios-annotations/core/config"
|
|
14
|
+
|
|
15
|
+
config.protocol = "http";
|
|
16
|
+
config.host = "localhost";
|
|
17
|
+
config.port = 8080;
|
|
18
|
+
config.prefix = "/api";
|
|
19
|
+
|
|
20
|
+
export default class TestService extends Service {
|
|
21
|
+
/**
|
|
22
|
+
* new TestService().get("a","b",null);
|
|
23
|
+
* <br>
|
|
24
|
+
* http://localhost:8080/api/path?p1=a&p2=b
|
|
25
|
+
* @param data1
|
|
26
|
+
* @param data2
|
|
27
|
+
* @returns {AxiosPromise<any>}
|
|
28
|
+
*/
|
|
29
|
+
get(required1, required2, optional1) {
|
|
30
|
+
return this.requestWith("GET", "/path")
|
|
31
|
+
.param("p1", true)
|
|
32
|
+
.param("p2", true)
|
|
33
|
+
.param("p3", false)
|
|
34
|
+
.send({
|
|
35
|
+
p1: required1,
|
|
36
|
+
p2: required2,
|
|
37
|
+
p3: optional1
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
post(data1, data2) {
|
|
42
|
+
return this.requestWith("POST", "/path2")
|
|
43
|
+
.param("p1", true)
|
|
44
|
+
.body("p2")
|
|
45
|
+
.send({
|
|
46
|
+
p1: data1,
|
|
47
|
+
p2: data2
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
basic() {
|
|
52
|
+
return this.request("POST", "/path3?p1=a&p2=b", {field1: 'c', field: 'd'},
|
|
53
|
+
{
|
|
54
|
+
headers: {
|
|
55
|
+
'Content-Type': 'application/json'
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Basic Usage With Decorators
|
|
64
|
+
|
|
65
|
+
使用装饰器
|
|
66
|
+
<br>
|
|
67
|
+
可能需要插件支持:
|
|
68
|
+
<br>
|
|
69
|
+
`@babel/plugin-proposal-decorators`
|
|
70
|
+
<br>
|
|
71
|
+
`@babel/plugin-proposal-class-properties`
|
|
72
|
+
<br>
|
|
73
|
+
添加配置:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"plugins": [
|
|
78
|
+
[
|
|
79
|
+
"@babel/plugin-proposal-decorators",
|
|
80
|
+
{
|
|
81
|
+
"legacy": true
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
[
|
|
85
|
+
"@babel/plugin-proposal-class-properties",
|
|
86
|
+
{
|
|
87
|
+
"loose": true
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`vue-cli`等脚手架已默认支持装饰器。
|
|
95
|
+
<br>
|
|
96
|
+
方法只需要返回参数,并注解参数类型。
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
import Service from "axios-annotations/core/service";
|
|
100
|
+
import RequestConfig from "axios-annotations/decorator/request-config";
|
|
101
|
+
import RequestParam from "axios-annotations/decorator/request-param";
|
|
102
|
+
import RequestMapping from "axios-annotations/decorator/request-mapping";
|
|
103
|
+
import RequestBody from "axios-annotations/decorator/request-body";
|
|
104
|
+
import RequestHeader from "axios-annotations/decorator/request-header";
|
|
105
|
+
|
|
106
|
+
@RequestMapping("/api")
|
|
107
|
+
export default class TestService extends Service {
|
|
108
|
+
@RequestMapping("/path", "GET")
|
|
109
|
+
@RequestParam("p1", true)
|
|
110
|
+
@RequestParam("p2", true)
|
|
111
|
+
@RequestParam("p3", false)
|
|
112
|
+
get(p1, p2, p3) {
|
|
113
|
+
return {p1, p2, p3};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@RequestMapping("/path2", "POST")
|
|
117
|
+
@RequestParam("p1", true)
|
|
118
|
+
@RequestBody("p2")
|
|
119
|
+
@RequestHeader("Content-Type", "text/plain")
|
|
120
|
+
post(p1, str2) {
|
|
121
|
+
return {p1, p2: str2};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### QueryString Encoding
|
|
127
|
+
`key-values pair`转查询串算法,运行环境不支持`URLSearchParams`时使用默认算法,也可以自定义。
|
|
128
|
+
<br>
|
|
129
|
+
使用第三方库,`qs`,`querystring`,`url-search-params-polyfill`等,不同运行环境下可能有差异。
|
|
130
|
+
```javascript
|
|
131
|
+
import qs from "qs";
|
|
132
|
+
import URLSearchParamsParser from "axios-annotations/core/parser";
|
|
133
|
+
|
|
134
|
+
if (typeof URLSearchParams === "undefined") {
|
|
135
|
+
URLSearchParamsParser.encode = function (encoder) {
|
|
136
|
+
return qs.stringify(encoder);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
如果不爽部分IDE的`non-promise inspection info`下划线,也可以给方法加上`async`。
|
|
142
|
+
|
|
143
|
+
## Configuration
|
|
144
|
+
|
|
145
|
+
### Custom Config
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
import Config from "axios-annotations/core/config";
|
|
149
|
+
import RequestConfig from "axios-annotations/decorator/request-config";
|
|
150
|
+
import RequestMapping from "axios-annotations/decorator/request-mapping";
|
|
151
|
+
|
|
152
|
+
const config = new Config();
|
|
153
|
+
config.host = "localhost";
|
|
154
|
+
config.port = 8086;
|
|
155
|
+
config.protocol = "http";
|
|
156
|
+
config.prefix = "/api";
|
|
157
|
+
|
|
158
|
+
@RequestConfig(config)
|
|
159
|
+
@RequestMapping("/test")
|
|
160
|
+
export default class TestService extends Service {
|
|
161
|
+
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Plugin
|
|
166
|
+
|
|
167
|
+
### Custom Plugin
|
|
168
|
+
|
|
169
|
+
插件函数接收配置对象为参数,出于扩展性考虑,通常由高阶函数返回。
|
|
170
|
+
|
|
171
|
+
```javascript
|
|
172
|
+
import {config} from "axios-annotations/core/config"
|
|
173
|
+
|
|
174
|
+
function ToastPlugin(fnToast) {
|
|
175
|
+
return function (config) {
|
|
176
|
+
config.axios.interceptors.response.use(function (e) {
|
|
177
|
+
return Promise.resolve(e);
|
|
178
|
+
}, function (e) {
|
|
179
|
+
fnToast(e);
|
|
180
|
+
return Promise.reject(e);
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
config.axios.interceptors.request.use(function (e) {
|
|
184
|
+
return Promise.resolve(e);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
config.plugins = [
|
|
190
|
+
ToastPlugin(function (e) {
|
|
191
|
+
if (typeof wx !== "undefined") {
|
|
192
|
+
wx.showToast({
|
|
193
|
+
icon: "none",
|
|
194
|
+
title: `[${e.response.status}]` + ' ' + e.config.url
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
})
|
|
198
|
+
];
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### <text style="color:red;">Auth Plugin</text>
|
|
202
|
+
可选的内置插件。
|
|
203
|
+
<br>
|
|
204
|
+
Basic Usage for Auth Plugin.
|
|
205
|
+
<br>
|
|
206
|
+
Take case of `Spring Security OAtuh2.0`。
|
|
207
|
+
```javascript
|
|
208
|
+
// DevServer Proxy Config
|
|
209
|
+
const authCfg = new Config();
|
|
210
|
+
authCfg.host = "localhost";
|
|
211
|
+
authCfg.port = 8080;
|
|
212
|
+
authCfg.protocol = "http";
|
|
213
|
+
authCfg.prefix = "/api";
|
|
214
|
+
|
|
215
|
+
@RequestConfig(authCfg)
|
|
216
|
+
@RequestMapping("/oauth")
|
|
217
|
+
export default class OAuth2Service extends Service {
|
|
218
|
+
@GetMapping("/token")
|
|
219
|
+
@RequestParam("grant_type", true)
|
|
220
|
+
@RequestParam("scope", false)
|
|
221
|
+
@RequestParam("client_id", false)
|
|
222
|
+
@RequestParam("client_secret", false)
|
|
223
|
+
@RequestParam("username", false)
|
|
224
|
+
@RequestParam("password", false)
|
|
225
|
+
@RequestBody()
|
|
226
|
+
token() {
|
|
227
|
+
return {
|
|
228
|
+
grant_type: "password",
|
|
229
|
+
scope: "all",
|
|
230
|
+
client_id: "client_1",
|
|
231
|
+
client_secret: "123456",
|
|
232
|
+
username: "admin",
|
|
233
|
+
password: "123456"
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@GetMapping("/token")
|
|
238
|
+
@RequestParam("grant_type", true)
|
|
239
|
+
@RequestParam("refresh_token", true)
|
|
240
|
+
@RequestParam("scope", false)
|
|
241
|
+
@RequestParam("client_id", true)
|
|
242
|
+
@RequestParam("client_secret", true)
|
|
243
|
+
refreshToken(session) {
|
|
244
|
+
return {
|
|
245
|
+
grant_type: "refresh_token",
|
|
246
|
+
refresh_token: session.refresh_token,
|
|
247
|
+
scope: "all",
|
|
248
|
+
client_id: "client_1",
|
|
249
|
+
client_secret: "123456"
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
Implement Authorizer.
|
|
255
|
+
<br/>
|
|
256
|
+
实现`Authorizer`类。
|
|
257
|
+
```javascript
|
|
258
|
+
import Authorizer from "axios-annotations/plugins/auth/authorizer";
|
|
259
|
+
|
|
260
|
+
export default class OAuth2Authorizer extends Authorizer {
|
|
261
|
+
async refreshSession(session) {
|
|
262
|
+
// access_token invalid, could refresh access_token with refresh_token through 'password' grant type
|
|
263
|
+
// access_token 过期,如果使用 password 方式认证, 可使用 refresh_token 进行刷新
|
|
264
|
+
const oauthService = new OAuth2Service();
|
|
265
|
+
let res;
|
|
266
|
+
try {
|
|
267
|
+
res = await oauthService.refreshToken(session);
|
|
268
|
+
} catch (e) {
|
|
269
|
+
throw e;
|
|
270
|
+
}
|
|
271
|
+
if(!res || !res.data){
|
|
272
|
+
throw new Error("Seession Unknow Error");
|
|
273
|
+
}
|
|
274
|
+
const nextSession = res.data;
|
|
275
|
+
return nextSession;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async onAuthorizedDenied(error) {
|
|
279
|
+
// refresh_token invalid,you should re-loign or logout here.
|
|
280
|
+
// refresh_token 过期触发该回调,在此进行重新登录或注销操作
|
|
281
|
+
|
|
282
|
+
// try logout, clean session.
|
|
283
|
+
// await this.invalidateSession();
|
|
284
|
+
// return;
|
|
285
|
+
|
|
286
|
+
const res = await new OAuth2Service().token();
|
|
287
|
+
if (res && res.data) {
|
|
288
|
+
const nextSession = res.data;
|
|
289
|
+
|
|
290
|
+
// save session manually if try re-login
|
|
291
|
+
await this.storageSession(nextSession);
|
|
292
|
+
return nextSession;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
throw error;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
onSessionInvalidated() {
|
|
299
|
+
// session cleaned, redirect to login page.
|
|
300
|
+
router.redirect("/login");
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
```
|
|
304
|
+
认证信息默认存储在`sessionStorage`。
|
|
305
|
+
<br>
|
|
306
|
+
Implement SessionStorage if store mode changed.
|
|
307
|
+
```javascript
|
|
308
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
309
|
+
import SessionStorage from "axios-annotations/plugins/auth/storage";
|
|
310
|
+
|
|
311
|
+
export default class RNSessionStorage extends SessionStorage {
|
|
312
|
+
async set(key, value) {
|
|
313
|
+
const jsonValue = JSON.stringify(value);
|
|
314
|
+
await AsyncStorage.setItem(key, jsonValue);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async get(key) {
|
|
318
|
+
// omit...
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async remove(key) {
|
|
322
|
+
// omit...
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
替换掉`Authorizer`存储器。
|
|
327
|
+
```javascript
|
|
328
|
+
export default class OAuth2Authorizer extends Authorizer {
|
|
329
|
+
constructor() {
|
|
330
|
+
super();
|
|
331
|
+
this.sessionStorage = new RNSessionStorage();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
在默认配置上设置插件。
|
|
336
|
+
```javascript
|
|
337
|
+
// config.js
|
|
338
|
+
import AuthorizationPlugin from "axios-annotations/plugins/auth/index";
|
|
339
|
+
|
|
340
|
+
// default config
|
|
341
|
+
const config = new Config();
|
|
342
|
+
config.host = "localhost";
|
|
343
|
+
config.port = 8080;
|
|
344
|
+
config.protocol = "http";
|
|
345
|
+
config.prefix = "/api";
|
|
346
|
+
|
|
347
|
+
const _authorizer = new OAuth2Authorizer();
|
|
348
|
+
|
|
349
|
+
config.plugins = [
|
|
350
|
+
AuthorizationPlugin(_authorizer)
|
|
351
|
+
];
|
|
352
|
+
|
|
353
|
+
// export it in order to save or read the grant result
|
|
354
|
+
export const authorizer = _authorizer;
|
|
355
|
+
|
|
356
|
+
// service.js
|
|
357
|
+
// the request will be authorized or not
|
|
358
|
+
@RequestConfig(config)
|
|
359
|
+
@RequestMapping("/test")
|
|
360
|
+
export default class TestService extends Service {
|
|
361
|
+
// ...
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
首次登录,需要手动保存认证信息。
|
|
365
|
+
<br>
|
|
366
|
+
but you may store grant information yourself when the first time login succeed.
|
|
367
|
+
```javascript
|
|
368
|
+
import {authorizer} from "/path/config.js";
|
|
369
|
+
|
|
370
|
+
// ... Login Page
|
|
371
|
+
{
|
|
372
|
+
methods: {
|
|
373
|
+
registerApi().then(async session => {
|
|
374
|
+
await authorizer.sessionStorage.storageSession(session.data);
|
|
375
|
+
// redirect to other page ...
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
## API
|
|
382
|
+
### Service
|
|
383
|
+
#### request(method, path, data?, config?): AxiosPromise
|
|
384
|
+
+ method : string `GET / POST / DELETE...`
|
|
385
|
+
+ path : string `相对路径`
|
|
386
|
+
+ data : Object `请求体`
|
|
387
|
+
+ config : Object `AxiosRequestConfig`
|
|
388
|
+
|
|
389
|
+
#### requestWith(method, path): RequestController
|
|
390
|
+
+ method : string `GET /POST / DELETE...`
|
|
391
|
+
+ path : string `相对路径`
|
|
392
|
+
|
|
393
|
+
> #### RequestController
|
|
394
|
+
> + param: (key, required?) : RequestController
|
|
395
|
+
> + key : string `标记查询串参数`
|
|
396
|
+
> + required : boolean `默认false,空字符串,null,undefined 将忽略`
|
|
397
|
+
> + header: (header, header) : RequestController
|
|
398
|
+
> + header : string `url 附加参数键值`
|
|
399
|
+
> + header : string | function `字符串,或者接收 send 方法参数的函数,该函数应返回合法值。`
|
|
400
|
+
>
|
|
401
|
+
> + body: (key) : RequestController
|
|
402
|
+
> + key : string `标记参数中请求体`
|
|
403
|
+
>
|
|
404
|
+
> + config: (cfg) : RequestController
|
|
405
|
+
> + cfg : `AxiosRequestConfig`
|
|
406
|
+
>
|
|
407
|
+
> + send: (data) : AxiosPromise<any>
|
|
408
|
+
> + data : object `参数键值对`
|
|
409
|
+
|
|
410
|
+
### Decorators
|
|
411
|
+
#### RequestMapping(path, method?)
|
|
412
|
+
+ path : string `相对路径`
|
|
413
|
+
+ method : string `默认GET,注解服务类时忽略该参数`
|
|
414
|
+
> 注解方法时,可以使用简化形式:
|
|
415
|
+
> <br>
|
|
416
|
+
> GetMapping(path)
|
|
417
|
+
> <br>
|
|
418
|
+
> PostMapping(path)
|
|
419
|
+
> <br>
|
|
420
|
+
> PatchMapping(path)
|
|
421
|
+
> <br>
|
|
422
|
+
> PutMapping(path)
|
|
423
|
+
> <br>
|
|
424
|
+
> DeleteMapping(path)
|
|
425
|
+
|
|
426
|
+
#### RequestParam(name, required?)
|
|
427
|
+
+ name : string `方法返回值属性`
|
|
428
|
+
+ required : boolean `是否必要参数`
|
|
429
|
+
|
|
430
|
+
#### RequestHeader(header, value)
|
|
431
|
+
+ header : string `请求头`
|
|
432
|
+
+ value : string `字符串或函数`
|
|
433
|
+
> 使用函数。
|
|
434
|
+
> ```javascript
|
|
435
|
+
> class TestService extends Service {
|
|
436
|
+
> @RequestHeader("Authorization", (token) => {
|
|
437
|
+
> return `Basic ${token}`;
|
|
438
|
+
> })
|
|
439
|
+
> @RequestMapping("/login", "GET")
|
|
440
|
+
> foo(token) {
|
|
441
|
+
> return {};
|
|
442
|
+
> }
|
|
443
|
+
> }
|
|
444
|
+
> ```
|
|
445
|
+
|
|
446
|
+
#### RequestBody(name)
|
|
447
|
+
+ name : string `方法返回值属性,默认为 body`
|
|
448
|
+
|
|
449
|
+
## 运行环境
|
|
450
|
+
部分运行环境,例如微信小程序,`axios`需要降级。<br>
|
|
451
|
+
微信小程序:
|
|
452
|
+
```shell
|
|
453
|
+
npm install axios@0.21.0
|
|
454
|
+
npm install axios-miniprogram-adapter
|
|
455
|
+
```
|
|
456
|
+
更新开发工具版本以支持装饰器语法。
|
package/core/config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/core/config");
|
package/core/parser.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/core/parser");
|
package/core/service.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/core/service");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/delete-mapping");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/get-mapping");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/patch-mapping");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/post-mapping");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/put-mapping");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/request-body");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/request-config");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/request-header");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/request-mapping");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../lib/decorator/request-param");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function normalizePath(e){return e.replace(/\/+/g,"/").replace(/\/$/,"")}function isNullOrEmpty(e){return null==e||""===e}Object.defineProperty(exports,"__esModule",{value:!0}),exports.isNullOrEmpty=isNullOrEmpty,exports.normalizePath=normalizePath;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {AxiosInstance} from "axios";
|
|
2
|
+
|
|
3
|
+
export type ConfigPluginHandler = (...args: any[]) => ((config: Config) => void);
|
|
4
|
+
|
|
5
|
+
export default class Config {
|
|
6
|
+
host: string;
|
|
7
|
+
|
|
8
|
+
port: number | null | string;
|
|
9
|
+
|
|
10
|
+
protocol: string;
|
|
11
|
+
|
|
12
|
+
prefix: string;
|
|
13
|
+
|
|
14
|
+
origin: string;
|
|
15
|
+
|
|
16
|
+
baseURL: string;
|
|
17
|
+
|
|
18
|
+
axios: AxiosInstance;
|
|
19
|
+
|
|
20
|
+
plugins: ConfigPluginHandler[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const config: Config;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.config=void 0;var _axios=_interopRequireDefault(require("axios"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var i=0;i<t.length;i++){var o=t[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}function _createClass(e,t,i){return t&&_defineProperties(e.prototype,t),i&&_defineProperties(e,i),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}var Config=function(){function e(){_classCallCheck(this,e),_defineProperty(this,"_host","localhost"),_defineProperty(this,"_port",8080),_defineProperty(this,"_protocol","http"),_defineProperty(this,"_prefix",""),_defineProperty(this,"_axios",_axios.default.create()),_defineProperty(this,"_plugins",[])}return _createClass(e,[{key:"host",get:function(){return this._host},set:function(e){this._host=e}},{key:"port",get:function(){return this._port},set:function(e){this._port=e}},{key:"protocol",get:function(){return this._protocol},set:function(e){this._protocol=e}},{key:"prefix",get:function(){return this._prefix},set:function(e){this._prefix=e}},{key:"origin",get:function(){return"".concat(this.protocol,"://").concat(this.host).concat(this.port?":"+this.port:"")}},{key:"baseURL",get:function(){return"".concat(this.origin).concat(this.prefix)}},{key:"axios",get:function(){return this._axios},set:function(e){this._axios=e}},{key:"plugins",get:function(){return this._plugins},set:function(e){this._plugins=e}}]),e}(),config=new(exports.default=Config);exports.config=config;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
declare const URLSearchParamsParser: {
|
|
2
|
+
encode: (encoder: object) => string;
|
|
3
|
+
|
|
4
|
+
decode: (data: object) => object;
|
|
5
|
+
|
|
6
|
+
has: (encoder: object, key: string) => boolean;
|
|
7
|
+
|
|
8
|
+
delete: (encoder: object, key: string) => void;
|
|
9
|
+
|
|
10
|
+
get: (encoder: object, key: string) => any;
|
|
11
|
+
|
|
12
|
+
append: (encoder: object, key: string, value: any) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default URLSearchParamsParser;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _common=require("./common");function _slicedToArray(r,e){return _arrayWithHoles(r)||_iterableToArrayLimit(r,e)||_unsupportedIterableToArray(r,e)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(r,e){if(r){if("string"==typeof r)return _arrayLikeToArray(r,e);var t=Object.prototype.toString.call(r).slice(8,-1);return"Map"===(t="Object"===t&&r.constructor?r.constructor.name:t)||"Set"===t?Array.from(r):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_arrayLikeToArray(r,e):void 0}}function _arrayLikeToArray(r,e){(null==e||e>r.length)&&(e=r.length);for(var t=0,n=new Array(e);t<e;t++)n[t]=r[t];return n}function _iterableToArrayLimit(r,e){var t=null==r?null:"undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(null!=t){var n,a,o=[],i=!0,u=!1;try{for(t=t.call(r);!(i=(n=t.next()).done)&&(o.push(n.value),!e||o.length!==e);i=!0);}catch(r){u=!0,a=r}finally{try{i||null==t.return||t.return()}finally{if(u)throw a}}return o}}function _arrayWithHoles(r){if(Array.isArray(r))return r}var URLSearchParamsParser={encode:function(r){return"undefined"==typeof URLSearchParams?Object.entries(r).reduce(function(e,r){var r=_slicedToArray(r,2),t=r[0],r=r[1],r=void 0===r?void 0:r;return Array.isArray(r)?r.forEach(function(r){e.push("".concat(t,"=").concat(encodeURIComponent(null===r?"null":void 0===r?"":r)))}):e.push("".concat(t,"=").concat(encodeURIComponent(null===r?"null":void 0===r?"":r))),e},[]).join("&"):r.toString()},decode:function(r){return"undefined"==typeof URLSearchParams?Object.assign({},r):new URLSearchParams(r)},has:function(r,e){return"undefined"==typeof URLSearchParams?Object.hasOwnProperty.call(r,e):r.has(e)},delete:function(r,e){"undefined"==typeof URLSearchParams?r&&delete r[e]:r.delete(e)},get:function(r,e){return"undefined"==typeof URLSearchParams?r?r[e]:void 0:r.get(e)},append:function(r,e,t){var n;"undefined"==typeof URLSearchParams?r&&(n=r[e],(0,_common.isNullOrEmpty)(n)?r[e]=t:r[e]=[].concat(n).concat(t)):r.append(e,t)}},_default=URLSearchParamsParser;exports.default=_default;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Config from "./config";
|
|
2
|
+
import {AxiosPromise, AxiosRequestConfig} from "axios";
|
|
3
|
+
|
|
4
|
+
export interface RequestController {
|
|
5
|
+
param: (key: string, required?: boolean) => RequestController;
|
|
6
|
+
|
|
7
|
+
header: (header: string, value: string | ((...args: any[]) => string)) => RequestController;
|
|
8
|
+
|
|
9
|
+
body: (key: string) => RequestController;
|
|
10
|
+
|
|
11
|
+
config: (config: Partial<AxiosRequestConfig>) => RequestController;
|
|
12
|
+
|
|
13
|
+
send: (data: Record<string, any>) => AxiosPromise<any>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default class Service {
|
|
17
|
+
constructor(path?: string);
|
|
18
|
+
|
|
19
|
+
config: Config;
|
|
20
|
+
|
|
21
|
+
path: string;
|
|
22
|
+
|
|
23
|
+
request(method: string, path: string, data?: any, config?: Partial<AxiosRequestConfig>): AxiosPromise<any>;
|
|
24
|
+
|
|
25
|
+
requestWith(method: string, path: string): RequestController;
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=exports.ConfigMapping=void 0;var _common=require("./common"),_parser=_interopRequireDefault(require("./parser")),_config=require("./config");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function _createForOfIteratorHelper(e,t){var r,n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=_unsupportedIterableToArray(e))||t&&e&&"number"==typeof e.length)return n&&(e=n),r=0,{s:t=function(){},n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:t};throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,o=!0,a=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return o=e.done,e},e:function(e){a=!0,i=e},f:function(){try{o||null==n.return||n.return()}finally{if(a)throw i}}}}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var r=Object.prototype.toString.call(e).slice(8,-1);return"Map"===(r="Object"===r&&e.constructor?e.constructor.name:r)||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?_arrayLikeToArray(e,t):void 0}}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var ConfigMapping={requestHeaders:function(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:[],r={};if(e)for(var n in e){var i=e[n];r[n]="function"==typeof i?i.apply(void 0,t):i}return r},axiosConfig:function(e,t){var r={};return(e||[]).forEach(function(e){"function"==typeof e?Object.assign(r,e.apply(void 0,t)):Object.assign(r,e)}),r},querystring:function(e,t){if(e){var r,n=_parser.default.decode(t);for(r in t){var i=t[r],o=e[r];!o||o.body?_parser.default.delete(n,r):o.required?(0,_common.isNullOrEmpty)(i)&&!_parser.default.has(n,r)&&_parser.default.append(n,r,""):(0,_common.isNullOrEmpty)(i)&&_parser.default.has(n,r)&&_parser.default.delete(n,r)}return _parser.default.encode(n)}return""},body:function(e,t){if(e)for(var r in e)if(!0===e[r].body)return(0,_common.isNullOrEmpty)(t)?void 0:t[r];return null}},Service=(exports.ConfigMapping=ConfigMapping,function(){function n(){var e=0<arguments.length&&void 0!==arguments[0]?arguments[0]:null;if(_classCallCheck(this,n),_defineProperty(this,"_path",""),_defineProperty(this,"_config",_config.config),_defineProperty(this,"_headers",{}),_defineProperty(this,"_params",{}),_defineProperty(this,"_configs",{}),_defineProperty(this,"_once",[]),!this._path&&e&&(this._path=e),"function"==typeof Object.getPrototypeOf?(Object.getPrototypeOf(this)._path&&(this._path=Object.getPrototypeOf(this)._path),Object.getPrototypeOf(this)._config&&(this._config=Object.getPrototypeOf(this)._config)):(this.__proto__._path&&(this._path=this.__proto__._path),this.__proto__._config&&(this._config=this.__proto__._config)),this.config&&this.config.plugins&&this.config.plugins.length){var t,r=_createForOfIteratorHelper(this.config.plugins);try{for(r.s();!(t=r.n()).done;)(0,t.value)(this.config)}catch(e){r.e(e)}finally{r.f()}}}return _createClass(n,[{key:"config",get:function(){return this._config},set:function(e){this._config=e}},{key:"path",get:function(){return this._path},set:function(e){this._path=e}},{key:"params",value:function(e,t){var r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{required:!1};if(!this._params||!this._params[e]||!Object.hasOwnProperty.call(this._params[e],t)){var r=Object.assign({required:!1,body:!1},r),n=this._params||{},i=this._params&&this._params[e]||{},o=i[t]||{};if(!0===r.body)for(var a in i)i[a].body=!1;this._params=Object.assign(n,_defineProperty({},e,Object.assign(i,_defineProperty({},t,Object.assign(o,r)))))}}},{key:"headers",value:function(e,t,r){var n=this._headers||{};Object.assign(n,_defineProperty({},e,Object.assign(n[e]||{},_defineProperty({},t,r))))}},{key:"configs",value:function(e,t){var r=this._configs||{};Object.assign(r,_defineProperty({},e,(r[e]||[]).concat(t)))}},{key:"pathVariable",value:function(e,t){var r=e,e=r.match(/{\w+}/g);return Array.isArray(e)&&e.forEach(function(e){e=e.substring(1,e.length-1);r=r.replaceAll("{".concat(e,"}"),t[e])}),r}},{key:"createRequestConfig",value:function(e,t,r){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:[],i=4<arguments.length&&void 0!==arguments[4]?arguments[4]:[],o=ConfigMapping.querystring(this._params[e],r),r=ConfigMapping.body(this._params[e],r),n=ConfigMapping.requestHeaders(this._headers[e],n),e=ConfigMapping.axiosConfig(this._configs[e],i),i="".concat(t).concat(o?"?"+o:"");return Object.assign(e,{headers:Object.assign(n,e.headers||null)}),{path:i,body:r,config:e}}},{key:"request",value:function(e,t){var r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{},n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:{},t=0<=t.indexOf("http")?t:this.config.baseURL+(0,_common.normalizePath)("/".concat(this.path||"","/").concat(t));return this.config.axios.request(Object.assign({method:e,url:t,data:r},n))}},{key:"requestWith",value:function(o,a){var s=this,f={},c=[],u={},n={param:function(e){return Object.assign(f,_defineProperty({},e,Object.assign(f[e]||{},{required:1<arguments.length&&void 0!==arguments[1]&&arguments[1],body:!1}))),n},header:function(e,t){return Object.assign(u,_defineProperty({},e,t)),n},body:function(e){var t,r=f[e]||{};for(t in f)f[t].body=!1;return Object.assign(f,_defineProperty({},e,Object.assign(r,{required:!1,body:!0}))),n},config:function(e){return c.push(e),n},send:function(e){var t=ConfigMapping.querystring(f,e),r=ConfigMapping.body(f,e),n=ConfigMapping.requestHeaders(u,[e]),i=ConfigMapping.axiosConfig(c,[e]),e="".concat(s.pathVariable(a,e)).concat(t?"?"+t:"");return Object.assign(i,{headers:Object.assign(n,i.headers||null)}),s.request(o,e,r,i)}};return n}}]),n}());exports.default=Service;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=DeleteMapping;var _requestMapping=_interopRequireDefault(require("./request-mapping"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function DeleteMapping(e){return(0,_requestMapping.default)(e,"DELETE")}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=GetMapping;var _requestMapping=_interopRequireDefault(require("./request-mapping"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function GetMapping(e){return(0,_requestMapping.default)(e,"GET")}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=PatchMapping;var _requestMapping=_interopRequireDefault(require("./request-mapping"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function PatchMapping(e){return(0,_requestMapping.default)(e,"PATCH")}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=PostMapping;var _requestMapping=_interopRequireDefault(require("./request-mapping"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function PostMapping(e){return(0,_requestMapping.default)(e,"POST")}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=PutMapping;var _requestMapping=_interopRequireDefault(require("./request-mapping"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function PutMapping(e){return(0,_requestMapping.default)(e,"PUT")}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function RequestBody(){var n=0<arguments.length&&void 0!==arguments[0]?arguments[0]:"body";return function(e,t,r){var u,o;r&&(u=r.value,o={required:!1,body:!0},r.value=function(){return this.params(t,n,o),u.apply(this,arguments)})}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=RequestBody;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import {AxiosPromise, AxiosRequestConfig} from "axios";
|
|
2
|
+
import Config from "../core/config";
|
|
3
|
+
import Service from "../core/service";
|
|
4
|
+
|
|
5
|
+
export default function RequestConfig(config: Config): (() => Service);
|
|
6
|
+
|
|
7
|
+
export default function RequestConfig(config: Partial<AxiosRequestConfig>): (() => AxiosPromise<any>);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function RequestConfig(u){return function(e,t,n){var o;n?(o=n.value,n.value=function(){return this.configs(t,u),o.apply(this,arguments)}):e.prototype._config=u}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=RequestConfig;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function RequestHeader(s,a){return function(e,t,r){var u;r&&(u=r.value,r.value=function(){return this.headers(t,s,a),u.apply(this,arguments)})}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=RequestHeader;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function RequestMapping(s){var c=1<arguments.length&&void 0!==arguments[1]?arguments[1]:null;return function(e,h,t){var p;t?(c=c||"GET",p=t.value,t.value=function(){for(var i=this,e=arguments.length,o=new Array(e),t=0;t<e;t++)o[t]=arguments[t];var n,a,r,u=p.apply(this,o);return u&&Object.hasOwnProperty.call(u,"then")&&"function"==typeof u.then?new Promise(function(a,r){u.then(function(e){var e=i.createRequestConfig(h,i.pathVariable(s,e),e,o,o),t=e.path,n=e.body,e=e.config;i.request(c,t,n,e).then(a).catch(r)})}):(n=(r=this.createRequestConfig(h,this.pathVariable(s,u),u,o,o)).path,a=r.body,r=r.config,this.request(c,n,a,r))}):e.prototype._path=s}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=RequestMapping;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function RequestParam(s){var i=1<arguments.length&&void 0!==arguments[1]&&arguments[1];return function(e,r,t){var u,a;t&&(u=t.value,a=Object.assign({required:!1,body:!1},{required:!0===i}),t.value=function(){return this.params(r,s,a),u.apply(this,arguments)})}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=RequestParam;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {AxiosError, AxiosPromise, AxiosRequestConfig} from "axios";
|
|
2
|
+
import SessionStorage from "./storage";
|
|
3
|
+
import SessionHistory from "./history";
|
|
4
|
+
|
|
5
|
+
export interface Session {
|
|
6
|
+
access_token?: string;
|
|
7
|
+
|
|
8
|
+
refresh_token?: string;
|
|
9
|
+
|
|
10
|
+
token?: string;
|
|
11
|
+
|
|
12
|
+
accessToken?: string;
|
|
13
|
+
|
|
14
|
+
refreshToken?: string;
|
|
15
|
+
|
|
16
|
+
expires_in?: number;
|
|
17
|
+
|
|
18
|
+
expiresIn?: number;
|
|
19
|
+
|
|
20
|
+
scope?: string;
|
|
21
|
+
|
|
22
|
+
token_type?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export default class Authorizer {
|
|
26
|
+
sessionKey: string;
|
|
27
|
+
|
|
28
|
+
sessionStorage: SessionStorage;
|
|
29
|
+
|
|
30
|
+
sessionHistory: SessionHistory;
|
|
31
|
+
|
|
32
|
+
getSession(): Promise<Session>;
|
|
33
|
+
|
|
34
|
+
storageSession(session: Session): Promise<void>;
|
|
35
|
+
|
|
36
|
+
refreshSession(session: Session): AxiosPromise<Session>;
|
|
37
|
+
|
|
38
|
+
withAuthentication(request: AxiosRequestConfig, session: Session): void;
|
|
39
|
+
|
|
40
|
+
checkSession(request: AxiosRequestConfig, session: Session): boolean;
|
|
41
|
+
|
|
42
|
+
checkResponse(response: Response): boolean;
|
|
43
|
+
|
|
44
|
+
onAuthorizedDenied(error: AxiosError): Promise<void>;
|
|
45
|
+
|
|
46
|
+
onSessionInvalidated(): void;
|
|
47
|
+
|
|
48
|
+
invalidateSession(): Promise<void>;
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _storage=_interopRequireDefault(require("./storage")),_history=_interopRequireDefault(require("./history"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function asyncGeneratorStep(e,t,r,n,s,o,i){try{var a=e[o](i),u=a.value}catch(e){return void r(e)}a.done?t(u):Promise.resolve(u).then(n,s)}function _asyncToGenerator(a){return function(){var e=this,i=arguments;return new Promise(function(t,r){var n=a.apply(e,i);function s(e){asyncGeneratorStep(n,t,r,s,o,"next",e)}function o(e){asyncGeneratorStep(n,t,r,s,o,"throw",e)}s(void 0)})}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}var Authorizer=function(){function e(){_classCallCheck(this,e),_defineProperty(this,"_sessionKey","$_SESSION"),_defineProperty(this,"_sessionStorage",new _storage.default),_defineProperty(this,"_sessionHistory",new _history.default)}var t,r,n,s,o;return _createClass(e,[{key:"sessionKey",get:function(){return this._sessionKey},set:function(e){this._sessionKey=e}},{key:"sessionStorage",get:function(){return this._sessionStorage},set:function(e){this._sessionStorage=e}},{key:"sessionHistory",get:function(){return this._sessionHistory},set:function(e){this._sessionHistory=e}},{key:"getSession",value:(o=_asyncToGenerator(regeneratorRuntime.mark(function e(){var t;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.sessionStorage.get(this.sessionKey);case 2:return t=e.sent,this.sessionHistory.size||this.sessionHistory.add(t),e.abrupt("return",t);case 5:case"end":return e.stop()}},e,this)})),function(){return o.apply(this,arguments)})},{key:"storageSession",value:(s=_asyncToGenerator(regeneratorRuntime.mark(function e(t){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return this.sessionHistory.add(t),e.next=3,this.sessionStorage.set(this.sessionKey,t);case 3:case"end":return e.stop()}},e,this)})),function(e){return s.apply(this,arguments)})},{key:"refreshSession",value:(n=_asyncToGenerator(regeneratorRuntime.mark(function e(t){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.abrupt("return",null);case 1:case"end":return e.stop()}},e)})),function(e){return n.apply(this,arguments)})},{key:"withAuthentication",value:function(e,t){var r,n;t&&(r=t.access_token,n=t.accessToken,t=t.token,(r||n||t)&&(e.headers.Authorization="Bearer "+(r||n||t)))}},{key:"checkSession",value:function(e,t){e=e.headers.Authorization||e.headers.authorization,e=e&&e.split(" ")[1]||"";return!this.sessionHistory.check(e)}},{key:"checkResponse",value:function(e){return 401!==(e||{status:0}).status}},{key:"onAuthorizedDenied",value:(r=_asyncToGenerator(regeneratorRuntime.mark(function e(t){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:throw t;case 1:case"end":return e.stop()}},e)})),function(e){return r.apply(this,arguments)})},{key:"onSessionInvalidated",value:function(){}},{key:"invalidateSession",value:(t=_asyncToGenerator(regeneratorRuntime.mark(function e(){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,this.sessionStorage.remove(this.sessionKey);case 2:this.onSessionInvalidated();case 3:case"end":return e.stop()}},e,this)})),function(){return t.apply(this,arguments)})}]),e}();exports.default=Authorizer;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {Session} from "./authorizer";
|
|
2
|
+
|
|
3
|
+
export default class SessionHistory {
|
|
4
|
+
add(session: Session): void;
|
|
5
|
+
|
|
6
|
+
check(jwt: string): boolean;
|
|
7
|
+
|
|
8
|
+
deprecate(session: Session): void;
|
|
9
|
+
|
|
10
|
+
clean(): void;
|
|
11
|
+
|
|
12
|
+
isDeprecated(session: Session): boolean;
|
|
13
|
+
|
|
14
|
+
size: number;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _common=require("../../core/common");function _classCallCheck(e,r){if(!(e instanceof r))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var i=r[t];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,i.key,i)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}var SessionHistory=function(){function e(){_classCallCheck(this,e),_defineProperty(this,"_history",new Array(10)),_defineProperty(this,"_position",0),_defineProperty(this,"_size",0)}return _createClass(e,[{key:"size",get:function(){return this._size}},{key:"add",value:function(r){var e,t,i,n,o;Object.keys(r).every(function(e){return(0,_common.isNullOrEmpty)(r[e])})||(e=r.access_token,t=r.accessToken,i=r.token,n=r.refresh_token,o=r.refreshToken,this._history[this._position]={access_token:e||t||i,refresh_token:n||o,invalid:!1},this._position++,this._position%=this._history.length,this._size=this._history.reduce(function(e,r){return r?e+1:e},0))}},{key:"check",value:function(i){return this._history.some(function(e){var r,t;return!!e&&(r=e.access_token,t=e.accessToken,e=e.token,(r||t||e)===i)})}},{key:"deprecate",value:function(e){var t=0,i=e.refresh_token,n=e.refreshToken,e=this._history.find(function(e,r){return t=r,!!e&&(e.refresh_token||e.refreshToken)===(i||n)});e&&(e.invalid=!0,e=this._history[0],this._history[0]=this._history[t],this._history[t]=e)}},{key:"clean",value:function(){for(var e=0;e<this._history.length;++e){var r=this._history[e];r&&r.invalid&&(this._history[e]=null)}this._size=this._history.reduce(function(e,r){return r?e+1:e},0)}},{key:"isDeprecated",value:function(i){return this._history.some(function(e){if(e){var r=i.refresh_token,t=i.refreshToken;if(r||t)return(e.refresh_token||e.refreshToken)===(r||t)&&e.invalid}return!1})}}]),e}();exports.default=SessionHistory;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=AuthorizationPlugin;var _queue=_interopRequireDefault(require("./queue"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function asyncGeneratorStep(e,r,t,n,s,a,o){try{var u=e[a](o),c=u.value}catch(e){return void t(e)}u.done?r(c):Promise.resolve(c).then(n,s)}function _asyncToGenerator(u){return function(){var e=this,o=arguments;return new Promise(function(r,t){var n=u.apply(e,o);function s(e){asyncGeneratorStep(n,r,t,s,a,"next",e)}function a(e){asyncGeneratorStep(n,r,t,s,a,"throw",e)}s(void 0)})}}function AuthorizationPlugin(o){return function(e){var r,t,s=!1,a=new _queue.default(o);e.axios.interceptors.response.use(function(e){return e},(r=_asyncToGenerator(regeneratorRuntime.mark(function e(r){var t,n;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(t=r.response,o.checkResponse(t)){e.next=65;break}if(s){e.next=60;break}return s=!0,e.next=6,o.getSession();case 6:if(n=e.sent,o.sessionHistory.isDeprecated(n))return e.prev=8,e.next=11,o.onAuthorizedDenied(r);e.next=21;break;case 11:o.sessionHistory.clean(),e.next=17;break;case 14:throw e.prev=14,e.t0=e.catch(8),r;case 17:return e.prev=17,s=!1,a.clear(),e.finish(17);case 21:if(o.checkSession(r.config,n)){e.next=47;break}return e.prev=22,e.t1=o,e.next=26,o.refreshSession(n);case 26:return e.t2=e.sent,e.next=29,e.t1.storageSession.call(e.t1,e.t2);case 29:e.next=47;break;case 31:return e.prev=31,e.t3=e.catch(22),o.sessionHistory.deprecate(n),e.prev=34,e.next=37,o.onAuthorizedDenied(e.t3);case 37:o.sessionHistory.clean(),e.next=43;break;case 40:throw e.prev=40,e.t4=e.catch(34),r;case 43:return e.prev=43,s=!1,a.clear(),e.finish(43);case 47:for(s=!1;a.size;)a.pop();return e.prev=49,e.next=52,a.resend(r);case 52:return e.abrupt("return",e.sent);case 55:throw e.prev=55,e.t5=e.catch(49),e.t5;case 58:e.next=63;break;case 60:return e.next=62,a.push(r);case 62:return e.abrupt("return",e.sent);case 63:e.next=66;break;case 65:throw r;case 66:case"end":return e.stop()}},e,null,[[8,14,17,21],[22,31],[34,40,43,47],[49,55]])})),function(e){return r.apply(this,arguments)})),e.axios.interceptors.request.use((t=_asyncToGenerator(regeneratorRuntime.mark(function e(r){var t;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,o.getSession();case 2:return t=e.sent,o.withAuthentication(r,t),e.abrupt("return",r);case 5:case"end":return e.stop()}},e)})),function(e){return t.apply(this,arguments)}))}}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {AxiosError, AxiosPromise} from "axios";
|
|
2
|
+
import Authorizer from "./authorizer";
|
|
3
|
+
|
|
4
|
+
export default class PendingQueue {
|
|
5
|
+
constructor(authorizer: Authorizer);
|
|
6
|
+
|
|
7
|
+
resend(error: AxiosError, retries?: number): AxiosPromise<any>;
|
|
8
|
+
|
|
9
|
+
push(error: AxiosError): AxiosPromise<any>;
|
|
10
|
+
|
|
11
|
+
pop(): void;
|
|
12
|
+
|
|
13
|
+
clear(): void;
|
|
14
|
+
|
|
15
|
+
size: number;
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var _axios=_interopRequireDefault(require("axios"));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function asyncGeneratorStep(e,r,t,n,i,o,a){try{var u=e[o](a),s=u.value}catch(e){return void t(e)}u.done?r(s):Promise.resolve(s).then(n,i)}function _asyncToGenerator(u){return function(){var e=this,a=arguments;return new Promise(function(r,t){var n=u.apply(e,a);function i(e){asyncGeneratorStep(n,r,t,i,o,"next",e)}function o(e){asyncGeneratorStep(n,r,t,i,o,"throw",e)}i(void 0)})}}function _classCallCheck(e,r){if(!(e instanceof r))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,r){for(var t=0;t<r.length;t++){var n=r[t];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function _createClass(e,r,t){return r&&_defineProperties(e.prototype,r),t&&_defineProperties(e,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,r,t){return r in e?Object.defineProperty(e,r,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[r]=t,e}function random(e,r){return(Math.random()*(r-e+1)|0)+e}function sleep(t){return new Promise(function(e){var r=setTimeout(function(){clearTimeout(r),r=void 0,e()},t)})}var PendingQueue=function(){function r(e){_classCallCheck(this,r),_defineProperty(this,"_queue",[]),_defineProperty(this,"_authorizer",null),_defineProperty(this,"_axios",_axios.default.create()),this._authorizer=e}var t;return _createClass(r,[{key:"resend",value:(t=_asyncToGenerator(regeneratorRuntime.mark(function e(r){var t,n,i,o=arguments;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:t=1<o.length&&void 0!==o[1]?o[1]:3,n=0;case 2:if(!(n<t)){e.next=25;break}if(0<n)return e.next=6,sleep(random(3e3,5e3));e.next=6;break;case 6:return e.next=8,this._authorizer.getSession();case 8:if(i=e.sent,this._authorizer.sessionHistory.isDeprecated(i))throw r;e.next=11;break;case 11:return e.prev=11,this._authorizer.withAuthentication(r.config,i),e.next=15,this._axios.request(r.config);case 15:return e.abrupt("return",e.sent);case 18:if(e.prev=18,e.t0=e.catch(11),t-1<=n)throw e.t0;e.next=22;break;case 22:++n,e.next=2;break;case 25:case"end":return e.stop()}},e,this,[[11,18]])})),function(e){return t.apply(this,arguments)})},{key:"push",value:function(t){var n=this;return new Promise(function(e,r){n._queue.push({error:t,resolve:e,reject:r})})}},{key:"pop",value:function(){var e=this._queue.shift(),r=e.error,t=e.resolve,e=e.reject;this.resend(r).then(t).catch(e)}},{key:"clear",value:function(){this._queue.splice(0).forEach(function(e){var r=e.error;(0,e.reject)(r)})}},{key:"size",get:function(){return this._queue.length}}]),r}();exports.default=PendingQueue;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function asyncGeneratorStep(e,t,r,n,o,a,i){try{var s=e[a](i),c=s.value}catch(e){return void r(e)}s.done?t(c):Promise.resolve(c).then(n,o)}function _asyncToGenerator(s){return function(){var e=this,i=arguments;return new Promise(function(t,r){var n=s.apply(e,i);function o(e){asyncGeneratorStep(n,t,r,o,a,"next",e)}function a(e){asyncGeneratorStep(n,t,r,o,a,"throw",e)}o(void 0)})}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}function _createClass(e,t,r){return t&&_defineProperties(e.prototype,t),r&&_defineProperties(e,r),Object.defineProperty(e,"prototype",{writable:!1}),e}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}Object.defineProperty(exports,"__esModule",{value:!0}),exports.default=void 0;var SessionStorage=function(){function e(){_classCallCheck(this,e),_defineProperty(this,"_inMemoryStorage",{})}var t,r,n;return _createClass(e,[{key:"set",value:(n=_asyncToGenerator(regeneratorRuntime.mark(function e(t,r){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:window&&window.sessionStorage?window.sessionStorage.setItem(t,JSON.stringify(r)):wx&&wx.setStorageSync?wx.setStorageSync(t,r):my&&my.setStorageSync?my.setStorageSync(t,r):tt&&tt.setStorageSync?tt.setStorageSync(t,r):this._inMemoryStorage[t]=r;case 1:case"end":return e.stop()}},e,this)})),function(e,t){return n.apply(this,arguments)})},{key:"get",value:(r=_asyncToGenerator(regeneratorRuntime.mark(function e(t){var r;return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:if(window&&window.sessionStorage)return r=window.sessionStorage.getItem(t),e.abrupt("return",JSON.parse(r));e.next=5;break;case 5:if(wx&&wx.getStorageSync)return e.abrupt("return",wx.getStorageSync(t));e.next=9;break;case 9:if(my&&my.getStorageSync)return e.abrupt("return",my.getStorageSync(t));e.next=13;break;case 13:if(tt&&tt.getStorageSync)return e.abrupt("return",tt.getStorageSync(t));e.next=17;break;case 17:return e.abrupt("return",this._inMemoryStorage[t]);case 18:case"end":return e.stop()}},e,this)})),function(e){return r.apply(this,arguments)})},{key:"remove",value:(t=_asyncToGenerator(regeneratorRuntime.mark(function e(t){return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:window&&window.sessionStorage?window.sessionStorage.removeItem(t):wx&&wx.removeStorageSync?wx.removeStorageSync(t):my&&my.removeStorageSync?my.removeStorageSync(t):tt&&tt.removeStorageSync?tt.removeStorageSync(t):delete this._inMemoryStorage[t];case 1:case"end":return e.stop()}},e,this)})),function(e){return t.apply(this,arguments)})}]),e}();exports.default=SessionStorage;
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "axios-annotations",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+ssh://git@github.com/sitorhy/axios-annotations.git"
|
|
7
|
+
},
|
|
8
|
+
"author": "sitorhy",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"miniprogram": "lib",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"axios",
|
|
13
|
+
"axios-annotations",
|
|
14
|
+
"axios-decorators"
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../../lib/plugins/auth/authorizer");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../../lib/plugins/auth/history");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../../lib/plugins/auth/index");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../../lib/plugins/auth/queue");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("../../lib/plugins/auth/storage");
|