├── .babelrc
├── .gitignore
├── README.md
├── doc
├── README-zh.md
├── logo-with-text.png
├── logo.png
└── request-flow.png
├── example
├── configs
│ └── sever-config.json
├── js
│ ├── github-service.js
│ ├── http
│ │ ├── http-service.js
│ │ └── interceptors
│ │ │ ├── req-logger.js
│ │ │ ├── res-error-catcher.js
│ │ │ └── res-logger.js
│ ├── index.js
│ └── main.js
└── ts
│ ├── src
│ ├── configs
│ │ └── sever-config.json
│ ├── http
│ │ ├── http-service.ts
│ │ ├── interceptors
│ │ │ └── request-logger.interceptor.ts
│ │ └── operators
│ │ │ └── ok-operator.pipe.ts
│ └── index.ts
│ └── tsconfig.json
├── package.json
├── src
├── clients
│ ├── browser-client.ts
│ └── index.ts
├── core
│ ├── error.ts
│ ├── index.ts
│ ├── interceptor
│ │ ├── attach-interceptor.ts
│ │ ├── index.ts
│ │ └── interceptor.ts
│ └── operation
│ │ ├── index.ts
│ │ ├── operation.ts
│ │ └── operators
│ │ ├── delete-operator.begin.ts
│ │ ├── expect-operator.terminal.ts
│ │ ├── get-operator.begin.ts
│ │ ├── index.ts
│ │ ├── match-operator.terminal.ts
│ │ ├── pipe-operator.pipe.ts
│ │ ├── post-operator.begin.ts
│ │ ├── put-operator.begin.ts
│ │ ├── request-operator.ts
│ │ └── unwrap-operator.terminal.ts
├── factory
│ ├── http-factory.ts
│ ├── http-service.ts
│ └── index.ts
├── index.ts
├── module
│ ├── hooks.ts
│ ├── index.ts
│ └── metadata.ts
├── services
│ ├── configure.ts
│ ├── index.ts
│ └── operator
│ │ ├── exec-stack.ts
│ │ ├── index.ts
│ │ ├── operator-exec-data.ts
│ │ ├── operator-service.ts
│ │ └── operator-set.ts
└── typings
│ └── construct.d.ts
├── tsconfig.json
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["@babel/preset-env"],
3 | "plugins": ["@babel/plugin-transform-runtime"]
4 | }
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | yarn-error.log
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 |
5 | English | [中文文档](doc/README-zh.md)
6 |
7 | ## What's Fence🐟
8 |
9 | Fence is an operator-based request library that provide a serises of APIs to help you more easily manipulate the request flow. And the `Fence` is works fine in browsers and server as well, cause `Fence` is based on Axios by default.
10 |
11 | ## Feature
12 |
13 | - 🌊 **Operator-based** The `Fence` whole system is operator-based, the means that you can define a lot of `operator` to do something with request data in the request flow, and there are 8 build-in operator, you can working fine with these operators.
14 | - 🍵 **Object-oriented** If you like `Object-Oriented Programing`, this library is perfect for you, we will cover `Function API` in the future.
15 | - 🚴 **lightweight** We have not provide a lot of `operator` for users, cause users can define them own operator and combine them into new operator.
16 | - 🙅♂️ **Perfect error handing system** Many developers often forget or incorrectly handing error which come from the request flow, `Fence` will force you to handing these errors or ignore these error by explicit, it can help developers understanding what they are doing rather than forget handing these errors.
17 | - ⚙️ **Removable** That is you can use the operator that you wanna use, the same you can remove the operator that you don't wanna use.
18 | - 🏹️ **Flexible** You can combine existing operators to create more possibilities.
19 |
20 | ## Usage
21 |
22 | You can install `Fence` with NPM and YARN as well.
23 |
24 | ```sh
25 | # YARN
26 | yarn add @wizardoc/fence
27 |
28 | # NPM
29 | npm i @wizardoc/fence
30 | ```
31 |
32 | ### Simple example
33 |
34 | ```ts
35 | import {
36 | HTTPModule,
37 | HTTPFactory,
38 | AxiosError,
39 | ErrorInteractModule,
40 | ErrorMessage,
41 | } from "@wizardoc/fence";
42 |
43 | @HTTPModule({
44 | server: {
45 | baseUrl: "api.github.com",
46 | protocol: "https",
47 | },
48 | })
49 | export class AppHttpModule implements ErrorInteractModule {
50 | errorInteract(errMsg: ErrorMessage, err: AxiosError): void {
51 | alert(errMsg);
52 | }
53 | }
54 |
55 | export async function main() {
56 | const http = HTTPFactory.create(AppHttpModule);
57 | const res = await http.get("/users/youncccat").expect(() => "Network Error");
58 |
59 | console.info(res);
60 | }
61 |
62 | main();
63 | ```
64 |
65 | > You can see [Example](https://github.com/wizardoc/http-request/tree/main/example) for more detail.
66 |
67 | ## Operator system
68 |
69 | The Operator system are the CORE of the `Fence`, in other word the `Fence` is designed to be based on operator system.
70 |
71 |
72 |
73 | As you can see the request is just like a flow, and you can define a lot of pipe-operator to manipulate the response data before terminated the request flow. For instance, I wanna get `avatar_url` of `youncccat` from GitHub.
74 |
75 | ```ts
76 | const res = await http
77 | .get("/users/youncccat")
78 | .pipe(({data}) => data)
79 | .pipe({avatar_url: avatar} => avatar)
80 | .expect(() => "Network Error");
81 | ```
82 |
83 | The beauty of the `pipe` is that can break the logics down into a smaller chunks, and these chunks is reusable and testable, you can use these chunks every where to help u complete whatever target you want to do without write duplicated code.
84 |
85 | In the operator system, there are three operator type as you can used:
86 |
87 | - **Begin-operator** like `get`, `post`, `put` or something like that
88 | - **Pipe-operator** like `pipe`
89 | - **Terminal-operator** like `unwrap`, `expect`, `match`
90 |
91 | ### Begin operator
92 |
93 | The begin-operator is located beginning of the entire request flow, that means you should invoke a begin-operator to start a request flow.
94 |
95 | ```ts
96 | http.get("/");
97 | ```
98 |
99 | The `get` just is a begin-operator, that can send `GET` request to the target server, but more interested things is you can also invoke a begin-operator after the another begin-operator, for instance you can invoked like the following code:
100 |
101 | ```ts
102 | http.get("/").post("/foo").get("/bar");
103 | ```
104 |
105 | And you can also mixin some pipe-operator
106 |
107 | ```ts
108 | http
109 | .get("/")
110 | .pipe(({ data }) => data.avatar_url)
111 | .post((avatar) => avatar);
112 | ```
113 |
114 | This gracefully solve the problem of request nesting. In above example, the response data of the `get` request is the dependencies of the `post` request, so we have to wait for the `get` request to complete and get `avatar` from the response data before send the `post` request, cause the `post` request need the `avatar` as the url of the request.
115 |
116 | In the `fetch API`, maybe we can do this with:
117 |
118 | ```ts
119 | fetch("/")
120 | .then((res) => res.json())
121 | .then(({ data }) => fetch(data.avatar_url, { method: "POST" }));
122 | ```
123 |
124 | As you can see, this workaround will leads `callback hell`, for example, if I have five requests that interdependent, using `Fetch API` :
125 |
126 | ```ts
127 | fetch("/")
128 | .then(res => res.json())
129 | .then(({data}) =>
130 | fetch(data.avatar_url, {method: 'POST'})
131 | .then(res => res.json())
132 | .then(({data}) =>
133 | fetch(data.avatar_url, {method: 'POST'})
134 | .then(res => res.json())
135 | .then(({data}) =>
136 | fetch(data.avatar_url, {method: 'POST'})
137 | .then(res => res.json())
138 | .then(({data}) =>
139 | fetch(data.avatar_url, {method: 'POST'})
140 | .then(res => res.json())
141 | .then(() => /** ... */)
142 |
143 | ```
144 |
145 | It's looks ugly and difficult to maintain.
146 |
147 | > Notice: if you have try to run the above `Fence` example code, you will found the request does not send out, A simple reason is that you forget handing errors that probably occur from the request flow, so the real request will not send out. `Fence` will against any request that does not handing errors, it can help you to make a robust application, force you to handing errors. In the rest of the chapter, you will learned terminal-operator, that can handing error when sending the real request out.
148 |
149 | ### Pipe operator
150 |
151 | Also you can invoke pipe-operator before terminated the request flow to process data. And the `Fence` contain a build-in pipe-operator named `pipe`.
152 |
153 | ```ts
154 | http.get("/foo").pipe(data => /** Do whatever you wanna do */).unwrap()
155 | ```
156 |
157 | > Notice: the `pipe` operator will not invoked when the request occurred errors.
158 |
159 | ### Terminal operator
160 |
161 | Terminal-operator usually contain error-handing logic, so in order to send a request, you have to invoke only one terminal-operator on invoke chain.
162 |
163 | ```ts
164 | http.get().post().pipe().unwrap();
165 | ```
166 |
167 | If you forget to write terminal-operator, this request will not be send out, this design is by intent, cause you have to handing errors for every request to make your application robust more.
168 |
169 | The `Fence` have three build-in terminal-operator, we will cover in following chapters.
170 |
171 | ### Define your own operator
172 |
173 | Excepts that you can use the build-in operators, you can also define your own operator by `Fence operator API`.
174 |
175 | For instance, you wanna know the request is sending successful or not in outside context.
176 |
177 | ```ts
178 | const res = http.get("/foo").unwrap();
179 |
180 | // Do something if no error occurred on the request.
181 | // but now I can't know any information of this request in outside,
182 | // though I just wanna know this request is success or not
183 | // ...
184 | ```
185 |
186 | Though I can't invoke a pipe-operator to process this condition, cause the `pipe` operator will not invoked when the request occurred errors. So we can define a own operator to process this condition.
187 |
188 | ```ts
189 | import {
190 | OperatorRunEnv,
191 | PipeOperator,
192 | PipeOperatorContext,
193 | PipeOperatorExec,
194 | } from "@wizardoc/fence";
195 |
196 | export type WithOkRes = {
197 | ok: boolean;
198 | } & T;
199 |
200 | @PipeOperator({
201 | name: "withOk",
202 | env: OperatorRunEnv.ERROR_OCCUR,
203 | })
204 | export class WithOk implements PipeOperatorExec {
205 | exec({
206 | value,
207 | err,
208 | }: PipeOperatorContext>): WithOkRes<
209 | Record
210 | > {
211 | return {
212 | ...(value ?? {}),
213 | ok: !err,
214 | };
215 | }
216 | }
217 | ```
218 |
219 | And then we should register this operator in our application.
220 |
221 | ```ts
222 | @HTTPModule({
223 | server: ServerConfigInfo,
224 | operators: [WithOk], // <---- register the withOk operator
225 | interceptors: [],
226 | })
227 | export class AppHttpModule {}
228 | ```
229 |
230 | Now let's send a request and do something in outside when the request is success to send out.
231 |
232 | ```ts
233 | const { ok } = http.get("/foo").withOk().unwrap();
234 |
235 | if (ok) {
236 | // do something
237 | }
238 | ```
239 |
240 | Also you can define a lot of interesting operator to resolve your problem, let's happy hacking!
241 |
242 | ## Module
243 |
244 | In order to use `Fence`, you need to define a root module that contain error handing function and some configure, it looks like:
245 |
246 | ```ts
247 | @HTTPModule({
248 | server: ServerConfigInfo,
249 | operators: [],
250 | interceptors: [],
251 | })
252 | export class AppHttpModule {}
253 | ```
254 |
255 | ### Server config
256 |
257 | The `ServerConfigInfo` is the configure of the endpoint of the backend server:
258 |
259 | ```ts
260 | export interface ServerConfigInfo {
261 | baseUrl: string;
262 | protocol: string;
263 | port?: number;
264 | prefix?: string;
265 | }
266 | ```
267 |
268 | The `ServerConfigInfo` is resolved as `[protocol]://[baseUrl]:[port][prefix]` in fence
269 |
270 | ## Interceptors
271 |
272 | The principle of interceptors in `Fence` is similar with `Axios Interceptor`, cause the `Fence` is based-on Axios, but difference with Axios.
273 |
274 | **Response interceptor**
275 |
276 | ```ts
277 | import { HTTPResponseInterceptor, AxiosResponse } from "@wizardoc/fence";
278 |
279 | export class Bar implements HTTPResponseInterceptor {
280 | onResponse(res: AxiosResponse): AxiosResponse | Promise {
281 | /** intercept logic */
282 | }
283 | }
284 | ```
285 |
286 | **Request interceptor**
287 |
288 | ```ts
289 | import { HTTPRequestInterceptor, AxiosRequestConfig } from "@wizardoc/fence";
290 |
291 | export class Foo implements HTTPRequestInterceptor {
292 | onRequest(
293 | config: AxiosRequestConfig
294 | ): AxiosRequestConfig | Promise {
295 | /** intercept logic */
296 | }
297 | }
298 | ```
299 |
300 | And then you should register your interceptors in the root module:
301 |
302 | ```ts
303 | @HTTPModule({
304 | server: ServerConfigInfo,
305 | interceptors: [Foo, Bar] /** Register interceptor here */,
306 | })
307 | export class AppHttpModule {}
308 | ```
309 |
310 | Now everything is working fine :)
311 |
312 | ### Example
313 |
314 | Let's define a logger interceptor to print request url when send request.
315 |
316 | ```ts
317 | import {
318 | HTTPRequestInterceptor,
319 | AxiosRequestConfig,
320 | HTTPFactory,
321 | } from "@wizardoc/fence";
322 |
323 | export class Logger implements HTTPRequestInterceptor {
324 | onRequest(
325 | config: AxiosRequestConfig
326 | ): AxiosRequestConfig | Promise {
327 | console.info("request ===> ", config.url);
328 |
329 | return config;
330 | }
331 | }
332 |
333 | @HTTPModule({
334 | server: {
335 | baseUrl: "api.github.com",
336 | protocol: "https",
337 | },
338 | interceptors: [Logger] /** Register interceptor here */,
339 | })
340 | export class AppHttpModule {}
341 |
342 | // Main
343 | const http = HTTPFactory.create(AppModule);
344 |
345 | // Fetch user info
346 | http.get("/users/youncccat").unwrap();
347 | ```
348 |
349 | **output**
350 |
351 | ```sh
352 | request ===> https://api.github.com/users/youncccat
353 | ```
354 |
355 | ## Error handing
356 |
357 | Error handing is a important things in request, if you forget handing errors, it could occur unexpect error in your application. But if you write all error handing logic in same place to make a global error handler, it dose not flexible, maybe you wanna process some error by separately. So we introduce the three ways to handle errors, of course you can defined your own error handler in terminal operator.
358 |
359 | ### 0x1 Global error handing
360 |
361 | We often handle some exceptions in the request flow, also we need a "global space" to handing the error that come from every request, so we need to use a terminal-operator named `expect`, that receive a callback that's sign like `() => string`, the return value of the callback is a error message which you wanna provide to the "global space".
362 |
363 | ```
364 | http.get('/foo').expect(() => 'Cannot visit foo')
365 |
366 | http.get('/bar').expect(() => 'Cannot visit bar')
367 |
368 | http.post('/user').expect(() => 'Cannot create the user')
369 | ```
370 |
371 | And then you can get these error message in `errorInteract` function, as you can see that the `errorInteract` just is "global space" that we talk about in above.
372 |
373 | In order to define the "global space", you have to make the `AppHttpModule` implements `ErrorInteractModule` interface, and implements the `errorInteract` function, refer the following code snap:
374 |
375 | ```ts
376 | @HTTPModule({
377 | server: {
378 | baseUrl: "api.github.com",
379 | protocol: "https",
380 | },
381 | })
382 | export class AppHttpModule implements ErrorInteractModule {
383 | // The errorInteract will be invoked when the request was fail
384 | errorInteract(errMsg: ErrorMessage, err: AxiosError): void {
385 | // The errMsg is the return value of the Expect's callback
386 | alert(errMsg);
387 | }
388 | }
389 | ```
390 |
391 | > Notice: if you are not familiar about the `Expect` operator, it's ok we will cover `operator` soon.
392 |
393 | That means if the `http.get('/foo').expect(() => 'Cannot visit foo')` was fail, the page will alert `Cannot visit foo`, but it doesn't make sense, cause there have a lot of type of the error, so actually the "error message" is just like if there have no error types is matched, then return the "error message".
394 |
395 | So maybe we will write codes that something like this:
396 |
397 | ```ts
398 | @HTTPModule({
399 | server: {
400 | baseUrl: "api.github.com",
401 | protocol: "https",
402 | },
403 | })
404 | export class AppHttpModule implements ErrorInteractModule {
405 | errorInteract(finalErrMsg: ErrorMessage, err: AxiosError): void {
406 | // The errMsg which is come from backend, but if the errMsg is undefined that means
407 | // we can't access the server of backend, so we can use the finalErrMsg that come
408 | // from the return value of the Expect's callback
409 | const errMsg = err.response?.data.err?.message;
410 |
411 | // You can use another function to show the error message to the page
412 | alert(errMsg ?? finalErrMsg);
413 | }
414 | }
415 | ```
416 |
417 | And maybe you notice that we don't have to use ui-related function(like `toast`, `alert`, `modal` etc.) in the `Expect`'s callback, cause we wanna separate ui-related code and describe error code, so the `Expect`'s callback just return error message without describe how to show the error message is the page, and we can define these code in `errorInteract` to interact with ui(page).
418 |
419 | ### 0x2 Do nothing with handling errors
420 |
421 | Sometimes you don't wanna handing these errors, you just wanna throw them to outer layer just like `throw`, and write down the logic of handing error in outer layer and catch them, so you can use the `unwrap` terminal-operator that does not do anything extra with handing errors, but just throw it as a raw Axios error.
422 |
423 | ```ts
424 | const getFoo = () => http.get("/foo").unwrap();
425 |
426 | const bar = async () => {
427 | try {
428 | await getFoo();
429 | } catch (e) {
430 | console.error("Catch error: ", e);
431 | }
432 | };
433 |
434 | async function main() {
435 | bar();
436 | }
437 |
438 | main();
439 | ```
440 |
441 | ### 0x3 Handing errors by separately
442 |
443 | Though the `unwrap` terminal-operator also can handing errors separately, but you have to write annoying `try-catch` block, and the error will throw to outer layer, maybe u just wanna process it in current layer, you can use `match` terminal-operator, the sign of `match` just like this:
444 |
445 | ```ts
446 | type Match = ((data: unknown) => unknown, (err: AxiosError) => unknown)) => Promise
447 | ```
448 |
449 | The `match` function receive two callback named `successful callback` and `failure callback`, if the request is successful, the `successful callback` will be invoked, conversely the `failure callback` will be invoked.
450 |
451 | ```ts
452 | const res = http.get("/foo").match(
453 | data => data,
454 | err => /** handing error logic */;
455 | )
456 | ```
457 |
458 | If you familiar Rust programming, you should also familiar to the `match` :)
459 |
460 | ## Examples
461 |
462 | We have write some examples in [Examples](https://github.com/wizardoc/http-request/tree/main/example), you can access the link for more detail.
463 |
464 | ## License
465 |
466 | MIT.
467 |
--------------------------------------------------------------------------------
/doc/README-zh.md:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 |
5 | [English](../README.md) | 中文文档
6 |
7 | ## 什么是 Fence🐟
8 |
9 | `Fence` 是一个基于操作符的请求库,它提供了一系列 API 让你更轻松处理作请求流。因为`Fence` 默认基于 Axios,所以`Fence` 在浏览器和服务器中也可以正常工作。
10 |
11 | ## 特性
12 |
13 | - 🌊 **基于操作符** `Fence`整个体系是基于`操作符`的,并且内置了 8 个 操作符。你也可以自定义一些`操作符`来配合内置的`操作符`一起完成数据请求。
14 | - 🍵 **面向对象** 如果你喜欢`面向对象编程`,那么这个库非常适合你,并且我们会在将来支持`Function API`。
15 | - 🚴 **轻量级** 我们没有为用户提供过多的`操作符`,因为用户可以自定义`操作符`,并将它们组合成新的`操作符`。
16 | - 🙅♂️ **完善的错误处理体系** 许多开发人员经常忘记或不正确地处理来自请求流的错误,`Fence` 会强制您处理这些错误或显式忽略这些错误。
17 | - ⚙️ **可拆卸** 你可以根据需求来决定要使用那些`操作符`,也可以删除一些没有使用到的`操作符`。
18 | - 🏹️ **灵活性** 你可以结合现有的`操作符`来创造更多的`操作符`。
19 |
20 | ## 用法
21 |
22 | 你可以使用`yarn`或者`npm`来安装`Fence`。
23 |
24 | ```sh
25 | # YARN
26 | yarn add @wizardoc/fence
27 |
28 | # NPM
29 | npm i @wizardoc/fence
30 | ```
31 |
32 | ### 简单案例
33 |
34 | ```ts
35 | import {
36 | HTTPModule,
37 | HTTPFactory,
38 | AxiosError,
39 | ErrorInteractModule,
40 | ErrorMessage,
41 | } from "@wizardoc/fence";
42 |
43 | @HTTPModule({
44 | server: {
45 | baseUrl: "api.github.com",
46 | protocol: "https",
47 | },
48 | })
49 | export class AppHttpModule implements ErrorInteractModule {
50 | errorInteract(errMsg: ErrorMessage, err: AxiosError): void {
51 | alert(errMsg);
52 | }
53 | }
54 |
55 | export async function main() {
56 | const http = HTTPFactory.create(AppHttpModule);
57 | const res = await http.get("/users/youncccat").expect(() => "Network Error");
58 |
59 | console.info(res);
60 | }
61 |
62 | main();
63 | ```
64 |
65 | > 你可以查看更多详细的[案例](https://github.com/wizardoc/http-request/tree/main/example).
66 |
67 | ## 操作符体系
68 |
69 | `Fence`是基于操作符体系设计的,同样操作符体系也是`Fence`的核心。
70 |
71 |
72 |
73 | 如你所见,请求就像一个流,你可以定义一些管道操作符,在数据响应之前终止请求。
74 | 例如,我想从 GitHub 获取 `youncccat` 的 `avatar_url`。
75 |
76 | ```ts
77 | const res = await http
78 | .get("/users/youncccat")
79 | .pipe(({data}) => data)
80 | .pipe({avatar_url: avatar} => avatar)
81 | .expect(() => "Network Error");
82 | ```
83 |
84 | `pipe` 的巧妙之处在于可以将逻辑分解成细小的块,这些块是可复用和可测试的,你可以在任何地方使用这些块来帮你完成需求,而无需编写重复的代码。
85 |
86 | 在操作符体系中,一共包含一下三种`操作符`类型:
87 |
88 | - **开始操作符** 像 `get`, `post`, `put` 或类似的
89 | - **管道操作符** 像 `pipe`
90 | - **终止操作符** 想 `unwrap`, `expect`, `match`
91 |
92 | ### 开始操作符
93 |
94 | 开始操作符位于整个请求流的开头,你应该调用开始操作符位来启动请求流。
95 |
96 | ```ts
97 | http.get("/");
98 | ```
99 |
100 | `get`仅仅是一个开始操作符,它可以向目标服务器发送`GET`请求,你可以在另一个开始操作符之后调用开始操作符,就像下面的代码:
101 |
102 | ```ts
103 | http.get("/").post("/foo").get("/bar");
104 | ```
105 |
106 | 你也可以混入一些管道操作符
107 |
108 | ```ts
109 | http
110 | .get("/")
111 | .pipe(({ data }) => data.avatar_url)
112 | .post((avatar) => avatar);
113 | ```
114 |
115 | 这样就优雅的解决了请求嵌套的问题。在上面的例子中,`get` 请求的响应数据是`post` 请求的依赖,所以我们必须等待`get` 请求完成并从响应数据中获取`avatar`,然后发送`post` `请求`。
116 |
117 | 在 `fetch API` 中,我们也许会这样做:
118 |
119 | ```ts
120 | fetch("/")
121 | .then((res) => res.json())
122 | .then(({ data }) => fetch(data.avatar_url, { method: "POST" }));
123 | ```
124 |
125 | 如果我有五个相互依赖的请求,使用“Fetch API”的情况下,将会导致“回调地狱”:
126 |
127 | ```ts
128 | fetch("/")
129 | .then(res => res.json())
130 | .then(({data}) =>
131 | fetch(data.avatar_url, {method: 'POST'})
132 | .then(res => res.json())
133 | .then(({data}) =>
134 | fetch(data.avatar_url, {method: 'POST'})
135 | .then(res => res.json())
136 | .then(({data}) =>
137 | fetch(data.avatar_url, {method: 'POST'})
138 | .then(res => res.json())
139 | .then(({data}) =>
140 | fetch(data.avatar_url, {method: 'POST'})
141 | .then(res => res.json())
142 | .then(() => /** ... */)
143 |
144 | ```
145 |
146 | 它不太美观并且难以维护 。
147 |
148 | > 注意:如果你尝试运行以上的`Fence`示例代码,你会发现请求没有发送出去,原因在于你忘记了在请求流中可能发生的错误,所以请求不会发送出去。 `Fence` 反对任何不处理错误的请求,你必须处理错误的情况,从而帮助您编写一个健壮的应用程序。在本章的其余部分,将介绍终止操作符,它可以在发送真实请求时处理错误。
149 |
150 | ### 管道操作符
151 |
152 | 你可以使用管道操作符在终止请求流之前处理数据。 `Fence` 内置了 `pipe` 的管道操作符。
153 |
154 | ```ts
155 | http.get("/foo").pipe(data => /** Do whatever you wanna do */).unwrap()
156 | ```
157 |
158 | > 注意:当请求发生错误时,`pipe` 操作符不会被调用。
159 |
160 | ### 终止操作符
161 |
162 | 通常情况下终止操作符包含错误处理逻辑 ,发送请求中只需在调用链上使用一个终止操作符。
163 |
164 | ```ts
165 | http.get().post().pipe().unwrap();
166 | ```
167 |
168 | 如果你忘记使用终止操作符,这个请求将不会被发送出去。这是有意而为之的,你必须为每个请求处理错误来确保程序的健壮性。
169 |
170 | `Fence` 内置了三个终止操作符,我们将在接下来的章节中介绍。
171 |
172 | ### 自定义操作符
173 |
174 | 除了可以使用内置操作符,还可以通过`Fence operator API`来自定义操作符。
175 |
176 | 例如,你想在外部上下文中知道请求发送是否成功。
177 |
178 | ```ts
179 | const res = http.get("/foo").unwrap();
180 |
181 | // Do something if no error occurred on the request.
182 | // but now I can't know any information of this request in outside,
183 | // though I just wanna know this request is success or not
184 | // ...
185 | ```
186 |
187 | 请求发生错误时不会调用管道操作符,所以无法使用管道操作符来处理这种情况,我们可以自定义一个操作符来处理这个情况。
188 |
189 | ```ts
190 | import {
191 | OperatorRunEnv,
192 | PipeOperator,
193 | PipeOperatorContext,
194 | PipeOperatorExec,
195 | } from "@wizardoc/fence";
196 |
197 | export type WithOkRes = {
198 | ok: boolean;
199 | } & T;
200 |
201 | @PipeOperator({
202 | name: "withOk",
203 | env: OperatorRunEnv.ERROR_OCCUR,
204 | })
205 | export class WithOk implements PipeOperatorExec {
206 | exec({
207 | value,
208 | err,
209 | }: PipeOperatorContext>): WithOkRes<
210 | Record
211 | > {
212 | return {
213 | ...(value ?? {}),
214 | ok: !err,
215 | };
216 | }
217 | }
218 | ```
219 |
220 | 然后在我们的应用程序中注册这个操作符。
221 |
222 | ```ts
223 | @HTTPModule({
224 | server: ServerConfigInfo,
225 | operators: [WithOk], // <---- register the withOk operator
226 | interceptors: [],
227 | })
228 | export class AppHttpModule {}
229 | ```
230 |
231 | 现在让我们发送一个请求,并在请求成功发送时在外面做一些事情。
232 |
233 | ```ts
234 | const { ok } = http.get("/foo").withOk().unwrap();
235 |
236 | if (ok) {
237 | // do something
238 | }
239 | ```
240 |
241 | 你也可以定义很多有趣的操作符来解决你的问题。
242 |
243 | ## 模板
244 |
245 | 使用`Fence`,你需要定义一个包含错误处理和配置项的根模块,例如:
246 |
247 | ```ts
248 | @HTTPModule({
249 | server: ServerConfigInfo,
250 | operators: [],
251 | interceptors: [],
252 | })
253 | export class AppHttpModule {}
254 | ```
255 |
256 | ### 服务器配置
257 |
258 | `ServerConfigInfo` 是后端服务器的配置:
259 |
260 | ```ts
261 | export interface ServerConfigInfo {
262 | baseUrl: string;
263 | protocol: string;
264 | port?: number;
265 | prefix?: string;
266 | }
267 | ```
268 |
269 | 在 fence 中`ServerConfigInfo` 被解析为`[protocol]://[baseUrl]:[port][prefix]`
270 |
271 | ## 拦截器
272 |
273 | 因为`Fence`是基于 Axios,所以拦截器的原理与`Axios Interceptor`类似,但与 Axios 有所不同。
274 |
275 | **响应拦截器**
276 |
277 | ```ts
278 | import { HTTPResponseInterceptor, AxiosResponse } from "@wizardoc/fence";
279 |
280 | export class Bar implements HTTPResponseInterceptor {
281 | onResponse(res: AxiosResponse): AxiosResponse | Promise {
282 | /** intercept logic */
283 | }
284 | }
285 | ```
286 |
287 | **请求拦截器**
288 |
289 | ```ts
290 | import { HTTPRequestInterceptor, AxiosRequestConfig } from "@wizardoc/fence";
291 |
292 | export class Foo implements HTTPRequestInterceptor {
293 | onRequest(
294 | config: AxiosRequestConfig
295 | ): AxiosRequestConfig | Promise {
296 | /** intercept logic */
297 | }
298 | }
299 | ```
300 |
301 | 你应该在根模块中注册你的拦截器:
302 |
303 | ```ts
304 | @HTTPModule({
305 | server: ServerConfigInfo,
306 | interceptors: [Foo, Bar] /** Register interceptor here */,
307 | })
308 | export class AppHttpModule {}
309 | ```
310 |
311 | 现在一切工作正常:)
312 |
313 | ### 例子
314 |
315 | 让我们定义一个记录拦截器在发送请求时打印请求 url。
316 |
317 | ```ts
318 | import {
319 | HTTPRequestInterceptor,
320 | AxiosRequestConfig,
321 | HTTPFactory,
322 | } from "@wizardoc/fence";
323 |
324 | export class Logger implements HTTPRequestInterceptor {
325 | onRequest(
326 | config: AxiosRequestConfig
327 | ): AxiosRequestConfig | Promise {
328 | console.info("request ===> ", config.url);
329 |
330 | return config;
331 | }
332 | }
333 |
334 | @HTTPModule({
335 | server: {
336 | baseUrl: "api.github.com",
337 | protocol: "https",
338 | },
339 | interceptors: [Logger] /** Register interceptor here */,
340 | })
341 | export class AppHttpModule {}
342 |
343 | // Main
344 | const http = HTTPFactory.create(AppModule);
345 |
346 | // Fetch user info
347 | http.get("/users/youncccat").unwrap();
348 | ```
349 |
350 | **输出**
351 |
352 | ```sh
353 | request ===> https://api.github.com/users/youncccat
354 | ```
355 |
356 | ## 错误处理
357 |
358 | 错误处理是请求中至关重要的,如果您忘记处理错误,你的应用程序中则可能发生意外的错误。但是如果你编写全局的请求错误处理逻辑,它就失去了灵活性。当然你可以在终止操作符中定义自己的错误处理逻辑,我们也提供了三种处理错误的方式。
359 |
360 | ### 0x1 全局错误处理
361 |
362 | 在处理请求流中的一些异常时,我们通常需要一个`global space`来处理来自每个请求的错误,为此我们提供了`expect`的终止操作符,它接收一个类似` () => string`的回调函数,函数的返回值是提供给`global space`的错误消息。
363 |
364 | ```
365 | http.get('/foo').expect(() => 'Cannot visit foo')
366 |
367 | http.get('/bar').expect(() => 'Cannot visit bar')
368 |
369 | http.post('/user').expect(() => 'Cannot create the user')
370 | ```
371 |
372 | `errorInteract` 就是我们上面讨论的`global space`,你可以在 `errorInteract` 函数中得到这些错误信息。
373 |
374 | 为了定义`global space`,你必须让`AppHttpModule`实现`ErrorInteractModule`接口,并实现`errorInteract`功能,参考如下:
375 |
376 | ```ts
377 | @HTTPModule({
378 | server: {
379 | baseUrl: "api.github.com",
380 | protocol: "https",
381 | },
382 | })
383 | export class AppHttpModule implements ErrorInteractModule {
384 | // The errorInteract will be invoked when the request was fail
385 | errorInteract(errMsg: ErrorMessage, err: AxiosError): void {
386 | // The errMsg is the return value of the Expect's callback
387 | alert(errMsg);
388 | }
389 | }
390 | ```
391 |
392 | > 注意:如果您不熟悉 `Expect` 运算符,没关系,我们很快就会介绍它。
393 |
394 | 如果 `http.get('/foo').expect(() => 'Cannot visit foo')` 失败,页面会提示 `Cannot visit foo`,但这没有意义,因为请求错误的类型很多,如果没有匹配的错误类型,则会默认返回“错误信息”。
395 |
396 | 所以我们会处理:
397 |
398 | ```ts
399 | @HTTPModule({
400 | server: {
401 | baseUrl: "api.github.com",
402 | protocol: "https",
403 | },
404 | })
405 | export class AppHttpModule implements ErrorInteractModule {
406 | errorInteract(finalErrMsg: ErrorMessage, err: AxiosError): void {
407 | // The errMsg which is come from backend, but if the errMsg is undefined that means
408 | // we can't access the server of backend, so we can use the finalErrMsg that come
409 | // from the return value of the Expect's callback
410 | const errMsg = err.response?.data.err?.message;
411 |
412 | // You can use another function to show the error message to the page
413 | alert(errMsg ?? finalErrMsg);
414 | }
415 | }
416 | ```
417 |
418 | 你也许注意到了,不必在 `Expect` 的回调中使用 ui 相关的函数(如 `toast`、`alert`、`modal` 等),我们应该对 ui 相关的代码和描述错误代码进行了解耦,`Expect`的回调只负责返回错误信息,`errorInteract`中定义这些错误信息如何在页面中展示。
419 |
420 | ### 0x2 不处理错误
421 |
422 | 有些情况你不想处理这些错误,你想使用`throw`将错误抛出,在外层捕获它们并做错误处理的逻辑。这时你可以使用`unwrap`终止操作符,它不会对错误做任何操作,只是将其当做原始 Axios 错误抛出。
423 |
424 | ```ts
425 | const getFoo = () => http.get("/foo").unwrap();
426 |
427 | const bar = async () => {
428 | try {
429 | await getFoo();
430 | } catch (e) {
431 | console.error("Catch error: ", e);
432 | }
433 | };
434 |
435 | async function main() {
436 | bar();
437 | }
438 |
439 | main();
440 | ```
441 |
442 | ### 0x3 单独处理错误
443 |
444 | 虽然 `unwrap` 终止操作符也可以单独处理错误,但是你必须编写烦人的 `try-catch` ,并且错误会抛出到外层,也许你只是想在当前层处理它,你可以使用 ` match` 终止运算符:
445 |
446 | ```ts
447 | type Match = ((data: unknown) => unknown, (err: AxiosError) => unknown)) => Promise
448 | ```
449 |
450 | `match` 接受`successful callback` 和`failure callback` 两个回调,如果请求成功,则会执行`successful callback`,反之会执行`failure callback`。
451 |
452 | ```ts
453 | const res = http.get("/foo").match(
454 | data => data,
455 | err => /** handing error logic */;
456 | )
457 | ```
458 |
459 | 如果你了解 Rust 编程,你应该也熟悉 `match` :)
460 |
461 | ## 更多案例
462 |
463 | 你可以访问[这里](https://github.com/wizardoc/http-request/tree/main/example)了解更多细节。
464 |
465 | ## License
466 |
467 | MIT.
468 |
--------------------------------------------------------------------------------
/doc/logo-with-text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardoc/fence/4e3a3d16b4fc1a47aa16e61fc6cf1552c59cd7f2/doc/logo-with-text.png
--------------------------------------------------------------------------------
/doc/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardoc/fence/4e3a3d16b4fc1a47aa16e61fc6cf1552c59cd7f2/doc/logo.png
--------------------------------------------------------------------------------
/doc/request-flow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardoc/fence/4e3a3d16b4fc1a47aa16e61fc6cf1552c59cd7f2/doc/request-flow.png
--------------------------------------------------------------------------------
/example/configs/sever-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "api.github.com",
3 | "port": 80,
4 | "protocol": "https",
5 | "mode": "prod"
6 | }
7 |
--------------------------------------------------------------------------------
/example/js/github-service.js:
--------------------------------------------------------------------------------
1 | import {http} from './http/http-service'
2 |
3 | export class GitHubService {
4 | getUserDetail(name) {
5 | return http.get(`/users/${name}`)
6 | }
7 |
8 | // Request to an incorrect addr
9 | async getWhatever() {
10 | const res = await http.get('/foo')
11 |
12 | res.expect(() => "This addr cannot be reached!").success(() => "impossible!")
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/example/js/http/http-service.js:
--------------------------------------------------------------------------------
1 | import {HTTPRequestFactory} from '../../..'
2 | import ServerConfig from '../../configs/sever-config.json'
3 | import {ReqLogger} from './interceptors/req-logger'
4 | import {ResLogger} from './interceptors/res-logger'
5 | import {ResErrorCatcher} from './interceptors/res-error-catcher'
6 |
7 | export class HTTPFactory extends HTTPRequestFactory {
8 | configure({interceptor, serverConfigure}) {
9 | serverConfigure.setConfig(ServerConfig)
10 |
11 | interceptor.use([
12 | ReqLogger,
13 | ResLogger,
14 | ResErrorCatcher
15 | ])
16 | }
17 |
18 | errorInteract(errMsg, err) {
19 | console.info(err)
20 | }
21 | }
22 |
23 | const httpFactory = new HTTPFactory()
24 |
25 | export const http = httpFactory.create()
26 |
--------------------------------------------------------------------------------
/example/js/http/interceptors/req-logger.js:
--------------------------------------------------------------------------------
1 | export class ReqLogger {
2 | onRequest(config) {
3 | console.info("REQ LOG: ===> ", JSON.stringify(config))
4 |
5 | return config
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/js/http/interceptors/res-error-catcher.js:
--------------------------------------------------------------------------------
1 | export class ResErrorCatcher {
2 | catchRes(err) {
3 | console.info("Error: ", err)
4 |
5 | throw err
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/js/http/interceptors/res-logger.js:
--------------------------------------------------------------------------------
1 | export class ResLogger {
2 | onResponse(res){
3 | // The res is an raw Axios response, so if u wanna get data when u using it,
4 | // u need to return data of res from res interceptor
5 | return res.data
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/example/js/index.js:
--------------------------------------------------------------------------------
1 | require("@babel/register")
2 | require("./main.js")
3 |
--------------------------------------------------------------------------------
/example/js/main.js:
--------------------------------------------------------------------------------
1 | import {GitHubService} from './github-service';
2 |
3 | const MOCK_USERNAME = 'youncccat';
4 |
5 | async function main() {
6 | // The service might inject in class as well as bound a certain variable using
7 | // DI lib that implemented by metadata in particular condition
8 | const githubService = new GitHubService();
9 | const res = await githubService.getUserDetail(MOCK_USERNAME);
10 |
11 | const {data: avatarURL} = res
12 | .expect(() => `Cannot access ${MOCK_USERNAME} information`)
13 | .pipe(data => data?.avatar_url);
14 |
15 | console.info(`${MOCK_USERNAME}'s avatar is ${avatarURL}`);
16 | }
17 |
18 | main();
19 |
--------------------------------------------------------------------------------
/example/ts/src/configs/sever-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "baseUrl": "api.github.com",
3 | "protocol": "https"
4 | }
--------------------------------------------------------------------------------
/example/ts/src/http/http-service.ts:
--------------------------------------------------------------------------------
1 | import {
2 | HTTPModule,
3 | HTTPFactory,
4 | AxiosError,
5 | ErrorInteractModule,
6 | ErrorMessage,
7 | } from "../../../..";
8 | import ServerConfig from "../configs/sever-config.json";
9 | import { RequestLogger } from "./interceptors/request-logger.interceptor";
10 | import { WithOk } from "./operators/ok-operator.pipe";
11 |
12 | @HTTPModule({
13 | server: ServerConfig,
14 | operators: [WithOk],
15 | interceptors: [RequestLogger],
16 | })
17 | export class AppModule implements ErrorInteractModule {
18 | errorInteract(errMsg: ErrorMessage, err: AxiosError): void {}
19 | }
20 |
21 | export async function main() {
22 | const http = HTTPFactory.create(AppModule);
23 |
24 | const { avatar, ok } = await http
25 | .get("/users/mistricky")
26 | .pipe(({ data }) => data.avatar_url)
27 | .pipe((avatar) => ({ avatar }))
28 | .withOk()
29 | .expect(() => "Network Error");
30 |
31 | // const res = await http
32 | // .get("/urs/youncccat")
33 | // .post("/")
34 | // .expect(() => "");
35 |
36 | console.info(avatar, ok);
37 | }
38 |
39 | main();
40 |
--------------------------------------------------------------------------------
/example/ts/src/http/interceptors/request-logger.interceptor.ts:
--------------------------------------------------------------------------------
1 | import { HTTPRequestInterceptor, AxiosRequestConfig } from "../../../../..";
2 |
3 | export class RequestLogger implements HTTPRequestInterceptor {
4 | onRequest(
5 | config: AxiosRequestConfig
6 | ): AxiosRequestConfig | Promise {
7 | console.info("request ===> ", config.url);
8 |
9 | return config;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/example/ts/src/http/operators/ok-operator.pipe.ts:
--------------------------------------------------------------------------------
1 | import {
2 | OperatorRunEnv,
3 | PipeOperator,
4 | PipeOperatorContext,
5 | PipeOperatorExec,
6 | } from "../../../../../dist";
7 |
8 | export type WithOkRes = {
9 | ok: boolean;
10 | } & T;
11 |
12 | @PipeOperator({
13 | name: "withOk",
14 | env: OperatorRunEnv.ERROR_OCCUR,
15 | })
16 | export class WithOk implements PipeOperatorExec {
17 | exec({
18 | value,
19 | err,
20 | }: PipeOperatorContext>): WithOkRes<
21 | Record
22 | > {
23 | return {
24 | ...(value ?? {}),
25 | ok: !err,
26 | };
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/example/ts/src/index.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardoc/fence/4e3a3d16b4fc1a47aa16e61fc6cf1552c59cd7f2/example/ts/src/index.ts
--------------------------------------------------------------------------------
/example/ts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "rootDir": "src",
4 | "lib": ["dom", "esnext"],
5 | "outDir": "dist",
6 | "types": ["node"],
7 | "declaration": true,
8 | "suppressImplicitAnyIndexErrors": true,
9 | "emitDecoratorMetadata":true,
10 | "experimentalDecorators": true,
11 | "resolveJsonModule": true,
12 | "esModuleInterop": true
13 | },
14 | "include": ["src/**/*"],
15 | "exclude": ["node_modules/**/*"]
16 | }
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@wizardoc/fence",
3 | "version": "2.0.4",
4 | "main": "dist/index.js",
5 | "license": "MIT",
6 | "files": [
7 | "dist"
8 | ],
9 | "dependencies": {
10 | "@wizardoc/fence": "2.0.3",
11 | "axios": "^0.19.2",
12 | "reflect-metadata": "^0.1.13"
13 | },
14 | "devDependencies": {
15 | "@babel/core": "^7.12.9",
16 | "@babel/plugin-transform-runtime": "^7.12.1",
17 | "@babel/preset-env": "^7.12.7",
18 | "@babel/register": "^7.12.1",
19 | "@types/axios": "^0.14.0",
20 | "@types/node": "^15.6.1",
21 | "babel-plugin-dynamic-import-node": "^2.3.3"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/clients/browser-client.ts:
--------------------------------------------------------------------------------
1 | import { AxiosError, AxiosStatic } from "axios";
2 | import { OperatorService } from "../services";
3 |
4 | import { ErrorInteractProcessor, ErrorMessage } from "../core/error";
5 | import { RawOperator } from "../core/operation";
6 | import { RequestHook } from "../module";
7 |
8 | type Request = () => R;
9 |
10 | export type Response = any;
11 |
12 | type Requests = {
13 | [index in HttpType]: Request;
14 | };
15 |
16 | interface Doer {
17 | Do(): Response;
18 | }
19 |
20 | export type ResValueArea = any;
21 |
22 | export type ExpectableCB = (err: AxiosError) => ErrorMessage;
23 |
24 | export interface Expectable {
25 | expect: OnExpect;
26 | }
27 |
28 | export type OnExpect = (cb?: ExpectableCB) => ResValueArea;
29 |
30 | export interface Successable {
31 | success: OnSuccess;
32 | }
33 |
34 | export interface Pipable {
35 | pipe: OnSuccess;
36 | }
37 |
38 | export type OnSuccess = (cb: OnSuccessCB) => ResValueArea;
39 | export type OnSuccessCB = (data: R | undefined) => T;
40 |
41 | export interface Result extends Successable {
42 | data?: R;
43 | ok: boolean;
44 | }
45 |
46 | export type ExpectFn = () => string | void;
47 | export type SimpleHTTPMethod = "GET" | "HEAD";
48 | export type ComplexHTTPMethod = "POST" | "PUT" | "DELETE" | "PATCH";
49 | export type HTTPMethod = SimpleHTTPMethod | ComplexHTTPMethod;
50 | export type HttpType = "SimpleHTTPMethod" | "ComplexHTTPMethod";
51 |
52 | interface DispatchPayload {
53 | method: HTTPMethod;
54 | path: string;
55 | data?: T;
56 | headers?: any;
57 | }
58 |
59 | export interface HTTPClientOptions {
60 | addr: string;
61 | axios: AxiosStatic;
62 | catcher: ErrorInteractProcessor;
63 | operators: RawOperator[];
64 | }
65 |
66 | export enum ContentType {
67 | Form = "application/x-www-form-urlencoded",
68 | }
69 |
70 | export interface HTTPClient {
71 | create(type: HttpType, payload: DispatchPayload): Doer;
72 | }
73 |
74 | export class BrowserClient {
75 | constructor(private options: HTTPClientOptions) {}
76 |
77 | create(type: HttpType, payload: DispatchPayload): Doer {
78 | const { path, data, headers, method } = payload;
79 | const lowerCaseMethod = method.toLowerCase();
80 |
81 | const requests: Requests = {
82 | ComplexHTTPMethod: () =>
83 | this.options.axios[lowerCaseMethod](this.join(path), data || {}, {
84 | headers: {
85 | "Content-Type": ContentType.Form,
86 | ...headers,
87 | },
88 | }),
89 | SimpleHTTPMethod: () =>
90 | this.options.axios[lowerCaseMethod](this.join(path), {
91 | params: data,
92 | headers: {
93 | ...headers,
94 | },
95 | }),
96 | };
97 |
98 | return {
99 | Do: () => this.Do(() => requests[type]()),
100 | };
101 | }
102 |
103 | private Do(request: Request): Response {
104 | return request();
105 | }
106 |
107 | private join(path: string): string {
108 | if (path.startsWith("http")) {
109 | return path;
110 | }
111 |
112 | const parsedPath = path.replace(/^\/(.*)/, (_, cap) => cap);
113 |
114 | return `${this.options.addr}${parsedPath}`;
115 | }
116 | }
117 |
118 | const noopFn: any = () => {};
119 | export const noop: ResValueArea = {
120 | success: noopFn,
121 | expect: noopFn,
122 | data: undefined,
123 | ok: false,
124 | pipe: noopFn,
125 | };
126 |
--------------------------------------------------------------------------------
/src/clients/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./browser-client";
2 |
--------------------------------------------------------------------------------
/src/core/error.ts:
--------------------------------------------------------------------------------
1 | import { AxiosError } from "axios";
2 |
3 | export enum ErrorOperates {
4 | GLOBAL_PROCESS,
5 | }
6 |
7 | export type ErrorMessage = string | ErrorOperates | void;
8 |
9 | export type ErrorInteractProcessor = (
10 | errMsg: ErrorMessage,
11 | err: AxiosError
12 | ) => void;
13 |
14 | export interface ErrorInteractModule {
15 | errorInteract(errMsg: ErrorMessage, err: AxiosError): void;
16 | }
17 |
18 | export const isErrorInteractModule = (
19 | module: any
20 | ): module is ErrorInteractModule => !!module.errorInteract;
21 |
22 | export const getErrorInteractFromModule = (
23 | module: any
24 | ): ErrorInteractProcessor => {
25 | if (!isErrorInteractModule(module)) {
26 | return () => {};
27 | }
28 |
29 | return module.errorInteract;
30 | };
31 |
--------------------------------------------------------------------------------
/src/core/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./error";
2 | export * from "./interceptor";
3 | export * from "./operation";
4 |
--------------------------------------------------------------------------------
/src/core/interceptor/attach-interceptor.ts:
--------------------------------------------------------------------------------
1 | import {
2 | AxiosInterceptorManager,
3 | AxiosRequestConfig,
4 | AxiosResponse,
5 | AxiosError,
6 | AxiosStatic,
7 | } from "axios";
8 | import { Constructable } from "../../typings/construct";
9 |
10 | import {
11 | HTTPRequestInterceptor,
12 | HTTPResponseInterceptor,
13 | HTTPRequestErrorCatch,
14 | HTTPResponseErrorCatch,
15 | } from "./interceptor";
16 |
17 | enum InterceptorType {
18 | Req = "request",
19 | Res = "response",
20 | }
21 |
22 | export type RequestInterceptor = (
23 | value: AxiosRequestConfig
24 | ) => AxiosRequestConfig | Promise;
25 |
26 | export type ResponseInterceptor = (
27 | value: AxiosResponse
28 | ) => AxiosResponse | Promise;
29 |
30 | export type ResponseErrorCatcher = (err: AxiosError) => any;
31 |
32 | export type RequestErrorCatcher = (err: AxiosError) => any;
33 |
34 | export type Use = (
35 | interceptors: AllowInterceptorTypes[],
36 | interceptorType: InterceptorType,
37 | isError?: boolean
38 | ) => void;
39 |
40 | type AllowInterceptorTypes =
41 | | RequestInterceptor
42 | | ResponseInterceptor
43 | | ResponseErrorCatcher
44 | | RequestErrorCatcher;
45 |
46 | export type HTTPInterceptors =
47 | | HTTPRequestInterceptor
48 | | HTTPResponseInterceptor
49 | | HTTPRequestErrorCatch
50 | | HTTPResponseErrorCatch;
51 |
52 | type InterceptorArgument = AxiosRequestConfig | AxiosResponse;
53 |
54 | function attach(
55 | interceptor: AllowInterceptorTypes,
56 | isError?: boolean
57 | ): (undefined | AllowInterceptorTypes)[] {
58 | return isError ? [undefined, interceptor] : [interceptor, undefined];
59 | }
60 |
61 | function useInterceptors(AxiosInstance: AxiosStatic): Use {
62 | return (
63 | interceptors: AllowInterceptorTypes[],
64 | interceptorType: InterceptorType,
65 | isError: boolean
66 | ): void => {
67 | for (const interceptor of interceptors) {
68 | (
69 | AxiosInstance.interceptors[
70 | interceptorType
71 | ] as AxiosInterceptorManager
72 | ).use(...(attach(interceptor, isError) as any));
73 | }
74 | };
75 | }
76 |
77 | function typeAssert(target: any, prop: string): target is T {
78 | return target[prop] !== undefined;
79 | }
80 |
81 | export class Interceptor {
82 | private useInterceptor: Use;
83 |
84 | constructor(axios: AxiosStatic) {
85 | this.useInterceptor = useInterceptors(axios);
86 | }
87 |
88 | use(interceptors: Constructable[]): void {
89 | for (const InterceptorConstructor of interceptors) {
90 | const interceptor = new InterceptorConstructor();
91 | const bindThis = (method: Function) => method.bind(interceptor);
92 |
93 | if (typeAssert(interceptor, "onRequest")) {
94 | this.useReq(bindThis(interceptor.onRequest));
95 | } else if (
96 | typeAssert(interceptor, "onResponse")
97 | ) {
98 | this.useRes(bindThis(interceptor.onResponse));
99 | } else if (typeAssert(interceptor, "catchReq")) {
100 | this.useReqError(bindThis(interceptor.catchReq));
101 | } else if (typeAssert(interceptor, "catchRes")) {
102 | this.useResError(bindThis(interceptor.catchRes));
103 | }
104 | }
105 | }
106 |
107 | private useReq(...interceptors: RequestInterceptor[]): void {
108 | this.useInterceptor(interceptors, InterceptorType.Req);
109 | }
110 |
111 | private useRes(...interceptors: ResponseInterceptor[]): void {
112 | this.useInterceptor(interceptors, InterceptorType.Res);
113 | }
114 |
115 | private useResError(...interceptors: ResponseErrorCatcher[]): void {
116 | this.useInterceptor(interceptors, InterceptorType.Res, true);
117 | }
118 |
119 | private useReqError(...interceptors: RequestErrorCatcher[]): void {
120 | this.useInterceptor(interceptors, InterceptorType.Req, true);
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/core/interceptor/index.ts:
--------------------------------------------------------------------------------
1 | export * from './attach-interceptor';
2 | export * from './interceptor';
3 |
--------------------------------------------------------------------------------
/src/core/interceptor/interceptor.ts:
--------------------------------------------------------------------------------
1 | import {AxiosRequestConfig, AxiosResponse, AxiosError} from 'axios';
2 |
3 | export interface HTTPResponseInterceptor {
4 | onResponse(res: AxiosResponse): AxiosResponse | Promise;
5 | }
6 |
7 | export interface HTTPRequestInterceptor {
8 | onRequest(
9 | req: AxiosRequestConfig,
10 | ): AxiosRequestConfig | Promise;
11 | }
12 |
13 | export interface HTTPRequestErrorCatch {
14 | catchReq(err: AxiosError): void;
15 | }
16 |
17 | export interface HTTPResponseErrorCatch {
18 | catchRes(err: AxiosError): void;
19 | }
20 |
--------------------------------------------------------------------------------
/src/core/operation/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./operation";
2 | export * from "./operators";
3 |
--------------------------------------------------------------------------------
/src/core/operation/operation.ts:
--------------------------------------------------------------------------------
1 | import "reflect-metadata";
2 | import { AxiosError } from "axios";
3 | import { ErrorInteractProcessor } from "../error";
4 | import { Constructable } from "../../typings/construct";
5 | import { HTTPService } from "../../factory";
6 |
7 | export type OperatorCallback = (value: unknown, ...args: unknown[]) => unknown;
8 |
9 | // The operator function allows u to defined ur own operator on result of request
10 | // and u can pass some args that exist in http-client context as parameters
11 | export type PipeFunction = (...args: unknown[]) => T;
12 |
13 | export type BeginPipeFunction = Omit, "operatorCallback">;
14 |
15 | export const PIPE_OPERATOR_METADATA_KEY = Symbol("PIPE_OPERATOR_METADATA_KEY");
16 | export const TERMINAL_OPERATOR_METADATA_KEY = Symbol(
17 | "TERMINAL_OPERATOR_METADATA_KEY"
18 | );
19 | export const BEGIN_OPERATOR_METADATA_KEY = Symbol(
20 | "BEGIN_OPERATOR_METADATA_KEY"
21 | );
22 |
23 | export interface PipeOperatorContext {
24 | value: T;
25 | err?: AxiosError;
26 | }
27 |
28 | export interface TerminalOperatorContext extends PipeOperatorContext {
29 | catcher: ErrorInteractProcessor;
30 | }
31 |
32 | export interface BeginOperatorContext extends PipeOperatorContext {
33 | httpService: HTTPService;
34 | }
35 |
36 | export interface Operator {
37 | exec(context: C, ...args: unknown[]): R;
38 | }
39 |
40 | export enum OperatorType {
41 | TERMINAL_OPERATOR,
42 | PIPE_OPERATOR,
43 | BEGIN_OPERATOR,
44 | }
45 |
46 | export enum OperatorRunEnv {
47 | ERROR_OCCUR,
48 | NO_ERROR,
49 | }
50 |
51 | export interface OperatorMetadata {
52 | configure: C;
53 | type: OperatorType;
54 | }
55 |
56 | export type RawOperator =
57 | | Constructable
58 | | Constructable
59 | | Constructable;
60 |
61 | export type PipeOperatorExec = Operator;
62 |
63 | export type TerminalOperatorExec = Operator;
64 |
65 | export type BeginOperatorExec = Operator;
66 |
67 | export interface OperatorConfigure {
68 | name: string;
69 | }
70 |
71 | export interface TerminalOperatorConfigure extends OperatorConfigure {}
72 | export interface PipeOperatorConfigure extends OperatorConfigure {
73 | env?: OperatorRunEnv;
74 | }
75 |
76 | export interface BeginOperatorConfigure extends PipeOperatorConfigure {}
77 |
78 | export const isOperator = (target: any): target is Operator =>
79 | !!target.exec;
80 |
81 | export const getOperatorMetadata = (
82 | target: any,
83 | key: Symbol
84 | ):
85 | | OperatorMetadata
86 | | undefined => Reflect.getMetadata(key, target);
87 |
88 | export const getTerminalOperatorMetadata = (
89 | target: any
90 | ): OperatorMetadata =>
91 | getOperatorMetadata(target, TERMINAL_OPERATOR_METADATA_KEY);
92 |
93 | export const getPipeOperatorMetadata = (
94 | target: any
95 | ): OperatorMetadata =>
96 | getOperatorMetadata(target, PIPE_OPERATOR_METADATA_KEY);
97 |
98 | export const getBeginOperatorMetadata = (
99 | target: any
100 | ): OperatorMetadata =>
101 | getOperatorMetadata(target, BEGIN_OPERATOR_METADATA_KEY);
102 |
103 | const parseConfigure = (
104 | configure: PipeOperatorConfigure
105 | ): PipeOperatorConfigure => ({
106 | env: OperatorRunEnv.NO_ERROR,
107 | ...configure,
108 | });
109 |
110 | export const PipeOperator =
111 | (configure: PipeOperatorConfigure) => (target: any) => {
112 | Reflect.defineMetadata(
113 | PIPE_OPERATOR_METADATA_KEY,
114 | {
115 | configure: parseConfigure(configure),
116 | type: OperatorType.PIPE_OPERATOR,
117 | },
118 | target
119 | );
120 | };
121 |
122 | export const TerminalOperator =
123 | (configure: TerminalOperatorConfigure) => (target: any) => {
124 | Reflect.defineMetadata(
125 | TERMINAL_OPERATOR_METADATA_KEY,
126 | {
127 | configure,
128 | type: OperatorType.TERMINAL_OPERATOR,
129 | },
130 | target
131 | );
132 | };
133 |
134 | export const BeginOperator =
135 | (configure: BeginOperatorConfigure) => (target: any) => {
136 | Reflect.defineMetadata(
137 | BEGIN_OPERATOR_METADATA_KEY,
138 | {
139 | configure,
140 | type: OperatorType.BEGIN_OPERATOR,
141 | },
142 | target
143 | );
144 | };
145 |
--------------------------------------------------------------------------------
/src/core/operation/operators/delete-operator.begin.ts:
--------------------------------------------------------------------------------
1 | import { RequestOptions } from "../../../factory";
2 | import { BeginOperator, BeginOperatorContext } from "../operation";
3 | import { RequestOperator } from "./request-operator";
4 |
5 | @BeginOperator({
6 | name: "delete",
7 | })
8 | export class Delete extends RequestOperator {
9 | sendRequest(
10 | { httpService }: BeginOperatorContext,
11 | url: string,
12 | data: unknown,
13 | options: Partial
14 | ) {
15 | return httpService.delete(url, data, options);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/core/operation/operators/expect-operator.terminal.ts:
--------------------------------------------------------------------------------
1 | import {
2 | OperatorCallback,
3 | TerminalOperator,
4 | TerminalOperatorContext,
5 | TerminalOperatorExec,
6 | } from "../operation";
7 |
8 | @TerminalOperator({ name: "expect" })
9 | export class Expect implements TerminalOperatorExec {
10 | exec(
11 | { catcher, value, err }: TerminalOperatorContext,
12 | cb: OperatorCallback
13 | ): void {
14 | const errMsg = cb(value) as string;
15 |
16 | if (!!err) {
17 | catcher(errMsg, err);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/core/operation/operators/get-operator.begin.ts:
--------------------------------------------------------------------------------
1 | import { RequestOptions } from "../../../factory";
2 | import { BeginOperator, BeginOperatorContext } from "../operation";
3 | import { RequestOperator } from "./request-operator";
4 |
5 | @BeginOperator({
6 | name: "get",
7 | })
8 | export class Get extends RequestOperator {
9 | sendRequest(
10 | { httpService }: BeginOperatorContext,
11 | url: string,
12 | data: unknown,
13 | options: Partial
14 | ) {
15 | return httpService.get(url, data, options);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/core/operation/operators/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./pipe-operator.pipe";
2 | export * from "./expect-operator.terminal";
3 | export * from "./unwrap-operator.terminal";
4 | export * from "./match-operator.terminal";
5 | export * from "./get-operator.begin";
6 | export * from "./post-operator.begin";
7 | export * from "./delete-operator.begin";
8 | export * from "./put-operator.begin";
9 |
--------------------------------------------------------------------------------
/src/core/operation/operators/match-operator.terminal.ts:
--------------------------------------------------------------------------------
1 | import { AxiosError } from "axios";
2 | import {
3 | OperatorCallback,
4 | TerminalOperator,
5 | TerminalOperatorContext,
6 | TerminalOperatorExec,
7 | } from "../operation";
8 |
9 | @TerminalOperator({ name: "match" })
10 | export class Match implements TerminalOperatorExec {
11 | exec(
12 | { value, err }: TerminalOperatorContext,
13 | successfulCallback: (data: unknown) => unknown,
14 | errorCallback: (err: AxiosError) => unknown
15 | ): unknown {
16 | if (err) {
17 | return errorCallback(err);
18 | }
19 |
20 | return successfulCallback(value);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/core/operation/operators/pipe-operator.pipe.ts:
--------------------------------------------------------------------------------
1 | import { OperatorCallback, PipeOperator, PipeOperatorExec } from "../operation";
2 |
3 | @PipeOperator({
4 | name: "pipe",
5 | })
6 | export class Pipe implements PipeOperatorExec {
7 | exec({ value }, cb: OperatorCallback): unknown {
8 | return cb(value);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/core/operation/operators/post-operator.begin.ts:
--------------------------------------------------------------------------------
1 | import { RequestOptions } from "../../../factory";
2 | import { BeginOperator, BeginOperatorContext } from "../operation";
3 | import { RequestOperator } from "./request-operator";
4 |
5 | @BeginOperator({
6 | name: "post",
7 | })
8 | export class Post extends RequestOperator {
9 | sendRequest(
10 | { httpService }: BeginOperatorContext,
11 | url: string,
12 | data: unknown,
13 | options: Partial
14 | ) {
15 | return httpService.post(url, data, options);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/core/operation/operators/put-operator.begin.ts:
--------------------------------------------------------------------------------
1 | import { RequestOptions } from "../../../factory";
2 | import { BeginOperator, BeginOperatorContext } from "../operation";
3 | import { RequestOperator } from "./request-operator";
4 |
5 | @BeginOperator({
6 | name: "put",
7 | })
8 | export class Put extends RequestOperator {
9 | sendRequest(
10 | { httpService }: BeginOperatorContext,
11 | url: string,
12 | data: unknown,
13 | options: Partial
14 | ) {
15 | return httpService.put(url, data, options);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/core/operation/operators/request-operator.ts:
--------------------------------------------------------------------------------
1 | import { PartialRequestOptions } from "../../../factory";
2 | import { OperatorResponse } from "../../../services";
3 | import { BeginOperatorContext, BeginOperatorExec } from "../operation";
4 |
5 | const maybeFn = (target: unknown, value: unknown): T =>
6 | typeof target === "function" ? target(value) : target;
7 |
8 | export abstract class RequestOperator implements BeginOperatorExec {
9 | exec(
10 | context: BeginOperatorContext,
11 | url: string | ((value: unknown) => string),
12 | data?: unknown | ((value: unknown) => unknown),
13 | options?: PartialRequestOptions
14 | ): unknown {
15 | const { value } = context;
16 | return this.sendRequest(
17 | context,
18 | maybeFn(url, value),
19 | maybeFn(data, value),
20 | options
21 | );
22 | }
23 |
24 | abstract sendRequest(
25 | context: BeginOperatorContext,
26 | url: string,
27 | data: unknown,
28 | options: PartialRequestOptions
29 | ): OperatorResponse;
30 | }
31 |
--------------------------------------------------------------------------------
/src/core/operation/operators/unwrap-operator.terminal.ts:
--------------------------------------------------------------------------------
1 | import {
2 | TerminalOperator,
3 | TerminalOperatorContext,
4 | TerminalOperatorExec,
5 | } from "../operation";
6 |
7 | @TerminalOperator({ name: "unwrap" })
8 | export class Unwrap implements TerminalOperatorExec {
9 | exec({ err }: TerminalOperatorContext): void {
10 | if (err) {
11 | // rethrow the error that occur when send request
12 | throw err;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/factory/http-factory.ts:
--------------------------------------------------------------------------------
1 | import "reflect-metadata";
2 | import { getErrorInteractFromModule, Interceptor } from "../core";
3 | import { HTTPModuleMetadata, HTTP_MODULE_METADATA_KEY } from "../module";
4 | import { HTTPService } from "./http-service";
5 | import Axios from "axios";
6 | import { OperatorResponse, OperatorService, ServerConfig } from "../services";
7 | import { BrowserClient } from "../clients";
8 |
9 | const NOT_A_MODULE_ERROR_MESSAGE =
10 | "HTTP Factory cannot create a service base on this module, please make sure the params has been decorated by @HTTPModule.";
11 |
12 | export class HTTPFactory {
13 | static create(Module: any): OperatorResponse {
14 | const moduleMetadata: HTTPModuleMetadata = Reflect.getMetadata(
15 | HTTP_MODULE_METADATA_KEY,
16 | Module
17 | );
18 |
19 | // Check the params whether is module or not
20 | if (!moduleMetadata) {
21 | throw new Error(NOT_A_MODULE_ERROR_MESSAGE);
22 | }
23 |
24 | // Can Inject some context info into module here
25 | const module = new Module();
26 |
27 | const interceptor = new Interceptor(Axios);
28 | const errorInteract = getErrorInteractFromModule(module);
29 | const serverConfig = new ServerConfig(moduleMetadata.server);
30 |
31 | // Set interceptors on raw axios
32 | interceptor.use(moduleMetadata.interceptors ?? []);
33 |
34 | const client = new BrowserClient({
35 | addr: serverConfig.getAbsPath(),
36 | axios: Axios,
37 | catcher: errorInteract,
38 | operators: moduleMetadata.operators ?? [],
39 | });
40 |
41 | const operatorService = new OperatorService(moduleMetadata.operators);
42 | const httpService = new HTTPService(client);
43 |
44 | // Return a new operatorSet when call http every time
45 | return new Proxy(
46 | {},
47 | {
48 | get: (_: any, key: string) =>
49 | operatorService.parseOperators(errorInteract, httpService)[key],
50 | }
51 | ) as unknown as OperatorResponse;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/factory/http-service.ts:
--------------------------------------------------------------------------------
1 | import { HTTPMethod, Response, HttpType, HTTPClient } from "../clients";
2 | import { RequestHook } from "../module";
3 | import { OperatorResponse } from "../services";
4 |
5 | export interface PostPayload {
6 | [index: string]: T;
7 | }
8 |
9 | export interface RequestOptions {
10 | headers?: any;
11 | useHooks: boolean;
12 | }
13 |
14 | export type PartialRequestOptions = Partial;
15 |
16 | export class HTTPService {
17 | constructor(private client: HTTPClient) {}
18 |
19 | get(path: string, data?: T, options?: PartialRequestOptions) {
20 | return this.simpleRequest("GET", path, data, options);
21 | }
22 |
23 | post(path: string, data?: T, options?: PartialRequestOptions) {
24 | return this.complexRequest("POST", path, data, options);
25 | }
26 |
27 | put(path: string, data?: T, options?: PartialRequestOptions) {
28 | return this.complexRequest("PUT", path, data, options);
29 | }
30 |
31 | delete(path: string, data?: T, options?: PartialRequestOptions) {
32 | return this.complexRequest("DELETE", path, data, options);
33 | }
34 |
35 | // Common request function that is wrapper of all request function, in other words
36 | // it can do anything before send real request or intercept response
37 | private request(
38 | type: HttpType,
39 | method: HTTPMethod,
40 | path: string,
41 | data?: T,
42 | options?: PartialRequestOptions
43 | ): OperatorResponse {
44 | return this.client
45 | .create(type, {
46 | method,
47 | path,
48 | data,
49 | headers: options?.headers ?? {},
50 | })
51 | .Do();
52 | }
53 |
54 | private complexRequest(
55 | method: HTTPMethod,
56 | path: string,
57 | data?: T,
58 | options?: PartialRequestOptions
59 | ) {
60 | return this.request("ComplexHTTPMethod", method, path, data, options);
61 | }
62 |
63 | private simpleRequest(
64 | method: HTTPMethod,
65 | path: string,
66 | data?: T,
67 | options?: PartialRequestOptions
68 | ) {
69 | return this.request("SimpleHTTPMethod", method, path, data, options);
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/factory/index.ts:
--------------------------------------------------------------------------------
1 | export * from './http-factory';
2 | export * from './http-service';
3 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "axios";
2 | export * from "./core";
3 | export * from "./factory";
4 | export * from "./module";
5 | export * from "./services";
6 | export * from "./clients";
7 |
--------------------------------------------------------------------------------
/src/module/hooks.ts:
--------------------------------------------------------------------------------
1 | import { HTTPMethod, ResValueArea } from "../clients";
2 |
3 | export interface RequestHook {
4 | beforeRequest(
5 | method: HTTPMethod,
6 | path: string,
7 | data?: any,
8 | headers?: any
9 | ): void | Promise;
10 | afterResponse(result: ResValueArea): void | Promise;
11 | }
12 |
13 | const HOOK_NOOP: RequestHook = {
14 | beforeRequest: () => {},
15 | afterResponse: () => {},
16 | };
17 |
18 | export const isHooksModule = (module: any): module is RequestHook =>
19 | module.beforeRequest || module.afterResponse;
20 |
21 | export const getHooksFromModule = (module: any): RequestHook => {
22 | if (!isHooksModule(module)) {
23 | return HOOK_NOOP;
24 | }
25 |
26 | const { beforeRequest, afterResponse } = module;
27 |
28 | return {
29 | ...HOOK_NOOP,
30 | beforeRequest,
31 | afterResponse,
32 | };
33 | };
34 |
--------------------------------------------------------------------------------
/src/module/index.ts:
--------------------------------------------------------------------------------
1 | export * from './metadata';
2 | export * from './hooks';
3 |
--------------------------------------------------------------------------------
/src/module/metadata.ts:
--------------------------------------------------------------------------------
1 | import { HTTPInterceptors } from "../core";
2 | import "reflect-metadata";
3 | import { ServerConfigInfo } from "../services";
4 | import { RawOperator } from "../core/operation";
5 | import { Constructable } from "../typings/construct";
6 |
7 | export const HTTP_MODULE_METADATA_KEY = Symbol("HTTP_MODULE_METADATA_KEY");
8 |
9 | export interface HTTPModuleMetadata {
10 | interceptors?: Constructable[];
11 | operators?: RawOperator[];
12 | server: ServerConfigInfo;
13 | }
14 |
15 | export const HTTPModule = (config: HTTPModuleMetadata) => (target: any) =>
16 | Reflect.defineMetadata(HTTP_MODULE_METADATA_KEY, config, target);
17 |
--------------------------------------------------------------------------------
/src/services/configure.ts:
--------------------------------------------------------------------------------
1 | export interface ServerConfigInfo {
2 | baseUrl: string;
3 | protocol: string;
4 | port?: number;
5 | prefix?: string;
6 | }
7 |
8 | export class ServerConfig {
9 | constructor(private config: ServerConfigInfo) {}
10 |
11 | getBaseURL(): string {
12 | const { baseUrl, port, prefix = "" } = this.config!;
13 | const parsedPort = port ? `:${port}` : "";
14 |
15 | return `${baseUrl}${parsedPort}${prefix}/`;
16 | }
17 |
18 | getAbsPath(): string {
19 | return `${this.config!.protocol}://${this.getBaseURL()}`;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/services/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./configure";
2 | export * from "./operator";
3 |
--------------------------------------------------------------------------------
/src/services/operator/exec-stack.ts:
--------------------------------------------------------------------------------
1 | import { OperatorRunEnv, OperatorType } from "../../core";
2 | import { OperatorExecData } from "./operator-exec-data";
3 |
4 | export type WaitForExecOperator void> = {
5 | exec: E;
6 | env?: OperatorRunEnv;
7 | type: OperatorType;
8 | };
9 |
10 | export type PreWaitForExecOperator = WaitForExecOperator<
11 | (request: () => Promise) => () => void
12 | >;
13 |
14 | interface WaitForExecContainer {
15 | request?: () => Promise;
16 | operators: WaitForExecOperator[];
17 | }
18 |
19 | const BEGIN_OPERATOR_NOT_FOUND_ERROR_MESSAGE =
20 | "Please make sure the begin operator has been invoked before.";
21 | const DUPLICATE_TERMINAL_OPERATOR_ERROR_MESSAGE =
22 | "Only one terminal operator is allowed for a request flow.";
23 | const UNKNOWN_OPERATOR_ERROR_MESSAGE = "Unknown operator.";
24 |
25 | export class ExecStack {
26 | private tasks: WaitForExecContainer[] = [];
27 |
28 | private container: WaitForExecContainer = { operators: [] };
29 |
30 | private terminalOperator?: PreWaitForExecOperator;
31 |
32 | constructor(private operatorExecData: OperatorExecData) {}
33 |
34 | addOperatorToContainer(
35 | operator: PreWaitForExecOperator | WaitForExecOperator
36 | ) {
37 | const { env, exec, type } = operator;
38 |
39 | // Check the begin operator whether is exist or not
40 | if (type !== OperatorType.BEGIN_OPERATOR && !this.container.request) {
41 | throw new Error(BEGIN_OPERATOR_NOT_FOUND_ERROR_MESSAGE);
42 | }
43 |
44 | // Make the operators as a task when get an terminal operator
45 | if (type === OperatorType.TERMINAL_OPERATOR) {
46 | // Duplicate terminal operator
47 | if (!!this.terminalOperator) {
48 | throw new Error(DUPLICATE_TERMINAL_OPERATOR_ERROR_MESSAGE);
49 | }
50 |
51 | this.terminalOperator = operator as PreWaitForExecOperator;
52 | this.makeContainerAsTask();
53 | return;
54 | }
55 |
56 | if (type === OperatorType.BEGIN_OPERATOR) {
57 | // If the begin operator is not a first operator of this container, the means that
58 | // the request flow contain multiple begin operator
59 | if (!!this.container.request) {
60 | this.makeContainerAsTask();
61 | }
62 |
63 | // New request flow
64 | this.container.request = operator.exec as () => Promise;
65 | return;
66 | }
67 |
68 | if (type === OperatorType.PIPE_OPERATOR) {
69 | this.container.operators.push(operator as WaitForExecOperator);
70 |
71 | return;
72 | }
73 |
74 | throw new Error(UNKNOWN_OPERATOR_ERROR_MESSAGE);
75 | }
76 |
77 | // Clear operators and move it to tasks
78 | private makeContainerAsTask() {
79 | // The request flow has not been initialized
80 | if (!this.container.request) {
81 | return;
82 | }
83 |
84 | this.tasks.push({ ...this.container });
85 | this.container = { operators: [] };
86 | }
87 |
88 | private async execOperators(operators: WaitForExecOperator[]) {
89 | for (const { env, exec } of operators) {
90 | if (
91 | !this.operatorExecData.err ||
92 | (!!this.operatorExecData.err && env === OperatorRunEnv.ERROR_OCCUR)
93 | ) {
94 | await exec();
95 | }
96 | }
97 | }
98 |
99 | // Execute all tasks
100 | async exec() {
101 | for (const { operators, request } of this.tasks) {
102 | // If an error occurred on the previous task, the request flow is terminated
103 | if (this.operatorExecData.err) {
104 | break;
105 | }
106 |
107 | await this.terminalOperator.exec(request)();
108 | await this.execOperators(operators);
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/services/operator/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./operator-service";
2 |
--------------------------------------------------------------------------------
/src/services/operator/operator-exec-data.ts:
--------------------------------------------------------------------------------
1 | import { AxiosError } from "axios";
2 |
3 | export class OperatorExecData {
4 | public data?: unknown;
5 | public err?: AxiosError;
6 | }
7 |
--------------------------------------------------------------------------------
/src/services/operator/operator-service.ts:
--------------------------------------------------------------------------------
1 | import { AxiosError } from "axios";
2 | import {
3 | ErrorInteractProcessor,
4 | getBeginOperatorMetadata,
5 | getPipeOperatorMetadata,
6 | getTerminalOperatorMetadata,
7 | Operator,
8 | PipeFunction,
9 | PipeOperatorConfigure,
10 | PipeOperatorExec,
11 | RawOperator,
12 | TerminalOperatorExec,
13 | } from "../../core";
14 | import {
15 | Pipe,
16 | Expect,
17 | Unwrap,
18 | Match,
19 | Get,
20 | Post,
21 | Put,
22 | Delete,
23 | } from "../../core/operation/operators";
24 | import { HTTPService } from "../../factory";
25 | import { OperatorSet, ParsedOperator } from "./operator-set";
26 |
27 | export interface OperatorResponse {
28 | pipe: (cb: (value: unknown) => unknown) => OperatorResponse;
29 | expect: (cb: (value: unknown) => string) => Promise;
30 | unwrap: () => Promise;
31 | match: (
32 | successfulCallback: (data: unknown) => unknown,
33 | errorCallback: (err: AxiosError) => unknown
34 | ) => Promise;
35 | [operatorName: string]: PipeFunction;
36 | }
37 |
38 | const BUILD_IN_OPERATORS: RawOperator[] = [
39 | Pipe,
40 | Expect,
41 | Unwrap,
42 | Match,
43 | Get,
44 | Post,
45 | Put,
46 | Delete,
47 | ];
48 |
49 | const NOT_A_OPERATOR_ERROR_MESSAGE =
50 | "Receive a invalid operator, please make sure u has been decorated by @PipeOperator or @TerminalOperator.";
51 |
52 | export type WaitForExecOperator = {
53 | name: string;
54 | exec: () => ReturnType["exec"]>;
55 | };
56 |
57 | export class OperatorService {
58 | private operators: ParsedOperator[] =
59 | [];
60 |
61 | constructor(operators: RawOperator[]) {
62 | this.operators = operators
63 | .concat(BUILD_IN_OPERATORS)
64 | .map>(
65 | (operator) => {
66 | const { configure, type } =
67 | getTerminalOperatorMetadata(operator) ??
68 | getPipeOperatorMetadata(operator) ??
69 | getBeginOperatorMetadata(operator);
70 |
71 | if (!configure) {
72 | throw new Error(NOT_A_OPERATOR_ERROR_MESSAGE);
73 | }
74 |
75 | return {
76 | name: configure.name,
77 | type,
78 | env: (configure as PipeOperatorConfigure).env,
79 | operator: new operator(),
80 | };
81 | }
82 | );
83 | }
84 |
85 | get terminalOperators(): ParsedOperator[] {
86 | return this.operators.filter(
87 | (operator) => !!getTerminalOperatorMetadata(operator)
88 | );
89 | }
90 |
91 | get pipeOperators(): ParsedOperator[] {
92 | return this.operators.filter(
93 | (operator) => !!getPipeOperatorMetadata(operator)
94 | );
95 | }
96 |
97 | // Parse these operators to the operators that can be executed directly
98 | parseOperators(
99 | catcher: ErrorInteractProcessor,
100 | httpService: HTTPService
101 | ): OperatorSet {
102 | return new OperatorSet(this.operators, catcher, httpService);
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/services/operator/operator-set.ts:
--------------------------------------------------------------------------------
1 | import Axios, { AxiosError } from "axios";
2 | import {
3 | BeginOperatorExec,
4 | BeginPipeFunction,
5 | ErrorInteractProcessor,
6 | OperatorCallback,
7 | OperatorRunEnv,
8 | OperatorType,
9 | PipeFunction,
10 | PipeOperatorExec,
11 | TerminalOperatorExec,
12 | } from "../../core";
13 | import { HTTPService } from "../../factory";
14 | import { ExecStack } from "./exec-stack";
15 | import { OperatorExecData } from "./operator-exec-data";
16 |
17 | const CANNOT_MATCH_OPERATOR_TYPE = "Cannot match the type of the operator";
18 |
19 | export type ParsedOperator = {
20 | name: string;
21 | type: OperatorType;
22 | env: OperatorRunEnv | undefined;
23 | operator: T;
24 | };
25 |
26 | export class OperatorSet {
27 | private operatorExecData = new OperatorExecData();
28 | private execStack = new ExecStack(this.operatorExecData);
29 |
30 | constructor(
31 | operators: ParsedOperator<
32 | TerminalOperatorExec | PipeOperatorExec | BeginOperatorExec
33 | >[],
34 | catcher: ErrorInteractProcessor,
35 | httpService: HTTPService
36 | ) {
37 | for (const { operator, type, name, env } of operators) {
38 | // Match the type of operator and return corresponding function
39 | switch (type) {
40 | case OperatorType.TERMINAL_OPERATOR:
41 | this[name] = this.processTerminalOperator(
42 | operator as TerminalOperatorExec,
43 | catcher
44 | );
45 | break;
46 | case OperatorType.PIPE_OPERATOR:
47 | this[name] = this.processPipeOperator(
48 | operator as PipeOperatorExec,
49 | env
50 | );
51 | break;
52 | case OperatorType.BEGIN_OPERATOR:
53 | this[name] = this.processBeginOperator(
54 | operator as BeginOperatorExec,
55 | env,
56 | httpService
57 | );
58 | break;
59 | default:
60 | throw new Error(CANNOT_MATCH_OPERATOR_TYPE);
61 | }
62 | }
63 | }
64 |
65 | private processTerminalOperator(
66 | operator: TerminalOperatorExec,
67 | catcher: ErrorInteractProcessor
68 | ): PipeFunction {
69 | return async (cb, ...args) => {
70 | this.execStack.addOperatorToContainer({
71 | type: OperatorType.TERMINAL_OPERATOR,
72 | exec: (request: () => Promise) => async () => {
73 | // Only a terminal operator can exist in a request
74 | try {
75 | this.operatorExecData.data = await request();
76 | } catch (e) {
77 | this.operatorExecData.err = e;
78 | }
79 |
80 | // The exec can throw an error to this context
81 | const data = await operator.exec(
82 | {
83 | value: this.operatorExecData.data,
84 | err: this.operatorExecData.err,
85 | catcher,
86 | },
87 | cb,
88 | ...args
89 | );
90 |
91 | // The terminal operator can return a value as a initial value of the data
92 | if (data !== undefined) {
93 | this.operatorExecData.data = data;
94 | }
95 |
96 | return this.operatorExecData.data as T;
97 | },
98 | });
99 |
100 | await this.execStack.exec();
101 |
102 | return this.operatorExecData.data;
103 | };
104 | }
105 |
106 | private processBeginOperator(
107 | operator: BeginOperatorExec,
108 | env: OperatorRunEnv,
109 | httpService: HTTPService
110 | ): BeginPipeFunction {
111 | return (...args: any[]) => {
112 | this.execStack.addOperatorToContainer({
113 | env,
114 | type: OperatorType.BEGIN_OPERATOR,
115 | exec: () =>
116 | operator.exec(
117 | {
118 | value: this.operatorExecData.data,
119 | err: this.operatorExecData.err,
120 | httpService,
121 | },
122 | ...args
123 | ),
124 | });
125 |
126 | return this;
127 | };
128 | }
129 |
130 | private processPipeOperator(
131 | operator: PipeOperatorExec,
132 | env: OperatorRunEnv
133 | ): PipeFunction {
134 | return (cb, ...args) => {
135 | // These operators will invoke later
136 | this.execStack.addOperatorToContainer({
137 | env,
138 | type: OperatorType.PIPE_OPERATOR,
139 | exec: () => {
140 | const data = operator.exec(
141 | {
142 | value: this.operatorExecData.data,
143 | err: this.operatorExecData.err,
144 | },
145 | cb,
146 | ...args
147 | );
148 |
149 | if (data !== undefined) {
150 | this.operatorExecData.data = data;
151 | }
152 | },
153 | });
154 |
155 | // The pipe operator can called like cascade
156 | return this;
157 | };
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/src/typings/construct.d.ts:
--------------------------------------------------------------------------------
1 | export interface Constructable {
2 | new (...args: any[]): T;
3 | }
4 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "experimentalDecorators": true,
4 | "emitDecoratorMetadata": true,
5 | "target": "ES5",
6 | "rootDir": "src",
7 | "lib": ["dom", "esnext"],
8 | "outDir": "dist",
9 | "types": ["node"],
10 | "declaration": true,
11 | "suppressImplicitAnyIndexErrors": true
12 | },
13 | "include": ["src/**/*"],
14 | "exclude": ["node_modules/**/*"]
15 | }
16 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@babel/code-frame@^7.12.13":
6 | version "7.12.13"
7 | resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
8 | integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
9 | dependencies:
10 | "@babel/highlight" "^7.12.13"
11 |
12 | "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.4":
13 | version "7.14.4"
14 | resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.4.tgz#45720fe0cecf3fd42019e1d12cc3d27fadc98d58"
15 | integrity sha512-i2wXrWQNkH6JplJQGn3Rd2I4Pij8GdHkXwHMxm+zV5YG/Jci+bCNrWZEWC4o+umiDkRrRs4dVzH3X4GP7vyjQQ==
16 |
17 | "@babel/core@^7.12.9":
18 | version "7.14.3"
19 | resolved "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz#5395e30405f0776067fbd9cf0884f15bfb770a38"
20 | integrity sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==
21 | dependencies:
22 | "@babel/code-frame" "^7.12.13"
23 | "@babel/generator" "^7.14.3"
24 | "@babel/helper-compilation-targets" "^7.13.16"
25 | "@babel/helper-module-transforms" "^7.14.2"
26 | "@babel/helpers" "^7.14.0"
27 | "@babel/parser" "^7.14.3"
28 | "@babel/template" "^7.12.13"
29 | "@babel/traverse" "^7.14.2"
30 | "@babel/types" "^7.14.2"
31 | convert-source-map "^1.7.0"
32 | debug "^4.1.0"
33 | gensync "^1.0.0-beta.2"
34 | json5 "^2.1.2"
35 | semver "^6.3.0"
36 | source-map "^0.5.0"
37 |
38 | "@babel/generator@^7.14.2", "@babel/generator@^7.14.3":
39 | version "7.14.3"
40 | resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz#0c2652d91f7bddab7cccc6ba8157e4f40dcedb91"
41 | integrity sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==
42 | dependencies:
43 | "@babel/types" "^7.14.2"
44 | jsesc "^2.5.1"
45 | source-map "^0.5.0"
46 |
47 | "@babel/helper-annotate-as-pure@^7.12.13":
48 | version "7.12.13"
49 | resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab"
50 | integrity sha512-7YXfX5wQ5aYM/BOlbSccHDbuXXFPxeoUmfWtz8le2yTkTZc+BxsiEnENFoi2SlmA8ewDkG2LgIMIVzzn2h8kfw==
51 | dependencies:
52 | "@babel/types" "^7.12.13"
53 |
54 | "@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13":
55 | version "7.12.13"
56 | resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc"
57 | integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==
58 | dependencies:
59 | "@babel/helper-explode-assignable-expression" "^7.12.13"
60 | "@babel/types" "^7.12.13"
61 |
62 | "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.16", "@babel/helper-compilation-targets@^7.14.4":
63 | version "7.14.4"
64 | resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.4.tgz#33ebd0ffc34248051ee2089350a929ab02f2a516"
65 | integrity sha512-JgdzOYZ/qGaKTVkn5qEDV/SXAh8KcyUVkCoSWGN8T3bwrgd6m+/dJa2kVGi6RJYJgEYPBdZ84BZp9dUjNWkBaA==
66 | dependencies:
67 | "@babel/compat-data" "^7.14.4"
68 | "@babel/helper-validator-option" "^7.12.17"
69 | browserslist "^4.16.6"
70 | semver "^6.3.0"
71 |
72 | "@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.0", "@babel/helper-create-class-features-plugin@^7.14.3":
73 | version "7.14.4"
74 | resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.4.tgz#abf888d836a441abee783c75229279748705dc42"
75 | integrity sha512-idr3pthFlDCpV+p/rMgGLGYIVtazeatrSOQk8YzO2pAepIjQhCN3myeihVg58ax2bbbGK9PUE1reFi7axOYIOw==
76 | dependencies:
77 | "@babel/helper-annotate-as-pure" "^7.12.13"
78 | "@babel/helper-function-name" "^7.14.2"
79 | "@babel/helper-member-expression-to-functions" "^7.13.12"
80 | "@babel/helper-optimise-call-expression" "^7.12.13"
81 | "@babel/helper-replace-supers" "^7.14.4"
82 | "@babel/helper-split-export-declaration" "^7.12.13"
83 |
84 | "@babel/helper-create-regexp-features-plugin@^7.12.13":
85 | version "7.14.3"
86 | resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.3.tgz#149aa6d78c016e318c43e2409a0ae9c136a86688"
87 | integrity sha512-JIB2+XJrb7v3zceV2XzDhGIB902CmKGSpSl4q2C6agU9SNLG/2V1RtFRGPG1Ajh9STj3+q6zJMOC+N/pp2P9DA==
88 | dependencies:
89 | "@babel/helper-annotate-as-pure" "^7.12.13"
90 | regexpu-core "^4.7.1"
91 |
92 | "@babel/helper-define-polyfill-provider@^0.2.2":
93 | version "0.2.3"
94 | resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6"
95 | integrity sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew==
96 | dependencies:
97 | "@babel/helper-compilation-targets" "^7.13.0"
98 | "@babel/helper-module-imports" "^7.12.13"
99 | "@babel/helper-plugin-utils" "^7.13.0"
100 | "@babel/traverse" "^7.13.0"
101 | debug "^4.1.1"
102 | lodash.debounce "^4.0.8"
103 | resolve "^1.14.2"
104 | semver "^6.1.2"
105 |
106 | "@babel/helper-explode-assignable-expression@^7.12.13":
107 | version "7.13.0"
108 | resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f"
109 | integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==
110 | dependencies:
111 | "@babel/types" "^7.13.0"
112 |
113 | "@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.14.2":
114 | version "7.14.2"
115 | resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz#397688b590760b6ef7725b5f0860c82427ebaac2"
116 | integrity sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==
117 | dependencies:
118 | "@babel/helper-get-function-arity" "^7.12.13"
119 | "@babel/template" "^7.12.13"
120 | "@babel/types" "^7.14.2"
121 |
122 | "@babel/helper-get-function-arity@^7.12.13":
123 | version "7.12.13"
124 | resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583"
125 | integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==
126 | dependencies:
127 | "@babel/types" "^7.12.13"
128 |
129 | "@babel/helper-hoist-variables@^7.13.0":
130 | version "7.13.16"
131 | resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.16.tgz#1b1651249e94b51f8f0d33439843e33e39775b30"
132 | integrity sha512-1eMtTrXtrwscjcAeO4BVK+vvkxaLJSPFz1w1KLawz6HLNi9bPFGBNwwDyVfiu1Tv/vRRFYfoGaKhmAQPGPn5Wg==
133 | dependencies:
134 | "@babel/traverse" "^7.13.15"
135 | "@babel/types" "^7.13.16"
136 |
137 | "@babel/helper-member-expression-to-functions@^7.13.12":
138 | version "7.13.12"
139 | resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz#dfe368f26d426a07299d8d6513821768216e6d72"
140 | integrity sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==
141 | dependencies:
142 | "@babel/types" "^7.13.12"
143 |
144 | "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12":
145 | version "7.13.12"
146 | resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977"
147 | integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==
148 | dependencies:
149 | "@babel/types" "^7.13.12"
150 |
151 | "@babel/helper-module-transforms@^7.13.0", "@babel/helper-module-transforms@^7.14.0", "@babel/helper-module-transforms@^7.14.2":
152 | version "7.14.2"
153 | resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz#ac1cc30ee47b945e3e0c4db12fa0c5389509dfe5"
154 | integrity sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==
155 | dependencies:
156 | "@babel/helper-module-imports" "^7.13.12"
157 | "@babel/helper-replace-supers" "^7.13.12"
158 | "@babel/helper-simple-access" "^7.13.12"
159 | "@babel/helper-split-export-declaration" "^7.12.13"
160 | "@babel/helper-validator-identifier" "^7.14.0"
161 | "@babel/template" "^7.12.13"
162 | "@babel/traverse" "^7.14.2"
163 | "@babel/types" "^7.14.2"
164 |
165 | "@babel/helper-optimise-call-expression@^7.12.13":
166 | version "7.12.13"
167 | resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz#5c02d171b4c8615b1e7163f888c1c81c30a2aaea"
168 | integrity sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==
169 | dependencies:
170 | "@babel/types" "^7.12.13"
171 |
172 | "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3":
173 | version "7.13.0"
174 | resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af"
175 | integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==
176 |
177 | "@babel/helper-remap-async-to-generator@^7.13.0":
178 | version "7.13.0"
179 | resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209"
180 | integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==
181 | dependencies:
182 | "@babel/helper-annotate-as-pure" "^7.12.13"
183 | "@babel/helper-wrap-function" "^7.13.0"
184 | "@babel/types" "^7.13.0"
185 |
186 | "@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.12", "@babel/helper-replace-supers@^7.14.4":
187 | version "7.14.4"
188 | resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.4.tgz#b2ab16875deecfff3ddfcd539bc315f72998d836"
189 | integrity sha512-zZ7uHCWlxfEAAOVDYQpEf/uyi1dmeC7fX4nCf2iz9drnCwi1zvwXL3HwWWNXUQEJ1k23yVn3VbddiI9iJEXaTQ==
190 | dependencies:
191 | "@babel/helper-member-expression-to-functions" "^7.13.12"
192 | "@babel/helper-optimise-call-expression" "^7.12.13"
193 | "@babel/traverse" "^7.14.2"
194 | "@babel/types" "^7.14.4"
195 |
196 | "@babel/helper-simple-access@^7.13.12":
197 | version "7.13.12"
198 | resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6"
199 | integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==
200 | dependencies:
201 | "@babel/types" "^7.13.12"
202 |
203 | "@babel/helper-skip-transparent-expression-wrappers@^7.12.1":
204 | version "7.12.1"
205 | resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf"
206 | integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==
207 | dependencies:
208 | "@babel/types" "^7.12.1"
209 |
210 | "@babel/helper-split-export-declaration@^7.12.13":
211 | version "7.12.13"
212 | resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05"
213 | integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==
214 | dependencies:
215 | "@babel/types" "^7.12.13"
216 |
217 | "@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0":
218 | version "7.14.0"
219 | resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288"
220 | integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==
221 |
222 | "@babel/helper-validator-option@^7.12.17":
223 | version "7.12.17"
224 | resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831"
225 | integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==
226 |
227 | "@babel/helper-wrap-function@^7.13.0":
228 | version "7.13.0"
229 | resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4"
230 | integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==
231 | dependencies:
232 | "@babel/helper-function-name" "^7.12.13"
233 | "@babel/template" "^7.12.13"
234 | "@babel/traverse" "^7.13.0"
235 | "@babel/types" "^7.13.0"
236 |
237 | "@babel/helpers@^7.14.0":
238 | version "7.14.0"
239 | resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz#ea9b6be9478a13d6f961dbb5f36bf75e2f3b8f62"
240 | integrity sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==
241 | dependencies:
242 | "@babel/template" "^7.12.13"
243 | "@babel/traverse" "^7.14.0"
244 | "@babel/types" "^7.14.0"
245 |
246 | "@babel/highlight@^7.12.13":
247 | version "7.14.0"
248 | resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz#3197e375711ef6bf834e67d0daec88e4f46113cf"
249 | integrity sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==
250 | dependencies:
251 | "@babel/helper-validator-identifier" "^7.14.0"
252 | chalk "^2.0.0"
253 | js-tokens "^4.0.0"
254 |
255 | "@babel/parser@^7.12.13", "@babel/parser@^7.14.2", "@babel/parser@^7.14.3":
256 | version "7.14.4"
257 | resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.14.4.tgz#a5c560d6db6cd8e6ed342368dea8039232cbab18"
258 | integrity sha512-ArliyUsWDUqEGfWcmzpGUzNfLxTdTp6WU4IuP6QFSp9gGfWS6boxFCkJSJ/L4+RG8z/FnIU3WxCk6hPL9SSWeA==
259 |
260 | "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12":
261 | version "7.13.12"
262 | resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a"
263 | integrity sha512-d0u3zWKcoZf379fOeJdr1a5WPDny4aOFZ6hlfKivgK0LY7ZxNfoaHL2fWwdGtHyVvra38FC+HVYkO+byfSA8AQ==
264 | dependencies:
265 | "@babel/helper-plugin-utils" "^7.13.0"
266 | "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
267 | "@babel/plugin-proposal-optional-chaining" "^7.13.12"
268 |
269 | "@babel/plugin-proposal-async-generator-functions@^7.14.2":
270 | version "7.14.2"
271 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.2.tgz#3a2085abbf5d5f962d480dbc81347385ed62eb1e"
272 | integrity sha512-b1AM4F6fwck4N8ItZ/AtC4FP/cqZqmKRQ4FaTDutwSYyjuhtvsGEMLK4N/ztV/ImP40BjIDyMgBQAeAMsQYVFQ==
273 | dependencies:
274 | "@babel/helper-plugin-utils" "^7.13.0"
275 | "@babel/helper-remap-async-to-generator" "^7.13.0"
276 | "@babel/plugin-syntax-async-generators" "^7.8.4"
277 |
278 | "@babel/plugin-proposal-class-properties@^7.13.0":
279 | version "7.13.0"
280 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37"
281 | integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==
282 | dependencies:
283 | "@babel/helper-create-class-features-plugin" "^7.13.0"
284 | "@babel/helper-plugin-utils" "^7.13.0"
285 |
286 | "@babel/plugin-proposal-class-static-block@^7.14.3":
287 | version "7.14.3"
288 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.14.3.tgz#5a527e2cae4a4753119c3a3e7f64ecae8ccf1360"
289 | integrity sha512-HEjzp5q+lWSjAgJtSluFDrGGosmwTgKwCXdDQZvhKsRlwv3YdkUEqxNrrjesJd+B9E9zvr1PVPVBvhYZ9msjvQ==
290 | dependencies:
291 | "@babel/helper-create-class-features-plugin" "^7.14.3"
292 | "@babel/helper-plugin-utils" "^7.13.0"
293 | "@babel/plugin-syntax-class-static-block" "^7.12.13"
294 |
295 | "@babel/plugin-proposal-dynamic-import@^7.14.2":
296 | version "7.14.2"
297 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.2.tgz#01ebabd7c381cff231fa43e302939a9de5be9d9f"
298 | integrity sha512-oxVQZIWFh91vuNEMKltqNsKLFWkOIyJc95k2Gv9lWVyDfPUQGSSlbDEgWuJUU1afGE9WwlzpucMZ3yDRHIItkA==
299 | dependencies:
300 | "@babel/helper-plugin-utils" "^7.13.0"
301 | "@babel/plugin-syntax-dynamic-import" "^7.8.3"
302 |
303 | "@babel/plugin-proposal-export-namespace-from@^7.14.2":
304 | version "7.14.2"
305 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz#62542f94aa9ce8f6dba79eec698af22112253791"
306 | integrity sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ==
307 | dependencies:
308 | "@babel/helper-plugin-utils" "^7.13.0"
309 | "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
310 |
311 | "@babel/plugin-proposal-json-strings@^7.14.2":
312 | version "7.14.2"
313 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.2.tgz#830b4e2426a782e8b2878fbfe2cba85b70cbf98c"
314 | integrity sha512-w2DtsfXBBJddJacXMBhElGEYqCZQqN99Se1qeYn8DVLB33owlrlLftIbMzn5nz1OITfDVknXF433tBrLEAOEjA==
315 | dependencies:
316 | "@babel/helper-plugin-utils" "^7.13.0"
317 | "@babel/plugin-syntax-json-strings" "^7.8.3"
318 |
319 | "@babel/plugin-proposal-logical-assignment-operators@^7.14.2":
320 | version "7.14.2"
321 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.2.tgz#222348c080a1678e0e74ea63fe76f275882d1fd7"
322 | integrity sha512-1JAZtUrqYyGsS7IDmFeaem+/LJqujfLZ2weLR9ugB0ufUPjzf8cguyVT1g5im7f7RXxuLq1xUxEzvm68uYRtGg==
323 | dependencies:
324 | "@babel/helper-plugin-utils" "^7.13.0"
325 | "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
326 |
327 | "@babel/plugin-proposal-nullish-coalescing-operator@^7.14.2":
328 | version "7.14.2"
329 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.2.tgz#425b11dc62fc26939a2ab42cbba680bdf5734546"
330 | integrity sha512-ebR0zU9OvI2N4qiAC38KIAK75KItpIPTpAtd2r4OZmMFeKbKJpUFLYP2EuDut82+BmYi8sz42B+TfTptJ9iG5Q==
331 | dependencies:
332 | "@babel/helper-plugin-utils" "^7.13.0"
333 | "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
334 |
335 | "@babel/plugin-proposal-numeric-separator@^7.14.2":
336 | version "7.14.2"
337 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz#82b4cc06571143faf50626104b335dd71baa4f9e"
338 | integrity sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg==
339 | dependencies:
340 | "@babel/helper-plugin-utils" "^7.13.0"
341 | "@babel/plugin-syntax-numeric-separator" "^7.10.4"
342 |
343 | "@babel/plugin-proposal-object-rest-spread@^7.14.4":
344 | version "7.14.4"
345 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.4.tgz#0e2b4de419915dc0b409378e829412e2031777c4"
346 | integrity sha512-AYosOWBlyyXEagrPRfLJ1enStufsr7D1+ddpj8OLi9k7B6+NdZ0t/9V7Fh+wJ4g2Jol8z2JkgczYqtWrZd4vbA==
347 | dependencies:
348 | "@babel/compat-data" "^7.14.4"
349 | "@babel/helper-compilation-targets" "^7.14.4"
350 | "@babel/helper-plugin-utils" "^7.13.0"
351 | "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
352 | "@babel/plugin-transform-parameters" "^7.14.2"
353 |
354 | "@babel/plugin-proposal-optional-catch-binding@^7.14.2":
355 | version "7.14.2"
356 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.2.tgz#150d4e58e525b16a9a1431bd5326c4eed870d717"
357 | integrity sha512-XtkJsmJtBaUbOxZsNk0Fvrv8eiqgneug0A6aqLFZ4TSkar2L5dSXWcnUKHgmjJt49pyB/6ZHvkr3dPgl9MOWRQ==
358 | dependencies:
359 | "@babel/helper-plugin-utils" "^7.13.0"
360 | "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
361 |
362 | "@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.14.2":
363 | version "7.14.2"
364 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.2.tgz#df8171a8b9c43ebf4c1dabe6311b432d83e1b34e"
365 | integrity sha512-qQByMRPwMZJainfig10BoaDldx/+VDtNcrA7qdNaEOAj6VXud+gfrkA8j4CRAU5HjnWREXqIpSpH30qZX1xivA==
366 | dependencies:
367 | "@babel/helper-plugin-utils" "^7.13.0"
368 | "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
369 | "@babel/plugin-syntax-optional-chaining" "^7.8.3"
370 |
371 | "@babel/plugin-proposal-private-methods@^7.13.0":
372 | version "7.13.0"
373 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787"
374 | integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==
375 | dependencies:
376 | "@babel/helper-create-class-features-plugin" "^7.13.0"
377 | "@babel/helper-plugin-utils" "^7.13.0"
378 |
379 | "@babel/plugin-proposal-private-property-in-object@^7.14.0":
380 | version "7.14.0"
381 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.14.0.tgz#b1a1f2030586b9d3489cc26179d2eb5883277636"
382 | integrity sha512-59ANdmEwwRUkLjB7CRtwJxxwtjESw+X2IePItA+RGQh+oy5RmpCh/EvVVvh5XQc3yxsm5gtv0+i9oBZhaDNVTg==
383 | dependencies:
384 | "@babel/helper-annotate-as-pure" "^7.12.13"
385 | "@babel/helper-create-class-features-plugin" "^7.14.0"
386 | "@babel/helper-plugin-utils" "^7.13.0"
387 | "@babel/plugin-syntax-private-property-in-object" "^7.14.0"
388 |
389 | "@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
390 | version "7.12.13"
391 | resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba"
392 | integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==
393 | dependencies:
394 | "@babel/helper-create-regexp-features-plugin" "^7.12.13"
395 | "@babel/helper-plugin-utils" "^7.12.13"
396 |
397 | "@babel/plugin-syntax-async-generators@^7.8.4":
398 | version "7.8.4"
399 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
400 | integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==
401 | dependencies:
402 | "@babel/helper-plugin-utils" "^7.8.0"
403 |
404 | "@babel/plugin-syntax-class-properties@^7.12.13":
405 | version "7.12.13"
406 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10"
407 | integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==
408 | dependencies:
409 | "@babel/helper-plugin-utils" "^7.12.13"
410 |
411 | "@babel/plugin-syntax-class-static-block@^7.12.13":
412 | version "7.12.13"
413 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.12.13.tgz#8e3d674b0613e67975ceac2776c97b60cafc5c9c"
414 | integrity sha512-ZmKQ0ZXR0nYpHZIIuj9zE7oIqCx2hw9TKi+lIo73NNrMPAZGHfS92/VRV0ZmPj6H2ffBgyFHXvJ5NYsNeEaP2A==
415 | dependencies:
416 | "@babel/helper-plugin-utils" "^7.12.13"
417 |
418 | "@babel/plugin-syntax-dynamic-import@^7.8.3":
419 | version "7.8.3"
420 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3"
421 | integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==
422 | dependencies:
423 | "@babel/helper-plugin-utils" "^7.8.0"
424 |
425 | "@babel/plugin-syntax-export-namespace-from@^7.8.3":
426 | version "7.8.3"
427 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a"
428 | integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==
429 | dependencies:
430 | "@babel/helper-plugin-utils" "^7.8.3"
431 |
432 | "@babel/plugin-syntax-json-strings@^7.8.3":
433 | version "7.8.3"
434 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a"
435 | integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==
436 | dependencies:
437 | "@babel/helper-plugin-utils" "^7.8.0"
438 |
439 | "@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
440 | version "7.10.4"
441 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699"
442 | integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==
443 | dependencies:
444 | "@babel/helper-plugin-utils" "^7.10.4"
445 |
446 | "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3":
447 | version "7.8.3"
448 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9"
449 | integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==
450 | dependencies:
451 | "@babel/helper-plugin-utils" "^7.8.0"
452 |
453 | "@babel/plugin-syntax-numeric-separator@^7.10.4":
454 | version "7.10.4"
455 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97"
456 | integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==
457 | dependencies:
458 | "@babel/helper-plugin-utils" "^7.10.4"
459 |
460 | "@babel/plugin-syntax-object-rest-spread@^7.8.3":
461 | version "7.8.3"
462 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871"
463 | integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==
464 | dependencies:
465 | "@babel/helper-plugin-utils" "^7.8.0"
466 |
467 | "@babel/plugin-syntax-optional-catch-binding@^7.8.3":
468 | version "7.8.3"
469 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1"
470 | integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==
471 | dependencies:
472 | "@babel/helper-plugin-utils" "^7.8.0"
473 |
474 | "@babel/plugin-syntax-optional-chaining@^7.8.3":
475 | version "7.8.3"
476 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a"
477 | integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==
478 | dependencies:
479 | "@babel/helper-plugin-utils" "^7.8.0"
480 |
481 | "@babel/plugin-syntax-private-property-in-object@^7.14.0":
482 | version "7.14.0"
483 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.0.tgz#762a4babec61176fec6c88480dec40372b140c0b"
484 | integrity sha512-bda3xF8wGl5/5btF794utNOL0Jw+9jE5C1sLZcoK7c4uonE/y3iQiyG+KbkF3WBV/paX58VCpjhxLPkdj5Fe4w==
485 | dependencies:
486 | "@babel/helper-plugin-utils" "^7.13.0"
487 |
488 | "@babel/plugin-syntax-top-level-await@^7.12.13":
489 | version "7.12.13"
490 | resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178"
491 | integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==
492 | dependencies:
493 | "@babel/helper-plugin-utils" "^7.12.13"
494 |
495 | "@babel/plugin-transform-arrow-functions@^7.13.0":
496 | version "7.13.0"
497 | resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae"
498 | integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==
499 | dependencies:
500 | "@babel/helper-plugin-utils" "^7.13.0"
501 |
502 | "@babel/plugin-transform-async-to-generator@^7.13.0":
503 | version "7.13.0"
504 | resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f"
505 | integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==
506 | dependencies:
507 | "@babel/helper-module-imports" "^7.12.13"
508 | "@babel/helper-plugin-utils" "^7.13.0"
509 | "@babel/helper-remap-async-to-generator" "^7.13.0"
510 |
511 | "@babel/plugin-transform-block-scoped-functions@^7.12.13":
512 | version "7.12.13"
513 | resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4"
514 | integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==
515 | dependencies:
516 | "@babel/helper-plugin-utils" "^7.12.13"
517 |
518 | "@babel/plugin-transform-block-scoping@^7.14.4":
519 | version "7.14.4"
520 | resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.4.tgz#caf140b0b2e2462c509553d140e6d0abefb61ed8"
521 | integrity sha512-5KdpkGxsZlTk+fPleDtGKsA+pon28+ptYmMO8GBSa5fHERCJWAzj50uAfCKBqq42HO+Zot6JF1x37CRprwmN4g==
522 | dependencies:
523 | "@babel/helper-plugin-utils" "^7.13.0"
524 |
525 | "@babel/plugin-transform-classes@^7.14.4":
526 | version "7.14.4"
527 | resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.4.tgz#a83c15503fc71a0f99e876fdce7dadbc6575ec3a"
528 | integrity sha512-p73t31SIj6y94RDVX57rafVjttNr8MvKEgs5YFatNB/xC68zM3pyosuOEcQmYsYlyQaGY9R7rAULVRcat5FKJQ==
529 | dependencies:
530 | "@babel/helper-annotate-as-pure" "^7.12.13"
531 | "@babel/helper-function-name" "^7.14.2"
532 | "@babel/helper-optimise-call-expression" "^7.12.13"
533 | "@babel/helper-plugin-utils" "^7.13.0"
534 | "@babel/helper-replace-supers" "^7.14.4"
535 | "@babel/helper-split-export-declaration" "^7.12.13"
536 | globals "^11.1.0"
537 |
538 | "@babel/plugin-transform-computed-properties@^7.13.0":
539 | version "7.13.0"
540 | resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed"
541 | integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==
542 | dependencies:
543 | "@babel/helper-plugin-utils" "^7.13.0"
544 |
545 | "@babel/plugin-transform-destructuring@^7.14.4":
546 | version "7.14.4"
547 | resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.4.tgz#acbec502e9951f30f4441eaca1d2f29efade59ed"
548 | integrity sha512-JyywKreTCGTUsL1OKu1A3ms/R1sTP0WxbpXlALeGzF53eB3bxtNkYdMj9SDgK7g6ImPy76J5oYYKoTtQImlhQA==
549 | dependencies:
550 | "@babel/helper-plugin-utils" "^7.13.0"
551 |
552 | "@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4":
553 | version "7.12.13"
554 | resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad"
555 | integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==
556 | dependencies:
557 | "@babel/helper-create-regexp-features-plugin" "^7.12.13"
558 | "@babel/helper-plugin-utils" "^7.12.13"
559 |
560 | "@babel/plugin-transform-duplicate-keys@^7.12.13":
561 | version "7.12.13"
562 | resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de"
563 | integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==
564 | dependencies:
565 | "@babel/helper-plugin-utils" "^7.12.13"
566 |
567 | "@babel/plugin-transform-exponentiation-operator@^7.12.13":
568 | version "7.12.13"
569 | resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1"
570 | integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==
571 | dependencies:
572 | "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13"
573 | "@babel/helper-plugin-utils" "^7.12.13"
574 |
575 | "@babel/plugin-transform-for-of@^7.13.0":
576 | version "7.13.0"
577 | resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062"
578 | integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==
579 | dependencies:
580 | "@babel/helper-plugin-utils" "^7.13.0"
581 |
582 | "@babel/plugin-transform-function-name@^7.12.13":
583 | version "7.12.13"
584 | resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051"
585 | integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==
586 | dependencies:
587 | "@babel/helper-function-name" "^7.12.13"
588 | "@babel/helper-plugin-utils" "^7.12.13"
589 |
590 | "@babel/plugin-transform-literals@^7.12.13":
591 | version "7.12.13"
592 | resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9"
593 | integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==
594 | dependencies:
595 | "@babel/helper-plugin-utils" "^7.12.13"
596 |
597 | "@babel/plugin-transform-member-expression-literals@^7.12.13":
598 | version "7.12.13"
599 | resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40"
600 | integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==
601 | dependencies:
602 | "@babel/helper-plugin-utils" "^7.12.13"
603 |
604 | "@babel/plugin-transform-modules-amd@^7.14.2":
605 | version "7.14.2"
606 | resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.2.tgz#6622806fe1a7c07a1388444222ef9535f2ca17b0"
607 | integrity sha512-hPC6XBswt8P3G2D1tSV2HzdKvkqOpmbyoy+g73JG0qlF/qx2y3KaMmXb1fLrpmWGLZYA0ojCvaHdzFWjlmV+Pw==
608 | dependencies:
609 | "@babel/helper-module-transforms" "^7.14.2"
610 | "@babel/helper-plugin-utils" "^7.13.0"
611 | babel-plugin-dynamic-import-node "^2.3.3"
612 |
613 | "@babel/plugin-transform-modules-commonjs@^7.14.0":
614 | version "7.14.0"
615 | resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.0.tgz#52bc199cb581e0992edba0f0f80356467587f161"
616 | integrity sha512-EX4QePlsTaRZQmw9BsoPeyh5OCtRGIhwfLquhxGp5e32w+dyL8htOcDwamlitmNFK6xBZYlygjdye9dbd9rUlQ==
617 | dependencies:
618 | "@babel/helper-module-transforms" "^7.14.0"
619 | "@babel/helper-plugin-utils" "^7.13.0"
620 | "@babel/helper-simple-access" "^7.13.12"
621 | babel-plugin-dynamic-import-node "^2.3.3"
622 |
623 | "@babel/plugin-transform-modules-systemjs@^7.13.8":
624 | version "7.13.8"
625 | resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3"
626 | integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==
627 | dependencies:
628 | "@babel/helper-hoist-variables" "^7.13.0"
629 | "@babel/helper-module-transforms" "^7.13.0"
630 | "@babel/helper-plugin-utils" "^7.13.0"
631 | "@babel/helper-validator-identifier" "^7.12.11"
632 | babel-plugin-dynamic-import-node "^2.3.3"
633 |
634 | "@babel/plugin-transform-modules-umd@^7.14.0":
635 | version "7.14.0"
636 | resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.0.tgz#2f8179d1bbc9263665ce4a65f305526b2ea8ac34"
637 | integrity sha512-nPZdnWtXXeY7I87UZr9VlsWme3Y0cfFFE41Wbxz4bbaexAjNMInXPFUpRRUJ8NoMm0Cw+zxbqjdPmLhcjfazMw==
638 | dependencies:
639 | "@babel/helper-module-transforms" "^7.14.0"
640 | "@babel/helper-plugin-utils" "^7.13.0"
641 |
642 | "@babel/plugin-transform-named-capturing-groups-regex@^7.12.13":
643 | version "7.12.13"
644 | resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9"
645 | integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==
646 | dependencies:
647 | "@babel/helper-create-regexp-features-plugin" "^7.12.13"
648 |
649 | "@babel/plugin-transform-new-target@^7.12.13":
650 | version "7.12.13"
651 | resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c"
652 | integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==
653 | dependencies:
654 | "@babel/helper-plugin-utils" "^7.12.13"
655 |
656 | "@babel/plugin-transform-object-super@^7.12.13":
657 | version "7.12.13"
658 | resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7"
659 | integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==
660 | dependencies:
661 | "@babel/helper-plugin-utils" "^7.12.13"
662 | "@babel/helper-replace-supers" "^7.12.13"
663 |
664 | "@babel/plugin-transform-parameters@^7.14.2":
665 | version "7.14.2"
666 | resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.2.tgz#e4290f72e0e9e831000d066427c4667098decc31"
667 | integrity sha512-NxoVmA3APNCC1JdMXkdYXuQS+EMdqy0vIwyDHeKHiJKRxmp1qGSdb0JLEIoPRhkx6H/8Qi3RJ3uqOCYw8giy9A==
668 | dependencies:
669 | "@babel/helper-plugin-utils" "^7.13.0"
670 |
671 | "@babel/plugin-transform-property-literals@^7.12.13":
672 | version "7.12.13"
673 | resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81"
674 | integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==
675 | dependencies:
676 | "@babel/helper-plugin-utils" "^7.12.13"
677 |
678 | "@babel/plugin-transform-regenerator@^7.13.15":
679 | version "7.13.15"
680 | resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39"
681 | integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==
682 | dependencies:
683 | regenerator-transform "^0.14.2"
684 |
685 | "@babel/plugin-transform-reserved-words@^7.12.13":
686 | version "7.12.13"
687 | resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695"
688 | integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==
689 | dependencies:
690 | "@babel/helper-plugin-utils" "^7.12.13"
691 |
692 | "@babel/plugin-transform-runtime@^7.12.1":
693 | version "7.14.3"
694 | resolved "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.3.tgz#1fd885a2d0de1d3c223795a4e9be72c2db4515cf"
695 | integrity sha512-t960xbi8wpTFE623ef7sd+UpEC5T6EEguQlTBJDEO05+XwnIWVfuqLw/vdLWY6IdFmtZE+65CZAfByT39zRpkg==
696 | dependencies:
697 | "@babel/helper-module-imports" "^7.13.12"
698 | "@babel/helper-plugin-utils" "^7.13.0"
699 | babel-plugin-polyfill-corejs2 "^0.2.0"
700 | babel-plugin-polyfill-corejs3 "^0.2.0"
701 | babel-plugin-polyfill-regenerator "^0.2.0"
702 | semver "^6.3.0"
703 |
704 | "@babel/plugin-transform-shorthand-properties@^7.12.13":
705 | version "7.12.13"
706 | resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad"
707 | integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==
708 | dependencies:
709 | "@babel/helper-plugin-utils" "^7.12.13"
710 |
711 | "@babel/plugin-transform-spread@^7.13.0":
712 | version "7.13.0"
713 | resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd"
714 | integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==
715 | dependencies:
716 | "@babel/helper-plugin-utils" "^7.13.0"
717 | "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
718 |
719 | "@babel/plugin-transform-sticky-regex@^7.12.13":
720 | version "7.12.13"
721 | resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f"
722 | integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==
723 | dependencies:
724 | "@babel/helper-plugin-utils" "^7.12.13"
725 |
726 | "@babel/plugin-transform-template-literals@^7.13.0":
727 | version "7.13.0"
728 | resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d"
729 | integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==
730 | dependencies:
731 | "@babel/helper-plugin-utils" "^7.13.0"
732 |
733 | "@babel/plugin-transform-typeof-symbol@^7.12.13":
734 | version "7.12.13"
735 | resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f"
736 | integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==
737 | dependencies:
738 | "@babel/helper-plugin-utils" "^7.12.13"
739 |
740 | "@babel/plugin-transform-unicode-escapes@^7.12.13":
741 | version "7.12.13"
742 | resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74"
743 | integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==
744 | dependencies:
745 | "@babel/helper-plugin-utils" "^7.12.13"
746 |
747 | "@babel/plugin-transform-unicode-regex@^7.12.13":
748 | version "7.12.13"
749 | resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac"
750 | integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==
751 | dependencies:
752 | "@babel/helper-create-regexp-features-plugin" "^7.12.13"
753 | "@babel/helper-plugin-utils" "^7.12.13"
754 |
755 | "@babel/preset-env@^7.12.7":
756 | version "7.14.4"
757 | resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.14.4.tgz#73fc3228c59727e5e974319156f304f0d6685a2d"
758 | integrity sha512-GwMMsuAnDtULyOtuxHhzzuSRxFeP0aR/LNzrHRzP8y6AgDNgqnrfCCBm/1cRdTU75tRs28Eh76poHLcg9VF0LA==
759 | dependencies:
760 | "@babel/compat-data" "^7.14.4"
761 | "@babel/helper-compilation-targets" "^7.14.4"
762 | "@babel/helper-plugin-utils" "^7.13.0"
763 | "@babel/helper-validator-option" "^7.12.17"
764 | "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.13.12"
765 | "@babel/plugin-proposal-async-generator-functions" "^7.14.2"
766 | "@babel/plugin-proposal-class-properties" "^7.13.0"
767 | "@babel/plugin-proposal-class-static-block" "^7.14.3"
768 | "@babel/plugin-proposal-dynamic-import" "^7.14.2"
769 | "@babel/plugin-proposal-export-namespace-from" "^7.14.2"
770 | "@babel/plugin-proposal-json-strings" "^7.14.2"
771 | "@babel/plugin-proposal-logical-assignment-operators" "^7.14.2"
772 | "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.2"
773 | "@babel/plugin-proposal-numeric-separator" "^7.14.2"
774 | "@babel/plugin-proposal-object-rest-spread" "^7.14.4"
775 | "@babel/plugin-proposal-optional-catch-binding" "^7.14.2"
776 | "@babel/plugin-proposal-optional-chaining" "^7.14.2"
777 | "@babel/plugin-proposal-private-methods" "^7.13.0"
778 | "@babel/plugin-proposal-private-property-in-object" "^7.14.0"
779 | "@babel/plugin-proposal-unicode-property-regex" "^7.12.13"
780 | "@babel/plugin-syntax-async-generators" "^7.8.4"
781 | "@babel/plugin-syntax-class-properties" "^7.12.13"
782 | "@babel/plugin-syntax-class-static-block" "^7.12.13"
783 | "@babel/plugin-syntax-dynamic-import" "^7.8.3"
784 | "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
785 | "@babel/plugin-syntax-json-strings" "^7.8.3"
786 | "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
787 | "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
788 | "@babel/plugin-syntax-numeric-separator" "^7.10.4"
789 | "@babel/plugin-syntax-object-rest-spread" "^7.8.3"
790 | "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
791 | "@babel/plugin-syntax-optional-chaining" "^7.8.3"
792 | "@babel/plugin-syntax-private-property-in-object" "^7.14.0"
793 | "@babel/plugin-syntax-top-level-await" "^7.12.13"
794 | "@babel/plugin-transform-arrow-functions" "^7.13.0"
795 | "@babel/plugin-transform-async-to-generator" "^7.13.0"
796 | "@babel/plugin-transform-block-scoped-functions" "^7.12.13"
797 | "@babel/plugin-transform-block-scoping" "^7.14.4"
798 | "@babel/plugin-transform-classes" "^7.14.4"
799 | "@babel/plugin-transform-computed-properties" "^7.13.0"
800 | "@babel/plugin-transform-destructuring" "^7.14.4"
801 | "@babel/plugin-transform-dotall-regex" "^7.12.13"
802 | "@babel/plugin-transform-duplicate-keys" "^7.12.13"
803 | "@babel/plugin-transform-exponentiation-operator" "^7.12.13"
804 | "@babel/plugin-transform-for-of" "^7.13.0"
805 | "@babel/plugin-transform-function-name" "^7.12.13"
806 | "@babel/plugin-transform-literals" "^7.12.13"
807 | "@babel/plugin-transform-member-expression-literals" "^7.12.13"
808 | "@babel/plugin-transform-modules-amd" "^7.14.2"
809 | "@babel/plugin-transform-modules-commonjs" "^7.14.0"
810 | "@babel/plugin-transform-modules-systemjs" "^7.13.8"
811 | "@babel/plugin-transform-modules-umd" "^7.14.0"
812 | "@babel/plugin-transform-named-capturing-groups-regex" "^7.12.13"
813 | "@babel/plugin-transform-new-target" "^7.12.13"
814 | "@babel/plugin-transform-object-super" "^7.12.13"
815 | "@babel/plugin-transform-parameters" "^7.14.2"
816 | "@babel/plugin-transform-property-literals" "^7.12.13"
817 | "@babel/plugin-transform-regenerator" "^7.13.15"
818 | "@babel/plugin-transform-reserved-words" "^7.12.13"
819 | "@babel/plugin-transform-shorthand-properties" "^7.12.13"
820 | "@babel/plugin-transform-spread" "^7.13.0"
821 | "@babel/plugin-transform-sticky-regex" "^7.12.13"
822 | "@babel/plugin-transform-template-literals" "^7.13.0"
823 | "@babel/plugin-transform-typeof-symbol" "^7.12.13"
824 | "@babel/plugin-transform-unicode-escapes" "^7.12.13"
825 | "@babel/plugin-transform-unicode-regex" "^7.12.13"
826 | "@babel/preset-modules" "^0.1.4"
827 | "@babel/types" "^7.14.4"
828 | babel-plugin-polyfill-corejs2 "^0.2.0"
829 | babel-plugin-polyfill-corejs3 "^0.2.0"
830 | babel-plugin-polyfill-regenerator "^0.2.0"
831 | core-js-compat "^3.9.0"
832 | semver "^6.3.0"
833 |
834 | "@babel/preset-modules@^0.1.4":
835 | version "0.1.4"
836 | resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e"
837 | integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==
838 | dependencies:
839 | "@babel/helper-plugin-utils" "^7.0.0"
840 | "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
841 | "@babel/plugin-transform-dotall-regex" "^7.4.4"
842 | "@babel/types" "^7.4.4"
843 | esutils "^2.0.2"
844 |
845 | "@babel/register@^7.12.1":
846 | version "7.13.16"
847 | resolved "https://registry.npmjs.org/@babel/register/-/register-7.13.16.tgz#ae3ab0b55c8ec28763877383c454f01521d9a53d"
848 | integrity sha512-dh2t11ysujTwByQjXNgJ48QZ2zcXKQVdV8s0TbeMI0flmtGWCdTwK9tJiACHXPLmncm5+ktNn/diojA45JE4jg==
849 | dependencies:
850 | clone-deep "^4.0.1"
851 | find-cache-dir "^2.0.0"
852 | make-dir "^2.1.0"
853 | pirates "^4.0.0"
854 | source-map-support "^0.5.16"
855 |
856 | "@babel/runtime@^7.8.4":
857 | version "7.14.0"
858 | resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6"
859 | integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==
860 | dependencies:
861 | regenerator-runtime "^0.13.4"
862 |
863 | "@babel/template@^7.12.13":
864 | version "7.12.13"
865 | resolved "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
866 | integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==
867 | dependencies:
868 | "@babel/code-frame" "^7.12.13"
869 | "@babel/parser" "^7.12.13"
870 | "@babel/types" "^7.12.13"
871 |
872 | "@babel/traverse@^7.13.0", "@babel/traverse@^7.13.15", "@babel/traverse@^7.14.0", "@babel/traverse@^7.14.2":
873 | version "7.14.2"
874 | resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz#9201a8d912723a831c2679c7ebbf2fe1416d765b"
875 | integrity sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==
876 | dependencies:
877 | "@babel/code-frame" "^7.12.13"
878 | "@babel/generator" "^7.14.2"
879 | "@babel/helper-function-name" "^7.14.2"
880 | "@babel/helper-split-export-declaration" "^7.12.13"
881 | "@babel/parser" "^7.14.2"
882 | "@babel/types" "^7.14.2"
883 | debug "^4.1.0"
884 | globals "^11.1.0"
885 |
886 | "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.2", "@babel/types@^7.14.4", "@babel/types@^7.4.4":
887 | version "7.14.4"
888 | resolved "https://registry.npmjs.org/@babel/types/-/types-7.14.4.tgz#bfd6980108168593b38b3eb48a24aa026b919bc0"
889 | integrity sha512-lCj4aIs0xUefJFQnwwQv2Bxg7Omd6bgquZ6LGC+gGMh6/s5qDVfjuCMlDmYQ15SLsWHd9n+X3E75lKIhl5Lkiw==
890 | dependencies:
891 | "@babel/helper-validator-identifier" "^7.14.0"
892 | to-fast-properties "^2.0.0"
893 |
894 | "@types/axios@^0.14.0":
895 | version "0.14.0"
896 | resolved "https://registry.npmjs.org/@types/axios/-/axios-0.14.0.tgz#ec2300fbe7d7dddd7eb9d3abf87999964cafce46"
897 | integrity sha1-7CMA++fX3d1+udOr+HmZlkyvzkY=
898 | dependencies:
899 | axios "*"
900 |
901 | "@types/node@^15.6.1":
902 | version "15.6.1"
903 | resolved "https://registry.npmjs.org/@types/node/-/node-15.6.1.tgz#32d43390d5c62c5b6ec486a9bc9c59544de39a08"
904 | integrity sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA==
905 |
906 | ansi-styles@^3.2.1:
907 | version "3.2.1"
908 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
909 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
910 | dependencies:
911 | color-convert "^1.9.0"
912 |
913 | axios@*:
914 | version "0.21.1"
915 | resolved "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
916 | integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
917 | dependencies:
918 | follow-redirects "^1.10.0"
919 |
920 | axios@^0.19.2:
921 | version "0.19.2"
922 | resolved "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
923 | integrity sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==
924 | dependencies:
925 | follow-redirects "1.5.10"
926 |
927 | babel-plugin-dynamic-import-node@^2.3.3:
928 | version "2.3.3"
929 | resolved "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3"
930 | integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==
931 | dependencies:
932 | object.assign "^4.1.0"
933 |
934 | babel-plugin-polyfill-corejs2@^0.2.0:
935 | version "0.2.2"
936 | resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327"
937 | integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ==
938 | dependencies:
939 | "@babel/compat-data" "^7.13.11"
940 | "@babel/helper-define-polyfill-provider" "^0.2.2"
941 | semver "^6.1.1"
942 |
943 | babel-plugin-polyfill-corejs3@^0.2.0:
944 | version "0.2.2"
945 | resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz#7424a1682ee44baec817327710b1b094e5f8f7f5"
946 | integrity sha512-l1Cf8PKk12eEk5QP/NQ6TH8A1pee6wWDJ96WjxrMXFLHLOBFzYM4moG80HFgduVhTqAFez4alnZKEhP/bYHg0A==
947 | dependencies:
948 | "@babel/helper-define-polyfill-provider" "^0.2.2"
949 | core-js-compat "^3.9.1"
950 |
951 | babel-plugin-polyfill-regenerator@^0.2.0:
952 | version "0.2.2"
953 | resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077"
954 | integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg==
955 | dependencies:
956 | "@babel/helper-define-polyfill-provider" "^0.2.2"
957 |
958 | browserslist@^4.16.6:
959 | version "4.16.6"
960 | resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
961 | integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==
962 | dependencies:
963 | caniuse-lite "^1.0.30001219"
964 | colorette "^1.2.2"
965 | electron-to-chromium "^1.3.723"
966 | escalade "^3.1.1"
967 | node-releases "^1.1.71"
968 |
969 | buffer-from@^1.0.0:
970 | version "1.1.1"
971 | resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
972 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
973 |
974 | call-bind@^1.0.0:
975 | version "1.0.2"
976 | resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
977 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==
978 | dependencies:
979 | function-bind "^1.1.1"
980 | get-intrinsic "^1.0.2"
981 |
982 | caniuse-lite@^1.0.30001219:
983 | version "1.0.30001230"
984 | resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001230.tgz#8135c57459854b2240b57a4a6786044bdc5a9f71"
985 | integrity sha512-5yBd5nWCBS+jWKTcHOzXwo5xzcj4ePE/yjtkZyUV1BTUmrBaA9MRGC+e7mxnqXSA90CmCA8L3eKLaSUkt099IQ==
986 |
987 | chalk@^2.0.0:
988 | version "2.4.2"
989 | resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
990 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
991 | dependencies:
992 | ansi-styles "^3.2.1"
993 | escape-string-regexp "^1.0.5"
994 | supports-color "^5.3.0"
995 |
996 | clone-deep@^4.0.1:
997 | version "4.0.1"
998 | resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
999 | integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
1000 | dependencies:
1001 | is-plain-object "^2.0.4"
1002 | kind-of "^6.0.2"
1003 | shallow-clone "^3.0.0"
1004 |
1005 | color-convert@^1.9.0:
1006 | version "1.9.3"
1007 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
1008 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
1009 | dependencies:
1010 | color-name "1.1.3"
1011 |
1012 | color-name@1.1.3:
1013 | version "1.1.3"
1014 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
1015 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
1016 |
1017 | colorette@^1.2.2:
1018 | version "1.2.2"
1019 | resolved "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
1020 | integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
1021 |
1022 | commondir@^1.0.1:
1023 | version "1.0.1"
1024 | resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
1025 | integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
1026 |
1027 | convert-source-map@^1.7.0:
1028 | version "1.7.0"
1029 | resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
1030 | integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
1031 | dependencies:
1032 | safe-buffer "~5.1.1"
1033 |
1034 | core-js-compat@^3.9.0, core-js-compat@^3.9.1:
1035 | version "3.13.1"
1036 | resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.13.1.tgz#05444caa8f153be0c67db03cf8adb8ec0964e58e"
1037 | integrity sha512-mdrcxc0WznfRd8ZicEZh1qVeJ2mu6bwQFh8YVUK48friy/FOwFV5EJj9/dlh+nMQ74YusdVfBFDuomKgUspxWQ==
1038 | dependencies:
1039 | browserslist "^4.16.6"
1040 | semver "7.0.0"
1041 |
1042 | debug@=3.1.0:
1043 | version "3.1.0"
1044 | resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
1045 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
1046 | dependencies:
1047 | ms "2.0.0"
1048 |
1049 | debug@^4.1.0, debug@^4.1.1:
1050 | version "4.3.1"
1051 | resolved "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
1052 | integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
1053 | dependencies:
1054 | ms "2.1.2"
1055 |
1056 | define-properties@^1.1.3:
1057 | version "1.1.3"
1058 | resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
1059 | integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==
1060 | dependencies:
1061 | object-keys "^1.0.12"
1062 |
1063 | electron-to-chromium@^1.3.723:
1064 | version "1.3.742"
1065 | resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.742.tgz#7223215acbbd3a5284962ebcb6df85d88b95f200"
1066 | integrity sha512-ihL14knI9FikJmH2XUIDdZFWJxvr14rPSdOhJ7PpS27xbz8qmaRwCwyg/bmFwjWKmWK9QyamiCZVCvXm5CH//Q==
1067 |
1068 | escalade@^3.1.1:
1069 | version "3.1.1"
1070 | resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
1071 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
1072 |
1073 | escape-string-regexp@^1.0.5:
1074 | version "1.0.5"
1075 | resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
1076 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
1077 |
1078 | esutils@^2.0.2:
1079 | version "2.0.3"
1080 | resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
1081 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
1082 |
1083 | find-cache-dir@^2.0.0:
1084 | version "2.1.0"
1085 | resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
1086 | integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==
1087 | dependencies:
1088 | commondir "^1.0.1"
1089 | make-dir "^2.0.0"
1090 | pkg-dir "^3.0.0"
1091 |
1092 | find-up@^3.0.0:
1093 | version "3.0.0"
1094 | resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
1095 | integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
1096 | dependencies:
1097 | locate-path "^3.0.0"
1098 |
1099 | follow-redirects@1.5.10:
1100 | version "1.5.10"
1101 | resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
1102 | integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==
1103 | dependencies:
1104 | debug "=3.1.0"
1105 |
1106 | follow-redirects@^1.10.0:
1107 | version "1.14.1"
1108 | resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
1109 | integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==
1110 |
1111 | function-bind@^1.1.1:
1112 | version "1.1.1"
1113 | resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
1114 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
1115 |
1116 | gensync@^1.0.0-beta.2:
1117 | version "1.0.0-beta.2"
1118 | resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
1119 | integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
1120 |
1121 | get-intrinsic@^1.0.2:
1122 | version "1.1.1"
1123 | resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
1124 | integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==
1125 | dependencies:
1126 | function-bind "^1.1.1"
1127 | has "^1.0.3"
1128 | has-symbols "^1.0.1"
1129 |
1130 | globals@^11.1.0:
1131 | version "11.12.0"
1132 | resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
1133 | integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
1134 |
1135 | has-flag@^3.0.0:
1136 | version "3.0.0"
1137 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
1138 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
1139 |
1140 | has-symbols@^1.0.1:
1141 | version "1.0.2"
1142 | resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423"
1143 | integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==
1144 |
1145 | has@^1.0.3:
1146 | version "1.0.3"
1147 | resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
1148 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
1149 | dependencies:
1150 | function-bind "^1.1.1"
1151 |
1152 | is-core-module@^2.2.0:
1153 | version "2.4.0"
1154 | resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
1155 | integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==
1156 | dependencies:
1157 | has "^1.0.3"
1158 |
1159 | is-plain-object@^2.0.4:
1160 | version "2.0.4"
1161 | resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
1162 | integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
1163 | dependencies:
1164 | isobject "^3.0.1"
1165 |
1166 | isobject@^3.0.1:
1167 | version "3.0.1"
1168 | resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
1169 | integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
1170 |
1171 | js-tokens@^4.0.0:
1172 | version "4.0.0"
1173 | resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
1174 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
1175 |
1176 | jsesc@^2.5.1:
1177 | version "2.5.2"
1178 | resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
1179 | integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
1180 |
1181 | jsesc@~0.5.0:
1182 | version "0.5.0"
1183 | resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
1184 | integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=
1185 |
1186 | json5@^2.1.2:
1187 | version "2.2.0"
1188 | resolved "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3"
1189 | integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==
1190 | dependencies:
1191 | minimist "^1.2.5"
1192 |
1193 | kind-of@^6.0.2:
1194 | version "6.0.3"
1195 | resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
1196 | integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
1197 |
1198 | locate-path@^3.0.0:
1199 | version "3.0.0"
1200 | resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
1201 | integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
1202 | dependencies:
1203 | p-locate "^3.0.0"
1204 | path-exists "^3.0.0"
1205 |
1206 | lodash.debounce@^4.0.8:
1207 | version "4.0.8"
1208 | resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
1209 | integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168=
1210 |
1211 | make-dir@^2.0.0, make-dir@^2.1.0:
1212 | version "2.1.0"
1213 | resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
1214 | integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
1215 | dependencies:
1216 | pify "^4.0.1"
1217 | semver "^5.6.0"
1218 |
1219 | minimist@^1.2.5:
1220 | version "1.2.5"
1221 | resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
1222 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
1223 |
1224 | ms@2.0.0:
1225 | version "2.0.0"
1226 | resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
1227 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
1228 |
1229 | ms@2.1.2:
1230 | version "2.1.2"
1231 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
1232 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
1233 |
1234 | node-modules-regexp@^1.0.0:
1235 | version "1.0.0"
1236 | resolved "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
1237 | integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=
1238 |
1239 | node-releases@^1.1.71:
1240 | version "1.1.72"
1241 | resolved "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe"
1242 | integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==
1243 |
1244 | object-keys@^1.0.12, object-keys@^1.1.1:
1245 | version "1.1.1"
1246 | resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
1247 | integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
1248 |
1249 | object.assign@^4.1.0:
1250 | version "4.1.2"
1251 | resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940"
1252 | integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==
1253 | dependencies:
1254 | call-bind "^1.0.0"
1255 | define-properties "^1.1.3"
1256 | has-symbols "^1.0.1"
1257 | object-keys "^1.1.1"
1258 |
1259 | p-limit@^2.0.0:
1260 | version "2.3.0"
1261 | resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
1262 | integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
1263 | dependencies:
1264 | p-try "^2.0.0"
1265 |
1266 | p-locate@^3.0.0:
1267 | version "3.0.0"
1268 | resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
1269 | integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
1270 | dependencies:
1271 | p-limit "^2.0.0"
1272 |
1273 | p-try@^2.0.0:
1274 | version "2.2.0"
1275 | resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
1276 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
1277 |
1278 | path-exists@^3.0.0:
1279 | version "3.0.0"
1280 | resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
1281 | integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
1282 |
1283 | path-parse@^1.0.6:
1284 | version "1.0.7"
1285 | resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
1286 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
1287 |
1288 | pify@^4.0.1:
1289 | version "4.0.1"
1290 | resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
1291 | integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
1292 |
1293 | pirates@^4.0.0:
1294 | version "4.0.1"
1295 | resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
1296 | integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==
1297 | dependencies:
1298 | node-modules-regexp "^1.0.0"
1299 |
1300 | pkg-dir@^3.0.0:
1301 | version "3.0.0"
1302 | resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3"
1303 | integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==
1304 | dependencies:
1305 | find-up "^3.0.0"
1306 |
1307 | reflect-metadata@^0.1.13:
1308 | version "0.1.13"
1309 | resolved "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
1310 | integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
1311 |
1312 | regenerate-unicode-properties@^8.2.0:
1313 | version "8.2.0"
1314 | resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec"
1315 | integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==
1316 | dependencies:
1317 | regenerate "^1.4.0"
1318 |
1319 | regenerate@^1.4.0:
1320 | version "1.4.2"
1321 | resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
1322 | integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
1323 |
1324 | regenerator-runtime@^0.13.4:
1325 | version "0.13.7"
1326 | resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
1327 | integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==
1328 |
1329 | regenerator-transform@^0.14.2:
1330 | version "0.14.5"
1331 | resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4"
1332 | integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==
1333 | dependencies:
1334 | "@babel/runtime" "^7.8.4"
1335 |
1336 | regexpu-core@^4.7.1:
1337 | version "4.7.1"
1338 | resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6"
1339 | integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==
1340 | dependencies:
1341 | regenerate "^1.4.0"
1342 | regenerate-unicode-properties "^8.2.0"
1343 | regjsgen "^0.5.1"
1344 | regjsparser "^0.6.4"
1345 | unicode-match-property-ecmascript "^1.0.4"
1346 | unicode-match-property-value-ecmascript "^1.2.0"
1347 |
1348 | regjsgen@^0.5.1:
1349 | version "0.5.2"
1350 | resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733"
1351 | integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==
1352 |
1353 | regjsparser@^0.6.4:
1354 | version "0.6.9"
1355 | resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.9.tgz#b489eef7c9a2ce43727627011429cf833a7183e6"
1356 | integrity sha512-ZqbNRz1SNjLAiYuwY0zoXW8Ne675IX5q+YHioAGbCw4X96Mjl2+dcX9B2ciaeyYjViDAfvIjFpQjJgLttTEERQ==
1357 | dependencies:
1358 | jsesc "~0.5.0"
1359 |
1360 | resolve@^1.14.2:
1361 | version "1.20.0"
1362 | resolved "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
1363 | integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
1364 | dependencies:
1365 | is-core-module "^2.2.0"
1366 | path-parse "^1.0.6"
1367 |
1368 | safe-buffer@~5.1.1:
1369 | version "5.1.2"
1370 | resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
1371 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
1372 |
1373 | semver@7.0.0:
1374 | version "7.0.0"
1375 | resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
1376 | integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
1377 |
1378 | semver@^5.6.0:
1379 | version "5.7.1"
1380 | resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
1381 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
1382 |
1383 | semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
1384 | version "6.3.0"
1385 | resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
1386 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
1387 |
1388 | shallow-clone@^3.0.0:
1389 | version "3.0.1"
1390 | resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
1391 | integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
1392 | dependencies:
1393 | kind-of "^6.0.2"
1394 |
1395 | source-map-support@^0.5.16:
1396 | version "0.5.19"
1397 | resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
1398 | integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
1399 | dependencies:
1400 | buffer-from "^1.0.0"
1401 | source-map "^0.6.0"
1402 |
1403 | source-map@^0.5.0:
1404 | version "0.5.7"
1405 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
1406 | integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
1407 |
1408 | source-map@^0.6.0:
1409 | version "0.6.1"
1410 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
1411 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
1412 |
1413 | supports-color@^5.3.0:
1414 | version "5.5.0"
1415 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
1416 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
1417 | dependencies:
1418 | has-flag "^3.0.0"
1419 |
1420 | to-fast-properties@^2.0.0:
1421 | version "2.0.0"
1422 | resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
1423 | integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
1424 |
1425 | unicode-canonical-property-names-ecmascript@^1.0.4:
1426 | version "1.0.4"
1427 | resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818"
1428 | integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==
1429 |
1430 | unicode-match-property-ecmascript@^1.0.4:
1431 | version "1.0.4"
1432 | resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c"
1433 | integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==
1434 | dependencies:
1435 | unicode-canonical-property-names-ecmascript "^1.0.4"
1436 | unicode-property-aliases-ecmascript "^1.0.4"
1437 |
1438 | unicode-match-property-value-ecmascript@^1.2.0:
1439 | version "1.2.0"
1440 | resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531"
1441 | integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==
1442 |
1443 | unicode-property-aliases-ecmascript@^1.0.4:
1444 | version "1.1.0"
1445 | resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4"
1446 | integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==
1447 |
--------------------------------------------------------------------------------