From c2ff8a849956cad8443c6832241390415542a1d5 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Mon, 23 Sep 2024 15:33:28 -0700 Subject: [PATCH 01/11] Update FixerStatus type to account for potential error props --- projects/plugins/protect/src/js/types/fixers.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/projects/plugins/protect/src/js/types/fixers.ts b/projects/plugins/protect/src/js/types/fixers.ts index c732af6311b63..507892abcb45e 100644 --- a/projects/plugins/protect/src/js/types/fixers.ts +++ b/projects/plugins/protect/src/js/types/fixers.ts @@ -2,12 +2,14 @@ export type FixerStatus = 'not_started' | 'in_progress' | 'fixed' | 'not_fixed'; export type FixersStatus = { ok: boolean; - threats: { + error?: string; + threats?: { [ key: number ]: ThreatFixStatus; }; }; export type ThreatFixStatus = { - status: FixerStatus; - last_updated: string; + error?: string; + status?: FixerStatus; + last_updated?: string; }; From 22c57e76b008a9db5ff0fc0c6053afaa546a7594 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Mon, 23 Sep 2024 15:34:28 -0700 Subject: [PATCH 02/11] changelog --- .../update-protect-use-fixers-response-error-prop-handling | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 projects/plugins/protect/changelog/update-protect-use-fixers-response-error-prop-handling diff --git a/projects/plugins/protect/changelog/update-protect-use-fixers-response-error-prop-handling b/projects/plugins/protect/changelog/update-protect-use-fixers-response-error-prop-handling new file mode 100644 index 0000000000000..75eea85cd389a --- /dev/null +++ b/projects/plugins/protect/changelog/update-protect-use-fixers-response-error-prop-handling @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Adds handling for FixerStatus error props From 0775abae4bf7d2875263b56e53ccfae356a69a8f Mon Sep 17 00:00:00 2001 From: dkmyta Date: Tue, 24 Sep 2024 12:47:44 -0700 Subject: [PATCH 03/11] Handle error responses --- .../src/js/data/scan/use-fixers-mutation.ts | 14 ++++++++++++ .../src/js/data/scan/use-fixers-query.ts | 22 ++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts b/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts index c50c3611c8592..5bdd20618b094 100644 --- a/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts +++ b/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts @@ -16,6 +16,20 @@ export default function useFixersMutation(): UseMutationResult { return useMutation( { mutationFn: API.fixThreats, onSuccess: data => { + // Handle a top level error + if ( data?.error ) { + throw new Error( data.error ); + } + + const isThreatLevelError = Object.values( data?.threats ).every( + ( threat: { error?: string } ) => Boolean( threat?.error ) + ); + + // Handle a threat level error + if ( isThreatLevelError ) { + throw new Error(); + } + // The data returned from the API is the same as the data we need to update the cache. queryClient.setQueryData( [ QUERY_FIXERS_KEY ], data ); diff --git a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts index f860359de8e29..029a470a083dc 100644 --- a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts +++ b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts @@ -74,6 +74,11 @@ export default function useFixersQuery( { | FixersStatus | undefined; + // Handle a top level error + if ( data?.error ) { + throw new Error( data?.error ); + } + const successes: string[] = []; const failures: string[] = []; @@ -81,6 +86,17 @@ export default function useFixersQuery( { const threat = data.threats[ threatId ]; const cachedThreat = cachedData?.threats?.[ threatId ]; + // Handle a threat level error + if ( threat?.error ) { + if ( threat.error === 'not_found' ) { + // If not_found after the initial fetch, fixers are done + queryClient.invalidateQueries( { queryKey: [ QUERY_SCAN_STATUS_KEY ] } ); + queryClient.invalidateQueries( { queryKey: [ QUERY_HISTORY_KEY ] } ); + } else { + failures.push( threatId ); + } + } + if ( cachedThreat?.status === 'in_progress' ) { // If still in progress if ( threat.status === 'in_progress' ) { @@ -93,7 +109,7 @@ export default function useFixersQuery( { } // Handle completion of fixers - if ( threat.status !== 'in_progress' ) { + if ( threat?.status !== 'in_progress' && ! threat?.error ) { queryClient.invalidateQueries( { queryKey: [ QUERY_SCAN_STATUS_KEY ] } ); queryClient.invalidateQueries( { queryKey: [ QUERY_HISTORY_KEY ] } ); @@ -117,8 +133,8 @@ export default function useFixersQuery( { return false; } - const inProgressNotStale = Object.values( query.state.data.threats ).some( - ( threat: { status: string; last_updated: string } ) => + const inProgressNotStale = Object.values( query.state.data?.threats ).some( + ( threat: { status?: string; last_updated?: string } ) => threat.status === 'in_progress' && ! fixerTimestampIsStale( threat.last_updated ) ); From 73a7a6d9e4e264a88e517022282e316bbd12a3be Mon Sep 17 00:00:00 2001 From: dkmyta Date: Tue, 24 Sep 2024 14:48:15 -0700 Subject: [PATCH 04/11] Only handle top level errors in useFixersQuery, threat level errors are handled in the completion block --- .../src/js/data/scan/use-fixers-query.ts | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts index 029a470a083dc..994535c72d8cf 100644 --- a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts +++ b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts @@ -83,23 +83,12 @@ export default function useFixersQuery( { const failures: string[] = []; Object.keys( data?.threats || {} ).forEach( threatId => { - const threat = data.threats[ threatId ]; + const threat = data?.threats[ threatId ]; const cachedThreat = cachedData?.threats?.[ threatId ]; - // Handle a threat level error - if ( threat?.error ) { - if ( threat.error === 'not_found' ) { - // If not_found after the initial fetch, fixers are done - queryClient.invalidateQueries( { queryKey: [ QUERY_SCAN_STATUS_KEY ] } ); - queryClient.invalidateQueries( { queryKey: [ QUERY_HISTORY_KEY ] } ); - } else { - failures.push( threatId ); - } - } - if ( cachedThreat?.status === 'in_progress' ) { // If still in progress - if ( threat.status === 'in_progress' ) { + if ( threat?.status === 'in_progress' ) { if ( ! fixerTimestampIsStale( cachedThreat.last_updated ) && fixerTimestampIsStale( threat.last_updated ) @@ -109,11 +98,11 @@ export default function useFixersQuery( { } // Handle completion of fixers - if ( threat?.status !== 'in_progress' && ! threat?.error ) { + if ( threat?.status !== 'in_progress' ) { queryClient.invalidateQueries( { queryKey: [ QUERY_SCAN_STATUS_KEY ] } ); queryClient.invalidateQueries( { queryKey: [ QUERY_HISTORY_KEY ] } ); - if ( threat.status === 'fixed' ) { + if ( threat?.status === 'fixed' ) { successes.push( threatId ); } else { failures.push( threatId ); From 56b527c278d652b8cc8cd845816069a2ba3f28c0 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Tue, 24 Sep 2024 14:59:32 -0700 Subject: [PATCH 05/11] Add clarifying comment --- projects/plugins/protect/src/js/data/scan/use-fixers-query.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts index 994535c72d8cf..5cb4f17695936 100644 --- a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts +++ b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts @@ -105,6 +105,7 @@ export default function useFixersQuery( { if ( threat?.status === 'fixed' ) { successes.push( threatId ); } else { + // Handle unsuccessful statuses and threat level errors failures.push( threatId ); } } From 2a084db8bb423d9831766c142f1c16c89e6cb4d4 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Tue, 1 Oct 2024 13:57:22 -0700 Subject: [PATCH 06/11] Improve fixer types --- .../plugins/protect/src/js/types/fixers.ts | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/projects/plugins/protect/src/js/types/fixers.ts b/projects/plugins/protect/src/js/types/fixers.ts index 507892abcb45e..519b3344b8eba 100644 --- a/projects/plugins/protect/src/js/types/fixers.ts +++ b/projects/plugins/protect/src/js/types/fixers.ts @@ -1,15 +1,40 @@ export type FixerStatus = 'not_started' | 'in_progress' | 'fixed' | 'not_fixed'; -export type FixersStatus = { - ok: boolean; - error?: string; - threats?: { - [ key: number ]: ThreatFixStatus; +// Discriminated union for top-level error +export type FixersStatusTopLevelError = { + ok: false; // Discriminator for overall failure + error: string; // When `ok` is false, top-level error is required +}; + +// Discriminated union for threat-level errors +export type FixersStatusThreatError = { + ok: true; // Discriminator for overall success + threats: { + [ key: number ]: ThreatFixError; // At least one threat has an error + }; +}; + +// Discriminated union for success scenario +export type FixersStatusSuccess = { + ok: true; // Discriminator for overall success + threats: { + [ key: number ]: ThreatFixStatusSuccess; // Threats with successful statuses }; }; -export type ThreatFixStatus = { - error?: string; - status?: FixerStatus; - last_updated?: string; +// Union type for fixers status (top-level or threat-level error, or success) +export type FixersStatus = + | FixersStatusTopLevelError + | FixersStatusThreatError + | FixersStatusSuccess; + +// Threat-level error (discriminated) +export type ThreatFixError = { + error: string; // Discriminator for threat-level error +}; + +// Threat-level success (discriminated) +export type ThreatFixStatusSuccess = { + status: FixerStatus; // Threat fix status (one of 'not_started', 'in_progress', etc.) + last_updated: string; // Last updated timestamp }; From 39dd7ed36d205f6234a0edbd04fdb421a71bde16 Mon Sep 17 00:00:00 2001 From: dkmyta Date: Tue, 1 Oct 2024 15:42:43 -0700 Subject: [PATCH 07/11] Fix prop handling --- .../src/js/data/scan/use-fixers-mutation.ts | 6 +- .../src/js/data/scan/use-fixers-query.ts | 71 ++++++++++--------- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts b/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts index 5bdd20618b094..431dc2dfddb30 100644 --- a/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts +++ b/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts @@ -17,12 +17,12 @@ export default function useFixersMutation(): UseMutationResult { mutationFn: API.fixThreats, onSuccess: data => { // Handle a top level error - if ( data?.error ) { + if ( data.ok === false ) { throw new Error( data.error ); } - const isThreatLevelError = Object.values( data?.threats ).every( - ( threat: { error?: string } ) => Boolean( threat?.error ) + const isThreatLevelError = Object.values( data.threats ).every( + ( threat: { error?: string } ) => Boolean( threat.error ) ); // Handle a threat level error diff --git a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts index 5cb4f17695936..ef6adaf53a762 100644 --- a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts +++ b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts @@ -75,38 +75,41 @@ export default function useFixersQuery( { | undefined; // Handle a top level error - if ( data?.error ) { - throw new Error( data?.error ); + if ( data.ok === false ) { + throw new Error( data.error ); } const successes: string[] = []; const failures: string[] = []; - Object.keys( data?.threats || {} ).forEach( threatId => { + Object.keys( data.threats || {} ).forEach( threatId => { const threat = data?.threats[ threatId ]; - const cachedThreat = cachedData?.threats?.[ threatId ]; - - if ( cachedThreat?.status === 'in_progress' ) { - // If still in progress - if ( threat?.status === 'in_progress' ) { - if ( - ! fixerTimestampIsStale( cachedThreat.last_updated ) && - fixerTimestampIsStale( threat.last_updated ) - ) { - failures.push( threatId ); - } - } - // Handle completion of fixers - if ( threat?.status !== 'in_progress' ) { - queryClient.invalidateQueries( { queryKey: [ QUERY_SCAN_STATUS_KEY ] } ); - queryClient.invalidateQueries( { queryKey: [ QUERY_HISTORY_KEY ] } ); + if ( cachedData.ok === true && cachedData?.threats ) { + const cachedThreat = cachedData.threats?.[ threatId ]; + + if ( cachedThreat?.status === 'in_progress' ) { + // If still in progress + if ( threat?.status === 'in_progress' ) { + if ( + ! fixerTimestampIsStale( cachedThreat.last_updated ) && + fixerTimestampIsStale( threat.last_updated ) + ) { + failures.push( threatId ); + } + } - if ( threat?.status === 'fixed' ) { - successes.push( threatId ); - } else { - // Handle unsuccessful statuses and threat level errors - failures.push( threatId ); + // Handle completion of fixers + if ( threat?.status !== 'in_progress' ) { + queryClient.invalidateQueries( { queryKey: [ QUERY_SCAN_STATUS_KEY ] } ); + queryClient.invalidateQueries( { queryKey: [ QUERY_HISTORY_KEY ] } ); + + if ( threat?.status === 'fixed' ) { + successes.push( threatId ); + } else { + // Handle unsuccessful statuses and threat level errors + failures.push( threatId ); + } } } } @@ -123,15 +126,19 @@ export default function useFixersQuery( { return false; } - const inProgressNotStale = Object.values( query.state.data?.threats ).some( - ( threat: { status?: string; last_updated?: string } ) => - threat.status === 'in_progress' && ! fixerTimestampIsStale( threat.last_updated ) - ); + const data = query.state.data; - // Refetch while any threats are still in progress and not stale. - if ( inProgressNotStale ) { - // Refetch on a shorter interval first, then slow down if it is taking a while. - return query.state.dataUpdateCount < 5 ? 5000 : 15000; + if ( data.ok === true && data?.threats ) { + const inProgressNotStale = Object.values( data.threats ).some( + ( threat: { status?: string; last_updated?: string } ) => + threat.status === 'in_progress' && ! fixerTimestampIsStale( threat.last_updated ) + ); + + // Refetch while any threats are still in progress and not stale. + if ( inProgressNotStale ) { + // Refetch on a shorter interval first, then slow down if it is taking a while. + return query.state.dataUpdateCount < 5 ? 5000 : 15000; + } } return false; From 47af3ae6180de7602de1476e68f148fbd9a49906 Mon Sep 17 00:00:00 2001 From: Nate Weller Date: Wed, 2 Oct 2024 10:13:46 -0600 Subject: [PATCH 08/11] Update useFixers hook for compatibility with type updates --- .../plugins/protect/src/js/hooks/use-fixers.ts | 15 +++++++++++++-- projects/plugins/protect/src/js/types/fixers.ts | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/projects/plugins/protect/src/js/hooks/use-fixers.ts b/projects/plugins/protect/src/js/hooks/use-fixers.ts index 2d31b65bb35cf..d86fd4e66a23c 100644 --- a/projects/plugins/protect/src/js/hooks/use-fixers.ts +++ b/projects/plugins/protect/src/js/hooks/use-fixers.ts @@ -13,7 +13,11 @@ export const fixerTimestampIsStale = ( lastUpdatedTimestamp: string ) => { }; export const fixerStatusIsStale = ( fixerStatus: ThreatFixStatus ) => { - return fixerStatus.status === 'in_progress' && fixerTimestampIsStale( fixerStatus.last_updated ); + return ( + 'status' in fixerStatus && + fixerStatus.status === 'in_progress' && + fixerTimestampIsStale( fixerStatus.last_updated ) + ); }; type UseFixersResult = { @@ -40,13 +44,20 @@ export default function useFixers(): UseFixersResult { const isThreatFixInProgress = useCallback( ( threatId: number ) => { - return fixersStatus?.threats?.[ threatId ]?.status === 'in_progress'; + if ( fixersStatus.ok === false ) { + return false; + } + const threatFix = fixersStatus.threats?.[ threatId ]; + return 'status' in threatFix && threatFix.status === 'in_progress'; }, [ fixersStatus ] ); const isThreatFixStale = useCallback( ( threatId: number ) => { + if ( fixersStatus.ok === false ) { + return false; + } const threatFixStatus = fixersStatus?.threats?.[ threatId ]; return threatFixStatus ? fixerStatusIsStale( threatFixStatus ) : false; }, diff --git a/projects/plugins/protect/src/js/types/fixers.ts b/projects/plugins/protect/src/js/types/fixers.ts index 519b3344b8eba..6f5cd693eb999 100644 --- a/projects/plugins/protect/src/js/types/fixers.ts +++ b/projects/plugins/protect/src/js/types/fixers.ts @@ -38,3 +38,5 @@ export type ThreatFixStatusSuccess = { status: FixerStatus; // Threat fix status (one of 'not_started', 'in_progress', etc.) last_updated: string; // Last updated timestamp }; + +export type ThreatFixStatus = ThreatFixError | ThreatFixStatusSuccess; From 3c2d4f3c6c9083bf0a3682ba9f4fc7258e055ab8 Mon Sep 17 00:00:00 2001 From: Nate Weller Date: Wed, 2 Oct 2024 10:20:32 -0600 Subject: [PATCH 09/11] Remove optional chaining where applicable, update logic to rely on TS types --- .../src/js/data/scan/use-fixers-query.ts | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts index ef6adaf53a762..99bfc63fa51e4 100644 --- a/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts +++ b/projects/plugins/protect/src/js/data/scan/use-fixers-query.ts @@ -6,7 +6,7 @@ import API from '../../api'; import { QUERY_FIXERS_KEY, QUERY_HISTORY_KEY, QUERY_SCAN_STATUS_KEY } from '../../constants'; import { fixerTimestampIsStale } from '../../hooks/use-fixers'; import useNotices from '../../hooks/use-notices'; -import { FixersStatus } from '../../types/fixers'; +import { FixersStatus, ThreatFixStatus } from '../../types/fixers'; const initialData: FixersStatus = window.jetpackProtectInitialState?.fixerStatus || { ok: true, @@ -83,31 +83,26 @@ export default function useFixersQuery( { const failures: string[] = []; Object.keys( data.threats || {} ).forEach( threatId => { - const threat = data?.threats[ threatId ]; + const threat = data.threats[ threatId ]; - if ( cachedData.ok === true && cachedData?.threats ) { + if ( cachedData.ok === true ) { const cachedThreat = cachedData.threats?.[ threatId ]; - if ( cachedThreat?.status === 'in_progress' ) { - // If still in progress - if ( threat?.status === 'in_progress' ) { + if ( cachedThreat && cachedThreat.status === 'in_progress' ) { + if ( threat.status === 'in_progress' ) { if ( ! fixerTimestampIsStale( cachedThreat.last_updated ) && fixerTimestampIsStale( threat.last_updated ) ) { failures.push( threatId ); } - } - - // Handle completion of fixers - if ( threat?.status !== 'in_progress' ) { + } else { queryClient.invalidateQueries( { queryKey: [ QUERY_SCAN_STATUS_KEY ] } ); queryClient.invalidateQueries( { queryKey: [ QUERY_HISTORY_KEY ] } ); - if ( threat?.status === 'fixed' ) { + if ( threat.status === 'fixed' ) { successes.push( threatId ); } else { - // Handle unsuccessful statuses and threat level errors failures.push( threatId ); } } @@ -128,10 +123,12 @@ export default function useFixersQuery( { const data = query.state.data; - if ( data.ok === true && data?.threats ) { + if ( data.ok === true ) { const inProgressNotStale = Object.values( data.threats ).some( - ( threat: { status?: string; last_updated?: string } ) => - threat.status === 'in_progress' && ! fixerTimestampIsStale( threat.last_updated ) + ( threat: ThreatFixStatus ) => + 'status' in threat && + threat.status === 'in_progress' && + ! fixerTimestampIsStale( threat.last_updated ) ); // Refetch while any threats are still in progress and not stale. From a2c7b3767a2c1cf2331be9b09db69b48e471e195 Mon Sep 17 00:00:00 2001 From: Nate Weller Date: Wed, 2 Oct 2024 10:44:06 -0600 Subject: [PATCH 10/11] Update types --- .../src/js/data/scan/use-fixers-mutation.ts | 4 +- .../plugins/protect/src/js/types/fixers.ts | 58 +++++++++---------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts b/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts index 431dc2dfddb30..873d115c0d68b 100644 --- a/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts +++ b/projects/plugins/protect/src/js/data/scan/use-fixers-mutation.ts @@ -21,9 +21,7 @@ export default function useFixersMutation(): UseMutationResult { throw new Error( data.error ); } - const isThreatLevelError = Object.values( data.threats ).every( - ( threat: { error?: string } ) => Boolean( threat.error ) - ); + const isThreatLevelError = Object.values( data.threats ).every( threat => 'error' in threat ); // Handle a threat level error if ( isThreatLevelError ) { diff --git a/projects/plugins/protect/src/js/types/fixers.ts b/projects/plugins/protect/src/js/types/fixers.ts index 6f5cd693eb999..b99a93def29a4 100644 --- a/projects/plugins/protect/src/js/types/fixers.ts +++ b/projects/plugins/protect/src/js/types/fixers.ts @@ -1,42 +1,40 @@ export type FixerStatus = 'not_started' | 'in_progress' | 'fixed' | 'not_fixed'; -// Discriminated union for top-level error -export type FixersStatusTopLevelError = { - ok: false; // Discriminator for overall failure - error: string; // When `ok` is false, top-level error is required +/** + * Threat Fix Status + * + * Individual fixer status for a threat. + */ +export type ThreatFixStatusError = { + error: string; }; -// Discriminated union for threat-level errors -export type FixersStatusThreatError = { - ok: true; // Discriminator for overall success - threats: { - [ key: number ]: ThreatFixError; // At least one threat has an error - }; +export type ThreatFixStatusSuccess = { + status: FixerStatus; + last_updated: string; }; -// Discriminated union for success scenario -export type FixersStatusSuccess = { - ok: true; // Discriminator for overall success - threats: { - [ key: number ]: ThreatFixStatusSuccess; // Threats with successful statuses - }; -}; +export type ThreatFixStatus = ThreatFixStatusError | ThreatFixStatusSuccess; -// Union type for fixers status (top-level or threat-level error, or success) -export type FixersStatus = - | FixersStatusTopLevelError - | FixersStatusThreatError - | FixersStatusSuccess; +/** + * Fixers Status + * + * Overall status of all fixers. + */ +type FixersStatusBase = { + ok: boolean; // Discriminator for overall success +}; -// Threat-level error (discriminated) -export type ThreatFixError = { - error: string; // Discriminator for threat-level error +export type FixersStatusError = FixersStatusBase & { + ok: false; + error: string; }; -// Threat-level success (discriminated) -export type ThreatFixStatusSuccess = { - status: FixerStatus; // Threat fix status (one of 'not_started', 'in_progress', etc.) - last_updated: string; // Last updated timestamp +export type FixersStatusSuccess = FixersStatusBase & { + ok: true; + threats: { + [ key: number ]: ThreatFixStatus; + }; }; -export type ThreatFixStatus = ThreatFixError | ThreatFixStatusSuccess; +export type FixersStatus = FixersStatusSuccess | FixersStatusError; From 35b609e805f3fcc0e1618ca28232e81e6bedb512 Mon Sep 17 00:00:00 2001 From: Nate Weller Date: Wed, 2 Oct 2024 11:17:36 -0600 Subject: [PATCH 11/11] Fix type error --- projects/plugins/protect/src/js/hooks/use-fixers.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/plugins/protect/src/js/hooks/use-fixers.ts b/projects/plugins/protect/src/js/hooks/use-fixers.ts index d86fd4e66a23c..fc92792a443eb 100644 --- a/projects/plugins/protect/src/js/hooks/use-fixers.ts +++ b/projects/plugins/protect/src/js/hooks/use-fixers.ts @@ -48,7 +48,7 @@ export default function useFixers(): UseFixersResult { return false; } const threatFix = fixersStatus.threats?.[ threatId ]; - return 'status' in threatFix && threatFix.status === 'in_progress'; + return threatFix && 'status' in threatFix && threatFix.status === 'in_progress'; }, [ fixersStatus ] );