React 18 and Vite (#4510)

This commit is contained in:
Matthew Penner 2022-11-25 13:25:03 -07:00 committed by GitHub
parent 1bb1b13f6d
commit 21613fa602
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
244 changed files with 4547 additions and 8933 deletions

View file

@ -1,8 +1,10 @@
import useSWR, { ConfigInterface, responseInterface } from 'swr';
import { ActivityLog, Transformers } from '@definitions/user';
import { AxiosError } from 'axios';
import type { AxiosError } from 'axios';
import type { SWRConfiguration } from 'swr';
import useSWR from 'swr';
import http, { PaginatedResult, QueryBuilderParams, withQueryBuilderParams } from '@/api/http';
import { toPaginatedSet } from '@definitions/helpers';
import { ActivityLog, Transformers } from '@definitions/user';
import useFilteredObject from '@/plugins/useFilteredObject';
import { useUserSWRKey } from '@/plugins/useSWRKey';
@ -10,8 +12,8 @@ export type ActivityLogFilters = QueryBuilderParams<'ip' | 'event', 'timestamp'>
const useActivityLogs = (
filters?: ActivityLogFilters,
config?: ConfigInterface<PaginatedResult<ActivityLog>, AxiosError>
): responseInterface<PaginatedResult<ActivityLog>, AxiosError> => {
config?: SWRConfiguration<PaginatedResult<ActivityLog>, AxiosError>,
) => {
const key = useUserSWRKey(['account', 'activity', JSON.stringify(useFilteredObject(filters || {}))]);
return useSWR<PaginatedResult<ActivityLog>>(
@ -26,7 +28,7 @@ const useActivityLogs = (
return toPaginatedSet(data, Transformers.toActivityLog);
},
{ revalidateOnMount: false, ...(config || {}) }
{ revalidateOnMount: false, ...(config || {}) },
);
};

View file

@ -12,7 +12,7 @@ export default (description: string, allowedIps: string): Promise<ApiKey & { sec
...rawDataToApiKey(data.attributes),
// eslint-disable-next-line camelcase
secretToken: data.meta?.secret_token ?? '',
})
}),
)
.catch(reject);
});

View file

@ -1,10 +1,12 @@
import useSWR, { ConfigInterface } from 'swr';
import type { AxiosError } from 'axios';
import type { SWRConfiguration } from 'swr';
import useSWR from 'swr';
import http, { FractalResponseList } from '@/api/http';
import { SSHKey, Transformers } from '@definitions/user';
import { AxiosError } from 'axios';
import { useUserSWRKey } from '@/plugins/useSWRKey';
const useSSHKeys = (config?: ConfigInterface<SSHKey[], AxiosError>) => {
const useSSHKeys = (config?: SWRConfiguration<SSHKey[], AxiosError>) => {
const key = useUserSWRKey(['account', 'ssh-keys']);
return useSWR(
@ -16,7 +18,7 @@ const useSSHKeys = (config?: ConfigInterface<SSHKey[], AxiosError>) => {
return Transformers.toSSHKey(datum.attributes);
});
},
{ revalidateOnMount: false, ...(config || {}) }
{ revalidateOnMount: false, ...(config || {}) },
);
};

View file

@ -20,9 +20,9 @@ export default ({ username, password, recaptchaData }: LoginData): Promise<Login
user: username,
password,
'g-recaptcha-response': recaptchaData,
})
}),
)
.then((response) => {
.then(response => {
if (!(response.data instanceof Object)) {
return reject(new Error('An error occurred while processing the login request.'));
}

View file

@ -8,11 +8,11 @@ export default (token: string, code: string, recoveryToken?: string): Promise<Lo
authentication_code: code,
recovery_token: recoveryToken && recoveryToken.length > 0 ? recoveryToken : undefined,
})
.then((response) =>
.then(response =>
resolve({
complete: response.data.data.complete,
intended: response.data.data.intended || undefined,
})
}),
)
.catch(reject);
});

View file

@ -19,11 +19,11 @@ export default (email: string, data: Data): Promise<PasswordResetResponse> => {
password: data.password,
password_confirmation: data.passwordConfirmation,
})
.then((response) =>
.then(response =>
resolve({
redirectTo: response.data.redirect_to,
sendToLogin: response.data.send_to_login,
})
}),
)
.catch(reject);
});

View file

@ -3,7 +3,7 @@ import http from '@/api/http';
export default (email: string, recaptchaData?: string): Promise<string> => {
return new Promise((resolve, reject) => {
http.post('/auth/password', { email, 'g-recaptcha-response': recaptchaData })
.then((response) => resolve(response.data.status || ''))
.then(response => resolve(response.data.status || ''))
.catch(reject);
});
};

View file

@ -15,17 +15,17 @@ function transform<T, M>(data: null | undefined, transformer: TransformerFunc<T>
function transform<T, M>(
data: FractalResponseData | null | undefined,
transformer: TransformerFunc<T>,
missing?: M
missing?: M,
): T | M;
function transform<T, M>(
data: FractalResponseList | FractalPaginatedResponse | null | undefined,
transformer: TransformerFunc<T>,
missing?: M
missing?: M,
): T[] | M;
function transform<T>(
data: FractalResponseData | FractalResponseList | FractalPaginatedResponse | null | undefined,
transformer: TransformerFunc<T>,
missing = undefined
missing = undefined,
) {
if (data === undefined || data === null) {
return missing;
@ -44,7 +44,7 @@ function transform<T>(
function toPaginatedSet<T extends TransformerFunc<Model>>(
response: FractalPaginatedResponse,
transformer: T
transformer: T,
): PaginatedResult<ReturnType<T>> {
return {
items: transform(response, transformer) as ReturnType<T>[],

View file

@ -19,7 +19,7 @@ export default ({ query, ...params }: QueryParams): Promise<PaginatedResult<Serv
resolve({
items: (data.data || []).map((datum: any) => rawDataToServerObject(datum)),
pagination: getPaginationSet(data.meta.pagination),
})
}),
)
.catch(reject);
});

View file

@ -11,7 +11,7 @@ const http: AxiosInstance = axios.create({
},
});
http.interceptors.request.use((req) => {
http.interceptors.request.use(req => {
if (!req.url?.endsWith('/resources')) {
store.getActions().progress.startContinuous();
}
@ -20,18 +20,18 @@ http.interceptors.request.use((req) => {
});
http.interceptors.response.use(
(resp) => {
resp => {
if (!resp.request?.url?.endsWith('/resources')) {
store.getActions().progress.setComplete();
}
return resp;
},
(error) => {
error => {
store.getActions().progress.setComplete();
throw error;
}
},
);
export default http;

View file

@ -1,21 +1,22 @@
import http from '@/api/http';
import { AxiosError } from 'axios';
import { History } from 'history';
import type { AxiosError } from 'axios';
import type { NavigateFunction } from 'react-router-dom';
export const setupInterceptors = (history: History) => {
import http from '@/api/http';
export const setupInterceptors = (navigate: NavigateFunction) => {
http.interceptors.response.use(
(resp) => resp,
resp => resp,
(error: AxiosError) => {
if (error.response?.status === 400) {
if (
(error.response?.data as Record<string, any>).errors?.[0].code === 'TwoFactorAuthRequiredException'
) {
if (!window.location.pathname.startsWith('/account')) {
history.replace('/account', { twoFactorRedirect: true });
navigate('/account', { state: { twoFactorRedirect: true } });
}
}
}
throw error;
}
},
);
};

View file

@ -1,8 +1,12 @@
import useSWR, { ConfigInterface, responseInterface } from 'swr';
import { ActivityLog, Transformers } from '@definitions/user';
import { AxiosError } from 'axios';
import http, { PaginatedResult, QueryBuilderParams, withQueryBuilderParams } from '@/api/http';
import type { AxiosError } from 'axios';
import type { SWRConfiguration } from 'swr';
import useSWR from 'swr';
import type { PaginatedResult, QueryBuilderParams } from '@/api/http';
import http, { withQueryBuilderParams } from '@/api/http';
import { toPaginatedSet } from '@definitions/helpers';
import type { ActivityLog } from '@definitions/user';
import { Transformers } from '@definitions/user';
import useFilteredObject from '@/plugins/useFilteredObject';
import { useServerSWRKey } from '@/plugins/useSWRKey';
import { ServerContext } from '@/state/server';
@ -11,9 +15,9 @@ export type ActivityLogFilters = QueryBuilderParams<'ip' | 'event', 'timestamp'>
const useActivityLogs = (
filters?: ActivityLogFilters,
config?: ConfigInterface<PaginatedResult<ActivityLog>, AxiosError>
): responseInterface<PaginatedResult<ActivityLog>, AxiosError> => {
const uuid = ServerContext.useStoreState((state) => state.server.data?.uuid);
config?: SWRConfiguration<PaginatedResult<ActivityLog>, AxiosError>,
) => {
const uuid = ServerContext.useStoreState(state => state.server.data?.uuid);
const key = useServerSWRKey(['activity', useFilteredObject(filters || {})]);
return useSWR<PaginatedResult<ActivityLog>>(
@ -28,7 +32,7 @@ const useActivityLogs = (
return toPaginatedSet(data, Transformers.toActivityLog);
},
{ revalidateOnMount: false, ...(config || {}) }
{ revalidateOnMount: false, ...(config || {}) },
);
};

View file

@ -11,9 +11,9 @@ export default (uuid: string, data: { connectionsFrom: string; databaseName: str
},
{
params: { include: 'password' },
}
},
)
.then((response) => resolve(rawDataToServerDatabase(response.data.attributes)))
.then(response => resolve(rawDataToServerDatabase(response.data.attributes)))
.catch(reject);
});
};

View file

@ -23,8 +23,8 @@ export default (uuid: string, includePassword = true): Promise<ServerDatabase[]>
http.get(`/api/client/servers/${uuid}/databases`, {
params: includePassword ? { include: 'password' } : undefined,
})
.then((response) =>
resolve((response.data.data || []).map((item: any) => rawDataToServerDatabase(item.attributes)))
.then(response =>
resolve((response.data.data || []).map((item: any) => rawDataToServerDatabase(item.attributes))),
)
.catch(reject);
});

View file

@ -4,7 +4,7 @@ import http from '@/api/http';
export default (uuid: string, database: string): Promise<ServerDatabase> => {
return new Promise((resolve, reject) => {
http.post(`/api/client/servers/${uuid}/databases/${database}/rotate-password`)
.then((response) => resolve(rawDataToServerDatabase(response.data.attributes)))
.then(response => resolve(rawDataToServerDatabase(response.data.attributes)))
.catch(reject);
});
};

View file

@ -10,7 +10,7 @@ export default async (uuid: string, directory: string, files: string[]): Promise
timeout: 60000,
timeoutErrorMessage:
'It looks like this archive is taking a long time to generate. It will appear once completed.',
}
},
);
return rawDataToFileObject(data);

View file

@ -8,6 +8,6 @@ export default async (uuid: string, directory: string, file: string): Promise<vo
timeout: 300000,
timeoutErrorMessage:
'It looks like this archive is taking a long time to be unarchived. Once completed the unarchived files will appear.',
}
},
);
};

View file

@ -4,7 +4,7 @@ export default (server: string, file: string): Promise<string> => {
return new Promise((resolve, reject) => {
http.get(`/api/client/servers/${server}/files/contents`, {
params: { file },
transformResponse: (res) => res,
transformResponse: res => res,
responseType: 'text',
})
.then(({ data }) => resolve(data))

View file

@ -25,7 +25,7 @@ export interface Server {
};
invocation: string;
dockerImage: string;
description: string;
description: string | null;
limits: {
memory: number;
swap: number;
@ -65,10 +65,10 @@ export const rawDataToServerObject = ({ attributes: data }: FractalResponseData)
featureLimits: { ...data.feature_limits },
isTransferring: data.is_transferring,
variables: ((data.relationships?.variables as FractalResponseList | undefined)?.data || []).map(
rawDataToServerEggVariable
rawDataToServerEggVariable,
),
allocations: ((data.relationships?.allocations as FractalResponseList | undefined)?.data || []).map(
rawDataToServerAllocation
rawDataToServerAllocation,
),
});
@ -80,7 +80,7 @@ export default (uuid: string): Promise<[Server, string[]]> => {
rawDataToServerObject(data),
// eslint-disable-next-line camelcase
data.meta?.is_server_owner ? ['*'] : data.meta?.user_permissions || [],
])
]),
)
.catch(reject);
});

View file

@ -26,7 +26,7 @@ export default (server: string): Promise<ServerStats> => {
networkRxInBytes: attributes.resources.network_rx_bytes,
networkTxInBytes: attributes.resources.network_tx_bytes,
uptime: attributes.resources.uptime,
})
}),
)
.catch(reject);
});

View file

@ -12,7 +12,7 @@ export default (server: string): Promise<Response> => {
resolve({
token: data.data.token,
socket: data.data.socket,
})
}),
)
.catch(reject);
});

View file

@ -16,7 +16,7 @@ export default async (uuid: string, schedule: number, task: number | undefined,
payload: data.payload,
continue_on_failure: data.continueOnFailure,
time_offset: data.timeOffset,
}
},
);
return rawDataToServerTask(response.attributes);

View file

@ -12,7 +12,7 @@ export default (uuid: string, params: Params, subuser?: Subuser): Promise<Subuse
http.post(`/api/client/servers/${uuid}/users${subuser ? `/${subuser.uuid}` : ''}`, {
...params,
})
.then((data) => resolve(rawDataToServerSubuser(data.data)))
.then(data => resolve(rawDataToServerSubuser(data.data)))
.catch(reject);
});
};

View file

@ -9,7 +9,7 @@ export const rawDataToServerSubuser = (data: FractalResponseData): Subuser => ({
twoFactorEnabled: data.attributes['2fa_enabled'],
createdAt: new Date(data.attributes.created_at),
permissions: data.attributes.permissions || [],
can: (permission) => (data.attributes.permissions || []).indexOf(permission) >= 0,
can: permission => (data.attributes.permissions || []).indexOf(permission) >= 0,
});
export default (uuid: string): Promise<Subuser[]> => {

View file

@ -1,11 +1,12 @@
import { ServerContext } from '@/state/server';
import useSWR from 'swr';
import http from '@/api/http';
import { rawDataToServerAllocation } from '@/api/transformers';
import { Allocation } from '@/api/server/getServer';
import { rawDataToServerAllocation } from '@/api/transformers';
import { ServerContext } from '@/state/server';
export default () => {
const uuid = ServerContext.useStoreState((state) => state.server.data!.uuid);
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
return useSWR<Allocation[]>(
['server:allocations', uuid],
@ -14,6 +15,6 @@ export default () => {
return (data.data || []).map(rawDataToServerAllocation);
},
{ revalidateOnFocus: false, revalidateOnMount: false }
{ revalidateOnFocus: false, revalidateOnMount: false },
);
};

View file

@ -1,9 +1,11 @@
import { createContext, useContext } from 'react';
import useSWR from 'swr';
import http, { getPaginationSet, PaginatedResult } from '@/api/http';
import { ServerBackup } from '@/api/server/types';
import type { PaginatedResult } from '@/api/http';
import http, { getPaginationSet } from '@/api/http';
import type { ServerBackup } from '@/api/server/types';
import { rawDataToServerBackup } from '@/api/transformers';
import { ServerContext } from '@/state/server';
import { createContext, useContext } from 'react';
interface ctx {
page: number;
@ -16,7 +18,7 @@ type BackupResponse = PaginatedResult<ServerBackup> & { backupCount: number };
export default () => {
const { page } = useContext(Context);
const uuid = ServerContext.useStoreState((state) => state.server.data!.uuid);
const uuid = ServerContext.useStoreState(state => state.server.data!.uuid);
return useSWR<BackupResponse>(['server:backups', uuid, page], async () => {
const { data } = await http.get(`/api/client/servers/${uuid}/backups`, { params: { page } });

View file

@ -1,7 +1,10 @@
import useSWR, { ConfigInterface } from 'swr';
import type { AxiosError } from 'axios';
import type { SWRConfiguration } from 'swr';
import useSWR from 'swr';
import http, { FractalResponseList } from '@/api/http';
import type { ServerEggVariable } from '@/api/server/types';
import { rawDataToServerEggVariable } from '@/api/transformers';
import { ServerEggVariable } from '@/api/server/types';
interface Response {
invocation: string;
@ -9,7 +12,7 @@ interface Response {
dockerImages: Record<string, string>;
}
export default (uuid: string, initialData?: Response | null, config?: ConfigInterface<Response>) =>
export default (uuid: string, fallbackData?: Response, config?: SWRConfiguration<Response, AxiosError>) =>
useSWR(
[uuid, '/startup'],
async (): Promise<Response> => {
@ -23,5 +26,5 @@ export default (uuid: string, initialData?: Response | null, config?: ConfigInte
dockerImages: data.meta.docker_images || {},
};
},
{ initialData: initialData || undefined, errorRetryCount: 3, ...(config || {}) }
{ fallbackData, errorRetryCount: 3, ...(config ?? {}) },
);

View file

@ -49,7 +49,7 @@ export const rawDataToFileObject = (data: FractalResponseData): FileObject => ({
const matches = ['application/jar', 'application/octet-stream', 'inode/directory', /^image\//];
return matches.every((m) => !this.mimetype.match(m));
return matches.every(m => !this.mimetype.match(m));
},
});