diff --git a/DEV.md b/DEV.md
index bfbfa013..b20f45cd 100644
--- a/DEV.md
+++ b/DEV.md
@@ -12,24 +12,17 @@
## 技术栈
* React 18
-
* AntDesign 5
-
* Zustand
-
* Emotion
-
* i18n
-
* pnpm
-
* ...
## 目录结构
-
```text
.
└── packages
@@ -37,13 +30,11 @@
├── arex-core arex 公共组件包 - 提供面向业务逻辑封装的重型组件
├── arex-request arex 请求包 - 提供浏览器发送 http-rest 请求支持
└── arex-lite arex 精简版 - 提供 arex 项目结构及组件 demo 演示
-
```
## 本地开发
-
### 启动项目
`Fork` 并 `git clone` 仓库
@@ -67,3 +58,5 @@ pnpm run test
pnpm run build
```
+### 服务接口代理
+本地开发需要修改packages/arex/config/proxy.json文件,指向服务接口地址。
diff --git a/packages/arex-request/src/components/Request/RequestBody.tsx b/packages/arex-request/src/components/Request/RequestBody.tsx
index d86c95db..ebab33ca 100644
--- a/packages/arex-request/src/components/Request/RequestBody.tsx
+++ b/packages/arex-request/src/components/Request/RequestBody.tsx
@@ -9,6 +9,7 @@ import { ArexContentTypes } from '../../types';
import RequestBinaryBody from './RequestBinaryBody';
import RequestBodyFormData from './RequestBodyFormData';
import RequestRawBody, { RequestRawBodyRef } from './RequestRawBody';
+import RequestURLEncodeBody from './RequestURLEncodeBody';
const rawSmallCateOptions = [
{
@@ -23,6 +24,10 @@ const rawSmallCateOptions = [
label: 'application/octet-stream',
value: 'application/octet-stream',
},
+ {
+ label: 'application/x-www-form-urlencoded',
+ value: 'application/x-www-form-urlencoded',
+ },
];
const RequestBody = () => {
@@ -124,6 +129,8 @@ const RequestBody = () => {
) : store.request.body.contentType.startsWith('application/octet-stream') ? (
+ ) : store.request.body.contentType.startsWith('application/x-www-form-urlencoded') ? (
+
) : null}
);
diff --git a/packages/arex-request/src/components/Request/RequestURLEncodeBody.tsx b/packages/arex-request/src/components/Request/RequestURLEncodeBody.tsx
new file mode 100644
index 00000000..155f54be
--- /dev/null
+++ b/packages/arex-request/src/components/Request/RequestURLEncodeBody.tsx
@@ -0,0 +1,111 @@
+import { CopyOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';
+import { copyToClipboard, SpaceBetweenWrapper, TooltipButton } from '@arextest/arex-core';
+import { App, Typography } from 'antd';
+import pagination from 'antd/es/pagination';
+import PM from 'postman-collection';
+import React, { FC, useEffect } from 'react';
+import { useTranslation } from 'react-i18next';
+
+import { useArexRequestStore } from '../../hooks';
+import { ArexRESTParam } from '../../types';
+import HeadersTable from '../HeadersTable';
+
+const RequestURLEncodeBody: FC = () => {
+ const { t } = useTranslation();
+ const { message } = App.useApp();
+ const { store, dispatch } = useArexRequestStore();
+ const { params } = store.request;
+ const body = store.request?.body?.body as string;
+
+ const setParams = (params: ArexRESTParam[]) => {
+ dispatch((state) => {
+ state.request.params = params;
+ // 同时更新body为URI编码格式
+ const urlEncoded = params
+ .filter((p) => p.active && p.key)
+ .map((p) => `${encodeURIComponent(p.key)}=${encodeURIComponent(p.value || '')}`)
+ .join('&');
+ if (state.request.body) {
+ state.request.body.body = urlEncoded;
+ }
+ });
+ };
+
+ // 初始化时从body解析参数
+ useEffect(() => {
+ if (body && params.length === 0) {
+ try {
+ const urlParams = new URLSearchParams(body);
+ const parsedParams: ArexRESTParam[] = [];
+ urlParams.forEach((value, key) => {
+ parsedParams.push({
+ key: decodeURIComponent(key),
+ value: decodeURIComponent(value),
+ active: true,
+ id: String(Math.random()),
+ });
+ });
+ if (parsedParams.length > 0) {
+ dispatch((state) => {
+ state.request.params = parsedParams;
+ });
+ }
+ } catch (e) {
+ console.warn('Failed to parse URL encoded body:', e);
+ }
+ }
+ }, [body, dispatch]);
+
+ const handleCopyParameters = () => {
+ const urlEncoded = params
+ .filter((p) => p.active)
+ .map((p) => `${encodeURIComponent(p.key)}=${encodeURIComponent(p.value)}`)
+ .join('&');
+ copyToClipboard(urlEncoded);
+ message.success(t('action.copy_success'));
+ };
+
+ return (
+
+
+ {t('request.urlencoded_body')}
+
+ }
+ onClick={handleCopyParameters}
+ />
+
+ }
+ onClick={() => {
+ setParams([]);
+ }}
+ />
+
+ }
+ onClick={() => {
+ setParams(
+ params.concat([{ value: '', key: '', id: String(Math.random()), active: true }]),
+ );
+ }}
+ />
+
+
+
+
+
+ );
+};
+
+export default RequestURLEncodeBody;
diff --git a/packages/arex-request/src/types/ArexContentTypes.ts b/packages/arex-request/src/types/ArexContentTypes.ts
index 02f9422b..1e6c5c3b 100644
--- a/packages/arex-request/src/types/ArexContentTypes.ts
+++ b/packages/arex-request/src/types/ArexContentTypes.ts
@@ -2,6 +2,7 @@ export const KnownContentTypes = {
'application/json': 'json',
'multipart/form-data': 'multipart',
'application/octet-stream': 'binary',
+ 'application/x-www-form-urlencoded': 'urlencoded',
} as const;
export type ArexContentTypes = keyof typeof KnownContentTypes;
diff --git a/packages/arex-server/server.js b/packages/arex-server/server.js
index 4e0eabba..667cdb5f 100644
--- a/packages/arex-server/server.js
+++ b/packages/arex-server/server.js
@@ -13,7 +13,11 @@ const SERVICE_SCHEDULE_URL = process.env.SERVICE_SCHEDULE_URL;
const SERVICE_STORAGE_URL = process.env.SERVICE_STORAGE_URL;
if (!SERVICE_API_URL || !SERVICE_SCHEDULE_URL || !SERVICE_STORAGE_URL) {
- throw new Error('SERVICE_API_URL, SERVICE_SCHEDULE_URL, SERVICE_STORAGE_URL are required');
+ const missingVars = [];
+ if (!SERVICE_API_URL) missingVars.push('SERVICE_API_URL');
+ if (!SERVICE_SCHEDULE_URL) missingVars.push('SERVICE_SCHEDULE_URL');
+ if (!SERVICE_STORAGE_URL) missingVars.push('SERVICE_STORAGE_URL');
+ throw new Error(`Missing required environment variables: ${missingVars.join(', ')}`);
}
app.use(
diff --git a/packages/arex/config/proxy.json b/packages/arex/config/proxy.json
index 1ea1b1a6..7f4ea191 100644
--- a/packages/arex/config/proxy.json
+++ b/packages/arex/config/proxy.json
@@ -1,14 +1,14 @@
[
{
"path": "/webApi",
- "target": "http://10.118.1.217:18090"
+ "target": "http://localhost:8090"
},
{
"path": "/schedule",
- "target": "http://10.118.1.217:18092"
+ "target": "http://localhost:8092"
},
{
"path": "/storage",
- "target": "http://10.118.1.217:18093"
+ "target": "http://localhost:8093"
}
]
diff --git a/packages/arex/package.json b/packages/arex/package.json
index c9deb889..d8e7d38e 100644
--- a/packages/arex/package.json
+++ b/packages/arex/package.json
@@ -26,7 +26,6 @@
"@emotion/styled": "^11.10.6",
"@formkit/auto-animate": "^0.7.0",
"@monaco-editor/react": "^4.6.0",
- "@sentry/react": "^7.113.0",
"ahooks": "^3.7.5",
"allotment": "^1.20.2",
"antd": "^5.19.0",
diff --git a/packages/arex/src/main.tsx b/packages/arex/src/main.tsx
index 5268ecb3..25f91d2f 100644
--- a/packages/arex/src/main.tsx
+++ b/packages/arex/src/main.tsx
@@ -12,14 +12,11 @@ import ReactDOM from 'react-dom/client';
import { BrowserRouter, HashRouter } from 'react-router-dom';
import { isClientProd } from '@/constant';
-import { initSentry } from '@/utils/sentry';
import App from './App';
dayjs.extend(customParseFormat);
-initSentry();
-
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
React.createElement(isClientProd ? HashRouter : BrowserRouter, {}, ),
);
diff --git a/packages/arex/src/utils/sentry.ts b/packages/arex/src/utils/sentry.ts
deleted file mode 100644
index 1ad4abae..00000000
--- a/packages/arex/src/utils/sentry.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import * as Sentry from '@sentry/react';
-
-export const initSentry = () => {
- Sentry.init({
- dsn: 'https://899ab2ff4de2e35d05c8d76b7a18a596@o1083554.ingest.us.sentry.io/4507525394006016',
- integrations: [Sentry.browserTracingIntegration(), Sentry.replayIntegration()],
- // Performance Monitoring
- tracesSampleRate: 1.0, // Capture 100% of the transactions
- // Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
- tracePropagationTargets: ['localhost', /^https:\/\/yourserver\.io\/api/],
- // Session Replay
- replaysSessionSampleRate: 0.1, // This sets the sample rate at 10%. You may want to change it to 100% while in development and then sample at a lower rate in production.
- replaysOnErrorSampleRate: 1.0, // If you're not already sampling the entire session, change the sample rate to 100% when sampling sessions where errors occur.
- });
- Sentry.setTag('user', localStorage.getItem('email') || 'anonymous');
-};
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e09ac75b..2057c9c1 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -102,9 +102,6 @@ importers:
'@monaco-editor/react':
specifier: ^4.6.0
version: 4.6.0(monaco-editor@0.39.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
- '@sentry/react':
- specifier: ^7.113.0
- version: 7.116.0(react@18.2.0)
ahooks:
specifier: ^3.7.5
version: 3.7.10(react@18.2.0)
@@ -222,7 +219,7 @@ importers:
version: 28.2.8
electron-builder:
specifier: ^24.9.1
- version: 24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
+ version: 24.13.3(electron-builder-squirrel-windows@24.13.3)
electron-log:
specifier: ^4.4.8
version: 4.4.8
@@ -1554,48 +1551,6 @@ packages:
'@rushstack/ts-command-line@4.17.1':
resolution: {integrity: sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==}
- '@sentry-internal/feedback@7.116.0':
- resolution: {integrity: sha512-tmfO+RTCrhIWMs3yg8X0axhbjWRZLsldSfoXBgfjNCk/XwkYiVGp7WnYVbb+IO+01mHCsis9uaYOBggLgFRB5Q==}
- engines: {node: '>=12'}
-
- '@sentry-internal/replay-canvas@7.116.0':
- resolution: {integrity: sha512-Sy0ydY7A97JY/IFTIj8U25kHqR5rL9oBk3HFE5EK9Phw56irVhHzEwLWae0jlFeCQEWoBYqpPgO5vXsaYzrWvw==}
- engines: {node: '>=12'}
-
- '@sentry-internal/tracing@7.116.0':
- resolution: {integrity: sha512-y5ppEmoOlfr77c/HqsEXR72092qmGYS4QE5gSz5UZFn9CiinEwGfEorcg2xIrrCuU7Ry/ZU2VLz9q3xd04drRA==}
- engines: {node: '>=8'}
-
- '@sentry/browser@7.116.0':
- resolution: {integrity: sha512-2aosATT5qE+QLKgTmyF9t5Emsluy1MBczYNuPmLhDxGNfB+MA86S8u7Hb0CpxdwjS0nt14gmbiOtJHoeAF3uTw==}
- engines: {node: '>=8'}
-
- '@sentry/core@7.116.0':
- resolution: {integrity: sha512-J6Wmjjx+o7RwST0weTU1KaKUAlzbc8MGkJV1rcHM9xjNTWTva+nrcCM3vFBagnk2Gm/zhwv3h0PvWEqVyp3U1Q==}
- engines: {node: '>=8'}
-
- '@sentry/integrations@7.116.0':
- resolution: {integrity: sha512-UZb60gaF+7veh1Yv79RiGvgGYOnU6xA97H+hI6tKgc1uT20YpItO4X56Vhp0lvyEyUGFZzBRRH1jpMDPNGPkqw==}
- engines: {node: '>=8'}
-
- '@sentry/react@7.116.0':
- resolution: {integrity: sha512-b7sYSIewK/h3dGzm7Rx6tBUzA6w7zw6m5rVIO3fWCy7T3xEUDggUaqklrFVHXUYx2yjzEgTFPg/Dd2NrSzua4w==}
- engines: {node: '>=8'}
- peerDependencies:
- react: 15.x || 16.x || 17.x || 18.x
-
- '@sentry/replay@7.116.0':
- resolution: {integrity: sha512-OrpDtV54pmwZuKp3g7PDiJg6ruRMJKOCzK08TF7IPsKrr4x4UQn56rzMOiABVuTjuS8lNfAWDar6c6vxXFz5KA==}
- engines: {node: '>=12'}
-
- '@sentry/types@7.116.0':
- resolution: {integrity: sha512-QCCvG5QuQrwgKzV11lolNQPP2k67Q6HHD9vllZ/C4dkxkjoIym8Gy+1OgAN3wjsR0f/kG9o5iZyglgNpUVRapQ==}
- engines: {node: '>=8'}
-
- '@sentry/utils@7.116.0':
- resolution: {integrity: sha512-Vn9fcvwTq91wJvCd7WTMWozimqMi+dEZ3ie3EICELC2diONcN16ADFdzn65CQQbYwmUzRjN9EjDN2k41pKZWhQ==}
- engines: {node: '>=8'}
-
'@sinclair/typebox@0.27.8':
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
@@ -3586,9 +3541,6 @@ packages:
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
engines: {node: '>= 4'}
- immediate@3.0.6:
- resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
-
immer@9.0.21:
resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==}
@@ -3960,9 +3912,6 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
- lie@3.1.1:
- resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==}
-
lilconfig@2.1.0:
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
engines: {node: '>=10'}
@@ -3996,9 +3945,6 @@ packages:
resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
engines: {node: '>=14'}
- localforage@1.10.0:
- resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
-
locate-character@3.0.0:
resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==}
@@ -7365,70 +7311,6 @@ snapshots:
colors: 1.2.5
string-argv: 0.3.2
- '@sentry-internal/feedback@7.116.0':
- dependencies:
- '@sentry/core': 7.116.0
- '@sentry/types': 7.116.0
- '@sentry/utils': 7.116.0
-
- '@sentry-internal/replay-canvas@7.116.0':
- dependencies:
- '@sentry/core': 7.116.0
- '@sentry/replay': 7.116.0
- '@sentry/types': 7.116.0
- '@sentry/utils': 7.116.0
-
- '@sentry-internal/tracing@7.116.0':
- dependencies:
- '@sentry/core': 7.116.0
- '@sentry/types': 7.116.0
- '@sentry/utils': 7.116.0
-
- '@sentry/browser@7.116.0':
- dependencies:
- '@sentry-internal/feedback': 7.116.0
- '@sentry-internal/replay-canvas': 7.116.0
- '@sentry-internal/tracing': 7.116.0
- '@sentry/core': 7.116.0
- '@sentry/integrations': 7.116.0
- '@sentry/replay': 7.116.0
- '@sentry/types': 7.116.0
- '@sentry/utils': 7.116.0
-
- '@sentry/core@7.116.0':
- dependencies:
- '@sentry/types': 7.116.0
- '@sentry/utils': 7.116.0
-
- '@sentry/integrations@7.116.0':
- dependencies:
- '@sentry/core': 7.116.0
- '@sentry/types': 7.116.0
- '@sentry/utils': 7.116.0
- localforage: 1.10.0
-
- '@sentry/react@7.116.0(react@18.2.0)':
- dependencies:
- '@sentry/browser': 7.116.0
- '@sentry/core': 7.116.0
- '@sentry/types': 7.116.0
- '@sentry/utils': 7.116.0
- hoist-non-react-statics: 3.3.2
- react: 18.2.0
-
- '@sentry/replay@7.116.0':
- dependencies:
- '@sentry-internal/tracing': 7.116.0
- '@sentry/core': 7.116.0
- '@sentry/types': 7.116.0
- '@sentry/utils': 7.116.0
-
- '@sentry/types@7.116.0': {}
-
- '@sentry/utils@7.116.0':
- dependencies:
- '@sentry/types': 7.116.0
-
'@sinclair/typebox@0.27.8': {}
'@sindresorhus/is@4.6.0': {}
@@ -8176,7 +8058,7 @@ snapshots:
app-builder-bin@4.0.0: {}
- app-builder-lib@24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)):
+ app-builder-lib@24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3):
dependencies:
'@develar/schema-utils': 2.6.5
'@electron/notarize': 2.2.1
@@ -9013,7 +8895,7 @@ snapshots:
dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3):
dependencies:
- app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
+ app-builder-lib: 24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3)
builder-util: 24.13.1
builder-util-runtime: 9.2.4
fs-extra: 10.1.0
@@ -9085,7 +8967,7 @@ snapshots:
electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3):
dependencies:
- app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
+ app-builder-lib: 24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3)
archiver: 5.3.2
builder-util: 24.13.1
fs-extra: 10.1.0
@@ -9093,9 +8975,9 @@ snapshots:
- dmg-builder
- supports-color
- electron-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)):
+ electron-builder@24.13.3(electron-builder-squirrel-windows@24.13.3):
dependencies:
- app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
+ app-builder-lib: 24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3)
builder-util: 24.13.1
builder-util-runtime: 9.2.4
chalk: 4.1.2
@@ -10028,8 +9910,6 @@ snapshots:
ignore@5.3.1: {}
- immediate@3.0.6: {}
-
immer@9.0.21: {}
immutable-json-patch@6.0.1: {}
@@ -10395,10 +10275,6 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
- lie@3.1.1:
- dependencies:
- immediate: 3.0.6
-
lilconfig@2.1.0: {}
lines-and-columns@1.2.4: {}
@@ -10437,10 +10313,6 @@ snapshots:
mlly: 1.6.1
pkg-types: 1.0.3
- localforage@1.10.0:
- dependencies:
- lie: 3.1.1
-
locate-character@3.0.0: {}
locate-path@5.0.0: