[Security][Lists] Add API functions and react hooks for value list APIs#69603
[Security][Lists] Add API functions and react hooks for value list APIs#69603rylnd merged 18 commits intoelastic:masterfrom
Conversation
This also adds a generic hook, useAsyncTask, that wraps an async function to provide basic utilities: * loading state * error state * abort/cancel function
These were not caught locally as I was accidentally running typescript without the full project.
… tuple This allows callers to further leverage fp-ts functions as needed.
* leverages new validateEither fn which returns an Either * constructs a pipeline that: * validates the payload * performs the API call * validates the response and short-circuits if any of those produce a Left value. It then converts the Either into a promise that either rejects with the Left or resolves with the Right.
This cleans up our validation pipeline considerably.
* refactors private API functions to accept the encoded request schema (i.e. snake cased) * refactors validateEither to use `schema.validate` instead of `schema.decode` since we don't actually want the decoded value, we just want to verify that it'll be able to be decoded on the backend.
* Continue to export decoded types without a qualifier * pull types used by hooks from their new location * Fix errors with usage of act()
|
Pinging @elastic/siem (Team:SIEM) |
|
This is ready for review, but I'm a little concerned about the increased bundle size. I'm going to take a look at that but I don't expect it will affect much. |
By pulling from the module directly instead of an index, we can hopefully narrow down our dependencies until tree-shaking does this for us.
|
@elasticmachine merge upstream |
| import { useCallback, useRef } from 'react'; | ||
| import useAsyncFn from 'react-use/lib/useAsyncFn'; | ||
|
|
||
| // Params can be generalized to a ...rest parameter extending unknown[] once https://github.com/microsoft/TypeScript/pull/39094 is available. |
There was a problem hiding this comment.
The one caveat with useAsyncTask right now. Otherwise, it Just Works™ and is type safe.
| args: DeleteListTaskArgs | ||
| ): ReturnType<typeof deleteList> => deleteList({ signal, ...args }); | ||
|
|
||
| // eslint-disable-next-line @typescript-eslint/explicit-function-return-type |
There was a problem hiding this comment.
Half the value of useAsyncTask is inferring arguments of the passed task, so this rule is ignored.
There was a problem hiding this comment.
Would it be worth adding this comment in the file itself for future reference?
There was a problem hiding this comment.
@yctercero that's a good idea, in the interest of build time I'll add that in the subsequent PR 😉
* master: skip failing suite (elastic#70104) (elastic#70103) [ENDPOINT] Hide the Timeline Flyout while on the Management Pages (elastic#69998) [SIEM][CASE] Persist callout when dismissed (elastic#68372) [SIEM][Exceptions] - Cleaned up and updated exception list item comment structure (elastic#69532) [Maps] remove indexing state from redux (elastic#69765) Add API integration test for deleting data streams. (elastic#70020) renames SIEM to Security Solution (elastic#70070)
Rather than returning a promise and requiring the caller to handle a rejection, we instead return nothing and require the user to watch the hook's state. * success can be handled with a useEffect on state.result * errors can be handled with a useEffect on state.error
|
Update: @XavierM diligently asked about To solve these and to encourage the safer, more idiomatic use of // BEFORE: potential unhandled rejection, potential call to handleSuccess after unmounted
task.start().then(handleSuccess);
// AFTER: no rejection to handle, no chance of handleSuccess being called after unmount
// since task.result will not change
useEffect(() => {
task.result && handleSuccess(task.result);
}, [task.result]);
task.start(); |
Assertion count wasn't updated following interface changes; we've now got two inline expectations so this isn't needed.
|
@elasticmachine merge upstream |
| pageSize, | ||
| signal, | ||
| }: FindListsParams): Promise<FoundListSchema> => | ||
| pipe( |
There was a problem hiding this comment.
Love this. I did validations on the exceptions, but it's way more verbose. I'd opt to update the exceptions list to use these same patterns.
| flow(toPromise) | ||
| ); | ||
|
|
||
| export { importListWithValidation as importList }; |
There was a problem hiding this comment.
I like that they're separated out. Maybe for our future selves or other sake we can add a comment above the non validation versions asking that they not be exported. I could see the case of someone in the future getting annoyed and wanting to just skirt the validations 🦺 Just a thought...
There was a problem hiding this comment.
@yctercero I had a similar thought, but I think that making the "default" function have validations makes sense for now. If in the future we need the unsafe version it'll have to be exported with a new name, and we can discuss said naming then.
yctercero
left a comment
There was a problem hiding this comment.
LGTM! Pulled into my branch for the exceptions builder and am using the hooks - working great! Left a few super minor comments. Really like the new patterns introduced in this PR.
FrankHassanabad
left a comment
There was a problem hiding this comment.
Brief, look, this is all great to me though. Lots of good techniques going on. Can't wait to begin using some of it.
|
@elasticmachine merge upstream |
💚 Build SucceededBuild metrics@kbn/optimizer bundle module count
History
To update your PR or re-run it, just comment with: |
…ata-streams * 'master' of github.com:elastic/kibana: (50 commits) [Logs UI] [Alerting] "Group by" functionality (elastic#68250) [Discover] Deangularize Skip to bottom button (elastic#69811) Implement recursive plugin discovery (elastic#68811) Use ts-expect-error in platform code (elastic#69883) [SIEM][Detection Engine][Lists] Moves getQueryFilter to common folder for use by both front and backend [Ingest Manager][SECURITY SOLUTION] adjust config reassign link and add roundtrip to Reassignment flow (elastic#70208) [Security][Lists] Add API functions and react hooks for value list APIs (elastic#69603) [ILM] Fix bug when clearing priority field (elastic#70154) [Platform][Security] Updates cluster_manager ignorePaths to include security scripts (elastic#70139) [IngestManager] Allow to filter agent by packages (elastic#69731) [code coverage] exclude folders: test_helpers, tests_bundle (elastic#70199) [Metrics UI] UX improvements for saved views (elastic#69910) [APM] docs: unique transaction troubleshooting (elastic#69831) Cross cluster search functional test with minimun privileges assigned to the test_user (elastic#70007) [Maps] choropleth layer wizard (elastic#69699) Make custom errors by extending Error (elastic#69966) [Ingest Manager] Support updated package output structure (elastic#69864) Resolver test coverage (elastic#70246) Async Discover search test (elastic#64388) [ui-shared-deps] include styled-components (elastic#69322) ... # Conflicts: # x-pack/plugins/snapshot_restore/server/types.ts
…bana into alerting/consumer-based-rbac * 'alerting/consumer-based-rbac' of github.com:gmmorris/kibana: (49 commits) [Discover] Deangularize Skip to bottom button (elastic#69811) Implement recursive plugin discovery (elastic#68811) Use ts-expect-error in platform code (elastic#69883) [SIEM][Detection Engine][Lists] Moves getQueryFilter to common folder for use by both front and backend [Ingest Manager][SECURITY SOLUTION] adjust config reassign link and add roundtrip to Reassignment flow (elastic#70208) [Security][Lists] Add API functions and react hooks for value list APIs (elastic#69603) [ILM] Fix bug when clearing priority field (elastic#70154) [Platform][Security] Updates cluster_manager ignorePaths to include security scripts (elastic#70139) [IngestManager] Allow to filter agent by packages (elastic#69731) [code coverage] exclude folders: test_helpers, tests_bundle (elastic#70199) [Metrics UI] UX improvements for saved views (elastic#69910) [APM] docs: unique transaction troubleshooting (elastic#69831) Cross cluster search functional test with minimun privileges assigned to the test_user (elastic#70007) [Maps] choropleth layer wizard (elastic#69699) Make custom errors by extending Error (elastic#69966) [Ingest Manager] Support updated package output structure (elastic#69864) Resolver test coverage (elastic#70246) Async Discover search test (elastic#64388) [ui-shared-deps] include styled-components (elastic#69322) SECURITY-ENDPOINT: add host properties (elastic#70238) ...
…Is (#69603) (#70279) * Add pure API functions and react hooks for value list APIs This also adds a generic hook, useAsyncTask, that wraps an async function to provide basic utilities: * loading state * error state * abort/cancel function * Fix type errors in hook tests These were not caught locally as I was accidentally running typescript without the full project. * Document current limitations of useAsyncTask * Defines a new validation function that returns an Either instead of a tuple This allows callers to further leverage fp-ts functions as needed. * Remove duplicated copyright comment * WIP: Perform request/response validations in the FP style * leverages new validateEither fn which returns an Either * constructs a pipeline that: * validates the payload * performs the API call * validates the response and short-circuits if any of those produce a Left value. It then converts the Either into a promise that either rejects with the Left or resolves with the Right. * Adds helper function to convert a TaskEither back to a Promise This cleans up our validation pipeline considerably. * Adds request/response validations to findLists * refactors private API functions to accept the encoded request schema (i.e. snake cased) * refactors validateEither to use `schema.validate` instead of `schema.decode` since we don't actually want the decoded value, we just want to verify that it'll be able to be decoded on the backend. * Refactor our API types * Add request/response validation to import/export functions * Fix type errors * Continue to export decoded types without a qualifier * pull types used by hooks from their new location * Fix errors with usage of act() * Attempting to reduce plugin bundle size By pulling from the module directly instead of an index, we can hopefully narrow down our dependencies until tree-shaking does this for us. * useAsyncFn's initiator does not return a promise Rather than returning a promise and requiring the caller to handle a rejection, we instead return nothing and require the user to watch the hook's state. * success can be handled with a useEffect on state.result * errors can be handled with a useEffect on state.error * Fix failing test Assertion count wasn't updated following interface changes; we've now got two inline expectations so this isn't needed. Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
…Is (elastic#69603) * Add pure API functions and react hooks for value list APIs This also adds a generic hook, useAsyncTask, that wraps an async function to provide basic utilities: * loading state * error state * abort/cancel function * Fix type errors in hook tests These were not caught locally as I was accidentally running typescript without the full project. * Document current limitations of useAsyncTask * Defines a new validation function that returns an Either instead of a tuple This allows callers to further leverage fp-ts functions as needed. * Remove duplicated copyright comment * WIP: Perform request/response validations in the FP style * leverages new validateEither fn which returns an Either * constructs a pipeline that: * validates the payload * performs the API call * validates the response and short-circuits if any of those produce a Left value. It then converts the Either into a promise that either rejects with the Left or resolves with the Right. * Adds helper function to convert a TaskEither back to a Promise This cleans up our validation pipeline considerably. * Adds request/response validations to findLists * refactors private API functions to accept the encoded request schema (i.e. snake cased) * refactors validateEither to use `schema.validate` instead of `schema.decode` since we don't actually want the decoded value, we just want to verify that it'll be able to be decoded on the backend. * Refactor our API types * Add request/response validation to import/export functions * Fix type errors * Continue to export decoded types without a qualifier * pull types used by hooks from their new location * Fix errors with usage of act() * Attempting to reduce plugin bundle size By pulling from the module directly instead of an index, we can hopefully narrow down our dependencies until tree-shaking does this for us. * useAsyncFn's initiator does not return a promise Rather than returning a promise and requiring the caller to handle a rejection, we instead return nothing and require the user to watch the hook's state. * success can be handled with a useEffect on state.result * errors can be handled with a useEffect on state.error * Fix failing test Assertion count wasn't updated following interface changes; we've now got two inline expectations so this isn't needed. Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
|
Pinging @elastic/security-solution (Team: SecuritySolution) |
Summary
This adds new API functions and their corresponding react hooks to be used for #67068.
This does not represent all value list endpoints, only those needed for the 7.9 management modal:
findListsimportListdeleteListexportListThis also adds a generic hook,
useAsyncTask, that wraps an async function to provide basic utilities:along with type inference of the provided function.
TODO:
Checklist
Delete any items that are not applicable to this PR.
For maintainers