gitscope
https://dev.kronoz.win/r/marzneshin.git
app/dashboard/src/stores/inbounds.store.ts · v0.1.1
Source
1 89f8f93 Mardin 2y ago import { create } from 'zustand';
2 89f8f93 Mardin 2y ago import { subscribeWithSelector } from 'zustand/middleware';
3 89f8f93 Mardin 2y ago import { useDashboard } from './dashboard.store';
4 89f8f93 Mardin 2y ago import { fetch } from 'service/http';
5 89f8f93 Mardin 2y ago import { Inbounds, InboundType } from 'types/inbounds';
6 89f8f93 Mardin 2y ago import { z } from 'zod';
7 6aab6f0 Mrdn 2y ago import { HostsFilterType, InboundsFilterType } from 'types';
8 6aab6f0 Mrdn 2y ago import { pageSizeManagers } from 'utils/userPreferenceStorage';
9 6aab6f0 Mrdn 2y ago import { queryClient } from 'service/react-query';
10 89f8f93 Mardin 2y ago
11 89f8f93 Mardin 2y ago const isPortThenValue = (value: number) => (value <= 65535 && value !== 0) ? value : null;
12 89f8f93 Mardin 2y ago
13 89f8f93 Mardin 2y ago export const hostSchema = z.object({
14 89f8f93 Mardin 2y ago remark: z.string().min(1, 'Remark is required'),
15 89f8f93 Mardin 2y ago address: z.string().min(1, 'Address is required'),
16 89f8f93 Mardin 2y ago port: z
17 89f8f93 Mardin 2y ago .string()
18 89f8f93 Mardin 2y ago .or(z.number())
19 89f8f93 Mardin 2y ago .nullable()
20 89f8f93 Mardin 2y ago .transform((value) => {
21 89f8f93 Mardin 2y ago if (typeof value === 'number') return isPortThenValue(value);
22 89f8f93 Mardin 2y ago if (value !== null && !isNaN(parseInt(value))) return isPortThenValue(Number(parseInt(value)));
23 89f8f93 Mardin 2y ago return null;
24 89f8f93 Mardin 2y ago }),
25 89f8f93 Mardin 2y ago path: z.string(),
26 89f8f93 Mardin 2y ago sni: z.string(),
27 89f8f93 Mardin 2y ago host: z.string(),
28 89f8f93 Mardin 2y ago security: z.enum(['inbound_default', 'none', 'tls']),
29 89f8f93 Mardin 2y ago alpn: z.string().optional(),
30 89f8f93 Mardin 2y ago fingerprint: z.string().optional(),
31 89f8f93 Mardin 2y ago });
32 89f8f93 Mardin 2y ago
33 89f8f93 Mardin 2y ago export type HostSchema = z.infer<typeof hostSchema>;
34 89f8f93 Mardin 2y ago export type HostType = HostSchema & { id?: number };
35 89f8f93 Mardin 2y ago export type Hosts = HostType[];
36 89f8f93 Mardin 2y ago
37 89f8f93 Mardin 2y ago export const fetchInbounds = async () => {
38 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
39 89f8f93 Mardin 2y ago return fetch('/inbounds')
40 89f8f93 Mardin 2y ago .then((inbounds: Inbounds) => {
41 89f8f93 Mardin 2y ago useInbounds.setState({ inbounds });
42 89f8f93 Mardin 2y ago })
43 89f8f93 Mardin 2y ago .finally(() => {
44 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
45 89f8f93 Mardin 2y ago });
46 89f8f93 Mardin 2y ago };
47 89f8f93 Mardin 2y ago
48 6aab6f0 Mrdn 2y ago export const fetchInboundHosts = async (id: number): Promise<Hosts> => {
49 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
50 89f8f93 Mardin 2y ago return fetch(`/inbounds/${id}/hosts`)
51 89f8f93 Mardin 2y ago .then((hosts: Hosts) => hosts)
52 89f8f93 Mardin 2y ago .finally(() => {
53 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
54 89f8f93 Mardin 2y ago });
55 89f8f93 Mardin 2y ago };
56 89f8f93 Mardin 2y ago
57 89f8f93 Mardin 2y ago type InboundsStateType = {
58 89f8f93 Mardin 2y ago // Loading
59 89f8f93 Mardin 2y ago loading: boolean;
60 89f8f93 Mardin 2y ago setLoading: (value: boolean) => void;
61 89f8f93 Mardin 2y ago // Inbounds
62 89f8f93 Mardin 2y ago inbounds: Inbounds;
63 89f8f93 Mardin 2y ago refetchInbounds: () => void;
64 89f8f93 Mardin 2y ago selectedInbound: InboundType | null;
65 89f8f93 Mardin 2y ago selectInbound: (inbound: InboundType) => void;
66 89f8f93 Mardin 2y ago // Hosts
67 6aab6f0 Mrdn 2y ago refetchHosts: () => void;
68 6aab6f0 Mrdn 2y ago hostsFilters: HostsFilterType;
69 6aab6f0 Mrdn 2y ago inboundsFilters: InboundsFilterType;
70 6aab6f0 Mrdn 2y ago onHostsFilterChange: (filters: Partial<HostsFilterType>) => void;
71 6aab6f0 Mrdn 2y ago onInboundsFilterChange: (filters: Partial<InboundsFilterType>) => void;
72 89f8f93 Mardin 2y ago selectedHost: HostType | null;
73 89f8f93 Mardin 2y ago selectHost: (host: HostType) => void;
74 89f8f93 Mardin 2y ago isEditingHost: boolean;
75 89f8f93 Mardin 2y ago onEditingHost: (isEditingHost: boolean, host: HostType | null) => void;
76 89f8f93 Mardin 2y ago editHost: (inboundId: number | undefined, host: HostType) => Promise<boolean | void>;
77 89f8f93 Mardin 2y ago isCreatingHost: boolean;
78 89f8f93 Mardin 2y ago onCreatingHost: (isCreatingHost: boolean) => void;
79 89f8f93 Mardin 2y ago createHost: (inboundId: number | undefined, host: HostSchema) => Promise<boolean | void>;
80 89f8f93 Mardin 2y ago isDeletingHost: boolean;
81 89f8f93 Mardin 2y ago onDeletingHost: (isDeletingHost: boolean, host: HostType) => void;
82 89f8f93 Mardin 2y ago deleteHost: (hostId: number) => void;
83 89f8f93 Mardin 2y ago };
84 89f8f93 Mardin 2y ago
85 89f8f93 Mardin 2y ago export const useInbounds = create(
86 6aab6f0 Mrdn 2y ago subscribeWithSelector<InboundsStateType>((set, get) => ({
87 89f8f93 Mardin 2y ago inbounds: [],
88 89f8f93 Mardin 2y ago selectedHost: null,
89 89f8f93 Mardin 2y ago selectedInbound: null,
90 89f8f93 Mardin 2y ago loading: false,
91 89f8f93 Mardin 2y ago isDeletingHost: false,
92 89f8f93 Mardin 2y ago isCreatingHost: false,
93 89f8f93 Mardin 2y ago isEditingHost: false,
94 6aab6f0 Mrdn 2y ago hostsFilters: {
95 6aab6f0 Mrdn 2y ago name: '',
96 6aab6f0 Mrdn 2y ago limit: pageSizeManagers.hosts.getPageSize(),
97 6aab6f0 Mrdn 2y ago sort: '-created_at',
98 6aab6f0 Mrdn 2y ago },
99 6aab6f0 Mrdn 2y ago inboundsFilters: {
100 6aab6f0 Mrdn 2y ago name: '',
101 6aab6f0 Mrdn 2y ago limit: pageSizeManagers.inbounds.getPageSize(),
102 6aab6f0 Mrdn 2y ago sort: '-created_at',
103 6aab6f0 Mrdn 2y ago },
104 6aab6f0 Mrdn 2y ago onHostsFilterChange: (filters) => {
105 6aab6f0 Mrdn 2y ago set({
106 6aab6f0 Mrdn 2y ago hostsFilters: {
107 6aab6f0 Mrdn 2y ago ...get().hostsFilters,
108 6aab6f0 Mrdn 2y ago ...filters,
109 6aab6f0 Mrdn 2y ago },
110 6aab6f0 Mrdn 2y ago });
111 6aab6f0 Mrdn 2y ago },
112 6aab6f0 Mrdn 2y ago onInboundsFilterChange: (filters) => {
113 6aab6f0 Mrdn 2y ago set({
114 6aab6f0 Mrdn 2y ago hostsFilters: {
115 6aab6f0 Mrdn 2y ago ...get().inboundsFilters,
116 6aab6f0 Mrdn 2y ago ...filters,
117 6aab6f0 Mrdn 2y ago },
118 6aab6f0 Mrdn 2y ago });
119 6aab6f0 Mrdn 2y ago },
120 89f8f93 Mardin 2y ago setLoading: (value) => {
121 89f8f93 Mardin 2y ago set({ loading: value })
122 89f8f93 Mardin 2y ago },
123 89f8f93 Mardin 2y ago refetchInbounds: () => {
124 89f8f93 Mardin 2y ago fetchInbounds();
125 89f8f93 Mardin 2y ago },
126 6aab6f0 Mrdn 2y ago refetchHosts: () => {
127 6aab6f0 Mrdn 2y ago queryClient.invalidateQueries('hosts');
128 6aab6f0 Mrdn 2y ago },
129 89f8f93 Mardin 2y ago selectInbound: (host): void => {
130 89f8f93 Mardin 2y ago set({ selectedInbound: host })
131 89f8f93 Mardin 2y ago },
132 89f8f93 Mardin 2y ago selectHost: (host: HostType): void => {
133 89f8f93 Mardin 2y ago set({ selectedHost: host })
134 89f8f93 Mardin 2y ago },
135 89f8f93 Mardin 2y ago onEditingHost: (isEditingHost: boolean, host: HostType | null) => {
136 89f8f93 Mardin 2y ago set({ isEditingHost, selectedHost: host });
137 89f8f93 Mardin 2y ago },
138 89f8f93 Mardin 2y ago editHost: async (hostId: number | undefined, body: HostSchema): Promise<boolean | void> => {
139 89f8f93 Mardin 2y ago if (hostId !== undefined) {
140 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
141 89f8f93 Mardin 2y ago return fetch(`/inbounds/hosts/${hostId}`, { method: 'PUT', body })
142 89f8f93 Mardin 2y ago .then(() => true)
143 89f8f93 Mardin 2y ago .catch(() => false)
144 89f8f93 Mardin 2y ago .finally(() => {
145 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
146 89f8f93 Mardin 2y ago });
147 89f8f93 Mardin 2y ago }
148 89f8f93 Mardin 2y ago },
149 89f8f93 Mardin 2y ago onCreatingHost: (isCreatingHost: boolean) => {
150 89f8f93 Mardin 2y ago set({ isCreatingHost });
151 89f8f93 Mardin 2y ago },
152 89f8f93 Mardin 2y ago createHost: async (inboundId: number | undefined, body: HostSchema): Promise<boolean | void> => {
153 89f8f93 Mardin 2y ago if (inboundId !== undefined) {
154 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
155 89f8f93 Mardin 2y ago return fetch(`/inbounds/${inboundId}/hosts/${body}`, { method: 'POST', body })
156 89f8f93 Mardin 2y ago .then(() => true)
157 89f8f93 Mardin 2y ago .catch(() => false)
158 89f8f93 Mardin 2y ago .finally(() => {
159 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
160 89f8f93 Mardin 2y ago });
161 89f8f93 Mardin 2y ago }
162 89f8f93 Mardin 2y ago },
163 89f8f93 Mardin 2y ago onDeletingHost: (isDeletingHost: boolean, host: HostType | null) => {
164 89f8f93 Mardin 2y ago set({ isDeletingHost, selectedHost: host });
165 89f8f93 Mardin 2y ago },
166 89f8f93 Mardin 2y ago deleteHost: async (hostId: number): Promise<boolean> => {
167 89f8f93 Mardin 2y ago useDashboard.setState({ loading: true });
168 89f8f93 Mardin 2y ago return fetch(`/inbounds/hosts/${hostId}`, { method: 'DELETE' })
169 89f8f93 Mardin 2y ago .then(() => true)
170 89f8f93 Mardin 2y ago .catch(() => false)
171 89f8f93 Mardin 2y ago .finally(() => {
172 89f8f93 Mardin 2y ago useDashboard.setState({ loading: false });
173 89f8f93 Mardin 2y ago });
174 89f8f93 Mardin 2y ago },
175 89f8f93 Mardin 2y ago }))
176 89f8f93 Mardin 2y ago );