Skip to content
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

Allow to extend ObjectType schemas #67357

Closed

Conversation

pgayvallet
Copy link
Contributor

@pgayvallet pgayvallet commented May 26, 2020

Summary

Fix #59083

Add a getRaw method on ObjectType returning the raw schema properties used to create the type. This allows to create new schemas with altered properties.

const origin = schema.object({
   initial: schema.string(),
});

const extended = schema.object({
   ...origin.getRaw(),
   added: schema.number(),
});

Checklist

@pgayvallet pgayvallet added Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc enhancement New value added to drive a business result v8.0.0 release_note:skip Skip the PR/issue when compiling release notes v7.9.0 labels May 26, 2020
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-platform (Team:Platform)

@pgayvallet pgayvallet marked this pull request as ready for review May 26, 2020 16:53
@pgayvallet pgayvallet requested a review from a team as a code owner May 26, 2020 16:53
@chrisronline
Copy link
Contributor

@pgayvallet This is great, thanks for working on this!

Do you mind including an example of how to use this properly?

@pgayvallet
Copy link
Contributor Author

@chrisronline is the jsdoc on getRaw sufficient? If not, what would you want me to add?

@chrisronline
Copy link
Contributor

@pgayvallet Ah, I didn't notice that in the PR. That's exactly what I wanted!

@joshdover
Copy link
Contributor

joshdover commented May 28, 2020

const origin = schema.object({
   initial: schema.string(),
});

const extended = schema.object({
   ...origin.getRaw(),
   added: schema.number(),
});

I don't really love this pattern because it exposes some implementation details of config-schema outside of the package.

Is there any reason this API wouldn't work?

const origin = schema.object({
   initial: schema.string(),
});

const extended = origin.extend({
   added: schema.number(),
});

In the future this extend API could also accept options (using one of the approaches defined in #59083 (comment)), but for now it doesn't need to.

@pgayvallet
Copy link
Contributor Author

pgayvallet commented Jun 2, 2020

@joshdover

I don't really love this pattern because it exposes some implementation details of config-schema outside of the package. Is there any reason this API wouldn't work?

As @restrry said in #59083 (comment), the limitation of the extend pattern is that it doesn't allow to suppress excessive properties, which is why I went for the getRaw instead

const origin = schema.object({
   initial: schema.string(),
   toRemove: schema.string()
});
const extended = origin.extend({
   toRemove: undefined, // error, undefined does not extends `Type<any>`, and can't easily change typings / implementation to allow it I think?
});

@kibanamachine
Copy link
Contributor

💛 Build succeeded, but was flaky


Test Failures

Kibana Pipeline / kibana-xpack-agent / Chrome X-Pack UI Functional Tests.x-pack/test/functional/apps/dashboard/_async_dashboard·ts.dashboard sample data dashboard "before all" hook for "should launch sample flights data set dashboard"

Link to Jenkins

Standard Out

Failed Tests Reporter:
  - Test has not failed recently on tracked branches

[00:00:00]       │
[00:00:00]         └-: dashboard
[00:00:00]           └-> "before all" hook
[00:08:00]           └-: sample data dashboard
[00:08:00]             └-> "before all" hook
[00:08:00]             └-> "before all" hook
[00:08:00]               │ debg ... sleep(5000) start
[00:08:05]               │ debg ... sleep(5000) end
[00:08:05]               │ debg navigateToActualUrl http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:05]               │ debg browser[INFO] http://localhost:6181/app/home?_t=1591085674705#/tutorial_directory/sampleData 341 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'unsafe-eval' 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-P5polb1UreUSOe5V/Pv7tc+yeZuJXiOi/3fqhGsU7BE='), or a nonce ('nonce-...') is required to enable inline execution.
[00:08:05]               │
[00:08:05]               │ debg browser[INFO] http://localhost:6181/bundles/app/core/bootstrap.js 11:19 "^ A single error about an inline script not firing due to content security policy is expected!"
[00:08:05]               │ debg currentUrl = http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:05]               │          appUrl = http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:05]               │ debg TestSubjects.find(kibanaChrome)
[00:08:05]               │ debg Find.findByCssSelector('[data-test-subj="kibanaChrome"]') with timeout=60000
[00:08:09]               │ debg browser[INFO] http://localhost:6181/33521/bundles/kbn-ui-shared-deps/kbn-ui-shared-deps.js 380:106115 "INFO: 2020-06-02T08:14:38Z
[00:08:09]               │        Adding connection to http://localhost:6181/elasticsearch
[00:08:09]               │
[00:08:09]               │      "
[00:08:09]               │ debg isGlobalLoadingIndicatorVisible
[00:08:09]               │ debg TestSubjects.exists(globalLoadingIndicator)
[00:08:09]               │ debg Find.existsByDisplayedByCssSelector('[data-test-subj="globalLoadingIndicator"]') with timeout=1500
[00:08:09]               │ debg TestSubjects.exists(globalLoadingIndicator-hidden)
[00:08:09]               │ debg Find.existsByCssSelector('[data-test-subj="globalLoadingIndicator-hidden"]') with timeout=100000
[00:08:09]               │ debg TestSubjects.exists(addSampleDataSetflights)
[00:08:09]               │ debg Find.existsByDisplayedByCssSelector('[data-test-subj="addSampleDataSetflights"]') with timeout=2500
[00:08:09]               │ debg TestSubjects.click(addSampleDataSetflights)
[00:08:09]               │ debg Find.clickByCssSelector('[data-test-subj="addSampleDataSetflights"]') with timeout=10000
[00:08:09]               │ debg Find.findByCssSelector('[data-test-subj="addSampleDataSetflights"]') with timeout=10000
[00:08:10]               │ debg TestSubjects.find(sampleDataSetCardflights)
[00:08:10]               │ debg Find.findByCssSelector('[data-test-subj="sampleDataSetCardflights"]') with timeout=10000
[00:08:11]               │ debg TestSubjects.exists(addSampleDataSetflights)
[00:08:11]               │ debg Find.existsByDisplayedByCssSelector('[data-test-subj="addSampleDataSetflights"]') with timeout=2500
[00:08:11]               │ info Taking screenshot "/dev/shm/workspace/kibana/x-pack/test/functional/screenshots/failure/dashboard sample data dashboard _before all_ hook.png"
[00:08:11]               │ info Current URL is: http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:11]               │ info Saving page source to: /dev/shm/workspace/kibana/x-pack/test/functional/failure_debug/html/dashboard sample data dashboard _before all_ hook.html
[00:08:11]               └- ✖ fail: "dashboard sample data dashboard "before all" hook for "should launch sample flights data set dashboard""
[00:08:11]               │

Stack Trace

Error: expected false to equal true
    at Assertion.assert (/dev/shm/workspace/kibana/packages/kbn-expect/expect.js:100:11)
    at Assertion.be.Assertion.equal (/dev/shm/workspace/kibana/packages/kbn-expect/expect.js:227:8)
    at Assertion.be (/dev/shm/workspace/kibana/packages/kbn-expect/expect.js:69:22)
    at Context.before (test/functional/apps/dashboard/_async_dashboard.ts:38:30)
    at process._tickCallback (internal/process/next_tick.js:68:7)

Kibana Pipeline / kibana-xpack-agent / Chrome X-Pack UI Functional Tests.x-pack/test/functional/apps/dashboard/_async_dashboard·ts.dashboard sample data dashboard "after all" hook for "toggle from Discover to Dashboard attempt 2"

Link to Jenkins

Standard Out

Failed Tests Reporter:
  - Test has failed 13 times on tracked branches: https://github.com/elastic/kibana/issues/65949

[00:00:00]       │
[00:00:00]         └-: dashboard
[00:00:00]           └-> "before all" hook
[00:08:00]           └-: sample data dashboard
[00:08:00]             └-> "before all" hook
[00:08:00]             └-> "before all" hook
[00:08:00]               │ debg ... sleep(5000) start
[00:08:05]               │ debg ... sleep(5000) end
[00:08:05]               │ debg navigateToActualUrl http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:05]               │ debg browser[INFO] http://localhost:6181/app/home?_t=1591085674705#/tutorial_directory/sampleData 341 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'unsafe-eval' 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-P5polb1UreUSOe5V/Pv7tc+yeZuJXiOi/3fqhGsU7BE='), or a nonce ('nonce-...') is required to enable inline execution.
[00:08:05]               │
[00:08:05]               │ debg browser[INFO] http://localhost:6181/bundles/app/core/bootstrap.js 11:19 "^ A single error about an inline script not firing due to content security policy is expected!"
[00:08:05]               │ debg currentUrl = http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:05]               │          appUrl = http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:05]               │ debg TestSubjects.find(kibanaChrome)
[00:08:05]               │ debg Find.findByCssSelector('[data-test-subj="kibanaChrome"]') with timeout=60000
[00:08:09]               │ debg browser[INFO] http://localhost:6181/33521/bundles/kbn-ui-shared-deps/kbn-ui-shared-deps.js 380:106115 "INFO: 2020-06-02T08:14:38Z
[00:08:09]               │        Adding connection to http://localhost:6181/elasticsearch
[00:08:09]               │
[00:08:09]               │      "
[00:08:09]               │ debg isGlobalLoadingIndicatorVisible
[00:08:09]               │ debg TestSubjects.exists(globalLoadingIndicator)
[00:08:09]               │ debg Find.existsByDisplayedByCssSelector('[data-test-subj="globalLoadingIndicator"]') with timeout=1500
[00:08:09]               │ debg TestSubjects.exists(globalLoadingIndicator-hidden)
[00:08:09]               │ debg Find.existsByCssSelector('[data-test-subj="globalLoadingIndicator-hidden"]') with timeout=100000
[00:08:09]               │ debg TestSubjects.exists(addSampleDataSetflights)
[00:08:09]               │ debg Find.existsByDisplayedByCssSelector('[data-test-subj="addSampleDataSetflights"]') with timeout=2500
[00:08:09]               │ debg TestSubjects.click(addSampleDataSetflights)
[00:08:09]               │ debg Find.clickByCssSelector('[data-test-subj="addSampleDataSetflights"]') with timeout=10000
[00:08:09]               │ debg Find.findByCssSelector('[data-test-subj="addSampleDataSetflights"]') with timeout=10000
[00:08:10]               │ debg TestSubjects.find(sampleDataSetCardflights)
[00:08:10]               │ debg Find.findByCssSelector('[data-test-subj="sampleDataSetCardflights"]') with timeout=10000
[00:08:11]               │ debg TestSubjects.exists(addSampleDataSetflights)
[00:08:11]               │ debg Find.existsByDisplayedByCssSelector('[data-test-subj="addSampleDataSetflights"]') with timeout=2500
[00:08:11]               │ info Taking screenshot "/dev/shm/workspace/kibana/x-pack/test/functional/screenshots/failure/dashboard sample data dashboard _before all_ hook.png"
[00:08:11]               │ info Current URL is: http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:11]               │ info Saving page source to: /dev/shm/workspace/kibana/x-pack/test/functional/failure_debug/html/dashboard sample data dashboard _before all_ hook.html
[00:08:11]               └- ✖ fail: "dashboard sample data dashboard "before all" hook for "should launch sample flights data set dashboard""
[00:08:11]               │
[00:08:11]               └-> "after all" hook
[00:08:11]                 │ debg navigateToActualUrl http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:12]                 │ debg browser[INFO] http://localhost:6181/app/home?_t=1591085681054#/tutorial_directory/sampleData 341 Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'unsafe-eval' 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-P5polb1UreUSOe5V/Pv7tc+yeZuJXiOi/3fqhGsU7BE='), or a nonce ('nonce-...') is required to enable inline execution.
[00:08:12]                 │
[00:08:12]                 │ debg browser[INFO] http://localhost:6181/bundles/app/core/bootstrap.js 11:19 "^ A single error about an inline script not firing due to content security policy is expected!"
[00:08:12]                 │ debg currentUrl = http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:12]                 │          appUrl = http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:08:12]                 │ debg TestSubjects.find(kibanaChrome)
[00:08:12]                 │ debg Find.findByCssSelector('[data-test-subj="kibanaChrome"]') with timeout=60000
[00:08:15]                 │ debg browser[INFO] http://localhost:6181/33521/bundles/kbn-ui-shared-deps/kbn-ui-shared-deps.js 380:106115 "INFO: 2020-06-02T08:14:43Z
[00:08:15]                 │        Adding connection to http://localhost:6181/elasticsearch
[00:08:15]                 │
[00:08:15]                 │      "
[00:08:15]                 │ debg isGlobalLoadingIndicatorVisible
[00:08:15]                 │ debg TestSubjects.exists(globalLoadingIndicator)
[00:08:15]                 │ debg Find.existsByDisplayedByCssSelector('[data-test-subj="globalLoadingIndicator"]') with timeout=1500
[00:08:15]                 │ debg TestSubjects.exists(globalLoadingIndicator-hidden)
[00:08:15]                 │ debg Find.existsByCssSelector('[data-test-subj="globalLoadingIndicator-hidden"]') with timeout=100000
[00:08:15]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:08:15]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:08:25]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:08:25]                 │      Wait timed out after 10037ms
[00:08:26]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:08:26]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:08:36]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:08:36]                 │      Wait timed out after 10018ms
[00:08:36]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:08:36]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:08:46]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:08:46]                 │      Wait timed out after 10039ms
[00:08:47]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:08:47]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [.kibana-event-log-8.0.0-000001] from [{"phase":"hot","action":"unfollow","name":"wait-for-follow-shard-tasks"}] to [{"phase":"hot","action":"unfollow","name":"pause-follower-index"}] in policy [kibana-event-log-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [ilm-history-2-000001] from [{"phase":"hot","action":"unfollow","name":"wait-for-follow-shard-tasks"}] to [{"phase":"hot","action":"unfollow","name":"pause-follower-index"}] in policy [ilm-history-ilm-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [.kibana-event-log-8.0.0-000001] from [{"phase":"hot","action":"unfollow","name":"pause-follower-index"}] to [{"phase":"hot","action":"unfollow","name":"close-follower-index"}] in policy [kibana-event-log-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [ilm-history-2-000001] from [{"phase":"hot","action":"unfollow","name":"pause-follower-index"}] to [{"phase":"hot","action":"unfollow","name":"close-follower-index"}] in policy [ilm-history-ilm-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [.kibana-event-log-8.0.0-000001] from [{"phase":"hot","action":"unfollow","name":"close-follower-index"}] to [{"phase":"hot","action":"unfollow","name":"unfollow-follower-index"}] in policy [kibana-event-log-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [ilm-history-2-000001] from [{"phase":"hot","action":"unfollow","name":"close-follower-index"}] to [{"phase":"hot","action":"unfollow","name":"unfollow-follower-index"}] in policy [ilm-history-ilm-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [.kibana-event-log-8.0.0-000001] from [{"phase":"hot","action":"unfollow","name":"unfollow-follower-index"}] to [{"phase":"hot","action":"unfollow","name":"open-follower-index"}] in policy [kibana-event-log-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [ilm-history-2-000001] from [{"phase":"hot","action":"unfollow","name":"unfollow-follower-index"}] to [{"phase":"hot","action":"unfollow","name":"open-follower-index"}] in policy [ilm-history-ilm-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [.kibana-event-log-8.0.0-000001] from [{"phase":"hot","action":"unfollow","name":"open-follower-index"}] to [{"phase":"hot","action":"unfollow","name":"wait-for-yellow-step"}] in policy [kibana-event-log-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [ilm-history-2-000001] from [{"phase":"hot","action":"unfollow","name":"open-follower-index"}] to [{"phase":"hot","action":"unfollow","name":"wait-for-yellow-step"}] in policy [ilm-history-ilm-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [.kibana-event-log-8.0.0-000001] from [{"phase":"hot","action":"unfollow","name":"wait-for-yellow-step"}] to [{"phase":"hot","action":"rollover","name":"check-rollover-ready"}] in policy [kibana-event-log-policy]
[00:08:48]                 │ info [o.e.x.i.IndexLifecycleTransition] [kibana-ci-immutable-ubuntu-18-tests-xl-1591082887332744209] moving index [ilm-history-2-000001] from [{"phase":"hot","action":"unfollow","name":"wait-for-yellow-step"}] to [{"phase":"hot","action":"rollover","name":"check-rollover-ready"}] in policy [ilm-history-ilm-policy]
[00:08:57]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:08:57]                 │      Wait timed out after 10029ms
[00:08:57]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:08:57]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:09:07]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:09:07]                 │      Wait timed out after 10037ms
[00:09:08]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:09:08]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:09:18]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:09:18]                 │      Wait timed out after 10031ms
[00:09:18]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:09:18]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:09:28]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:09:28]                 │      Wait timed out after 10050ms
[00:09:29]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:09:29]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:09:39]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:09:39]                 │      Wait timed out after 10014ms
[00:09:39]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:09:39]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:09:49]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:09:49]                 │      Wait timed out after 10033ms
[00:09:50]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:09:50]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:10:00]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:10:00]                 │      Wait timed out after 10028ms
[00:10:00]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:10:00]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:10:10]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:10:10]                 │      Wait timed out after 10041ms
[00:10:11]                 │ debg TestSubjects.find(removeSampleDataSetflights)
[00:10:11]                 │ debg Find.findByCssSelector('[data-test-subj="removeSampleDataSetflights"]') with timeout=10000
[00:10:21]                 │ debg --- retry.tryForTime error: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
[00:10:21]                 │      Wait timed out after 10008ms
[00:10:21]                 │ info Taking screenshot "/dev/shm/workspace/kibana/x-pack/test/functional/screenshots/failure/dashboard sample data dashboard _after all_ hook.png"
[00:10:22]                 │ info Current URL is: http://localhost:6181/app/home#/tutorial_directory/sampleData
[00:10:22]                 │ info Saving page source to: /dev/shm/workspace/kibana/x-pack/test/functional/failure_debug/html/dashboard sample data dashboard _after all_ hook.html
[00:10:22]                 └- ✖ fail: "dashboard sample data dashboard "after all" hook for "toggle from Discover to Dashboard attempt 2""
[00:10:22]                 │

Stack Trace

Error: retry.tryForTime timeout: TimeoutError: Waiting for element to be located By(css selector, [data-test-subj="removeSampleDataSetflights"])
Wait timed out after 10008ms
    at /dev/shm/workspace/kibana/node_modules/selenium-webdriver/lib/webdriver.js:842:17
    at process._tickCallback (internal/process/next_tick.js:68:7)
    at onFailure (/dev/shm/workspace/kibana/test/common/services/retry/retry_for_success.ts:28:9)
    at retryForSuccess (/dev/shm/workspace/kibana/test/common/services/retry/retry_for_success.ts:68:13)

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@joshdover
Copy link
Contributor

As @restrry said in #59083 (comment), the limitation of the extend pattern is that it doesn't allow to suppress excessive properties, which is why I went for the getRaw instead

Missed that comment, however I think this would still be possible from a TypeScript perspective.

interface A {
  initial: string;
  toRemove: string;
}

interface B {
  toRemove: undefined;
}

type C = Omit<A, keyof B> & B;
type D = C['toRemove'] // undefined

Interface for extend could look like:

public extend<NP extends Props>(newProps: NP): ObjectType<Omit<P, NP> & NP>;

Could also use NonNullable on the values to exclude any keys that are undefined or null. Not familiar enough with the Joi API to say whether or not that's possible in the implementation.

@pgayvallet
Copy link
Contributor Author

pgayvallet commented Jun 3, 2020

public extend<NP extends Props>(newProps: NP): ObjectType<Omit<P, NP> & NP>;

I'm not sure this is as simple:

  • The newProps parameters would still not be able to have undefined keys to erase the initial schema keys as type Props = Record<string, Type<any>> does not allow undefined keys. We could allow them, but not without ugly ObjectResultType type hack to exclude the undefined keys from Props in the equivalent ObjectResultType. This would still pollute the ObjectType signature, as it would allow to do something like
schema.object({ doesntMakeSenseImho: undefined })
  • Even if first point is fixed, the return type ObjectType<Omit<P, NP> & NP> would then include the undefined keys in it's definition

I think we could add a NullableProps type that would be used for this extend function

public extend<NP extends NullableProps>(newProps: NP): ObjectType<Omit<P, NP> & NP>;

with

type NullableProps = Record<string, Type<any> | undefined | null>;

but we would still need to adapt the (already complicated) ObjectResultType type to remove keys having null or undefined values using NonNullable. Note that (I think that) the resulting type would still be polluted with key: never entries.

I can try the approach if we think this is better. It does avoid leaking some 'internals' of the object schema, however I'm not sure it's really easier to use, as omitting keys from a schema seems like more natural than setting them to undefined

@pgayvallet
Copy link
Contributor Author

created #68067 as an alternative. See #59083 (comment) for the discussion

@joshdover
Copy link
Contributor

Question: do we have a real use case in mind that requires extending a schema + removing some keys?

@pgayvallet
Copy link
Contributor Author

Question: do we have a real use case in mind that requires extending a schema + removing some keys?

Not on my side. @chrisronline ?

@chrisronline
Copy link
Contributor

We need to take the existing Elasticsearch config schema and:

@pgayvallet
Copy link
Contributor Author

Well, anyway, it's would now be possible with both implementations 😄

@joshdover tell me if I should close this PR in favor of #68067.

@pgayvallet
Copy link
Contributor Author

Closing in favor of #68067

@pgayvallet pgayvallet closed this Jun 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New value added to drive a business result release_note:skip Skip the PR/issue when compiling release notes Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v7.9.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support extending config schemas
5 participants