mirror of https://github.com/alibaba/ice.git
Plugin/request (#439)
* feat: introduce useRequest * chore: add some description * fix: export statment for generator * fix: make @ice/types dev dep * fix: remove I prefix for interface * fix: lint * fix: update pnpm * feat: add use case for app config * fix: using export request config * fix: review for code * fix: dev dependency
This commit is contained in:
parent
d0bb41ffec
commit
ec42015d34
|
@ -1,6 +1,6 @@
|
|||
import { Meta, Title, Links, Main, Scripts } from 'ice';
|
||||
|
||||
function Document(props) {
|
||||
function Document() {
|
||||
return (
|
||||
<html>
|
||||
<head>
|
||||
|
@ -19,4 +19,4 @@ function Document(props) {
|
|||
);
|
||||
}
|
||||
|
||||
export default Document;
|
||||
export default Document;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export default function home() {
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
<h2>Home Page</h2>
|
||||
|
@ -15,4 +15,4 @@ export function getConfig() {
|
|||
],
|
||||
title: 'Home',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
chrome 55
|
|
@ -0,0 +1,8 @@
|
|||
import { defineConfig } from '@ice/app';
|
||||
import request from '@ice/plugin-request';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
request(),
|
||||
],
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "with-plugin-request",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "ice start",
|
||||
"build": "ice build"
|
||||
},
|
||||
"description": "ICE example with plugin-request",
|
||||
"author": "ICE Team",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@ice/app": "workspace:*",
|
||||
"@ice/plugin-request": "workspace:*",
|
||||
"@ice/runtime": "workspace:*",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.0.17",
|
||||
"@types/react-dom": "^18.0.6"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import { defineRequestConfig } from '@ice/plugin-request/esm/types';
|
||||
const requestConfig = {
|
||||
// 可选的,全局设置 request 是否返回 response 对象,默认为 false
|
||||
withFullResponse: false,
|
||||
baseURL: '/api',
|
||||
headers: {},
|
||||
// 其它 RequestConfig 参数
|
||||
|
||||
// 拦截器
|
||||
interceptors: {
|
||||
request: {
|
||||
onConfig: (config) => {
|
||||
// 发送请求前:可以对 RequestConfig 做一些统一处理
|
||||
config.headers = { a: 1 };
|
||||
return config;
|
||||
},
|
||||
onError: (error) => {
|
||||
return Promise.reject(error);
|
||||
},
|
||||
},
|
||||
response: {
|
||||
onConfig: (response) => {
|
||||
console.log(response);
|
||||
// 请求成功:可以做全局的 toast 展示,或者对 response 做一些格式化
|
||||
if (response.data.status === 1) {
|
||||
alert('请求失败');
|
||||
}
|
||||
return response;
|
||||
},
|
||||
onError: (error) => {
|
||||
// MOCK DATA for `/api/user`
|
||||
if (error.config.url === '/api/user') {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
error.response.data = {
|
||||
name: 'ICE',
|
||||
age: 26,
|
||||
};
|
||||
resolve(error.response);
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
// 请求出错:服务端返回错误状态码
|
||||
console.log(error.response.data);
|
||||
console.log(error.response.status);
|
||||
console.log(error.response.headers);
|
||||
return Promise.reject(error);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
app: {
|
||||
rootId: 'app',
|
||||
},
|
||||
};
|
||||
|
||||
export const request = defineRequestConfig(() => requestConfig);
|
|
@ -0,0 +1,22 @@
|
|||
import { Meta, Title, Links, Main, Scripts } from 'ice';
|
||||
|
||||
function Document() {
|
||||
return (
|
||||
<html>
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta name="description" content="ICE 3 Example for plugin request." />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<Meta />
|
||||
<Title />
|
||||
<Links />
|
||||
</head>
|
||||
<body>
|
||||
<Main />
|
||||
<Scripts />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
export default Document;
|
|
@ -0,0 +1,30 @@
|
|||
import { useEffect } from 'react';
|
||||
import { useRequest } from 'ice';
|
||||
import service from '../service';
|
||||
import styles from './index.module.css';
|
||||
|
||||
export default function Home() {
|
||||
const { data, error, loading, request } = useRequest(service.getUser);
|
||||
|
||||
useEffect(() => {
|
||||
request();
|
||||
}, []);
|
||||
|
||||
if (error) {
|
||||
return <div>failed to load</div>;
|
||||
}
|
||||
if (!data || loading) {
|
||||
return <div>loading...</div>;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<h2 className={styles.title}>Name: {data.name} Age: {data.age}</h2>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export function getConfig() {
|
||||
return {
|
||||
title: 'Home',
|
||||
};
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
.title {
|
||||
color: red;
|
||||
margin-left: 10rpx;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import { Outlet } from 'ice';
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<div>
|
||||
<h1>ICE 3.0 Layout</h1>
|
||||
<Outlet />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export function getConfig() {
|
||||
return {
|
||||
title: 'Layout',
|
||||
meta: [
|
||||
{
|
||||
name: 'layout-color',
|
||||
content: '#f00',
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
export function getData() {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve({
|
||||
layout: true,
|
||||
});
|
||||
}, 1 * 100);
|
||||
});
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import { request } from 'ice';
|
||||
|
||||
const service = {
|
||||
async getUser() {
|
||||
return await request('/api/user');
|
||||
},
|
||||
|
||||
async getRepo(id) {
|
||||
return await request(`/api/repo/${id}`);
|
||||
},
|
||||
|
||||
async getDetail(params) {
|
||||
const data = await request({
|
||||
url: '/api/detail',
|
||||
params,
|
||||
});
|
||||
|
||||
return data.map(item => {
|
||||
return {
|
||||
...item,
|
||||
price: item.oldPrice,
|
||||
text: item.status === '1' ? '确定' : '取消',
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
export default service;
|
|
@ -0,0 +1,14 @@
|
|||
declare module '*.module.less' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
|
||||
declare module '*.module.css' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
||||
|
||||
declare module '*.module.scss' {
|
||||
const classes: { [key: string]: string };
|
||||
export default classes;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"buildOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"outDir": "build",
|
||||
"module": "esnext",
|
||||
"target": "es6",
|
||||
"jsx": "react-jsx",
|
||||
"moduleResolution": "node",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"lib": ["es6", "dom"],
|
||||
"sourceMap": true,
|
||||
"allowJs": true,
|
||||
"rootDir": "./",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noImplicitAny": false,
|
||||
"importHelpers": true,
|
||||
"strictNullChecks": true,
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"noUnusedLocals": true,
|
||||
"skipLibCheck": true,
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"ice": [".ice"]
|
||||
}
|
||||
},
|
||||
"include": ["src", ".ice", "ice.config.*"],
|
||||
"exclude": ["node_modules", "build", "public"]
|
||||
}
|
|
@ -82,8 +82,8 @@
|
|||
"@types/sass": "^1.43.1",
|
||||
"@types/temp": "^0.9.1",
|
||||
"chokidar": "^3.5.3",
|
||||
"react": "^18.0.0",
|
||||
"unplugin": "^0.9.5",
|
||||
"react": "^18.2.0",
|
||||
"unplugin": "^0.8.0",
|
||||
"webpack": "^5.73.0",
|
||||
"webpack-dev-server": "^4.7.4"
|
||||
},
|
||||
|
|
|
@ -44,11 +44,11 @@ export function generateExports(exportList: ExportData[]) {
|
|||
const specifiers = isDefaultImport ? [specifier] : specifier;
|
||||
const symbol = type ? ';' : ',';
|
||||
importStatements.push(`import ${type ? 'type ' : ''}${isDefaultImport ? specifier : `{ ${specifier.join(', ')} }`} from '${source}';`);
|
||||
exportStatements = specifiers.map((specifierStr) => {
|
||||
specifiers.forEach((specifierStr) => {
|
||||
if (exportAlias && exportAlias[specifierStr]) {
|
||||
return `${exportAlias[specifierStr]}: ${specifierStr}${symbol}`;
|
||||
exportStatements.push(`${exportAlias[specifierStr]}: ${specifierStr}${symbol}`);
|
||||
} else {
|
||||
return `${specifierStr}${symbol}`;
|
||||
exportStatements.push(`${specifierStr}${symbol}`);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# CHANGELOG
|
||||
|
||||
## 1.0.0
|
||||
|
||||
- The initial version of the plugin.
|
|
@ -0,0 +1,66 @@
|
|||
# ICE Request Plugin
|
||||
|
||||
## Usage
|
||||
|
||||
Install from npm.
|
||||
|
||||
```bash
|
||||
$ npm i @ice/plugin-request -S
|
||||
```
|
||||
|
||||
Add plugin.
|
||||
|
||||
```js title="ice.config.mts"
|
||||
import { defineConfig } from '@ice/app';
|
||||
import request from '@ice/plugin-request';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
request(),
|
||||
],
|
||||
});
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### request
|
||||
|
||||
```js title="service.ts"
|
||||
import { request } from 'ice';
|
||||
|
||||
export async function getUser(id) {
|
||||
return await request(`/api/user/${id}`);
|
||||
}
|
||||
```
|
||||
|
||||
### useRequest
|
||||
|
||||
```js title="home.tsx"
|
||||
import { useEffect } from 'react';
|
||||
import { useRequest } from 'ice';
|
||||
|
||||
export default function Home() {
|
||||
const {
|
||||
data,
|
||||
error,
|
||||
loading,
|
||||
request
|
||||
} = useRequest(service.getUser);
|
||||
|
||||
useEffect(() => {
|
||||
request();
|
||||
}, []);
|
||||
|
||||
if (error) {
|
||||
return <div>failed to load</div>;
|
||||
}
|
||||
if (!data || loading) {
|
||||
return <div>loading...</div>;
|
||||
}
|
||||
return (
|
||||
<h2 className={styles.title}>
|
||||
Name: {data.name} Age: {data.age}
|
||||
</h2>
|
||||
);
|
||||
}
|
||||
```
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"name": "@ice/plugin-request",
|
||||
"version": "1.0.0",
|
||||
"description": "Request plugin for ice.",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./esm/index.d.ts",
|
||||
"import": "./esm/index.js",
|
||||
"default": "./esm/index.js"
|
||||
},
|
||||
"./runtime": {
|
||||
"types": "./esm/runtime.d.ts",
|
||||
"import": "./esm/runtime.js",
|
||||
"default": "./esm/runtime.js"
|
||||
},
|
||||
"./hooks": {
|
||||
"types": "./esm/hooks.d.ts",
|
||||
"import": "./esm/hooks.js",
|
||||
"default": "./esm/hooks.js"
|
||||
},
|
||||
"./request": {
|
||||
"types": "./esm/request.d.ts",
|
||||
"import": "./esm/request.js",
|
||||
"default": "./esm/request.js"
|
||||
},
|
||||
"./types": {
|
||||
"types": "./esm/types.d.ts",
|
||||
"import": "./esm/types.js",
|
||||
"default": "./esm/types.js"
|
||||
},
|
||||
"./esm/types": {
|
||||
"types": "./esm/types.d.ts",
|
||||
"import": "./esm/types.js",
|
||||
"default": "./esm/types.js"
|
||||
},
|
||||
"./esm/runtime": {
|
||||
"types": "./esm/runtime.d.ts",
|
||||
"import": "./esm/runtime.js",
|
||||
"default": "./esm/runtime.js"
|
||||
}
|
||||
},
|
||||
"main": "./esm/index.js",
|
||||
"types": "./esm/index.d.ts",
|
||||
"files": [
|
||||
"esm",
|
||||
"!esm/**/*.map"
|
||||
],
|
||||
"dependencies": {
|
||||
"ahooks": "^3.0.0",
|
||||
"axios": "^0.27.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ice/types": "^1.0.0",
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"regenerator-runtime": "^0.13.9"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "http",
|
||||
"url": "https://github.com/ice-lab/ice-next/tree/master/packages/plugin-request"
|
||||
},
|
||||
"scripts": {
|
||||
"watch": "tsc -w",
|
||||
"build": "tsc"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
import { useRequest as useAhooksRequest } from 'ahooks';
|
||||
import type { Options, Result, Service, Plugin } from 'ahooks/lib/useRequest/src/types';
|
||||
import type { AxiosRequestConfig } from 'axios';
|
||||
import request from './request.js';
|
||||
|
||||
interface RequestResult<R, P extends any[]> extends Result<R, P> {
|
||||
request: (...args: P) => Promise<R>;
|
||||
}
|
||||
|
||||
function useRequest<TData, TParams extends any[]>(
|
||||
service: AxiosRequestConfig | Service<TData, TParams>,
|
||||
options?: Options<TData, TParams>,
|
||||
plugins?: Plugin<TData, TParams>[]) {
|
||||
let s: Service<TData, TParams>;
|
||||
if (isFunction(service)) {
|
||||
s = service as Service<TData, TParams>;
|
||||
} else {
|
||||
const options = service as AxiosRequestConfig;
|
||||
s = async (...extraOptions: TParams) => {
|
||||
const response = await request({ ...options, ...extraOptions });
|
||||
return response.data as TData;
|
||||
};
|
||||
}
|
||||
const req = useAhooksRequest(s, {
|
||||
// Note:
|
||||
// ahooks/useRequest manual default to true.
|
||||
// ICE3/useRequest Default to manual request.
|
||||
manual: true,
|
||||
...options,
|
||||
}, plugins);
|
||||
return {
|
||||
...req,
|
||||
// Modify ahooks' useRequest `run` as `request`
|
||||
request: req.run,
|
||||
} as RequestResult<TData, TParams>;
|
||||
}
|
||||
|
||||
export default useRequest;
|
||||
|
||||
function isFunction(fn: any): fn is Function {
|
||||
return typeof fn === 'function';
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
import { fileURLToPath } from 'url';
|
||||
import path from 'path';
|
||||
import type { Plugin } from '@ice/types';
|
||||
import type { Request, Interceptors, InterceptorRequest, InterceptorResponse } from './types';
|
||||
|
||||
// @ts-ignore
|
||||
interface PluginRequestOptions {}
|
||||
|
||||
const plugin: Plugin<PluginRequestOptions | void> = () => ({
|
||||
name: 'plugin-request',
|
||||
setup: ({ generator }) => {
|
||||
// Add useRequest export for 'ice'.
|
||||
// import { useRequest } from 'ice';
|
||||
generator.addExport({
|
||||
specifier: 'useRequest',
|
||||
source: '@ice/plugin-request/hooks',
|
||||
type: false,
|
||||
});
|
||||
// import { request } from 'ice';
|
||||
generator.addExport({
|
||||
specifier: 'request',
|
||||
source: '@ice/plugin-request/request',
|
||||
type: false,
|
||||
});
|
||||
},
|
||||
runtime: path.join(path.dirname(fileURLToPath(import.meta.url)), 'runtime.js'),
|
||||
});
|
||||
|
||||
export type {
|
||||
Request,
|
||||
Interceptors,
|
||||
InterceptorRequest,
|
||||
InterceptorResponse,
|
||||
PluginRequestOptions,
|
||||
};
|
||||
export default plugin;
|
|
@ -0,0 +1,124 @@
|
|||
import type { AxiosRequestConfig, CancelTokenStatic, CancelStatic } from 'axios';
|
||||
import axios from 'axios';
|
||||
|
||||
// https://github.com/axios/axios#request-config
|
||||
const DEFAULT_CONFIG = {};
|
||||
|
||||
const axiosInstances = {
|
||||
default: axios.create(DEFAULT_CONFIG),
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an axios instance.
|
||||
* @param instanceName
|
||||
*/
|
||||
export function createAxiosInstance(instanceName?: string) {
|
||||
if (instanceName) {
|
||||
if (axiosInstances[instanceName]) {
|
||||
return axiosInstances;
|
||||
}
|
||||
axiosInstances[instanceName] = axios.create(DEFAULT_CONFIG);
|
||||
}
|
||||
return axiosInstances;
|
||||
}
|
||||
|
||||
export function setAxiosInstance(requestConfig, axiosInstance) {
|
||||
const { interceptors = {}, ...requestOptions } = requestConfig;
|
||||
Object.keys(requestOptions).forEach(key => {
|
||||
axiosInstance.defaults[key] = requestOptions[key];
|
||||
});
|
||||
|
||||
function isExist(handlers, [fulfilled, rejected]) {
|
||||
return handlers.some(item => item.fulfilled === fulfilled && item.rejected === rejected);
|
||||
}
|
||||
|
||||
// Add request interceptor.
|
||||
if (interceptors.request) {
|
||||
const [fulfilled, rejected] = [
|
||||
interceptors.request.onConfig || function (config) { return config; },
|
||||
interceptors.request.onError || function (error) { return Promise.reject(error); },
|
||||
];
|
||||
if (isExist(axiosInstance.interceptors.request.handlers, [fulfilled, rejected])) return;
|
||||
axiosInstance.interceptors.request.use(fulfilled, rejected);
|
||||
}
|
||||
|
||||
// Add response interceptor.
|
||||
if (interceptors.response) {
|
||||
const [fulfilled, rejected] = [
|
||||
interceptors.response.onConfig || function (response) { return response; },
|
||||
interceptors.response.onError || function (error) { return Promise.reject(error); },
|
||||
];
|
||||
if (isExist(axiosInstance.interceptors.response.handlers, [fulfilled, rejected])) return;
|
||||
axiosInstance.interceptors.response.use(fulfilled, rejected);
|
||||
}
|
||||
}
|
||||
|
||||
interface RequestConfig extends AxiosRequestConfig {
|
||||
instanceName?: string;
|
||||
withFullResponse?: boolean;
|
||||
}
|
||||
|
||||
export interface RequestProps {
|
||||
get: <T = any>(url: string, config?: RequestConfig) => Promise<T>;
|
||||
delete: <T = any>(url: string, config?: RequestConfig) => Promise<T>;
|
||||
head: <T = any>(url: string, config?: RequestConfig) => Promise<T>;
|
||||
options: <T = any>(url: string, config?: RequestConfig) => Promise<T>;
|
||||
post: <T = any>(url: string, data?: any, config?: RequestConfig) => Promise<T>;
|
||||
put: <T = any>(url: string, data?: any, config?: RequestConfig) => Promise<T>;
|
||||
patch: <T = any>(url: string, data?: any, config?: RequestConfig) => Promise<T>;
|
||||
}
|
||||
|
||||
interface Request extends RequestProps {
|
||||
<T = any>(options: RequestConfig): Promise<T>;
|
||||
<T = any>(url: string, config?: RequestConfig): Promise<T>;
|
||||
Cancel: CancelStatic;
|
||||
CancelToken: CancelTokenStatic;
|
||||
isCancel: (value: any) => boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request, return response.data | response
|
||||
* @param options Reference: https://github.com/axios/axios#request-config
|
||||
*/
|
||||
const request = async function <T = any>(options): Promise<T> {
|
||||
try {
|
||||
const instanceName = options.instanceName ? options.instanceName : 'default';
|
||||
const axiosInstance = createAxiosInstance()[instanceName];
|
||||
if (!(typeof axiosInstance === 'function')) {
|
||||
throw new Error(`unknown ${instanceName} in request method`);
|
||||
}
|
||||
const response = await axiosInstance(options);
|
||||
if (axiosInstance.defaults.withFullResponse || options.withFullResponse) {
|
||||
return response;
|
||||
}
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
// Provide aliases for supported request methods
|
||||
['delete', 'get', 'head', 'options'].forEach((method) => {
|
||||
request[method] = function <T = any>(url, config) {
|
||||
return request<T>(Object.assign(config || {}, {
|
||||
method,
|
||||
url,
|
||||
}));
|
||||
};
|
||||
});
|
||||
|
||||
['post', 'put', 'patch'].forEach((method) => {
|
||||
request[method] = function <T = any>(url, data, config) {
|
||||
return request<T>(Object.assign(config || {}, {
|
||||
method,
|
||||
url,
|
||||
data,
|
||||
}));
|
||||
};
|
||||
});
|
||||
|
||||
request.CancelToken = axios.CancelToken;
|
||||
request.isCancel = axios.isCancel;
|
||||
|
||||
export default request as Request;
|
|
@ -0,0 +1,24 @@
|
|||
import type { RuntimePlugin } from '@ice/types';
|
||||
import { createAxiosInstance, setAxiosInstance } from './request.js';
|
||||
import type { RequestConfig } from './types';
|
||||
|
||||
const runtime: RuntimePlugin = async ({ appContext }) => {
|
||||
const { appExport } = appContext;
|
||||
const requestConfig: RequestConfig = (typeof appExport.request === 'function' ? await appExport.request() : appExport.request) || {};
|
||||
|
||||
// Support multi configs.
|
||||
if (Array.isArray(requestConfig)) {
|
||||
requestConfig.forEach(requestItem => {
|
||||
const instanceName = requestItem.instanceName ? requestItem.instanceName : 'default';
|
||||
if (instanceName) {
|
||||
const axiosInstance = createAxiosInstance(instanceName)[instanceName];
|
||||
setAxiosInstance(requestItem, axiosInstance);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const axiosInstance = createAxiosInstance().default;
|
||||
setAxiosInstance(requestConfig, axiosInstance);
|
||||
}
|
||||
};
|
||||
|
||||
export default runtime;
|
|
@ -0,0 +1,32 @@
|
|||
import type { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
|
||||
|
||||
export interface InterceptorRequest<T = AxiosRequestConfig> {
|
||||
onConfig?: (config: T) => T | Promise<T>;
|
||||
onError?: (error: AxiosError) => Promise<void>;
|
||||
}
|
||||
|
||||
export interface InterceptorResponse<K = AxiosResponse> {
|
||||
onConfig?: (response: K) => K | Promise<K>;
|
||||
onError?: (error: AxiosError) => Promise<void>;
|
||||
}
|
||||
|
||||
export interface Interceptors {
|
||||
request?: InterceptorRequest<AxiosRequestConfig>;
|
||||
response?: InterceptorResponse<AxiosResponse>;
|
||||
}
|
||||
|
||||
interface CustomRequest extends AxiosRequestConfig {
|
||||
instanceName?: string;
|
||||
withFullResponse?: boolean;
|
||||
interceptors?: Interceptors;
|
||||
}
|
||||
|
||||
export type Request = CustomRequest | CustomRequest[];
|
||||
export type RequestConfig = Request | object;
|
||||
|
||||
export function defineRequestConfig(configOrDefineConfig: RequestConfig | (() => RequestConfig)): RequestConfig {
|
||||
if (typeof configOrDefineConfig === 'function') {
|
||||
return configOrDefineConfig();
|
||||
}
|
||||
return configOrDefineConfig;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"rootDir": "src",
|
||||
"outDir": "esm",
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
|
@ -114,7 +114,6 @@ async function render({ history, runtime, Document }: RenderOptions) {
|
|||
const RouteWrappers = runtime.getWrappers();
|
||||
const AppRouter = runtime.getAppRouter();
|
||||
|
||||
|
||||
render(
|
||||
document.getElementById(appConfig.app.rootId),
|
||||
<BrowserEntry
|
||||
|
|
104
pnpm-lock.yaml
104
pnpm-lock.yaml
|
@ -302,6 +302,25 @@ importers:
|
|||
'@types/react-dom': 18.0.3
|
||||
webpack: 5.74.0
|
||||
|
||||
examples/with-plugin-request:
|
||||
specifiers:
|
||||
'@ice/app': workspace:*
|
||||
'@ice/plugin-request': workspace:*
|
||||
'@ice/runtime': workspace:*
|
||||
'@types/react': ^18.0.17
|
||||
'@types/react-dom': ^18.0.6
|
||||
react: ^18.2.0
|
||||
react-dom: ^18.2.0
|
||||
dependencies:
|
||||
'@ice/app': link:../../packages/ice
|
||||
'@ice/plugin-request': link:../../packages/plugin-request
|
||||
'@ice/runtime': link:../../packages/runtime
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
devDependencies:
|
||||
'@types/react': 18.0.17
|
||||
'@types/react-dom': 18.0.6
|
||||
|
||||
examples/with-store:
|
||||
specifiers:
|
||||
'@ice/app': workspace:*
|
||||
|
@ -512,7 +531,7 @@ importers:
|
|||
multer: ^1.4.5-lts.1
|
||||
open: ^8.4.0
|
||||
path-to-regexp: ^6.2.0
|
||||
react: ^18.0.0
|
||||
react: ^18.2.0
|
||||
react-router: ^6.3.0
|
||||
regenerator-runtime: ^0.13.9
|
||||
resolve.exports: ^1.1.0
|
||||
|
@ -520,7 +539,7 @@ importers:
|
|||
semver: ^7.3.5
|
||||
temp: ^0.9.4
|
||||
trusted-cert: ^1.1.3
|
||||
unplugin: ^0.9.5
|
||||
unplugin: ^0.8.0
|
||||
webpack: ^5.73.0
|
||||
webpack-dev-server: ^4.7.4
|
||||
dependencies:
|
||||
|
@ -577,7 +596,7 @@ importers:
|
|||
'@types/temp': 0.9.1
|
||||
chokidar: 3.5.3
|
||||
react: 18.2.0
|
||||
unplugin: 0.9.5_3qmdnfoccgmcaqi5n264fyeyfi
|
||||
unplugin: 0.8.1_3qmdnfoccgmcaqi5n264fyeyfi
|
||||
webpack: 5.74.0_esbuild@0.14.54
|
||||
webpack-dev-server: 4.8.1_webpack@5.74.0
|
||||
|
||||
|
@ -672,6 +691,23 @@ importers:
|
|||
'@ice/types': link:../types
|
||||
'@types/webpack': 5.28.0
|
||||
|
||||
packages/plugin-request:
|
||||
specifiers:
|
||||
'@ice/types': ^1.0.0
|
||||
'@types/react': ^18.0.0
|
||||
'@types/react-dom': ^18.0.0
|
||||
ahooks: ^3.0.0
|
||||
axios: ^0.27.2
|
||||
regenerator-runtime: ^0.13.9
|
||||
dependencies:
|
||||
ahooks: 3.4.1
|
||||
axios: 0.27.2
|
||||
devDependencies:
|
||||
'@ice/types': link:../types
|
||||
'@types/react': 18.0.17
|
||||
'@types/react-dom': 18.0.6
|
||||
regenerator-runtime: 0.13.9
|
||||
|
||||
packages/plugin-store:
|
||||
specifiers:
|
||||
'@ice/store': ^2.0.1
|
||||
|
@ -5526,6 +5562,7 @@ packages:
|
|||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
@ -5535,6 +5572,7 @@ packages:
|
|||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
@ -5544,6 +5582,7 @@ packages:
|
|||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
@ -5553,6 +5592,7 @@ packages:
|
|||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
@ -6233,6 +6273,7 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
|
@ -6241,6 +6282,7 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
|
@ -6249,6 +6291,7 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
|
@ -6257,6 +6300,7 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
|
@ -7182,6 +7226,22 @@ packages:
|
|||
screenfull: 5.2.0
|
||||
dev: false
|
||||
|
||||
/ahooks/3.4.1:
|
||||
resolution: {integrity: sha512-PMxCDO6JsFdNrAyN3cW1J/2qt/vy2EJ/9KhxGOxj41hJhQddjgaBJjZKf/FrrnZmL+3yGPioZtbC4C7q7ru3yA==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
'@types/js-cookie': 2.2.7
|
||||
ahooks-v3-count: 1.0.0
|
||||
dayjs: 1.11.2
|
||||
intersection-observer: 0.12.0
|
||||
js-cookie: 2.2.1
|
||||
lodash: 4.17.21
|
||||
resize-observer-polyfill: 1.5.1
|
||||
screenfull: 5.2.0
|
||||
dev: false
|
||||
|
||||
/ahooks/3.4.1_react@18.2.0:
|
||||
resolution: {integrity: sha512-PMxCDO6JsFdNrAyN3cW1J/2qt/vy2EJ/9KhxGOxj41hJhQddjgaBJjZKf/FrrnZmL+3yGPioZtbC4C7q7ru3yA==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
@ -7559,7 +7619,6 @@ packages:
|
|||
|
||||
/asynckit/0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
dev: true
|
||||
|
||||
/at-least-node/1.0.0:
|
||||
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
||||
|
@ -7651,6 +7710,15 @@ packages:
|
|||
- debug
|
||||
dev: false
|
||||
|
||||
/axios/0.27.2:
|
||||
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.1
|
||||
form-data: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/axobject-query/2.2.0:
|
||||
resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==}
|
||||
dev: true
|
||||
|
@ -8356,7 +8424,6 @@ packages:
|
|||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
dev: true
|
||||
|
||||
/comma-separated-tokens/1.0.8:
|
||||
resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
|
||||
|
@ -9253,7 +9320,6 @@ packages:
|
|||
/delayed-stream/1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: true
|
||||
|
||||
/delegates/1.0.0:
|
||||
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
|
||||
|
@ -10916,7 +10982,6 @@ packages:
|
|||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
dev: true
|
||||
|
||||
/forwarded/0.2.0:
|
||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||
|
@ -18193,6 +18258,31 @@ packages:
|
|||
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
/unplugin/0.8.1_3qmdnfoccgmcaqi5n264fyeyfi:
|
||||
resolution: {integrity: sha512-o7rUZoPLG1fH4LKinWgb77gDtTE6mw/iry0Pq0Z5UPvZ9+HZ1/4+7fic7t58s8/CGkPrDpGq+RltO+DmswcR4g==}
|
||||
peerDependencies:
|
||||
esbuild: '>=0.13'
|
||||
rollup: ^2.50.0
|
||||
vite: ^2.3.0 || ^3.0.0-0
|
||||
webpack: 4 || 5
|
||||
peerDependenciesMeta:
|
||||
esbuild:
|
||||
optional: true
|
||||
rollup:
|
||||
optional: true
|
||||
vite:
|
||||
optional: true
|
||||
webpack:
|
||||
optional: true
|
||||
dependencies:
|
||||
acorn: 8.8.0
|
||||
chokidar: 3.5.3
|
||||
esbuild: 0.14.54
|
||||
webpack: 5.74.0_esbuild@0.14.54
|
||||
webpack-sources: 3.2.3
|
||||
webpack-virtual-modules: 0.4.4
|
||||
dev: true
|
||||
|
||||
/unplugin/0.9.5_3qmdnfoccgmcaqi5n264fyeyfi:
|
||||
resolution: {integrity: sha512-luraheyfxwtvkvHpsOvMNv7IjLdORTWKZp0gWYNHGLi2ImON3iIZOj464qEyyEwLA/EMt12fC415HW9zRpOfTg==}
|
||||
peerDependencies:
|
||||
|
|
Loading…
Reference in New Issue