未完待续...
parent
2d475c89e5
commit
fdab3afb48
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
"@babel/preset-typescript",
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"targets": {
|
||||||
|
"browsers": [
|
||||||
|
"ie >= 11"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"modules": false,
|
||||||
|
"loose": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"@babel/plugin-proposal-optional-chaining"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
/node_modules
|
||||||
|
/package
|
||||||
|
/types
|
||||||
|
/coverage
|
||||||
|
/rollup.config.js
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-03-06 20:35:23
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-05 14:17:08
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"extends": [
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"prettier/@typescript-eslint",
|
||||||
|
"plugin:prettier/recommended"
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"@typescript-eslint",
|
||||||
|
"prettier"
|
||||||
|
],
|
||||||
|
"env": {
|
||||||
|
"node": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
|
"@typescript-eslint/no-namespace": "off"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
/node_modules
|
||||||
|
/package
|
||||||
|
/types
|
||||||
|
/coverage
|
||||||
|
/yarn-error.log
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"printWidth": 120,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"singleQuote": true,
|
||||||
|
"semi": true,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"arrowParens": "always",
|
||||||
|
"parser": "typescript"
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
language: node_js
|
||||||
|
node_js: stable
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- node_modules
|
||||||
|
install:
|
||||||
|
- npm install
|
||||||
|
script:
|
||||||
|
- npm run coverage
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 初秋
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-05 01:56:05
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-05 01:56:06
|
||||||
|
*/
|
|
@ -0,0 +1,70 @@
|
||||||
|
{
|
||||||
|
"name": "axios-miniprogram",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "微信小程序专用请求库。",
|
||||||
|
"main": "package/index.js",
|
||||||
|
"miniprogram": "package",
|
||||||
|
"types": "types/index.d.ts",
|
||||||
|
"files": [
|
||||||
|
"package",
|
||||||
|
"types"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "rollup -c",
|
||||||
|
"lint": "eslint --ext ts --fix src test",
|
||||||
|
"prettier": "prettier --write --config .prettierrc \"{src,test}/**/*.{js,ts}\"",
|
||||||
|
"test": "jest",
|
||||||
|
"test:watch": "yarn test -- --watch",
|
||||||
|
"test:cov": "yarn test -- --coverage",
|
||||||
|
"coverage": "yarn test:cov --coverageReporters=text-lcov | coveralls"
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "yarn lint && yarn prettier && yarn test && git add ."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"preset": "ts-jest",
|
||||||
|
"globals": {
|
||||||
|
"ts-jest": {
|
||||||
|
"babelConfig": "test/.babelrc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/early-autumn/axios-miniprogram.git"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/early-autumn/axios-miniprogram/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/early-autumn/axios-miniprogram#readme",
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.8.7",
|
||||||
|
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
|
||||||
|
"@babel/plugin-transform-modules-commonjs": "^7.9.0",
|
||||||
|
"@babel/plugin-transform-runtime": "^7.8.3",
|
||||||
|
"@babel/preset-env": "^7.8.7",
|
||||||
|
"@babel/preset-typescript": "^7.8.3",
|
||||||
|
"@babel/runtime": "^7.8.7",
|
||||||
|
"@types/jest": "^25.1.3",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^2.22.0",
|
||||||
|
"@typescript-eslint/parser": "^2.22.0",
|
||||||
|
"coveralls": "^3.0.9",
|
||||||
|
"eslint": "^6.8.0",
|
||||||
|
"eslint-config-prettier": "^6.10.0",
|
||||||
|
"eslint-plugin-prettier": "^3.1.2",
|
||||||
|
"husky": "^4.2.3",
|
||||||
|
"jest": "^25.1.0",
|
||||||
|
"miniprogram-api-typings": "^2.10.3",
|
||||||
|
"prettier": "^1.19.1",
|
||||||
|
"rollup-plugin-babel": "^4.4.0",
|
||||||
|
"rollup-plugin-node-resolve": "^5.2.0",
|
||||||
|
"rollup-plugin-typescript2": "^0.26.0",
|
||||||
|
"ts-jest": "^25.2.1",
|
||||||
|
"typescript": "^3.8.3"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-03-06 20:40:30
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-13 15:24:07
|
||||||
|
*/
|
||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
import nodeResolve from 'rollup-plugin-node-resolve';
|
||||||
|
import babel from 'rollup-plugin-babel';
|
||||||
|
import typescript from 'rollup-plugin-typescript2';
|
||||||
|
|
||||||
|
function removeDir(name) {
|
||||||
|
try {
|
||||||
|
if (fs.statSync(name).isFile()) {
|
||||||
|
fs.unlinkSync(name);
|
||||||
|
} else {
|
||||||
|
fs.readdirSync(name).forEach((dir) => removeDir(path.join(name, dir)));
|
||||||
|
fs.rmdirSync(name);
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function() {
|
||||||
|
removeDir('package');
|
||||||
|
removeDir('types');
|
||||||
|
|
||||||
|
return {
|
||||||
|
input: 'src/index.ts',
|
||||||
|
output: {
|
||||||
|
file: 'package/index.js',
|
||||||
|
format: 'cjs',
|
||||||
|
indent: false,
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
nodeResolve({
|
||||||
|
extensions: ['.ts'],
|
||||||
|
}),
|
||||||
|
typescript({ useTsconfigDeclarationDir: true }),
|
||||||
|
babel({
|
||||||
|
extensions: ['.ts'],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-13 21:14:53
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 13:41:45
|
||||||
|
*/
|
||||||
|
import { Cancel } from '../types';
|
||||||
|
|
||||||
|
export default class CancelStatic implements Cancel {
|
||||||
|
message?: string;
|
||||||
|
|
||||||
|
constructor(message?: string) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
toString() {
|
||||||
|
const message = this.message ? `: ${this.message}` : '';
|
||||||
|
|
||||||
|
return `Cancel${message}`;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-13 20:00:08
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 19:17:53
|
||||||
|
*/
|
||||||
|
import { CancelToken, CancelAction, CancelExecutor, CancelTokenSource } from '../types';
|
||||||
|
import Cancel from './Cancel';
|
||||||
|
|
||||||
|
export default class CancelTokenStatic implements CancelToken {
|
||||||
|
reason?: Cancel;
|
||||||
|
|
||||||
|
listener: Promise<Cancel>;
|
||||||
|
|
||||||
|
constructor(executor: CancelExecutor) {
|
||||||
|
let action!: CancelAction;
|
||||||
|
|
||||||
|
this.listener = new Promise<Cancel>((resolve) => {
|
||||||
|
action = (message) => {
|
||||||
|
// 防止重复取消
|
||||||
|
if (this.reason) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.reason = new Cancel(message);
|
||||||
|
|
||||||
|
resolve(this.reason);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
executor(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
throwIfRequested() {
|
||||||
|
if (this.reason) {
|
||||||
|
throw this.reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回一个 CancelTokenSource
|
||||||
|
*
|
||||||
|
* CancelTokenSource.token 是一个 CancelToken 对象
|
||||||
|
*
|
||||||
|
* CancelTokenSource.cancel 是一个 CancelAction 函数
|
||||||
|
*
|
||||||
|
* 调用 CancelTokenSource.cancel('这里可以填写您的错误信息')
|
||||||
|
*
|
||||||
|
* 取消 CancelTokenSource.token
|
||||||
|
*/
|
||||||
|
static source(): CancelTokenSource {
|
||||||
|
let cancel!: CancelAction;
|
||||||
|
|
||||||
|
const token = new CancelTokenStatic(function executor(action) {
|
||||||
|
cancel = action;
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
token,
|
||||||
|
cancel,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-14 09:23:25
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 19:18:58
|
||||||
|
*/
|
||||||
|
import Cancel from './Cancel';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是不是一个取消对象
|
||||||
|
*
|
||||||
|
* @param value 判断的值
|
||||||
|
*/
|
||||||
|
export default function isCancel(value: any) {
|
||||||
|
return value && value instanceof Cancel;
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-13 18:00:27
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 23:40:52
|
||||||
|
*/
|
||||||
|
import { Params, Data, AxiosRequestConfig, Axios, AxiosMethodConfig, AxiosPromise, Method } from '../types';
|
||||||
|
import dispatchRequest from './dispatchRequest';
|
||||||
|
|
||||||
|
export default class AxiosStatic implements Axios {
|
||||||
|
request(config: AxiosRequestConfig): AxiosPromise {
|
||||||
|
return dispatchRequest(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
options(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise {
|
||||||
|
return this._requestMethodWithoutParams('options', url, params, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
get(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise {
|
||||||
|
return this._requestMethodWithoutParams('get', url, params, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
head(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise {
|
||||||
|
return this._requestMethodWithoutParams('head', url, params, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
post(url: string, data?: Data, config?: AxiosMethodConfig): AxiosPromise {
|
||||||
|
return this._requestMethodWithoutData('post', url, data, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
put(url: string, data?: Data, config?: AxiosMethodConfig): AxiosPromise {
|
||||||
|
return this._requestMethodWithoutData('put', url, data, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise {
|
||||||
|
return this._requestMethodWithoutParams('delete', url, params, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
trace(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise {
|
||||||
|
return this._requestMethodWithoutParams('trace', url, params, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise {
|
||||||
|
return this._requestMethodWithoutParams('connect', url, params, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
_requestMethodWithoutParams(method: Method, url: string, params?: Params, config: AxiosMethodConfig = {}) {
|
||||||
|
return this.request({ ...config, method, url, params });
|
||||||
|
}
|
||||||
|
|
||||||
|
_requestMethodWithoutData(method: Method, url: string, data?: Data, config: AxiosMethodConfig = {}) {
|
||||||
|
return this.request({ ...config, method, url, data });
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-14 22:23:39
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 22:55:33
|
||||||
|
*/
|
||||||
|
import { AxiosRequestConfig, AxiosResponse } from '../types';
|
||||||
|
|
||||||
|
class AxiosError extends Error {
|
||||||
|
isAxiosError = true;
|
||||||
|
config: AxiosRequestConfig;
|
||||||
|
response?: AxiosResponse;
|
||||||
|
|
||||||
|
constructor(message: string, config: AxiosRequestConfig, response?: AxiosResponse) {
|
||||||
|
super(message);
|
||||||
|
|
||||||
|
this.config = config;
|
||||||
|
this.response = response;
|
||||||
|
|
||||||
|
// 修复
|
||||||
|
Object.setPrototypeOf(this, AxiosError.prototype);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function createError(message: string, config: AxiosRequestConfig, response?: AxiosResponse): AxiosError {
|
||||||
|
return new AxiosError(message, config, response);
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-13 15:22:22
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 23:23:46
|
||||||
|
*/
|
||||||
|
import { AxiosRequestConfig, AxiosPromise } from '../types';
|
||||||
|
import request from './request';
|
||||||
|
import transformRequestConfig from './transformRequestConfig';
|
||||||
|
|
||||||
|
export default function dispatchRequest(config: AxiosRequestConfig): AxiosPromise {
|
||||||
|
transformRequestConfig(config);
|
||||||
|
|
||||||
|
return request(config);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-13 18:01:16
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 22:51:17
|
||||||
|
*/
|
||||||
|
import { AxiosRequestConfig, AxiosPromise } from '../types';
|
||||||
|
import createError from './createError';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送请求
|
||||||
|
*
|
||||||
|
* @param config 请求配置
|
||||||
|
*/
|
||||||
|
export default function request(config: AxiosRequestConfig): AxiosPromise {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const { cancelToken, method, ...options } = config;
|
||||||
|
|
||||||
|
// method 转为全大写
|
||||||
|
const methodType = (method?.toUpperCase() ?? 'GET') as WechatMiniprogram.RequestOption['method'];
|
||||||
|
|
||||||
|
function catchError({ errMsg }: WechatMiniprogram.GeneralCallbackResult): void {
|
||||||
|
reject(createError(errMsg, config));
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleResponse(result: WechatMiniprogram.RequestSuccessCallbackResult): void {
|
||||||
|
const response = { ...result, config };
|
||||||
|
const { statusCode, errMsg } = response;
|
||||||
|
|
||||||
|
if (statusCode >= 200 && statusCode < 300) {
|
||||||
|
resolve(response);
|
||||||
|
} else {
|
||||||
|
reject(createError(!!errMsg ? errMsg : `Request failed with status code ${statusCode}`, config, response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 替换 config 中的 success fail complete
|
||||||
|
const request = wx.request({
|
||||||
|
...options,
|
||||||
|
method: methodType,
|
||||||
|
success: handleResponse,
|
||||||
|
fail: catchError,
|
||||||
|
complete: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 如果存在取消令牌
|
||||||
|
// 则调用取消令牌里的 listener 监听用户的取消操作
|
||||||
|
if (cancelToken !== undefined) {
|
||||||
|
cancelToken.listener.then(function onCanceled(reason): void {
|
||||||
|
request.abort();
|
||||||
|
reject(reason);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-14 10:15:50
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 23:09:27
|
||||||
|
*/
|
||||||
|
import { AxiosRequestConfig } from '../types';
|
||||||
|
import processURL from '../helper/processURL';
|
||||||
|
import processData from '../helper/processData';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 config
|
||||||
|
*
|
||||||
|
* @param config AxiosRequestConfig
|
||||||
|
*/
|
||||||
|
export default function transformRequestConfig(config: AxiosRequestConfig): void {
|
||||||
|
const { url, params, data } = config;
|
||||||
|
|
||||||
|
config.url = processURL(url, params);
|
||||||
|
config.data = processData(data);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-13 22:50:35
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 23:09:59
|
||||||
|
*/
|
||||||
|
import { Data } from '../types';
|
||||||
|
import { isPlainObject } from './utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理请求参数
|
||||||
|
*
|
||||||
|
* @param data 请求参数
|
||||||
|
*/
|
||||||
|
export default function processData(data: Data): Data {
|
||||||
|
if (!isPlainObject(data)) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.stringify(data);
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-13 21:45:45
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 23:07:28
|
||||||
|
*/
|
||||||
|
import { Params } from '../types';
|
||||||
|
import { isPlainObject, isDate } from './utils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对字符串进行编码转换
|
||||||
|
*
|
||||||
|
* @param str 字符串
|
||||||
|
*/
|
||||||
|
function encode(str: string): string {
|
||||||
|
return encodeURIComponent(str)
|
||||||
|
.replace(/%40/g, '@')
|
||||||
|
.replace(/%3A/gi, ':')
|
||||||
|
.replace(/%24/g, '$')
|
||||||
|
.replace(/%2C/gi, ',')
|
||||||
|
.replace(/%20/g, '+')
|
||||||
|
.replace(/%5B/gi, '[')
|
||||||
|
.replace(/%5D/gi, ']');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拼接 URL 和 参数
|
||||||
|
*
|
||||||
|
* @param url URL
|
||||||
|
* @param params 参数
|
||||||
|
*/
|
||||||
|
function joinURL(url: string, paramsStr: string): string {
|
||||||
|
// 移除 hash
|
||||||
|
const hashIndex = paramsStr.indexOf('#');
|
||||||
|
if (hashIndex !== -1) {
|
||||||
|
paramsStr = paramsStr.slice(0, hashIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拼接前缀
|
||||||
|
const prefix = url.indexOf('?') === -1 ? '?' : '&';
|
||||||
|
paramsStr = `${prefix}${paramsStr}`;
|
||||||
|
|
||||||
|
return `${url}${paramsStr}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理 URL 参数
|
||||||
|
*
|
||||||
|
* @param url URL
|
||||||
|
* @param params 参数
|
||||||
|
*/
|
||||||
|
export default function processURL(url: string, params?: Params): string {
|
||||||
|
if (params === undefined) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
const parts: string[] = [];
|
||||||
|
|
||||||
|
Object.entries(params).forEach(([key, value]): void => {
|
||||||
|
if (value === null || value === undefined || value !== value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果值是一个数组, 则特殊处理 key
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
key += '[]';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转成数组统一处理
|
||||||
|
const values: any[] = [].concat(value);
|
||||||
|
|
||||||
|
values.forEach((val: any): void => {
|
||||||
|
if (isPlainObject(val)) {
|
||||||
|
val = JSON.stringify(val);
|
||||||
|
} else if (isDate(val)) {
|
||||||
|
val = val.toISOString();
|
||||||
|
}
|
||||||
|
|
||||||
|
parts.push(`${encode(key)}=${encode(val)}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (parts.length !== 0) {
|
||||||
|
url = joinURL(url, parts.join('&'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-13 21:55:40
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 14:28:31
|
||||||
|
*/
|
||||||
|
const _toString = Object.prototype.toString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是不是一个日期对象
|
||||||
|
*
|
||||||
|
* @param date 判断目标
|
||||||
|
*/
|
||||||
|
export function isDate(date: any): date is Date {
|
||||||
|
return _toString.call(date) === '[object Date]';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是不是一个普通对象
|
||||||
|
*
|
||||||
|
* @param obj 判断目标
|
||||||
|
*/
|
||||||
|
export function isPlainObject(obj: any): obj is object {
|
||||||
|
return _toString.call(obj) === '[object Object]';
|
||||||
|
}
|
||||||
|
|
||||||
|
// export function isObject(value: any): value is object {
|
||||||
|
// return value !== null && typeof value === 'object';
|
||||||
|
// }
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-14 23:22:52
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 23:22:52
|
||||||
|
*/
|
|
@ -0,0 +1,176 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-13 15:23:53
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 23:42:10
|
||||||
|
*/
|
||||||
|
import 'miniprogram-api-typings';
|
||||||
|
|
||||||
|
export declare type AnyObject = Record<string, any>;
|
||||||
|
|
||||||
|
export declare type Params = AnyObject;
|
||||||
|
|
||||||
|
export declare type Data = AxiosRequestConfig['data'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求方法
|
||||||
|
*/
|
||||||
|
export declare type Method =
|
||||||
|
| 'options'
|
||||||
|
| 'get'
|
||||||
|
| 'head'
|
||||||
|
| 'post'
|
||||||
|
| 'put'
|
||||||
|
| 'delete'
|
||||||
|
| 'trace'
|
||||||
|
| 'connect'
|
||||||
|
| WechatMiniprogram.RequestOption['method'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求体
|
||||||
|
*/
|
||||||
|
export type AxiosRequestConfig = Omit<WechatMiniprogram.RequestOption, 'method' | 'success' | 'fail' | 'complete'> & {
|
||||||
|
/** HTTP 请求方法
|
||||||
|
*
|
||||||
|
* 可选值:
|
||||||
|
* - 'options': HTTP 请求 OPTIONS;
|
||||||
|
* - 'OPTIONS': HTTP 请求 OPTIONS;
|
||||||
|
* - 'get': HTTP 请求 GET;
|
||||||
|
* - 'GET': HTTP 请求 GET;
|
||||||
|
* - 'head': HTTP 请求 HEAD;
|
||||||
|
* - 'HEAD': HTTP 请求 HEAD;
|
||||||
|
* - 'post': HTTP 请求 POST;
|
||||||
|
* - 'POST': HTTP 请求 POST;
|
||||||
|
* - 'put': HTTP 请求 PUT;
|
||||||
|
* - 'PUT': HTTP 请求 PUT;
|
||||||
|
* - 'delete': HTTP 请求 DELETE;
|
||||||
|
* - 'DELETE': HTTP 请求 DELETE;
|
||||||
|
* - 'trace': HTTP 请求 TRACE;
|
||||||
|
* - 'TRACE': HTTP 请求 TRACE;
|
||||||
|
* - 'connect': HTTP 请求 CONNECT;
|
||||||
|
* - 'CONNECT': HTTP 请求 CONNECT;
|
||||||
|
*/
|
||||||
|
method?: Method;
|
||||||
|
/**
|
||||||
|
* URL 参数
|
||||||
|
*/
|
||||||
|
params?: Params;
|
||||||
|
/**
|
||||||
|
* 开启 http2
|
||||||
|
*/
|
||||||
|
enableHttp2?: boolean;
|
||||||
|
/**
|
||||||
|
* 开启 quic
|
||||||
|
*/
|
||||||
|
enableQuic?: boolean;
|
||||||
|
/**
|
||||||
|
* 开启 cache
|
||||||
|
*/
|
||||||
|
enableCache?: boolean;
|
||||||
|
/**
|
||||||
|
* 取消令牌
|
||||||
|
*/
|
||||||
|
cancelToken?: CancelToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应体
|
||||||
|
*/
|
||||||
|
export interface AxiosResponse extends WechatMiniprogram.RequestSuccessCallbackResult {
|
||||||
|
config: AxiosRequestConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
export declare type AxiosPromise = Promise<AxiosResponse>;
|
||||||
|
|
||||||
|
export type AxiosMethodConfig = Omit<AxiosRequestConfig, 'url'>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Axios 对象
|
||||||
|
*/
|
||||||
|
export interface Axios {
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param config 000
|
||||||
|
*/
|
||||||
|
request(config: AxiosRequestConfig): AxiosPromise;
|
||||||
|
|
||||||
|
options(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise;
|
||||||
|
|
||||||
|
get(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise;
|
||||||
|
|
||||||
|
head(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise;
|
||||||
|
|
||||||
|
post(url: string, data?: Data, config?: AxiosMethodConfig): AxiosPromise;
|
||||||
|
|
||||||
|
put(url: string, data?: Data, config?: AxiosMethodConfig): AxiosPromise;
|
||||||
|
|
||||||
|
delete(url: string, params?: Params, config?: AxiosMethodConfig): AxiosPromise;
|
||||||
|
|
||||||
|
trace(url: string, params?: Data, config?: AxiosMethodConfig): AxiosPromise;
|
||||||
|
|
||||||
|
connect(url: string, params?: Data, config?: AxiosMethodConfig): AxiosPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AxiosInstance extends Axios {
|
||||||
|
(config: AxiosRequestConfig): AxiosPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
// export interface AxiosError extends Error {
|
||||||
|
// isAxiosError: boolean;
|
||||||
|
// config: AxiosRequestConfig;
|
||||||
|
// response?: AxiosResponse;
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消对象
|
||||||
|
*/
|
||||||
|
export interface Cancel {
|
||||||
|
/**
|
||||||
|
* 取消原因
|
||||||
|
*/
|
||||||
|
message?: string;
|
||||||
|
/**
|
||||||
|
* 序列化
|
||||||
|
*/
|
||||||
|
toString(): string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消操作
|
||||||
|
*/
|
||||||
|
export interface CancelAction {
|
||||||
|
(message?: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消操作执行器
|
||||||
|
*/
|
||||||
|
export interface CancelExecutor {
|
||||||
|
(cancel: CancelAction): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消令牌
|
||||||
|
*/
|
||||||
|
export interface CancelToken {
|
||||||
|
/**
|
||||||
|
* 取消对象
|
||||||
|
*/
|
||||||
|
reason?: Cancel;
|
||||||
|
/**
|
||||||
|
* 取消时触发
|
||||||
|
*/
|
||||||
|
listener: Promise<Cancel>;
|
||||||
|
/**
|
||||||
|
* 如果已取消 则抛出取消对象
|
||||||
|
*/
|
||||||
|
throwIfRequested(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消令牌 source
|
||||||
|
*/
|
||||||
|
export interface CancelTokenSource {
|
||||||
|
token: CancelToken;
|
||||||
|
cancel: CancelAction;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"targets": {
|
||||||
|
"node": "current"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
"@babel/plugin-proposal-optional-chaining",
|
||||||
|
"@babel/plugin-transform-modules-commonjs"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
/*
|
||||||
|
* @Author: early-autumn
|
||||||
|
* @Date: 2020-04-14 23:43:45
|
||||||
|
* @LastEditors: early-autumn
|
||||||
|
* @LastEditTime: 2020-04-14 23:45:11
|
||||||
|
*/
|
||||||
|
import { isDate } from '../src/helper/utils';
|
||||||
|
|
||||||
|
describe('', () => {
|
||||||
|
it('', () => {
|
||||||
|
expect(isDate({})).toBeFalsy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"module": "esnext",
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"es2017"
|
||||||
|
],
|
||||||
|
"declaration": true,
|
||||||
|
"declarationDir": "./types",
|
||||||
|
"sourceMap": true,
|
||||||
|
"removeComments": false,
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"./src/**/*"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue