Engineering Initiated - FE: Improve api entity naming (#45865)

This commit is contained in:
RachelElysia
2026-05-21 16:10:31 -04:00
committed by GitHub
parent 0c494a1ae4
commit 4de604a3dc
41 changed files with 167 additions and 157 deletions
+1
View File
@@ -89,6 +89,7 @@ Use helpers from `frontend/utilities/strings/stringUtils.ts`:
- Interface files live in `frontend/interfaces/` with `I` prefix: `IHost`, `IUser`, `IPack`
- Legacy pattern: some files export both PropTypes (default export) and TypeScript interfaces (named export)
- New code should use TypeScript interfaces only
- API interface naming: use `*FormData` for form-driven request bodies, `*ApiParams`/`*QueryParams` for request params, `*Response` for API responses, `*QueryKey` when typing a React Query key. Avoid `*Body`, `*PostBody`, `*Payload`, `*Request` for API request bodies. `*PreviewPayload` is fine for outgoing webhook shapes (matches the "Preview payload" UI terminology).
## Hooks & Context
- Custom hooks in `frontend/hooks/` — e.g., `useTeamIdParam`, `useCheckboxListStateManagement`
+22 -5
View File
@@ -94,22 +94,39 @@ const functionWithTableName = (tableName: string)=> {
```typescript
// API interfaces should live in the relevant entities file.
// Their names should be named to clarify what they are used for when interacting
// with the API
// Their names should clarify what they are used for when interacting with the
// API. In service functions, prefer `formData` as the variable name for request
// bodies to stay consistent with the *FormData interface naming convention.
// should be defined in service/entities/hosts.ts
interface IHostDetailsReponse {
interface IHostDetailsResponse {
...
}
interface IGetHostsQueryParams {
...
}
// should be defined in service/entities/fleets.ts
interface ICreateFleetPostBody {
// should be defined in service/entities/users.ts
interface IUpdateUserFormData {
...
}
// should be defined in service/entities/software.ts
interface IGetSoftwareApiParams {
...
}
interface ISoftwareCountResponse {
...
}
// Use *FormData for form-driven bodies, *ApiParams/*QueryParams for request
// params, *Response for responses, *QueryKey when typing a React Query key.
// Avoid *Body, *PostBody, *Payload, *Request for API request bodies — use
// *FormData instead, even for programmatic request bodies (e.g.
// IDeleteQueriesFormData). One consistent suffix is easier to follow than
// asking each dev to judge "is this form-driven enough?"
// *PreviewPayload is fine for outgoing webhook shapes (matches the
// "Preview payload" UI terminology).
```
## Utilities
+1 -1
View File
@@ -257,7 +257,7 @@ export type RecoveryLockPasswordStatus =
| "removing_enforcement"
| "failed";
export interface IMdmSSOReponse {
export interface IMdmSSOResponse {
url: string;
}
-8
View File
@@ -2,14 +2,6 @@ import { IFormField } from "./form_field";
import { IPack } from "./pack";
import { ISchedulableQuery, ISchedulableQueryStats } from "./schedulable_query";
export interface IEditQueryFormData {
description?: string | number | boolean | undefined;
name?: string | number | boolean | undefined;
query?: string | number | boolean | undefined;
observer_can_run?: string | number | boolean | undefined;
automations_enabled?: boolean;
}
export interface IStoredQueryResponse {
query: ISchedulableQuery;
}
+6 -6
View File
@@ -103,7 +103,7 @@ export interface IQueryKeyQueriesLoadAll {
}
// Create a new query
/** POST /api/v1/fleet/queries */
export interface ICreateQueryRequestBody {
export interface ICreateQueryFormData {
name: string;
query: string;
description?: string;
@@ -121,10 +121,10 @@ export interface ICreateQueryRequestBody {
// response is ISchedulableQuery
// Modify a query by id
// Edit a query by id
/** PATCH /api/v1/fleet/queries/{id} */
export interface IModifyQueryRequestBody
extends Omit<ICreateQueryRequestBody, "name" | "query" | "fleet_id"> {
export interface IEditQueryFormData
extends Omit<ICreateQueryFormData, "name" | "query" | "fleet_id"> {
id?: number;
name?: string;
query?: string;
@@ -141,7 +141,7 @@ export interface IModifyQueryRequestBody
// Delete a query by name
/** DELETE /api/v1/fleet/queries/{name} */
export interface IDeleteQueryRequestBody {
export interface IDeleteQueryFormData {
fleet_id?: number; // searches for a global query if omitted
}
@@ -151,7 +151,7 @@ export interface IDeleteQueryRequestBody {
// Delete queries by id
/** POST /api/v1/fleet/queries/delete */
export interface IDeleteQueriesRequestBody {
export interface IDeleteQueriesFormData {
ids: number[];
}
+4 -4
View File
@@ -114,10 +114,10 @@ export interface INewTeamUser {
/**
* The shape of the body expected from the API when adding new users to teams
*/
export interface INewTeamUsersBody {
export interface INewTeamUsersFormData {
users: INewTeamUser[];
}
export interface IRemoveTeamUserBody {
export interface IRemoveTeamUserFormData {
users: { id?: number }[];
}
interface INewTeamSecret {
@@ -125,10 +125,10 @@ interface INewTeamSecret {
secret: string;
created_at?: string;
}
export interface INewTeamSecretBody {
export interface INewTeamSecretFormData {
secrets: INewTeamSecret[];
}
export interface IRemoveTeamSecretBody {
export interface IRemoveTeamSecretFormData {
secrets: { secret: string }[];
}
+1 -1
View File
@@ -66,7 +66,7 @@ export interface IUser {
/**
* The shape of the request body when updating a user.
*/
export interface IUserUpdateBody {
export interface IUserUpdateFormData {
global_role?: UserRole | null;
teams?: ITeam[];
name: string;
+1 -1
View File
@@ -5,7 +5,7 @@ export interface IVariable {
updated_at: string;
}
export interface IVariablePayload {
export interface IVariableFormData {
name: string;
value: string;
}
+1 -1
View File
@@ -9,7 +9,7 @@ export default PropTypes.shape({
build_user: PropTypes.string,
});
export interface IVersionData {
export interface IVersionResponse {
version: string;
branch: string;
revision: string;
@@ -1,7 +1,7 @@
import React, { useContext, useEffect, useState } from "react";
import { IUser } from "interfaces/user";
import { IVersionData } from "interfaces/version";
import { IVersionResponse } from "interfaces/version";
import { AppContext } from "context/app";
@@ -31,7 +31,7 @@ const AccountSidePanel = ({
onGetApiToken,
}: IAccountSidePanelProps): JSX.Element => {
const { isPremiumTier, config } = useContext(AppContext);
const [versionData, setVersionData] = useState<IVersionData>();
const [versionData, setVersionData] = useState<IVersionResponse>();
const [themeMode, setThemeModeState] = useState<ThemeMode>(() =>
getThemeMode()
);
@@ -7,7 +7,7 @@ import { NotificationContext } from "context/notification";
import { ICreateUserWithInvitationFormData } from "interfaces/user";
import paths from "router/paths";
import usersAPI from "services/entities/users";
import inviteAPI, { IValidateInviteResp } from "services/entities/invites";
import inviteAPI, { IValidateInviteResponse } from "services/entities/invites";
import AuthenticationFormWrapper from "components/AuthenticationFormWrapper";
import Spinner from "components/Spinner";
@@ -36,12 +36,12 @@ const ConfirmInvitePage = ({ router, params }: IConfirmInvitePageProps) => {
data: validInvite,
error: validateInviteError,
isLoading: isVerifyingInvite,
} = useQuery<IValidateInviteResp, AxiosError, IInvite>(
} = useQuery<IValidateInviteResponse, AxiosError, IInvite>(
"invite",
() => inviteAPI.verify(invite_token),
{
...DEFAULT_USE_QUERY_OPTIONS,
select: (resp: IValidateInviteResp) => resp.invite,
select: (resp: IValidateInviteResponse) => resp.invite,
}
);
@@ -9,7 +9,7 @@ import { AppContext } from "context/app";
import { NotificationContext } from "context/notification";
import usersAPI from "services/entities/users";
import sessionsAPI from "services/entities/sessions";
import inviteAPI, { IValidateInviteResp } from "services/entities/invites";
import inviteAPI, { IValidateInviteResponse } from "services/entities/invites";
import { IInvite } from "interfaces/invite";
import { getErrorReason } from "interfaces/errors";
import { DEFAULT_USE_QUERY_OPTIONS } from "utilities/constants";
@@ -43,12 +43,12 @@ const ConfirmSSOInvitePage = ({
data: validInvite,
error: validateInviteError,
isLoading: isVerifyingInvite,
} = useQuery<IValidateInviteResp, AxiosError, IInvite>(
} = useQuery<IValidateInviteResponse, AxiosError, IInvite>(
["invite", invite_token],
() => inviteAPI.verify(invite_token),
{
...DEFAULT_USE_QUERY_OPTIONS,
select: (resp: IValidateInviteResp) => resp.invite,
select: (resp: IValidateInviteResponse) => resp.invite,
}
);
@@ -5,7 +5,7 @@ import { SingleValue } from "react-select-5";
import chartsAPI, {
IChartResponse,
IChartRequestParams,
IChartApiParams,
IChartQueryKey,
} from "services/entities/charts";
import { DEFAULT_USE_QUERY_OPTIONS } from "utilities/constants";
@@ -150,7 +150,7 @@ const ChartCard = ({
? true
: historicalDataEnabled?.[datasetConfigKey] ?? true;
const queryParams: IChartRequestParams = useMemo(() => {
const queryParams: IChartApiParams = useMemo(() => {
return {
// Add an extra day to ensure we get the full # of calendar days
// represented in the chart, regardless of timezone.
@@ -9,7 +9,7 @@ import SSOError from "components/MDM/SSOError";
import Spinner from "components/Spinner/Spinner";
import Button from "components/buttons/Button";
import CustomLink from "components/CustomLink";
import { IMdmSSOReponse } from "interfaces/mdm";
import { IMdmSSOResponse } from "interfaces/mdm";
import AuthenticationFormWrapper from "components/AuthenticationFormWrapper";
const baseClass = "mdm-apple-sso-page";
@@ -25,7 +25,7 @@ const DEPSSOLoginPage = ({
? "account_driven_enroll"
: "mdm_sso";
}
const { error } = useQuery<IMdmSSOReponse, AxiosError>(
const { error } = useQuery<IMdmSSOResponse, AxiosError>(
["dep_sso"],
() => mdmAPI.initiateMDMAppleSSO(query),
{
@@ -1,7 +1,7 @@
import React, { useContext, useState } from "react";
import Modal from "components/Modal";
import Button from "components/buttons/Button";
import { IVariablePayload } from "interfaces/variables";
import { IVariableFormData } from "interfaces/variables";
import { hasStatusKey } from "interfaces/errors";
import variablesAPI from "services/entities/variables";
import { NotificationContext } from "context/notification";
@@ -59,7 +59,7 @@ const AddCustomVariableModal = ({
const validation = validateFormData({ name, value }, true);
if (validation.isValid) {
setIsSaving(true);
const newVariable: IVariablePayload = {
const newVariable: IVariableFormData = {
name: variableName,
value: variableValue,
};
@@ -1,6 +1,6 @@
import React from "react";
import { IAddCertAuthorityBody } from "services/entities/certificates";
import { IAddCertAuthorityFormData } from "services/entities/certificates";
import { ICertificateAuthorityType } from "interfaces/certificates";
import { LEARN_MORE_ABOUT_BASE_LINK } from "utilities/constants";
import { IDropdownOption } from "interfaces/dropdownOption";
@@ -68,7 +68,7 @@ export const generateDropdownOptions = (hasNDESCert: boolean) => {
export const generateAddCertAuthorityData = (
certAuthorityType: ICertificateAuthorityType,
formData: ICertFormData
): IAddCertAuthorityBody | undefined => {
): IAddCertAuthorityFormData | undefined => {
switch (certAuthorityType) {
case "ndes_scep_proxy": {
const {
@@ -1,6 +1,6 @@
import React from "react";
import { IEditCertAuthorityBody } from "services/entities/certificates";
import { IEditCertAuthorityFormData } from "services/entities/certificates";
import {
ICertificateAuthority,
ICertificatesCustomSCEP,
@@ -79,7 +79,7 @@ export const generateDefaultFormData = (
export const generateEditCertAuthorityData = (
certAuthority: ICertificateAuthority,
formData: ICertFormData
): IEditCertAuthorityBody => {
): IEditCertAuthorityFormData => {
const certAuthWithoutType = Object.assign({}, certAuthority);
delete certAuthWithoutType.type;
delete certAuthWithoutType.id;
@@ -5,7 +5,7 @@ import { AppContext } from "context/app";
import { NotificationContext } from "context/notification";
import useTeamIdParam from "hooks/useTeamIdParam";
import { IApiError } from "interfaces/errors";
import { INewTeamUsersBody, ITeam } from "interfaces/team";
import { INewTeamUsersFormData, ITeam } from "interfaces/team";
import { IUpdateUserFormData, IUser, IUserFormErrors } from "interfaces/user";
import { ITeamSubnavProps } from "interfaces/team_subnav";
import PATHS from "router/paths";
@@ -172,7 +172,7 @@ const UsersPage = ({ location, router }: ITeamSubnavProps): JSX.Element => {
]);
const onAddUserSubmit = useCallback(
(newUsers: INewTeamUsersBody) => {
(newUsers: INewTeamUsersFormData) => {
teamsAPI
.addUsers(currentTeamDetails?.id, newUsers)
.then(() => {
@@ -1,6 +1,6 @@
import React, { useCallback, useState } from "react";
import { INewTeamUser, INewTeamUsersBody, ITeam } from "interfaces/team";
import { INewTeamUser, INewTeamUsersFormData, ITeam } from "interfaces/team";
import endpoints from "utilities/endpoints";
import Modal from "components/Modal";
import Button from "components/buttons/Button";
@@ -13,7 +13,7 @@ interface IAddUsersModal {
team: ITeam;
disabledUsers: number[];
onCancel: () => void;
onSubmit: (userIds: INewTeamUsersBody) => void;
onSubmit: (userIds: INewTeamUsersFormData) => void;
onCreateNewTeamUser: () => void;
}
@@ -1,6 +1,6 @@
import { userTeamStub } from "test/stubs";
import createMockUser from "__mocks__/userMock";
import { IUserUpdateBody } from "interfaces/user";
import { IUserUpdateFormData } from "interfaces/user";
import { IUserFormData, NewUserType } from "../components/UserForm/UserForm";
import userManagementHelpers from "./userManagementHelpers";
@@ -8,11 +8,11 @@ import userManagementHelpers from "./userManagementHelpers";
describe("userManagementHelpers module", () => {
describe("generateUpdatedData function", () => {
it("returns an object with only the difference between the two", () => {
const updatedTeam: IUserUpdateBody = {
const updatedTeam: IUserUpdateFormData = {
...userTeamStub,
role: "maintainer",
};
const newTeam: IUserUpdateBody = {
const newTeam: IUserUpdateFormData = {
...userTeamStub,
id: 2,
role: "observer",
@@ -24,7 +24,7 @@ import scriptsAPI, {
IListScriptsQueryKey,
IScriptBatchSupportedFilters,
IScriptsResponse,
IRunScriptBatchRequest,
IRunScriptBatchFormData,
} from "services/entities/scripts";
import ScriptDetailsModal from "pages/hosts/components/ScriptDetailsModal";
import Spinner from "components/Spinner";
@@ -150,7 +150,7 @@ const RunScriptBatchModal = ({
setIsUpdating(true);
// Create the base request.
let body: IRunScriptBatchRequest;
let body: IRunScriptBatchFormData;
if (runByFilters) {
body = {
@@ -11,7 +11,7 @@ import { NotificationContext } from "context/notification";
import classNames from "classnames";
import deviceUserAPI, {
IGetDeviceCertsRequestParams,
IGetDeviceCertsApiParams,
IGetDeviceCertificatesResponse,
IGetSetupExperienceStatusesResponse,
} from "services/entities/device_user";
@@ -199,7 +199,7 @@ const DeviceUserPage = ({
IGetDeviceCertificatesResponse,
Error,
IGetDeviceCertificatesResponse,
Array<IGetDeviceCertsRequestParams & { scope: "device-certificates" }>
Array<IGetDeviceCertsApiParams & { scope: "device-certificates" }>
>(
[
{
@@ -16,7 +16,7 @@ import activitiesAPI, {
} from "services/entities/activities";
import hostAPI, {
IGetHostCertificatesResponse,
IGetHostCertsRequestParams,
IGetHostCertsApiParams,
} from "services/entities/hosts";
import teamAPI, { ILoadTeamsResponse } from "services/entities/teams";
import commandAPI from "services/entities/command";
@@ -353,7 +353,7 @@ const HostDetailsPage = ({
IGetHostCertificatesResponse,
Error,
IGetHostCertificatesResponse,
Array<IGetHostCertsRequestParams & { scope: "host-certificates" }>
Array<IGetHostCertsApiParams & { scope: "host-certificates" }>
>(
[
{
+30 -32
View File
@@ -24,7 +24,7 @@ import queryAPI from "services/entities/queries";
import statusAPI from "services/entities/status";
import {
IGetQueryResponse,
ICreateQueryRequestBody,
ICreateQueryFormData,
ISchedulableQuery,
} from "interfaces/schedulable_query";
import { IConfig } from "interfaces/config";
@@ -259,42 +259,40 @@ const EditQueryPage = ({
setShowOpenSchemaActionText(!isSidebarOpen);
}, [isSidebarOpen]);
const onSubmitNewQuery = debounce(
async (formData: ICreateQueryRequestBody) => {
setIsQuerySaving(true);
try {
const { query } = await queryAPI.create(formData);
router.push(
getPathWithQueryParams(PATHS.REPORT_DETAILS(query.id), {
fleet_id: query.team_id,
host_id: hostId,
})
const onSubmitNewQuery = debounce(async (formData: ICreateQueryFormData) => {
setIsQuerySaving(true);
try {
const { query } = await queryAPI.create(formData);
router.push(
getPathWithQueryParams(PATHS.REPORT_DETAILS(query.id), {
fleet_id: query.team_id,
host_id: hostId,
})
);
renderFlash("success", "Report created.");
setBackendValidators({});
} catch (createError) {
if (getErrorReason(createError).includes("already exists")) {
const teamErrorText =
teamNameForQuery && apiTeamIdForQuery !== 0
? `the ${teamNameForQuery} fleet`
: "all fleets";
setBackendValidators({
name: `A report with that name already exists for ${teamErrorText}.`,
});
} else {
renderFlash(
"error",
"Something went wrong creating your report. Please try again."
);
renderFlash("success", "Report created.");
setBackendValidators({});
} catch (createError) {
if (getErrorReason(createError).includes("already exists")) {
const teamErrorText =
teamNameForQuery && apiTeamIdForQuery !== 0
? `the ${teamNameForQuery} fleet`
: "all fleets";
setBackendValidators({
name: `A report with that name already exists for ${teamErrorText}.`,
});
} else {
renderFlash(
"error",
"Something went wrong creating your report. Please try again."
);
setBackendValidators({});
}
} finally {
setIsQuerySaving(false);
}
} finally {
setIsQuerySaving(false);
}
);
});
const onUpdateQuery = async (formData: ICreateQueryRequestBody) => {
const onUpdateQuery = async (formData: ICreateQueryFormData) => {
if (!queryId) {
return false;
}
@@ -33,7 +33,7 @@ import usePlatformSelector from "hooks/usePlatformSelector";
import {
ISchedulableQuery,
ICreateQueryRequestBody,
ICreateQueryFormData,
QueryLoggingOption,
} from "interfaces/schedulable_query";
import { CommaSeparatedPlatformString } from "interfaces/platform";
@@ -88,9 +88,9 @@ interface IEditQueryFormProps {
isStoredQueryLoading: boolean;
isQuerySaving: boolean;
isQueryUpdating: boolean;
onSubmitNewQuery: (formData: ICreateQueryRequestBody) => void;
onSubmitNewQuery: (formData: ICreateQueryFormData) => void;
onOsqueryTableSelect: (tableName: string) => void;
onUpdate: (formData: ICreateQueryRequestBody) => void;
onUpdate: (formData: ICreateQueryFormData) => void;
onOpenSchemaSidebar: () => void;
renderLiveQueryWarning: () => JSX.Element | null;
backendValidators: { [key: string]: string };
@@ -7,7 +7,7 @@ import PATHS from "router/paths";
import { getPathWithQueryParams } from "utilities/url";
import { ICreateQueryRequestBody } from "interfaces/schedulable_query";
import { ICreateQueryFormData } from "interfaces/schedulable_query";
import queryAPI from "services/entities/queries";
import { NotificationContext } from "context/notification";
@@ -33,7 +33,7 @@ const baseClass = "save-as-new-query-modal";
interface ISaveAsNewQueryModal {
router: InjectedRouter;
location: Location;
initialQueryData: ICreateQueryRequestBody;
initialQueryData: ICreateQueryFormData;
hostId?: number;
onExit: () => void;
}
@@ -22,7 +22,7 @@ import {
import { CommaSeparatedPlatformString } from "interfaces/platform";
import {
ICreateQueryRequestBody,
ICreateQueryFormData,
ISchedulableQuery,
QueryLoggingOption,
} from "interfaces/schedulable_query";
@@ -51,7 +51,7 @@ export interface ISaveNewQueryModalProps {
queryValue: string;
apiTeamIdForQuery?: number; // query will be global if omitted
isLoading: boolean;
saveQuery: (formData: ICreateQueryRequestBody) => void;
saveQuery: (formData: ICreateQueryFormData) => void;
toggleSaveNewQueryModal: () => void;
backendValidators: { [key: string]: string };
existingQuery?: ISchedulableQuery;
+4 -4
View File
@@ -29,7 +29,7 @@ interface IRequestCertAuthorityResponse {
certificate: string;
}
export type IAddCertAuthorityBody =
export type IAddCertAuthorityFormData =
| { digicert: ICertificatesDigicert }
| { ndes_scep_proxy: ICertificatesNDES }
| { custom_scep_proxy: ICertificatesCustomSCEP }
@@ -37,7 +37,7 @@ export type IAddCertAuthorityBody =
| { smallstep: ICertificatesSmallstep }
| { custom_est_proxy: ICertificatesCustomEST };
export type IEditCertAuthorityBody =
export type IEditCertAuthorityFormData =
| { digicert: Partial<ICertificatesDigicert> }
| { ndes_scep_proxy: Partial<ICertificatesNDES> }
| { custom_scep_proxy: Partial<ICertificatesCustomSCEP> }
@@ -86,7 +86,7 @@ export default {
},
addCertificateAuthority: (
certData: IAddCertAuthorityBody
certData: IAddCertAuthorityFormData
): Promise<IAddCertAuthorityResponse> => {
const { CERTIFICATE_AUTHORITIES } = endpoints;
return sendRequest("POST", CERTIFICATE_AUTHORITIES, certData);
@@ -94,7 +94,7 @@ export default {
editCertificateAuthority: (
id: number,
updateData: IEditCertAuthorityBody
updateData: IEditCertAuthorityFormData
): Promise<void> => {
const { CERTIFICATE_AUTHORITY } = endpoints;
return sendRequest("PATCH", CERTIFICATE_AUTHORITY(id), updateData);
+3 -3
View File
@@ -24,7 +24,7 @@ export interface IChartResponse {
data: IChartDataPoint[];
}
export interface IChartRequestParams {
export interface IChartApiParams {
days?: number;
resolution?: number;
tz_offset?: number;
@@ -38,11 +38,11 @@ export interface IChartRequestParams {
export interface IChartQueryKey {
scope: "chart";
metric: string;
params: IChartRequestParams;
params: IChartApiParams;
}
export default {
getChartData: (metric: string, params: IChartRequestParams = {}) => {
getChartData: (metric: string, params: IChartApiParams = {}) => {
const queryString = buildQueryStringFromParams(params);
const endpoint = endpoints.CHART_DATA(metric);
const path = queryString ? `${endpoint}?${queryString}` : endpoint;
+2 -2
View File
@@ -5,7 +5,7 @@ import { getPathWithQueryParams } from "utilities/url";
import { PaginationParams } from "./common";
export interface IGetCommandsRequest extends PaginationParams {
export interface IGetCommandsApiParams extends PaginationParams {
order_key?: string;
order_direction?: "asc" | "desc";
host_identifier?: string;
@@ -41,7 +41,7 @@ export interface IGetHostCommandResultsQueryKey
export default {
getCommands: (
requestParams: IGetCommandsRequest
requestParams: IGetCommandsApiParams
): Promise<IGetCommandsResponse> => {
const { COMMANDS } = endpoints;
const url = getPathWithQueryParams(COMMANDS, requestParams);
+4 -4
View File
@@ -31,7 +31,7 @@ export interface IGetDeviceSoftwareResponse {
};
}
interface IGetDeviceDetailsRequest {
interface IGetDeviceDetailsApiParams {
token: string;
exclude_software?: boolean;
}
@@ -45,7 +45,7 @@ export interface IGetDeviceCertificatesResponse {
count: number;
}
export interface IGetDeviceCertsRequestParams extends IListOptions {
export interface IGetDeviceCertsApiParams extends IListOptions {
token: string;
}
@@ -67,7 +67,7 @@ export default {
loadHostDetails: ({
token,
exclude_software,
}: IGetDeviceDetailsRequest): Promise<IDUPDetails> => {
}: IGetDeviceDetailsApiParams): Promise<IDUPDetails> => {
const { DEVICE_USER_DETAILS } = endpoints;
let path = `${DEVICE_USER_DETAILS}/${token}`;
if (exclude_software) {
@@ -165,7 +165,7 @@ export default {
per_page,
order_key,
order_direction,
}: IGetDeviceCertsRequestParams): Promise<IGetDeviceCertificatesResponse> => {
}: IGetDeviceCertsApiParams): Promise<IGetDeviceCertificatesResponse> => {
const { DEVICE_CERTIFICATES } = endpoints;
const path = `${DEVICE_CERTIFICATES(token)}?${buildQueryStringFromParams({
page,
+2 -2
View File
@@ -252,7 +252,7 @@ export interface IHostSoftwareQueryKey extends IHostSoftwareQueryParams {
softwareUpdatedAt?: string;
}
export interface IGetHostCertsRequestParams extends IListOptions {
export interface IGetHostCertsApiParams extends IListOptions {
host_id: number;
}
@@ -762,7 +762,7 @@ export default {
per_page,
order_key,
order_direction,
}: IGetHostCertsRequestParams): Promise<IGetHostCertificatesResponse> => {
}: IGetHostCertsApiParams): Promise<IGetHostCertificatesResponse> => {
const { HOST_CERTIFICATES } = endpoints;
const path = `${HOST_CERTIFICATES(host_id)}?${buildQueryStringFromParams({
page,
+2 -2
View File
@@ -3,7 +3,7 @@ import { IInstallerType } from "interfaces/installer";
import sendRequest from "services";
import ENDPOINTS from "utilities/endpoints";
export interface ICheckInstallerExistenceRequestParams {
export interface ICheckInstallerExistenceApiParams {
enrollSecret: string;
includeDesktop: boolean;
installerType: IInstallerType;
@@ -14,7 +14,7 @@ export default {
enrollSecret,
includeDesktop,
installerType,
}: ICheckInstallerExistenceRequestParams): Promise<BlobPart> => {
}: ICheckInstallerExistenceApiParams): Promise<BlobPart> => {
const path = `${
ENDPOINTS.DOWNLOAD_INSTALLER
}/${installerType}?desktop=${includeDesktop}&enroll_secret=${encodeURIComponent(
+2 -2
View File
@@ -22,7 +22,7 @@ interface IInviteSearchOptions {
sortBy?: ISortOption[];
}
export interface IValidateInviteResp {
export interface IValidateInviteResponse {
invite: IInvite;
}
@@ -46,7 +46,7 @@ export default {
return sendRequest("DELETE", path);
},
verify: (token: string): Promise<IValidateInviteResp> => {
verify: (token: string): Promise<IValidateInviteResponse> => {
return sendRequest("GET", endpoints.INVITE_VERIFY(token));
},
loadAll: ({ globalFilter = "" }: IInviteSearchOptions) => {
+7 -5
View File
@@ -3,7 +3,7 @@ import {
IBootstrapPackageMetadata,
IHostMdmProfile,
IMdmProfile,
IMdmSSOReponse,
IMdmSSOResponse,
MdmProfileStatus,
} from "interfaces/mdm";
import { API_NO_TEAM_ID } from "interfaces/team";
@@ -51,7 +51,7 @@ export const isDDMProfile = (profile: IMdmProfile | IHostMdmProfile) => {
return profile.profile_uuid.startsWith("d");
};
interface IUpdateSetupExperienceBody {
interface IUpdateSetupExperienceFormData {
fleet_id?: number;
enable_end_user_authentication?: boolean;
lock_end_user_info?: boolean;
@@ -193,7 +193,7 @@ const mdmService = {
return sendRequest("GET", path);
},
initiateMDMAppleSSO: (params: IMDMSSOParams): Promise<IMdmSSOReponse> => {
initiateMDMAppleSSO: (params: IMDMSSOParams): Promise<IMdmSSOResponse> => {
const { MDM_APPLE_SSO } = endpoints;
return sendRequest("POST", MDM_APPLE_SSO, params);
},
@@ -276,7 +276,9 @@ const mdmService = {
});
},
updateSetupExperienceSettings: (updateData: IUpdateSetupExperienceBody) => {
updateSetupExperienceSettings: (
updateData: IUpdateSetupExperienceFormData
) => {
const { MDM_SETUP_EXPERIENCE } = endpoints;
const body = {
...updateData,
@@ -292,7 +294,7 @@ const mdmService = {
updateReleaseDeviceSetting: (teamId: number, isEnabled: boolean) => {
const { MDM_SETUP_EXPERIENCE } = endpoints;
const body: IUpdateSetupExperienceBody = {
const body: IUpdateSetupExperienceFormData = {
fleet_id: teamId,
apple_enable_release_device_manually: isEnabled,
};
+3 -3
View File
@@ -27,11 +27,11 @@ export interface IGetVppTokensResponse {
vpp_tokens: IMdmVppToken[];
}
export interface IUploadVppTokenReponse {
export interface IUploadVppTokenResponse {
vpp_token: IMdmVppToken;
}
export type IRenewVppTokenResponse = IUploadVppTokenReponse;
export type IRenewVppTokenResponse = IUploadVppTokenResponse;
export default {
getAppleAPNInfo: () => {
@@ -73,7 +73,7 @@ export default {
return sendRequest("GET", MDM_VPP_TOKENS);
},
uploadVppToken: (token: File): Promise<IUploadVppTokenReponse> => {
uploadVppToken: (token: File): Promise<IUploadVppTokenResponse> => {
const { MDM_VPP_TOKENS } = endpoints;
const formData = new FormData();
formData.append("token", token);
+4 -4
View File
@@ -4,8 +4,8 @@ import endpoints from "utilities/endpoints";
import { getErrorReason } from "interfaces/errors";
import { ISelectedTargetsForApi } from "interfaces/target";
import {
ICreateQueryRequestBody,
IModifyQueryRequestBody,
ICreateQueryFormData,
IEditQueryFormData,
IQueryKeyQueriesLoadAll,
ISchedulableQuery,
} from "interfaces/schedulable_query";
@@ -44,7 +44,7 @@ export interface IQueriesResponse {
export default {
create: (
createQueryRequestBody: ICreateQueryRequestBody
createQueryRequestBody: ICreateQueryFormData
): Promise<ICreateQueryResponse> => {
const { QUERIES } = endpoints;
if (createQueryRequestBody.name) {
@@ -135,7 +135,7 @@ export default {
);
}
},
update: (id: number, updateParams: IModifyQueryRequestBody) => {
update: (id: number, updateParams: IEditQueryFormData) => {
const { QUERIES } = endpoints;
const path = `${QUERIES}/${id}`;
if (updateParams.name) {
+10 -10
View File
@@ -55,13 +55,13 @@ export interface IScriptResultResponse {
/**
* Request params for for GET /hosts/:id/scripts
*/
export interface IHostScriptsRequestParams {
export interface IHostScriptsApiParams {
host_id: number;
page?: number;
per_page?: number;
}
export interface IHostScriptsQueryKey extends IHostScriptsRequestParams {
export interface IHostScriptsQueryKey extends IHostScriptsApiParams {
scope: "host_scripts";
}
@@ -81,7 +81,7 @@ export interface IHostScriptsResponse {
*
* https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/api-for-contributors.md#run-script-asynchronously
*/
export interface IScriptRunRequest {
export interface IScriptRunFormData {
host_id: number;
script_id: number; // script_id is not required by the API currently, but we require it here to ensure it is always provided
// script_contents: string; // script_contents is only supported for the CLI currently
@@ -104,22 +104,22 @@ export interface IScriptBatchSupportedFilters {
team_id?: number;
status?: string; // TODO: More defined typing
}
interface IRunScriptBatchRequestBase {
interface IRunScriptBatchFormDataBase {
script_id: number;
not_before?: string; // ISO 8601 date-time string
}
interface IByFilters extends IRunScriptBatchRequestBase {
interface IByFilters extends IRunScriptBatchFormDataBase {
host_ids?: never;
filters: IScriptBatchSupportedFilters;
}
interface IByHostIds extends IRunScriptBatchRequestBase {
interface IByHostIds extends IRunScriptBatchFormDataBase {
host_ids: number[];
filters?: never;
}
/** Request body for POST /scripts/run/batch */
export type IRunScriptBatchRequest = IByFilters | IByHostIds;
export type IRunScriptBatchFormData = IByFilters | IByHostIds;
/** 202 successful response body for POST /scripts/run/batch */
export interface IRunScriptBatchResponse {
@@ -222,7 +222,7 @@ export interface IScriptBatchHostResultsResponse
}
export default {
getHostScripts({ host_id, page, per_page }: IHostScriptsRequestParams) {
getHostScripts({ host_id, page, per_page }: IHostScriptsApiParams) {
const { HOST_SCRIPTS } = endpoints;
const path = `${HOST_SCRIPTS(host_id)}?${buildQueryStringFromParams({
page,
@@ -286,12 +286,12 @@ export default {
return sendRequest("GET", SCRIPT_RESULT(executionId));
},
runScript(request: IScriptRunRequest): Promise<IScriptRunResponse> {
runScript(request: IScriptRunFormData): Promise<IScriptRunResponse> {
const { SCRIPT_RUN } = endpoints;
return sendRequest("POST", SCRIPT_RUN, request);
},
runScriptBatch(
request: IRunScriptBatchRequest
request: IRunScriptBatchFormData
): Promise<IRunScriptBatchResponse> {
const { SCRIPT_RUN_BATCH } = endpoints;
return sendRequest("POST", SCRIPT_RUN_BATCH, request);
+11 -11
View File
@@ -148,7 +148,7 @@ export interface IFleetMaintainedAppResponse {
fleet_maintained_app: IFleetMaintainedAppDetails;
}
interface IAddFleetMaintainedAppPostBody {
interface IAddFleetMaintainedAppFormData {
fleet_id: number;
fleet_maintained_app_id: number;
pre_install_query?: string;
@@ -163,7 +163,7 @@ interface IAddFleetMaintainedAppPostBody {
categories: string[];
}
export interface IAddAppStoreAppPostBody {
export interface IAddAppStoreAppFormData {
app_store_id: string;
fleet_id: number;
platform: ApplePlatform | "android";
@@ -178,7 +178,7 @@ export interface IAddAppStoreAppPostBody {
}
// 4.77 Edit for Android app is not yet available
export interface IEditAppStoreAppPostBody {
export interface IEditAppStoreAppFormData {
fleet_id: number;
self_service?: boolean;
// No automatic_install on edit VPP or android app
@@ -202,7 +202,7 @@ const handleAndroidForm = (
) => {
const { SOFTWARE_APP_STORE_APPS } = endpoints;
const body: IAddAppStoreAppPostBody = {
const body: IAddAppStoreAppFormData = {
app_store_id: formData.applicationID,
fleet_id: teamId,
platform: formData.platform,
@@ -235,7 +235,7 @@ const handleVppAppForm = (teamId: number, formData: ISoftwareVppFormData) => {
throw new Error("Selected app is required. This should not happen.");
}
const body: IAddAppStoreAppPostBody = {
const body: IAddAppStoreAppFormData = {
app_store_id: formData.selectedApp.app_store_id,
fleet_id: teamId,
platform: formData.selectedApp?.platform, // Nested platform
@@ -328,14 +328,14 @@ const handleEditPackageForm = (
const handleDisplayNameAppStoreAppForm = (
formData: ISoftwareDisplayNameFormData,
body: IEditAppStoreAppPostBody
body: IEditAppStoreAppFormData
) => {
body.display_name = formData.displayName || "";
};
const handleConfigurationAppStoreAppForm = (
formData: ISoftwareConfigurationFormData,
body: IEditAppStoreAppPostBody
body: IEditAppStoreAppFormData
) => {
// Use ?? to preserve empty strings (iOS/iPadOS clears config with "")
body.configuration = formData.configuration ?? "{}";
@@ -343,7 +343,7 @@ const handleConfigurationAppStoreAppForm = (
const handleAutoUpdateConfigAppStoreAppForm = (
formData: ISoftwareAutoUpdateConfigFormData,
body: IEditAppStoreAppPostBody
body: IEditAppStoreAppFormData
) => {
body.auto_update_enabled = formData.autoUpdateEnabled;
if (formData.autoUpdateEnabled) {
@@ -368,7 +368,7 @@ const handleAutoUpdateConfigAppStoreAppForm = (
const handleEditAppStoreAppForm = (
formData: ISoftwareVppFormData,
body: IEditAppStoreAppPostBody
body: IEditAppStoreAppFormData
) => {
body.self_service = formData.selfService;
@@ -668,7 +668,7 @@ export default {
) => {
const { EDIT_SOFTWARE_APP_STORE_APP } = endpoints;
const body: IEditAppStoreAppPostBody = { fleet_id: teamId };
const body: IEditAppStoreAppFormData = { fleet_id: teamId };
if ("displayName" in formData) {
// Handles Edit display name form only
@@ -802,7 +802,7 @@ export default {
const { SOFTWARE_FLEET_MAINTAINED_APPS } = endpoints;
// Base64 encode script fields to bypass WAF rules that block script patterns
const body: IAddFleetMaintainedAppPostBody = {
const body: IAddFleetMaintainedAppFormData = {
fleet_id: teamId,
fleet_maintained_app_id: formData.appId,
pre_install_query: encodeScriptBase64(formData.preInstallQuery),
+4 -4
View File
@@ -8,8 +8,8 @@ import { IEnrollSecret } from "interfaces/enroll_secret";
import { ITeamIntegrations } from "interfaces/integration";
import {
API_NO_TEAM_ID,
INewTeamUsersBody,
IRemoveTeamUserBody,
INewTeamUsersFormData,
IRemoveTeamUserFormData,
ITeamConfig,
ITeamWebhookSettings,
} from "interfaces/team";
@@ -179,7 +179,7 @@ export default {
return sendRequest("PATCH", path, data);
},
addUsers: (teamId: number | undefined, newUsers: INewTeamUsersBody) => {
addUsers: (teamId: number | undefined, newUsers: INewTeamUsersFormData) => {
if (!teamId || teamId <= API_NO_TEAM_ID) {
return Promise.reject(
new Error(
@@ -194,7 +194,7 @@ export default {
},
removeUsers: (
teamId: number | undefined,
removeUsers: IRemoveTeamUserBody
removeUsers: IRemoveTeamUserFormData
) => {
if (!teamId || teamId <= API_NO_TEAM_ID) {
return Promise.reject(
+4 -4
View File
@@ -1,9 +1,9 @@
import { IVariable, IVariablePayload } from "interfaces/variables";
import { IVariable, IVariableFormData } from "interfaces/variables";
import sendRequest from "services";
import { buildQueryStringFromParams } from "utilities/url";
import endpoints from "utilities/endpoints";
export interface IListVariablesRequestApiParams {
export interface IListVariablesApiParams {
page?: number;
per_page?: number;
}
@@ -19,7 +19,7 @@ export interface IListVariablesResponse {
export default {
getVariables(
params: IListVariablesRequestApiParams
params: IListVariablesApiParams
): Promise<IListVariablesResponse> {
const { VARIABLES } = endpoints;
const path = `${VARIABLES}?${buildQueryStringFromParams({
@@ -30,7 +30,7 @@ export default {
return sendRequest("GET", path);
},
addVariable(variable: IVariablePayload) {
addVariable(variable: IVariableFormData) {
const { VARIABLES } = endpoints;
return sendRequest("POST", VARIABLES, variable);
},