This is an automated email from the ASF dual-hosted git repository.

LiteSun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-dashboard.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a54982c2 refactor: stop apis layer importing types from components 
(#3445)
9a54982c2 is described below

commit 9a54982c249b22aaecd5169f490fdec9d194f155
Author: Yuhan <[email protected]>
AuthorDate: Tue Jul 28 14:33:30 2026 +0800

    refactor: stop apis layer importing types from components (#3445)
---
 src/apis/plugins.ts                                    |  4 +++-
 src/apis/ssls.ts                                       |  4 ++--
 src/apis/stream_routes.ts                              |  2 +-
 .../form-slice/FormItemPlugins/PluginEditorDrawer.tsx  |  5 ++++-
 .../form-slice/FormPartStreamRoute/schema.ts           | 18 ++++++------------
 src/routes/upstreams/detail.$id.tsx                    | 15 +++------------
 src/types/schema/apisix/ssls.ts                        | 12 ++++++++++++
 src/types/schema/apisix/stream_routes.ts               | 10 ++++++++++
 8 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/src/apis/plugins.ts b/src/apis/plugins.ts
index 8e14b343c..145d53526 100644
--- a/src/apis/plugins.ts
+++ b/src/apis/plugins.ts
@@ -17,7 +17,6 @@
 import { queryOptions, skipToken } from '@tanstack/react-query';
 import type { AxiosRequestConfig } from 'axios';
 
-import type { PluginConfig } from 
'@/components/form-slice/FormItemPlugins/PluginEditorDrawer';
 import {
   API_PLUGIN_METADATA,
   API_PLUGINS,
@@ -26,6 +25,9 @@ import {
 import { req } from '@/config/req';
 import type { APISIXType } from '@/types/schema/apisix';
 
+/** A plugin's name paired with its config object (the plugin-editor shape). */
+export type PluginConfig = { name: string; config: object };
+
 
 export type NeedPluginSchema = {
   schema: APISIXType['PluginSchemaKeys'];
diff --git a/src/apis/ssls.ts b/src/apis/ssls.ts
index 6cc7322da..ae3f18bb0 100644
--- a/src/apis/ssls.ts
+++ b/src/apis/ssls.ts
@@ -16,9 +16,9 @@
  */
 import type { AxiosInstance } from 'axios';
 
-import type { SSLPostType } from '@/components/form-slice/FormPartSSL/schema';
 import { API_SSLS } from '@/config/constant';
 import type { APISIXType } from '@/types/schema/apisix';
+import type { SSLPostBody } from '@/types/schema/apisix/ssls';
 import type { PageSearchType } from '@/types/schema/pageSearch';
 
 export const getSSLListReq = (req: AxiosInstance, params: PageSearchType) =>
@@ -41,7 +41,7 @@ export const putSSLReq = (req: AxiosInstance, data: 
APISIXType['SSL']) => {
   );
 };
 
-export const postSSLReq = (req: AxiosInstance, data: SSLPostType) =>
+export const postSSLReq = (req: AxiosInstance, data: SSLPostBody) =>
   req.post<APISIXType['SSL'], APISIXType['RespSSLDetail']>(API_SSLS, data);
 
 export const deleteAllSSLs = async (req: AxiosInstance) => {
diff --git a/src/apis/stream_routes.ts b/src/apis/stream_routes.ts
index 786529f7d..a1cf493d5 100644
--- a/src/apis/stream_routes.ts
+++ b/src/apis/stream_routes.ts
@@ -17,13 +17,13 @@
 
 import type { AxiosInstance } from 'axios';
 
-import type { StreamRoutePostType } from 
'@/components/form-slice/FormPartStreamRoute/schema';
 import {
   API_STREAM_ROUTES,
   PAGE_SIZE_MAX,
   PAGE_SIZE_MIN,
 } from '@/config/constant';
 import type { APISIXType } from '@/types/schema/apisix';
+import type { StreamRoutePostType } from '@/types/schema/apisix/stream_routes';
 
 import type { WithServiceIdFilter } from './routes';
 
diff --git a/src/components/form-slice/FormItemPlugins/PluginEditorDrawer.tsx 
b/src/components/form-slice/FormItemPlugins/PluginEditorDrawer.tsx
index eb55ede2b..cf3e8827c 100644
--- a/src/components/form-slice/FormItemPlugins/PluginEditorDrawer.tsx
+++ b/src/components/form-slice/FormItemPlugins/PluginEditorDrawer.tsx
@@ -22,12 +22,15 @@ import { useEffect } from 'react';
 import { FormProvider, useForm } from 'react-hook-form';
 import { useTranslation } from 'react-i18next';
 
+import type { PluginConfig } from '@/apis/plugins';
 import { FormSubmitBtn } from '@/components/form/Btn';
 import { FormItemEditor } from '@/components/form/Editor';
 
 import type { PluginCardListProps } from './PluginCardList';
 
-export type PluginConfig = { name: string; config: object };
+// PluginConfig is defined in the API layer (apis/plugins) and re-exported
+// here so existing importers keep their path.
+export type { PluginConfig };
 export type PluginEditorDrawerProps = Pick<PluginCardListProps, 'mode'> & {
   opened: boolean;
   onClose: () => void;
diff --git a/src/components/form-slice/FormPartStreamRoute/schema.ts 
b/src/components/form-slice/FormPartStreamRoute/schema.ts
index 82de48cb2..2e9afcb5f 100644
--- a/src/components/form-slice/FormPartStreamRoute/schema.ts
+++ b/src/components/form-slice/FormPartStreamRoute/schema.ts
@@ -14,15 +14,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-import type { TypeOf } from 'zod';
-
-import { APISIXCommon } from '@/types/schema/apisix/common';
-import { APISIXStreamRoutes } from '@/types/schema/apisix/stream_routes';
-
-export const StreamRoutePostSchema = APISIXStreamRoutes.StreamRoute.omit({
-  create_time: true,
-  update_time: true,
-  id: true,
-}).merge(APISIXCommon.Basic);
-
-export type StreamRoutePostType = TypeOf<typeof StreamRoutePostSchema>;
+// The stream-route create-form schema lives in the schema layer so the API
+// layer can type its request body without importing from components/.
+export {
+  StreamRoutePostSchema,
+  type StreamRoutePostType,
+} from '@/types/schema/apisix/stream_routes';
diff --git a/src/routes/upstreams/detail.$id.tsx 
b/src/routes/upstreams/detail.$id.tsx
index e05c66bbe..b7ba2eb05 100644
--- a/src/routes/upstreams/detail.$id.tsx
+++ b/src/routes/upstreams/detail.$id.tsx
@@ -17,11 +17,7 @@
 import { zodResolver } from '@hookform/resolvers/zod';
 import { Button, Group, Skeleton } from '@mantine/core';
 import { notifications } from '@mantine/notifications';
-import {
-  queryOptions,
-  useMutation,
-  useSuspenseQuery,
-} from '@tanstack/react-query';
+import { useMutation, useSuspenseQuery } from '@tanstack/react-query';
 import {
   createFileRoute,
   useNavigate,
@@ -33,7 +29,8 @@ import { useTranslation } from 'react-i18next';
 import { useBoolean } from 'react-use';
 import type { z } from 'zod';
 
-import { getUpstreamReq, putUpstreamReq } from '@/apis/upstreams';
+import { getUpstreamQueryOptions } from '@/apis/hooks';
+import { putUpstreamReq } from '@/apis/upstreams';
 import { FormSubmitBtn } from '@/components/form/Btn';
 import { FormPartUpstream } from '@/components/form-slice/FormPartUpstream';
 import {
@@ -59,12 +56,6 @@ type Props = {
   setReadOnly: (v: boolean) => void;
 };
 
-const getUpstreamQueryOptions = (id: string) =>
-  queryOptions({
-    queryKey: ['upstream', id],
-    queryFn: () => getUpstreamReq(req, id),
-  });
-
 const UpstreamDetailForm = (
   props: Props & Pick<APISIXType['Upstream'], 'id'>
 ) => {
diff --git a/src/types/schema/apisix/ssls.ts b/src/types/schema/apisix/ssls.ts
index c32d5fa90..87f24020d 100644
--- a/src/types/schema/apisix/ssls.ts
+++ b/src/types/schema/apisix/ssls.ts
@@ -49,6 +49,18 @@ const SSL = z
   .merge(APISIXCommon.Basic)
   .merge(APISIXCommon.Info);
 
+// The request body of an SSL create: the stored resource minus the
+// server-managed id/timestamps. The form's own post type (which also carries
+// the UI-only `__clientEnabled` helper) is assignable to this, so the API
+// layer can type its payload without importing from components/.
+export const SSLPostBodySchema = SSL.omit({
+  id: true,
+  create_time: true,
+  update_time: true,
+});
+
+export type SSLPostBody = z.infer<typeof SSLPostBodySchema>;
+
 export const APISIXSSLs = {
   SSL,
   SSLStatus: APISIXCommon.Status,
diff --git a/src/types/schema/apisix/stream_routes.ts 
b/src/types/schema/apisix/stream_routes.ts
index c1f75d776..576342f7e 100644
--- a/src/types/schema/apisix/stream_routes.ts
+++ b/src/types/schema/apisix/stream_routes.ts
@@ -51,6 +51,16 @@ const StreamRoute = z
   .merge(APISIXCommon.Basic.omit({ status: true }))
   .merge(APISIXCommon.Info);
 
+// The shape the create form submits: the stored resource minus the
+// server-managed id/timestamps, plus the editable Basic fields.
+export const StreamRoutePostSchema = StreamRoute.omit({
+  create_time: true,
+  update_time: true,
+  id: true,
+}).merge(APISIXCommon.Basic);
+
+export type StreamRoutePostType = z.infer<typeof StreamRoutePostSchema>;
+
 export const APISIXStreamRoutes = {
   StreamRoute,
 };

Reply via email to