-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Migrate SO management libs to typescript #60555
Migrate SO management libs to typescript #60555
Conversation
Pinging @elastic/kibana-platform (Team:Platform) |
const $http = jest.fn(); | ||
const $http = jest.fn() as any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$http a callable class. Too difficult to properly type even with jest utilities. This is going to be removed anyway when migrating to NP apis
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this file going to be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not the file, but the $http
service is going to be replaced by core's http
service, which provide proper mocks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm asking because in the NP we keep test files side by side to the code, while here it's under a separate __jest__
folder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't sure about the jest test-files pattern for legacy, but it seems I can safely move them one level up. Will do.
it('should import a file', async () => { | ||
class FileReader { | ||
readAsText(text) { | ||
this.onload({ | ||
target: { | ||
result: JSON.stringify({ text }), | ||
}, | ||
}); | ||
} | ||
} | ||
it('should import a file with valid json format', async () => { | ||
const file = new File([`{"text": "foo"}`], 'file.json'); | ||
|
||
const file = 'foo'; | ||
|
||
const imported = await importLegacyFile(file, FileReader); | ||
expect(imported).toEqual({ text: file }); | ||
const imported = await importLegacyFile(file); | ||
expect(imported).toEqual({ text: 'foo' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was using a mocked FileReader implementation, therefor testing only a small part of the importFile
function. Adapted the tests to use a real File
as input
obj: { | ||
type: 'a', | ||
id: '1', | ||
}, | ||
type: 'a', | ||
id: '1', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test dataset did not match real structure. Adapted test data and updated snapshots.
jest.mock('../../../../../../../../../plugins/kibana_utils/public', () => ({ | ||
SavedObjectNotFound: class SavedObjectNotFound extends Error { | ||
constructor(options) { | ||
super(); | ||
for (const option in options) { | ||
if (options.hasOwnProperty(option)) { | ||
this[option] = options[option]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This mocking was useless, as the only runtime usage of the mock was the import in the test file... adapted to declare the SavedObjectNotFound
in the test file instead
export async function importLegacyFile(file, FileReader = window.FileReader) { | ||
export async function importLegacyFile(file: File) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the FileReader
param was only there for testing purposes. Adapted the tests and removed the param.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/legacy/core_plugins/kibana/public/management/sections/objects/lib/jest/import_legacy_file.test.js is still js file
values: { title: this.title }, | ||
values: { title }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like an error after a probable extraction from a react component. I don't even know how the this
reference was working (probably it wasn't).
|
||
async function getSavedObject(doc, services) { | ||
const service = services.find(service => service.type === doc._type); | ||
type SavedObjectsRawDoc = Record<string, any>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't find a proper type for the raw doc we are manipulating in this file. Even the server side SavedObjectsRawDoc
doesn't match. Had to fallback to a generic record...
export interface SavedObjectMetadata { | ||
icon?: string; | ||
title?: string; | ||
editUrl?: string; | ||
inAppUrl?: { path: string; uiCapabilitiesPath: string }; | ||
} | ||
|
||
export type SavedObjectWithMetadata<T = unknown> = SavedObject<T> & { | ||
meta: SavedObjectMetadata; | ||
}; | ||
|
||
export interface SavedObjectRelation { | ||
id: string; | ||
type: string; | ||
relationship: 'child' | 'parent'; | ||
meta: SavedObjectMetadata; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicated types with src/plugins/saved_objects_management
. Will be removed once everything get moved.
const $http = jest.fn(); | ||
const $http = jest.fn() as any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this file going to be removed?
const response = await kfetch({ | ||
method: 'GET', | ||
pathname: '/api/kibana/management/saved_objects/_find', | ||
query: findOptions, | ||
query: findOptions as Record<string, any>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
KFetchQuery
type is not really useful 😕
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea. all kfetch
usages will be removed when this moves to the NP plugin, so I did not really bother much about these force-casts.
const response = await $http(options); | ||
return response ? response.data : undefined; | ||
const response = await $http<SavedObjectRelation[]>(options); | ||
return response?.data; | ||
} catch (resp) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's something new
export async function importLegacyFile(file, FileReader = window.FileReader) { | ||
export async function importLegacyFile(file: File) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/legacy/core_plugins/kibana/public/management/sections/objects/lib/jest/import_legacy_file.test.js is still js file
switch (type) { | ||
case 'search': | ||
case 'searches': | ||
return uiCapabilities.discover.show; | ||
return uiCapabilities.discover.show as boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised that we don't allow to specify the type of Capabilities
via a generic interface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is something that was 'migrated' a little too fast to TS imho. Adding a genetic type on Capabilities
would probably allow to remove quite a lot of force-cast in our TS plugins code.
However something like Capabilities<T> extends T
is not permitted, so I'm not sure how we would allow to add arbitrary root-level properties on Capabilities
to replace
/** Custom capabilities, registered by plugins. */
[key: string]: Record<string, boolean | Record<string, boolean>>;
|
||
export const isSameQuery = (query1, query2) => { | ||
export const isSameQuery = (query1: any, query2: any) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I cannot see we use it. I would rather remove the code. We always can find removed code in the git history.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, only usage is in a TODO (🙈)
Lines 240 to 242 in 7df981f
onQueryChange = ({ query }) => { | |
// TODO: Use isSameQuery to compare new query with state.activeQuery to avoid re-fetching the | |
// same data we already have. |
I'll remove it for now
doc: SavedObjectsRawDoc, | ||
indexPatterns: IndexPatternsContract, | ||
overwriteAll: boolean, | ||
confirmModalPromise: OverlayStart['openConfirm'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it a method or a promise? Signature says that's a method. Let's rename to something more meaningful - openConfirm
, for example
conflictedIndexPatterns, | ||
overwriteAll | ||
resolutions: Array<{ oldId: string; newId: string }>, | ||
conflictedIndexPatterns: any[], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
working with code in this file is not fun 😓
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lib/resolve_saved_objects.js
and lib/resolve_import_errors.js
really could use some proper cleanup and refactoring (most of the lib function does). I will create an issue to track all possible improvements once most of the SO management PR lands.
@elasticmachine merge upstream |
💚 Build SucceededHistory
To update your PR or re-run it, just comment with: |
* migrate most libs * migrate last lib files * fix get_relationships * fix getSavedObject * migrate tests to TS * address review comments * move test files outside of __jest__ folder
Summary
Part of #50308
'low effort' straightforward migration of the
src/legacy/core_plugins/kibana/public/management/sections/objects/lib
code base to typescriptPR's goal is to ease the diff of the next PR(s) by pre-migrating the management lib functions to TS. Behavior and implementation remains unchanged.
Did only minimal adaptation of the tests and did not add any, as we will wait to migrate the libs to NP apis before doing so.
Checklist