From 729acf76fde55f0ac3f0f7b257d9a014ba392073 Mon Sep 17 00:00:00 2001 From: Aleh Zasypkin Date: Wed, 9 Aug 2023 13:05:54 +0200 Subject: [PATCH 01/41] Refresh `.security-tokens` index in tests before simulating "missing refresh token" scenario. (#163466) ## Summary Elasticsearch no longer refreshes `.security-tokens` index after token is created, and we need to respect that in the tests that simulate "expired refresh token" scenario. Checked locally with: ```bash ES_SNAPSHOT_MANIFEST="https://storage.googleapis.com/kibana-ci-es-snapshots-daily/8.10.0/archives/20230808-202136_29386737/manifest.json" ``` __Caused by: https://github.com/elastic/elasticsearch/pull/98102__ __Fixes: https://github.com/elastic/kibana/issues/163455__ __Fixes: https://github.com/elastic/kibana/issues/163456__ --- .../tests/kerberos/kerberos_login.ts | 6 ++++-- .../tests/oidc/authorization_code_flow/oidc_auth.ts | 3 +++ .../security_api_integration/tests/saml/saml_login.ts | 9 +++++++-- .../test/security_api_integration/tests/token/session.ts | 3 +++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/x-pack/test/security_api_integration/tests/kerberos/kerberos_login.ts b/x-pack/test/security_api_integration/tests/kerberos/kerberos_login.ts index 588ff9125a21b..e73bb06f0203a 100644 --- a/x-pack/test/security_api_integration/tests/kerberos/kerberos_login.ts +++ b/x-pack/test/security_api_integration/tests/kerberos/kerberos_login.ts @@ -431,8 +431,7 @@ export default function ({ getService }: FtrProviderContext) { }); }); - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/163456 - describe.skip('API access with missing access token document or expired refresh token.', () => { + describe('API access with missing access token document or expired refresh token.', () => { let sessionCookie: Cookie; beforeEach(async () => { @@ -447,6 +446,9 @@ export default function ({ getService }: FtrProviderContext) { sessionCookie = parseCookie(cookies[0])!; checkCookieIsSet(sessionCookie); + // Let's make sure that created tokens are available for search. + await getService('es').indices.refresh({ index: '.security-tokens' }); + // Let's delete tokens from `.security-tokens` index directly to simulate the case when // Elasticsearch automatically removes access/refresh token document from the index after // some period of time. diff --git a/x-pack/test/security_api_integration/tests/oidc/authorization_code_flow/oidc_auth.ts b/x-pack/test/security_api_integration/tests/oidc/authorization_code_flow/oidc_auth.ts index f1aef15c081f2..9ecdbd311a109 100644 --- a/x-pack/test/security_api_integration/tests/oidc/authorization_code_flow/oidc_auth.ts +++ b/x-pack/test/security_api_integration/tests/oidc/authorization_code_flow/oidc_auth.ts @@ -621,6 +621,9 @@ export default function ({ getService }: FtrProviderContext) { }); it('should properly set cookie and start new OIDC handshake', async function () { + // Let's make sure that created tokens are available for search. + await getService('es').indices.refresh({ index: '.security-tokens' }); + // Let's delete tokens from `.security-tokens` index directly to simulate the case when // Elasticsearch automatically removes access/refresh token document from the index // after some period of time. diff --git a/x-pack/test/security_api_integration/tests/saml/saml_login.ts b/x-pack/test/security_api_integration/tests/saml/saml_login.ts index fbb7aa25fa162..8358f24c5d028 100644 --- a/x-pack/test/security_api_integration/tests/saml/saml_login.ts +++ b/x-pack/test/security_api_integration/tests/saml/saml_login.ts @@ -593,8 +593,7 @@ export default function ({ getService }: FtrProviderContext) { }); }); - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/163455 - describe.skip('API access with missing access token document.', () => { + describe('API access with missing access token document.', () => { let sessionCookie: Cookie; beforeEach(async () => { @@ -615,6 +614,9 @@ export default function ({ getService }: FtrProviderContext) { sessionCookie = parseCookie(samlAuthenticationResponse.headers['set-cookie'][0])!; + // Let's make sure that created tokens are available for search. + await getService('es').indices.refresh({ index: '.security-tokens' }); + // Let's delete tokens from `.security` index directly to simulate the case when // Elasticsearch automatically removes access/refresh token document from the index // after some period of time. @@ -700,6 +702,9 @@ export default function ({ getService }: FtrProviderContext) { [ 'when access token document is missing', async () => { + // Let's make sure that created tokens are available for search. + await getService('es').indices.refresh({ index: '.security-tokens' }); + const esResponse = await getService('es').deleteByQuery({ index: '.security-tokens', body: { query: { match: { doc_type: 'token' } } }, diff --git a/x-pack/test/security_api_integration/tests/token/session.ts b/x-pack/test/security_api_integration/tests/token/session.ts index f42d9cc93585f..3e8d44ce247cc 100644 --- a/x-pack/test/security_api_integration/tests/token/session.ts +++ b/x-pack/test/security_api_integration/tests/token/session.ts @@ -189,6 +189,9 @@ export default function ({ getService }: FtrProviderContext) { beforeEach(async () => (sessionCookie = await createSessionCookie())); it('should clear cookie and redirect to login', async function () { + // Let's make sure that created tokens are available for search. + await getService('es').indices.refresh({ index: '.security-tokens' }); + // Let's delete tokens from `.security` index directly to simulate the case when // Elasticsearch automatically removes access/refresh token document from the index // after some period of time. From 4fc9906c17206a67426e743984d8d628f7b14321 Mon Sep 17 00:00:00 2001 From: Stratoula Kalafateli Date: Wed, 9 Aug 2023 14:16:02 +0300 Subject: [PATCH 02/41] [TSVB] Unskip tsdb tests (#163471) ## Summary Closes https://github.com/elastic/kibana/issues/163454 Now ES doesnt error out for average aggregation in counter fields. So we can remove the test for this scenario --- .../apps/visualize/group6/_tsvb_tsdb_basic.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/test/functional/apps/visualize/group6/_tsvb_tsdb_basic.ts b/test/functional/apps/visualize/group6/_tsvb_tsdb_basic.ts index 35769d524012d..44953ae2e6619 100644 --- a/test/functional/apps/visualize/group6/_tsvb_tsdb_basic.ts +++ b/test/functional/apps/visualize/group6/_tsvb_tsdb_basic.ts @@ -17,8 +17,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const testSubjects = getService('testSubjects'); - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/163454 - describe.skip('visual builder tsdb check', function describeIndexTests() { + describe('visual builder tsdb check', function describeIndexTests() { before(async () => { log.info(`loading sample TSDB index...`); await esArchiver.load('test/functional/fixtures/es_archiver/kibana_sample_data_logs_tsdb'); @@ -62,15 +61,5 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(isFieldForAggregationValid).to.be(true); expect(await testSubjects.exists('visualization-error-text')).to.be(false); }); - - it('should show an error when using an unsupported tsdb field type', async () => { - await visualBuilder.selectAggType('Average'); - await visualBuilder.setFieldForAggregation('bytes_counter'); - // this is still returning true - const isFieldForAggregationValid = await visualBuilder.checkFieldForAggregationValidity(); - expect(isFieldForAggregationValid).to.be(true); - // but an error should appear in visualization - expect(await testSubjects.exists('visualization-error-text')).to.be(true); - }); }); } From b59af8b63789fc0359a67d8a1aaadce62dec6b4d Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Wed, 9 Aug 2023 08:04:34 -0400 Subject: [PATCH 03/41] fix(slo): Active alert query (#163404) --- .../slo_active_alerts_badge.stories.tsx | 2 +- .../hooks/slo/use_fetch_active_alerts.ts | 19 +++++++++---------- .../pages/slos/components/slo_summary.tsx | 6 +++++- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_active_alerts_badge.stories.tsx b/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_active_alerts_badge.stories.tsx index 08fa152301d43..3aed4658ab766 100644 --- a/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_active_alerts_badge.stories.tsx +++ b/x-pack/plugins/observability/public/components/slo/slo_status_badge/slo_active_alerts_badge.stories.tsx @@ -25,4 +25,4 @@ const Template: ComponentStory = (props: Props) => ( ); export const Default = Template.bind({}); -Default.args = { activeAlerts: { count: 2, ruleIds: ['rule-1', 'rule-2'] } }; +Default.args = { activeAlerts: { count: 2 } }; diff --git a/x-pack/plugins/observability/public/hooks/slo/use_fetch_active_alerts.ts b/x-pack/plugins/observability/public/hooks/slo/use_fetch_active_alerts.ts index 319f3e57a4a4c..580d72e550e6b 100644 --- a/x-pack/plugins/observability/public/hooks/slo/use_fetch_active_alerts.ts +++ b/x-pack/plugins/observability/public/hooks/slo/use_fetch_active_alerts.ts @@ -19,7 +19,6 @@ interface Params { export interface ActiveAlerts { count: number; - ruleIds: string[]; } type ActiveAlertsMap = Record; @@ -37,7 +36,6 @@ interface FindApiResponse { buckets: Array<{ key: string; doc_count: number; - perRuleId: { buckets: Array<{ key: string; doc_count: number }> }; }>; }; }; @@ -77,20 +75,22 @@ export function useFetchActiveAlerts({ sloIds = [] }: Params): UseFetchActiveAle }, }, ], + should: [ + { + terms: { + 'kibana.alert.rule.parameters.sloId': sloIds, + }, + }, + ], + minimum_should_match: 1, }, }, aggs: { perSloId: { terms: { + size: sloIds.length, field: 'kibana.alert.rule.parameters.sloId', }, - aggs: { - perRuleId: { - terms: { - field: 'kibana.alert.rule.uuid', - }, - }, - }, }, }, }), @@ -102,7 +102,6 @@ export function useFetchActiveAlerts({ sloIds = [] }: Params): UseFetchActiveAle ...acc, [bucket.key]: { count: bucket.doc_count ?? 0, - ruleIds: bucket.perRuleId.buckets.map((rule) => rule.key), } as ActiveAlerts, }), {} diff --git a/x-pack/plugins/observability/public/pages/slos/components/slo_summary.tsx b/x-pack/plugins/observability/public/pages/slos/components/slo_summary.tsx index 491eb2e8bc09c..f2a6fce036ebe 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/slo_summary.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/slo_summary.tsx @@ -87,7 +87,11 @@ export function SloSummary({ slo, historicalSummary = [], historicalSummaryLoadi defaultMessage: 'Budget remaining', })} textAlign="right" - title={numeral(errorBudgetRemaining).format(percentFormat)} + title={ + slo.summary.status === 'NO_DATA' + ? NOT_AVAILABLE_LABEL + : numeral(errorBudgetRemaining).format(percentFormat) + } titleColor={titleColor} titleSize="m" reverse From 21b33e4342ba6161b5cb8dd6dd492c07aa857c7f Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 9 Aug 2023 13:45:11 +0100 Subject: [PATCH 04/41] skip failing es promotion suites (#163486) --- .../api_integration/apis/metrics_ui/log_entry_highlights.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts index fd87af88ebc8b..f1be3edf0f4ac 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_entry_highlights.ts @@ -45,7 +45,8 @@ export default function ({ getService }: FtrProviderContext) { after(() => esArchiver.unload('x-pack/test/functional/es_archives/infra/simple_logs')); describe('/log_entries/highlights', () => { - describe('with the default source', () => { + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/163486 + describe.skip('with the default source', () => { before(() => kibanaServer.savedObjects.cleanStandardList()); after(() => kibanaServer.savedObjects.cleanStandardList()); From fd2815234875a3e432993b2da4c2fdb1796e7625 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 9 Aug 2023 08:24:03 -0600 Subject: [PATCH 05/41] [Dashboard] Unskip failing `embed_mode` screenshot test (#163424) Closes https://github.com/elastic/kibana/issues/163207 ## Summary Since Chrome was updated in the CI environment, our old CI-generated screenshots were outdated - this PR updates the `embed_mode` screenshot tests so that we are once again in sync with the CI environment. For more context, please refer to https://github.com/elastic/kibana/pull/160085 ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../apps/dashboard/group5/embed_mode.ts | 3 +-- .../baseline/dashboard_embed_mode.png | Bin 131944 -> 129613 bytes .../dashboard_embed_mode_scrolling.png | Bin 92543 -> 92765 bytes .../dashboard_embed_mode_with_url_params.png | Bin 142900 -> 140548 bytes 4 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/functional/apps/dashboard/group5/embed_mode.ts b/test/functional/apps/dashboard/group5/embed_mode.ts index 2599326daba43..16934fc9101a8 100644 --- a/test/functional/apps/dashboard/group5/embed_mode.ts +++ b/test/functional/apps/dashboard/group5/embed_mode.ts @@ -24,8 +24,7 @@ export default function ({ const screenshot = getService('screenshots'); const log = getService('log'); - // Failing: See https://github.com/elastic/kibana/issues/163207 - describe.skip('embed mode', () => { + describe('embed mode', () => { /* * Note: The baseline images used in all of the screenshot tests in this test suite were taken directly from the CI environment * in order to overcome a known issue with the pixel density of fonts being significantly different when running locally versus diff --git a/test/functional/screenshots/baseline/dashboard_embed_mode.png b/test/functional/screenshots/baseline/dashboard_embed_mode.png index 0c6b37523367931aec8b5d1819be339c9ab72f54..592cd6c4ff4036976b571165fcda8938f93f9d6d 100644 GIT binary patch literal 129613 zcmce-Wmr^g_Xj$NfJ%w9l(Zn-jY@}rG*U`;*U*U4Aq@fp0@B?h-93naLpKcFJ;d4g zK9BGJy{>bek7s{TX74-Jx>x?zxiRPokdeX@Xf@Q@eva;f)l-JkK6p>+HsI$ki!^OJU2{9neNPrczs3T8CN)ZCcUIhj&Vh+*z?PFHRKTmJM%9X3O(el!vC?6l2*clXEVsT9+ zLL^4k(~QV08!v9szfHy8^nKX+*aktN`YGG#mH;`9jV6X>0|hQWX5096*!5SMe;;~w z_c!dUqN4M(qrXPkCNwiY8mY>okL1N2oK`OEZAFb}b9G6AlyNZ)Ac;?)i5-ircJ5zN zOqW|nND4Jh+u+kplBKNwPNqspV9|RNI@))BQNOro*KNX;sLffCLyCp2$UqCBB)amR z2@y(BpP~-^mza2_B$nsW()3Hqrfo)?36dhFL0v}e@Se!t{LWuEf4Q48Sa0%*v%{*( zsF@3HSCJfIrDpp{>CbnC|9&b98T?N1(oy?TS0MF9xT`szE~-0MRrqH(1Ftu< z)=|UGmP~bO@xKJ<5*B8XWPI&gQFg1m$ynE$K9gdsU>6Ea5RR_0(jwTK`5gvguTu?E z{Z~?Qt_nFMAj@jp8=}@nXkDF0CAW-U#j0w*#Fvhz{-yX)Q9A)a9_wv*NPRVC?JY;m zG}?6gvMSi5Yn~o2@$Y6ot5QD-Gu#n@@%zcFLd(GAevs*wbM9DPzl`Uw@_(0Ej}W;a`|+_TG+rt^ski0gbjX2lhPu7gvl(z zcTx!x_Dn(iC0Vb4xs!RAlPN{8%+D{2_*;Mh^i-yW^EtxR!-jds;0DECt&fx*KlAS< z(cZG4bu|Ww5%;JdY)%T#_uWnIy;Q2;&^;y#%s>5E=nXq!OZ52fW($p&o+lpvL=f>_ zJ3R{fEX1CHru+9TojsvZ0)jJr^ZoM`LG<^EJyTtHQGb{EtWk{CRm<+9Je}0c4pRXA zWTx}yOh079VaPFEh5G0repF*U{2$Jw8R^G=rwbOlwSTGBJnt22d;mq**_^lRu?f^_ z`ZFpY+v}-*`%Akz387Ihw|{hS3KiwHbOysXo2TAvbZmFV9#h1pvM)BT+`HyP7O#Xo})#TOz8k)@+%LJjW=88K;n&q3hs z4NMX9HBn<5?kGU6UE*frhCyjZRBEM{JyFK=cZNBF{LEz5de1)GTkO&`!zK8C?Rq1j zMQ_z#8Xx3mKL2+V&F9Sjn$r-1AO-Kej! z<%^ZCl+gT4rV=ml=f4xunCg4Jdlv(Pe=+~}H1L=>2nqfwdQPjl%6~U~kDGYaB)DU- zP~eWOooHC-5*5`&jmp3uIW|nCjb+asX{d;Z$EX|K@j$g!-!7}*KX1L6`tBJAJOcPl ztM$aPZaP8z&c?;RMGr*D9ucgH1S~heR)IG4ImWw@z6A7pFT%o!2!`K0x8>7?Z8_Jy zXuI176Io@POkkV;tlco!mMeuV*Ue~M+be+dy|0_DnBGZ#BRyz_ zZx;73yW+Up@=io$Z?@eqG*hvQ#)HP!6gjFg^g2Fwe2720)1Y`|oZvtf>$W2?t-h*E z58u}haYRH}vySnFkP*Xx6}>1eX6jJDh{d2BM^&7{s?QxuSCiV_ zw+^Y6Hx4I6Anbc7`(s57qh{@TMrYs1eZN~>(1bJfz{PzaVfxkXx50ko9T)ps!dHDt z-Cn)IgE1uVrLvmW|Iwv*W!SfY?ldSKFuTfsm=dGMvgiC=53S1?G2GXj-<8EU_Gi`f zE+ZHdB}BMW2b^)YN|%%GocnGsffh6~GkItG(~PJ5oexx
    #)ye8M^&|7sV2JkE< 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 z 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 literal 131944 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

    |IQcC~~4SpP{B!(u0tz#9Hc+SoD!yF+=e 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⁢X_d&AjzR5)!qRd?B--D8dHZj#u2nfR>5ek> zIVw1sKcT;sMj_aMWu(Fc=T=9>|&JaCYQfUARA_81Vo~oPn*7z@M<} zbTJQ(B8Y?w(58Ccsp$ng%vKn(4Vz5_0kBVEa|l>`mosM)Z+0nSS`i z60}JvH$#1GJ^; zdSbrK$d+mdy$hd*&nsAMa+RU?pxNzz_8p|;wA+8iZnWdm@Z%v&muG#b#|365YF+{c zrlwtoPve`J`#3|DIZ25r@u@tPcku-a@yPmXD=S}OpGz<_2{K4pr#1f1R%g)s)CQQ1 zXQY4L`bpD0(5;nXbp-*7oyGGKttIs=G<}|V`L@mo#w?XNT0V3g@y`XY?R~SM+f=JG z-rBl04DgvRE)}9spn`iBSe3CdIhR$0 zfq;}Hg2LX8*CNc6GbHyjy;eBZYeNVH zt`m?vgzZoJvx?P$o)ETRkLZ7MhdxjLafkjF6?e>@8yeP*E?xySNYV4O-JY~(*l*4a z)Zgy8{tp?OD&>+)u}yX~`*#PNb?L{n%;#;Wm1)%?HK6Y!InctMT2NY$0KpTj_f3+> z{E=FtuVed*y6l?-1j?P!sHK_W4E7r(sh~JWHvFmdETAYpS6S^I5&BX&{;!g@%tv+{ z4}w(UYr6^Txd{m7^|B}8u%^os$;ggvCRT*0&qK4eT5f^5PB2 zwwPlp^YyuSo}gJMuj<4~^_IB9wgPbUzAfz7V399C`UJeIGw1rtp|;0^Cjii^wz_mFw> zU$tE32h@vtyjWcdv{$}f_$M!@rzt%Qy@fvi`woAO0=pLvobAv?ltc`L;`#Zr4HR-u zBz&&Iouv}|56X7D5&&p8*aT~Wdu;`5f)^)89F+&;{sbwttqx~nWgFf7MYwp>#|&K~ zaJpo(ui^0&R_0ZqzwxG~?hqB-YR*5GLdKeec~g1Io?(hv;W(jbLN_)vTh;JqqOy&{ zcVA!JUMXR@7$KZA*=3`icbb_R_4iuVtj0?zGP?ABmUA{vO(`+-0ULvB6pYD zVgg!EjZfoa*pZo(?FgyO)Y1~7Zhw4ws8$e^g-M`CMtFk^%VmER>lWKrpPH(&DXA$- zC{CpvJ4cJ?01a3gO~VYPIwDAWMqx0pf}6efUwCcPdZ48Xuf;p#XA4hgL+57Wi3kWH zDJ|Q_X8ir|Um1E@-eJD>%8*lmcSmw;yA*wZ#ex%V_%lK41eA|-h*(d`iF)_Ina9eu zwOnX352f%6< zI#1s1&rc|w1WC3H&lI<3-D=1r`w4my8%&kE4Au5gc|o9Ea5+8Ppqy+0T@DlgV}egW z^yYCLLH9+K4v~LH8FXM z5?M3I%3(yCZ9|Ezk9G_QXeLQc*2&-{0vkMO{koe1c*-ApN~>}A z`F20V(@X0gKpg_TwDec<{afVALjQLS-_!6L#i@^Grr+bWL0U?E3mLFVI8#nbzM-769rm%2Z&C4a{0r32p(P7g+Z)zSP zyFF8>=-%PrFoQ+w-!JiuzG0Qz(H8bU^NM}vb6Vy{|GriEZ8zaZj{GkV^GZ$qWFL6m zoPWlE#60aurdsI#j>CFu`D3OxNt>qD?97af=pj2yl!L(o0_~PTK|u!A*4Qm81BvTG!ZFBn;Cvc>OvG><6>D)YGL|oek-Kg29Hcj|?CQ#47U; zOx7bKf}Kdhyw~=1$|^?z{bQ~|33wn92*m$c$4l$QKo3{O+y;Cz;^$-OYgww-Sy@^A zn+ySN0$f`x=|7500#fvzy2v6>G~+G1f_yi_X-Ng}LSI5StfA3@)wq`PezNT&Q`vuo z=>JWKJ5yZfBlGd&k-6v?Ke5H|&U*&fG0MvOS&4_MlI!WocM0EJ{h7%eykx42A)cpS zUpU16Ay`6nN|rpgW1An6~2nJi~E_piP*`IIR?CnSYh*Ft=I0yX_F*7#9rNLqGpdtLke_%DEYZulX>fhffaj)@jOy_Mw zbzDNdZySz;E^Bo_GDk8E?xcv=_p5c*mWvDeCI)t9my60l~K*k9}fE+RtJ{3#Ket2rceMzXIr;i5`C2f8*oL zNAT5dQ6R7S<4pm=9#YpBZNn$IZZ>?J=p013_Fp}*grt_Ziaj`dza4^nPL$pqoIuq~ zZZ4jdnbAB`Q*$=>Y}yiZ%?i9~nIw}Wp8vQMpqi#N8tyOo+3Z;&!?X|f)3cap?U^4H z44oh98os-~J)E^n?GDYnY+-5`Tv76E+Sm%MxTP)m_Y%1xla**iI3;r}nVg5S_N>?|}ObI?BIhS2}s`{?DxS(NfrKG37Lkx`d0OG)H+~c)HRuOIK72= zO17uAq@jAb{0nE3ciW4es$}8+a2*8K{^JVX{;ec^m*}V1Q!0shn{45NJFCq0{_XvC z`%_|KT!a#vQ>Sxmf{@GRRTg#Y$Drg?%2vH!Y&jcP|Na_`BO8D-;@$Wxt^J#MBYGRn}`! zsD9vZ>%UpDYkT_ZzK5U}nTM7O#O&+911omK))7Nmkz|{4Y`#1@>3O!s6ff+awC^-o zEkiNge}RfGC@E29RUh()ILN}`C|ekY&f-&1kzLu}NcrMq-`?Jijj-AO?o~OazilR% z-0&TC=lAcZUGK7LV&z(+r|2P|kbg7<81EPWP>+DPza`%ex#x8l9jaci3w&W8uLpWD)s1opI6(h5M0p^M?AQejVjOGWA#+c%%OdomHA zkVw`~V+MGQxoz1-mJrZ(f}EVYIon?{wVLqq@;a9$^GU_TXz1?VB|ty}GAxJHzZAH! zhcCN7bGmFFs33lNKS?R@6xZtE6gUF8*gv#3ARKAswv&U|Hr;k>wFZc$d7E3zJB{|iA%R8n#z z1G97w&#OqX4QUa#Bba?udGykpcba*If0zZWlmgZaJz2F*4qq*=9z z^z{F_j4m3&4SEv;HJ(~WZfNDk;rvhv`SN>zZ##j?uL~O3NuIh8A5z^@&%tuX6i+e= zjd{Vz@hf7bWGh3_UC6u-O9ixLoT2_q6d>I6+}<*}0WfyR599X7>gw3|z{>4LPbNdd z;o%y4B2a`jK*yudZx8&cw1olMy#lQU9I+8MU3PXXad7N4w4+*9cqlfv#BVsg8TW?S zhs~fqfa*n&zH={O56bX+!S&Gi5MAg9tO7pb5j5Oh72FhsR+hM^!3XuAJs&<++#*D< z>7HXkp`DMT#g~QbaR}0EVKu(;7!mHT{{5hy->`X>Zi(;)0(=G-`^~k#%U`+79_-T` zCS=#ZoCX-`h&A7?Z8*73)17K7{wa=wghs^k1IUU8D6@ZdJeZAY2wod|e6QVwq_Df2 z5iM+U9ILRRqGxR1nt^hAuk%ZG6+&ljivl2>+>qO_FagL|tnMw{)=X2*4OD!c%g6Kg zQvWFX%cLb#34KJ6KBCs5k0oR6OsBNOb1j{-4L)6O9yPbzA%by?{q|1J#}zC>${cCB%y?5QjDI^ z07QPKP`=zOkA&gQTd(AUxIh^hbuh8?z zYuugQ!j3{bzVJlb4!s*xfAJCBaO`5-dHy(7?R|^0S^3okAhydM^9|#6@|=ZN+oFzm zFc?xiycrjPsBw2}sy;HqYDW!O&os8&mP-)87#)3ngSwwoI^=}z&J;QNbj)vK@t=>i zz_s4Le+>vC)pn6HQCI+|fI}pz-aqro<$Ek9MhmdY-EiXztYXD{tIv$>oHoBr-<*5$ zys^y1NR`JEbs5$G-7VI5l~bFo32k!NJqF3Q6wcK3qrJqqy5@;YUB9@!rnvyK(W4{9 zIx;}9y%{ScMSysLy(D41+P2T>HaU5sbXopQvaEBK%9se&Kp4=2X3Iy9N*X}%g)Z!U znl^fy&*ZDt31MK6Q@$^sBy@W`kOo z;Zcv;N6(gfr8u~_B<5oIOxIAD!otFTD=0qv{3(boAHQThUJo69ZFUB!&}u#ehxy#i z?-~_&m{&r4^YZWniY?w7h@Xf@wEikLxe%ag?@gwJhj^2QCdB_Y-*C;r9lY~h7O0Gk zqFdHix9%GlXx%7## zXBaV$4}44IDBvm^(l^vG5xzGl0_!nPu5)=ojlFV&)-T3`3(r2@Zvsf_oke-+rt78V z)^%X&Y@D3Lx-UkmHa64SE`nyArEns8Xelm_v}3$my&DkV?lDe*y}qW{RKs{_9qTGB zGnXW^kfD8dJ)*`L$1*7`aQ&0Lr&q+UTcf?b#f+Ad`KUJIm~f#Zdf~yA6CtBnlOQra z<>h6v^Yh1MYkw=Wi@c&U7JWsPP3p%aN#ipD*@U_->?dn$BHRuOJY#sILqt6CSN9() z;uy! za9@ygTyv|0vRYR;s+0W-J_hH5_?m3Jno1b5ty>@KNfXg9dN!59 zPA_A>DEHz|0Y}Zjx!-6NpH>(#wVpKgEYWGcpv`9Dh3DBZW0q5{*0I%$`q8_df&!wd z=Yy4wERuP8Ird#-cVx6G%uB??#rsd^Ot#7O_~R5LrSjVCJ%UC{&2(oDD)tsoFKVrkHV08;y$-RGeWo~+x{(&zdDp8gh_tW1vmS}&{0tAa>G4F)J!_7 zYCh!!+oi`ZhzcI}WN4SM39R)ikc&9MuZ-vTeN)IlFXp12i*B5tvnogy8DtKGH_Ocjzh_C)R4C$Qh(DjE zyS~^FouLB%zBXFIy^peXoR}&yE*f!Yl_WK7D~^UQ?#x!nD6Ks;uT~Jq%F}aMzX;f? zxNb4TEpKdMvi$R{3j;l6?>nDo{iX6OG7yelF+cv4;Ak?`2TB)Ko<=4ns*9t$+)hbnb ze`Sy7_%LCH!ewf35P>^2V8C|D=0j=t&noVAZNt-Ke<;&8u3F9rqjy!mu1e?X4_m z`(=4uh#aLWSJ~-=(Kl{hnM0oI65Ma(aF}j7idu3x8gRB7q7|~+`oTTn_Bx`}dNRw_ zNF=l|RM6aJyfWxIem+q*M-R7r&GB)SR>3B|@ZMZw<=hO;r9mfKj(IYs_$ve1s8Y2x z2kjguE(S~CZ^>TxO{mFVm(T2%5_!|_wX4)i=V>>Y6)o@jhxg~`iSOl2D%Gs;DESEx zkgOY0Ayic{@QE3g_s6XIRl2HEb*uI>Ra*AlcJ@g3j-qCF;lKV06=~#dz2J3R+)($#ReM`VNiP_Lkr7 zepSluX`po`2!?^R+;mw$iuK|Qd_$@%m#* zD7Y^UBr)`@w{xAP%+~YkP@#Ss#v=rY?+RpAR2jwMRwPVKQTt)3Z}Qby2#I#B4Xe-P zKMnat&|4}BzOhVtl8syw5THwrcN?%sjNc>AeqD1Vd)-Du_ZC7`v$W$)+5P!oJPvsk z>JVwYe08>{XI5p}8Qj+9jzLXMTgF4n=k6Q*#!-5=x!2r;sQKe6D%JubbM~ehFEZwz zd8t5I!()rf2-OED-nHIi)~bOddHX$~BBP(9tx(JyE|p7*VjMsiQ7{2 zTlSinw3RdrN$$ujw%{6N;K9#Hb1Fe)BI9gI^5fhs)CF~N%?C`*#1TwMXNA}#goMc; zxaFtBgFhp0crQlB_(w+4%o83L-WZD$u>6v)a3aHAcUWvbke3#kBBCrSn|)8=kT!7- z1HqjB0#$0!9?YaGlA7OOfo(!e&0Gfd6xFP~KG;2G-TVGvQg?L-OF-!c@g>Q`S316- z>@PdqMek-fTo`HSk*npber@KJP^%5Rr|Vx}!P9J5m_eh%6iFa6C?Z>|>YqaF{!ro)G6+jt$0a?!6W$v7eGE zxs>@xY|Sa|mY#Zs&yeuK*CFo6xi;m1_B7Rl(Af4gV&~xJx>jkG$OHS3d1U;?`PQKQ zjlvOPYVz#O&wsTgOnH3#KFn2k&1snW(~4yuB~TC$W^Z;Y#Sv=-h590tWK^>W0uTtq zqg!;u7{t=PE#d4hBU1f^Fbw4xXO$6&$psD{3=;>BF%Ssvy?~Xmo()W;zGYSU3>A5c z51P6lM2l#vw07>GC8_00Rk?;hC>_nMp{VjF7Ym|vy$T+TT|pookC=EIU6Ryq;o6{Z ztC9LSNeo{&-;Uzh-rMp}iQf@1xqWnk91x>2R#Vh0g)BfRlFZju?(6L(rNVB@Vh{Ul zT{iW{lQ+@7)isn+L|PD-?Zq0Ga*R~)lQ$TM!=RF1Dp)LCcHj^rKp+wy%$3^>)w5+z zk}{q15L@!bdevJ^l30M_Xj~@CR!(t?CV@}#{^9&cxN)+@{?R!F)shV~vvxBs8v{3= zMn14}aPkc=_8ZTzKiqa=^6%drZBc7Sm+c}9LzUD1n5d|!m2wsRxU}yJpTndNu|iv0 zo5*_lgJ{i>Hs<+YFZgkRf{EI`?FsVj6h3i?UgDTlSv&k$c3|ebKOpJ`mx&Lsy%cz&sHC6Uc z)()kZZuM{2cW=O*7O2V`BaQh5lm!TxM&FcP)z0X-YbR-b@ zN$xUSEKO~}#u7`HE9rEnyM9>R#R3i~ZsTXLj=!q&GtdiuQz!r)P?bV*ex3TQX~Va4 z#7K;keE;e=1^v6VO;t#WN=jr?EZ#lzVPZ0EYwM}vB^?NTu(IcCK-ovSD?B;0Ay}y* zTZa!9{)TwKI($1nYYCMSxwj;7Uor8kbA;hUiM>ahl>Q>u#tu?FJFxF#Y6_fI8^eI2 z1^J0!+JA3opq4achC-8i{~zDp9Gy^2IlXcv6{*%PbS&gqvEIBm5EPHR7&4XuFMgdLH1QVcqH>r3KW zcWybXF13W{{U~@q%r6GzfJl^U+kBb>jDSaAJMep!{}Xq70v$hpN_){^q6gYsgj zF?q0$U*PF($&2n!5wkVa@V2+kyD`I9pa|A`g63c;Jn}J{w?$)`Z=W(+$ktf{y5Jmpd9wi$1-z9+nMp# z@*VVU%KZ6F!B6ZPo@=$#+qa3Thmord=|U&Oyjp0h^47Nc&kNa6QXGj%*2$}q`hFZ6 zzAOV`;<9J3cMt_?CEYhG9v0z@ze-C~4yZi|3qB%4f8DH03Ng-c#dm4uTjfm2?5f;1 z-uIxdBhtHXc{4v{X)IBaS>S1hAbDW{LBQot=wCs(6v?+4jTW6PH6u~?j`Q@?zbF_g z1V5XtjZZu~G5XHN!1P^*By0JhiI%QZVN-Ln`D*!ATW4o!C9w?2#tA0kj`iau6lz{r zZTRe6o(CzfCE5lVrxb{2D908P4=UUl#&P4Ye!b)J<>D+PhR1rXt^{QhlUI4{maALE zb_Z+0acs>wOLJ#1ASjS!%OZ+ZKQBtpQ(ixajI_Wl-fMc^BSCm$?TA!QWZDTvYGvY! zoYKE^yfqi8KG{tdB9avm(eGX2x@@eD{tURVYZ|d4vy5{6?fKPtqUVP@`qkv`lFG!vs73H(~+jg#|A^JTPS^4T$9z+wsNX%a94pmLk@8A4AIOeesb;|e`%)xDiukGJ zdgA6P7|A=fmGOwQ|C+JiYqSe>tcG3sv+%)4+B?#beR(8XUc7K;Z>)87_LhD~4+E(_ zNOkBfhs$NcAU>Ddqp``;DqG8B$*)w4EqfD5&#G4~@h7Hi5VDoroV;2+%TdQc*0S+w zn!OTuh`1F?TqPSWmGNZfr<_!Sj;KM@HcOrws+5Z7<>Q>5yh;BtRe>xlWIvpHa?+;hRRgZOw<2gJHEVk`4@fxF(MkXp`IQ4kHeZRMs zx`AF@;iLXdj}5P;`KXm~=ZXHRjp{7uD8lkx>g&ZK3tOEkpq`bB6W9ZJjbIxk;9*YSr)L`yV7{jxHq&~9a zwX(^OqY1C*lblYGMUN7*Ax+X76~8X1C^xE*3(j-l)ag+o)qXU2Mwip~)W8tU-Tl<@#}KiP_E<+OD7?x7~qd-Oe!j zwc$b)c&Pg!#oC32X>e|G0kBB>Z9m_h-@LrV7~iY!#TrHbCzekiVE1k^UH7G`4aOX! zMYfht6VR_9@Cu%QB9%Z~(xSeLCTy(t_@X_j8=jx(bv>H~j!y$QA=c?7QWVMUQ`kt~ zr&1isEgN_J+Y^X|^g^F}Ps~nbKZVyz^Xhu+n~sxm-%`;BrS`?BUE>i2}w9l+SjH2okYPJ4rI$qqnAPJ{6O?*g=q@dwyY9*i zWGd_83mR5TUudSM|Ck$Cp&Gt49 z8W?*1TqQC-J`awj$J)kdjr76zMZv056}9Uj29>N_|9gDlY*)kA!#E z#-wFrWC8*L2D4v;hNXgF5e*{6(5cLx>@BN&x0ejVqkNQ!P2;J$wY60_^=@Z(@6b9T zG}N}^#B+OjQDF8{A3CSIHtCUbv_rbIT7#(C1w@Av?f0;y~YO@>_G(IWn! zIQ~S2Xw-SybfZ4g_Cu1n9L`zpxpzA+icG#X2UB=;?5@5D&Dq;#$b{UsT8tfz_y-U!ZVY>b^Vf(7rbM!!dTf zde%wu!%z=Per-}#pUIrNrShVIatX;|^@(j8cZpe_768?Ky=h*{q0$KvW3%Yo@rBM` zjB%$EU0Gm6w_$fOQMeAZvVAww)L<+wkJAQ^cUjH$*pOj)EK==lmC!SWgj%lUDwRfq{u_(KS&Mmb95C`=45XRQ|ftY(P8#Z49<5pB4Zl z$PsOJ(&ZDfUi*o%%4F-;#hY|~rOoKeY6^^^RIyKy!sW5*APq~Ut~oxDX6ig=a4sHL z3Z>&V?SAZta!RN6n#m$W(xAV-EfQv^UgY&!|c2Fna!l75?ys;&kk+@OHp(u2onOA=LTvAfn;`|hgd~0INyst9y%Xx`T z)xn(ShPsYzwA=n_l7Qoish8ZR+7r(o&~{UI&U6rfRg2?K(ON|&xoVPmY7!FVpm``U ze~~))U6Vy-WjrHFw3~HFr`4jqK@x0p&wKp88H@2qE!h3)8?`M8#$Km|(hlu^_{`h- zm)%Z3W`KveC(J+R;kY{dB!^ZVwcXA>u$+;QeqSZyS=dT{RtjLem)3AL(*25u0=i4UOe+>WE4#JZ*jbG2LN?Eo*M zMx%U5!{v|mmPR(d9=!Qm9@;7V`ZIdvV5}JG9ZqN82kY7w<|_ucUJDnyo8tIP$Aid~ zzKu6$9IgTI^>sGFEG$LcJ2r6LK7;!WJB=ak6S|M)Jdj(i>jH_jbr=aAr*At~Cgf|} z_xew{JkB!1@y+@z!Pm?~akKg7H3kIM+xZX8-P3eXgOoH*{TB zyfD>zxX=h29nFBjR4_2$+1(q?rZ=ONfn{{PG4#Z_*c#wNHg|YbVfgtCDUVk=?v3WKo6Tk7JG8_#(#s%^cY7BTJin9k zm=h0A^cW=5r@el)6gf1}-QW`lfVe84*)n0%d*=saIEPj^DvQ6}qF_K?I6b%m;e&*M zoFmLeVfU2XUqp&#v*~}bU*vqb*h;?C+{zJ%GXL@i$v z4ZA-d_xGpmimaXqIrS8vIy&RF_WS|M8tgi0A|ERoMoxKzcYW-^!uiQYPqTb1kJDe5 zASyn+>1k+YwVC0FV&x+_j=tWT=)WN#;Fgg3*ZzlIO*lOX5)bY%ba(P-vREeklBm&> znHf9j>!o0X!updX?SVsSqT&gv%G@c)91XCa;IW?g>oqy_B|rYIcxM;UtxgDBCrJ>A zyB^5uY73_0JUddxN3S%mgF&(&VJu=n;na1e2>LLN$_VAS^VOV>wzqY3^v}^`0Q4VS zd6Z7kUv6t8(;Gokr{dyLej{IfWMss=C)uZzQj;eCPHlnpV(4;Tx|#W6p6>Z91iWGN z!WVySpiP>7SVT08gmXm2E1kLe(2STu$B#2}*u%*OYb>@Dwa08#yN1HM-I!sitE+DS z$xF+~fO+ikS{z<^&!6L?in{9hJEDtrA$Z&UHCut2raE(fDkmp&PnA;CGuiWG&ADdl zn5A;>OYH6_%G&Jj5Rt5og-rE!8)~%HC}W``KI>tXQ_m5p&Z_=m0mq-%gzw>sR_S2k zOuBj9wK^Ftmm>tGH!EL0%+%b+bXOquxx?swMvsnQBCWbv-k7@AL@Ap-b4A^aAHH;_}~~*dK?UB6|9tmC>nMeXh{4g=8m6DAZ;v$!|Ss+-j&L z!Q);?OA3Wmxmwun`EUGUn`v5M;Zs*#$Gtspd`h8f5cQ~8YL)c{kgzyzAn}*KjIICX zYgh>jWPc815zln2b;-+mTIA+*OXbQ6s${M!jUn&IbP-oXJq$`nHu_g*1;g^UW7 ztn9t_-ZP_Q%RXd>?DZjsBK)rV==(gs=a1)pdA)jd?(2SE@4c?~IXCL`sD>Rx^`Zf` z%Z&2IEkRbj>WTLFRHvRLAJq21uIKjWw+}V+^^>j7h2?DAce5Tw%p`X5vwHPJq@7;8 zefTRph=tj+#R&Ap?I%l-zO=Ho1CtJ2K1S_rezi9H#y~$%d-ICtXUC%pt!mM(Q@XL5 zJ8o7ZnXg=*P@IBOCqVXSv;FsTy3>R_|MNN1<1{b1XYw zFco-d8;2=y3U$xDLydh=R&{pM>QDk3S3>ha`0dRM-w4n}JNom$WOI7mcw!{W>wzF% z%fiRuUn{Y;$-MUUY^^_Og5OS!zJ2IdtYhM<;kDpV@fbSw8a`>x9_q}tW8U=kTET1D zKl>pSxtW(>GCr;uUU38&nV_nb*3;8F-5HN`pRp~VYA9oG|EpP$Hlug@0jqZB z4Lly_4%lT?2p;)Hi~PNbN(n!|qXP#0R-bSxzn_ohy?b^UG`)!xB) zYaR~&x1?GGJigC)c*Ffxr;LE3nS^WqZ71;y$j-UkFm@>-Dn@s!m1$ z^Sq&vsw1f;{#xg!C{(A{JtTAx$9-UsM)JS^9U4LW|GN_R@8t6hcjk4)CbIB>mNjhp5j z!5^=!X8YWS>SW*!G>=4i9VZaH_LCFEy~yU}etY*G%7)GGDdVbUVYnAgW#=9Oq-9nl zAu}FNv{()5C%!BO)HUp8u{|krzgAiE>=;werLxei-B$vrFt6k z+&gS#p@wBUI~12|pxvD5ygE8;Aq}<9Ry_x?Wh$mpoPx~9yYWiPNAEuL`&-nOcJv0k zMivP@>o-M-k)#sdkti1MYJr?n0aQoYz|DAU(mmMBdyt_4ik&hxJXm1neP8NFpnLVU zQ;i-RO8{ogDF{hc^@@+Kx)$l(<5L0dt`OIJdHFsWnL;L@2+ya2#1w17l6J&Y-VQB)C(ofsg;g0nj+=JEo6Ax3mYMxD2rMQHjr`~R z4-YB(<<*p|UuTcs*)a92#PMMk^MbtOh}yLL#m0ztwpT?WZ-U+mV%?{D%d%gUp9ZAyqKLyc|a z?M7sG=i|J!hWe0MmnA*Lt=lo~)Z00l z$fHcKNx}l`AmrNa_QHtwb_rvJEfc^aEsDTC6etN0FU}(b7Rwsf++lJ^u~2az58kdy zBr^Z!{7h`K!K`|Y0uNnN^I?=a0)7ub5-|2q?PF@f;pjnt4PjGRtujr<64+n-#Un4d`|%VTkhK+n zcC=L3P{uOOWfGp0DHhKX^B7OCC1a12Z(xMt_l#PcGah+zLA(y*Gq#Cuq6@ zR3zt3R;` zICutsPYeAPHdP&j(x+-SF51H_QIw)8a!j!9k+%0#a_snC>4P`#tYAO?Qo#UKIwd}B zTrrm~(TE)@Zm6AaJliN+W1jt3K7n6IhCRbGKY0S1*<%*;b0+^TJ}3f%Ib66>8UCW$ z&^*8vvSfSd=Kg3;hJRjDO~F&p5jji{z4*yYN5@d2GhD;-ce4kSGv&b_;y0k7p|rHJ z4L{CgZhP0FZ6;M(xd0|cuOJZKVFb89i0Zw^YrSS}@UMHC>MF(Ybfx1aH>Vgyg{HU0 z5K0HrdZ*83>HTUQV)T*4Whn;r$ZrL;YCVF4{hXg%$wTZ2*)W4c2l_QD{?yd6|7!oh zV6r!tZDO8XYu+1&aqGTc{%01>?GJg8-DUw{+GW&VM%$T zG#Cp_csvhAQHDe=U7HLY<;Rk2(!sCfOUs9b8E$86&9xfnc%x^?`x;r7lBlv zhUJfxRUjNj?=v)L;=Pp$dEA1O!33Rp>BhUucZ#$IG#<-?pTM}VKy9Vv&N{ZJdEvKC z7as!M31oV6dFMuid1A=r#pDFsuh}6vAd@ilxC2S@y?bTk z3GCW$NEhuk#1xNo{$gCZIB8wDBCL$YN@cQo*z8Pg*L?Q=Ou2K2N|YI-W!t3t@MP{g1@F!4@k1f^b5DHS3MXA3 z2X0b6Bl?(;IbndVVYVzLg|E6<7JR#r%PL0sV7f2);aLT7cbR59f6rF+>oG;6J@uMO z>(E5L(Jl4Y>e9~&_w42+?$n8CvD!~YnaFR7p@q>eA7wLYkVkuMHhd4L6?7pdFU{0cH)IQ+YnI5V zcO1$4roZv=xM1s3_qT{k$;{XG>a~t)!qu2>@fy87e35~)ifj6qBNi7c1Px)pux}`N z%f|hN8tJNrAg?$wTrY2~(-IQ6MU0^v#5fEdib_1h zCF*4#a&vXOdGo?EZ8i2gDRe{$ zBRIk)QnO9uqDwjQ`f|gs-KOoXE-m4Gad7%c_5QEHL&w?NhL+SkdxP5eM;e~=lIU#U zHE<0~!ks*p4bycZy!s~lsbz&>*R&I`V!xLkbv8Rr(|9aa8$a~iF7wAD8?aAyRfb~pR zp@q&bTbA>i$51N^*H2eEw&pg6#Ob&g==IyX_r@v9z(^$bkow9N?{~s0iip4_S-^8m zKToc4O3IgJjhg*W*XS<7`cr;URZIQm+d?Cs-J?C9(v?lFf7?`&0D`aoTRA$8@q8ho_2Jesh80!ByWKC|r3})G$e(S#6eZ-aG1vwu;V` zusInQ=?u{~gtSdO^BwgXd0ZonOHKFgZ@stkq=2!yL$ODF$I8iVPLZOU3p$tf3+nl{ zcUiK(oc$?yI8kW!24~h^&j&IF`Hv-2`ryqyKm$LB6G||5#g(hpD4>sF;_hLKE*bj9pYahb@KUqM3yACeVXZ|#AvpEHkdUGN(8fOYOi<6@H z9Y(Si`;^?dKrFawUpbFR``T^RcLrHRI?3vWw)zAO>ceG!4ExG!)$2sI*PHYY*Ikt_ z98>epe~0rqEfg1x`wQ+>nc9jGfK*L$QI#xbpCR0=8M64-H(t@a4zW#E@Uq$5#anzf z7@^nCIS1IKi4AhbkTTukf%rk4;#rx(cdoo5b|0f%)g!%y1=cI+_mfO^Ji+lhF^ZBy z+V3XrC^$%`kx%A6;TQSa!GSCz&zh;T--Jfev%3PQP7?3$CdBpj)}7i7V)^k}zowy0 zI)p}kessjzV1@Jc&7!6!Z52)|DKGnA5u6Ns`n&5&$XwAk?h-LEWo$RKzV_3Or{1pS z^OmccO%m`ME#ab=#m;NVvMgy&2 z>;v}W8CGazETe{FXUTz(js3x^rzHazOrL^MpX2?pNZ)fDmw1?g)IsjxR~g-AD)vFC zfWr#W0ydje?QDzBW1;{8LXUHmG=2uW)-zpKAen;@yAl{e(XUin{TTP&EpVAnW%E(EuJ6u>i zC$9oy0wScgTLJ;`3tO)7>3b7hTdoLsqp3sTGNrjvcdv_8CcEH?5xlY?cCFc|zx%Fq z40#**27B6`p7ldp{`q?pJ_9b1*A>rRjkNmeMuM76ENdEAc#YMu1!BZ zTRdFHWwoc?DSVABqNp&);lIrEpwl(D{dp;m4GdK1a?2>CJo8|LXALCRjr?p|FAf=h zL>`k#XbKcjIb1&z`F@s8-e{|S93Z1JKQcqCqkRBL7#t5OMe}Uz_~$KbdI#)C1P2Ad zd3eAqw-or}1J#D_g*-DKc>n|8E>q1;>DaExXKb0+l0=Y(wl0y=5m(Z}1FN}(==BSR z(()IFnx5|3zcnzzXG#KQ<)PYAlIy9hqb?xw=l7dvSAHv~8hVZKil+Zt^>5TEc!>k3 zw2*l)t+9nLcaJ|FA#HoS2>$f3?k!gs(ReR3rA&#g;<2t_%ESspZXz2g#cB?42(YSK zjpu7$RuT8~Y>w~wt=3K_&R}Cz`G(-JqIkfV1B`m)`zk4TRYF|84Xqfh64vX%#54n> z+XYLPRf6L@&}ra+kW!iNxN3HtYcHITZ)Xy`N4C^qM5Z9!R5`aw)~2V^1*4MS%EWwx zkWSJ~uau}LBQL>Ktp^ChB|~TP{M&~o2hV-W*q|vR7(#*oPV)ouE^-F`u~R&yY}ds( z8}Xzr4VuNB9Q7?c7@<{xIDyJ~1O%WE%rA;;P(d!UTInO|-_r3&)*g3SP1 zmELV=ZKik_Lb?bn1Ol%pCs$0w)^uLnn=h()FsK$XMLW&|Ob%K{5CkHD-CI|6-j}F? z8P6v(fDWvVYN?w@hXtiBYb*ULI;gP;;n|wURumI8C1S`|rP3ve7zE-%WBA*H-rRL4 z=TJZwbiKxXMWgb4sP^2)c2@@&JD3;^mzFqv%01`R{OU>AUS_o^AK8jOwj zwe=P#05C*|`aB!z(yu@!308Y^KnHms z#<)|*Vd0ViagIuPz7(VkHHmQj=|jINiw{UEXh#?eh*C7H;U*=VLe_dlHv*~MFN>{` zDe49QOz2t-6DJJTk8704a7c6XAcejD{w?4#i}d*f8euJ*S2Pi3$@!D?yCa3lVwD)T z18GR}i?-ug$6jCK&#w%%AW#OqDd_fqVwS5pky-t@m(fpS8+PIOl;5>AQMbX z%jM?}OBiql_85o*AJ|6z2zIOEr&TtVl!1^hti>jJ)X5XO`fb#HyPIhs#lk}X##Bkv zpt#PKT+->7@QHo^nm~hzTS;f?b|rDG^5V6&UD(sLi~*e$rz42_SpMt5B~vHStRN&t zaXM((wB>lO@}j*H_=ZCstWcUJ27fce>VsuXGc*ef6Yn5|Yr8D&U1-_IG#CJmDm?4H zXeDd&4F1P)%rNmP90QUD_4XYTYrs*aDzAppso(R4wb0|B-3M-idJ*K;wmT6S!1l!N zJD-H+>A#?sr56%|ge#sW4$w&Cx}Or4dBU$8-RF4=*8j>Zx%uz#VjVMWI0D_*W5U4f zVxsTao+RJyVeSDe!U<%0Jia{&SQNK(@ITX!#U?6AJmL2%0Eq)Yu<&&@_c*G(omkfh z3Rqx}8r+ZCRQpiJX_Wxo|Kcx3kki0lQP+IsVi*bF+8Fst4nh=pMQXPpPjU3OSxZ0J zIZ(?GVp-;E8bs+&r6j?f{t;ht2530@X|$5O&c&aWXjfNk=!_QlAM_dxAI(70IN;e} z^3oETzAOCw|3Rh+`%Ty6>b@Dh_#FjJ1;Uu9F}oBTm-m`xQmAYI|D3}D?yjJYX6|bz zK)_(|N8o;cY!O~x3lIC66EMI)NvJfrjsLaRG?xZiqDg`k8W+W=p_fkKSBsK^maH_p z{4vk-ohvOs_f+p=y)vh>j8V>bo>mMc-+8bO7s~#=$+CdUM=8i)2nZ}RSiCBl(`qa7 zO-Y@gEo7MDRp%7<%H(}LE9KGtO%n$8d1scaFeE?zo3aMtj>66>t%10xm~TGlRu#cd zY$9gDmT&oLDeXEDOJEEU2Cw3YG?-#Fc-#`+2h|@ifkp|pbS+$Bq>yB=y zcok;V>~pdfi+ErVfmVAaO-lH(jF4vv%mXNZj>AQ$Ndd?o0GnU~rSd8h6B{C2Bzb7X zihqPCg)3<+?xx##+=rPq6--_*FH1wDSK_}izi!$;F_*Zi;F$+0zAhURtx<;KB1?=e z+M-zi12BHRFiNJX`wrYQ^|MdaE_GZY#(){n=1lJaW{Jdgx=^qJ%**_^(?6P$GWpMx zHRZ8FCD`WE@=Po)>VfrQ3+6O9XjXstzzRK$SimNFGpBkM-)qlRb_W&_zl*Z_8jt#C zQ(6Ewf`P-e4N&oyf&lY+vS*fmyAr%m2d#mKJOcQQs*DrXIH*9o0mCYDk2C-Z3Lm%Z zLF*5k9qi52vpqIiK8(!i2K z0Zn-Sb+G**iSf6E6UYgP2XmSa_%z{lUd5ogQg?{{aVKKE;K zD^cS72Z0PgNN#m1Lehc9xy`qIJ~E(V$uunjmnKB%Jf%_|-J`__#IXsm4zcc%u8K#? zJC+k5XP%(k-u>4BP>V2wnxEi21mFQK@jTf~lE=77q5V%X9p2_Zde2nab>K4N^F+q@ zN-4yX9wBh=dQS6rU2;KU!Eu_H#B=>0Ww-z@4lAb4m@=z_ZAfRCJ~#gzy{SfMuj%VNJ+AGfj$CUZ-LRqS4&)q>~9?BsRwyY76 zqa0~&p((fm@>Ct z;8xsqQ?KK8$bcMkUc+C+r(-K?j(->hiH~A>rYHw=Rn$N{vTiKgSJ~HHy}Yc? zrD1UPm>gX>v;txRSD)&wEOoOchA7UZ1M&;~@03Jy(`?_aawZ+4eMg>5rtT00UrRid zA@E2Y?>XtlYn!oueEmyMr>H`HISobbz%f^SBXO--;a8hO*i>b9yjnGtH|%tC%E`1U z3S^P0>f@EC#rM=}My3+^7yJe-Zr0S)im+<6jE~oHpI3So6xb@-RZl)bDuPQ$L6uYkS; z9Eb&fCoMudF$UlRDFmK-o~KoQ-r_=B_rMjCS?Ad*Z^Ii#yc0Pw@oiZ8IKI|g$C{$%mG&QF9C-!?_2X$} zLeG5li$y_S{NC|%ozMX-HdLlv3Pm00o^+5zE1oDLK)ZJaBU>_G6pw%|dB@w2v&e z9|uK|+>j=ecKP}N9Ci9oP&PDCQHl%=wk`;*48G|0O%v!0ldBlS&FnC{WsXhFMDR5; zk>JZ+C7XTLO?MCEepA3>jOyd)Vt@bk;*)KPAzSc+v77Ew6+`pa;24Dm^ zM*G=P&?ZAXw=W?nDILwhQv3Ih8ms2QcSpam?w-cflb-h3S8N2F`?pXnoZRf$jH=k1 z`xR}iqshn>(kh8grHDdTx_dXg=GmJfUI|a=3abSOo;z$6KAVini0APiNUG_2s*swR zZfGJVucMlrEqA<+yczJP(DMk@i1+r>ukWw?Vxb`*m^0y%HP_VNlT$+rIz|9LdFf@J z{aWSIhl-*_@zt{OOU!qNS10^Gd|;T^XewFAYS(iviXKf|(d=a~IQHt(-xfqCqd~;M z%TIcBO9qnl#)cg{9yugIaC z_K_;?DXGJ@Xl@wFNDd+_5Rr|bxY_-5_@r`<^g#uWelGi9tKP%SMwPrObMNjLwF|cS zqsKDg1@C2KPA{r?o9&T4aXp6>!d<_8Edvr>hCl}^FjFNsQO_#|)%I=gX%E~WL&a*f zMg5m0Yua^+(b?VS@4v0kS*sWpm#5E_uJg4@Dbi0oQ3qQ&co;?&Y#t$_93)AYqfN{_YQpwcLzz9}i{|q67txawyj$;?E7Y`vmjv-8 z*G8`yDIjDazt>SXsu}iXSMIwQA+3%9kHn(kk(x4FQJxaTt9P8qMw}9=PL0|c3en{& z)YA1-8?KaS^^<&GPt${scU)*wxCj_5?dMY0*7l!Naae*HeT3v!65cp^)I_&EQd@fu zY-g?$kkNc2qA3FXY?hS8M=2?P{r263UBMfY*)-b4?87ZGd80Hk@OyHs=3&Llw;YUH z1V-{=hd;BRr9xIqEI{-t+o$csYKoHplkOwUdDq`Ng-pgnmdi5lNOJO{ z)kQw-G1294PPq_ZMpAt*XzX#rhaQ!E(^5!r=65HUhKj+- zVh=ny3>!T?l|PM{BrVUO4)i=mHAX;az_KK>5~Tv3c#e2rf$uNZO7ADtOOS52M5sHD zO-`AxH^$}-KN;BfX)%(6R-=i;SUeTv_|7`Oclo6AVMCh?=RK{j|4ooPsjU>T5RW$y zvw8q*Vh;Uw#YBJnb1OH>Wbt$VK8hDwVHqDtnE*b8$|{>1co8f8x5TQ68-h5PA&lsT z0*OF!IK{ifcg?zcVf>t2r_Mbd3bSF`@as;!C#YdXq3O=M1=G`0%!^!FXnmlS$V$A% z$zI&51YcIxo?_ROI*^u8{^}9?`oS;ZZ)K^ODai&#auR_%JKI^7kdF%_%m#9b7hd_c zFjJen`4vWb=;!Bhj0yCRn*9jX{EsaFEG+;T+lAytA`HK|n+JXsR;65xo0<6j6JTp@ zV*>O7VhI5mVD^_F8Wr!^SYCxQC59Wy{U@lVq+h@di~mhWpNhd`!z4Lx9zPVLVdgt| zJ7K6_FI1Ev`!%6wP?5A62gCwXZ>wm%*7HAo%0vuS*JhXr5>^;!HHf#NjCwk} zElZIgwv<~?Q>X9mdj2!wSCX6qVIPn2Dcpf>n_2?)j(Ff22G(isC(Wz@wFAgjaK&%B zLgxYZZ>zA3 zCVm}74T zSmZ`|ErJu>_RU0)lJ@EA+0&){UJs8P7X1{>nzeHum+g?56f%RlU1Kdh(27IgJloD6d0nU3Yer+i%>|@Y#&h@%S-9 zD6g*U5tq-$&qx@VfkG06>c!TR;>Z-1KYLyJQa<*s8Q0G#7o z@Aa~YeP0wy<^A_T!TB_^?~SAWbg@FWKk9UM560VK0V+QYOs*j-$)Yj_Yc0>yIB35iHI!YB*h$%pcU@#MNz&j?r^^ zflCN*my^mDPW*%(JSz;`Ee1Zy4UVpsahbOS#YNwfs46lHO-_v6m{R-kluLVA5R*+k znr`@dnb)(8((xe(1z152Fj7mNqNnmz+a%79*VJT!(rkW{5?6FhdRfZgDqXLF|LwhWu&3KCQhpt{2 ze=vlJ=@SUr*N}@S5NYfr$UZ1vOxPgaIZo> zj6}DM7^j>e5G2H9a`9D$_(Eqst1g978!x(_F({_rHkN-31OY9;qJlhGm|E&)?d$s8 zUI|DG|L))zxIF%H3*8Unz~nIz=%`-*a{P1Y%}y4HWDl3EgOF>l2kw)9mM9wn+|ZNF zrb??)q{Yn>+mQlI+z%3BIb~-pmPR*UX%PKiK1P|5N@S#K?1Vu61)+n;2ngpCE8nOg zL`X={wq=8hmH1^E%TPo;h2SlhlJPRPe&zxf8QJHEz}s4lvH zLV$yGM%+NJ33AD^#&bm^XYd=wgTLHo_b5SVfHiueGs4~xPs^k_Z3nCS(1#Z*$OLzu zG;0OUj*yq&H#uz2r%FK8@f!9_F@C^xk{`kq_XCI|FXhYnxIi?7z44b7^I4VYtNdV& z@RmJom=}txk9``YAG1o459t()Ry-@wiqK+W2t>crsd*uyJOpm(y90nm8Wf=f`BA2nL z^x6C%xz7|lF6`OuFC9}r;`MIR5WMsUF!w7+i-N`_UHW$`b|xbhsPL>4)p0`sST_+l z_n!0w09L#%!gVOn zi?K-?Ny36ZCke(QPR)0?^GINfi&Mwxw5Oj3S`0x(Q5zRG;5vimTNrk*IX>>6wwXl4 z*OcFrTk$5sUt-N+Uqw{+ea$}rd=rl?n{XMb(PDWAapTK}!f?C`mk@?K4<{U2yukTK zEO%SoX?u%*MFIXpC z%AIM5*N+f}QE~3yXzy%vU5FlQ3}%Pbo%%U7EHtAqpzObfnMsT4L(9MF2IR#SCHCZo za^fA7DtN`evRdlazpE*9vGnSei1b8&4}2$tczz1vW0u#1*n`=7z)51j$-I{)C3f2& z`NQ6!e3H+5XFf-&NJ63OLsXUa+0C1^uD?{>o&RgxeuDjKXvQb+B`CX~N3rh%dP05E zC%LlT5&CRC%g`46ea}OKDMG$mpOQ+rTGkL4hnlUeoxEjiU3sBXpW6Sx|NE=_LGeYC_FNvaG?)d%5UI8b-6?7+yUFq*h>X3DKI~nNI*aG+m3)xhf(5g+XytcTTxS={y+lSh~(N{o-50iw;eOH&b2dl zGhC1r+t-U00=d%LmyN~S7C%}{h(ntEU1Kz=Tg9Lsc)2`SLfH?Qqp)8b6kz#-j|&LRocfFC`lGsg})obNeXvdc$3(EbdY6{pK3 z>e#Pr&6Lzne_eb2& z#8$tTbfI{WzQm(u*#%6F@9&Oi>;8MzElLH(-81jjhU_|RQhQ_?*@SP#_iQ||7S(wv z#;K~Pn}YURtE5xtgMI2$bh{&G`o2~&fodb@z8qAvcom=TJ=|<*Nl&QLW)xcyRG$PI zHu-dM`j0`~qF>8}!->k&$0!C+YqUDb5=hn--NHNr}Prus;D7HcK0Ae5;4(I|^-93ZTFw|2D zr0R%fwxq4)XBOOar-Tm!*;+5z&hyvb&6@Tqrq!V+HXttt zd+eO3BWX@|t(QLbLtwfd281$hx&G-&&M-LRju+C0RcPhKtvQVj{V*`vXsB zssk#t#oQaTg@4~W|5>MFC?`eLQeGsJZg%ae5-2I$h6P*dS1a8vE=CQ0lmZ?k(qXz? z$KZHhOR-vMKZDQc;j^@?YF#Curm-k3GMBU3ebqaROEN^igi&~Sn;9l^<@>FTQY~j^ zscVvEy24qq;UK13K=_Ims=*^_wo~-sM4W7%CnuYV!=icYB4@GXg&Dagsww5L^ zzisrb>~y(CwK?K7W=+#Jufv{?^1jbsv$ArBkRu6rOZD;#^A#qY@g)W4+mY1R8#TPx~?fVja5kPx7!ggAB2@t}Q=83j2GSs}N<9lehLYrv=hyafcY6@QdWAq!q^e1au)GRFH%f~r zG(xNUUh`|KVOW$0IXQg^4;e_!p?in;!Pyq1_Na?Vd_X1j{v21Cl;}UO+W_nbk{qDU znkjHsP)Z)kI%Gd}%9tCBM;}{7T_Xy`$UM2#34`5=fo1_r!$uhd*U)6GOp+REppnyo z6J1-*+2s~^0)tgk?|Gj(&no>(FPzliH>9nEvr_Wwp>|-F*Z2eIQO`#G+?#J7Mz2CBi?n5dBJ0Pq)X*rhQkQ-neDeG)Qmryq5Ff* z7&Z~6nyQ7u`xe80Q{zBdd3RCY@8u~AL};z3s2|@rx@h4D5mXt!MgV}MvD_)+|k0v-99?YmliG`y03`jX;Pz;>0)AJQyc#&>rt*- z{6hHRbfq-TGAw%~mAI25T9ntK9LkoOA~0cDhtqn$hW%5}bGFX-HWfPxUssYx7ntfY zE=$5bTIwBAJn1I!Ge3O}3Z+gl5*W37@w+Zm)v+EI&s7P5L%Yb;-?mu=*sggud`lx0 z{0tiH@pRHJqLUYBmIaP-GE8ya=}G77_&l#8?$>Nlu8>pu^k(3a=GW!sI*SNg->bTI zgVZgXrB-`#Cg%D|U!;|Xxl_^jegj}=F=)OqH{JBtvuhYx?&8Zc1s~ch)+<@@2&A5O`T^5y52P za-}etKM?Sc4xKd?b-h?RKbW(E6-zn$knzTqXCZow(?#&K+x)bDP6oJRanqL`3v^7Y zmNpRn&aWjoAB#?N%6-d|2f#X-80qBwYW?E>p<4+jlKS%WbnP$X$OGLL^=l`tqB;B- zQRt&3QpnrXRTj?x<8ro^(5fr9xBF-V8j28T1oZIN2JOqn7r_ABk3lbXBgRGje<)|F z!9(8Jgt4XQmXt6kLk*ek`B?^4Wb`dwCA2I8Ex-;Ibbe>iR-wLsH(*2&jq98H57-l| z1krIcH75>-l(wj;R>>r>wF4kP!hh*EM8ivz(8~dRe*(0Ez!nn^tXUC?wn+eiD7Wze zrlTgkUswEurAlX!s1sTou_t&yq7d+!twwU0bD@F125iX{wy15cm)N&+1T9yX>)Kkp zCu>>xDm8k@9h(3!wI=$)?7$W3qpQKFx0%dc&i7>!{x$HQTnjdTM=Gy%5OiVp`7V0F zh4oTiaoE2S43-MIba!6n`o*&)ag2gIwKrKt3wdg~jeEr)*gDAXZkFagWHBj8?1{W5 z{+sU8JO5hOw9;*Ah`2zv>{tEQWYvB3g4;NqssPKKN1>hS=m!L*{vBIOaz?(iUK2(; z`5Uk>Jsag#AnKm0q`2ccD3u5o_2=8n(-dgb0EVU${n?!JZLVoA2h7pRfz5@}CA>_U zBTtuidc15^o&&PK^Umc};Lzi3ba&8>S3))`@vURhWES%_14KIQv0S*uQ4iEch0ugS z&4@dC_NdPL2_;-m-yIgh%c+*T&u&6HpnkQ>b+C(Nm>N*p+4wR~Xa(xcsy*mn4OC8` zDUk%MQYE!;N99_hbraBP+~7GldLI=d9fub666h$eUmQnU>1%3%^AcF9m90nk#rl`L z|6%c7l5?0;{-k`m@YX>PVAg-l#V;gJN*6k~u5fq+a9AhJnaMVvuiC-^%n%=Y&oAgd z*JKPVPVp+71i^`J2Y#H;o6W2kYW)f{ZiIi0eY8K>$NNfS#o=mj;wbiEy+RZ!1}GV# zgO8VQbJ*q^I2D0d;YH-lX_v>;O#*n}>X6AquuylC z#L4C~dwshhqi2V0O3@{vdQvuB81!K2pYjRdbYZTL=IGtmYIc|ghbu6msLKZPG;3|m zDkrov{)qurSUzqoY0@%D>3PHobKOt*m9R0>_bqh;EjI7hl2w6zw#SmK6?yYOA-s25 z!Ko_6+e!!tapNomi|M4kpOb9?$e=;Ije0wY?SgM6o+PlO#R z^w`3F#s~m(d{H<4>92q|XdMb$Xc8S9{nuOqLidg!exNWS1wPifU9LX&>q!v02YW~m zOhd$(Zg)?{XX8+rDOB392ZO+z?qea9u~!`Z*Lznduu%nYqDPxwbC*jG73N!fa?GjP ziD9zrOEO0tGY!wIW$3J~$mUF@{WL_9Q|Ezq>ay-51HT3flLW1s{bW3SH4O&Za&#^i zH4GkUI%oaBLZw9@$lL1NCUebI41~% zo$f`)`3z6+{o~I{m?UB6>Gz}Q(@C_NVn?+b)ha!Fp0af1wmUFzWWst2tOt=|Y{uZT zK-ll0<@=}7Jw zxJ8lr3p>_|q6D)PG;2EK!9s3YbROMwpwCO3&)|Nh>WE3m<4I9(Y`7NUHH$5z}X^XZj=5w zXRJNIA-87@LrIbFYYYic`oALy1tUfK=e*95Pm3C6+(B}PjIRDoeG zQ)g12&n{#a(F&0ndT^MRgD!d(=E_?#$CXFEFNCS#BM{;xOpo)i81F+9eF8Gr;ofUH z=h~~@t*VIuI7D`wd3v%<2%Q^mU!))o`}<(0dHl*XX(gF9t3pPSASivnk8o~&Qf}Jl zg`+Tt^z7?_Q$l3Qg8ftHI%vS^xaTsMzK%deAxO>aLuSZoGZXH|w>Uu%tL*SX3NHf0 zlgo3c0zH-}@v@=QhAI|3GOfQ#x?ELZXf8S{^vShrBd$B@nnKk_p4p89Gu<60Y;0W` zv}Pm~z0(lahkB+TB?8VDubfRsS3@~6oHBkZ=T5!n#urM0F1Ue!g9&6{A~2LH@KuaX~{_fFPtCpOlbsQxoS&G?vmwT)}fVSL%eFRR-# z``AvwQR$NTd0t_Nb1P_w&t_~yDlH!+G`TQ3dgiL+_XS&~A0r=}nRG_)a_umPN3&G8NZhslT2)RF zpQ8|D7!vr2rI2q1?H>BF*!|h7+nG_FEnZLT8r@Ri?G&nV(1w^ck1Z2V=L18PIwQ_r zBFt#3v?I=bP}146l`f8(ml-p&pwNz+rJz+Yb^PeErTyR|@~->a2{fV>g1%u}9tS4s zh&8E5yAumWv6=uIu+-U77`Upw-(u-13$`!2yw#fDcataln!R3^oSe=tC4Wi%M2tVp z>Xpv{*iUW!Tdm5uL?8X!V2av>3FH@|e@}rii&AM^8NXfXm5<;^`8BGh>Z$%3AorLZZ)$DGrW|6?$ zn-{SyG4g(M{s@?8mp56u@}|g%y01n@BZG^=L??i{ARUn@Duc%Ldf}lF z+ug~7l!bZOs>QS_i(#5m^jXUE?^C4HK6-_m6sfbp5Es9GeOau5ERMwcFz*mPdo6NF zB3Yn}%(6EFict%G)O69LUY4L%g;i}_EgSDPov@kaI64+M@L25JcX=aNDN6!Qndc^I z8|ghyP}3unh~ND3ON2~UDkf(>154ob>3EvgPQ+Fak7ah9K7Wc1CW!`plhXp8AaM52X}%N zDNYYM*DR-k@!VYBG-6=$I)^HOO6ZI`G7a_g)2ybiNk^uP54Jfqft(MZVJC2L*<^8 zfis)kRH^aqrIae0oe`$(En@S;R$8gy|H(uCujTv-d9st@Y`P(05q_!>HR*xL zt^1Wm@~SRlFW{h4i+cp2r;BzDmHI+g1gJJR!Mn##`ia06fdXpiET&qQUn8OR$|xJn zYJJOM0YR||ay%;f{T+nBtM;6EW<)R?Zl#2b;6aG(^mOqfX~rF}jFs(#?CwbHmr)aO zc&A891;=X(Oxuk(u?e}_P0QU4ps7>GaYe{XGBtL~%hq)4jZ)Y>_o;@~0Q{qVsRE?_ zGs3C4JE(V2CINdh4ZF^=s`$Ap4^|Q9=33>)kpLRjDseO*kh*d&oaw^{tUh`XrguE& zyXF~L@QQzk7*w1X#g13}9JEJerrMF(gVag#_(Zec>VpIK!G{ou;;8Mc~z9 zqR)@Xk~ALMz3A?y#+qZrspG}0EaQv)4JWiQrorT8X&IVpj}7tLcN^E+a?3$^?@j(` zhQ25Grq(^OT~enG0k!y8w0cCO@I|7ABYDQ!zD+f3{N9H>a#@x}!jxRX)Id(1{uIAJ zoX6&`C+1Z0Ir=O`siqkXg(`6;sL<_pM$2gm+RM9y@2V$f)Ld4dIzBHixgKNBSh{aMp+Fv!`#0J*aFdap@G^47W*!5cZ zrk-kG8uRV&=tRiq!vkpB=D#ubdGn`(`RK%AL!g!}Mm}80(z6Q-itWy?K|R%hcwc1X zXy`v=)ZjW$^MLCJuuxu1`90Rq~_K|x&7Br#%A$6|m$`#~3G48mk z(9oxfg~FcvvU0-$W#b|Ach!Mr3(5BZojM{6xzT96MQ^I)WzHp%!>qsXDVY3n47tZe zOL-NH$W3Dmu{c^;tjV34EZBkC`4mmaVQiKEYpHN;_qMrsqnRTR`b_3zT)5vpka( z>$OJMw~sg4)Rqujq;XyqC*RNrqicsi!H7@d?mUE2h1E#;*sT>ZW2Zk0%v!{G zR#9JtH`CZszJ70kR(}+NmK9$3Orf90;5g(|$cT+T;Hlu%otAO}%zpEtJS|oa$k0A| z>$i4FS-<)r0`Ll(a!GCES2S$5M=*QGN*Y$W?S@G6-KK-QR%WHB^65afhaPk73Ig9J zR1MDjPqoU?EWn}Nn`sLL1*TY+`q&}X&*&?!Mfi?w8$>xtdA)t|QNKRQQb(E}b^UrR zM=;!UGS=UHmliRu&^3cD7u0-goxzZLC8Fx0UYQk_mir&v8(gTJ9iEN1bJz{px68Xv z-$`lV#wu^pQ%N4e+4E`)=+_#F1#v}#xa@W;_@4N<3?43Ip@yMrn`)U+veG4oYdD3% z3Omos3KQB1JG^be)$P+7CZ%K8P+QIy6m*iCM@wL$!^1j*zw`T&Z?|8Jh*M%_Bz1to zAT6!ev{O>pT`LriM#-7Y6iA?612(OXcKp7LycJmrbT8!wc$1YUx4Wl00&U%=4d!)m zci|IHE_Fkolfxn=#|_e{$Id4P!Me`&7m<2CEdnS1(GWWTWI86hzm1*v=J*;vM-470IxZ$~ z&R}gEtYx+A{nC%sas_aQ$=dLP<3|&f7VCZvO?d=|rW?p%B12l(^r?aa>FwlY)^6G> zk-W_ex|VlO7p-=*7Wn&gzx0>E?WcXsh`{u!?Kr;~I2V(~tFVU8BxuDb35zs3GxX6~ zPn-sp*wp?eR96B%$HZ+UH*lMv)~J{wG!_lWMQlap?;c1ZxlL$Cq9lv;=2ip$tP0Ca z#^+qcw{KTRIv-$9b`%P+)+F#RQeA#dN>fA(xK*3!-NTP;0T7D{Kg9DTE$dOu&Cw8L z!D&-i*@KA|+vXx1SSb%JdWW3ukHqA#uWJoOPOErcmpQ1EUb1G3JKc^72KVtY6zL4a zlimid?q#h(x#8-9W#$Q>MFVmB|Z2vtpv6#Jd(;W=spu5?AZ7*&N4ZJECfe!gX46@S1Wwa(pR;_BWiwiZlpUYS?5VL-8+vQEnW+$^ zL!|GMx1Zq6b*DZ!@sSj#p0^4~a=%ujHx=^PTQ);qlH5KicXYpV52%=r(^FLwd}v7< z3L>;+Z!diGy1F_|_;#la4!2eMp(TNskm=@3Gx)dCJw47JBSiUl4iwAk9a|fVvF&^k zK!sW(*xtT|^NS)X`C2#UvD!o-=-q$PL(b1U!SxfbjD5(<01MBK>}#``8T5L68|?s;gKvVMLv#s^zRG!^Rh}MgcSbH8#vVG{KJ#{ zO|mb^%BcVE7>vCiSOOk&Ky4B3SB^+Xh>a4EQ@LK9qFGG8_xkT$u-*m;`HJOskEr^U z*L{krURp->`HPwFR0)3Z)&i0?#N8HtK*Re-1wFLr76PZG31UdGgDwQI3rbsQRS- z-xmh8La<^Q9>9kJqE9 zHFG~YjL6w1zF2wk(1SzQGa`$orm40rs9)8`pylmlMkZoKevp*pv8+^pJ`yHoWSo9+ z(tt4#r6vW|H$SV>DfE9rQFR-F(Us|vOE+)d5>Alu;Rbo_zKd1 zTO*zu4eI&3#G#Qjxj6D!gB+SF0(4ZEHONGVoB@PMuh(_ua#c4Dx4!qAQPWYeubd$_ zl`)UVr8@crJWnqk+wbSfHdF8wV{)kfuUF+BiB7=gI8B8WtHf^S_|quobtjJn7)8#7 zH%94Pj+WYlkDm$iaaW={!M0!wBI~C}C)4?t-NNFJ&`?{Yh-TDN~@$-!k*7x#q zv}AYTHYi)!9WgzM9C@9mkH+KSv+2L)=ju!wkHToO--J&fW8#*9Erb=UncroO^ zx@(#`$-ifGr_Nx*_Xh|Nm>ge+an$ynv%Me*1EjL4Z+w-^yp`p%C;U<#vn#NB!&?A-jq)5JvNTpPDEg#oob!SI@hqX+-HM+YS>-K85znDGyuFeWg z*Gr&jY@f*jj!t3-k8BOczjsy$ve(_k=MlIzdP>^Dm9*Zr40t!-j({iTytd-O>{lZk zbr7JZ@|g3B3B_(rzi#lN(o{__eSWIv^8gNtn^bOcwosbP4lWFzGth@Y2=DAD!&6Vq z@nmr5aa^(;m;~piX+spVR}GBp6@uJ!A9wxNFNvFz_}mE42&Xq%-`H*(>k@po)SuC) zHKSv>IvOpyTFF=Fx{XpEZ3vkN4h}0G!Q!}oBC^*)O!7GjS7#V}=LezKSu9?{4EfAA8_}S=tmXJp4T%tu zUpM5eZG;vZMRrA6Zz}qIxXG(@%S7hA_oO?5sq%LlQBHRpk7@<7$s%*rPq?RFT*FUK zlN7WYzJ*+gd3UGUUKSb#iF>4utv8BIVid=3^T=V;^Cj-X5LL^TzkK-yd-N2lDjEq; zEY4dLJi<6NBI36r@av%cPvBJ80Vu1Q*pN>kqjkYV6}qD#Si=R)TP=MlDG4gtA~s#` zQ;A3@$#KZo(uUM zWJqK1Ar=3;y<&I17!7TIYO6D!p=_Zc{r7J(D{C-^tzzbO3MYadG)2b9Xy=RE%p2!> z>J0%8L2>>S&&Oxj1M%603)?k`*7Mb|?At7CXX#J6X(+2arw~B_OP|VBm8i2gSRAc` za&w=FM`f->Ii=pL$6i&}r`PM@_k?moS{)WV_YoVM4-p4dK{PxcGT0vSUo!4z8s5VQ z>(#-|uj*~Zb09^+0q{23BGiKuYL8CyGk_ z7_l`>FrHsDh9*P`m%DNVYQCVMOe6=im2X-Kpkf3X5_y}o{c$UI}(mw^g*{5@O z3DSsQm;qrDV+QF|6gu>&PL`=s!SQ^)-Xeua^v7W^3d=*!{#=~tc_O>a)%%Q5qYbB3 zXVj9#WmM;Ktq{|#*p#N^g$g;l(&)exA-5Y3R=%PHY%hLyxfn<=1g*=zN}N);Jub=3 zck!6rfV9Soc;f1*-YYdctAF+iar*lbbSFM7R7Mva!M8@aS=|FJ8(Ig}sXLt1E zUh@EgjBxt=6pH83KY_j5M@~OH+Vvx2#(K{It-=uVD6IZ1Td?%NyIH|w(;gZ!Do!*P zF0PhVzH=sC!!3+7KBvIOnnDv6Uhg}~WAw-GFiRitT!r)d3+{uZn#{aStPxJ1_v)NV;Ql-M-0*5~5A-Efv;7EETU_G&I z83V-=rX2>^7E|<|@7+HxFY7cKuqO`AR}ua&j2t6uC)vhmNwD0%5&k!Z3@^EnMr?+F!%?&$#RA z>kY4YpC$2Z6w<^fOUp@Yp zI{rBXE}h95#C3a>Ewz0q{b0kx>vBZK&rj^*Be?8s`3`J3HN@T)ky=-MlDHBa9NaxM z6`$x1%Q77WeNtUEI;)?UZP=C5PD{t*b47TC%UmFrsb;pc$IZsho-AO<-0X5p!B635 z?`w?DV}uaTpynxUdb?J}_cjn>v;{?MBph{2YY7PMF5^oP%g>XtZl@v6m_p&qzRtr8 znAWVeq9W$4%h!Zuc@9n^gG2{$hHt!jNKw6O9x;QN!!*lHuC?xyFP4aUBfLm~Dt)%$ zx%agja;v*zo^!;zoE*dC`wem;qQhcB?Pp-gp2jh$S{sNzuI}%9v2vYnXb+2RLFm>Q z!lzeSp|Pey#iWXuVLhFTnK()%c`Sx~s9k#R*=*O?a9Fgue$D6(2rhf>eMpub(rO6* z$-{{Usm8DGqPV$9G@do%Kme*yZ|%xB9&ib(9-XEWtJ9C;W(!`IQ8(Pft$<??ZX_dbNh_)@Nk z<0%q=mb1T`q=rp#nvMN$XkbX?M!=&1}ol zyGl4gY2YNyuP)ZUrc%~o$5e18+3+BaxezNiRlv3X^T4R$4qJROZ5 zvtY}aP+eRm=;h%z$v9f{Uy)xu%x1GlWMw0z(=Lc-I&DriFedDrolPEo=(@Sgnk6tL zM+s%G`msLdI_+=YJTyym_x79~RYLCCJh3ZU7BRtMG6n{3>nX_9n~a_u*?_|Dt@uD7 z=CZG?ST%FqlgFm4Ft|oIDc1)zE6W)hz5Br7p_Ch9f#v192RMDN=N$A@|w6ey3 zm?rcTJU9JdH80!zVVHE#`#dHsEmX67YtSzCqw^i5Y-FUP*-9V@f0NPn)1#Nj#eT7| zm_F7k=}YYAzdE{R=jPtNeLFNQSYM;JX3%zT!Ur9AQEmJ9M6B%*Im{8O;$iiv*{9(F$A(`EhUPmXROsCa%qHy$V@JAz%%4%%x zO?o4VNB0C1vTploJk@8>1Rf2@W2wDmTbrCdI@}W3Vi1bT%Tv*-fqqvTm;Q;a=iW(? zK|#D5y*|RqjvSK4)2yIiLdpD=C?HTz5~l~ranyr<{GgAh)|b)UX?5pSg5x?+ zry%nS1j`jm*yc0$&E7D0~3M6hYNB<;pGk9hY7#EHXP^JxJeF8{uR6kv50nEi4wKa zv{oGe#JXRKWlV5cg}DMcs{e5dlj^PxC{JJpz}p$e1bhVLZ*^_ z+GCf^krr!pRWC}hxO=675>tRwCIl|ssR)*QvA9&dtQe1h`i_a;54amhr&%_TId+;U zB@0}YZ4n=;+#na$FK*11{0EMdXIT2DTC(yjeszQPFvl_MM?s9%$D(6vt>>QO;?i&s za2{%M(r{D752|%lUqP~Tn5?X-y;q+-dlnoT`J}9Q^e8?fIwWEmu{;6|$nNg2oiC39 z{0j8(lf^0#6ykEmiTrN#ahjYza=aA#_xKU|LdpK84O9@U!UOD5ujV_H?zAjE~nvymuWs4y9hH%s~5 zH-hw-y(@-laQA+Xu;otDr@&h<3{i!E+Ku*1YI6uag7hjSzY2yIsuK?vtAeJ>Gl3vpslS19d$k`?Scs%qj%IstECpm{ z8rd|VZ28L7?K#w)6ByzTKSR%1yz-)1p7W?*89@b>c9IE031mQw=|gV%%i;K0i6 z+c&+7qBm~Tm`~>Gtb5jVx7XB~uz)d%d1}eHxdRsJDaQ8Eh(5XoFIQZ2_w*!J8{h3t zLv5bkEH<8Nw-WR&*rIiIER%3?solc70$Sndn{Fc{M(g!8cy}Y>ZVzZ4kL@J~K|cSqx` z1Gh5GcwS_XBAxj}(~Hy(kIAi8eUVGGW)Pxy$)3F_LZEUX#%4$m&sQ98PCsNl*KN3C`zwX-|bZg%!_ z5%W$kylE}p;adcF-@)bO$PyL$Z=17pPX})u&Kzmu>7TFf?EJcsQnRzS|JBhU(A<(( zNP`m=;NMMIy6z#rge=kj@#Cza$EX&9Ee3{AW86LeK`&F?9XMz<=_Al@YLe#19!wl| z@S&~=aU!g@d+0R2a2LL8crBLOQKEhf-Byd)Q(-vm@jpgp+>nbO03;J%i9O&g%~V(p z&La!=~fb#`sVExqmVM2=XR$dKxi=; zx}lnJwzCTXkbC_8N1#oN=(l#vcC%u7WwB6=EXb@rFgGTpT=M$MA;IUlr8(grmM1eK z_mq^>8=ITIb{%kC_lIYy>+iSmNC?0L_g-&jZ^T%PKbo?X~pU-wz66)SskKKSGn z6jWPY=?FY*I*^m+6e$&cDA(Mw!R9(xBI9mDLQGie4w)#^Y7cQ)!A~pogx8g8T*4)9 z+aKt+M*?FqqCa;b!h%C0ge$mCMk*nVb&bStB$!qY8s%{q?;^D7ZE}_AC8VTiDD#}1 zxxt$0x%*C!-mN#Qxudi7$M2l>r?aQdhl@2z-81^EIq;L&uV~PT_YkTQo5t5ikg!0eEFol5)6ipWm62@>kA|@f9)8pz}jdZO4qYK^;FX2Tj79vd~YYM zw+*T>IYex7+K(&sY<4bJzgsvK5$#*u(hOhnK!0y-q55iMVQr0w-#P8(70&kTmaN*z zPLjIGa7tg}*g3#{1NaOlm0|~sQ*}AW%CpNjbZ{_i*(Ydm|Z*aoz1irMUOQ=b_*Ey3GR>l{hQ}g}XGR5M`yL0r>pq|jM`**`BlY>)V zmCs#VbS;ZH34p?KJ)*7kNQ=6n?4ea?Z*n!Uhrumd%R@FzK>WP-W>n9s9lwZdo7+u( zNh~+Sr*3PC@QC{HD7^m4AS%-Txte&fa<%<1_4@kT^Tm~MsAWim)aFw5y&cn*bf9eC zP87|i2cw%PNSWU45PDSW-iB;C@^$kBqGUB!mwL5~|2;k3`Y7VuB2jw!SIOgnO}YHm z*Gv7S5V-71oG@-R{0Qp(OxVsFKU#%Fnwi@JoWd*Q;S~6Rj`6_tpK8-zr(tMrENm#b zK1mF1f2`3<%G0ZbR%1NTkY;3cewg9 zAWFv-vm-|Z4>3CwcJvZYm8uy7tPGG)lDs@H&X$W<9gnAzvxN~i=O4R6R_u7mW9DiK zRu7>P78V3dS}uscy&u}I@U^pRL0tu(bx*_?-1^6MfkKkz?p|^ntkgm6Wxcf5crfbi zoo}ygXnAuJZ!kQM<_2QGT$KwzfnJ}F9>yV`bagF7NXA#Y$C!gZp!&F&T{Z+!$6@q*L?hr-DC)Q1@(FFv4y2v zk~U*BwFkR9+kZ>#!ylQIRYnr&b=#KQx@=IDb<@XhI80FhIdKK;cA;E2ZwVQ_ostrC zE%IZpfBTYt_trm$zTwd*(X@S>ira&Ea_cXYQ zL4e)sGl`k0_jOPd0oPO<=uFvj;6^oV3(C*f25#utiUU00+>(C9N`uc}o25QiF|PKr z8G{j@#8%j^+bIH>$ZO2EN7Ome)R^YxyVtHB<2i1^Vr{&@STwTfbq^#@zS-B(aC37u z=aYVNb=`bc=lUMNi5+?a51_%JA)B_t^#gyg+7>9 zv%vA@fgtvUfRwC+Xs&`%s|A(L(OmK}iRTSp*%$U@RwXAFhK`OEZ+b=QnPYKBa5~Mxx&b@B~ z?vc=;>dsJ2yf!xuS%h!S&N%=rYqiptYVC8FC9_|KC;}8aK&fYUV?P2KcX=C_osIj= z&aS`^{$VacVI)9j_4E2V=9mST!*V_;N`RoBhBRuVW`X$^Kz;0t)u}kY>hs9FIj${u zh0(s?b#VqQoy(NMxuOyf@a^_+-~QTe$8PzOcBN%h_;X&N>B-WS;Oenj46etf4cT>r z^}Pdd(W_y_Ixe4bNO7A1IEI`yu`k$3ynRKM$YrZip>L6Vto97IV);< zp1`6aGxydpG$eT0a-`{Kx{sdK?k@h0WAbE?LImJIm3j|EBN=E=dy=p9qiF)dU(z+_ z`n%)eCW%HLdKR^jqZ&M9C@69P4(r*kr6sg-)xjx`z48QSjJRJD)Ax%AZqZDt?@nXCp(~##1Fu9A@(M zuPFu=((7pyAXP?tut{W)tfD=NR{deG-uu_MnZFN6ajUH1I;B^|%JjuwOX*8zth3#x zLg$>~m{ooNqF(Gk%^nI#E=ogvSv6P zraS>*#GlGqBr&-kunhl<_O#aJrQv|u3siu^gBY7s+YO=vSx177&Mo5=07^k$+e7B8 zwzkS&ULNqqOxq}<^$?tcOI^bJC6ToELr3SLgcFrI9 zW6{*4Cb^<;NPi*HYX^pS;r>j2#&*qaw6RpBhQ8iL^xK&-E!a{8d}I_8FCP&lN69Z7 zl)CSCjN#YuI|gdGI|h0|6$&2%sW>FuwQW5qxBRz%^jm9^i?~LMV)^*It7PL?%(}gh z;q%XgjNZJ8LVKVH2IhNxv#s0cddim0Q`>y};cy;o1RW^r)&X0%(C{A4=TiudJ_b}) z5(0QlwM<<&v&}XJ;MnYRZDV3$8r_+~YcCwPhPA#F$ck%gduBK#Nt@iZ3M7e!C1g+R zj_o=E%^k^*w{A2&o?c!by|##`W0L_ot;!y%sZ5V;XJ-e%WsB*uk@b~?*o1`Mh}3%Z zRuiwwx_Eju%1SGIlabpe>9XR|(u{xnc{_!x?O0xYT2e;F@NBX%j&9>h1Q7Go)qRjo z6$p|^t$%}wISBM-)T`_{`OkKaJjDkShJmTQ<#j&DR@rYx?y*_osW#r%Jy`L19oyd> zf?4Pa9{nVn@i793^dCMD$Y${PLClQckxOYG?FiDD{c3A#`Sx!tI=MW#ZQddyhXAva zP2&rY%Q5u zgZ+GY+CS*$mG@0VQj)qO4{?pjV{mh`*5%NOXg;6@>cpH-cYb&5=?f5u=PG>)4A_np z=cMV-o6L*^&}ggfkwgV9-2Psi&!YG%)r}jkkRvQMunSOOZGFCOG%%(bTkxkxNYBvKp8&ex@W62800aup!)ld7x z1nv#kK79C~T&$SEd{|?GcLqDnfu2Vs!Ma#J&Mqi1k7dqt`n^xKcWE3B1A+$Oy*to{ z5OY2d_%io>oNuM<3GWrr^DON-guR*49+!!2eZ$;r^RA|r#nM;oTZ~3Wa_y{HD`DIt zqKTJGH%_~x;kVZel5r={_>AlpGt8-vc zp^x9bF+rQHc|7r|XT?Lkv%QNW8U*ms^|#H}LO(2DyRV_>$|eQI#!^HOOm+YaB()Mi zhS(4m1Zw8eK_M; z`XW77@7MPCL($t=A1N4CR?X-`>9mq;>B1SqsK7r5Siieo%`^(-q`RwpH z5fM?5N-1JG57=-u_1M6&6dFMC6_4En>$n9ja2$2(Z?j~dp%yRM?{8;#Q) z0ZyThXE>cRC57ToXbB^pKpQH|Atjj5K_s@V+-P8FShqGJiY1jgfF4;IJv#y)zTvPP%;XPC2)4LRCD}3o<1R0dUVkX_kpYuhws&SGs6MDoV&MbRadSji4LjQ2421xz@7t?dBP;oKW?@7$ zy>YG;Oj6RQiVBRbpw@W)1nBSRV>Z)Ez5; z0^7WW5nk+a;c?X)wA@dprU_t%3Pn#j+nl7{-&{7Ew>l+bLxFALIc9U1eWCck01bsy0F(~#qgEc&-AjzPi3 zgKax{m-%c|H=<*qi)_UnfKfOf6|Ube@Sy{0jT>BgBOul}9zLLidEc{&pY56_aOwxY zDW69Cj!7eXdfA*i+vp{HdA{KDb>%_WHQNJszTQ%0GFx4ya6;cQmGjEC-zewioH$7U zW?7H%hB6W|^XgHNq3}|=l&f0MlkqUJM!ip7IEkI@0l`cr^78ixe z<*NC=Q+ovHYv!b-t@wP(=7!FP2_@K0S=m#EJwF`r0xmyRAgW}ru|DT>f;UVs!>~6N z8m?oj2M66785zm%zwsISH)GN=LR*QDBc!uqqGDB`ax0QKIq}AsR6ur)i&Jh(xn`0{ z<+z)n#C!q}15%0;o+EV7GWx(LVfs0 zKv*)5F?pMS0OOr8>xgV*T*d38$6mQ7;#z1G9H^V|fsc`{kGp~kLZ^{HyV6^$DXqp- z2pI_R(Z{W+hKN+(m1ss!*7_a|*VP^eNl-6V%!Y5v59VC_-JLAQ!G@L+v^YNia=z03 z5T}!Z+^({|(0TaXe7%luv)0$w zldoY|k;J?qz4w2#LUHp$Y|1*1uW z3FSV~85y7T^zZ{)*^}s1==smuGDTkXbgIrWVLhHBi(01hx@15|BcTiZ8+5qpbz}Q~ z1zpkged+RdTy6wSe6LQ+V*L#s@~kTWqyYNO729UCs22NIAMsDvBnu6v#CnwlH0p;k zxoV2K{U7l(8Ze z)%dA-Ghhcy08#Yob&Z$|kho=Te|=hde7msd+8;5Hkiv@{wEw;?XD7b^zp_R}OJ%yJ zKd_d=kW8G?-&J)dLTvpl+c&%F{`#`i`-ugS(?8duVLxmA@@1s^-G4u-C@nW9X1=0t z`E-+iPE9ToK}1R%hZmVRwf}WJ(5dO}&d&uyRu9ZlZQXFoQD{;NE8=s)R0F~;>CCcU zt{!BOk<$mDray_5=vDr!?Kw39AkjEGsz_gcbcTL+kAzm%Ve8VN#OV9isXt`{M}qr} znDf2_yng%uY%Gv&_3hq7W&RpP!6_3JRp>Xh0Ou*Lv=N!15iUm1rP zb-h&NFbTsK=S3rk0CaCVa;cg(7sh^nHBo#dK&2ZY7Ls1xyO$8+CLuXYNyW)tnjNkI zC_aK2>5Zq4!(wxBaQl9=RyI(4HYKO)5^3uAaf-~S?{U5gVvb2~*JB)r0 z?>`pu&rfn+=xn#e=XIh%?CJVCIGPrm`%-Gc)wAn-h25bqh&bmXq#>q^ZEP(v3e-a zYqD-7sV8^Z6?9%t2e6%Jg=yI zn;8)QUDFO1kE7Wj&=A-^H&_*1h?n)%euNc$Aj4npqm2_$&GgB)Jg>-lo#5x1QCJT8I}WD!bnxFr{mhJ zEweR9=i841^DsgPfSTKcxC7BizBHcs{tImBepm-ksqGtNGgaog_S<67n^(JOR&S*w%U!=m~43h53x*G@sqg}>GnFDMw?b#WP zJ@jyoq*3GijEt-!M*ePL!qHl-TvJNKD3210)Gwz6M6p6BrmQ?kL52AQ6cE7b(@_EF zSc+6RU-I&5QOjOGb*ZNTw(gp%;?2weMbJ)C!@;N!R`;IP%q~U02$_fghl zvGO>dKUel*=oHK$g+n@HZ(R>A6BFv%!3KP%L(43 z@q1iCs)RlEp3fMpb&CG!vLmd>K4fh4$)21^@tcq5y(v{KhhD9yZQ*y_!cvpkSJmiM zY2`+BmH;Iak>Mj3v$*vBv~`}{1|pygyS5o{ygZnb13*tmXy`h;nB6|^Yn>FuZvpQ+zuDf9kd#H#yG(QAu%1oQ?P;GTOv<^PZc!0TM>2BFYoX9|-w{xQaImq%8V9`250wQ7&hY`-43J5= zWPBE0&NnVazc^aTY_B_hy1LrY_2-^*HQTIKvv9yKL$1Ul$N>4JQsL;y&Gw_|aa&hT zLlXk}mEA>v<5D?KHLINX* zxYh5&4*zNa9Cv6(4tXa)!no+9&N9=Mx0?AqH|6Re4!1Ig=ss#L?7{eHl_GM?kL&lL zk+`y1<1X)nf-8QYTrVF|2DRw!@&e+~4C8q~8w$2WMnRW#%*@Jq_n=D;0_t}_Ql@m3UM6TF%xLh@PXyf{U>1>T!N><8ZX(^J$_0{qA}LLpp^c^2du;-!8r^ z;#QAUegkxJa}JwXN`;pP%iws`axG6bAU6=rHacMDir4_<3!YU32AWIapyk zkO+NYB!$9Aeh35-PR#ow1he-ii>;1M`)MSu&*;(D-KA#USehuLb$7dmnXaIyBE?37 zoa1A0z$`Z({DL$O8Q$)#w3B}2aVc=vw&C--wZ#}Kl*=5?4|@f;Yo1y~hGzZM8I%DC z*J07oWI$Y|Am@wGsM*@s-tGf>R!OW5%*V?wtMLt(sMe$0uXAG)fKWhVT^aM8A0t9SB-rmPm|nz2RH=u)kmRC8{ewTde&$4 zee>gOsyl2C;ZfkE!Hwdm9kxHy(_f6uZEw`~`}a>@zgzv-zCg>F#bjRFH#j&NJCIyL z0dMbce6EnIW1t3e;0lUrP;7Q)YHD`u0Kzd2lMcwwh0^d#*g22!0IF;zw|Hw4xLCdT zDUgM$w{fMf%H?*H!}N;yO7=^#3)%^EH*^$~0=0@|tGSk& z*sdla;jW#jW(?T=lw2(_=}LpBbtn#9r>~zltwzan86tuwW3|Q4xNLi1@87d?(eUvJ z?O!u8GOh1}N#d(C&HURd4Cz6P!<6I{gr87h>8&l3BIVOe zOI+I5T;ZjwL63-tRMN`=J`YbBO3RSzQj?O#DiszJ<+QZ4obMa)fsYJ9pXif_x0>+N zzK*1nWJsffTAj_()9+zYE`jLyLRTcr{T8L4eD4l!9bSnA20nig^zD3_*wfR??dFVA zpv}9xn|5cqoL%tZIHLVgt8M?n7LJ5LOl_;9Rq)7%EG#Vi!_SW!hyb4-uXx8xO}R9| z_IVwpFh4?|AQ{qkG3NQeQS>oqL|Ftxlv2e`rvbNbGBJ|>G!OP=`XLmIDxZ%^2^ zzJ*2SaH`AB+%ucShKT6sH{e6d7|v3v{TW*_a`G7F6(6Kup-^#zBvwO|n{#N_^mGCc z3LRj3oSmH;F+&Ln36n)SXnk8Utnc5Cbu>rY?VPoEdm^ZSC5?eN04QYipe&_Tl^k-l z%X2ljFEOI@78{~#Eq1>QCPX^kfe1mMzN-2Pnf z`TOM33KRqEfqueqY%AFlYH2)~=+1!t3<}=C#K(bvbDKC?9Y&3cW6L<4Of9mQ4ax6< z)*}sXb7R^4v+u=RMzd>yJCebqvSg95;Kf{abU*c%Em@#iuN&ag$`P_u|+T>hNaE zjgthuPy{_MOnNSCQ#Nqlh>1M||COsf^*x+ekZsJ>D8BrSF0&ZBs_JLhFUmz~xcKJZ&>0?!>BcAma*mg7L_Xn|k7t+s z?1O;K@aq(Z8N=H_z~S!wXCFw5kL<(e%nWN8i!#5~786$P0_&Ml7$g!QLY%~n5jPxS z;VPb{{h+}_OFKLe;;C_i3wX%GF zt5%||<&^QTcd+0FJsCH-jF0t}Yg)X(M^b$EQ5* zuVDI1l@Bm{*5;y*Yan zT&Pxl?Kh74jg3yv&n{qeI%o8KN+zF3oJ`S?l0TY3xl~@vRso9B)L1gQdXWyJ`itZ9 zzN(kvAEjfd*lg!V&JGqb&-c~?xg^EKCyLGOzpEFuPZp`h*mQLB*{z+W{o^SS{>&)s^ET;VlTjQJb8$+o$ zd29*Ien%b4E!a+GkArFTi0;R0SU{aLb@otk{qt*=pD_yuhggxC2&wos}Gx@{Ak=1C#^uP8JW1PTH=|#*yNF_LMfX|NA;?wD~|wtQrqaSuK*1x zCH&VB2uCrd)guT3G^#`xITI3 zdN4057ycRU@!F>N(SA0qT7FS9ic)qfcBmgAUPc_4_w~sZB^_U=VFz3+zZ=sb#P1iF zBcxe#rvaQ#=PZvZBn5r6%cHsv!;MK_!0+W7@NS#*zFmB7b`7rg50&RXgcsN0P=3pv z?@qzElbjO+-+6Uw$-SLN7m^h>lG*&tqzGN$b`K`2o-f#Ri8sz1LkdKs99$lK zex&|aaj(UZh7?G)%mywtSfst}yh+8nV=T9o?ksN3GHF%wIbh+DpT7U~>n*U;cf}@T zoyg?FiQLRU1(&a-3eV^2ymjN^cCo)C8Fjcsqn*ogdqI-xdZ6vRJNfFPtL=hPk)uS->|$F$^$Laj=;TU5f0-Z5j2LW8JsV+n6}+t?zNJT||F`k?h5#jzij#=xPU z_2B~Pojhsd=ewF4RBs<|fUiq@U%M$)^;%rAe}#z|Tv>?$D%Y16JEP0VOI{aL^ZamY zftmJm4Y3yo3;A?Z$7NRUit~5F_IgaWG6ntG+P+Bg`0mH$|1c}r#l^#`Fz&IN{;~9H zqi)=hv@~OI{C8zv(Z{r|^N)f|`pf0grtP9Uos}FJb7(>`z~I5D^WJ zV>Xe9_(H$^dVO)YqzLi-qIrKyBH(qAHmgZl@3fs@vSyxp(S%K_n{=|-@3?nCl&_H5 zwNb>*w8my>cr+`g&UH$#&v@%<)akf4+879;cPnp) zQUo(i2mA~>0_&~`_oig8VCZrtrnc3Cb2|&ws(76IXO5~f10`RO#+(R{rKy`o_5(K6 zgzaPqIf>1bZ6JYh8zjMMW$N)+qCphJzCn@0cP9f@K*Kv2^#$G{#uWzQyMRxgbLFw1 zTklkE)RpbNFr49VzwwB}p!s@vBm$pvWj`72cs}Jkt6;_ttD@5QIGZ<<;Z_YPm8;}_ zqXicJEMg`WaHGd5UFtAgcDk|O6poF==PItF6l*S(ffxx|z&UL*nY8<}X6hdBGBBhi zS8joVZ$XZ=V0tFoR)^Ydsi9-FLy}gz>P3lm_4}S-J(yW6hTf}VV*qFf`aL$ICfcQY z9Ixf&+qL=%Di^&YSZi;&)bN~$zY6xXMrm3cvq1uAM^J6i)pFb%&MTTI^JB(l((Ha-8wLP^NbL(w zJZ?LRg_`?5ARq0^6edy44=s0>clQt@6ALN3 zy~RQ`I_)YO+2tmWxx3`t>d~k;eR7R5eUNQ7;`01t26ctZmtHX|?;!byuwnTYR?ElRo}9blapiN;_4n9MFSFLz=X@>fll7HS)XaG z4RZa~?e$C_I{0tEbhYRLRcfVLeOnYF*UibDO8-FrubkHEGKsY5`!9FdQzMDefipw*0wD%C zGxzgdWY+)$l^QwA1g3OFkZGM0WlO=47#IM&Bf^##A0v5RD9D$72U6uX6L7%<$q3 ziujA@Ku**k>b11WKl%U`Pccz;@(*k;CXu63e0{OcdY7ZhEgXX;lIwqY zE0s1vBuQ-kBHH2KUhrTfvyGtvU6emFZnz@Ba{G%q2Hnd|*-&e@6#EzRHF@pV>N|YW za|vC($j{$ndJn$$x)9J?J^u0Expuv;iGu=H9FMD7pv(nwVpxF(A^zX@;me=OW>7R} zmaT*tuQ*^HYe7r?Vz#9NCOo2Eg^RuDX^shue(ldJMKaS|a1?Um0SzWpAmhQ+HP^< z57BT>f-WQYSyOul6i$FA;Der5|H$62=KtW~EsnCpOPgOW>A@5BN6U2Sy~U!>?7b@$ zF~R(|6L^i@RhT09Wo;QS15$sf@!3=j4|J+iT7>9V|I#tRWpN^T+4tA$AQnJ(k~9YN z`;8ypy~K1JLSHLRWHJ|v2o7EW1--kwJ31z2-0v1%r>$I*KJ++x9XMIp0cOmse?a>i z?yYI84F7;#=x2@2FMWMYwcOI(PFH~ThC3ejgzC~K+36g_nS%KIl{ziMSY(jGJmNo4!je> zSFb)b-ZFy7e|%HzR_=MOHE z_(>M1fTQqtiBhjPN9PVG49gMz^RCh~LS7H(mjtyRS{=ex$*ET!FVd%71O)_Wm9xbv zqO`Kz9RviLWAqgN^JWnPT@zOl%}}#@5p5)-e6-_rod(^sTqQ6oaUhXibZ;*s6+M_729`EL|Q%1Yc;uMvUjhU=$)_UPB^Zq^Bca9_*!RF?f9Y*44 zkA3&mF47|ns3Rj)vArxdzq>vu`n#q#U`-JBTNcZHhDj?IZH_Vw(3rEuxZrfW7SHV1 z#BJZCRes{8&F``{ymaNX9bAD=epZhL)7Tv*!1z&>u&iZiP$Y$2RldvXesET zZ}qt)*3-QiD-6NtkW_fR@`$c1-F3RK>%vpB`zB1C2%u~^)2vH%4yg~YzS&{2!oK*t zpH^1TN_L5a9K$alE(H#%)DjWtgv^#e&%x_(f&>d6_5N&@R=ejZi^=S)`^)cH!VwV~ z4>Qa6&JH_0QKFL8OZlMUeQ4k0upW!7IcNZFN2?}8?6h_`Wl9~(PngThQ*13=TF}=I z)@8wiizF0$(n*PGHD%eKVC%P=drwWQ?+wXQY_e5X*Q)<;L4z|)e7_+YBu}93u)43D z!owjqRbC*UIZ!mQ%_&@PmUi9h(=(dcJr2Gilb|ms&w`3VWpkN}>Mz_qh4S1WB$gYa zfxf~>>pPX(DQq*w)DDL$A~{qF;kca9-@d(Ft+YQGK1fmHF>edjjz}zpMOw@2f{bHFdb`^+wJaX`4w` z=G3?gz#~(al9Pqy{Ry0Juak~dJ^rk)1|VQf&arMYYf9+r=tL6FckFAaCbfP@HWM1? z?Y#_7XNg$tfOBj=x0gv|>RR-WtqR@#ykHvHkYTd0#c8vA#t)BDzm_kqa?us0@nhj< zz}65U3paa?6e<7KutAJTGuR&ngKPdUP~V^b(XU7{H{2|<=GX+JnaPO3Esg#Unm&00 z_-Akx@0Xn~4wu`PmvoZ2Ow;mhmTnmLAFN3_f{;yy_lvY^>wS8Nn|!>l&5yWz_3DGG z{cJ*KVwuW~sVD*Fn>V0g2>S2ry|mMqZPNv};eLVr2JnhjB_@+ekN+__x(zowd)MIL zS*!~*Zva1!vTS}5lazG2zmeaas-Cft-Qi8;^dbdKFxyvS%}B(vi2z7`Ma1YwV~Po^ zV=$@uV|T=^)5(?Z?qpHd8Q$rqy3X0VfB`KQdp_!@`!5j@oW<&86O)K9UI0u)CI!;f z+*tcZz9@#z`&~#_WTYWD2F`BR8L>T=6Ajhm7*z5zaR&9C>B*JYDoyUMjEvW*F=88z zD5%OW`B+$j0dfaTt*q6VbD-~5u}QCCY#NU>)8SX{y`ziGeE*z;M7Sh!=g>DSB-VUo zGM|#awhTa?QpN67tLJCDpaPTrDVTRj6n!0D=MeHS$>MKR;ln_~82X)Rke?HUCgSGY z&|eu9MG{LjVsf}|xiMgl_y**lE*>w^dEE}lKpJm2lhL|vOCn%`38ZcAo}RC8G392M zh<26_yyUMxix2cAFcOp*cscE!@mkH4wyiy{L>Ej531JPoIBK7q^xr$IMF+_>8xA`= zdqT;TJU4S>U54XQgG+m7r@y1AtZKG9t3Y!G)LcQnFZ${3y6{~k9}L9BLUzxdKTC}c zwesA0ZxLqlyH*4>amHkcD*c!{m)-L4$|oPK(;h0bp|rt_){AKBC}dyX zhuQh9Ynx^OSNyqmJD^dodI4jr&0k@(d6aS@)T{?~fBh~%cG2(ZD%KWy>LDL9HF^Bt zIKOL**`R{$vzZ&8-6{{M^>cTBw%~SX*i+-OQC|LFW25Sq(b4Gkl66k{YT+{Z8G97R(bG6LAWj$3q2J*!TQ1wN9xf#o^CWod_-^=mAX=h9xH#ov(5=IUq^> zSeIdMEPz=?I%-5K$W@CZa z0*o`hKc23_e1?jQ98$Sk>vFtHL#XpEEs)>O1oe&IF}Z5wh^@vwvOj}>1A z%^2Tc-@-^Em|(9BOSGJ;pcO~Jkzv6}&B}VB!*xGA zKQ%B{WhwcYRByp;KOeM5+ARMe5QTsIx>1gVgtSIU^8lpx45rLvuVisX#=L1?A|tPF z7SF`d>LCOZgeJ3Vpuhl#x=)e3J4fxi`=udMVdq+rS{C6Uw;i-*Dk~!aKUv0eT=?Ch z2tT@UI9N!Tm{81Bn&xPZkpT>gN_!;B0ruw1b?naj_Cl~fkvZpDEA^7eT3xn3o?d>K zaE@~!P6i8v2DxOu)MC(~u{ zruXrH-*Id36KHuqXc!_C@_cF_{74a%9G6(8?{wE`d2@LX{f&WfIFU=u3Jdhf{W_nO z_V&4>QEp1g-@oJ}_;Y%?z0xAARb#?L@28i82Phr`MWzh5%{32==`y{LynyFSOD(W# z=roB-k(Exjp6Q)eW57ZIezx)FlOBT(TjIOcl8(Kd(`UCtyq=#E7*ni#6?S+}Fa3f7 z0-l?h<@*OovUu)edV70wwj!?WC8q4TZpv)(I-Wfn8)GHp+m|`Fihn|*JF9Sdi}MPv z4|u*Jt(=s6{WovW+zyuuY#U2Ku7G22@sOwl9L3hiz1Ha|5a812_M*@i*JWI0?g=7E zL)_3~XT5wj=aG#t5$3B7!egCqE*_keRHrW%)PZLMBLTL$hZe4`uL0}k!@_z5k#u-$ zBL{9r7Gyv>yW_&kqbHMTw;&YvCA0Ip>|1v)lpgp=Xt0>x`>#=kam7P1Z(_2jQ^6))EQ&i@Z0GL0ymDYF#GoEw z@m(8{OJhO6z=(Bs67x~0wu-0KDCJNX*8AXiC~|J~u28o~B-^FEy}i%OG@!N?)#G#? z9UET(@ZA7Um75kwy(AGZdi>M@nptJ{_+Y?4pX`MO#L*nvw*$d;0$9QCnOb;6oWahX z9!2)JdB`JUnSS%?t-=A1^NOP5M(^;rX)$`$LV*T%ASwZ-eX2?k1qVks$fwcJ(Pc)6 z(>afpyf4~SD`Vooc+c$pz$N$u)`B5`sL?Vb9(SNzM%q? z;aI*1y~@ch_C4_k$TQ^9*kVcGFAGdU>WH-f9uLqvLzBXVIox^Qh0u_7Nh2GZLGC;m zrF>`Fj0fs0TtdRnGZW@&B`5Z%?Qt2EQQM0Xr?mI*4`S;Q=SA9iG3uGD(Z>;ltp1#S zHre_e*r3TU9u&)6^d#Jd_z|f*$G^+rmxL%5p7h5t1sFTQCom;oo~-+qpnU> zkB+iz4eGQfjfqyz3v*rqlfP}H1Yi0+p6p1Tk_v? zmBs2|EzMpyZ)|KBrl;$9z2D;u50@mfSW0|1Mn**32IFP$c#V3g4T88pSgx0Eb^EgY zYF;oH6Vx$d>p#)VAgx8v4snKJY})VT$;miCcMJ{=zCcFaZ0qPrN=Z5S zGln4(&k${~6y@!Ghb!#B$L^aUb+}kx^*t7son5s%ib!Dy{~fK)7C|5~(KoGcl3Brd z>O)o_OcTi>B6?o@?myq-jSyl|E{VPkk@CeJv zpZXOB<}$;HHK2zUOlP1tx%UF+WYl|3y-4lZvu82P2KqxS*QeWEN5ajgTg~v4Dqa`97w}y}LWv-Ff92OV7?;5go8^2b zW&lB)Z4}@*SyL8r8{t=g4SiPN{o898twA*M`uqw$(}rFB6L7PF4Q}0ogW(E9=^>Gk z(}SXEDy=`XWrI*4zK%EklZ$R*TYp|tBweH0L4hoPDJQ2x$eMJLYnU4X=^6dh(#J_U ztV(lVB0&scK9Ie&{?P2LDY3qG>ha7rHgdmYT8X{&^tz4V*Vx6-y!mq}3}5d!l@1K6 zyZ1LlHNB@BUuQvpK~EqEc&%5U7zfh^w8O-fp4SfW@Nu=x^KpCF{IJ}arFe@v{0K(4 zQ1bBj-<%$M$Xrokbrsi{JC|D0F~=t=lv@db%kplnne?zL=yCCI_k0#IPw?!z*b39s_HWyn%d(As)!fxD8#GRr-^(oY0QVy zUV1*WA_pZ!8gDFdKPD#TAYiIN(0E$oVe@mySaeect8T?rt8xUCOdzNO^-d4y6ik3a z-lgCt_GxrK1}$h^LpbJ!(UkgHK*aL$CGzHUNh4^LuQ{3(ZEm>G_VJ+A%EmPxseknf zPa4p|=EDugL)_A3Y}%C)?{uTm*JiK~ufbW}8cY!hx`0q=DS|l|W_N1yRSuoy93;VzK9Wak*q*7$G( zFCjO2coVUp*&y&BLKA^Mz5cr#Lrh$Jb$uP@@>aD~A*Sc<_f#=A5;2<$dpgXo8)4to z@c`o#5BN&+f$nMfR_k-$+%s=V$<*mc+&lA-ZEVJr3bO+VGBR?Hi@WE3k4_&G7*j3v z*W0`3lX;EN=PJ974vN)_!N?05;lcE5HM(_V_PfW-cTntECAL?MPWS=I>YXnCchm#m zvWzS&-hj~rAOYVVGe(W;_w%A@IldreU=V2YiXC?{GcybHDcL3D`S1)h_f8cbHX*(U z=YA~cO+(li0mEiS&zuE;#6l)7^y&2}I$*0uCbmybrmR7RD5lr%9`Q-wTF(Kz}ux*`k_4x=?{j<4`I;n0Ubj*iVnU z&RFXid!_r1H63sietHZj0BtAG3OPYD(}WP=ptS;_R)DDhsX^O!$n+~BqK=0zlD!#> z1i%T4>$H~5;o2MGBZe^?m#*t@-z!|$%+wfN@9+sX@DYu#y zDCyK_aO`z}jjo-~v$3&d>s*rHvRaYd-(E~Im}N7MWVYr8Hj7ql*=yGraV`tB@YEhj zfEiAOkV34Ez$n8EreeJh{6x-(~+s1>1hT(*q(ExwLASBFAMrD=7cETRcYy+9HgUwvV&z~OxQKajxA`@rW ziG?Fu$Bkx~Akq99OlfJ2qkb!jXNObrl`q~H_1w`=aKr&9=@nsas@(&vpg|F*#TydG z?P2jo6sB-o-srcmw^mzri>EU}?H%N}T;5Gv-mVTi@ZOrH^>*xhZU>^^0A9GH8X9mj zy#k)N^qLnOed1;~BZFGNVs#=v*;{sk0WWY^+rR@gIr448(3SC$84QTuzxq_oEvMT7 z*ZR=bq7F?dIgT3|GI9fq+n?E54bN>z8`o|5Vg#AlYE^h+oo?TyQ6aK~oDGz}gD=&0 ziK-oHCqqQsk~iP{Ud`cbF$7qnO7}Lo!J(ld%`8Hn8)x%BU&lBsFBqeUJy?AAU&t?I z2BK^nEWo7j)ff-X(uU&+hPMYCw9M|kL_jcG&p*%w@Q8%`yoFHf9=DxrMJd;1I!I6e zsP*+nR@YL4bGGx2N|h}n!U4nAY%ysyWk-Wb9ycH;2uD7J|Fq-RDtM?7j*mO(cl9Gj zlhVfS$0wXa+B}tRM^6Bgg>TR2pDS>Dwox8*;WuF61$mV`;*}TkFSdTQ)(vT)Lacfb zJ&Y$NK|A>|zd#Y3G?~1Zq$FIBqZlf~#W5#yIg!H!ip9`3iZ|JUph+mSCbKHy3iN$x zy3$D8C`d@16BA*e5F4uqAWukmM9I2WyOqWRaLTZ)&O}qPXvJ<`UQkrV=uuEsUHZh( zqMHbXq>PZHL8?N!SEX}bTA3NKrd}V?wt6N$hh0}0J&tmg_Z+jQE^is$j38X-O>e86gjM?|o4aCH9q^=4vSCre4G@cmW;O1@j{k*@j0y^iz|xc&!kbOh@= zTZ#7+pmapM$F1#!p?DZ4XN1n(s2jKTdwDoJP}l>xSg5}lZ5+#z}>TB6#Ica?BJ%RK5vvm=tsmRAT8EvT#T zAB}l8{evNip9p+4D5QTS6Vc$1Y=L)3?cdu;CM$bI2-8h#wQ@Kh9U-6GD|2ZCbx*pf8hhq+MQ(hj#gU5&9wS+z-6ont2EL4 zd&STtoUUNm5gH)KmT;Yig3_N+*_c{MdJ3Wa0 z*Nb4S-k%)o{qvIaq#LYEg4~m@dC(-wIOsh#7q&Q(8{9WptpUNct@V;>=ZxEJ->clrfP) z;bc+uq(&eWi^-RUE(`hZvi3p#;2#*ETHq=V4docVgo{za)3y?MDzDJ-`vDZhc31Eg z270vrC*%_egI?A;0CA4h@Gcl?m@i13<)Clv@0tr;d=PZ;w5}(UTDvnP>F>QN^CQZC z_O=7y6AX{UIp3XE1%)9DG!@U#OTBt%ym+}wseYjhxcQPazH-n4nBEk~Zq5t{g-@Qy zIxOBBo$jW4)AokP;|92(AUwyf`S$oR^Tmr7&sL5x6t#I>#`kZ5$_k&;;puCjO#n~~ z$dK?p0{lOv+M*}ExWcgjZ0J?48(_C6qRvz>$$Y+oS=VG;hs!>1cE%|&Y`9riRtgMZ zuYHE#9_HMFN#M^X;*yh-eQTOK`-MQCaK25leQzqaegEf&s6gah$GHQ*E0sN(Tt|~r z|6U!(130fCK-6p(ViioZwMH_8XoYyJQHc>z)*35=jXP+{p&vw|TGy*xECfA<<2 z*wI6reyGUr^zs&1G!gIS<>$}7l1pAFCcG=seFZBDOZSdJak;66k3YY>oE0GQlUiQ? z*4kG)+w@=-Zyr!5!vNr__ZXuBCOYF!FMo7wVn)buXE<&v!@`8+1H zh(Z~-;czeR9o@P*z)6v*#u9_(A-{aDjPCIfORsz9CEBapf5F%xRdv#_!P zJ)6WHh~KWOeHe-jt~*i*3|p4C$$$eu0tWXSE3|*evk}+jqi~*RGCIoBC?K!P~-S%RVM&}c7?|&3W#B?N+!Ub zTCf4RI_364nt_e$3#GpkvCi-(9*7UYjW@ba^4 zA$(Zx77dhaK1*h^GqwpPUitY{;UxTNU=!CD+X5Eroh^$#RE}rV_?gq(jNJz-rEG0B- z(>MQD-W&avFd#^BwBDNJVX>ST$|GZ|HU~0l-QGF^kmbB9GWk^>C!2B1X^O+r=^yE1 zhzY2byoiM~lZ#ndS=(l3ae+b?;IK+XYCy6AB5VLc{t(2QtmVBpQjJ$F`e~M16L^Mk zDzsG@!fFc>hMn1G6wUg8yQ4l1=@+qM9@!k38 zLhuOE`na*iV43Az&-O#RUg}g0um)+= zMKm2)i5#JD%>G=ZPxLw-0JMya@5Li2p`SQ!P?qs3H+bwX(QJ4n-fTWnYz~}!u$<(- zLByMMuZb8cvGDKxFg;NHE|^*2zy9e7GkFK^&UOhDEF$aRJ-mg>yo~<)>*D|Y8u07n zmENHJ{jlg$wSLqYkVzzm{;Q0*dOGddpQs0%IDP8?r+P56%)h^w%c_w%b0zj465PS(tY**ewUXt6!-5Ay#H|o0}_@I z06`GC2=>(sSt}JyogE0rId1kt`4*V&$W)o>9|?o$f>Y?(D$$Sgf%GvQ)$2AC^#lz{$y} zBoYr4Y2b`%mfHwbTd7lf)!4kes0Rb7g@k;8x4w_HwOMFMRaZz44h@y*8^8vOQUR+d zxPe~%z=mAEg>Y;N6>&t{fU+x@&4a;dn~_vN;Iju}!dPck7FD!HkqGai{bKvf461>F zF!(83W-}B-(k+FSyPC6o!LMM&&5@Yl3HITV6>HDxU$* z2(^S~qi>h;l2!hO-?{9uI7c%1#*4K+|%Z2|&KXdzH^ z9qu1eDo3r!5vug?;?MBv6C(uP`#J5D)q^MH=`=$0G}I`i%3GTC+)p}Vfwm7!hiny1 zygU#NFDnz4L^<3V{iNsaF0{EqssV!;syPp&8(;O_p3G`aWOdZ)y0s>6l!O0mHT6TH zBxS0+>gPA}s8ZclUsxD>5`zm8f&O14o&`gQSkRr43S53k+L=f_qfa`X!O#y>E9D02 zC3&s~DK^VZUlJna%Paa3IvM-de$PIG5|vfXHtpAli53&{uNDNjuC7}rstiAVQWu0< z-)+9H&3KaH>Gde|5pYIB+Ewtc0S*sb`5(`lw3q7=zxU6f!^QeYJJLb7uCNe_*DzE| zrR3lHGdBpj3BYalEP0`7vRsGGqkPwcI!{r!%k7EE#9)N;T?vi2_%)gOTX!3VtWeyHz@XK8 zA(fG6#OOM~vW&6XD{iR2MH+a`CX)pRrpFdeSs57{17xVPv-6u0&5JO$Z{B_0mX3dZ zeU)-Ft(A(cX%)K_F@ZBUajJ6PVZN(8`p{&%*&lCqUMA~2{;C+Rsc!WHa5Rt5JN^Mowsm$!2 z1VrK)%{ov$96tCqmMOI`=QbxQ0@hqInx;8o(>6&3AIckO^3bDxq6u_}9wQ)b-su=9 z+<0PSg-|<7vdI^mHfq!FgKC4H& z#mQ#n6f|0rvONLu3AjuXm3NL?Tel)zzg2R10vIZM$Ba{P@z>s`lE5$AG5k;o+kRyT z)lOwHXE^fn{0ZwOd)BEJMwvw;HvczOpMYK=A`;BJnM8rvg`+l3N3awYmn*xv7WcCs z=oUFbHMLo@Y)q-*N(N(pqPe#GG1_xd6lfO#0?uBF4Q&RodFXY#U_l^laHjl~`C2?2 zxXI)<=epD3^g1CZuHvktZYy%2zQawowGODB1xG){;I>JKx+1>0 zsSR0{K#%r^e*>&PO5X?b=;@UCEpy#D8IB>HH;^of)T~cWhz>%>$4Y6ay&)`@ZMF*6 z9(()@(VyyXni9Z5EZ?|Qp8PYCkd%k+rFgW2jQK#M4m))uf7K0LY{=sjhy4=;zN)o2 zQTmqh{?ellVsI{#I;DLgxzGQ-v?Pl>3*mVp!ct6@ ziwMXMlTOT=sW=8;L{nqQ%RI1arYz;Q+q-srcQ{B90$N1T@qQ_1&Onp!9+Te6|Lmk= zw*ht{T9F200VnFbcj8V=$m2-S8`8s?U8x~mE+D5gfpN6O7Pa5pH_ODy22SibWD%MOojVkX04x*FirexWCmC~F}uCida6 zO;kWY0Hh!?&X6=-CzT45m;LdKU-I%caYB`#Rtf4;roP=_vVb4q@;tMn(QqCoyZmv^ z#n!89vnl4Q3zel}bn!PRlHLJK&8G#XzWjeTG8!N>=-$!r$9m)o5E?WRHsA=dS$+j zfBk1%g;YHK(K7HV$MLjgmR;|9YGUN%0%dp|9lFXHyBJD<9`&kU_vKgXDzt_;s+V1W zZ(8$R#|CN)R_~2xcaWBehSH!QYD$?nsS8$FOyYKh1JH@G~}>o~q28mZsx)7M6N9 z6|h2Y@eOT8|HE8qkz)V?#pVx!zN7;2Q@$*fB8%k;K`;vQnykm`v^y1x-Vd769xgVM zltDih$RdRxdUcWo{{{)08-K8iQbpb;DapQ9sP+mu6iuxk4WWX zwc6ismsZGA=>q@_E|2@OoF0WSKJ1UA9o^lsO33$?Kk{ul@@EYMFqVI#YLe+^m|CW?=u!c$oowR&y| zL81n#;SU?XU%s|un$UJhsW4s05}3x_u(Fe&#jC-ph$z!uO*5wLg`AB7pU%}I-PlfSr!SXq8#l$2kyf>}V`0FV49=^`* z`TqIC+I;&UMIOWja&)Lll(H~0##-0t()9mSmukt32zo!^=siPC!@lUA0#dFA2MwHPuop7TuXm*@)a;$Pd97K+Q9t0WPgsw{eQM`0& zOkpaF?ZK4KfN-^%ER<>ceC^_sq}J$l^n`VcHLdXj?NAgJM$R`42#In|H=WM(vrXe} z#m%-aJ(zTAO6EOjt?%(XY;AcxEl`21#Sjd#PPt|P1SPv`I|mSg^uC;FrPXV|1Xaoy zT?V3EBJZwejBV=7PmhTsLY|H9Q;9{u4$JL2uv565ek~4$lLhPp1VTFI928XL-kV1Z z+AJ6|9bSD#83FOFrDJhrT8+_yeg`@3<=GV6K167^y`McM<{G^az1-{#=i?k66P`aC z%keUopF2z^sIp?`;6M@;g_UmxGRx7d`&t-ahAci?-ua3|K-b{q{wNgcvR7+GWDhc2 z*~GH;&J9SxPw8f1lKcCSw;6(7r9L@N{QuPgoR?R*T%-}e6ewhN{CeYdfc^ih8r{F7 zV68M`&Nb>fArx*%Y=gaJv%BK}6r~Dbs+7UB?JQK$efv1qmJ}@tq#zCIsM6h$*V3`L ztw5|yFjJNdWOkSp^hq1rT98&%&?Od%a|?{sQmGY1KJ_lOlZ4-nZh2V0Lq*d7KVIEpKfZ=0A3$+hzc>^;%-Wzq(Wsv4a!RLWu#t7t6WpDL|H2?^p4f4j>FJ4*jx}dMb-NJ`Kk;COGeo(-A+^txxMt%Wz?)no3iF&@z}Ki$KPafwojUPptCbc z^w#YdRFft{DJ)ra-hH}eLrG$*?F~BZ;Le265*=!&UJz8Ol%Y5s6MM8UwRTHcKoA4f znSdUemc7vgV1XbHm+n68><9xj=zH7rR6s_87eMu*FE4J(z+g;v_xA>%yf>O2?8C*! zi}@=S4G|{w1pTWJznMrQ@i2fRi2yoS!1wOx7%24&&%fsZLFJVVK}Lq6pcO$Ko32={*S`^A8$VSOCJ{rj~IfleY^nJpZR%h)sf*+72_EQ!^BS<5Az`5pb0hR2|7samTMAr*eeaNy)~2AJu#t8Fl>t z%k$8n8z_cO4@((0+Za6C8LU-op&a^MSq*eUh=8Rf3#eoY_YU9Y zoa{@r;mpd*l(6An5^^V@@rp(Fmut1H@CB%WAUbe;-^7ayy z4>k}o!n?_N?zpcg3U1|T6t}Z85ct4UJZ04#i6?#SXbSu+hwb=R9pp1G~ku0+DMR z#I~elTFq8h$|q0Wdb7R9J(~Ld7OK5IC*ZO(o$Sr>9={|X9GdV&0GC$ke_ng14nQGr z(=KqDI+u@NgfVEj6$4-T(}tl_00MOxh1=0GEFf;cr4*}{7Pw$K9^877atQ*z+aV^(ixc;93a4Siz`_DIwf1iKazI0M zJnxxtPk63P^0?zNtzrB82Ey^D%Tw%-09rl;10{}F9ykk!8P^`n>#ko}b`1P>< zbCm&g83y_ZCIJD#j~@&G12?_lc6xz?L`D>N)EQd<9eFzM zh`&P)Ovll7+EvPYl?T6GqqA6%+=K1OzK205mRr8TBk8jsfh?DSt?-8vr#P98j!~p^ zw-EHMm9TL$G z;jWH6SzqV9c~-q`GRMH;=+)lWF3|~F3SGE5MV|8np>oM;c~p|0VR;A%-|s4kpZiiJQJ9A+2DT5X4+xU$1{$A^j>a=+U0LGnm3lsX>8pB={c!*ORSdBQIN0Rg3pUjZirzKuAa>qBs4x^T9_f%fDN<)IZJAOoIVn0p1h>R9%$ zm}HmIw~vAVD#A-KKkc8|+h43sZ2KZ4eJKPZ9>#ZiKYm@;kT4bxZoV9=mX#DDnoYbu zZJ}gg(X_WP{BmRGJz9bxn>d)`OpDX4n3iB9RQx3K%nY0;Pg9_>?XIkbpU4k4Ueq9; zd$?5qSkY68ktaOPe_#T=g;LCjiQEa%q{^ZiVu_u$nGHAow844ZqBI@gTvHBYUo8@u1I7UK@_v%&O0l%9^nL4tb zmUda}jK_oi$z^NDH&TO9aBtCa@jG(8Bi3mC$&y=Q;3p`ls1jro@4)3g6lQqdOLj{a z)V2#%a_2$O8o*l~aAJX3&b~(-&WDrw8rbM3{yrnu28?`@6%WdIu5Yyt|4Ot!zuW(va(>L_Roq6 zGSDAU4DQ(ijTO~<+_VP6Q!6ba&*9+M4abpMl7&LZ#1RUtNkqYkPG+&gv~z*vIOZXM zDI1#hpE4A0&a;h!xZ)U9Q^4#3G{QUoU%$R_Ecnzq({_9FrXgVUk9~U!CZFtoCqQrm zbh-LtRphy~`iHw-Vk@=cm{Jc4R6>E!fO_7c6fVyLt|CEUKy(4rlErWz2T#E{H%KNg z+t-JCEkiITKoUdG2weMx1_lX~KjsU<(C9Z=gsvU{+shwp%-ebRbd2$&tl!+UE5?)_ z>O`Awkk)P@QZ1@)Uao;#e^$quLYAH4r$LAX>aFABkt8-BE{I&F6c~f=vPoutwLj6K zsiifZH4((1(-K-?x}2w!^?7Gm7>qC!eppPmB4en&bW-q=zppn&jlgeEUCC<=0>-V! z@AfOtG!@<+7WR)`m8ubYH!*KNMKZ`_7_f zabjn7DEovfnjlZx=)TcyMs81G(G7Y&kqVJv|B`pA7E|8|WHRJWT@5C>&ofdbL9+&y_FeMZxA_ z^Q|ZS_0~XQRPH0X(MU#DrQrmZUOKSKMctxe?u|0`?Rw9HK;K5`zT0%+NA9WOcUhns z07|8a`!B8}w;LSlE2z+Hw0(4-Oem{7ZKRgYKQ6 zWK?=~Ptd)ATVeQ^h%W&Fa1rv=-{W1H<%b3bX+TEu=@B^${sq#D?zukYOZTG|*sB|T z6QB*~4xvN_9WxzseIe)88b4QOrqoJQXuG&>n^DK6Ra>_|X3d0`Ne#}`5howFv@rlwd&p{DEsnY*e9GRVFrTiC>ai=e!Ee{ZhKWX z?X4+&esh+)^->%Fn{mbSF+w91P|_OzaPzwzfH>&0*l3_XO=ns)b5f z9JPpG;Lcc14~QzrV2NqzgrJcGzrcI=cMa$^p#Z}WbemnjbVx={M^zg)5|tz zAT>YTvv9b$Zcar(w{d!JAq|s$Q@D1CVMn(uht=(Pp z-P<*ajetl>Ns5$oNh6X1($d`}DBYmasnQ`xgGfksN=Qg|Nq2Xj>-Lvtyx;i7`QyBf zXAF_&j=k4j>&kh}8I?4A-jecIa5)l6eymqj=^|pHP@Ve))b;ioQML?C>7Ezhu>9d- zla7*cx+k0b!U#Csf~|P2c_n$ClX`yPsb2}7N)T8I;zK~7dZx=kr3N$_?qRmGR3rU7B$CT2Fpj~_p_ z#TMa}Lru>7Ac!O|?8bFKxW9PIk5(g-D76u%rlvNdosVASumQI4&1M3VtZqyN;8NP~z^7E|H+D2B@zF;WL%DH9Cizb< zFC9UQ)Ufq8|A3=o|2S32k(Bz;36SbgFm4jewS@LPk=^3o9NAF>4!GE~v^2XfI>77N zZ{h^A9FHbzPMu{hm-;FXpQz;Oo!l2(i6n6Gc>n%A0b=x_?u&G+

    xZpDZ1gml`i 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 diff --git a/test/functional/screenshots/baseline/dashboard_embed_mode_with_url_params.png b/test/functional/screenshots/baseline/dashboard_embed_mode_with_url_params.png index cbf96cdbf278b4221d88b02bab0d78e9731d69f7..26a18ede2d686fefdf1fa2382819591e4c79558b 100644 GIT binary patch literal 140548 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�uttfpQ6%U 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 B{wn|g From db0996f4a3f3a882347384e9f24de7e560f4d0eb Mon Sep 17 00:00:00 2001 From: Marshall Main <55718608+marshallmain@users.noreply.github.com> Date: Wed, 9 Aug 2023 07:26:08 -0700 Subject: [PATCH 06/41] [Security Solution] Move remaining timeline route schemas to /common/api (#162857) Closes https://github.com/elastic/security-team/issues/7099 Follow up to https://github.com/elastic/kibana/pull/162314 I mislabeled 3 timeline-related internal APIs as detection engine APIs on [this spreadsheet](https://docs.google.com/spreadsheets/d/1VCoJ74EkyGuj59VwWj_3v2ecB84pNCpzGqkYnS0SUKw/edit?pli=1#gid=1102015677) (create_tags, get_tags_by_name, get_dashboards_by_tags). The APIs are now correctly categorized on the spreadsheet and this PR establishes schemas for them in `/common/api`. I also converted these 3 small schemas to io-ts to make it easier to avoid pulling in `@kbn/config-schema` to `public`, as that increased the async chunk size by a full 840KB. --- .github/CODEOWNERS | 1 + .../api/tags/create_tag/create_tag_route.ts | 15 +++++++++++++++ .../get_dashboards_by_tags_route.ts | 10 ++++++++++ .../get_tags_by_name/get_tags_by_name_route.ts | 10 ++++++++++ .../security_solution/common/api/tags/index.ts | 10 ++++++++++ .../dashboards/routes/get_dashboards_by_tags.ts | 9 +++------ .../server/lib/tags/routes/create_tag.ts | 11 +++-------- .../server/lib/tags/routes/get_tags_by_name.ts | 9 +++------ 8 files changed, 55 insertions(+), 20 deletions(-) create mode 100644 x-pack/plugins/security_solution/common/api/tags/create_tag/create_tag_route.ts create mode 100644 x-pack/plugins/security_solution/common/api/tags/get_dashboards_by_tags/get_dashboards_by_tags_route.ts create mode 100644 x-pack/plugins/security_solution/common/api/tags/get_tags_by_name/get_tags_by_name_route.ts create mode 100644 x-pack/plugins/security_solution/common/api/tags/index.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index dfcda878c2e4e..06e0d2478429f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1098,6 +1098,7 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib /x-pack/plugins/security_solution/server/lib/timeline @elastic/security-threat-hunting-investigations ## Security Solution sub teams - Threat Hunting Explore +/x-pack/plugins/security_solution/common/api/tags @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/common/api/risk_score @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/common/search_strategy/security_solution/matrix_histogram @elastic/security-threat-hunting-explore diff --git a/x-pack/plugins/security_solution/common/api/tags/create_tag/create_tag_route.ts b/x-pack/plugins/security_solution/common/api/tags/create_tag/create_tag_route.ts new file mode 100644 index 0000000000000..160ae43b9aa0f --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/tags/create_tag/create_tag_route.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import * as rt from 'io-ts'; + +export const createTagRequest = rt.intersection([ + rt.type({ + name: rt.string, + description: rt.string, + }), + rt.partial({ color: rt.string }), +]); diff --git a/x-pack/plugins/security_solution/common/api/tags/get_dashboards_by_tags/get_dashboards_by_tags_route.ts b/x-pack/plugins/security_solution/common/api/tags/get_dashboards_by_tags/get_dashboards_by_tags_route.ts new file mode 100644 index 0000000000000..af2c89a967311 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/tags/get_dashboards_by_tags/get_dashboards_by_tags_route.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +export const getDashboardsRequest = rt.type({ tagIds: rt.array(rt.string) }); diff --git a/x-pack/plugins/security_solution/common/api/tags/get_tags_by_name/get_tags_by_name_route.ts b/x-pack/plugins/security_solution/common/api/tags/get_tags_by_name/get_tags_by_name_route.ts new file mode 100644 index 0000000000000..4ae16c320c02e --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/tags/get_tags_by_name/get_tags_by_name_route.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as rt from 'io-ts'; + +export const getTagsByNameRequest = rt.type({ name: rt.string }); diff --git a/x-pack/plugins/security_solution/common/api/tags/index.ts b/x-pack/plugins/security_solution/common/api/tags/index.ts new file mode 100644 index 0000000000000..3f48011365f42 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/tags/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './create_tag/create_tag_route'; +export * from './get_dashboards_by_tags/get_dashboards_by_tags_route'; +export * from './get_tags_by_name/get_tags_by_name_route'; diff --git a/x-pack/plugins/security_solution/server/lib/dashboards/routes/get_dashboards_by_tags.ts b/x-pack/plugins/security_solution/server/lib/dashboards/routes/get_dashboards_by_tags.ts index 7e0f8bfdaa4ce..356e4c1996e24 100644 --- a/x-pack/plugins/security_solution/server/lib/dashboards/routes/get_dashboards_by_tags.ts +++ b/x-pack/plugins/security_solution/server/lib/dashboards/routes/get_dashboards_by_tags.ts @@ -6,7 +6,6 @@ */ import type { Logger } from '@kbn/core/server'; import { i18n } from '@kbn/i18n'; -import { schema } from '@kbn/config-schema'; import type { DashboardAttributes } from '@kbn/dashboard-plugin/common'; import { transformError } from '@kbn/securitysolution-es-utils'; @@ -15,10 +14,8 @@ import type { SetupPlugins } from '../../../plugin'; import type { SecuritySolutionPluginRouter } from '../../../types'; import { buildSiemResponse } from '../../detection_engine/routes/utils'; import { buildFrameworkRequest } from '../../timeline/utils/common'; - -const getDashboardsParamsSchema = schema.object({ - tagIds: schema.arrayOf(schema.string()), -}); +import { getDashboardsRequest } from '../../../../common/api/tags'; +import { buildRouteValidationWithExcess } from '../../../utils/build_validation/route_validation'; export const getDashboardsByTagsRoute = ( router: SecuritySolutionPluginRouter, @@ -28,7 +25,7 @@ export const getDashboardsByTagsRoute = ( router.post( { path: INTERNAL_DASHBOARDS_URL, - validate: { body: getDashboardsParamsSchema }, + validate: { body: buildRouteValidationWithExcess(getDashboardsRequest) }, options: { tags: ['access:securitySolution'], }, diff --git a/x-pack/plugins/security_solution/server/lib/tags/routes/create_tag.ts b/x-pack/plugins/security_solution/server/lib/tags/routes/create_tag.ts index 4eaed27813214..6ddc14d64d53f 100644 --- a/x-pack/plugins/security_solution/server/lib/tags/routes/create_tag.ts +++ b/x-pack/plugins/security_solution/server/lib/tags/routes/create_tag.ts @@ -6,22 +6,17 @@ */ import type { Logger } from '@kbn/core/server'; import { i18n } from '@kbn/i18n'; -import { schema } from '@kbn/config-schema'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { createTagRequest } from '../../../../common/api/tags'; import { INTERNAL_TAGS_URL } from '../../../../common/constants'; import type { SetupPlugins } from '../../../plugin'; import type { SecuritySolutionPluginRouter } from '../../../types'; +import { buildRouteValidationWithExcess } from '../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../detection_engine/routes/utils'; import { buildFrameworkRequest } from '../../timeline/utils/common'; import { createTag } from '../saved_objects'; -const createTagBodySchema = schema.object({ - name: schema.string(), - description: schema.string(), - color: schema.maybe(schema.string()), -}); - export const createTagRoute = ( router: SecuritySolutionPluginRouter, logger: Logger, @@ -30,7 +25,7 @@ export const createTagRoute = ( router.put( { path: INTERNAL_TAGS_URL, - validate: { body: createTagBodySchema }, + validate: { body: buildRouteValidationWithExcess(createTagRequest) }, options: { tags: ['access:securitySolution'], }, diff --git a/x-pack/plugins/security_solution/server/lib/tags/routes/get_tags_by_name.ts b/x-pack/plugins/security_solution/server/lib/tags/routes/get_tags_by_name.ts index 05d20d90e09b2..a88578365f037 100644 --- a/x-pack/plugins/security_solution/server/lib/tags/routes/get_tags_by_name.ts +++ b/x-pack/plugins/security_solution/server/lib/tags/routes/get_tags_by_name.ts @@ -6,20 +6,17 @@ */ import type { Logger } from '@kbn/core/server'; import { i18n } from '@kbn/i18n'; -import { schema } from '@kbn/config-schema'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { getTagsByNameRequest } from '../../../../common/api/tags'; import { INTERNAL_TAGS_URL } from '../../../../common/constants'; import type { SetupPlugins } from '../../../plugin'; import type { SecuritySolutionPluginRouter } from '../../../types'; +import { buildRouteValidationWithExcess } from '../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../detection_engine/routes/utils'; import { buildFrameworkRequest } from '../../timeline/utils/common'; import { findTagsByName } from '../saved_objects'; -const getTagsParamsSchema = schema.object({ - name: schema.string(), -}); - export const getTagsByNameRoute = ( router: SecuritySolutionPluginRouter, logger: Logger, @@ -28,7 +25,7 @@ export const getTagsByNameRoute = ( router.get( { path: INTERNAL_TAGS_URL, - validate: { query: getTagsParamsSchema }, + validate: { query: buildRouteValidationWithExcess(getTagsByNameRequest) }, options: { tags: ['access:securitySolution'], }, From f48d422a2e5114e899df5697a18de10918beb779 Mon Sep 17 00:00:00 2001 From: Wafaa Nasr Date: Wed, 9 Aug 2023 16:40:55 +0200 Subject: [PATCH 07/41] [Security Solution] [Flaky test] Fix double ftr test flakiness (#162990) ## Summary - Addresses https://github.com/elastic/kibana/issues/155122 ## Investigations *First attempt* > While investigating the three failing pipelines and examining the Artifacts, specifically target/test_failures/*.log, I discovered the root cause to be > Did not get an expected 200 "ok" when waiting for a list item (waitForListItem) yet. Retrying until we get a 200 "ok". body: {"message":"list_id: \"list_items.txt\" item of 1.0 does not exist","status_code":404}, status: 404 > > ![image](https://github.com/elastic/kibana/assets/12671903/ad3c4db9-e340-42c0-8a61-63e5387b9b83) > *Second attempt* > Upon incorporating additional logs to pinpoint the underlying issue, it was realized that the test will persist in its attempts until the preceding error is rectified, and it was determined that the list_items.txt file contains the correct item once located. > > The problem seemed to be associated with incomplete indexing of all indices signalsOpen.hits.hits when the test verifies against the anticipated value. > > To investigate the matter, two iterations were conducted, totaling 490 attempts. During these iterations, logs, and warnings were deliberately inserted to facilitate the tracing of the issue. > > https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2770#0189bb29-c258-4586-986a-2ac5e128eb52 > https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2768#0189baeb-8f09-488e-936f-69e72d089787 > > In this [Atifact](https://s3.amazonaws.com/buildkiteartifacts.com/e0f3970e-3a75-4621-919f-e6c773e2bb12/fedcad1e-0f36-4d55-bdc7-e1edbecf91fe/0189bb29-495f-4b7e-b34e-558ff6c02ce2/0189bb29-c258-4586-986a-2ac5e128eb52/target/test_failures/0189bb29-c258-4586-986a-2ac5e128eb52_d98d35afa0abd1ad03e28a68882291c4.log?response-content-type=text%2Fplain&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAQPCP3C7LXS7MSJGH%2F20230808%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230808T102039Z&X-Amz-Expires=600&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEOH%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJHMEUCIQDYG9De6RYDlVNcO0JGqO6Qc4dpzCQG1s%2BgaXTSimWc9QIgfkZgXlnVcScJCO56vz2VQx1buVTNEDEaVYhYmDgupEgq%2BgMIiv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FARAAGgwwMzIzNzk3MDUzMDMiDOz2Gl2kfcuTHVaWyirOA4iHfkFBI7KBoy%2F97CuLMAxGLNIR8h4FtLCsY664lMhgDGd%2FBVi82zu%2B2Y5DAGEboOmb7C1q%2FX6CyesjDKP7sknXdfT7q8B4jBRK4QcVw2AAvC9%2BqMeN37eCfRXWT%2FrQAEdaWzxkJxk4BtFcATds3LJmmAlbYOT2L7vItmGzGs%2FnkRYevX%2Fq6hwxWqmOKNNot9hZ9sMJ3TZvGsA3045459BfyfObwIlzb13Pj6V7%2FMyTb87RjQazFiK%2Bb7qOXB%2B7ItaVAcpG7diXzPAif%2F%2FEiJedTHtBVh4LsMIKQtiASbcTh4X90kYtVMUcH%2BSG0B41WjWYPok0C3tHfQnGhGBIbSnqvMGmWgwGlhHNF1G7nIDYyWs32PQ3M3WmTGQuLIwp2hPzk4wFtgH%2FDQPWevRFRT%2FhzYJf05hyBT9BMcST9eeKTqEqs52PhCHDlCgo7K5bGjT86OO16MzEKdA77HRro8GqIh6mgTMyQ5gKpH38ueUWvQZnLix4T5HYw0EyJgRLRfiVIpKcH0jRobaFwKSfSYc%2FZ2FPHsAK31weedhy6tafwU7elNYiAaMRv4AQhB%2FlrGWYd6IjOrdgSFowlkd1m5%2FrYTY3k7%2F8D0vsxgjUETDX9semBjqlAWkLq%2FLaRV5KokMNXfT3lCVNJzpYeN1%2FdnInE%2BQn3Ub86kRgMOfTN2OgDHkuYSKsQ95tFHH49NfRn6rTw8tI2Tjs3pToqp65gCYh9MzUKTd2EWsgqdNn6y%2BbHRGFJxd7cacrX9Ghr4XyNme5aAeWAVYNXSqJ1KIbtWmRcwwhThAJHxWk5%2FoBwScZRUSYGWmkhaxnZXDjXg6LBuH7uZOJjf%2FLuFVdtQ%3D%3D&X-Amz-SignedHeaders=host&X-Amz-Signature=8a44c3a5e3b88b632097dc344ecec1ba6d6cb8e80e10d9058e96883e43d925b5) > > ![image](https://github.com/elastic/kibana/assets/12671903/bc58d389-3586-4343-a9f9-9577331d4876) > > ## Solution By modifying the third parameter of the `await waitForSignalsToBePresent(supertest, log, 1, [id]);` function to a value of 3 instead of the initial 1, we signify the number of alerts we need to await before conducting assertions. This change is made to accommodate the assertion of three alerts being generated, accounting for the exclusion of a single 1.0 value. --- .../group7/exception_operators_data_types/double.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group7/exception_operators_data_types/double.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group7/exception_operators_data_types/double.ts index 05d821b5932fb..39a878a82f896 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group7/exception_operators_data_types/double.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group7/exception_operators_data_types/double.ts @@ -33,8 +33,7 @@ export default ({ getService }: FtrProviderContext) => { const log = getService('log'); const es = getService('es'); - // Failing: See https://github.com/elastic/kibana/issues/155122 - describe.skip('Rule exception operators for data type double', () => { + describe('Rule exception operators for data type double', () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/rule_exceptions/double'); await esArchiver.load('x-pack/test/functional/es_archives/rule_exceptions/double_as_string'); @@ -490,7 +489,6 @@ export default ({ getService }: FtrProviderContext) => { expect(hits).to.eql([]); }); }); - describe('working against string values in the data set', () => { it('will return 3 results if we have a list that includes 1 double', async () => { await importFile(supertest, log, 'double', ['1.0'], 'list_items.txt'); @@ -509,7 +507,7 @@ export default ({ getService }: FtrProviderContext) => { ], ]); await waitForRuleSuccess({ supertest, log, id }); - await waitForSignalsToBePresent(supertest, log, 1, [id]); + await waitForSignalsToBePresent(supertest, log, 3, [id]); const signalsOpen = await getSignalsById(supertest, log, id); const hits = signalsOpen.hits.hits.map((hit) => hit._source?.double).sort(); expect(hits).to.eql(['1.1', '1.2', '1.3']); From efbb04607a611a6a49f158eb86df9dc1e64d855e Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Wed, 9 Aug 2023 10:45:52 -0400 Subject: [PATCH 08/41] fix(slo): Handle error during SLO resources installation (#163440) --- .../plugins/observability/server/services/slo/slo_installer.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/observability/server/services/slo/slo_installer.ts b/x-pack/plugins/observability/server/services/slo/slo_installer.ts index b59612ca30253..d6e8b8295348f 100644 --- a/x-pack/plugins/observability/server/services/slo/slo_installer.ts +++ b/x-pack/plugins/observability/server/services/slo/slo_installer.ts @@ -37,7 +37,6 @@ export class DefaultSLOInstaller implements SLOInstaller { this.logger.error('Failed to install SLO common resources and summary transforms', { error, }); - throw error; } finally { this.isInstalling = false; clearTimeout(installTimeout); From 0c51ce6f05dd6a8a688516556970e49c071e282e Mon Sep 17 00:00:00 2001 From: Ying Mao Date: Wed, 9 Aug 2023 10:54:41 -0400 Subject: [PATCH 09/41] [Response Ops][Alerting] Adding `ignore_malformed` to `.alerts-*` index template settings (#163414) Resolves https://github.com/elastic/kibana/issues/161465 ## Summary Adds `ignore_malformed: true` to alerts index template settings. This ignores malformed content globally across all allowed mapping types. For existing alerts as data indices, the new setting is not applied directly to the existing concrete indices but will be applied whenever the alias rolls over and a new concrete index is created. ## Verify - Verify that after upgrading alerts indices created in an older version to this branch, alerts continue to be written and read as expected. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Vitalii Dmyterko --- .../server/alerts_service/alerts_service.test.ts | 2 ++ .../lib/create_or_update_index_template.test.ts | 1 + .../lib/create_or_update_index_template.ts | 1 + .../group4/alerts_as_data/install_resources.ts | 2 ++ .../rule_execution_logic/non_ecs_fields.ts | 11 +++++------ 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/alerting/server/alerts_service/alerts_service.test.ts b/x-pack/plugins/alerting/server/alerts_service/alerts_service.test.ts index e3942b26ee6fa..5c4acce28b108 100644 --- a/x-pack/plugins/alerting/server/alerts_service/alerts_service.test.ts +++ b/x-pack/plugins/alerting/server/alerts_service/alerts_service.test.ts @@ -114,6 +114,7 @@ const getIndexTemplatePutBody = (opts?: GetIndexTemplatePutBodyOpts) => { name: '.alerts-ilm-policy', rollover_alias: `.alerts-${context ? context : 'test'}.alerts-${namespace}`, }, + 'index.mapping.ignore_malformed': true, 'index.mapping.total_fields.limit': 2500, }, mappings: { @@ -640,6 +641,7 @@ describe('Alerts Service', () => { name: '.alerts-ilm-policy', rollover_alias: `.alerts-empty.alerts-default`, }, + 'index.mapping.ignore_malformed': true, 'index.mapping.total_fields.limit': 2500, }, mappings: { diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.test.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.test.ts index d4ce203a0d0e3..38c2207e5f410 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.test.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.test.ts @@ -42,6 +42,7 @@ const IndexTemplate = (namespace: string = 'default') => ({ name: 'test-ilm-policy', rollover_alias: `.alerts-test.alerts-${namespace}`, }, + 'index.mapping.ignore_malformed': true, 'index.mapping.total_fields.limit': 2500, }, }, diff --git a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.ts b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.ts index a17fad2d875ed..388fe6344a51f 100644 --- a/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.ts +++ b/x-pack/plugins/alerting/server/alerts_service/lib/create_or_update_index_template.ts @@ -54,6 +54,7 @@ export const getIndexTemplate = ({ rollover_alias: indexPatterns.alias, }, 'index.mapping.total_fields.limit': totalFieldsLimit, + 'index.mapping.ignore_malformed': true, }, mappings: { dynamic: false, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/install_resources.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/install_resources.ts index b6c86b49c7fba..e80a8f94d93b6 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/install_resources.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/install_resources.ts @@ -163,6 +163,7 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F rollover_alias: '.alerts-test.patternfiring.alerts-default', }, mapping: { + ignore_malformed: 'true', total_fields: { limit: '2500', }, @@ -196,6 +197,7 @@ export default function createAlertsAsDataInstallResourcesTest({ getService }: F }); expect(contextIndex[indexName].settings?.index?.mapping).to.eql({ + ignore_malformed: 'true', total_fields: { limit: '2500', }, diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/non_ecs_fields.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/non_ecs_fields.ts index 32ae758b20807..f315dfabb4d86 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/non_ecs_fields.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/non_ecs_fields.ts @@ -56,7 +56,6 @@ export default ({ getService }: FtrProviderContext) => { }; }; - // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/154277 describe('Non ECS fields in alert document source', () => { before(async () => { await esArchiver.load( @@ -259,6 +258,7 @@ export default ({ getService }: FtrProviderContext) => { // we don't validate it because geo_point is very complex type with many various representations: array, different object, string with few valid patterns // more on geo_point type https://www.elastic.co/guide/en/elasticsearch/reference/current/geo-point.html + // since .alerts-* indices allow _ignore_malformed option, alert will be indexed for this document it('should fail creating alert when ECS field mapping is geo_point', async () => { const document = { client: { @@ -269,12 +269,11 @@ export default ({ getService }: FtrProviderContext) => { }, }; - const { errors } = await indexAndCreatePreviewAlert(document); + const { errors, alertSource } = await indexAndCreatePreviewAlert(document); - expect(errors[0]).toContain('Bulk Indexing of signals failed'); - expect(errors[0]).toContain( - 'failed to parse field [client.geo.location] of type [geo_point]' - ); + expect(errors).toEqual([]); + + expect(alertSource).toHaveProperty('client.geo.location', 'test test'); }); it('should strip invalid boolean values and left valid ones', async () => { From 143355a7f4a8379a35ed29d7417dba82379b2127 Mon Sep 17 00:00:00 2001 From: Marta Bondyra <4283304+mbondyra@users.noreply.github.com> Date: Wed, 9 Aug 2023 17:05:58 +0200 Subject: [PATCH 10/41] [Lens] Add tooltip for partition and heatmap filtering (#162716) ## Summary The breaking tests have nothing to do with this PR. I ran the [test PR and it broke too.](https://github.com/elastic/kibana/pull/163229/files) ### Functionality changes #### XY Chart Adds tooltip action for x series if it exists. The copy is different for time and categorical series. https://github.com/elastic/kibana/assets/4283304/2a043e04-c5b1-480d-be10-ae618145fb65 Screenshot 2023-08-04 at 17 37 39 Screenshot 2023-08-04 at 17 37 57 When filtering by one time interval we create a time picker filter and not regular filter now. #### Partition Chart Adds tooltip actions filters. Doesn't add them if we only have metric dimensions. https://github.com/elastic/kibana/assets/4283304/c4d427c3-fb81-4f9d-b4be-dcb5ba872fdb #### Heat map Chart Adds tooltip actions filters https://github.com/elastic/kibana/assets/4283304/68795a02-8d40-47af-8366-d7c4f88c6ce3 ### Code changes #### Changes to `MultiValueClickContext` 1. I changed the interface to: ``` export interface MultiValueClickContext { {...} data: { data: Array<{ cells: Array<{ column: number; row: number; }>; table: Pick; relation?: BooleanRelation; }>; {...} }; } ``` The important changes are accepting the array of data (this way we can pass multiple tables for different dataviews, for example for different layers for xy chart and we don't have run separate handlers for separate layers). Also we don't pass a single column and array of values (that then we have to convert to multiple rows inside of the functions) but a `cells` array. This way we can pass values that belong to different rows and columns. I also added a `relation` param so user can control if they prefer to use `AND` or `OR` relation for combined filter. If none is used, the filters are separate. Fixes https://github.com/elastic/kibana/issues/150304 --------- Co-authored-by: Stratoula Kalafateli --- .../common/types/expression_renderers.ts | 12 +- .../components/heatmap_component.test.tsx | 66 ++++ .../public/components/heatmap_component.tsx | 123 +++++-- .../expression_renderers/heatmap_renderer.tsx | 5 + .../utils/get_split_dimension_utils.test.ts | 2 +- .../public/utils/get_split_dimension_utils.ts | 1 + .../partition_vis_component.test.tsx.snap | 54 +++ .../partition_vis_component.test.tsx | 66 +++- .../components/partition_vis_component.tsx | 52 ++- .../expression_partition_vis/public/types.ts | 11 +- .../public/utils/filter_helpers.ts | 41 ++- .../__snapshots__/xy_chart.test.tsx.snap | 50 +++ .../components/tooltip/tooltip_actions.tsx | 259 ++++++++++++++ .../public/components/xy_chart.test.tsx | 330 +++++++++++------- .../public/components/xy_chart.tsx | 151 ++------ .../expression_xy/tsconfig.json | 2 + ...ate_filters_from_multi_value_click.test.ts | 188 ++++++++-- .../create_filters_from_multi_value_click.ts | 107 +++--- .../actions/multi_value_click_action.ts | 37 +- src/plugins/data/public/plugin.ts | 2 +- .../public/lib/triggers/triggers.ts | 33 +- .../workspace_panel/workspace_panel.test.tsx | 4 +- .../workspace_panel/workspace_panel.tsx | 4 +- .../lens/public/embeddable/embeddable.tsx | 63 ++-- x-pack/plugins/lens/public/types.ts | 6 + x-pack/plugins/lens/public/utils.test.ts | 77 ++-- x-pack/plugins/lens/public/utils.ts | 42 ++- .../visualization_actions/lens_embeddable.tsx | 8 +- .../functional/apps/lens/group4/dashboard.ts | 7 +- 29 files changed, 1330 insertions(+), 473 deletions(-) create mode 100644 src/plugins/chart_expressions/expression_xy/public/components/tooltip/tooltip_actions.tsx diff --git a/src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts b/src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts index b59a8ee2c5166..dfeff855f867f 100644 --- a/src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts +++ b/src/plugins/chart_expressions/expression_heatmap/common/types/expression_renderers.ts @@ -10,7 +10,11 @@ import type { PaletteRegistry } from '@kbn/coloring'; import type { ChartsPluginSetup, ChartsPluginStart } from '@kbn/charts-plugin/public'; import type { DatatableUtilitiesService } from '@kbn/data-plugin/common'; import type { IFieldFormat, SerializedFieldFormat } from '@kbn/field-formats-plugin/common'; -import type { RangeSelectContext, ValueClickContext } from '@kbn/embeddable-plugin/public'; +import type { + RangeSelectContext, + ValueClickContext, + MultiValueClickContext, +} from '@kbn/embeddable-plugin/public'; import type { PersistedState } from '@kbn/visualizations-plugin/public'; import { IInterpreterRenderHandlers } from '@kbn/expressions-plugin/common'; import type { HeatmapExpressionProps } from './expression_functions'; @@ -25,6 +29,11 @@ export interface BrushEvent { data: RangeSelectContext['data']; } +export interface MultiFilterEvent { + name: 'multiFilter'; + data: MultiValueClickContext['data']; +} + export type FormatFactory = (mapping?: SerializedFieldFormat) => IFieldFormat; export type HeatmapRenderProps = HeatmapExpressionProps & { @@ -35,6 +44,7 @@ export type HeatmapRenderProps = HeatmapExpressionProps & { datatableUtilities: DatatableUtilitiesService; onClickValue: (data: FilterEvent['data']) => void; onSelectRange: (data: BrushEvent['data']) => void; + onClickMultiValue: (data: MultiFilterEvent['data']) => void; paletteService: PaletteRegistry; uiState: PersistedState; interactive: boolean; diff --git a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.test.tsx b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.test.tsx index 34b4df99c9af4..eef7fd3eb6aba 100644 --- a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.test.tsx +++ b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.test.tsx @@ -14,6 +14,8 @@ import { GeometryValue, XYChartSeriesIdentifier, Tooltip, + TooltipAction, + TooltipValue, } from '@elastic/charts'; import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import { EmptyPlaceholder } from '@kbn/charts-plugin/public'; @@ -121,6 +123,7 @@ describe('HeatmapComponent', function () { uiState, onClickValue: jest.fn(), onSelectRange: jest.fn(), + onClickMultiValue: jest.fn(), datatableUtilities: createDatatableUtilitiesMock(), paletteService: palettesRegistry, formatFactory: formatService.deserialize, @@ -444,4 +447,67 @@ describe('HeatmapComponent', function () { expect(settingsComponent.prop('ariaUseDefaultSummary')).toEqual(true); }); }); + + describe('tooltip', () => { + it('should not have actions if chart is not interactive', () => { + const component = shallowWithIntl(); + const tooltip = component.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions).toBeUndefined(); + }); + it('should have tooltip actions when the chart is fully configured and interactive', () => { + const component = shallowWithIntl(); + const tooltip = component.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions?.length).toBe(1); + expect(actions).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + onSelect: expect.any(Function), + disabled: expect.any(Function), + }), + ]) + ); + }); + + it('selecting correct actions calls a callback with correct filter data', () => { + const component = shallowWithIntl(); + const tooltip = component.find(Tooltip); + const actions = tooltip.prop('actions') as TooltipAction[]; + actions[0].onSelect!( + [ + { + label: 'Dest', + datum: { + x: 'a', + y: 'd', + value: 0, + originalIndex: 0, + }, + } as TooltipValue, + { + label: 'Test', + datum: { + x: 'a', + y: 'd', + value: 0, + originalIndex: 0, + }, + } as TooltipValue, + ], + [] + ); + expect(wrapperProps.onClickMultiValue).toHaveBeenCalledWith({ + data: [ + { + cells: [ + { column: 1, row: 0 }, + { column: 2, row: 0 }, + ], + table: wrapperProps.data, + }, + ], + }); + }); + }); }); diff --git a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx index 95856d1bae485..97e5979766089 100644 --- a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx +++ b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx @@ -18,12 +18,13 @@ import { ScaleType, Settings, TooltipType, - TooltipProps, ESFixedIntervalUnit, ESCalendarIntervalUnit, PartialTheme, SettingsProps, Tooltip, + SeriesIdentifier, + TooltipValue, } from '@elastic/charts'; import type { CustomPaletteState } from '@kbn/charts-plugin/public'; import { search } from '@kbn/data-plugin/public'; @@ -36,6 +37,7 @@ import { DEFAULT_LEGEND_SIZE, LegendSizeToPixels, } from '@kbn/visualizations-plugin/common/constants'; +import { i18n } from '@kbn/i18n'; import { DatatableColumn } from '@kbn/expressions-plugin/public'; import { IconChartHeatmap } from '@kbn/chart-icons'; import { getOverridesFor } from '@kbn/chart-expressions-common'; @@ -138,7 +140,7 @@ function computeColorRanges( export const HeatmapComponent: FC = memo( ({ - data, + data: table, args, timeZone, formatFactory, @@ -147,6 +149,7 @@ export const HeatmapComponent: FC = memo( datatableUtilities, onClickValue, onSelectRange, + onClickMultiValue, paletteService, uiState, interactive, @@ -204,8 +207,6 @@ export const HeatmapComponent: FC = memo( }, [renderComplete] ); - - const table = data; const valueAccessor = args.valueAccessor ? getAccessorByDimension(args.valueAccessor, table.columns) : undefined; @@ -221,10 +222,10 @@ export const HeatmapComponent: FC = memo( ? getAccessorByDimension(args.yAccessor, table.columns) : undefined; const splitChartRowAccessor = args.splitRowAccessor - ? getSplitDimensionAccessor(data.columns, args.splitRowAccessor, formatFactory) + ? getSplitDimensionAccessor(table.columns, args.splitRowAccessor, formatFactory) : undefined; const splitChartColumnAccessor = args.splitColumnAccessor - ? getSplitDimensionAccessor(data.columns, args.splitColumnAccessor, formatFactory) + ? getSplitDimensionAccessor(table.columns, args.splitColumnAccessor, formatFactory) : undefined; const xAxisColumnIndex = table.columns.findIndex((v) => v.id === xAccessor); @@ -260,6 +261,8 @@ export const HeatmapComponent: FC = memo( datatables: [formattedTable.table], }); + const hasTooltipActions = interactive; + const onElementClick = useCallback( (e: HeatmapElementEvent[]) => { const cell = e[0][0]; @@ -277,6 +280,7 @@ export const HeatmapComponent: FC = memo( }), column: xAxisColumnIndex, value: x, + table, }, ...(yAxisColumn ? [ @@ -290,6 +294,7 @@ export const HeatmapComponent: FC = memo( }), column: yAxisColumnIndex, value: y, + table, }, ] : []), @@ -317,15 +322,10 @@ export const HeatmapComponent: FC = memo( points.push(point); } } - const context: FilterEvent['data'] = { - data: points.map((point) => ({ - row: point.row, - column: point.column, - value: point.value, - table, - })), - }; - onClickValue(context); + + onClickValue({ + data: points, + }); }, [ args.splitColumnAccessor, @@ -472,10 +472,6 @@ export const HeatmapComponent: FC = memo( } } - const tooltip: TooltipProps = { - type: args.showTooltip ? TooltipType.Follow : TooltipType.None, - }; - const valueFormatter = (d: number) => { let value = d; @@ -598,6 +594,69 @@ export const HeatmapComponent: FC = memo( const xAxisTitle = args.gridConfig.xTitle ?? xAxisColumn?.name; const yAxisTitle = args.gridConfig.yTitle ?? yAxisColumn?.name; + const filterSelectedTooltipValues = ( + tooltipSelectedValues: Array< + TooltipValue, SeriesIdentifier> + > + ) => { + const { datum } = tooltipSelectedValues[0]; + if (!datum) { + return; + } + const { x, y } = datum; + + const shouldFilterByX = tooltipSelectedValues.some( + ({ label }) => label === xAxisColumn?.name + ); + + const shouldFilterByY = tooltipSelectedValues.some( + ({ label }) => label === yAxisColumn?.name + ); + + const cells = [ + ...(xAxisColumn && shouldFilterByX + ? [ + { + column: xAxisColumnIndex, + row: table.rows.findIndex((r) => { + if (!xAxisColumn) return false; + if (formattedTable.formattedColumns[xAxisColumn.id]) { + // stringify the value to compare with the chart value + return xValuesFormatter.convert(r[xAxisColumn.id]) === x; + } + return r[xAxisColumn.id] === x; + }), + }, + ] + : []), + ...(yAxisColumn && shouldFilterByY + ? [ + { + column: yAxisColumnIndex, + row: table.rows.findIndex((r) => { + if (formattedTable.formattedColumns[yAxisColumn.id]) { + // stringify the value to compare with the chart value + return yValuesFormatter.convert(r[yAxisColumn.id]) === y; + } + return r[yAxisColumn.id] === y; + }), + }, + ] + : []), + ]; + + if (cells.length) { + onClickMultiValue({ + data: [ + { + table, + cells, + }, + ], + }); + } + }; + return ( <> {showLegend !== undefined && ( @@ -619,7 +678,31 @@ export const HeatmapComponent: FC = memo( splitColumnAccessor={splitChartColumnAccessor} splitRowAccessor={splitChartRowAccessor} /> - + , SeriesIdentifier> + actions={ + hasTooltipActions + ? [ + { + disabled: (selected) => selected.length < 1, + label: (selected) => + selected.length === 0 + ? i18n.translate( + 'expressionHeatmap.tooltipActions.emptyFilterSelection', + { + defaultMessage: 'Select at least one series to filter', + } + ) + : i18n.translate('expressionHeatmap.tooltipActions.filterValues', { + defaultMessage: 'Filter {seriesNumber} series', + values: { seriesNumber: selected.length }, + }), + onSelect: filterSelectedTooltipValues, + }, + ] + : undefined + } + type={args.showTooltip ? TooltipType.Follow : TooltipType.None} + /> { handlers.event({ name: 'brush', data }); }; + const onClickMultiValue = (data: MultiFilterEvent['data']) => { + handlers.event({ name: 'multiFilter', data }); + }; const renderComplete = () => { const executionContext = handlers.getExecutionContext(); @@ -97,6 +101,7 @@ export const heatmapRenderer: ( chartsActiveCursorService={plugins.charts.activeCursor} syncTooltips={config.syncTooltips} syncCursor={config.syncCursor} + onClickMultiValue={onClickMultiValue} /> diff --git a/src/plugins/chart_expressions/expression_heatmap/public/utils/get_split_dimension_utils.test.ts b/src/plugins/chart_expressions/expression_heatmap/public/utils/get_split_dimension_utils.test.ts index 6b510b28c8060..6a4912f0af501 100644 --- a/src/plugins/chart_expressions/expression_heatmap/public/utils/get_split_dimension_utils.test.ts +++ b/src/plugins/chart_expressions/expression_heatmap/public/utils/get_split_dimension_utils.test.ts @@ -136,7 +136,7 @@ describe('createSplitPoint', () => { const point = createSplitPoint(splitDimension, 'c', defaultFormatter, data); expect(defaultFormatter).toHaveBeenCalledTimes(1); - expect(point).toStrictEqual({ column: 2, row: 1, value: 'c' }); + expect(point).toStrictEqual({ column: 2, row: 1, value: 'c', table: data }); }); it('returns undefined if value is not found in the table', () => { diff --git a/src/plugins/chart_expressions/expression_heatmap/public/utils/get_split_dimension_utils.ts b/src/plugins/chart_expressions/expression_heatmap/public/utils/get_split_dimension_utils.ts index e59d6c1aec28b..ec4c69ad233c3 100644 --- a/src/plugins/chart_expressions/expression_heatmap/public/utils/get_split_dimension_utils.ts +++ b/src/plugins/chart_expressions/expression_heatmap/public/utils/get_split_dimension_utils.ts @@ -51,6 +51,7 @@ export function createSplitPoint( row: splitPointRowIndex, column: table.columns.findIndex((column) => column.id === accessor), value: table.rows[splitPointRowIndex][accessor], + table, }; } } diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap b/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap index 65fa256304fde..0b8a82459fd97 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_partition_vis/public/components/__snapshots__/partition_vis_component.test.tsx.snap @@ -223,6 +223,15 @@ exports[`PartitionVisComponent should render correct structure for donut 1`] = ` > { + it('should not have actions if chart is not interactive', () => { + const component = shallow(); + const tooltip = component.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions).toBeUndefined(); + }); + it('should not have actions if chart has only metrics', () => { + const noBucketParams = { + ...wrapperProps, + visParams: { + ...wrapperProps.visParams, + dimensions: { ...wrapperProps.visParams.dimensions, buckets: [] }, + }, + }; + + const component = shallow(); + const tooltip = component.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions).toBeUndefined(); + }); + it('should have tooltip actions when the chart is fully configured and interactive', () => { + const component = shallow(); + const tooltip = component.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions?.length).toBe(1); + expect(actions).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + onSelect: expect.any(Function), + disabled: expect.any(Function), + }), + ]) + ); + }); + it('selecting correct actions calls a callback with correct filter data', () => { + const component = shallow(); + const tooltip = component.find(Tooltip); + const actions = tooltip.prop('actions') as TooltipAction[]; + actions[0].onSelect!( + [ + { + label: 'JetBeats', + color: '#79aad9', + isHighlighted: false, + isVisible: true, + seriesIdentifier: { + specId: 'donut', + key: 'JetBeats', + }, + value: 655, + formattedValue: '655', + valueAccessor: 1, + }, + ], + [] + ); + expect(wrapperProps.fireEvent).toHaveBeenCalledWith({ + name: 'multiFilter', + data: { data: [{ cells: [{ column: 0, row: 2 }], table: wrapperProps.visData }] }, + }); + }); + }); }); diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx index c151741158ac1..de1c977cbdadf 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx +++ b/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx @@ -20,7 +20,9 @@ import { PartitionElementEvent, SettingsProps, Tooltip, + TooltipValue, } from '@elastic/charts'; +import { i18n } from '@kbn/i18n'; import { useEuiTheme } from '@elastic/eui'; import type { PaletteRegistry } from '@kbn/coloring'; import { LegendToggle, ChartsPluginSetup } from '@kbn/charts-plugin/public'; @@ -72,6 +74,7 @@ import { } from './partition_vis_component.styles'; import { filterOutConfig } from '../utils/filter_out_config'; import { ColumnCellValueActions, FilterEvent, StartDeps } from '../types'; +import { getMultiFilterCells } from '../utils/filter_helpers'; declare global { interface Window { @@ -205,6 +208,7 @@ const PartitionVisComponent = (props: PartitionVisComponentProps) => { splitChartDimension, splitChartFormatter ); + props.fireEvent({ name: 'filter', data: { data } }); }, [metricColumn.id, originalVisData, props, visParams.dimensions.metrics.length] @@ -385,10 +389,7 @@ const PartitionVisComponent = (props: PartitionVisComponentProps) => { ); const fixedViewPort = document.getElementById('app-fixed-viewport'); - const tooltip: TooltipProps = { - ...(fixedViewPort ? { boundary: fixedViewPort } : {}), - type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, - }; + const legendPosition = visParams.legendPosition ?? Position.Right; const splitChartColumnAccessor = splitColumn @@ -405,6 +406,49 @@ const PartitionVisComponent = (props: PartitionVisComponentProps) => { ? getColumnByAccessor(splitRow[0], visData.columns) : undefined; + const hasTooltipActions = + interactive && bucketAccessors.filter((a) => a !== 'metric-name').length > 0; + + const tooltip: TooltipProps = { + ...(fixedViewPort ? { boundary: fixedViewPort } : {}), + type: visParams.addTooltip ? TooltipType.Follow : TooltipType.None, + actions: hasTooltipActions + ? [ + { + disabled: (selected) => selected.length < 1, + label: (selected) => + selected.length === 0 + ? i18n.translate('expressionPartitionVis.tooltipActions.emptyFilterSelection', { + defaultMessage: 'Select at least one series to filter', + }) + : i18n.translate('expressionPartitionVis.tooltipActions.filterValues', { + defaultMessage: 'Filter {seriesNumber} series', + values: { seriesNumber: selected.length }, + }), + onSelect: ( + tooltipSelectedValues: Array< + TooltipValue, SeriesIdentifier> + > + ) => { + const cells = getMultiFilterCells(tooltipSelectedValues, bucketColumns, visData); + + props.fireEvent({ + name: 'multiFilter', + data: { + data: [ + { + table: visData, + cells, + }, + ], + }, + }); + }, + }, + ] + : undefined, + }; + /** * Checks whether data have all zero values. * If so, the no data container is loaded. diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/types.ts b/src/plugins/chart_expressions/expression_partition_vis/public/types.ts index 77636d3a41832..0beca2e79de8d 100755 --- a/src/plugins/chart_expressions/expression_partition_vis/public/types.ts +++ b/src/plugins/chart_expressions/expression_partition_vis/public/types.ts @@ -5,7 +5,11 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { CellValueContext, ValueClickContext } from '@kbn/embeddable-plugin/public'; +import type { + CellValueContext, + ValueClickContext, + MultiValueClickContext, +} from '@kbn/embeddable-plugin/public'; import { ChartsPluginSetup, ChartsPluginStart } from '@kbn/charts-plugin/public'; import { Plugin as ExpressionsPublicPlugin, @@ -36,6 +40,11 @@ export interface FilterEvent { data: ValueClickContext['data']; } +export interface MultiFilterEvent { + name: 'multiFilter'; + data: MultiValueClickContext['data']; +} + export interface CellValueAction { id: string; iconType: string; diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/utils/filter_helpers.ts b/src/plugins/chart_expressions/expression_partition_vis/public/utils/filter_helpers.ts index c7b793d87149f..b34a4f74147d8 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/utils/filter_helpers.ts +++ b/src/plugins/chart_expressions/expression_partition_vis/public/utils/filter_helpers.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { LayerValue, SeriesIdentifier } from '@elastic/charts'; +import { LayerValue, SeriesIdentifier, TooltipValue } from '@elastic/charts'; import { Datatable, DatatableColumn } from '@kbn/expressions-plugin/public'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { ValueClickContext } from '@kbn/embeddable-plugin/public'; @@ -26,6 +26,45 @@ export const canFilter = async ( return Boolean(filters.length); }; +export const getMultiFilterCells = ( + tooltipSelectedValues: Array, SeriesIdentifier>>, + bucketColumns: Array>, + visData: Datatable +) => { + const row = visData.rows.findIndex((r) => + tooltipSelectedValues.every(({ valueAccessor, seriesIdentifier }) => { + if (typeof valueAccessor !== 'number' || valueAccessor < 1) return; + const index = valueAccessor - 1; + const bucketColumnId = bucketColumns[index].id; + if (!bucketColumnId) return; + return r[bucketColumnId] === seriesIdentifier.key; + }) + ); + + return tooltipSelectedValues + .map(({ valueAccessor }) => { + if (typeof valueAccessor !== 'number' || valueAccessor < 1) return; + const index = valueAccessor - 1; + const bucketColumnId = bucketColumns[index].id; + if (!bucketColumnId) return; + const column = visData.columns.findIndex((c) => c.id === bucketColumnId); + + if (column === -1) { + return; + } + + return { + column, + row, + }; + }) + .filter(nonNullable); +}; + +function nonNullable(v: T): v is NonNullable { + return v != null; +} + export const getFilterClickData = ( clickedLayers: LayerValue[], bucketColumns: Array>, diff --git a/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap b/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap index fb8faf123fa66..fe76259b65889 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap +++ b/src/plugins/chart_expressions/expression_xy/public/components/__snapshots__/xy_chart.test.tsx.snap @@ -565,6 +565,11 @@ exports[`XYChart component it renders area 1`] = ` "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} @@ -1568,6 +1573,11 @@ exports[`XYChart component it renders bar 1`] = ` "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} @@ -2571,6 +2581,11 @@ exports[`XYChart component it renders horizontal bar 1`] = ` "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} @@ -3574,6 +3589,11 @@ exports[`XYChart component it renders line 1`] = ` "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} @@ -4577,6 +4597,11 @@ exports[`XYChart component it renders stacked area 1`] = ` "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} @@ -5580,6 +5605,11 @@ exports[`XYChart component it renders stacked bar 1`] = ` "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} @@ -6583,6 +6613,11 @@ exports[`XYChart component it renders stacked horizontal bar 1`] = ` "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} @@ -7616,6 +7651,11 @@ exports[`XYChart component split chart should render split chart if both, splitR "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} @@ -8857,6 +8897,11 @@ exports[`XYChart component split chart should render split chart if splitColumnA "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} @@ -10091,6 +10136,11 @@ exports[`XYChart component split chart should render split chart if splitRowAcce "label": [Function], "onSelect": [Function], }, + Object { + "disabled": [Function], + "label": [Function], + "onSelect": [Function], + }, ] } headerFormatter={[Function]} diff --git a/src/plugins/chart_expressions/expression_xy/public/components/tooltip/tooltip_actions.tsx b/src/plugins/chart_expressions/expression_xy/public/components/tooltip/tooltip_actions.tsx new file mode 100644 index 0000000000000..04cec59fd0b1d --- /dev/null +++ b/src/plugins/chart_expressions/expression_xy/public/components/tooltip/tooltip_actions.tsx @@ -0,0 +1,259 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Datum, TooltipAction, TooltipValue, XYChartSeriesIdentifier } from '@elastic/charts'; +import { + getAccessorByDimension, + getColumnByAccessor, +} from '@kbn/visualizations-plugin/common/utils'; +import { FormatFactory } from '@kbn/visualization-ui-components'; +import { FieldFormat } from '@kbn/field-formats-plugin/common'; +import { i18n } from '@kbn/i18n'; +import { MultiClickTriggerEvent } from '@kbn/charts-plugin/public'; +import { Datatable } from '@kbn/expressions-plugin/common'; +import { BooleanRelation } from '@kbn/es-query'; +import { isTimeChart } from '../../../common/helpers'; +import { CommonXYDataLayerConfig } from '../../../common'; +import { DatatablesWithFormatInfo, LayersFieldFormats } from '../../helpers'; +import { MultiFilterEvent } from '../../types'; + +type XYTooltipValue = TooltipValue, XYChartSeriesIdentifier>; + +function nonNullable(v: T): v is NonNullable { + return v != null; +} + +export function createSplitPoint( + accessor: string | number, + value: string | number | undefined, + rows: Datatable['rows'], + table: Datatable +) { + if (value === undefined) return; + const splitPointRowIndex = rows.findIndex((row) => { + if (Array.isArray(value)) { + return value.includes(row[accessor]); + } + return row[accessor] === value; + }); + if (splitPointRowIndex !== -1) { + return { + row: splitPointRowIndex, + column: table.columns.findIndex((column) => column.id === accessor), + value: table.rows[splitPointRowIndex][accessor], + table, + }; + } +} + +export const getXSeriesPoint = ( + layer: CommonXYDataLayerConfig, + value: any, + fieldFormats: LayersFieldFormats, + formattedDatatables: DatatablesWithFormatInfo, + xAxisFormatter: FieldFormat, + formatFactory: FormatFactory +) => { + const { table } = layer; + const xColumn = layer.xAccessor && getColumnByAccessor(layer.xAccessor, table.columns); + const xAccessor = layer.xAccessor + ? getAccessorByDimension(layer.xAccessor, table.columns) + : undefined; + + const xFormat = xColumn ? fieldFormats[layer.layerId].xAccessors[xColumn.id] : undefined; + const currentXFormatter = + xAccessor && formattedDatatables[layer.layerId]?.formattedColumns[xAccessor] && xColumn + ? formatFactory(xFormat) + : xAxisFormatter; + + const rowIndex = table.rows.findIndex((row) => { + if (xAccessor) { + if (formattedDatatables[layer.layerId]?.formattedColumns[xAccessor]) { + // stringify the value to compare with the chart value + return currentXFormatter.convert(row[xAccessor]) === value; + } + return row[xAccessor] === value; + } + }); + + return { + row: rowIndex, + column: table.columns.findIndex((col) => col.id === xAccessor), + table, + value: xAccessor ? table.rows[rowIndex][xAccessor] : value, + }; +}; + +function getXSeriesValue(dataLayers: CommonXYDataLayerConfig[], firstSeries: XYTooltipValue) { + const layer = dataLayers.find((l) => + firstSeries.seriesIdentifier.seriesKeys.some((key: string | number) => + l.accessors.some( + (accessor) => getAccessorByDimension(accessor, l.table.columns) === key.toString() + ) + ) + ); + if (!layer) return; + + const { table } = layer; + + const xAccessor = layer.xAccessor + ? getAccessorByDimension(layer.xAccessor, table.columns) + : undefined; + + return xAccessor ? firstSeries.datum?.[xAccessor] : null; +} + +export const getTooltipActions = ( + dataLayers: CommonXYDataLayerConfig[], + onClickMultiValue: (data: MultiFilterEvent['data']) => void, + fieldFormats: LayersFieldFormats, + formattedDatatables: DatatablesWithFormatInfo, + xAxisFormatter: FieldFormat, + formatFactory: FormatFactory, + isEnabled?: boolean +) => { + if (!isEnabled) return; + const hasSplitAccessors = dataLayers.some((l) => l.splitAccessors?.length); + const hasXAxis = dataLayers.every((l) => l.xAccessor); + const isTimeViz = isTimeChart(dataLayers); + + if (!hasSplitAccessors && !hasXAxis) return; + + const xSeriesActions: Array> = hasXAxis + ? [ + { + disabled: () => !hasXAxis, + label: (_, [firstSeries]: XYTooltipValue[]) => { + if (isTimeViz) { + return i18n.translate('expressionXY.tooltipActions.filterByTime', { + defaultMessage: 'Filter by time', + }); + } + + const value = getXSeriesValue(dataLayers, firstSeries); + + return i18n.translate('expressionXY.tooltipActions.filterForXSeries', { + defaultMessage: 'Filter for {value}', + values: { + value: xAxisFormatter.convert(value) || value, + }, + }); + }, + + onSelect: (_: XYTooltipValue[], [firstSeries]: XYTooltipValue[]) => { + const layer = dataLayers.find((l) => + firstSeries.seriesIdentifier.seriesKeys.some((key: string | number) => + l.accessors.some( + (accessor) => getAccessorByDimension(accessor, l.table.columns) === key.toString() + ) + ) + ); + if (!layer) return; + + const value = getXSeriesValue(dataLayers, firstSeries); + + const xSeriesPoint = getXSeriesPoint( + layer, + value, + fieldFormats, + formattedDatatables, + xAxisFormatter, + formatFactory + ); + + const context: MultiFilterEvent['data'] = { + data: [ + { + table: xSeriesPoint.table, + cells: [ + { + row: xSeriesPoint.row, + column: xSeriesPoint.column, + }, + ], + }, + ], + }; + onClickMultiValue(context); + }, + }, + ] + : []; + + const breakdownTooltipActions: Array> = + hasSplitAccessors + ? [ + { + disabled: (selected) => selected.length < 1, + label: (selected) => + selected.length === 0 + ? i18n.translate('expressionXY.tooltipActions.emptyFilterSelection', { + defaultMessage: 'Select at least one series to filter', + }) + : i18n.translate('expressionXY.tooltipActions.filterValues', { + defaultMessage: 'Filter {seriesNumber} selected series', + values: { seriesNumber: selected.length }, + }), + onSelect: (tooltipSelectedValues: XYTooltipValue[]) => { + const layerIndexes: number[] = []; + tooltipSelectedValues.forEach((v) => { + const index = dataLayers.findIndex((l) => + v.seriesIdentifier.seriesKeys.some((key: string | number) => + l.accessors.some( + (accessor) => + getAccessorByDimension(accessor, l.table.columns) === key.toString() + ) + ) + ); + if (!layerIndexes.includes(index) && index !== -1) { + layerIndexes.push(index); + } + }); + + const filterPoints: MultiClickTriggerEvent['data']['data'] = []; + + if (!layerIndexes.length) return; + layerIndexes.forEach((layerIndex) => { + const layer = dataLayers[layerIndex]; + const { table } = layer; + + if (layer.splitAccessors?.length !== 1) return; + + const splitAccessor = getAccessorByDimension( + layer.splitAccessors[0], + table.columns + ); + const splitPoints = tooltipSelectedValues + .map((v) => + createSplitPoint( + splitAccessor, + v.datum?.[splitAccessor], + formattedDatatables[layer.layerId].table.rows, + table + ) + ) + .filter(nonNullable); + if (splitPoints.length) { + filterPoints.push({ + cells: splitPoints.map(({ row, column }) => ({ row, column })), + relation: BooleanRelation.OR, + table, + }); + } + }); + if (filterPoints?.length) { + onClickMultiValue({ + data: filterPoints, + }); + } + }, + }, + ] + : []; + return [...xSeriesActions, ...breakdownTooltipActions]; +}; diff --git a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.test.tsx b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.test.tsx index a43e4f1c05410..4a9e63c5ad7b3 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.test.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.test.tsx @@ -107,6 +107,7 @@ describe('XYChart component', () => { convertSpy = jest.fn((x) => x); getFormatSpy = jest.fn(); getFormatSpy.mockReturnValue({ convert: convertSpy }); + jest.clearAllMocks(); defaultProps = { data: dataPluginMock.createStartContract(), @@ -1140,126 +1141,6 @@ describe('XYChart component', () => { expect(headerFormatter).toBeUndefined(); }); - test('should not have tooltip actions for the detailed tooltip', () => { - const { args, data } = sampleArgs(); - - const wrapper = mountWithIntl( - - ); - - const tooltip = wrapper.find(Tooltip); - const actions = tooltip.prop('actions'); - expect(actions).toBeUndefined(); - }); - - test('should not have tooltip actions for no split accessor', () => { - const { args, data } = sampleArgs(); - - const wrapper = mountWithIntl( - - ); - - const tooltip = wrapper.find(Tooltip); - const actions = tooltip.prop('actions'); - expect(actions).toBeUndefined(); - }); - - test('should have tooltip actions for split accessor and default tooltip', () => { - const { args, data } = sampleArgs(); - - const wrapper = mountWithIntl( - - ); - - const tooltip = wrapper.find(Tooltip); - const actions = tooltip.prop('actions'); - expect(actions?.length).toBe(1); - expect(actions).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - onSelect: expect.any(Function), - disabled: expect.any(Function), - }), - ]) - ); - }); - test('onElementClick returns correct context data', () => { const geometry: GeometryValue = { x: 5, y: 1, accessor: 'y1', mark: null, datum: {} }; const series = { @@ -3548,4 +3429,213 @@ describe('XYChart component', () => { } }); }); + + describe('tooltip actions', () => { + test('should not have tooltip actions for the detailed tooltip', () => { + const { args, data } = sampleArgs(); + + const wrapper = mountWithIntl( + + ); + + const tooltip = wrapper.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions).toBeUndefined(); + }); + test('should not have tooltip action when there is no split accessor nor x serie', () => { + const { args, data } = sampleArgs(); + + const wrapper = mountWithIntl( + + ); + + const tooltip = wrapper.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions).toBeUndefined(); + }); + test('should not have only x series tooltip action when there is no split accessor', () => { + const { args, data } = sampleArgs(); + + const wrapper = mountWithIntl( + + ); + + const tooltip = wrapper.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions?.length).toBe(1); + expect(actions).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + onSelect: expect.any(Function), + disabled: expect.any(Function), + }), + ]) + ); + }); + test('should have tooltip actions for split accessor and x series', () => { + const { args, data } = sampleArgs(); + + const wrapper = mountWithIntl( + + ); + + const tooltip = wrapper.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions?.length).toBe(2); + expect(actions).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + onSelect: expect.any(Function), + disabled: expect.any(Function), + }), + ]) + ); + }); + test('should have tooltip actions for split accessor', () => { + const { args, data } = sampleArgs(); + + const wrapper = mountWithIntl( + + ); + + const tooltip = wrapper.find(Tooltip); + const actions = tooltip.prop('actions'); + expect(actions?.length).toBe(1); + expect(actions).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + onSelect: expect.any(Function), + disabled: expect.any(Function), + }), + ]) + ); + }); + test('should call onClickMultiValue with a correct data for multiple series selected', () => {}); + test('should call onClickMultiValue with a correct data for time selected', () => {}); + }); }); diff --git a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx index e1ad4fa19d1c0..b8ac9d5cd0bbb 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx @@ -8,7 +8,6 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { css } from '@emotion/react'; -import { i18n } from '@kbn/i18n'; import { Chart, Settings, @@ -30,13 +29,12 @@ import { XYChartElementEvent, Tooltip, XYChartSeriesIdentifier, - TooltipValue, SettingsProps, } from '@elastic/charts'; import { partition } from 'lodash'; import { IconType } from '@elastic/eui'; import { PaletteRegistry } from '@kbn/coloring'; -import { Datatable, RenderMode } from '@kbn/expressions-plugin/common'; +import { RenderMode } from '@kbn/expressions-plugin/common'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { EmptyPlaceholder, LegendToggle } from '@kbn/charts-plugin/public'; import { EventAnnotationServiceType } from '@kbn/event-annotation-plugin/public'; @@ -113,6 +111,7 @@ import { XYCurrentTime } from './xy_current_time'; import './xy_chart.scss'; import { TooltipHeader } from './tooltip'; import { LegendColorPickerWrapperContext, LegendColorPickerWrapper } from './legend_color_picker'; +import { createSplitPoint, getTooltipActions, getXSeriesPoint } from './tooltip/tooltip_actions'; declare global { interface Window { @@ -150,7 +149,6 @@ export type XYChartRenderProps = Omit & { function nonNullable(v: T): v is NonNullable { return v != null; } - function getValueLabelsStyling(isHorizontal: boolean): { displayValue: RecursivePartial; } { @@ -184,28 +182,6 @@ function getIconForSeriesType(layer: CommonXYDataLayerConfig): IconType { ); } -function createSplitPoint( - accessor: string | number, - value: string | number, - rows: Datatable['rows'], - table: Datatable -) { - const splitPointRowIndex = rows.findIndex((row) => { - if (Array.isArray(value)) { - return value.includes(row[accessor]); - } - return row[accessor] === value; - }); - if (splitPointRowIndex !== -1) { - return { - row: splitPointRowIndex, - column: table.columns.findIndex((column) => column.id === accessor), - value: table.rows[splitPointRowIndex][accessor], - table, - }; - } -} - export const XYChartReportable = React.memo(XYChart); export function XYChart({ @@ -560,59 +536,11 @@ export function XYChart({ valueLabels !== ValueLabelModes.HIDE && getValueLabelsStyling(shouldRotate); - const filterSelectedTooltipValues = ( - tooltipSelectedValues: Array< - TooltipValue, XYChartSeriesIdentifier> - > - ) => { - const layerIndexes: number[] = []; - tooltipSelectedValues.forEach((v) => { - const index = dataLayers.findIndex((l) => - v.seriesIdentifier.seriesKeys.some((key: string | number) => - l.accessors.some( - (accessor) => getAccessorByDimension(accessor, l.table.columns) === key.toString() - ) - ) - ); - if (!layerIndexes.includes(index) && index !== -1) { - layerIndexes.push(index); - } - }); - - if (!layerIndexes.length) return; - layerIndexes.forEach((layerIndex) => { - const layer = dataLayers[layerIndex]; - const { table } = layer; - - if (layer.splitAccessors?.length !== 1) return; - - const splitAccessor = getAccessorByDimension(layer.splitAccessors[0], table.columns); - const filterValues = tooltipSelectedValues - .map((v) => v.datum?.[splitAccessor]) - .filter(nonNullable); - - const splitPoints = filterValues - .map((v) => - createSplitPoint(splitAccessor, v, formattedDatatables[layer.layerId].table.rows, table) - ) - .filter(nonNullable); - if (splitPoints.length) { - onClickMultiValue({ - data: { - column: splitPoints[0].column, - value: splitPoints.map(({ value }) => value), - table, - }, - }); - } - }); - }; - const clickHandler: ElementClickListener = ([elementEvent]) => { // this cast is safe because we are rendering a cartesian chart const [xyGeometry, xySeries] = elementEvent as XYChartElementEvent; - const layerIndex = dataLayers.findIndex((l) => + const layer = dataLayers.find((l) => xySeries.seriesKeys.some((key: string | number) => l.accessors.some( (accessor) => getAccessorByDimension(accessor, l.table.columns) === key.toString() @@ -620,42 +548,19 @@ export function XYChart({ ) ); - if (layerIndex === -1) { + if (!layer) { return; } - - const layer = dataLayers[layerIndex]; const { table } = layer; - const xColumn = layer.xAccessor && getColumnByAccessor(layer.xAccessor, table.columns); - const xAccessor = layer.xAccessor - ? getAccessorByDimension(layer.xAccessor, table.columns) - : undefined; - - const xFormat = xColumn ? fieldFormats[layer.layerId].xAccessors[xColumn.id] : undefined; - const currentXFormatter = - xAccessor && formattedDatatables[layer.layerId]?.formattedColumns[xAccessor] && xColumn - ? formatFactory(xFormat) - : xAxisFormatter; - - const rowIndex = table.rows.findIndex((row) => { - if (xAccessor) { - if (formattedDatatables[layer.layerId]?.formattedColumns[xAccessor]) { - // stringify the value to compare with the chart value - return currentXFormatter.convert(row[xAccessor]) === xyGeometry.x; - } - return row[xAccessor] === xyGeometry.x; - } - }); - - const points = [ - { - row: rowIndex, - column: table.columns.findIndex((col) => col.id === xAccessor), - value: xAccessor ? table.rows[rowIndex][xAccessor] : xyGeometry.x, - table, - }, - ]; + const xSeriesPoint = getXSeriesPoint( + layer, + xyGeometry.x, + fieldFormats, + formattedDatatables, + xAxisFormatter, + formatFactory + ); const splitPoints: FilterEvent['data']['data'] = []; @@ -700,7 +605,7 @@ export function XYChart({ } const context: FilterEvent['data'] = { - data: [...points, ...splitPoints], + data: [xSeriesPoint, ...splitPoints], }; onClickValue(context); }; @@ -796,8 +701,6 @@ export function XYChart({ overflowX: 'hidden', position: uiState ? 'absolute' : 'relative', }); - // enable the tooltip actions only if there is at least one splitAccessor to the dataLayer - const hasTooltipActions = dataLayers.some((dataLayer) => dataLayer.splitAccessors) && interactive; const { theme: settingsThemeOverrides = {}, ...settingsOverrides } = getOverridesFor( overrides, @@ -844,25 +747,15 @@ export function XYChart({ ) : undefined } - actions={ - !args.detailedTooltip && hasTooltipActions - ? [ - { - disabled: (selected) => selected.length < 1, - label: (selected) => - selected.length === 0 - ? i18n.translate('expressionXY.tooltipActions.emptyFilterSelection', { - defaultMessage: 'Select at least one series to filter', - }) - : i18n.translate('expressionXY.tooltipActions.filterValues', { - defaultMessage: 'Filter {seriesNumber} series', - values: { seriesNumber: selected.length }, - }), - onSelect: filterSelectedTooltipValues, - }, - ] - : undefined - } + actions={getTooltipActions( + dataLayers, + onClickMultiValue, + fieldFormats, + formattedDatatables, + xAxisFormatter, + formatFactory, + interactive && !args.detailedTooltip + )} customTooltip={ args.detailedTooltip ? ({ header, values }) => ( diff --git a/src/plugins/chart_expressions/expression_xy/tsconfig.json b/src/plugins/chart_expressions/expression_xy/tsconfig.json index 7f2af7005070d..901b7eb0568c6 100644 --- a/src/plugins/chart_expressions/expression_xy/tsconfig.json +++ b/src/plugins/chart_expressions/expression_xy/tsconfig.json @@ -32,6 +32,8 @@ "@kbn/kibana-react-plugin", "@kbn/chart-expressions-common", "@kbn/event-annotation-common", + "@kbn/visualization-ui-components", + "@kbn/es-query", ], "exclude": [ "target/**/*", diff --git a/src/plugins/data/public/actions/filters/create_filters_from_multi_value_click.test.ts b/src/plugins/data/public/actions/filters/create_filters_from_multi_value_click.test.ts index 804f898945e57..f138544065b82 100644 --- a/src/plugins/data/public/actions/filters/create_filters_from_multi_value_click.test.ts +++ b/src/plugins/data/public/actions/filters/create_filters_from_multi_value_click.test.ts @@ -11,50 +11,81 @@ import { dataPluginMock } from '../../mocks'; import { setIndexPatterns, setSearchService } from '../../services'; import { createFiltersFromMultiValueClickAction } from './create_filters_from_multi_value_click'; import { FieldFormatsGetConfigFn, BytesFormat } from '@kbn/field-formats-plugin/common'; +import { Datatable } from '@kbn/expressions-plugin/common'; +import { BooleanRelation, Filter } from '@kbn/es-query'; const mockField = { name: 'bytes', filterable: true, }; +let table: Pick; + describe('createFiltersFromMultiValueClickAction', () => { let dataPoints: Parameters[0]['data']; beforeEach(() => { - dataPoints = { - table: { - columns: [ - { - name: 'test', - id: '1-1', - meta: { - type: 'date', - source: 'esaggs', - sourceParams: { - indexPatternId: 'logstash-*', - type: 'histogram', - params: { - field: 'bytes', - interval: 30, - otherBucket: true, - }, + table = { + columns: [ + { + name: 'test', + id: '1-1', + meta: { + type: 'date', + source: 'esaggs', + sourceParams: { + indexPatternId: 'logstash-*', + type: 'histogram', + params: { + field: 'bytes', + interval: 30, + otherBucket: true, }, }, }, - ], - rows: [ - { - '1-1': '2048', + }, + { + name: 'avg', + id: '2-2', + meta: { + type: 'number', + source: 'esaggs', + sourceParams: { + indexPatternId: 'logstash-*', + type: 'average', + params: { + field: 'bytes', + }, + }, }, - ], - meta: { - source: 'dataview-1', - type: 'esaggs', }, + ], + rows: [ + { + '1-1': 1691189380, + '2-2': 2048, + }, + { + '1-1': 1691189680, + '2-2': 90, + }, + ], + meta: { + source: 'dataview-1', + type: 'esaggs', }, - column: 0, - value: ['2048'], }; + dataPoints = [ + { + table, + cells: [ + { + column: 0, + row: 0, + }, + ], + }, + ]; const dataStart = dataPluginMock.createStartContract(); setSearchService(dataStart.search); @@ -72,30 +103,117 @@ describe('createFiltersFromMultiValueClickAction', () => { }); test('ignores event when value for rows is not provided', async () => { - dataPoints.table.rows[0]['1-1'] = null; + dataPoints[0].table.rows[0]['1-1'] = null; const filters = await createFiltersFromMultiValueClickAction({ data: dataPoints }); expect(filters).toBeUndefined(); }); test('ignores event when dataview id is not provided', async () => { - dataPoints.table.meta = undefined; + dataPoints[0].table.meta = undefined; const filters = await createFiltersFromMultiValueClickAction({ data: dataPoints }); expect(filters).toBeUndefined(); }); test('handles an event when aggregations type is a terms', async () => { - (dataPoints.table.columns[0].meta.sourceParams as any).type = 'terms'; - const filters = await createFiltersFromMultiValueClickAction({ data: dataPoints }); + (dataPoints[0].table.columns[0].meta.sourceParams as any).type = 'terms'; + const filters = (await createFiltersFromMultiValueClickAction({ + data: dataPoints, + })) as Filter[]; - expect(filters?.query?.match_phrase?.bytes).toEqual('2048'); + expect(filters[0]?.query?.match_phrase?.bytes).toEqual(1691189380); }); test('handles an event when aggregations type is not terms', async () => { - const filters = await createFiltersFromMultiValueClickAction({ data: dataPoints }); + const filters = (await createFiltersFromMultiValueClickAction({ + data: dataPoints, + })) as Filter[]; - expect(filters?.query?.range.bytes.gte).toEqual(2048); - expect(filters?.query?.range.bytes.lt).toEqual(2078); + expect(filters[0]?.query?.range.bytes.gte).toEqual(1691189380); + expect(filters[0]?.query?.range.bytes.lt).toEqual(1691189410); + }); + test('creates combined filters if relation is passed', async () => { + dataPoints[0].cells = [ + { + column: 0, + row: 0, + }, + { + column: 0, + row: 1, + }, + ]; + dataPoints[0].relation = BooleanRelation.OR; + const filters = (await createFiltersFromMultiValueClickAction({ + data: dataPoints, + })) as Filter[]; + expect(filters.length).toEqual(1); + expect(filters[0]?.meta.type).toEqual('combined'); + }); + test('creates separate filters if relation is not passed', async () => { + dataPoints[0].cells = [ + { + column: 0, + row: 0, + }, + { + column: 0, + row: 1, + }, + ]; + const filters = (await createFiltersFromMultiValueClickAction({ + data: dataPoints, + })) as Filter[]; + expect(filters.length).toEqual(2); + }); + test('creates separate filters for multiple tables', async () => { + dataPoints = [ + { + table, + cells: [ + { + column: 0, + row: 0, + }, + ], + }, + { + table, + cells: [ + { + column: 0, + row: 1, + }, + ], + }, + ]; + const filters = (await createFiltersFromMultiValueClickAction({ + data: dataPoints, + })) as Filter[]; + expect(filters.length).toEqual(2); + }); + test('doesnt combine duplicate filters', async () => { + dataPoints = [ + { + table, + cells: [ + { + column: 0, + row: 0, + }, + { + column: 0, + row: 0, + }, + ], + relation: BooleanRelation.OR, + }, + ]; + const filters = (await createFiltersFromMultiValueClickAction({ + data: dataPoints, + })) as Filter[]; + expect(filters.length).toEqual(1); + expect(filters[0]?.meta?.type).toEqual('range'); }); }); diff --git a/src/plugins/data/public/actions/filters/create_filters_from_multi_value_click.ts b/src/plugins/data/public/actions/filters/create_filters_from_multi_value_click.ts index b33f994015cfe..5bce14cedf1cd 100644 --- a/src/plugins/data/public/actions/filters/create_filters_from_multi_value_click.ts +++ b/src/plugins/data/public/actions/filters/create_filters_from_multi_value_click.ts @@ -5,68 +5,77 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import { buildCombinedFilter, Filter, toggleFilterNegated, BooleanRelation } from '@kbn/es-query'; +import { + buildCombinedFilter, + toggleFilterNegated, + Filter, + compareFilters, + COMPARE_ALL_OPTIONS, +} from '@kbn/es-query'; +import { Truthy, uniqWith } from 'lodash'; import { createFilter } from './create_filters_from_value_click'; import type { MultiValueClickContext } from '../multi_value_click_action'; +import { mapAndFlattenFilters } from '../../query'; type MultiValueClickDataContext = MultiValueClickContext['data']; +export const truthy = (value: T): value is Truthy => !!value; + /** @public */ export const createFiltersFromMultiValueClickAction = async ({ data, negate, -}: MultiValueClickDataContext) => { - const { table, column, value } = data; - const dataViewId = table?.meta?.source; - if (!dataViewId) return; - - const columnId = table.columns[column].id; +}: MultiValueClickDataContext): Promise => { + if (!data || data.length === 0) return; - const filters = ( + const result = ( await Promise.all( - value.map(async (v) => { - return ( - await createFilter( - table, - column, - table.rows.findIndex((r) => r[columnId] === v) + data.map(async (d) => { + const { table, cells, relation } = d; + const dataViewId = table?.meta?.source; + if (!dataViewId) return; + + const filters = ( + await Promise.all( + cells.map(async ({ column, row }) => await createFilter(table, column, row)) ) - )?.[0]; + ) + .flat() + .filter(truthy); + + const uniqueFilters = uniqWith(mapAndFlattenFilters(filters), (a, b) => + compareFilters(a, b, COMPARE_ALL_OPTIONS) + ); + + if (uniqueFilters.length === 0) return; + + if (uniqueFilters.length === 1) { + return negate ? [toggleFilterNegated(uniqueFilters[0])] : uniqueFilters; + } + + if (!relation) { + return negate ? uniqueFilters.map((f) => toggleFilterNegated(f)) : uniqueFilters; + } + + const filtersHaveAlias = uniqueFilters.every((f) => f.meta.alias); + const alias = filtersHaveAlias + ? uniqueFilters.map((f) => f.meta.alias).join(` ${relation} `) + : ''; + + return buildCombinedFilter( + relation, + uniqueFilters, + { id: dataViewId }, + undefined, + negate, + alias + ); }) ) - ).filter(Boolean) as Filter[]; - if (filters.length === 0) return; - // no need for combined filter in case of one filter - if (filters.length === 1) { - if (filters[0] && negate) { - return toggleFilterNegated(filters[0]); - } - return filters[0]; - } - const filtersHaveAlias = filters.every((f) => f.meta.alias); - let alias = ''; - if (filtersHaveAlias) { - filters.forEach((f, i) => { - if (i === filters.length - 1) { - alias += `${f.meta.alias}`; - } else { - alias += `${f.meta.alias} ${BooleanRelation.OR} `; - } - }); - } - let filter: Filter = buildCombinedFilter( - BooleanRelation.OR, - filters, - { - id: dataViewId, - }, - undefined, - undefined, - alias - ); - if (filter && negate) { - filter = toggleFilterNegated(filter); - } + ) + .flat() + .filter(truthy); - return filter; + if (result.length === 0) return; + return result; }; diff --git a/src/plugins/data/public/actions/multi_value_click_action.ts b/src/plugins/data/public/actions/multi_value_click_action.ts index 422b1d8653e02..1f9059ae5e866 100644 --- a/src/plugins/data/public/actions/multi_value_click_action.ts +++ b/src/plugins/data/public/actions/multi_value_click_action.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import type { Filter } from '@kbn/es-query'; import { Datatable } from '@kbn/expressions-plugin/public'; import { UiActionsActionDefinition } from '@kbn/ui-actions-plugin/public'; -import { FilterManager } from '../query'; +import { BooleanRelation, extractTimeFilter, convertRangeFilterToTimeRange } from '@kbn/es-query'; +import { QueryStart } from '../query'; import { createFiltersFromMultiValueClickAction } from './filters/create_filters_from_multi_value_click'; export type MultiValueClickActionContext = MultiValueClickContext; @@ -20,18 +20,21 @@ export interface MultiValueClickContext { // Apps using this property will need to cast to `IEmbeddable`. embeddable?: unknown; data: { - data: { + data: Array<{ + cells: Array<{ + column: number; + row: number; + }>; table: Pick; - column: number; - value: any[]; - }; + relation?: BooleanRelation; + }>; timeFieldName?: string; negate?: boolean; }; } export function createMultiValueClickActionDefinition( - getStartServices: () => { filterManager: FilterManager } + getStartServices: () => { query: QueryStart } ): UiActionsActionDefinition { return { type: ACTION_MULTI_VALUE_CLICK, @@ -41,9 +44,23 @@ export function createMultiValueClickActionDefinition( const filters = await createFiltersFromMultiValueClickAction(context.data); return Boolean(filters); }, - execute: async (context: MultiValueClickActionContext) => { - const filter = (await createFiltersFromMultiValueClickAction(context.data)) as Filter; - getStartServices().filterManager.addFilters(filter); + execute: async ({ data }: MultiValueClickActionContext) => { + const filters = await createFiltersFromMultiValueClickAction(data); + if (!filters || filters?.length === 0) return; + const { + filterManager, + timefilter: { timefilter }, + } = getStartServices().query; + + if (data.timeFieldName) { + const { timeRangeFilter, restOfFilters } = extractTimeFilter(data.timeFieldName, filters); + filterManager.addFilters(restOfFilters); + if (timeRangeFilter) { + timefilter.setTime(convertRangeFilterToTimeRange(timeRangeFilter)); + } + } else { + filterManager.addFilters(filters); + } }, }; } diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts index 02d5e7f69ad51..8f4e37afb29b2 100644 --- a/src/plugins/data/public/plugin.ts +++ b/src/plugins/data/public/plugin.ts @@ -158,7 +158,7 @@ export class DataPublicPlugin uiActions.addTriggerAction( 'MULTI_VALUE_CLICK_TRIGGER', createMultiValueClickActionDefinition(() => ({ - filterManager: query.filterManager, + query, })) ); diff --git a/src/plugins/embeddable/public/lib/triggers/triggers.ts b/src/plugins/embeddable/public/lib/triggers/triggers.ts index 94c09c2d79376..dbafad289c006 100644 --- a/src/plugins/embeddable/public/lib/triggers/triggers.ts +++ b/src/plugins/embeddable/public/lib/triggers/triggers.ts @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n'; import { Datatable, DatatableColumnMeta } from '@kbn/expressions-plugin/common'; import { Trigger, RowClickContext } from '@kbn/ui-actions-plugin/public'; +import { BooleanRelation } from '@kbn/es-query'; import { IEmbeddable } from '..'; export interface EmbeddableContext { @@ -32,11 +33,14 @@ export interface ValueClickContext { export interface MultiValueClickContext { embeddable?: T; data: { - data: { + data: Array<{ table: Pick; - column: number; - value: any[]; - }; + cells: Array<{ + column: number; + row: number; + }>; + relation?: BooleanRelation; + }>; timeFieldName?: string; negate?: boolean; }; @@ -157,12 +161,27 @@ export const cellValueTrigger: Trigger = { export const isValueClickTriggerContext = ( context: ChartActionContext -): context is ValueClickContext => context.data && 'data' in context.data; +): context is ValueClickContext => { + return ( + context.data && + 'data' in context.data && + Array.isArray(context.data.data) && + context.data.data.length > 0 && + 'column' in context.data.data[0] + ); +}; export const isMultiValueClickTriggerContext = ( context: ChartActionContext -): context is MultiValueClickContext => - context.data && 'data' in context.data && !Array.isArray(context.data.data); +): context is MultiValueClickContext => { + return ( + context.data && + 'data' in context.data && + Array.isArray(context.data.data) && + context.data.data.length > 0 && + 'cells' in context.data.data[0] + ); +}; export const isRangeSelectTriggerContext = ( context: ChartActionContext diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx index 18d0833ed4250..6514e13d65a11 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.test.tsx @@ -530,7 +530,9 @@ describe('workspace_panel', () => { const onEvent = expressionRendererMock.mock.calls[0][0].onEvent!; - const eventData = { myData: true, table: { rows: [], columns: [] }, column: 0 }; + const eventData = { + data: [{ table: { rows: [], columns: [] }, cells: [{ column: 0, row: 0 }] }], + }; onEvent({ name: 'multiFilter', data: eventData }); expect(uiActionsMock.getTrigger).toHaveBeenCalledWith(VIS_EVENT_TO_TRIGGER.multiFilter); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index 3f92236c99e5d..02db9e18919f7 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -434,7 +434,7 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ plugins.uiActions.getTrigger(VIS_EVENT_TO_TRIGGER[event.name]).exec({ data: { ...event.data, - timeFieldName: inferTimeField(plugins.data.datatableUtilities, event.data), + timeFieldName: inferTimeField(plugins.data.datatableUtilities, event), }, }); } @@ -442,7 +442,7 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ plugins.uiActions.getTrigger(VIS_EVENT_TO_TRIGGER[event.name]).exec({ data: { ...event.data, - timeFieldName: inferTimeField(plugins.data.datatableUtilities, event.data), + timeFieldName: inferTimeField(plugins.data.datatableUtilities, event), }, }); } diff --git a/x-pack/plugins/lens/public/embeddable/embeddable.tsx b/x-pack/plugins/lens/public/embeddable/embeddable.tsx index 8741d73a4a7b4..67dea2f98231c 100644 --- a/x-pack/plugins/lens/public/embeddable/embeddable.tsx +++ b/x-pack/plugins/lens/public/embeddable/embeddable.tsx @@ -1227,45 +1227,35 @@ export class Embeddable if (!this.deps.getTrigger || this.input.disableTriggers) { return; } + + let eventHandler: + | LensBaseEmbeddableInput['onBrushEnd'] + | LensBaseEmbeddableInput['onFilter'] + | LensBaseEmbeddableInput['onTableRowClick']; + let shouldExecuteDefaultTriggers = true; + if (isLensBrushEvent(event)) { - let shouldExecuteDefaultTriggers = true; - if (this.input.onBrushEnd) { - this.input.onBrushEnd({ - ...event.data, - preventDefault: () => { - shouldExecuteDefaultTriggers = false; - }, - }); - } - if (shouldExecuteDefaultTriggers) { - this.deps.getTrigger(VIS_EVENT_TO_TRIGGER[event.name]).exec({ - data: { - ...event.data, - timeFieldName: - event.data.timeFieldName || - inferTimeField(this.deps.data.datatableUtilities, event.data), - }, - embeddable: this, - }); - } + eventHandler = this.input.onBrushEnd; + } else if (isLensFilterEvent(event) || isLensMultiFilterEvent(event)) { + eventHandler = this.input.onFilter; + } else if (isLensTableRowContextMenuClickEvent(event)) { + eventHandler = this.input.onTableRowClick; } - if (isLensFilterEvent(event) || isLensMultiFilterEvent(event)) { - let shouldExecuteDefaultTriggers = true; - if (this.input.onFilter) { - this.input.onFilter({ - ...event.data, - preventDefault: () => { - shouldExecuteDefaultTriggers = false; - }, - }); - } + + eventHandler?.({ + ...event.data, + preventDefault: () => { + shouldExecuteDefaultTriggers = false; + }, + }); + + if (isLensFilterEvent(event) || isLensMultiFilterEvent(event) || isLensBrushEvent(event)) { if (shouldExecuteDefaultTriggers) { this.deps.getTrigger(VIS_EVENT_TO_TRIGGER[event.name]).exec({ data: { ...event.data, timeFieldName: - event.data.timeFieldName || - inferTimeField(this.deps.data.datatableUtilities, event.data), + event.data.timeFieldName || inferTimeField(this.deps.data.datatableUtilities, event), }, embeddable: this, }); @@ -1273,15 +1263,6 @@ export class Embeddable } if (isLensTableRowContextMenuClickEvent(event)) { - let shouldExecuteDefaultTriggers = true; - if (this.input.onTableRowClick) { - this.input.onTableRowClick({ - ...event.data, - preventDefault: () => { - shouldExecuteDefaultTriggers = false; - }, - }); - } if (shouldExecuteDefaultTriggers) { this.deps.getTrigger(VIS_EVENT_TO_TRIGGER[event.name]).exec( { diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 3b989366fa307..8b69929b4fb84 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -1331,6 +1331,12 @@ export interface LensTableRowContextMenuEvent { data: RowClickContext['data']; } +export type TriggerEvent = + | BrushTriggerEvent + | ClickTriggerEvent + | MultiClickTriggerEvent + | LensTableRowContextMenuEvent; + export function isLensFilterEvent(event: ExpressionRendererEvent): event is ClickTriggerEvent { return event.name === 'filter'; } diff --git a/x-pack/plugins/lens/public/utils.test.ts b/x-pack/plugins/lens/public/utils.test.ts index 52e509557b2fc..e775059586aff 100644 --- a/x-pack/plugins/lens/public/utils.test.ts +++ b/x-pack/plugins/lens/public/utils.test.ts @@ -56,9 +56,12 @@ describe('utils', () => { test('infer time field for brush event', () => { expect( inferTimeField(datatableUtilities, { - table, - column: 0, - range: [1, 2], + name: 'brush', + data: { + table, + column: 0, + range: [1, 2], + }, }) ).toEqual('abc'); }); @@ -66,9 +69,12 @@ describe('utils', () => { test('do not return time field if time range is not bound', () => { expect( inferTimeField(datatableUtilities, { - table: tableWithoutAppliedTimeRange, - column: 0, - range: [1, 2], + name: 'brush', + data: { + table: tableWithoutAppliedTimeRange, + column: 0, + range: [1, 2], + }, }) ).toEqual(undefined); }); @@ -76,14 +82,17 @@ describe('utils', () => { test('infer time field for click event', () => { expect( inferTimeField(datatableUtilities, { - data: [ - { - table, - column: 0, - row: 0, - value: 1, - }, - ], + name: 'filter', + data: { + data: [ + { + table, + column: 0, + row: 0, + value: 1, + }, + ], + }, }) ).toEqual('abc'); }); @@ -91,15 +100,18 @@ describe('utils', () => { test('do not return time field for negated click event', () => { expect( inferTimeField(datatableUtilities, { - data: [ - { - table, - column: 0, - row: 0, - value: 1, - }, - ], - negate: true, + name: 'filter', + data: { + data: [ + { + table, + column: 0, + row: 0, + value: 1, + }, + ], + negate: true, + }, }) ).toEqual(undefined); }); @@ -107,14 +119,17 @@ describe('utils', () => { test('do not return time field for click event without bound time field', () => { expect( inferTimeField(datatableUtilities, { - data: [ - { - table: tableWithoutAppliedTimeRange, - column: 0, - row: 0, - value: 1, - }, - ], + name: 'filter', + data: { + data: [ + { + table: tableWithoutAppliedTimeRange, + column: 0, + row: 0, + value: 1, + }, + ], + }, }) ).toEqual(undefined); }); diff --git a/x-pack/plugins/lens/public/utils.ts b/x-pack/plugins/lens/public/utils.ts index 446d7aac37e66..b1deface2cd77 100644 --- a/x-pack/plugins/lens/public/utils.ts +++ b/x-pack/plugins/lens/public/utils.ts @@ -14,11 +14,6 @@ import type { TimefilterContract } from '@kbn/data-plugin/public'; import type { IUiSettingsClient, SavedObjectReference } from '@kbn/core/public'; import type { DataView, DataViewsContract } from '@kbn/data-views-plugin/public'; import type { DatatableUtilitiesService } from '@kbn/data-plugin/common'; -import { - BrushTriggerEvent, - ClickTriggerEvent, - MultiClickTriggerEvent, -} from '@kbn/charts-plugin/public'; import { emptyTitleText } from '@kbn/visualization-ui-components'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; import { ISearchStart } from '@kbn/data-plugin/public'; @@ -34,6 +29,10 @@ import { DragDropOperation, isOperation, UserMessage, + TriggerEvent, + isLensBrushEvent, + isLensMultiFilterEvent, + isLensFilterEvent, } from './types'; import type { DatasourceStates, VisualizationState } from './state_management'; import type { IndexPatternServiceAPI } from './data_views_service/service'; @@ -214,17 +213,28 @@ export function getRemoveOperation( return layerCount === 1 ? 'clear' : 'remove'; } -export function inferTimeField( - datatableUtilities: DatatableUtilitiesService, - context: BrushTriggerEvent['data'] | ClickTriggerEvent['data'] | MultiClickTriggerEvent['data'] -) { - const tablesAndColumns = - 'table' in context - ? [{ table: context.table, column: context.column }] - : !context.negate - ? context.data - : // if it's a negated filter, never respect bound time field - []; +function getTablesAndColumnsFromContext(event: TriggerEvent) { + // if it's a negated filter, never respect bound time field + if ('negate' in event.data && event.data.negate) { + return []; + } + if (isLensBrushEvent(event)) { + return [{ table: event.data.table, column: event.data.column }]; + } + if (isLensMultiFilterEvent(event)) { + return event.data.data.map(({ table, cells }) => ({ + table, + column: cells[0].column, + })); + } + if (isLensFilterEvent(event)) { + return event.data.data; + } + return event.data; +} + +export function inferTimeField(datatableUtilities: DatatableUtilitiesService, event: TriggerEvent) { + const tablesAndColumns = getTablesAndColumnsFromContext(event); return !Array.isArray(tablesAndColumns) ? [tablesAndColumns] : tablesAndColumns diff --git a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx index eadf94552794e..943bf4dab0d80 100644 --- a/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx +++ b/x-pack/plugins/security_solution/public/common/components/visualization_actions/lens_embeddable.tsx @@ -187,7 +187,7 @@ const LensEmbeddableComponent: React.FC = ({ const onFilterCallback = useCallback( async (e: ClickTriggerEvent['data'] | MultiClickTriggerEvent['data']) => { - if (!Array.isArray(e.data) || preferredSeriesType !== 'area') { + if (!isClickTriggerEvent(e) || preferredSeriesType !== 'area') { return; } // Update timerange when clicking on a dot in an area chart @@ -301,4 +301,10 @@ const LensEmbeddableComponent: React.FC = ({ ); }; +const isClickTriggerEvent = ( + e: ClickTriggerEvent['data'] | MultiClickTriggerEvent['data'] +): e is ClickTriggerEvent['data'] => { + return Array.isArray(e.data) && 'column' in e.data[0]; +}; + export const LensEmbeddable = React.memo(LensEmbeddableComponent); diff --git a/x-pack/test/functional/apps/lens/group4/dashboard.ts b/x-pack/test/functional/apps/lens/group4/dashboard.ts index daa8a750ad1c8..e94f935323235 100644 --- a/x-pack/test/functional/apps/lens/group4/dashboard.ts +++ b/x-pack/test/functional/apps/lens/group4/dashboard.ts @@ -107,9 +107,14 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { // show the tooltip actions await rightClickInChart(30, 5); // hardcoded position of bar, depends heavy on data and charts implementation - await (await find.byCssSelector('.echTooltipActions__action')).click(); + await (await find.allByCssSelector('.echTooltipActions__action'))[1].click(); const hasIpFilter = await filterBar.hasFilter('ip', '97.220.3.248'); expect(hasIpFilter).to.be(true); + await rightClickInChart(35, 5); // hardcoded position of bar, depends heavy on data and charts implementation + await (await find.allByCssSelector('.echTooltipActions__action'))[0].click(); + const time = await PageObjects.timePicker.getTimeConfig(); + expect(time.start).to.equal('Sep 21, 2015 @ 09:00:00.000'); + expect(time.end).to.equal('Sep 21, 2015 @ 12:00:00.000'); }); }); From c04f5661d354e36940e73f4095d7bed38f3bde17 Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Wed, 9 Aug 2023 17:06:37 +0200 Subject: [PATCH 11/41] [Infra UI] Centralize chart components (#163283) closes [#161957](https://github.com/elastic/kibana/issues/161957) ## Summary This PR encapsulates the styling and logic to render the Lens charts components. Doing so simplifies the usage in places that render these charts, eliminating the previously necessary code duplication ### How to test - Start a local Kibana instance - Navigate to `Infrastructure` > `Hosts` - Confirm that all charts still work - Play with the filters - Verify whether only charts above the fold are rendered - Open the flyout - Switch hosts with the flyout open --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../lens/dashboards/host/kpi_grid_config.ts | 35 ++-- .../components/asset_details/constants.ts | 8 + .../tabs/overview/kpis/kpi_grid.tsx | 60 +++++-- .../asset_details/tabs/overview/kpis/tile.tsx | 124 -------------- .../tabs/overview/metrics/metric_chart.tsx | 116 ------------- .../tabs/overview/metrics/metrics_grid.tsx | 92 +++++++--- .../components/lens/chart_load_error.tsx | 38 +++++ .../components/lens/chart_placeholder.tsx | 3 +- .../infra/public/components/lens/index.tsx | 3 +- .../public/components/lens/lens_chart.tsx | 110 ++++++++++++ .../public/components/lens/lens_wrapper.tsx | 36 ++-- .../metric_explanation/tooltip_content.tsx | 4 +- .../infra/public/components/lens/types.ts | 27 +++ .../infra/public/hooks/use_lens_attributes.ts | 4 +- .../components/chart/metric_chart_wrapper.tsx | 27 +-- .../hosts/components/kpis/hosts_tile.tsx | 12 +- .../hosts/components/kpis/kpi_grid.tsx | 16 +- .../metrics/hosts/components/kpis/tile.tsx | 157 +++++------------- .../components/tabs/metrics/metric_chart.tsx | 138 ++++----------- .../public/pages/metrics/hosts/constants.ts | 3 +- .../translations/translations/fr-FR.json | 16 +- .../translations/translations/ja-JP.json | 16 +- .../translations/translations/zh-CN.json | 16 +- .../page_objects/infra_hosts_view.ts | 4 +- 24 files changed, 472 insertions(+), 593 deletions(-) create mode 100644 x-pack/plugins/infra/public/components/asset_details/constants.ts delete mode 100644 x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/tile.tsx delete mode 100644 x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metric_chart.tsx create mode 100644 x-pack/plugins/infra/public/components/lens/chart_load_error.tsx create mode 100644 x-pack/plugins/infra/public/components/lens/lens_chart.tsx create mode 100644 x-pack/plugins/infra/public/components/lens/types.ts diff --git a/x-pack/plugins/infra/public/common/visualizations/lens/dashboards/host/kpi_grid_config.ts b/x-pack/plugins/infra/public/common/visualizations/lens/dashboards/host/kpi_grid_config.ts index cc4f51c8f2d18..9dde33f39cbdf 100644 --- a/x-pack/plugins/infra/public/common/visualizations/lens/dashboards/host/kpi_grid_config.ts +++ b/x-pack/plugins/infra/public/common/visualizations/lens/dashboards/host/kpi_grid_config.ts @@ -5,16 +5,24 @@ * 2.0. */ -import { TypedLensByValueInput } from '@kbn/lens-plugin/public'; import { i18n } from '@kbn/i18n'; -import { Layer } from '../../../../../hooks/use_lens_attributes'; +import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import type { Layer } from '../../../../../hooks/use_lens_attributes'; import { hostLensFormulas } from '../../../constants'; -import { FormulaConfig } from '../../../types'; import { TOOLTIP } from './translations'; -import { MetricLayerOptions } from '../../visualization_types/layers'; -export interface KPIChartProps - extends Pick { +import type { FormulaConfig } from '../../../types'; +import type { MetricLayerOptions } from '../../visualization_types'; + +export const KPI_CHART_HEIGHT = 150; +export const AVERAGE_SUBTITLE = i18n.translate( + 'xpack.infra.assetDetailsEmbeddable.overview.kpi.subtitle.average', + { + defaultMessage: 'Average', + } +); + +export interface KPIChartProps extends Pick { layers: Layer; toolTip: string; } @@ -22,7 +30,7 @@ export interface KPIChartProps export const KPI_CHARTS: KPIChartProps[] = [ { id: 'cpuUsage', - title: i18n.translate('xpack.infra.hostsViewPage.metricTrend.cpuUsage.title', { + title: i18n.translate('xpack.infra.assetDetailsEmbeddable.overview.kpi.cpuUsage.title', { defaultMessage: 'CPU Usage', }), layers: { @@ -45,9 +53,12 @@ export const KPI_CHARTS: KPIChartProps[] = [ }, { id: 'normalizedLoad1m', - title: i18n.translate('xpack.infra.hostsViewPage.metricTrend.normalizedLoad1m.title', { - defaultMessage: 'CPU Usage', - }), + title: i18n.translate( + 'xpack.infra.assetDetailsEmbeddable.overview.kpi.normalizedLoad1m.title', + { + defaultMessage: 'CPU Usage', + } + ), layers: { data: { ...hostLensFormulas.normalizedLoad1m, @@ -68,7 +79,7 @@ export const KPI_CHARTS: KPIChartProps[] = [ }, { id: 'memoryUsage', - title: i18n.translate('xpack.infra.hostsViewPage.metricTrend.memoryUsage.title', { + title: i18n.translate('xpack.infra.assetDetailsEmbeddable.overview.kpi.memoryUsage.title', { defaultMessage: 'CPU Usage', }), layers: { @@ -91,7 +102,7 @@ export const KPI_CHARTS: KPIChartProps[] = [ }, { id: 'diskSpaceUsage', - title: i18n.translate('xpack.infra.hostsViewPage.metricTrend.diskSpaceUsage.title', { + title: i18n.translate('xpack.infra.assetDetailsEmbeddable.overview.kpi.diskSpaceUsage.title', { defaultMessage: 'CPU Usage', }), layers: { diff --git a/x-pack/plugins/infra/public/components/asset_details/constants.ts b/x-pack/plugins/infra/public/components/asset_details/constants.ts new file mode 100644 index 0000000000000..546e2b9aad4d9 --- /dev/null +++ b/x-pack/plugins/infra/public/components/asset_details/constants.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const METRIC_CHART_HEIGHT = 300; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/kpi_grid.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/kpi_grid.tsx index b86201a29098c..c134f0de6bb7a 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/kpi_grid.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/kpi_grid.tsx @@ -4,21 +4,55 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; + +import React, { useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { Tile, type TileProps } from './tile'; -import { KPI_CHARTS } from '../../../../../common/visualizations/lens/dashboards/host/kpi_grid_config'; +import type { DataView } from '@kbn/data-views-plugin/public'; +import type { TimeRange } from '@kbn/es-query'; +import { LensChart, TooltipContent } from '../../../../lens'; +import { buildCombinedHostsFilter } from '../../../../../utils/filters/build'; +import { + KPI_CHARTS, + KPI_CHART_HEIGHT, + AVERAGE_SUBTITLE, +} from '../../../../../common/visualizations/lens/dashboards/host/kpi_grid_config'; + +interface Props { + dataView?: DataView; + nodeName: string; + timeRange: TimeRange; +} + +export const KPIGrid = React.memo(({ nodeName, dataView, timeRange }: Props) => { + const filters = useMemo(() => { + return [ + buildCombinedHostsFilter({ + field: 'host.name', + values: [nodeName], + dataView, + }), + ]; + }, [dataView, nodeName]); -export const KPIGrid = React.memo(({ nodeName, dataView, timeRange: dateRange }: TileProps) => { return ( - <> - - {KPI_CHARTS.map((chartProp, index) => ( - - - - ))} - - + + {KPI_CHARTS.map(({ id, layers, title, toolTip }, index) => ( + + } + visualizationType="lnsMetric" + disableTriggers + hidePanelTitles + /> + + ))} + ); }); diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/tile.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/tile.tsx deleted file mode 100644 index 9907b81d64fc0..0000000000000 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/kpis/tile.tsx +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React, { useMemo } from 'react'; -import type { DataView } from '@kbn/data-views-plugin/public'; -import { i18n } from '@kbn/i18n'; -import { EuiIcon, EuiPanel, EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip } from '@elastic/eui'; -import styled from 'styled-components'; -import type { Action } from '@kbn/ui-actions-plugin/public'; -import { TimeRange } from '@kbn/es-query'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { LensWrapper, TooltipContent } from '../../../../lens'; -import type { KPIChartProps } from '../../../../../common/visualizations/lens/dashboards/host/kpi_grid_config'; -import { useLensAttributes } from '../../../../../hooks/use_lens_attributes'; -import { buildCombinedHostsFilter } from '../../../../../utils/filters/build'; - -const MIN_HEIGHT = 150; - -export interface TileProps { - timeRange: TimeRange; - dataView?: DataView; - nodeName: string; -} - -export const Tile = ({ - id, - layers, - title, - toolTip, - dataView, - nodeName, - timeRange, -}: KPIChartProps & TileProps) => { - const getSubtitle = () => - i18n.translate('xpack.infra.assetDetailsEmbeddable.overview.metricTrend.subtitle.average', { - defaultMessage: 'Average', - }); - - const { formula, attributes, getExtraActions, error } = useLensAttributes({ - dataView, - title, - layers: { ...layers, options: { ...layers.options, subtitle: getSubtitle() } }, - visualizationType: 'lnsMetric', - }); - - const filters = useMemo(() => { - return [ - buildCombinedHostsFilter({ - field: 'host.name', - values: [nodeName], - dataView, - }), - ]; - }, [dataView, nodeName]); - - const extraActions: Action[] = useMemo( - () => - getExtraActions({ - timeRange, - filters, - }), - [filters, getExtraActions, timeRange] - ); - - const loading = !attributes; - - return ( - - {error ? ( - - - - - - - - - - - ) : ( - } - anchorClassName="eui-fullWidth" - > - - - )} - - ); -}; - -const EuiPanelStyled = styled(EuiPanel)` - min-height: ${MIN_HEIGHT}px; - .echMetric { - border-radius: ${({ theme }) => theme.eui.euiBorderRadius}; - pointer-events: none; - } -`; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metric_chart.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metric_chart.tsx deleted file mode 100644 index ad75734013a29..0000000000000 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metric_chart.tsx +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React, { useMemo } from 'react'; -import { Action } from '@kbn/ui-actions-plugin/public'; -import { EuiIcon, EuiPanel, EuiFlexGroup, EuiFlexItem, EuiText, useEuiTheme } from '@elastic/eui'; -import { css } from '@emotion/react'; -import { TypedLensByValueInput } from '@kbn/lens-plugin/public'; -import type { DataView } from '@kbn/data-views-plugin/public'; -import type { TimeRange } from '@kbn/es-query'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { LensWrapper } from '../../../../lens/lens_wrapper'; -import { buildCombinedHostsFilter } from '../../../../../utils/filters/build'; -import { useLensAttributes, type Layer } from '../../../../../hooks/use_lens_attributes'; -import type { FormulaConfig, XYLayerOptions } from '../../../../../common/visualizations'; - -export interface MetricChartProps extends Pick { - title: string; - layers: Array>; - dataView?: DataView; - timeRange: TimeRange; - nodeName: string; -} - -const MIN_HEIGHT = 250; - -export const MetricChart = ({ - id, - title, - layers, - nodeName, - timeRange, - dataView, - overrides, -}: MetricChartProps) => { - const { euiTheme } = useEuiTheme(); - - const { attributes, getExtraActions, error } = useLensAttributes({ - dataView, - layers, - title, - visualizationType: 'lnsXY', - }); - - const filters = useMemo(() => { - return [ - buildCombinedHostsFilter({ - field: 'host.name', - values: [nodeName], - dataView, - }), - ]; - }, [dataView, nodeName]); - - const extraActions: Action[] = useMemo( - () => - getExtraActions({ - timeRange, - filters, - }), - [timeRange, filters, getExtraActions] - ); - - const loading = !attributes; - - return ( - - {error ? ( - - - - - - - - - - - ) : ( - - )} - - ); -}; diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metrics_grid.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metrics_grid.tsx index 531b5aa4a4191..be96fe575d2be 100644 --- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metrics_grid.tsx +++ b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metrics_grid.tsx @@ -4,18 +4,30 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React from 'react'; +import React, { useCallback } from 'react'; import { EuiFlexGrid, EuiFlexItem, EuiTitle, EuiSpacer, EuiFlexGroup } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { DataView } from '@kbn/data-views-plugin/public'; -import { TimeRange } from '@kbn/es-query'; +import type { TimeRange } from '@kbn/es-query'; import { FormattedMessage } from '@kbn/i18n-react'; -import { HostMetricsDocsLink } from '../../../../lens'; -import { MetricChart, type MetricChartProps } from './metric_chart'; -import { hostLensFormulas } from '../../../../../common/visualizations'; +import { buildCombinedHostsFilter } from '../../../../../utils/filters/build'; +import type { Layer } from '../../../../../hooks/use_lens_attributes'; +import { HostMetricsDocsLink, LensChart, type LensChartProps } from '../../../../lens'; +import { + type FormulaConfig, + hostLensFormulas, + type XYLayerOptions, +} from '../../../../../common/visualizations'; +import { METRIC_CHART_HEIGHT } from '../../../constants'; -const PERCENT_LEFT_AXIS: Pick['overrides'] = { +type DataViewOrigin = 'logs' | 'metrics'; +interface MetricChartConfig extends Pick { + layers: Array>; + toolTip: string; +} + +const PERCENT_LEFT_AXIS: Pick['overrides'] = { axisLeft: { domain: { min: 0, @@ -24,7 +36,7 @@ const PERCENT_LEFT_AXIS: Pick['overrides'] = { }, }; -const LEGEND_SETTINGS: Pick['overrides'] = { +const LEGEND_SETTINGS: Pick['overrides'] = { settings: { showLegend: true, legendPosition: 'bottom', @@ -33,8 +45,8 @@ const LEGEND_SETTINGS: Pick['overrides'] = { }; const CHARTS_IN_ORDER: Array< - Pick & { - dataViewType: 'logs' | 'metrics'; + Pick & { + dataViewOrigin: DataViewOrigin; } > = [ { @@ -49,7 +61,7 @@ const CHARTS_IN_ORDER: Array< layerType: 'data', }, ], - dataViewType: 'metrics', + dataViewOrigin: 'metrics', overrides: { axisLeft: PERCENT_LEFT_AXIS.axisLeft, }, @@ -65,7 +77,7 @@ const CHARTS_IN_ORDER: Array< layerType: 'data', }, ], - dataViewType: 'metrics', + dataViewOrigin: 'metrics', overrides: { axisLeft: PERCENT_LEFT_AXIS.axisLeft, }, @@ -96,7 +108,7 @@ const CHARTS_IN_ORDER: Array< layerType: 'referenceLine', }, ], - dataViewType: 'metrics', + dataViewOrigin: 'metrics', }, { id: 'logRate', @@ -109,7 +121,7 @@ const CHARTS_IN_ORDER: Array< layerType: 'data', }, ], - dataViewType: 'logs', + dataViewOrigin: 'logs', }, { id: 'diskSpaceUsageAvailable', @@ -152,7 +164,7 @@ const CHARTS_IN_ORDER: Array< axisLeft: PERCENT_LEFT_AXIS.axisLeft, settings: LEGEND_SETTINGS.settings, }, - dataViewType: 'metrics', + dataViewOrigin: 'metrics', }, { id: 'diskThroughputReadWrite', @@ -184,7 +196,7 @@ const CHARTS_IN_ORDER: Array< overrides: { settings: LEGEND_SETTINGS.settings, }, - dataViewType: 'metrics', + dataViewOrigin: 'metrics', }, { id: 'diskIOReadWrite', @@ -216,7 +228,7 @@ const CHARTS_IN_ORDER: Array< overrides: { settings: LEGEND_SETTINGS.settings, }, - dataViewType: 'metrics', + dataViewOrigin: 'metrics', }, { id: 'rxTx', @@ -248,7 +260,7 @@ const CHARTS_IN_ORDER: Array< overrides: { settings: LEGEND_SETTINGS.settings, }, - dataViewType: 'metrics', + dataViewOrigin: 'metrics', }, ]; @@ -259,8 +271,35 @@ export interface MetricsGridProps { logsDataView?: DataView; } +export interface MetricsGridProps { + nodeName: string; + timeRange: TimeRange; + metricsDataView?: DataView; + logsDataView?: DataView; +} + export const MetricsGrid = React.memo( ({ nodeName, metricsDataView, logsDataView, timeRange }: MetricsGridProps) => { + const getDataView = useCallback( + (dataViewOrigin: DataViewOrigin) => { + return dataViewOrigin === 'metrics' ? metricsDataView : logsDataView; + }, + [logsDataView, metricsDataView] + ); + + const getFilters = useCallback( + (dataViewOrigin: DataViewOrigin) => { + return [ + buildCombinedHostsFilter({ + field: 'host.name', + values: [nodeName], + dataView: getDataView(dataViewOrigin), + }), + ]; + }, + [getDataView, nodeName] + ); + return ( @@ -277,13 +316,20 @@ export const MetricsGrid = React.memo( - {CHARTS_IN_ORDER.map(({ dataViewType, ...chartProp }, index) => ( + {CHARTS_IN_ORDER.map(({ dataViewOrigin, id, layers, title, overrides }, index) => ( - ))} diff --git a/x-pack/plugins/infra/public/components/lens/chart_load_error.tsx b/x-pack/plugins/infra/public/components/lens/chart_load_error.tsx new file mode 100644 index 0000000000000..5ffdc573a2cd7 --- /dev/null +++ b/x-pack/plugins/infra/public/components/lens/chart_load_error.tsx @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiIcon, EuiText } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { css } from '@emotion/react'; + +export const ChartLoadError = () => { + return ( + + + + + + + + + + + ); +}; diff --git a/x-pack/plugins/infra/public/components/lens/chart_placeholder.tsx b/x-pack/plugins/infra/public/components/lens/chart_placeholder.tsx index 7bf35f0e0392a..2dfcbfa21c814 100644 --- a/x-pack/plugins/infra/public/components/lens/chart_placeholder.tsx +++ b/x-pack/plugins/infra/public/components/lens/chart_placeholder.tsx @@ -6,8 +6,7 @@ */ import React from 'react'; -import { EuiFlexGroup, EuiProgress, EuiFlexItem, EuiLoadingChart } from '@elastic/eui'; -import { useEuiTheme } from '@elastic/eui'; +import { EuiFlexGroup, EuiProgress, EuiFlexItem, EuiLoadingChart, useEuiTheme } from '@elastic/eui'; import { css } from '@emotion/react'; export const ChartLoadingProgress = ({ hasTopMargin = false }: { hasTopMargin?: boolean }) => { diff --git a/x-pack/plugins/infra/public/components/lens/index.tsx b/x-pack/plugins/infra/public/components/lens/index.tsx index 17a2f5b480442..93d050209a219 100644 --- a/x-pack/plugins/infra/public/components/lens/index.tsx +++ b/x-pack/plugins/infra/public/components/lens/index.tsx @@ -5,8 +5,7 @@ * 2.0. */ +export { LensChart, type LensChartProps } from './lens_chart'; export { ChartPlaceholder } from './chart_placeholder'; -export { LensWrapper } from './lens_wrapper'; - export { TooltipContent } from './metric_explanation/tooltip_content'; export { HostMetricsDocsLink } from './metric_explanation/host_metrics_docs_link'; diff --git a/x-pack/plugins/infra/public/components/lens/lens_chart.tsx b/x-pack/plugins/infra/public/components/lens/lens_chart.tsx new file mode 100644 index 0000000000000..2d4b599d56de2 --- /dev/null +++ b/x-pack/plugins/infra/public/components/lens/lens_chart.tsx @@ -0,0 +1,110 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { CSSProperties, useMemo } from 'react'; +import { EuiPanel, EuiToolTip, type EuiPanelProps } from '@elastic/eui'; +import { Action } from '@kbn/ui-actions-plugin/public'; +import { css } from '@emotion/react'; +import { useLensAttributes, type UseLensAttributesParams } from '../../hooks/use_lens_attributes'; +import type { BaseChartProps } from './types'; +import type { TooltipContentProps } from './metric_explanation/tooltip_content'; +import { LensWrapper } from './lens_wrapper'; +import { ChartLoadError } from './chart_load_error'; + +const MIN_HEIGHT = 300; + +export type LensChartProps = UseLensAttributesParams & + BaseChartProps & + Pick & { + toolTip?: React.ReactElement; + }; + +export const LensChart = ({ + id, + borderRadius, + dateRange, + filters, + hidePanelTitles, + lastReloadRequestTime, + query, + onBrushEnd, + overrides, + toolTip, + disableTriggers = false, + height = MIN_HEIGHT, + loading = false, + ...lensAttributesParams +}: LensChartProps) => { + const { formula, attributes, getExtraActions, error } = useLensAttributes({ + ...lensAttributesParams, + }); + + const isLoading = loading || !attributes; + + const extraActions: Action[] = useMemo( + () => + getExtraActions({ + timeRange: dateRange, + query, + filters, + }), + [dateRange, filters, getExtraActions, query] + ); + + const sytle: CSSProperties = useMemo(() => ({ height }), [height]); + + const Lens = ( + + ); + + const getContent = () => { + if (!toolTip) { + return Lens; + } + + return ( + + {Lens} + + ); + }; + + return ( + + {error ? : getContent()} + + ); +}; diff --git a/x-pack/plugins/infra/public/components/lens/lens_wrapper.tsx b/x-pack/plugins/infra/public/components/lens/lens_wrapper.tsx index dc3c11dccacc0..f203c9c344797 100644 --- a/x-pack/plugins/infra/public/components/lens/lens_wrapper.tsx +++ b/x-pack/plugins/infra/public/components/lens/lens_wrapper.tsx @@ -9,7 +9,8 @@ import type { Action } from '@kbn/ui-actions-plugin/public'; import { ViewMode } from '@kbn/embeddable-plugin/public'; import type { TimeRange } from '@kbn/es-query'; import { TypedLensByValueInput } from '@kbn/lens-plugin/public'; -import { euiStyled } from '@kbn/kibana-react-plugin/common'; +import { css } from '@emotion/react'; +import { useEuiTheme } from '@elastic/eui'; import { useKibanaContextForPlugin } from '../../hooks/use_kibana'; import { ChartLoadingProgress, ChartPlaceholder } from './chart_placeholder'; import { parseDateRange } from '../../utils/datemath'; @@ -30,10 +31,11 @@ export const LensWrapper = ({ dateRange, filters, lastReloadRequestTime, - loading, + loading = false, query, ...props }: LensWrapperProps) => { + const { euiTheme } = useEuiTheme(); const [intersectionObserverEntry, setIntersectionObserverEntry] = useState(); const [embeddableLoaded, setEmbeddableLoaded] = useState(false); @@ -96,11 +98,25 @@ export const LensWrapper = ({ return { from, to }; }, [state.dateRange]); - const isLoading = loading || !state.attributes; return ( - +
    <> {isLoading && !embeddableLoaded ? ( @@ -120,7 +136,7 @@ export const LensWrapper = ({ )} - +
    ); }; @@ -142,13 +158,3 @@ const EmbeddableComponentMemo = React.memo( return ; } ); - -const Container = euiStyled.div` - position: relative; - border-radius: ${({ theme }) => theme.eui.euiSizeS}; - overflow: hidden; - height: 100%; - .echLegend .echLegendList { - display: flex; - } -`; diff --git a/x-pack/plugins/infra/public/components/lens/metric_explanation/tooltip_content.tsx b/x-pack/plugins/infra/public/components/lens/metric_explanation/tooltip_content.tsx index fd46700130ee4..52459e70e2b05 100644 --- a/x-pack/plugins/infra/public/components/lens/metric_explanation/tooltip_content.tsx +++ b/x-pack/plugins/infra/public/components/lens/metric_explanation/tooltip_content.tsx @@ -11,14 +11,14 @@ import { css } from '@emotion/react'; import { FormattedMessage } from '@kbn/i18n-react'; import { HOST_METRICS_DOC_HREF } from '../../../common/visualizations/constants'; -interface Props extends Pick, 'style'> { +export interface TooltipContentProps extends Pick, 'style'> { description: string; formula?: string; showDocumentationLink?: boolean; } export const TooltipContent = React.memo( - ({ description, formula, showDocumentationLink = false, style }: Props) => { + ({ description, formula, showDocumentationLink = false, style }: TooltipContentProps) => { const onClick = (e: React.MouseEvent) => { e.stopPropagation(); }; diff --git a/x-pack/plugins/infra/public/components/lens/types.ts b/x-pack/plugins/infra/public/components/lens/types.ts new file mode 100644 index 0000000000000..8a4791de8cdf5 --- /dev/null +++ b/x-pack/plugins/infra/public/components/lens/types.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DataView } from '@kbn/data-views-plugin/public'; +import type { LensWrapperProps } from './lens_wrapper'; + +export type BaseChartProps = Pick< + LensWrapperProps, + | 'id' + | 'dateRange' + | 'disableTriggers' + | 'filters' + | 'hidePanelTitles' + | 'lastReloadRequestTime' + | 'loading' + | 'overrides' + | 'onBrushEnd' + | 'query' + | 'title' +> & { + dataView?: DataView; + height?: number; +}; diff --git a/x-pack/plugins/infra/public/hooks/use_lens_attributes.ts b/x-pack/plugins/infra/public/hooks/use_lens_attributes.ts index 721bf5669d203..6f3ae0cf37aff 100644 --- a/x-pack/plugins/infra/public/hooks/use_lens_attributes.ts +++ b/x-pack/plugins/infra/public/hooks/use_lens_attributes.ts @@ -68,7 +68,9 @@ interface UseLensAttributesMetricChartParams visualizationType: 'lnsMetric'; } -type UseLensAttributesParams = UseLensAttributesXYChartParams | UseLensAttributesMetricChartParams; +export type UseLensAttributesParams = + | UseLensAttributesXYChartParams + | UseLensAttributesMetricChartParams; export const useLensAttributes = ({ dataView, diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/chart/metric_chart_wrapper.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/chart/metric_chart_wrapper.tsx index 97be988142aa0..e78aae020b46b 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/chart/metric_chart_wrapper.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/chart/metric_chart_wrapper.tsx @@ -6,8 +6,8 @@ */ import React, { useEffect, useRef, CSSProperties } from 'react'; import { Chart, Metric, type MetricWNumber, type MetricWTrend } from '@elastic/charts'; -import { EuiPanel, EuiToolTip } from '@elastic/eui'; -import styled from 'styled-components'; +import { EuiPanel, EuiToolTip, useEuiTheme } from '@elastic/eui'; +import { css } from '@emotion/react'; import { ChartPlaceholder } from '../../../../../components/lens'; export interface Props extends Pick { @@ -16,11 +16,11 @@ export interface Props extends Pick { + const euiTheme = useEuiTheme(); const loadedOnce = useRef(false); useEffect(() => { @@ -42,7 +42,7 @@ export const MetricChartWrapper = React.memo( }; return ( - + {loading && !loadedOnce.current ? ( ) : ( @@ -52,19 +52,20 @@ export const MetricChartWrapper = React.memo( content={toolTip} anchorClassName="eui-fullWidth" > - + - + )} ); } ); - -const KPIChartStyled = styled(Chart)` - .echMetric { - border-radius: ${(p) => p.theme.eui.euiBorderRadius}; - pointer-events: none; - } -`; diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/hosts_tile.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/hosts_tile.tsx index 0571733b80034..f38e6772a3c84 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/hosts_tile.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/hosts_tile.tsx @@ -6,7 +6,6 @@ */ import { i18n } from '@kbn/i18n'; import React from 'react'; -import { KPIChartProps } from '../../../../../common/visualizations/lens/dashboards/host/kpi_grid_config'; import { hostLensFormulas } from '../../../../../common/visualizations'; import { useHostCountContext } from '../../hooks/use_host_count'; import { useUnifiedSearchContext } from '../../hooks/use_unified_search'; @@ -16,21 +15,20 @@ import { type Props, MetricChartWrapper } from '../chart/metric_chart_wrapper'; import { TooltipContent } from '../../../../../components/lens'; const HOSTS_CHART: Omit = { - id: `metric-hostCount`, + id: 'hostsViewKPI-hostsCount', color: '#6DCCB1', - title: i18n.translate('xpack.infra.hostsViewPage.metricTrend.hostCount.title', { + title: i18n.translate('xpack.infra.hostsViewPage.kpi.hostCount.title', { defaultMessage: 'Hosts', }), - ['data-test-subj']: 'hostsViewKPI-hostsCount', }; -export const HostsTile = ({ style }: Pick) => { +export const HostsTile = ({ height }: { height: number }) => { const { data: hostCountData, isRequestRunning: hostCountLoading } = useHostCountContext(); const { searchCriteria } = useUnifiedSearchContext(); const getSubtitle = () => { return searchCriteria.limit < (hostCountData?.count.value ?? 0) - ? i18n.translate('xpack.infra.hostsViewPage.metricTrend.subtitle.hostCount.limit', { + ? i18n.translate('xpack.infra.hostsViewPage.kpi.subtitle.hostCount.limit', { defaultMessage: 'Limited to {limit}', values: { limit: searchCriteria.limit, @@ -42,7 +40,7 @@ export const HostsTile = ({ style }: Pick) => { return ( { return ( @@ -26,11 +24,11 @@ export const KPIGrid = () => { - + {KPI_CHARTS.map((chartProp, index) => ( - + ))} diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/tile.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/tile.tsx index 950e74478dd4b..7211c89ce9071 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/tile.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/kpis/tile.tsx @@ -4,53 +4,47 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useMemo, useCallback } from 'react'; - +import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { BrushTriggerEvent } from '@kbn/charts-plugin/public'; -import { EuiIcon, EuiPanel, EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip } from '@elastic/eui'; -import styled from 'styled-components'; -import { Action } from '@kbn/ui-actions-plugin/public'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { LensWrapper, TooltipContent } from '../../../../../components/lens'; -import { KPIChartProps } from '../../../../../common/visualizations/lens/dashboards/host/kpi_grid_config'; +import { LensChart, TooltipContent } from '../../../../../components/lens'; +import { + type KPIChartProps, + AVERAGE_SUBTITLE, +} from '../../../../../common/visualizations/lens/dashboards/host/kpi_grid_config'; import { buildCombinedHostsFilter } from '../../../../../utils/filters/build'; -import { useLensAttributes } from '../../../../../hooks/use_lens_attributes'; import { useMetricsDataViewContext } from '../../hooks/use_data_view'; import { useUnifiedSearchContext } from '../../hooks/use_unified_search'; import { useHostsViewContext } from '../../hooks/use_hosts_view'; import { useHostCountContext } from '../../hooks/use_host_count'; import { useAfterLoadedState } from '../../hooks/use_after_loaded_state'; -import { KPI_CHART_MIN_HEIGHT } from '../../constants'; -export const Tile = ({ id, title, layers, style, toolTip }: KPIChartProps) => { - const { searchCriteria, onSubmit } = useUnifiedSearchContext(); +export const Tile = ({ + id, + title, + layers, + toolTip, + height, +}: KPIChartProps & { height: number }) => { + const { searchCriteria } = useUnifiedSearchContext(); const { dataView } = useMetricsDataViewContext(); const { requestTs, hostNodes, loading: hostsLoading } = useHostsViewContext(); const { data: hostCountData, isRequestRunning: hostCountLoading } = useHostCountContext(); const shouldUseSearchCriteria = hostNodes.length === 0; + const loading = hostsLoading || hostCountLoading; + const getSubtitle = () => { return searchCriteria.limit < (hostCountData?.count.value ?? 0) - ? i18n.translate('xpack.infra.hostsViewPage.metricTrend.subtitle.average.limit', { + ? i18n.translate('xpack.infra.hostsViewPage.kpi.subtitle.average.limit', { defaultMessage: 'Average (of {limit} hosts)', values: { limit: searchCriteria.limit, }, }) - : i18n.translate('xpack.infra.hostsViewPage.metricTrend.subtitle.average', { - defaultMessage: 'Average', - }); + : AVERAGE_SUBTITLE; }; - const { formula, attributes, getExtraActions, error } = useLensAttributes({ - dataView, - title, - layers: { ...layers, options: { ...layers.options, subtitle: getSubtitle() } }, - visualizationType: 'lnsMetric', - }); - const filters = useMemo(() => { return shouldUseSearchCriteria ? searchCriteria.filters @@ -61,106 +55,33 @@ export const Tile = ({ id, title, layers, style, toolTip }: KPIChartProps) => { dataView, }), ]; - }, [shouldUseSearchCriteria, searchCriteria.filters, hostNodes, dataView]); - - const loading = hostsLoading || !attributes || hostCountLoading; + }, [dataView, hostNodes, searchCriteria.filters, shouldUseSearchCriteria]); - // prevents requestTs and serchCriteria states from reloading the chart - // we want it to reload only once the host count and table have finished loading + // prevents requestTs and searchCriteria state from reloading the chart + // we want it to reload only once the table has finished loading const { afterLoadedState } = useAfterLoadedState(loading, { - attributes, lastReloadRequestTime: requestTs, - ...searchCriteria, + dateRange: searchCriteria.dateRange, + query: shouldUseSearchCriteria ? searchCriteria.query : undefined, filters, }); - const extraActions: Action[] = useMemo( - () => - getExtraActions({ - timeRange: afterLoadedState.dateRange, - query: shouldUseSearchCriteria ? afterLoadedState.query : undefined, - filters, - }), - [ - afterLoadedState.dateRange, - afterLoadedState.query, - filters, - getExtraActions, - shouldUseSearchCriteria, - ] - ); - - const handleBrushEnd = useCallback( - ({ range }: BrushTriggerEvent['data']) => { - const [min, max] = range; - onSubmit({ - dateRange: { - from: new Date(min).toISOString(), - to: new Date(max).toISOString(), - mode: 'absolute', - }, - }); - }, - [onSubmit] - ); - return ( - - {error ? ( - - - - - - - - - - - ) : ( - } - anchorClassName="eui-fullWidth" - > -
    - -
    -
    - )} -
    + } + visualizationType="lnsMetric" + disableTriggers + hidePanelTitles + /> ); }; - -const EuiPanelStyled = styled(EuiPanel)` - min-height: ${KPI_CHART_MIN_HEIGHT}px; - .echMetric { - border-radius: ${({ theme }) => theme.eui.euiBorderRadius}; - pointer-events: none; - } -`; diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/metrics/metric_chart.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/metrics/metric_chart.tsx index b31e5c1cb08d2..c0f05c55d1e9e 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/metrics/metric_chart.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/metrics/metric_chart.tsx @@ -4,59 +4,35 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { CSSProperties, useCallback, useMemo } from 'react'; -import { Action } from '@kbn/ui-actions-plugin/public'; -import { BrushTriggerEvent } from '@kbn/charts-plugin/public'; -import { EuiIcon, EuiPanel, EuiFlexGroup, EuiFlexItem, EuiText, useEuiTheme } from '@elastic/eui'; -import { css } from '@emotion/react'; -import { TypedLensByValueInput } from '@kbn/lens-plugin/public'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { LensWrapper } from '../../../../../../components/lens'; -import { useLensAttributes, Layer } from '../../../../../../hooks/use_lens_attributes'; +import React, { useMemo } from 'react'; +import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; +import { LensChart } from '../../../../../../components/lens'; +import type { Layer } from '../../../../../../hooks/use_lens_attributes'; import { useMetricsDataViewContext } from '../../../hooks/use_data_view'; import { useUnifiedSearchContext } from '../../../hooks/use_unified_search'; -import { FormulaConfig, XYLayerOptions } from '../../../../../../common/visualizations'; +import type { FormulaConfig, XYLayerOptions } from '../../../../../../common/visualizations'; import { useHostsViewContext } from '../../../hooks/use_hosts_view'; import { buildCombinedHostsFilter } from '../../../../../../utils/filters/build'; import { useHostsTableContext } from '../../../hooks/use_hosts_table'; import { useAfterLoadedState } from '../../../hooks/use_after_loaded_state'; -import { METRIC_CHART_MIN_HEIGHT } from '../../../constants'; +import { METRIC_CHART_HEIGHT } from '../../../constants'; export interface MetricChartProps extends Pick { title: string; layers: Array>; } -const lensStyle: CSSProperties = { - height: METRIC_CHART_MIN_HEIGHT, -}; - export const MetricChart = ({ id, title, layers, overrides }: MetricChartProps) => { - const { euiTheme } = useEuiTheme(); - const { searchCriteria, onSubmit } = useUnifiedSearchContext(); + const { searchCriteria } = useUnifiedSearchContext(); const { dataView } = useMetricsDataViewContext(); const { requestTs, loading } = useHostsViewContext(); const { currentPage } = useHostsTableContext(); const shouldUseSearchCriteria = currentPage.length === 0; - // prevents requestTs and serchCriteria states from reloading the chart - // we want it to reload only once the table has finished loading - const { afterLoadedState } = useAfterLoadedState(loading, { - lastReloadRequestTime: requestTs, - ...searchCriteria, - }); - - const { attributes, getExtraActions, error } = useLensAttributes({ - dataView, - layers, - title, - visualizationType: 'lnsXY', - }); - const filters = useMemo(() => { return shouldUseSearchCriteria - ? afterLoadedState.filters + ? searchCriteria.filters : [ buildCombinedHostsFilter({ field: 'host.name', @@ -64,85 +40,31 @@ export const MetricChart = ({ id, title, layers, overrides }: MetricChartProps) dataView, }), ]; - }, [afterLoadedState.filters, currentPage, dataView, shouldUseSearchCriteria]); - - const extraActions: Action[] = useMemo( - () => - getExtraActions({ - timeRange: afterLoadedState.dateRange, - query: shouldUseSearchCriteria ? afterLoadedState.query : undefined, - filters, - }), - [ - afterLoadedState.dateRange, - afterLoadedState.query, - filters, - getExtraActions, - shouldUseSearchCriteria, - ] - ); + }, [searchCriteria.filters, currentPage, dataView, shouldUseSearchCriteria]); - const handleBrushEnd = useCallback( - ({ range }: BrushTriggerEvent['data']) => { - const [min, max] = range; - onSubmit({ - dateRange: { - from: new Date(min).toISOString(), - to: new Date(max).toISOString(), - mode: 'absolute', - }, - }); - }, - [onSubmit] - ); + // prevents requestTs and searchCriteria state from reloading the chart + // we want it to reload only once the table has finished loading + const { afterLoadedState } = useAfterLoadedState(loading, { + lastReloadRequestTime: requestTs, + dateRange: searchCriteria.dateRange, + query: shouldUseSearchCriteria ? searchCriteria.query : undefined, + }); return ( - - {error ? ( - - - - - - - - - - - ) : ( - - )} - + dataView={dataView} + dateRange={afterLoadedState.dateRange} + height={METRIC_CHART_HEIGHT} + layers={layers} + lastReloadRequestTime={afterLoadedState.lastReloadRequestTime} + loading={loading} + filters={filters} + query={afterLoadedState.query} + title={title} + overrides={overrides} + visualizationType="lnsXY" + /> ); }; diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/constants.ts b/x-pack/plugins/infra/public/pages/metrics/hosts/constants.ts index 296d779e8a0fd..aace07448692e 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/constants.ts +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/constants.ts @@ -15,8 +15,7 @@ export const DEFAULT_PAGE_SIZE = 10; export const LOCAL_STORAGE_HOST_LIMIT_KEY = 'hostsView:hostLimitSelection'; export const LOCAL_STORAGE_PAGE_SIZE_KEY = 'hostsView:pageSizeSelection'; -export const KPI_CHART_MIN_HEIGHT = 150; -export const METRIC_CHART_MIN_HEIGHT = 300; +export const METRIC_CHART_HEIGHT = 300; export const HOST_LIMIT_OPTIONS = [50, 100, 500] as const; export const HOST_METRICS_DOC_HREF = 'https://ela.st/docs-infra-host-metrics'; diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index fafb56aed9727..11f22770bec5f 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -18661,8 +18661,8 @@ "xpack.infra.homePage.toolbar.showingLastOneMinuteDataText": "Dernières {duration} de données pour l'heure sélectionnée", "xpack.infra.hostsViewPage.errorOnCreateOrLoadDataview": "Une erreur s’est produite lors de la création d’une vue de données : {metricAlias}. Essayez de recharger la page.", "xpack.infra.hostsViewPage.landing.calloutRoleClarificationWithDocsLink": "Un rôle avec accès aux paramètres avancés dans Kibana sera nécessaire. {docsLink}", - "xpack.infra.hostsViewPage.metricTrend.subtitle.average.limit": "Moyenne (de {limit} hôtes)", - "xpack.infra.hostsViewPage.metricTrend.subtitle.hostCount.limit": "Limité à {limit}", + "xpack.infra.hostsViewPage.kpi.subtitle.average.limit": "Moyenne (de {limit} hôtes)", + "xpack.infra.hostsViewPage.kpi.subtitle.hostCount.limit": "Limité à {limit}", "xpack.infra.hostsViewPage.table.selectedHostsButton": "Sélection effectuée de {selectedHostsCount} {selectedHostsCount, plural, =1 {hôte} one {hôtes} many {hôtes} other {hôtes}}", "xpack.infra.hostsViewPage.table.tooltip.documentationLabel": "Pour en savoir plus, consultez {documentation}", "xpack.infra.inventoryTimeline.header": "Moyenne {metricLabel}", @@ -18801,6 +18801,11 @@ "xpack.infra.assetDetailsEmbeddable.description": "Ajoutez une vue de détails de ressource.", "xpack.infra.assetDetailsEmbeddable.displayName": "Détails de ressource", "xpack.infra.assetDetailsEmbeddable.title": "Détails de ressource", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.cpuUsage.title": "Utilisation CPU", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.diskSpaceUsage.title": "Utilisation de l’espace disque", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.memoryUsage.title": "Utilisation mémoire", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.normalizedLoad1m.title": "Charge normalisée", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.subtitle.average": "Moyenne", "xpack.infra.bottomDrawer.kubernetesDashboardsLink": "Tableaux de bord Kubernetes", "xpack.infra.chartSection.missingMetricDataBody": "Les données de ce graphique sont manquantes.", "xpack.infra.chartSection.missingMetricDataText": "Données manquantes", @@ -18885,6 +18890,7 @@ "xpack.infra.hostsViewPage.errorOnCreateOrLoadDataviewTitle": "Erreur lors de la création d'un Data View", "xpack.infra.hostsViewPage.hostLimit": "Limite de l'hôte", "xpack.infra.hostsViewPage.hostLimit.tooltip": "Pour garantir des performances de recherche plus rapides, le nombre d'hôtes retournés est limité.", + "xpack.infra.hostsViewPage.kpi.hostCount.title": "Hôtes", "xpack.infra.hostsViewPage.landing.calloutReachOutToYourKibanaAdministrator": "Votre rôle d'utilisateur ne dispose pas des privilèges suffisants pour activer cette fonctionnalité - veuillez \n contacter votre administrateur Kibana et lui demander de visiter cette page pour activer la fonctionnalité.", "xpack.infra.hostsViewPage.landing.enableHostsView": "Activer la vue des hôtes", "xpack.infra.hostsViewPage.landing.introMessage": "Bienvenue sur la fonctionnalité \"Hôtes\", désormais disponible en version bêta. Avec ce puissant outil, \n vous pouvez facilement voir et analyser vos hôtes et identifier tout problème afin de les corriger rapidement. \n Obtenez une vue détaillée des indicateurs pour vos hôtes afin de savoir lesquels déclenchent le plus d’alertes, et filtrez \n les hôtes que vous voulez analyser à l'aide de tout filtre KQL ainsi que de répartitions simples comme le fournisseur cloud et \n le système d'exploitation.", @@ -18901,12 +18907,6 @@ "xpack.infra.hostsViewPage.metrics.tooltip.normalizedLoad1m": "Moyenne de la charge sur 1 minute normalisée par le nombre de cœurs de processeur. ", "xpack.infra.hostsViewPage.metrics.tooltip.rx": "Nombre d'octets qui ont été reçus par seconde sur les interfaces publiques des hôtes.", "xpack.infra.hostsViewPage.metrics.tooltip.tx": "Nombre d'octets envoyés par seconde sur les interfaces publiques des hôtes.", - "xpack.infra.hostsViewPage.metricTrend.cpuUsage.title": "Utilisation CPU", - "xpack.infra.hostsViewPage.metricTrend.diskSpaceUsage.title": "Utilisation de l’espace disque", - "xpack.infra.hostsViewPage.metricTrend.hostCount.title": "Hôtes", - "xpack.infra.hostsViewPage.metricTrend.memoryUsage.title": "Utilisation mémoire", - "xpack.infra.hostsViewPage.metricTrend.normalizedLoad1m.title": "Charge normalisée", - "xpack.infra.hostsViewPage.metricTrend.subtitle.average": "Moyenne", "xpack.infra.hostsViewPage.table.addFilter": "Ajouter un filtre", "xpack.infra.hostsViewPage.table.cpuUsageColumnHeader": "Utilisation CPU (moy.)", "xpack.infra.hostsViewPage.table.diskSpaceUsageColumnHeader": "Utilisation de l’espace disque (moy.)", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 66ea13be17908..15960dbd920ed 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -18675,8 +18675,8 @@ "xpack.infra.homePage.toolbar.showingLastOneMinuteDataText": "指定期間のデータの最後の{duration}", "xpack.infra.hostsViewPage.errorOnCreateOrLoadDataview": "データビューの作成中にエラーが発生しました:{metricAlias}。ページを再読み込みしてください。", "xpack.infra.hostsViewPage.landing.calloutRoleClarificationWithDocsLink": "Kibanaの高度な設定にアクセスできるロールが必要です。{docsLink}", - "xpack.infra.hostsViewPage.metricTrend.subtitle.average.limit": "({limit}ホストの)平均", - "xpack.infra.hostsViewPage.metricTrend.subtitle.hostCount.limit": "{limit}に制限", + "xpack.infra.hostsViewPage.kpi.subtitle.average.limit": "({limit}ホストの)平均", + "xpack.infra.hostsViewPage.kpi.subtitle.hostCount.limit": "{limit}に制限", "xpack.infra.hostsViewPage.table.selectedHostsButton": "{selectedHostsCount}件の{selectedHostsCount, plural, =1 {ホスト} other {ホスト}}が選択済み", "xpack.infra.hostsViewPage.table.tooltip.documentationLabel": "詳細については、{documentation}を参照してください。", "xpack.infra.inventoryTimeline.header": "平均{metricLabel}", @@ -18815,6 +18815,11 @@ "xpack.infra.assetDetailsEmbeddable.description": "アセット詳細ビューを追加します。", "xpack.infra.assetDetailsEmbeddable.displayName": "アセット詳細", "xpack.infra.assetDetailsEmbeddable.title": "アセット詳細", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.cpuUsage.title": "CPU使用状況", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.diskSpaceUsage.title": "ディスク容量使用状況", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.memoryUsage.title": "メモリー使用状況", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.normalizedLoad1m.title": "正規化された負荷", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.subtitle.average": "平均", "xpack.infra.bottomDrawer.kubernetesDashboardsLink": "Kubernetesダッシュボード", "xpack.infra.chartSection.missingMetricDataBody": "このチャートはデータが欠けています。", "xpack.infra.chartSection.missingMetricDataText": "データが欠けています", @@ -18899,6 +18904,7 @@ "xpack.infra.hostsViewPage.errorOnCreateOrLoadDataviewTitle": "データビューの作成エラー", "xpack.infra.hostsViewPage.hostLimit": "ホスト制限", "xpack.infra.hostsViewPage.hostLimit.tooltip": "クエリパフォーマンスを確実に高めるために、返されるホスト数には制限があります", + "xpack.infra.hostsViewPage.kpi.hostCount.title": "ホスト", "xpack.infra.hostsViewPage.landing.calloutReachOutToYourKibanaAdministrator": "ユーザーロールには、この機能を有効にするための十分な権限がありません。 \n この機能を有効にするために、Kibana管理者に連絡して、このページにアクセスするように依頼してください。", "xpack.infra.hostsViewPage.landing.enableHostsView": "ホストビューを有効化", "xpack.infra.hostsViewPage.landing.introMessage": "「ホスト」機能へようこそ!ベータ版でご利用いただけるようになりました。この強力なツールを使用すると、\n ホストを簡単に表示、分析し、あらゆる問題を特定して、迅速に対処できます。\n ホストのメトリックを詳細に表示し、どのメトリックが最も多くのアラートをトリガーしているかを確認し、 \n 任意のKQLフィルターを使用して分析したいホストや、クラウドプロバイダーやオペレーティングシステムといった簡単な内訳をフィルターできます \n 。", @@ -18915,12 +18921,6 @@ "xpack.infra.hostsViewPage.metrics.tooltip.normalizedLoad1m": "CPUコア数で正規化した1分間の負荷平均。", "xpack.infra.hostsViewPage.metrics.tooltip.rx": "ホストのパブリックインターフェースで1秒間に受信したバイト数。", "xpack.infra.hostsViewPage.metrics.tooltip.tx": "ホストのパブリックインターフェースで1秒間に送信したバイト数。", - "xpack.infra.hostsViewPage.metricTrend.cpuUsage.title": "CPU使用状況", - "xpack.infra.hostsViewPage.metricTrend.diskSpaceUsage.title": "ディスク容量使用状況", - "xpack.infra.hostsViewPage.metricTrend.hostCount.title": "ホスト", - "xpack.infra.hostsViewPage.metricTrend.memoryUsage.title": "メモリー使用状況", - "xpack.infra.hostsViewPage.metricTrend.normalizedLoad1m.title": "正規化された負荷", - "xpack.infra.hostsViewPage.metricTrend.subtitle.average": "平均", "xpack.infra.hostsViewPage.table.addFilter": "フィルターを追加します", "xpack.infra.hostsViewPage.table.cpuUsageColumnHeader": "CPU使用状況(平均)", "xpack.infra.hostsViewPage.table.diskSpaceUsageColumnHeader": "ディスク容量使用状況(平均)", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 7b86064bc4322..0cff43087c67f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -18675,8 +18675,8 @@ "xpack.infra.homePage.toolbar.showingLastOneMinuteDataText": "选定时间过去 {duration}的数据", "xpack.infra.hostsViewPage.errorOnCreateOrLoadDataview": "尝试创建以下数据视图时出错:{metricAlias}。尝试重新加载该页面。", "xpack.infra.hostsViewPage.landing.calloutRoleClarificationWithDocsLink": "他们将需要有权访问 Kibana 中的高级设置的角色。{docsLink}", - "xpack.infra.hostsViewPage.metricTrend.subtitle.average.limit": "平均值(属于 {limit} 台主机)", - "xpack.infra.hostsViewPage.metricTrend.subtitle.hostCount.limit": "限定为 {limit}", + "xpack.infra.hostsViewPage.kpi.subtitle.average.limit": "平均值(属于 {limit} 台主机)", + "xpack.infra.hostsViewPage.kpi.subtitle.hostCount.limit": "限定为 {limit}", "xpack.infra.hostsViewPage.table.selectedHostsButton": "已选定 {selectedHostsCount} 个{selectedHostsCount, plural, =1 {主机} other {主机}}", "xpack.infra.hostsViewPage.table.tooltip.documentationLabel": "请参阅 {documentation} 了解更多信息", "xpack.infra.inventoryTimeline.header": "平均值 {metricLabel}", @@ -18815,6 +18815,11 @@ "xpack.infra.assetDetailsEmbeddable.description": "添加资产详情视图。", "xpack.infra.assetDetailsEmbeddable.displayName": "资产详情", "xpack.infra.assetDetailsEmbeddable.title": "资产详情", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.cpuUsage.title": "CPU 使用率", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.diskSpaceUsage.title": "磁盘空间使用率", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.memoryUsage.title": "内存利用率", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.normalizedLoad1m.title": "标准化负载", + "xpack.infra.assetDetailsEmbeddable.overview.kpi.subtitle.average": "平均值", "xpack.infra.bottomDrawer.kubernetesDashboardsLink": "Kubernetes 仪表板", "xpack.infra.chartSection.missingMetricDataBody": "此图表的数据缺失。", "xpack.infra.chartSection.missingMetricDataText": "缺失数据", @@ -18899,6 +18904,7 @@ "xpack.infra.hostsViewPage.errorOnCreateOrLoadDataviewTitle": "创建数据视图时出错", "xpack.infra.hostsViewPage.hostLimit": "主机限制", "xpack.infra.hostsViewPage.hostLimit.tooltip": "为确保更快的查询性能,对返回的主机数量实施了限制", + "xpack.infra.hostsViewPage.kpi.hostCount.title": "主机", "xpack.infra.hostsViewPage.landing.calloutReachOutToYourKibanaAdministrator": "您的用户角色权限不足,无法启用此功能 - 请 \n 联系您的 Kibana 管理员,要求他们访问此页面以启用该功能。", "xpack.infra.hostsViewPage.landing.enableHostsView": "启用主机视图", "xpack.infra.hostsViewPage.landing.introMessage": "欢迎使用“主机”功能,该功能现在为公测版!使用这个强大的工具,\n 您可以轻松查看并分析主机,并确定任何问题以便快速予以解决。\n 获取您主机的详细指标视图,了解哪些指标触发了大多数告警, \n 并使用任何 KQL 筛选以及云提供商和操作系统等常见细目筛选 \n 您要分析的主机。", @@ -18915,12 +18921,6 @@ "xpack.infra.hostsViewPage.metrics.tooltip.normalizedLoad1m": "1 分钟负载平均值,按 CPU 核心数进行标准化。", "xpack.infra.hostsViewPage.metrics.tooltip.rx": "主机的公共接口上每秒接收的字节数。", "xpack.infra.hostsViewPage.metrics.tooltip.tx": "主机的公共接口上每秒发送的字节数。", - "xpack.infra.hostsViewPage.metricTrend.cpuUsage.title": "CPU 使用率", - "xpack.infra.hostsViewPage.metricTrend.diskSpaceUsage.title": "磁盘空间使用率", - "xpack.infra.hostsViewPage.metricTrend.hostCount.title": "主机", - "xpack.infra.hostsViewPage.metricTrend.memoryUsage.title": "内存利用率", - "xpack.infra.hostsViewPage.metricTrend.normalizedLoad1m.title": "标准化负载", - "xpack.infra.hostsViewPage.metricTrend.subtitle.average": "平均值", "xpack.infra.hostsViewPage.table.addFilter": "添加筛选", "xpack.infra.hostsViewPage.table.cpuUsageColumnHeader": "CPU 使用率(平均值)", "xpack.infra.hostsViewPage.table.diskSpaceUsageColumnHeader": "磁盘空间使用率(平均值)", diff --git a/x-pack/test/functional/page_objects/infra_hosts_view.ts b/x-pack/test/functional/page_objects/infra_hosts_view.ts index b56b57843cd3b..00ae0af08cf07 100644 --- a/x-pack/test/functional/page_objects/infra_hosts_view.ts +++ b/x-pack/test/functional/page_objects/infra_hosts_view.ts @@ -206,7 +206,7 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) { // Flyout Tabs async getAssetDetailsKPITileValue(type: string) { const container = await testSubjects.find('assetDetailsKPIGrid'); - const element = await container.findByTestSubject(`assetDetailsKPI-${type}`); + const element = await container.findByTestSubject(`infraAssetDetailsKPI${type}`); const div = await element.findByClassName('echMetricText__value'); return div.getAttribute('title'); }, @@ -229,7 +229,7 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) { async getAssetDetailsMetricsCharts() { const container = await testSubjects.find('assetDetailsMetricsChartGrid'); - return container.findAllByCssSelector('[data-test-subj*="assetDetailsMetricsChart"]'); + return container.findAllByCssSelector('[data-test-subj*="infraAssetDetailsMetricsChart"]'); }, getMetadataTab() { From c0fe4ac2eb1b9a91b7f331173e38be1c8c1dbffb Mon Sep 17 00:00:00 2001 From: Paulo Henrique Date: Wed, 9 Aug 2023 08:19:02 -0700 Subject: [PATCH 12/41] [Cloud Security] [Findings] [Misconfigurations] [Alerts] - Create detection rule (#162750) Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../common/api/create_detection_rule.ts | 59 ++++++++ .../public/components/take_action.tsx | 129 ++++++++++++++++++ .../public/components/test_subjects.ts | 5 +- .../findings_flyout/findings_flyout.tsx | 11 +- .../create_detection_rule_from_finding.ts | 99 ++++++++++++++ .../cloud_security_posture/tsconfig.json | 2 +- 6 files changed, 302 insertions(+), 3 deletions(-) create mode 100644 x-pack/plugins/cloud_security_posture/public/common/api/create_detection_rule.ts create mode 100644 x-pack/plugins/cloud_security_posture/public/components/take_action.tsx create mode 100644 x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_finding.ts diff --git a/x-pack/plugins/cloud_security_posture/public/common/api/create_detection_rule.ts b/x-pack/plugins/cloud_security_posture/public/common/api/create_detection_rule.ts new file mode 100644 index 0000000000000..ef0aa3321f35e --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/common/api/create_detection_rule.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { HttpSetup } from '@kbn/core/public'; + +const DETECTION_ENGINE_URL = '/api/detection_engine' as const; +const DETECTION_ENGINE_RULES_URL = `${DETECTION_ENGINE_URL}/rules` as const; + +interface RuleCreateProps { + type: string; + language: string; + license: string; + author: string[]; + filters: any[]; + false_positives: any[]; + risk_score: number; + risk_score_mapping: any[]; + severity: string; + severity_mapping: any[]; + threat: any[]; + interval: string; + from: string; + to: string; + timestamp_override: string; + timestamp_override_fallback_disabled: boolean; + actions: any[]; + enabled: boolean; + alert_suppression: { + group_by: string[]; + missing_fields_strategy: string; + }; + index: string[]; + query: string; + references: string[]; + name: string; + description: string; + tags: string[]; +} + +export interface RuleResponse extends RuleCreateProps { + id: string; +} + +export const createDetectionRule = async ({ + http, + rule, +}: { + http: HttpSetup; + rule: RuleCreateProps; +}): Promise => { + const res = await http.post(DETECTION_ENGINE_RULES_URL, { + body: JSON.stringify(rule), + }); + + return res as RuleResponse; +}; diff --git a/x-pack/plugins/cloud_security_posture/public/components/take_action.tsx b/x-pack/plugins/cloud_security_posture/public/components/take_action.tsx new file mode 100644 index 0000000000000..57684d02fd157 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/components/take_action.tsx @@ -0,0 +1,129 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; +import { + EuiButton, + EuiContextMenuItem, + EuiContextMenuPanel, + EuiFlexGroup, + EuiFlexItem, + EuiPopover, + EuiText, + useGeneratedHtmlId, +} from '@elastic/eui'; +import { toMountPoint } from '@kbn/kibana-react-plugin/public'; +import type { HttpSetup } from '@kbn/core/public'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { CREATE_RULE_ACTION_SUBJ, TAKE_ACTION_SUBJ } from './test_subjects'; +import { useKibana } from '../common/hooks/use_kibana'; +import type { RuleResponse } from '../common/api/create_detection_rule'; + +const RULE_PAGE_PATH = '/app/security/rules/id/'; + +interface TakeActionProps { + createRuleFn: (http: HttpSetup) => Promise; +} +/* + * This component is used to create a detection rule from Flyout. + * It accepts a createRuleFn parameter which is used to create a rule in a generic way. + */ +export const TakeAction = ({ createRuleFn }: TakeActionProps) => { + const [isPopoverOpen, setPopoverOpen] = useState(false); + const [isLoading, setIsLoading] = useState(false); + const closePopover = () => { + setPopoverOpen(false); + }; + + const smallContextMenuPopoverId = useGeneratedHtmlId({ + prefix: 'smallContextMenuPopover', + }); + + const { http, notifications } = useKibana().services; + + const showSuccessToast = (ruleResponse: RuleResponse) => { + return notifications.toasts.addSuccess({ + toastLifeTimeMs: 10000, + color: 'success', + iconType: '', + text: toMountPoint( +
    + + {ruleResponse.name} + {` `} + + + + + + + + + + + + +
    + ), + }); + }; + + const button = ( + setPopoverOpen(!isPopoverOpen)} + > + + + ); + + return ( + + { + closePopover(); + setIsLoading(true); + const ruleResponse = await createRuleFn(http); + setIsLoading(false); + showSuccessToast(ruleResponse); + }} + data-test-subj={CREATE_RULE_ACTION_SUBJ} + > + + , + ]} + /> + + ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/components/test_subjects.ts b/x-pack/plugins/cloud_security_posture/public/components/test_subjects.ts index 638076818d3f0..a1fa5d985df3c 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/test_subjects.ts +++ b/x-pack/plugins/cloud_security_posture/public/components/test_subjects.ts @@ -32,4 +32,7 @@ export const NO_VULNERABILITIES_STATUS_TEST_SUBJ = { export const VULNERABILITIES_CONTAINER_TEST_SUBJ = 'vulnerabilities_container'; -export const VULNERABILITIES_CVSS_SCORE_BADGE_SUBJ = 'vuknerabilities_cvss_score_badge'; +export const VULNERABILITIES_CVSS_SCORE_BADGE_SUBJ = 'vulnerabilities_cvss_score_badge'; + +export const TAKE_ACTION_SUBJ = 'csp:take_action'; +export const CREATE_RULE_ACTION_SUBJ = 'csp:create_rule'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.tsx index f59463e00125f..2c59f360850d8 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/findings_flyout.tsx @@ -25,9 +25,11 @@ import { } from '@elastic/eui'; import { assertNever } from '@kbn/std'; import { i18n } from '@kbn/i18n'; +import type { HttpSetup } from '@kbn/core/public'; import cisLogoIcon from '../../../assets/icons/cis_logo.svg'; import { CspFinding } from '../../../../common/schemas/csp_finding'; import { CspEvaluationBadge } from '../../../components/csp_evaluation_badge'; +import { TakeAction } from '../../../components/take_action'; import { TableTab } from './table_tab'; import { JsonTab } from './json_tab'; import { OverviewTab } from './overview_tab'; @@ -36,6 +38,7 @@ import type { BenchmarkId } from '../../../../common/types'; import { CISBenchmarkIcon } from '../../../components/cis_benchmark_icon'; import { BenchmarkName } from '../../../../common/types'; import { FINDINGS_FLYOUT } from '../test_subjects'; +import { createDetectionRuleFromFinding } from '../utils/create_detection_rule_from_finding'; const tabs = [ { @@ -127,6 +130,9 @@ export const FindingsRuleFlyout = ({ }: FindingFlyoutProps) => { const [tab, setTab] = useState(tabs[0]); + const createMisconfigurationRuleFn = async (http: HttpSetup) => + await createDetectionRuleFromFinding(http, findings); + return ( @@ -160,7 +166,7 @@ export const FindingsRuleFlyout = ({ - + + + + diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_finding.ts b/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_finding.ts new file mode 100644 index 0000000000000..179ac6e27713c --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_finding.ts @@ -0,0 +1,99 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { HttpSetup } from '@kbn/core/public'; +import type { CspFinding } from '../../../../common/schemas/csp_finding'; +import { LATEST_FINDINGS_INDEX_DEFAULT_NS } from '../../../../common/constants'; +import { createDetectionRule } from '../../../common/api/create_detection_rule'; + +const DEFAULT_RULE_RISK_SCORE = 0; +const DEFAULT_RULE_SEVERITY = 'low'; +const DEFAULT_RULE_ENABLED = true; +const DEFAULT_RULE_AUTHOR = 'Elastic'; +const DEFAULT_RULE_LICENSE = 'Elastic License v2'; +const ALERT_SUPPRESSION_FIELD = 'resource.id'; +const ALERT_TIMESTAMP_FIELD = 'event.ingested'; + +enum AlertSuppressionMissingFieldsStrategy { + // per each document a separate alert will be created + DoNotSuppress = 'doNotSuppress', + // only one alert will be created per suppress by bucket + Suppress = 'suppress', +} + +const convertReferencesLinksToArray = (input: string | undefined) => { + if (!input) { + return []; + } + // Match all URLs in the input string using a regular expression + const matches = input.match(/(https?:\/\/\S+)/g); + + if (!matches) { + return []; + } + + // Remove the numbers and new lines + return matches.map((link) => link.replace(/^\d+\. /, '').replace(/\n/g, '')); +}; + +const STATIC_RULE_TAGS = ['Elastic', 'Cloud Security']; + +const generateMisconfigurationsTags = (finding: CspFinding) => { + return [STATIC_RULE_TAGS] + .concat(finding.rule.tags) + .concat( + finding.rule.benchmark.posture_type ? [finding.rule.benchmark.posture_type.toUpperCase()] : [] + ) + .flat(); +}; + +const generateMisconfigurationsRuleQuery = (finding: CspFinding) => { + return ` + rule.benchmark.rule_number: "${finding.rule.benchmark.rule_number}" + AND rule.benchmark.id: "${finding.rule.benchmark.id}" + AND result.evaluation: "failed" + `; +}; + +/* + * Creates a detection rule from a CspFinding + */ +export const createDetectionRuleFromFinding = async (http: HttpSetup, finding: CspFinding) => { + return await createDetectionRule({ + http, + rule: { + type: 'query', + language: 'kuery', + license: DEFAULT_RULE_LICENSE, + author: [DEFAULT_RULE_AUTHOR], + filters: [], + false_positives: [], + risk_score: DEFAULT_RULE_RISK_SCORE, + risk_score_mapping: [], + severity: DEFAULT_RULE_SEVERITY, + severity_mapping: [], + threat: [], + interval: '1h', + from: 'now-7200s', + to: 'now', + timestamp_override: ALERT_TIMESTAMP_FIELD, + timestamp_override_fallback_disabled: false, + actions: [], + enabled: DEFAULT_RULE_ENABLED, + alert_suppression: { + group_by: [ALERT_SUPPRESSION_FIELD], + missing_fields_strategy: AlertSuppressionMissingFieldsStrategy.Suppress, + }, + index: [LATEST_FINDINGS_INDEX_DEFAULT_NS], + query: generateMisconfigurationsRuleQuery(finding), + references: convertReferencesLinksToArray(finding.rule.references), + name: finding.rule.name, + description: finding.rule.rationale, + tags: generateMisconfigurationsTags(finding), + }, + }); +}; diff --git a/x-pack/plugins/cloud_security_posture/tsconfig.json b/x-pack/plugins/cloud_security_posture/tsconfig.json index ae8f7d610002b..a88bbf2bd0995 100755 --- a/x-pack/plugins/cloud_security_posture/tsconfig.json +++ b/x-pack/plugins/cloud_security_posture/tsconfig.json @@ -48,7 +48,7 @@ "@kbn/shared-ux-router", "@kbn/core-saved-objects-server", "@kbn/share-plugin", - "@kbn/core-http-server", + "@kbn/core-http-server" ], "exclude": [ "target/**/*", From 49849cf42c3d9febdd7ace60888b3c03b637b088 Mon Sep 17 00:00:00 2001 From: Antonio Date: Wed, 9 Aug 2023 17:22:05 +0200 Subject: [PATCH 13/41] [Cases] Fix flaky test in user actions pagination (#163474) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #156750 Fixes #156747 Fixes #156744 Fixes #156743 Fixes #156748 Fixes #156746 Fixes #156745 Fixes #156749 ## Summary Basically what you suggested offline @js-jankisalvi. | Scenario | Old Test | Functional test where it is covered | | ------------- | ------------- | ------------- | | Only shows one list of user actions when `total_user_actions < 10` | `'renders only one action list when user actions are less than or equal to 10'` | `'initially renders user actions list correctly'`| | `Show More` button does not show up when `total_user_actions <= page_size` | `'shows more button visible 21st user action added'` | `'initially renders user actions list correctly'` | | Shows 2 user action lists when `total_user_actions > page_size` | `'renders two user actions list when user actions are more than 10'` | `'shows more actions on button click'` | | loading spinner | `'Loading spinner when user actions loading'` | `'shows more actions on button click'` | ## Flaky Test Runner Let's make sure that the functional tests don't become flaky too. https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2826 --- .../components/user_actions/index.test.tsx | 225 ------------------ .../apps/cases/group1/view_case.ts | 12 + 2 files changed, 12 insertions(+), 225 deletions(-) diff --git a/x-pack/plugins/cases/public/components/user_actions/index.test.tsx b/x-pack/plugins/cases/public/components/user_actions/index.test.tsx index 1d3ba134f7e6d..15c2a8661edb0 100644 --- a/x-pack/plugins/cases/public/components/user_actions/index.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/index.test.tsx @@ -373,229 +373,4 @@ describe.skip(`UserActions`, () => { expect(screen.getAllByText('Damaged Raccoon')[0]).toBeInTheDocument(); }); }); - - // FLAKY: https://github.com/elastic/kibana/issues/156750 - // FLAKY: https://github.com/elastic/kibana/issues/156749 - // FLAKY: https://github.com/elastic/kibana/issues/156748 - // FLAKY: https://github.com/elastic/kibana/issues/156747 - // FLAKY: https://github.com/elastic/kibana/issues/156746 - // FLAKY: https://github.com/elastic/kibana/issues/156745 - // FLAKY: https://github.com/elastic/kibana/issues/156744 - // FLAKY: https://github.com/elastic/kibana/issues/156743 - describe.skip('pagination', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('Loading spinner when user actions loading', () => { - useFindCaseUserActionsMock.mockReturnValue({ isLoading: true }); - useInfiniteFindCaseUserActionsMock.mockReturnValue({ isLoading: true }); - appMockRender.render( - - ); - - expect(screen.getByTestId('user-actions-loading')).toBeInTheDocument(); - }); - - it('renders two user actions list when user actions are more than 10', () => { - appMockRender.render(); - - expect(screen.getAllByTestId('user-actions-list')).toHaveLength(2); - }); - - it('renders only one user actions list when last page is 0', async () => { - useFindCaseUserActionsMock.mockReturnValue({ - ...defaultUseFindCaseUserActions, - data: { userActions: [] }, - }); - const props = { - ...defaultProps, - userActionsStats: { - total: 0, - totalComments: 0, - totalOtherActions: 0, - }, - }; - - appMockRender.render(); - - await waitForComponentToUpdate(); - - expect(screen.getAllByTestId('user-actions-list')).toHaveLength(1); - }); - - it('renders only one user actions list when last page is 1', async () => { - useFindCaseUserActionsMock.mockReturnValue({ - ...defaultUseFindCaseUserActions, - data: { userActions: [] }, - }); - const props = { - ...defaultProps, - userActionsStats: { - total: 1, - totalComments: 0, - totalOtherActions: 1, - }, - }; - - appMockRender.render(); - - await waitForComponentToUpdate(); - - expect(screen.getAllByTestId('user-actions-list')).toHaveLength(1); - }); - - it('renders only one action list when user actions are less than or equal to 10', async () => { - useFindCaseUserActionsMock.mockReturnValue({ - ...defaultUseFindCaseUserActions, - data: { userActions: [] }, - }); - const props = { - ...defaultProps, - userActionsStats: { - total: 10, - totalComments: 6, - totalOtherActions: 4, - }, - }; - - appMockRender.render(); - - await waitForComponentToUpdate(); - - expect(screen.getAllByTestId('user-actions-list')).toHaveLength(1); - }); - - it('call fetchNextPage on showMore button click', async () => { - useInfiniteFindCaseUserActionsMock.mockReturnValue({ - ...defaultInfiniteUseFindCaseUserActions, - hasNextPage: true, - }); - const props = { - ...defaultProps, - userActionsStats: { - total: 25, - totalComments: 10, - totalOtherActions: 15, - }, - }; - - appMockRender.render(); - - await waitForComponentToUpdate(); - - expect(screen.getAllByTestId('user-actions-list')).toHaveLength(2); - - const showMore = screen.getByTestId('cases-show-more-user-actions'); - - expect(showMore).toBeInTheDocument(); - - userEvent.click(showMore); - - await waitFor(() => { - expect(defaultInfiniteUseFindCaseUserActions.fetchNextPage).toHaveBeenCalled(); - }); - }); - - it('shows more button visible 21st user action added', async () => { - const mockUserActions = [ - ...caseUserActions, - getUserAction('comment', UserActionActions.create), - getUserAction('comment', UserActionActions.update), - getUserAction('comment', UserActionActions.create), - getUserAction('comment', UserActionActions.update), - getUserAction('comment', UserActionActions.create), - getUserAction('comment', UserActionActions.update), - getUserAction('comment', UserActionActions.create), - ]; - useInfiniteFindCaseUserActionsMock.mockReturnValue({ - ...defaultInfiniteUseFindCaseUserActions, - data: { - pages: [ - { - total: 20, - page: 1, - perPage: 10, - userActions: mockUserActions, - }, - ], - }, - }); - useFindCaseUserActionsMock.mockReturnValue({ - ...defaultUseFindCaseUserActions, - data: { - total: 20, - page: 2, - perPage: 10, - userActions: mockUserActions, - }, - }); - const props = { - ...defaultProps, - userActionsStats: { - total: 20, - totalComments: 10, - totalOtherActions: 10, - }, - }; - - const { rerender } = appMockRender.render(); - - await waitForComponentToUpdate(); - - expect(screen.getAllByTestId('user-actions-list')).toHaveLength(2); - expect(screen.queryByTestId('cases-show-more-user-actions')).not.toBeInTheDocument(); - - useInfiniteFindCaseUserActionsMock.mockReturnValue({ - ...defaultInfiniteUseFindCaseUserActions, - data: { - pages: [ - { - total: 21, - page: 1, - perPage: 10, - userActions: mockUserActions, - }, - { - total: 21, - page: 2, - perPage: 10, - userActions: [getUserAction('comment', UserActionActions.create)], - }, - ], - }, - hasNextPage: true, - }); - useFindCaseUserActionsMock.mockReturnValue({ - ...defaultUseFindCaseUserActions, - data: { - total: 21, - page: 2, - perPage: 10, - userActions: mockUserActions, - }, - }); - - const newProps = { - ...props, - userActionsStats: { - total: 21, - totalComments: 11, - totalOtherActions: 10, - }, - }; - - rerender(); - - await waitForComponentToUpdate(); - - expect(screen.getAllByTestId('user-actions-list')).toHaveLength(2); - - const firstUserActionsList = screen.getAllByTestId('user-actions-list')[0]; - - expect(firstUserActionsList.getElementsByTagName('li')).toHaveLength(11); - - expect(screen.getByTestId('cases-show-more-user-actions')).toBeInTheDocument(); - }); - }); }); diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts b/x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts index ab4ed59336826..b44f62e71b9a0 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/group1/view_case.ts @@ -724,6 +724,16 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { await cases.api.deleteAllCases(); }); + it('initially renders user actions list correctly', async () => { + expect(testSubjects.missingOrFail('cases-show-more-user-actions')); + + const userActionsLists = await find.allByCssSelector( + '[data-test-subj="user-actions-list"]' + ); + + expect(userActionsLists).length(1); + }); + it('shows more actions on button click', async () => { await cases.api.generateUserActions({ caseId: createdCase.id, @@ -731,6 +741,8 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { totalUpdates: 4, }); + expect(testSubjects.missingOrFail('user-actions-loading')); + await header.waitUntilLoadingHasFinished(); await testSubjects.click('case-refresh'); From f4856f74784cf5ca2094f2f54a6d86f2aff3335a Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 9 Aug 2023 16:49:57 +0100 Subject: [PATCH 14/41] fix(NA): apply ipv4 first dns result order for worker threads (#163484) This PR is a follow up of https://github.com/elastic/kibana/pull/163025 as we discover the initial fix doesn't apply correctly to working threads during development. --- src/setup_node_env/dns_ipv4_first.js | 13 +++++++++++++ src/setup_node_env/index.js | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 src/setup_node_env/dns_ipv4_first.js diff --git a/src/setup_node_env/dns_ipv4_first.js b/src/setup_node_env/dns_ipv4_first.js new file mode 100644 index 0000000000000..75dd876c46d35 --- /dev/null +++ b/src/setup_node_env/dns_ipv4_first.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +// enables Node 16 default DNS lookup behavior for the current thread +require('dns').setDefaultResultOrder('ipv4first'); + +// overrides current process node options, so it can be restored in worker threads too +process.env.NODE_OPTIONS = `${process.env.NODE_OPTIONS || ''} --dns-result-order=ipv4first`; diff --git a/src/setup_node_env/index.js b/src/setup_node_env/index.js index 4f7babd66ac58..176785e10246a 100644 --- a/src/setup_node_env/index.js +++ b/src/setup_node_env/index.js @@ -10,7 +10,7 @@ require('./setup_env'); // restore < Node 16 default DNS lookup behavior -require('dns').setDefaultResultOrder('ipv4first'); +require('./dns_ipv4_first'); require('@kbn/babel-register').install(); require('./polyfill'); From dc949ee3736105eff3b4f424834dab39393518b1 Mon Sep 17 00:00:00 2001 From: Janki Salvi <117571355+js-jankisalvi@users.noreply.github.com> Date: Wed, 9 Aug 2023 17:52:36 +0200 Subject: [PATCH 15/41] [Cases] Hide cases in stack management UI (#163037) ## Summary fixes https://github.com/elastic/kibana/issues/160337 This PR - hides cases in the serverless Elasticsearch project, cases APIs throw error - throws 403 from API when `owner=cases` for security or observability serverless mode - verifies the behaviour in serverless functional as well as api_integration tests **How to test** - Boot up `es` serverless solution and make sure that `cases` from the navbar is hidden and cannot not be accessible through url as well - Boot up `observability` or `security` serverless solutions and make sure that `cases` is available in the navbar and works fine - Boot up classic kibana and make sure that the left navbar has the same menu entries it always had. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios https://github.com/elastic/kibana/assets/117571355/20c1974e-44f0-45b0-80aa-e644fec148ff ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- config/serverless.yml | 3 + .../test_suites/core_plugins/rendering.ts | 1 + x-pack/plugins/cases/common/ui/types.ts | 3 + x-pack/plugins/cases/public/plugin.test.ts | 154 +++++++++++ x-pack/plugins/cases/public/plugin.ts | 50 ++-- x-pack/plugins/cases/server/config.test.ts | 3 + x-pack/plugins/cases/server/config.ts | 3 + x-pack/plugins/cases/server/index.ts | 1 + x-pack/plugins/cases/server/plugin.test.ts | 123 +++++++++ x-pack/plugins/cases/server/plugin.ts | 4 +- x-pack/plugins/cases/tsconfig.json | 1 + .../observability/cases/find_cases.ts | 57 ++++ .../observability/cases/get_case.ts | 38 +++ .../observability/cases/helpers/api.ts | 247 ++++++++++++++++++ .../observability/cases/helpers/omit.ts | 49 ++++ .../observability/cases/post_case.ts | 64 +++++ .../test_suites/observability/index.ts | 3 + .../test_suites/search/cases/find_cases.ts | 23 ++ .../test_suites/search/cases/post_case.ts | 43 +++ .../test_suites/search/index.ts | 2 + .../test_suites/security/cases/find_cases.ts | 60 +++++ .../test_suites/security/cases/get_case.ts | 38 +++ .../test_suites/security/cases/helpers/api.ts | 247 ++++++++++++++++++ .../security/cases/helpers/omit.ts | 49 ++++ .../test_suites/security/cases/post_case.ts | 77 ++++++ .../test_suites/security/index.ts | 3 + .../test_suites/observability/navigation.ts | 17 ++ .../test_suites/search/navigation.ts | 13 + .../test_suites/security/ftr/navigation.ts | 14 + x-pack/test_serverless/tsconfig.json | 1 + 30 files changed, 1366 insertions(+), 25 deletions(-) create mode 100644 x-pack/plugins/cases/public/plugin.test.ts create mode 100644 x-pack/plugins/cases/server/plugin.test.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/cases/find_cases.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/cases/helpers/api.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/cases/helpers/omit.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/search/cases/find_cases.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/search/cases/post_case.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/cases/find_cases.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/cases/helpers/api.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/cases/helpers/omit.ts create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts diff --git a/config/serverless.yml b/config/serverless.yml index 43e9b86eb1f4a..7a79f262cea73 100644 --- a/config/serverless.yml +++ b/config/serverless.yml @@ -90,3 +90,6 @@ vis_type_timeseries.readOnly: true vis_type_vislib.readOnly: true vis_type_xy.readOnly: true input_control_vis.readOnly: true + +# Disable cases in stack management +xpack.cases.stack.enabled: false diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index 673c092a546a9..f03af110fd866 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -197,6 +197,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.cases.files.allowedMimeTypes (array)', 'xpack.cases.files.maxSize (number)', 'xpack.cases.markdownPlugins.lens (boolean)', + 'xpack.cases.stack.enabled (boolean)', 'xpack.ccr.ui.enabled (boolean)', 'xpack.cloud.base_url (string)', 'xpack.cloud.cname (string)', diff --git a/x-pack/plugins/cases/common/ui/types.ts b/x-pack/plugins/cases/common/ui/types.ts index 86f32c87ebeeb..e2e453aaaf278 100644 --- a/x-pack/plugins/cases/common/ui/types.ts +++ b/x-pack/plugins/cases/common/ui/types.ts @@ -59,6 +59,9 @@ export interface CasesUiConfigType { maxSize?: number; allowedMimeTypes: string[]; }; + stack: { + enabled: boolean; + }; } export const StatusAll = 'all' as const; diff --git a/x-pack/plugins/cases/public/plugin.test.ts b/x-pack/plugins/cases/public/plugin.test.ts new file mode 100644 index 0000000000000..bb81b7d501c5d --- /dev/null +++ b/x-pack/plugins/cases/public/plugin.test.ts @@ -0,0 +1,154 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PluginInitializerContext } from '@kbn/core/public'; +import { coreMock } from '@kbn/core/public/mocks'; +import { licensingMock } from '@kbn/licensing-plugin/public/mocks'; +import { featuresPluginMock } from '@kbn/features-plugin/public/mocks'; +import { securityMock } from '@kbn/security-plugin/public/mocks'; +import { managementPluginMock } from '@kbn/management-plugin/public/mocks'; +import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; +import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; +import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks'; +import { lensPluginMock } from '@kbn/lens-plugin/public/mocks'; +import { contentManagementMock } from '@kbn/content-management-plugin/public/mocks'; +import { mockStorage } from '@kbn/kibana-utils-plugin/public/storage/hashed_item_store/mock'; +import { triggersActionsUiMock } from '@kbn/triggers-actions-ui-plugin/public/mocks'; +import type { CasesPluginSetup, CasesPluginStart } from './types'; +import { CasesUiPlugin } from './plugin'; +import { ALLOWED_MIME_TYPES } from '../common/constants/mime_types'; + +function getConfig(overrides = {}) { + return { + markdownPlugins: { lens: true }, + files: { maxSize: 1, allowedMimeTypes: ALLOWED_MIME_TYPES }, + stack: { enabled: true }, + ...overrides, + }; +} + +describe('Cases Ui Plugin', () => { + let context: PluginInitializerContext; + let plugin: CasesUiPlugin; + let coreSetup: ReturnType; + let coreStart: ReturnType; + let pluginsSetup: jest.Mocked; + let pluginsStart: jest.Mocked; + + beforeEach(() => { + context = coreMock.createPluginInitializerContext(getConfig()); + plugin = new CasesUiPlugin(context); + coreSetup = coreMock.createSetup(); + coreStart = coreMock.createStart(); + + pluginsSetup = { + files: { + filesClientFactory: { asScoped: jest.fn(), asUnscoped: jest.fn() }, + registerFileKind: jest.fn(), + }, + security: securityMock.createSetup(), + management: managementPluginMock.createSetupContract(), + }; + + pluginsStart = { + licensing: licensingMock.createStart(), + uiActions: uiActionsPluginMock.createStartContract(), + files: { + filesClientFactory: { asScoped: jest.fn(), asUnscoped: jest.fn() }, + getAllFindKindDefinitions: jest.fn(), + getFileKindDefinition: jest.fn(), + }, + features: featuresPluginMock.createStart(), + security: securityMock.createStart(), + data: dataPluginMock.createStartContract(), + embeddable: embeddablePluginMock.createStartContract(), + lens: lensPluginMock.createStartContract(), + contentManagement: contentManagementMock.createStartContract(), + storage: { + store: { + getItem: mockStorage.getItem, + setItem: mockStorage.setItem, + removeItem: mockStorage.removeItem, + clear: mockStorage.clear, + }, + get: jest.fn(), + set: jest.fn(), + clear: jest.fn(), + remove: jest.fn(), + }, + triggersActionsUi: triggersActionsUiMock.createStart(), + }; + }); + + describe('setup()', () => { + it('should start setup cases plugin correctly', async () => { + const setup = plugin.setup(coreSetup, pluginsSetup); + + expect(setup).toMatchInlineSnapshot(` + Object { + "attachmentFramework": Object { + "registerExternalReference": [Function], + "registerPersistableState": [Function], + }, + } + `); + }); + + it('should register kibana feature when stack is enabled', async () => { + plugin.setup(coreSetup, pluginsSetup); + + expect( + pluginsSetup.management.sections.section.insightsAndAlerting.registerApp + ).toHaveBeenCalled(); + }); + + it('should not register kibana feature when stack is disabled', async () => { + context = coreMock.createPluginInitializerContext(getConfig({ stack: { enabled: false } })); + const pluginWithStackDisabled = new CasesUiPlugin(context); + + pluginWithStackDisabled.setup(coreSetup, pluginsSetup); + + expect( + pluginsSetup.management.sections.section.insightsAndAlerting.registerApp + ).not.toHaveBeenCalled(); + }); + }); + + describe('start', () => { + it('should start cases plugin correctly', async () => { + const pluginStart = plugin.start(coreStart, pluginsStart); + + expect(pluginStart).toStrictEqual({ + api: { + cases: { + bulkGet: expect.any(Function), + find: expect.any(Function), + getCasesMetrics: expect.any(Function), + getCasesStatus: expect.any(Function), + }, + getRelatedCases: expect.any(Function), + }, + helpers: { + canUseCases: expect.any(Function), + getRuleIdFromEvent: expect.any(Function), + getUICapabilities: expect.any(Function), + groupAlertsByRule: expect.any(Function), + }, + hooks: { + useCasesAddToExistingCaseModal: expect.any(Function), + useCasesAddToNewCaseFlyout: expect.any(Function), + }, + ui: { + getAllCasesSelectorModal: expect.any(Function), + getCases: expect.any(Function), + getCasesContext: expect.any(Function), + getRecentCases: expect.any(Function), + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/cases/public/plugin.ts b/x-pack/plugins/cases/public/plugin.ts index 82d62f2c07da7..f4909f344e7fc 100644 --- a/x-pack/plugins/cases/public/plugin.ts +++ b/x-pack/plugins/cases/public/plugin.ts @@ -75,30 +75,32 @@ export class CasesUiPlugin }); } - plugins.management.sections.section.insightsAndAlerting.registerApp({ - id: APP_ID, - title: APP_TITLE, - order: 1, - async mount(params: ManagementAppMountParams) { - const [coreStart, pluginsStart] = (await core.getStartServices()) as [ - CoreStart, - CasesPluginStart, - unknown - ]; - - const { renderApp } = await import('./application'); - - return renderApp({ - mountParams: params, - coreStart, - pluginsStart, - storage, - kibanaVersion, - externalReferenceAttachmentTypeRegistry, - persistableStateAttachmentTypeRegistry, - }); - }, - }); + if (config.stack.enabled) { + plugins.management.sections.section.insightsAndAlerting.registerApp({ + id: APP_ID, + title: APP_TITLE, + order: 1, + async mount(params: ManagementAppMountParams) { + const [coreStart, pluginsStart] = (await core.getStartServices()) as [ + CoreStart, + CasesPluginStart, + unknown + ]; + + const { renderApp } = await import('./application'); + + return renderApp({ + mountParams: params, + coreStart, + pluginsStart, + storage, + kibanaVersion, + externalReferenceAttachmentTypeRegistry, + persistableStateAttachmentTypeRegistry, + }); + }, + }); + } return { attachmentFramework: { diff --git a/x-pack/plugins/cases/server/config.test.ts b/x-pack/plugins/cases/server/config.test.ts index 54fc42f694bc2..352faac983f29 100644 --- a/x-pack/plugins/cases/server/config.test.ts +++ b/x-pack/plugins/cases/server/config.test.ts @@ -106,6 +106,9 @@ describe('config validation', () => { "markdownPlugins": Object { "lens": true, }, + "stack": Object { + "enabled": true, + }, } `); }); diff --git a/x-pack/plugins/cases/server/config.ts b/x-pack/plugins/cases/server/config.ts index c2daeb73b03de..7e30671ee4734 100644 --- a/x-pack/plugins/cases/server/config.ts +++ b/x-pack/plugins/cases/server/config.ts @@ -20,6 +20,9 @@ export const ConfigSchema = schema.object({ // intentionally not setting a default here so that we can determine if the user set it maxSize: schema.maybe(schema.number({ min: 0 })), }), + stack: schema.object({ + enabled: schema.boolean({ defaultValue: true }), + }), }); export type ConfigType = TypeOf; diff --git a/x-pack/plugins/cases/server/index.ts b/x-pack/plugins/cases/server/index.ts index 62748905f6b82..b1cadb43f147c 100644 --- a/x-pack/plugins/cases/server/index.ts +++ b/x-pack/plugins/cases/server/index.ts @@ -16,6 +16,7 @@ export const config: PluginConfigDescriptor = { exposeToBrowser: { markdownPlugins: true, files: { maxSize: true, allowedMimeTypes: true }, + stack: { enabled: true }, }, deprecations: ({ renameFromRoot }) => [ renameFromRoot('xpack.case.enabled', 'xpack.cases.enabled', { level: 'critical' }), diff --git a/x-pack/plugins/cases/server/plugin.test.ts b/x-pack/plugins/cases/server/plugin.test.ts new file mode 100644 index 0000000000000..255e6ce42af68 --- /dev/null +++ b/x-pack/plugins/cases/server/plugin.test.ts @@ -0,0 +1,123 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PluginInitializerContext } from '@kbn/core/server'; +import {} from '@kbn/core/server'; +import { coreMock } from '@kbn/core/server/mocks'; +import { usageCollectionPluginMock } from '@kbn/usage-collection-plugin/server/mocks'; +import { licensingMock } from '@kbn/licensing-plugin/server/mocks'; +import { featuresPluginMock } from '@kbn/features-plugin/server/mocks'; +import { createFilesSetupMock } from '@kbn/files-plugin/server/mocks'; +import { securityMock } from '@kbn/security-plugin/server/mocks'; +import { makeLensEmbeddableFactory } from '@kbn/lens-plugin/server/embeddable/make_lens_embeddable_factory'; +import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; +import { actionsMock } from '@kbn/actions-plugin/server/mocks'; +import { notificationsMock } from '@kbn/notifications-plugin/server/mocks'; +import { alertsMock } from '@kbn/alerting-plugin/server/mocks'; +import type { PluginsSetup, PluginsStart } from './plugin'; +import { CasePlugin } from './plugin'; +import type { ConfigType } from './config'; +import { ALLOWED_MIME_TYPES } from '../common/constants/mime_types'; + +function getConfig(overrides = {}) { + return { + markdownPlugins: { lens: true }, + files: { maxSize: 1, allowedMimeTypes: ALLOWED_MIME_TYPES }, + stack: { enabled: true }, + ...overrides, + }; +} + +describe('Cases Plugin', () => { + let context: PluginInitializerContext; + let plugin: CasePlugin; + let coreSetup: ReturnType; + let coreStart: ReturnType; + let pluginsSetup: jest.Mocked; + let pluginsStart: jest.Mocked; + + beforeEach(() => { + context = coreMock.createPluginInitializerContext(getConfig()); + + plugin = new CasePlugin(context); + coreSetup = coreMock.createSetup(); + coreStart = coreMock.createStart(); + + pluginsSetup = { + taskManager: taskManagerMock.createSetup(), + actions: actionsMock.createSetup(), + files: createFilesSetupMock(), + lens: { + lensEmbeddableFactory: makeLensEmbeddableFactory( + () => ({}), + () => ({}), + {} + ), + registerVisualizationMigration: jest.fn(), + }, + security: securityMock.createSetup(), + licensing: licensingMock.createSetup(), + usageCollection: usageCollectionPluginMock.createSetupContract(), + features: featuresPluginMock.createSetup(), + }; + + pluginsStart = { + licensing: licensingMock.createStart(), + actions: actionsMock.createStart(), + files: { fileServiceFactory: { asScoped: jest.fn(), asInternal: jest.fn() } }, + features: featuresPluginMock.createStart(), + security: securityMock.createStart(), + notifications: notificationsMock.createStart(), + ruleRegistry: { getRacClientWithRequest: jest.fn(), alerting: alertsMock.createStart() }, + }; + }); + + describe('setup()', () => { + it('should start setup cases plugin correctly', async () => { + plugin.setup(coreSetup, pluginsSetup); + + expect(context.logger.get().debug).toHaveBeenCalledWith( + `Setting up Case Workflow with core contract [${Object.keys( + coreSetup + )}] and plugins [${Object.keys(pluginsSetup)}]` + ); + }); + + it('should register kibana feature when stack is enabled', async () => { + plugin.setup(coreSetup, pluginsSetup); + + expect(pluginsSetup.features.registerKibanaFeature).toHaveBeenCalled(); + }); + + it('should not register kibana feature when stack is disabled', async () => { + context = coreMock.createPluginInitializerContext( + getConfig({ stack: { enabled: false } }) + ); + const pluginWithStackDisabled = new CasePlugin(context); + + pluginWithStackDisabled.setup(coreSetup, pluginsSetup); + + expect(pluginsSetup.features.registerKibanaFeature).not.toHaveBeenCalled(); + }); + }); + + describe('start', () => { + it('should start cases plugin correctly', async () => { + const pluginStart = plugin.start(coreStart, pluginsStart); + + expect(context.logger.get().debug).toHaveBeenCalledWith(`Starting Case Workflow`); + + expect(pluginStart).toMatchInlineSnapshot(` + Object { + "getCasesClientWithRequest": [Function], + "getExternalReferenceAttachmentTypeRegistry": [Function], + "getPersistableStateAttachmentTypeRegistry": [Function], + } + `); + }); + }); +}); diff --git a/x-pack/plugins/cases/server/plugin.ts b/x-pack/plugins/cases/server/plugin.ts index 0ae005e09b188..510686f1a98bd 100644 --- a/x-pack/plugins/cases/server/plugin.ts +++ b/x-pack/plugins/cases/server/plugin.ts @@ -121,7 +121,9 @@ export class CasePlugin { this.securityPluginSetup = plugins.security; this.lensEmbeddableFactory = plugins.lens.lensEmbeddableFactory; - plugins.features.registerKibanaFeature(getCasesKibanaFeature()); + if (this.caseConfig.stack.enabled) { + plugins.features.registerKibanaFeature(getCasesKibanaFeature()); + } core.savedObjects.registerType( createCaseCommentSavedObjectType({ diff --git a/x-pack/plugins/cases/tsconfig.json b/x-pack/plugins/cases/tsconfig.json index cb82b27d5334d..ccd6e228d6aff 100644 --- a/x-pack/plugins/cases/tsconfig.json +++ b/x-pack/plugins/cases/tsconfig.json @@ -68,6 +68,7 @@ "@kbn/core-theme-browser", "@kbn/serverless", "@kbn/core-http-server", + "@kbn/alerting-plugin", "@kbn/content-management-plugin", ], "exclude": [ diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/find_cases.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/find_cases.ts new file mode 100644 index 0000000000000..6f88c0ded2fdd --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/find_cases.ts @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { + findCases, + createCase, + deleteAllCaseItems, + postCaseReq, + findCasesResp, +} from './helpers/api'; + +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('find_cases', () => { + afterEach(async () => { + await deleteAllCaseItems(es); + }); + + it('should return empty response', async () => { + const cases = await findCases({ supertest }); + expect(cases).to.eql(findCasesResp); + }); + + it('should return cases', async () => { + const a = await createCase(supertest, postCaseReq); + const b = await createCase(supertest, postCaseReq); + const c = await createCase(supertest, postCaseReq); + + const cases = await findCases({ supertest }); + + expect(cases).to.eql({ + ...findCasesResp, + total: 3, + cases: [a, b, c], + count_open_cases: 3, + }); + }); + + it('returns empty response when trying to find cases with owner as cases', async () => { + const cases = await findCases({ supertest, query: { owner: 'cases' } }); + expect(cases).to.eql(findCasesResp); + }); + + it('returns empty response when trying to find cases with owner as securitySolution', async () => { + const cases = await findCases({ supertest, query: { owner: 'securitySolution' } }); + expect(cases).to.eql(findCasesResp); + }); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts new file mode 100644 index 0000000000000..fffc529d2df30 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/get_case.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; + +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { + getCase, + createCase, + deleteCasesByESQuery, + getPostCaseRequest, + postCaseResp, +} from './helpers/api'; +import { removeServerGeneratedPropertiesFromCase } from './helpers/omit'; + +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('get_case', () => { + afterEach(async () => { + await deleteCasesByESQuery(es); + }); + + it('should return a case', async () => { + const postedCase = await createCase(supertest, getPostCaseRequest()); + const theCase = await getCase({ supertest, caseId: postedCase.id, includeComments: true }); + + const data = removeServerGeneratedPropertiesFromCase(theCase); + expect(data).to.eql(postCaseResp()); + expect(data.comments?.length).to.eql(0); + }); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/helpers/api.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/helpers/api.ts new file mode 100644 index 0000000000000..5f196ef3e3372 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/helpers/api.ts @@ -0,0 +1,247 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Client } from '@elastic/elasticsearch'; +import type SuperTest from 'supertest'; +import { ALERTING_CASES_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server/src/saved_objects_index_pattern'; +import { CASES_URL } from '@kbn/cases-plugin/common'; +import { Case, CaseSeverity, CaseStatuses } from '@kbn/cases-plugin/common/types/domain'; +import type { CasePostRequest } from '@kbn/cases-plugin/common/types/api'; +import { ConnectorTypes } from '@kbn/cases-plugin/common/types/domain'; +import { CasesFindResponse } from '@kbn/cases-plugin/common/types/api'; + +export interface User { + username: string; + password: string; + description?: string; + roles: string[]; +} + +export const superUser: User = { + username: 'superuser', + password: 'superuser', + roles: ['superuser'], +}; + +export const setupAuth = ({ + apiCall, + headers, + auth, +}: { + apiCall: SuperTest.Test; + headers: Record; + auth?: { user: User; space: string | null } | null; +}): SuperTest.Test => { + if (!Object.hasOwn(headers, 'Cookie') && auth != null) { + return apiCall.auth(auth.user.username, auth.user.password); + } + + return apiCall; +}; + +export const getSpaceUrlPrefix = (spaceId: string | undefined | null) => { + return spaceId && spaceId !== 'default' ? `/s/${spaceId}` : ``; +}; + +export const deleteAllCaseItems = async (es: Client) => { + await Promise.all([ + deleteCasesByESQuery(es), + deleteCasesUserActions(es), + deleteComments(es), + deleteConfiguration(es), + deleteMappings(es), + ]); +}; + +export const deleteCasesUserActions = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases-user-actions', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const deleteCasesByESQuery = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const deleteComments = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases-comments', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const deleteConfiguration = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases-configure', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const deleteMappings = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases-connector-mappings', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const defaultUser = { email: null, full_name: null, username: 'elastic' }; +/** + * A null filled user will occur when the security plugin is disabled + */ +export const nullUser = { email: null, full_name: null, username: null }; + +export const postCaseReq: CasePostRequest = { + description: 'This is a brand new case of a bad meanie defacing data', + title: 'Super Bad Observability Issue', + tags: ['defacement'], + severity: CaseSeverity.LOW, + connector: { + id: 'none', + name: 'none', + type: ConnectorTypes.none, + fields: null, + }, + settings: { + syncAlerts: true, + }, + owner: 'observability', + assignees: [], +}; + +/** + * Return a request for creating a case. + */ +export const getPostCaseRequest = (req?: Partial): CasePostRequest => ({ + ...postCaseReq, + ...req, +}); + +export const postCaseResp = ( + id?: string | null, + req: CasePostRequest = postCaseReq +): Partial => ({ + ...req, + ...(id != null ? { id } : {}), + comments: [], + duration: null, + severity: req.severity ?? CaseSeverity.LOW, + totalAlerts: 0, + totalComment: 0, + closed_by: null, + created_by: defaultUser, + external_service: null, + status: CaseStatuses.open, + updated_by: null, + category: null, +}); + +const findCommon = { + page: 1, + per_page: 20, + total: 0, + count_open_cases: 0, + count_closed_cases: 0, + count_in_progress_cases: 0, +}; + +export const findCasesResp: CasesFindResponse = { + ...findCommon, + cases: [], +}; + +export const createCase = async ( + supertest: SuperTest.SuperTest, + params: CasePostRequest, + expectedHttpCode: number = 200, + auth: { user: User; space: string | null } | null = { user: superUser, space: null }, + headers: Record = {} +): Promise => { + const apiCall = supertest.post(`${CASES_URL}`); + + setupAuth({ apiCall, headers, auth }); + + const response = await apiCall + .set('kbn-xsrf', 'foo') + .set('x-elastic-internal-origin', 'foo') + .set(headers) + .send(params) + .expect(expectedHttpCode); + + return response.body; +}; + +export const findCases = async ({ + supertest, + query = {}, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + query?: Record; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: res } = await supertest + .get(`${getSpaceUrlPrefix(auth.space)}${CASES_URL}/_find`) + .auth(auth.user.username, auth.user.password) + .query({ sortOrder: 'asc', ...query }) + .set('kbn-xsrf', 'foo') + .set('x-elastic-internal-origin', 'foo') + .send() + .expect(expectedHttpCode); + + return res; +}; + +export const getCase = async ({ + supertest, + caseId, + includeComments = false, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + caseId: string; + includeComments?: boolean; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: theCase } = await supertest + .get( + `${getSpaceUrlPrefix(auth?.space)}${CASES_URL}/${caseId}?includeComments=${includeComments}` + ) + .set('kbn-xsrf', 'foo') + .set('x-elastic-internal-origin', 'foo') + .auth(auth.user.username, auth.user.password) + .expect(expectedHttpCode); + + return theCase; +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/helpers/omit.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/helpers/omit.ts new file mode 100644 index 0000000000000..b25506bfaebea --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/helpers/omit.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Case, Attachment } from '@kbn/cases-plugin/common/types/domain'; +import { omit } from 'lodash'; + +interface CommonSavedObjectAttributes { + id?: string | null; + created_at?: string | null; + updated_at?: string | null; + version?: string | null; + [key: string]: unknown; +} + +const savedObjectCommonAttributes = ['created_at', 'updated_at', 'version', 'id']; + +export const removeServerGeneratedPropertiesFromObject = ( + object: T, + keys: K[] +): Omit => { + return omit(object, keys); +}; +export const removeServerGeneratedPropertiesFromSavedObject = < + T extends CommonSavedObjectAttributes +>( + attributes: T, + keys: Array = [] +): Omit => { + return removeServerGeneratedPropertiesFromObject(attributes, [ + ...savedObjectCommonAttributes, + ...keys, + ]); +}; + +export const removeServerGeneratedPropertiesFromCase = (theCase: Case): Partial => { + return removeServerGeneratedPropertiesFromSavedObject(theCase, ['closed_at']); +}; + +export const removeServerGeneratedPropertiesFromComments = ( + comments: Attachment[] | undefined +): Array> | undefined => { + return comments?.map((comment) => { + return removeServerGeneratedPropertiesFromSavedObject(comment, []); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts new file mode 100644 index 0000000000000..2bb37149c007f --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/post_case.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { ConnectorTypes } from '@kbn/cases-plugin/common/types/domain'; + +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { deleteCasesByESQuery, createCase, getPostCaseRequest } from './helpers/api'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + + describe('post_case', () => { + afterEach(async () => { + await deleteCasesByESQuery(es); + }); + + it('should create a case', async () => { + expect( + await createCase( + supertest, + getPostCaseRequest({ + connector: { + id: '123', + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: 'High', parent: null }, + }, + }), + 200 + ) + ); + }); + + it('should throw 403 when create a case with securitySolution as owner', async () => { + expect( + await createCase( + supertest, + getPostCaseRequest({ + owner: 'securitySolution', + }), + 403 + ) + ); + }); + + it('should throw 403 when create a case with cases as owner', async () => { + expect( + await createCase( + supertest, + getPostCaseRequest({ + owner: 'cases', + }), + 403 + ) + ); + }); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/index.ts b/x-pack/test_serverless/api_integration/test_suites/observability/index.ts index b235be792ed42..443c9366d751b 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/index.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/index.ts @@ -17,5 +17,8 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./threshold_rule/documents_count_fired')); loadTestFile(require.resolve('./threshold_rule/custom_eq_avg_bytes_fired')); loadTestFile(require.resolve('./threshold_rule/group_by_fired')); + loadTestFile(require.resolve('./cases/post_case')); + loadTestFile(require.resolve('./cases/find_cases')); + loadTestFile(require.resolve('./cases/get_case')); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/search/cases/find_cases.ts b/x-pack/test_serverless/api_integration/test_suites/search/cases/find_cases.ts new file mode 100644 index 0000000000000..b847833b30b46 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/search/cases/find_cases.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CASES_URL } from '@kbn/cases-plugin/common/constants'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + + describe('find_cases', () => { + it('403 when calling find cases API', async () => { + await supertest + .get(`${CASES_URL}/_find`) + .set('kbn-xsrf', 'foo') + .set('x-elastic-internal-origin', 'foo') + .expect(403); + }); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/search/cases/post_case.ts b/x-pack/test_serverless/api_integration/test_suites/search/cases/post_case.ts new file mode 100644 index 0000000000000..4391fa29e0831 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/search/cases/post_case.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CASES_URL } from '@kbn/cases-plugin/common/constants'; +import { CaseSeverity } from '@kbn/cases-plugin/common/types/domain'; +import { ConnectorTypes } from '@kbn/cases-plugin/common/types/domain'; + +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + + describe('post_case', () => { + it('403 when trying to create case', async () => { + await supertest + .post(CASES_URL) + .set('kbn-xsrf', 'foo') + .set('x-elastic-internal-origin', 'foo') + .send({ + description: 'This is a brand new case of a bad meanie defacing data', + title: 'Super Bad Observability Issue', + tags: ['defacement'], + severity: CaseSeverity.LOW, + connector: { + id: 'none', + name: 'none', + type: ConnectorTypes.none, + fields: null, + }, + settings: { + syncAlerts: true, + }, + owner: 'cases', + assignees: [], + }) + .expect(403); + }); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/search/index.ts b/x-pack/test_serverless/api_integration/test_suites/search/index.ts index 20c04f741b1ac..13ddf80d5a950 100644 --- a/x-pack/test_serverless/api_integration/test_suites/search/index.ts +++ b/x-pack/test_serverless/api_integration/test_suites/search/index.ts @@ -10,5 +10,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ loadTestFile }: FtrProviderContext) { describe('serverless search API', function () { loadTestFile(require.resolve('./snapshot_telemetry')); + loadTestFile(require.resolve('./cases/post_case')); + loadTestFile(require.resolve('./cases/find_cases')); }); } diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/find_cases.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/find_cases.ts new file mode 100644 index 0000000000000..07283119aea2f --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/find_cases.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +import { + findCases, + createCase, + deleteAllCaseItems, + findCasesResp, + postCaseReq, +} from './helpers/api'; + +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('find_cases', () => { + describe('basic tests', () => { + afterEach(async () => { + await deleteAllCaseItems(es); + }); + + it('should return empty response', async () => { + const cases = await findCases({ supertest }); + expect(cases).to.eql(findCasesResp); + }); + + it('should return cases', async () => { + const a = await createCase(supertest, postCaseReq); + const b = await createCase(supertest, postCaseReq); + const c = await createCase(supertest, postCaseReq); + + const cases = await findCases({ supertest }); + + expect(cases).to.eql({ + ...findCasesResp, + total: 3, + cases: [a, b, c], + count_open_cases: 3, + }); + }); + + it('returns empty response when trying to find cases with owner as cases', async () => { + const cases = await findCases({ supertest, query: { owner: 'cases' } }); + expect(cases).to.eql(findCasesResp); + }); + + it('returns empty response when trying to find cases with owner as observability', async () => { + const cases = await findCases({ supertest, query: { owner: 'observability' } }); + expect(cases).to.eql(findCasesResp); + }); + }); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts new file mode 100644 index 0000000000000..c8dd9ec867514 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/get_case.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +import { + getCase, + createCase, + deleteCasesByESQuery, + getPostCaseRequest, + postCaseResp, +} from './helpers/api'; +import { removeServerGeneratedPropertiesFromCase } from './helpers/omit'; + +export default ({ getService }: FtrProviderContext): void => { + const supertest = getService('supertest'); + const es = getService('es'); + + describe('get_case', () => { + afterEach(async () => { + await deleteCasesByESQuery(es); + }); + + it('should return a case', async () => { + const postedCase = await createCase(supertest, getPostCaseRequest()); + const theCase = await getCase({ supertest, caseId: postedCase.id, includeComments: true }); + + const data = removeServerGeneratedPropertiesFromCase(theCase); + expect(data).to.eql(postCaseResp()); + expect(data.comments?.length).to.eql(0); + }); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/helpers/api.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/helpers/api.ts new file mode 100644 index 0000000000000..afba9c46c67c2 --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/helpers/api.ts @@ -0,0 +1,247 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { Client } from '@elastic/elasticsearch'; +import type SuperTest from 'supertest'; +import { ALERTING_CASES_SAVED_OBJECT_INDEX } from '@kbn/core-saved-objects-server/src/saved_objects_index_pattern'; +import { CASES_URL } from '@kbn/cases-plugin/common'; +import { Case, CaseSeverity, CaseStatuses } from '@kbn/cases-plugin/common/types/domain'; +import type { CasePostRequest } from '@kbn/cases-plugin/common/types/api'; +import { ConnectorTypes } from '@kbn/cases-plugin/common/types/domain'; +import { CasesFindResponse } from '@kbn/cases-plugin/common/types/api'; + +export interface User { + username: string; + password: string; + description?: string; + roles: string[]; +} + +export const superUser: User = { + username: 'superuser', + password: 'superuser', + roles: ['superuser'], +}; + +export const setupAuth = ({ + apiCall, + headers, + auth, +}: { + apiCall: SuperTest.Test; + headers: Record; + auth?: { user: User; space: string | null } | null; +}): SuperTest.Test => { + if (!Object.hasOwn(headers, 'Cookie') && auth != null) { + return apiCall.auth(auth.user.username, auth.user.password); + } + + return apiCall; +}; + +export const getSpaceUrlPrefix = (spaceId: string | undefined | null) => { + return spaceId && spaceId !== 'default' ? `/s/${spaceId}` : ``; +}; + +export const deleteAllCaseItems = async (es: Client) => { + await Promise.all([ + deleteCasesByESQuery(es), + deleteCasesUserActions(es), + deleteComments(es), + deleteConfiguration(es), + deleteMappings(es), + ]); +}; + +export const deleteCasesUserActions = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases-user-actions', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const deleteCasesByESQuery = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const deleteComments = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases-comments', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const deleteConfiguration = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases-configure', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const deleteMappings = async (es: Client): Promise => { + await es.deleteByQuery({ + index: ALERTING_CASES_SAVED_OBJECT_INDEX, + q: 'type:cases-connector-mappings', + wait_for_completion: true, + refresh: true, + body: {}, + conflicts: 'proceed', + }); +}; + +export const defaultUser = { email: null, full_name: null, username: 'elastic' }; +/** + * A null filled user will occur when the security plugin is disabled + */ +export const nullUser = { email: null, full_name: null, username: null }; + +export const postCaseReq: CasePostRequest = { + description: 'This is a brand new case of a bad meanie defacing data', + title: 'Super Bad Observability Issue', + tags: ['defacement'], + severity: CaseSeverity.LOW, + connector: { + id: 'none', + name: 'none', + type: ConnectorTypes.none, + fields: null, + }, + settings: { + syncAlerts: true, + }, + owner: 'securitySolution', + assignees: [], +}; + +/** + * Return a request for creating a case. + */ +export const getPostCaseRequest = (req?: Partial): CasePostRequest => ({ + ...postCaseReq, + ...req, +}); + +export const postCaseResp = ( + id?: string | null, + req: CasePostRequest = postCaseReq +): Partial => ({ + ...req, + ...(id != null ? { id } : {}), + comments: [], + duration: null, + severity: req.severity ?? CaseSeverity.LOW, + totalAlerts: 0, + totalComment: 0, + closed_by: null, + created_by: defaultUser, + external_service: null, + status: CaseStatuses.open, + updated_by: null, + category: null, +}); + +const findCommon = { + page: 1, + per_page: 20, + total: 0, + count_open_cases: 0, + count_closed_cases: 0, + count_in_progress_cases: 0, +}; + +export const findCasesResp: CasesFindResponse = { + ...findCommon, + cases: [], +}; + +export const createCase = async ( + supertest: SuperTest.SuperTest, + params: CasePostRequest, + expectedHttpCode: number = 200, + auth: { user: User; space: string | null } | null = { user: superUser, space: null }, + headers: Record = {} +): Promise => { + const apiCall = supertest.post(`${CASES_URL}`); + + setupAuth({ apiCall, headers, auth }); + + const { body: theCase } = await apiCall + .set('kbn-xsrf', 'foo') + .set('x-elastic-internal-origin', 'foo') + .set(headers) + .send(params) + .expect(expectedHttpCode); + + return theCase; +}; + +export const findCases = async ({ + supertest, + query = {}, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + query?: Record; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: res } = await supertest + .get(`${getSpaceUrlPrefix(auth.space)}${CASES_URL}/_find`) + .auth(auth.user.username, auth.user.password) + .query({ sortOrder: 'asc', ...query }) + .set('kbn-xsrf', 'foo') + .set('x-elastic-internal-origin', 'foo') + .send() + .expect(expectedHttpCode); + + return res; +}; + +export const getCase = async ({ + supertest, + caseId, + includeComments = false, + expectedHttpCode = 200, + auth = { user: superUser, space: null }, +}: { + supertest: SuperTest.SuperTest; + caseId: string; + includeComments?: boolean; + expectedHttpCode?: number; + auth?: { user: User; space: string | null }; +}): Promise => { + const { body: theCase } = await supertest + .get( + `${getSpaceUrlPrefix(auth?.space)}${CASES_URL}/${caseId}?includeComments=${includeComments}` + ) + .set('kbn-xsrf', 'foo') + .set('x-elastic-internal-origin', 'foo') + .auth(auth.user.username, auth.user.password) + .expect(expectedHttpCode); + + return theCase; +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/helpers/omit.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/helpers/omit.ts new file mode 100644 index 0000000000000..b25506bfaebea --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/helpers/omit.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Case, Attachment } from '@kbn/cases-plugin/common/types/domain'; +import { omit } from 'lodash'; + +interface CommonSavedObjectAttributes { + id?: string | null; + created_at?: string | null; + updated_at?: string | null; + version?: string | null; + [key: string]: unknown; +} + +const savedObjectCommonAttributes = ['created_at', 'updated_at', 'version', 'id']; + +export const removeServerGeneratedPropertiesFromObject = ( + object: T, + keys: K[] +): Omit => { + return omit(object, keys); +}; +export const removeServerGeneratedPropertiesFromSavedObject = < + T extends CommonSavedObjectAttributes +>( + attributes: T, + keys: Array = [] +): Omit => { + return removeServerGeneratedPropertiesFromObject(attributes, [ + ...savedObjectCommonAttributes, + ...keys, + ]); +}; + +export const removeServerGeneratedPropertiesFromCase = (theCase: Case): Partial => { + return removeServerGeneratedPropertiesFromSavedObject(theCase, ['closed_at']); +}; + +export const removeServerGeneratedPropertiesFromComments = ( + comments: Attachment[] | undefined +): Array> | undefined => { + return comments?.map((comment) => { + return removeServerGeneratedPropertiesFromSavedObject(comment, []); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts new file mode 100644 index 0000000000000..1d49545c3d53a --- /dev/null +++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/post_case.ts @@ -0,0 +1,77 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { ConnectorTypes } from '@kbn/cases-plugin/common/types/domain'; + +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { deleteCasesByESQuery, createCase, getPostCaseRequest, postCaseResp } from './helpers/api'; +import { removeServerGeneratedPropertiesFromCase } from './helpers/omit'; + +export default ({ getService }: FtrProviderContext): void => { + const es = getService('es'); + const supertest = getService('supertest'); + + describe('post_case', () => { + afterEach(async () => { + await deleteCasesByESQuery(es); + }); + + it('should create a case', async () => { + const postedCase = await createCase( + supertest, + getPostCaseRequest({ + connector: { + id: '123', + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: 'High', parent: null }, + }, + }) + ); + const data = removeServerGeneratedPropertiesFromCase(postedCase); + + expect(data).to.eql( + postCaseResp( + null, + getPostCaseRequest({ + connector: { + id: '123', + name: 'Jira', + type: ConnectorTypes.jira, + fields: { issueType: 'Task', priority: 'High', parent: null }, + }, + }) + ) + ); + }); + + it('should throw 403 when trying to create a case with observability as owner', async () => { + expect( + await createCase( + supertest, + getPostCaseRequest({ + owner: 'observability', + }), + 403 + ) + ); + }); + + it('should throw 403 when trying to create a case with cases as owner', async () => { + expect( + await createCase( + supertest, + getPostCaseRequest({ + owner: 'cases', + }), + 403 + ) + ); + }); + }); +}; diff --git a/x-pack/test_serverless/api_integration/test_suites/security/index.ts b/x-pack/test_serverless/api_integration/test_suites/security/index.ts index a57d4446e4b9b..294f4b32af5e6 100644 --- a/x-pack/test_serverless/api_integration/test_suites/security/index.ts +++ b/x-pack/test_serverless/api_integration/test_suites/security/index.ts @@ -11,5 +11,8 @@ export default function ({ loadTestFile }: FtrProviderContext) { describe('serverless security API', function () { loadTestFile(require.resolve('./fleet')); loadTestFile(require.resolve('./snapshot_telemetry')); + loadTestFile(require.resolve('./cases/post_case')); + loadTestFile(require.resolve('./cases/find_cases')); + loadTestFile(require.resolve('./cases/get_case')); }); } diff --git a/x-pack/test_serverless/functional/test_suites/observability/navigation.ts b/x-pack/test_serverless/functional/test_suites/observability/navigation.ts index 6c90a2a410b61..2054e8eb011f6 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/navigation.ts @@ -86,5 +86,22 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await expect(await browser.getCurrentUrl()).contain('/app/discover#/p/log-explorer'); }); + + it('shows cases in sidebar navigation', async () => { + await svlCommonNavigation.expectExists(); + + await svlCommonNavigation.sidenav.expectLinkExists({ + deepLinkId: 'observability-overview:cases', + }); + }); + + it('navigates to cases app', async () => { + await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'observability-overview:cases' }); + + await svlCommonNavigation.sidenav.expectLinkActive({ + deepLinkId: 'observability-overview:cases', + }); + expect(await browser.getCurrentUrl()).contain('/app/observability/cases'); + }); }); } diff --git a/x-pack/test_serverless/functional/test_suites/search/navigation.ts b/x-pack/test_serverless/functional/test_suites/search/navigation.ts index edf4c41274403..ba19e7b756073 100644 --- a/x-pack/test_serverless/functional/test_suites/search/navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/search/navigation.ts @@ -74,5 +74,18 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await expect(await browser.getCurrentUrl()).contain('/app/discover'); }); + + it('does not show cases in sidebar navigation', async () => { + await svlSearchLandingPage.assertSvlSearchSideNavExists(); + + expect(await testSubjects.missingOrFail('cases')); + }); + + it('does not navigate to cases app', async () => { + await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'discover' }); + + expect(await browser.getCurrentUrl()).not.contain('/app/management/cases'); + await testSubjects.missingOrFail('cases-all-title'); + }); }); } diff --git a/x-pack/test_serverless/functional/test_suites/security/ftr/navigation.ts b/x-pack/test_serverless/functional/test_suites/security/ftr/navigation.ts index 1ea8ed53c0ca4..695336b7734fb 100644 --- a/x-pack/test_serverless/functional/test_suites/security/ftr/navigation.ts +++ b/x-pack/test_serverless/functional/test_suites/security/ftr/navigation.ts @@ -43,5 +43,19 @@ export default function ({ getPageObject, getService }: FtrProviderContext) { await expect(await browser.getCurrentUrl()).contain('app/security/dashboards'); }); + + it('shows cases in sidebar navigation', async () => { + await svlSecLandingPage.assertSvlSecSideNavExists(); + await svlCommonNavigation.expectExists(); + + expect(await testSubjects.existOrFail('solutionSideNavItemLink-cases')); + }); + + it('navigates to cases app', async () => { + await testSubjects.click('solutionSideNavItemLink-cases'); + + expect(await browser.getCurrentUrl()).contain('/app/security/cases'); + await testSubjects.existOrFail('cases-all-title'); + }); }); } diff --git a/x-pack/test_serverless/tsconfig.json b/x-pack/test_serverless/tsconfig.json index 8c431b2537986..eb69a37884039 100644 --- a/x-pack/test_serverless/tsconfig.json +++ b/x-pack/test_serverless/tsconfig.json @@ -46,5 +46,6 @@ "@kbn/test-subj-selector", "@kbn/core-http-common", "@kbn/data-views-plugin", + "@kbn/core-saved-objects-server", ] } From e2b10cb831c506d898a6ffba7f5f8a776439586c Mon Sep 17 00:00:00 2001 From: Konrad Szwarc Date: Wed, 9 Aug 2023 17:59:28 +0200 Subject: [PATCH 16/41] [Fleet][Kafka Output] Tweaks for Kafka UI/API (#162875) 1. Removed Kerberos option from auth type selection 2. Used EuiFieldPassword component for password input State: ![Screenshot 2023-08-01 at 11 16 30](https://github.com/elastic/kibana/assets/29123534/3ef0b3f8-c98b-42d0-9645-fdb6437859f5) 3. Added `None` authentication option. This will save `auth_type` as `none` and won't pass `usernamer`, `password` nor `ssl` to the SO. ![Screenshot 2023-08-02 at 15 59 08](https://github.com/elastic/kibana/assets/29123534/9bbe9ce7-2749-484f-833d-72d1c9e5ee46) 4. Renamed `broker_ack_reliability` to `required_acks` in UI and API. Changed value type to `1 || 0 || -1` 5. Renamed `broker_buffer_size` to `channel_buffer_size` in UI and API. 6. Temporarily disabled `password` field encryption. 7. `partition` key stored in yaml follows proper requirements 8. `topics` key stored in yaml follows proper requirements --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../current_mappings.json | 31 +- .../group2/check_registered_types.test.ts | 2 +- .../plugins/fleet/common/constants/output.ts | 25 +- .../plugins/fleet/common/openapi/bundled.json | 42 +- .../plugins/fleet/common/openapi/bundled.yaml | 32 +- .../schemas/output_create_request_kafka.yaml | 10 +- .../schemas/output_update_request_kafka.yaml | 10 +- .../fleet/common/types/models/output.ts | 9 +- .../cypress/e2e/fleet_settings_outputs.cy.ts | 561 +++++++++--------- x-pack/plugins/fleet/cypress/screens/fleet.ts | 6 +- .../fleet/cypress/screens/fleet_outputs.ts | 31 +- .../edit_output_flyout/index.test.tsx | 6 +- .../edit_output_flyout/output_form_kafka.tsx | 7 +- .../output_form_kafka_authentication.tsx | 203 +++++-- .../output_form_kafka_broker.tsx | 46 +- .../output_form_kafka_headers.tsx | 5 +- .../output_form_kafka_topics.tsx | 50 +- .../output_form_validators.test.tsx | 62 ++ .../output_form_validators.tsx | 97 +++ .../edit_output_flyout/use_output_form.tsx | 95 ++- .../plugins/fleet/public/hooks/use_input.ts | 23 +- .../fleet/server/saved_objects/index.ts | 44 ++ .../migrations/to_v8_10_0.test.ts | 62 ++ .../saved_objects/migrations/to_v8_10_0.ts | 44 ++ .../agent_policies/full_agent_policy.ts | 69 ++- .../fleet/server/services/output.test.ts | 79 ++- .../plugins/fleet/server/services/output.ts | 40 +- .../fleet/server/types/models/output.test.ts | 20 +- .../fleet/server/types/models/output.ts | 58 +- .../fleet/server/types/so_attributes.ts | 5 +- .../apis/outputs/crud.ts | 24 +- 31 files changed, 1249 insertions(+), 549 deletions(-) create mode 100644 x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_10_0.test.ts create mode 100644 x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_10_0.ts diff --git a/packages/kbn-check-mappings-update-cli/current_mappings.json b/packages/kbn-check-mappings-update-cli/current_mappings.json index 748b27fe13dd1..c2c9022b42b2a 100644 --- a/packages/kbn-check-mappings-update-cli/current_mappings.json +++ b/packages/kbn-check-mappings-update-cli/current_mappings.json @@ -629,17 +629,6 @@ } } }, - "search": { - "dynamic": false, - "properties": { - "title": { - "type": "text" - }, - "description": { - "type": "text" - } - } - }, "alert": { "dynamic": false, "properties": { @@ -931,6 +920,17 @@ } } }, + "search": { + "dynamic": false, + "properties": { + "title": { + "type": "text" + }, + "description": { + "type": "text" + } + } + }, "visualization": { "dynamic": false, "properties": { @@ -1657,6 +1657,9 @@ "auth_type": { "type": "keyword" }, + "connection_type": { + "type": "keyword" + }, "username": { "type": "keyword" }, @@ -1743,6 +1746,12 @@ }, "broker_buffer_size": { "type": "integer" + }, + "required_acks": { + "type": "integer" + }, + "channel_buffer_size": { + "type": "integer" } } }, diff --git a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts index c5ce6a38d9dc9..d0b9d01272b24 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/group2/check_registered_types.test.ts @@ -105,7 +105,7 @@ describe('checking migration metadata changes on all registered SO types', () => "infrastructure-ui-source": "113182d6895764378dfe7fa9fa027244f3a457c4", "ingest-agent-policies": "f11cc19275f4c3e4ee7c5cd6423b6706b21b989d", "ingest-download-sources": "d7edc5e588d9afa61c4b831604582891c54ef1c7", - "ingest-outputs": "bffa0fd93dfdde904d7f5aff77df72d1c35938d9", + "ingest-outputs": "b4e636b13a5d0f89f0400fb67811d4cca4736eb0", "ingest-package-policies": "55816507db0134b8efbe0509e311a91ce7e1c6cc", "ingest_manager_settings": "418311b03c8eda53f5d2ea6f54c1356afaa65511", "inventory-view": "b8683c8e352a286b4aca1ab21003115a4800af83", diff --git a/x-pack/plugins/fleet/common/constants/output.ts b/x-pack/plugins/fleet/common/constants/output.ts index b23fbc3cc2c2a..59f3ceff36a0f 100644 --- a/x-pack/plugins/fleet/common/constants/output.ts +++ b/x-pack/plugins/fleet/common/constants/output.ts @@ -42,6 +42,12 @@ export const kafkaAuthType = { Userpass: 'user_pass', Ssl: 'ssl', Kerberos: 'kerberos', + None: 'none', +} as const; + +export const kafkaConnectionType = { + Plaintext: 'plaintext', + Encryption: 'encryption', } as const; export const kafkaSaslMechanism = { @@ -60,18 +66,19 @@ export const kafkaTopicWhenType = { Equals: 'equals', Contains: 'contains', Regexp: 'regexp', - Range: 'range', - Network: 'network', - HasFields: 'has_fields', - Or: 'or', - And: 'and', - Not: 'not', } as const; export const kafkaAcknowledgeReliabilityLevel = { - Commit: 'Wait for local commit', - Replica: 'Wait for all replicas to commit', - DoNotWait: 'Do not wait', + Commit: 1, + Replica: -1, + DoNotWait: 0, +} as const; + +export const kafkaVerificationModes = { + Full: 'full', + None: 'none', + Strict: 'strict', + Certificate: 'certificate', } as const; export const kafkaSupportedVersions = [ diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index cc1ad5c98c32a..200cebba48cc7 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -7701,6 +7701,15 @@ }, "key": { "type": "string" + }, + "verification_mode": { + "type": "string", + "enum": [ + "none", + "full", + "certificate", + "strict" + ] } } }, @@ -7751,6 +7760,13 @@ "auth_type": { "type": "string" }, + "connection_type": { + "type": "string", + "enum": [ + "plaintext", + "encryption" + ] + }, "username": { "type": "string" }, @@ -7826,11 +7842,8 @@ "broker_timeout": { "type": "number" }, - "broker_buffer_size": { + "required_acks": { "type": "number" - }, - "broker_ack_reliability": { - "type": "string" } }, "required": [ @@ -8103,6 +8116,15 @@ }, "key": { "type": "string" + }, + "verification_mode": { + "type": "string", + "enum": [ + "none", + "full", + "certificate", + "strict" + ] } } }, @@ -8153,6 +8175,13 @@ "auth_type": { "type": "string" }, + "connection_type": { + "type": "string", + "enum": [ + "plaintext", + "encryption" + ] + }, "username": { "type": "string" }, @@ -8228,10 +8257,7 @@ "broker_timeout": { "type": "number" }, - "broker_ack_reliability": { - "type": "string" - }, - "broker_buffer_size": { + "required_acks": { "type": "number" } }, diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index 0d72245fa2d99..6c216e464a104 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -4959,6 +4959,13 @@ components: type: string key: type: string + verification_mode: + type: string + enum: + - none + - full + - certificate + - strict proxy_id: type: string shipper: @@ -4990,6 +4997,11 @@ components: type: string auth_type: type: string + connection_type: + type: string + enum: + - plaintext + - encryption username: type: string password: @@ -5038,10 +5050,8 @@ components: type: number broker_timeout: type: number - broker_buffer_size: + required_acks: type: number - broker_ack_reliability: - type: string required: - name - type @@ -5223,6 +5233,13 @@ components: type: string key: type: string + verification_mode: + type: string + enum: + - none + - full + - certificate + - strict proxy_id: type: string shipper: @@ -5254,6 +5271,11 @@ components: type: string auth_type: type: string + connection_type: + type: string + enum: + - plaintext + - encryption username: type: string password: @@ -5302,9 +5324,7 @@ components: type: number broker_timeout: type: number - broker_ack_reliability: - type: string - broker_buffer_size: + required_acks: type: number required: - name diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/output_create_request_kafka.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/output_create_request_kafka.yaml index dbed2b44dc08a..fa76c2301ed94 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/output_create_request_kafka.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/output_create_request_kafka.yaml @@ -35,6 +35,9 @@ properties: type: string key: type: string + verification_mode: + type: string + enum: ['none', 'full', 'certificate', 'strict'] proxy_id: type: string shipper: @@ -66,6 +69,9 @@ properties: type: string auth_type: type: string + connection_type: + type: string + enum: ['plaintext', 'encryption'] username: type: string password: @@ -114,10 +120,8 @@ properties: type: number broker_timeout: type: number - broker_buffer_size: + required_acks: type: number - broker_ack_reliability: - type: string required: - name - type diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/output_update_request_kafka.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/output_update_request_kafka.yaml index bb1e76fa70a55..2ce5525a1a9f4 100644 --- a/x-pack/plugins/fleet/common/openapi/components/schemas/output_update_request_kafka.yaml +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/output_update_request_kafka.yaml @@ -35,6 +35,9 @@ properties: type: string key: type: string + verification_mode: + type: string + enum: ['none', 'full', 'certificate', 'strict'] proxy_id: type: string shipper: @@ -66,6 +69,9 @@ properties: type: string auth_type: type: string + connection_type: + type: string + enum: ['plaintext', 'encryption'] username: type: string password: @@ -114,9 +120,7 @@ properties: type: number broker_timeout: type: number - broker_ack_reliability: - type: string - broker_buffer_size: + required_acks: type: number required: - name diff --git a/x-pack/plugins/fleet/common/types/models/output.ts b/x-pack/plugins/fleet/common/types/models/output.ts index 95f353575afd6..a537e0ab0233b 100644 --- a/x-pack/plugins/fleet/common/types/models/output.ts +++ b/x-pack/plugins/fleet/common/types/models/output.ts @@ -11,14 +11,18 @@ import type { kafkaAuthType, kafkaCompressionType, kafkaSaslMechanism } from '.. import type { kafkaPartitionType } from '../../constants'; import type { kafkaTopicWhenType } from '../../constants'; import type { kafkaAcknowledgeReliabilityLevel } from '../../constants'; +import type { kafkaVerificationModes } from '../../constants'; +import type { kafkaConnectionType } from '../../constants'; export type OutputType = typeof outputType; export type KafkaCompressionType = typeof kafkaCompressionType; export type KafkaAuthType = typeof kafkaAuthType; +export type KafkaConnectionTypeType = typeof kafkaConnectionType; export type KafkaSaslMechanism = typeof kafkaSaslMechanism; export type KafkaPartitionType = typeof kafkaPartitionType; export type KafkaTopicWhenType = typeof kafkaTopicWhenType; export type KafkaAcknowledgeReliabilityLevel = typeof kafkaAcknowledgeReliabilityLevel; +export type KafkaVerificationMode = typeof kafkaVerificationModes; interface NewBaseOutput { is_default: boolean; @@ -34,6 +38,7 @@ interface NewBaseOutput { certificate_authorities?: string[]; certificate?: string; key?: string; + verification_mode?: ValueOf; } | null; proxy_id?: string | null; shipper?: ShipperOutput | null; @@ -76,6 +81,7 @@ export interface KafkaOutput extends NewBaseOutput { compression?: ValueOf; compression_level?: number; auth_type?: ValueOf; + connection_type?: ValueOf; username?: string; password?: string; sasl?: { @@ -105,6 +111,5 @@ export interface KafkaOutput extends NewBaseOutput { }>; timeout?: number; broker_timeout?: number; - broker_ack_reliability?: ValueOf; - broker_buffer_size?: number; + required_acks?: ValueOf; } diff --git a/x-pack/plugins/fleet/cypress/e2e/fleet_settings_outputs.cy.ts b/x-pack/plugins/fleet/cypress/e2e/fleet_settings_outputs.cy.ts index 45ff5257fc7c2..2d9f33d8e1efa 100644 --- a/x-pack/plugins/fleet/cypress/e2e/fleet_settings_outputs.cy.ts +++ b/x-pack/plugins/fleet/cypress/e2e/fleet_settings_outputs.cy.ts @@ -5,10 +5,6 @@ * 2.0. */ -import { allowedExperimentalValues } from '../../common/experimental_features'; - -import { ExperimentalFeaturesService } from '../../public/services'; - import { getSpecificSelectorId, SETTINGS_CONFIRM_MODAL_BTN, @@ -42,323 +38,358 @@ describe('Outputs', () => { }); describe('Kafka', () => { - ExperimentalFeaturesService.init(allowedExperimentalValues); - - const { kafkaOutput: isKafkaOutputEnabled } = ExperimentalFeaturesService.get(); - - // TODO: Remove IF statement once Kafka is GA - if (!isKafkaOutputEnabled) { - it('is not available', () => { - visit('/app/fleet/settings'); - }); - } else { - describe('Form validation', () => { - it('renders all form fields', () => { - selectKafkaOutput(); - - cy.getBySel(SETTINGS_OUTPUTS.NAME_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.VERSION_SELECT); - cy.get('[placeholder="Specify host"'); - cy.getBySel(SETTINGS_OUTPUTS.ADD_HOST_ROW_BTN); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SELECT).within(() => { - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_PASSWORD_OPTION); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SSL_OPTION); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_KERBEROS_OPTION); - }); - - // Verify user/pass fields - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_PASSWORD_INPUT); - - // Verify SSL fields - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SSL_OPTION).click(); - cy.get('[placeholder="Specify certificate authority"]'); - cy.get('[placeholder="Specify ssl certificate"]'); - cy.get('[placeholder="Specify certificate key"]'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_PASSWORD_OPTION).click(); - - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_SELECT).within(() => { - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_PLAIN_OPTION); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_SCRAM_256_OPTION); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_SCRAM_512_OPTION); - }); + describe('Form validation', () => { + it('renders all form fields', () => { + selectKafkaOutput(); + + cy.getBySel(SETTINGS_OUTPUTS.NAME_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.VERSION_SELECT); + cy.get('[placeholder="Specify host"'); + cy.getBySel(SETTINGS_OUTPUTS.ADD_HOST_ROW_BTN); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SELECT).within(() => { + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_NONE_OPTION); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_PASSWORD_OPTION); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SSL_OPTION); + }); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_PANEL).within(() => { - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_SELECT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_RANDOM_OPTION); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_HASH_OPTION); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_ROUND_ROBIN_OPTION); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_EVENTS_INPUT); - }); + // Verify user/pass fields + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_PASSWORD_INPUT); + cy.get('[placeholder="Specify certificate authority"]'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_VERIFICATION_MODE_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_CONNECTION_TYPE_SELECT).should( + 'not.exist' + ); + + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_SELECT).within(() => { + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_PLAIN_OPTION); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_SCRAM_256_OPTION); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_SCRAM_512_OPTION); + }); - // Verify Round Robin fields - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_RANDOM_OPTION).click(); + // Verify SSL fields + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SSL_OPTION).click(); + cy.get('[placeholder="Specify certificate authority"]'); + cy.get('[placeholder="Specify ssl certificate"]'); + cy.get('[placeholder="Specify certificate key"]'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_VERIFICATION_MODE_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_CONNECTION_TYPE_SELECT).should( + 'not.exist' + ); + + // Verify None fields + + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_NONE_OPTION).click(); + + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_SELECT).should('not.exist'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_INPUT).should('not.exist'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_PASSWORD_INPUT).should('not.exist'); + cy.get('[placeholder="Specify ssl certificate"]').should('not.exist'); + cy.get('[placeholder="Specify certificate key"]').should('not.exist'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_VERIFICATION_MODE_INPUT).should( + 'not.exist' + ); + cy.get('[placeholder="Specify certificate authority"]').should('not.exist'); + + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_CONNECTION_TYPE_SELECT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_CONNECTION_TYPE_PLAIN_OPTION); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_CONNECTION_TYPE_ENCRYPTION_OPTION); + + cy.getBySel( + SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_CONNECTION_TYPE_ENCRYPTION_OPTION + ).click(); + + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_VERIFICATION_MODE_INPUT); + cy.get('[placeholder="Specify certificate authority"]'); + + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_PASSWORD_OPTION).click(); + + // Verify Partitioning fields + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_PANEL).within(() => { + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_SELECT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_RANDOM_OPTION); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_HASH_OPTION); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_ROUND_ROBIN_OPTION); cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_EVENTS_INPUT); + }); - // Verify Hash fields - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_HASH_OPTION).click(); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_HASH_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_RANDOM_OPTION).click(); - - // Topics - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_PANEL).within(() => { - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_DEFAULT_TOPIC_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_ADD_ROW_BUTTON); - }); + // Verify Round Robin fields + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_RANDOM_OPTION).click(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_EVENTS_INPUT); - // Verify one topic processor fields - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_ADD_ROW_BUTTON).click(); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_TOPIC_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT); - - // Verify additional topic processor fields - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_ADD_ROW_BUTTON).click(); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_TOPIC_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT); - cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.TOPICS_TOPIC_INPUT, 1)); - cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT, 1)); - cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT, 1)); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_DRAG_HANDLE_ICON); - - // Verify remove topic processors - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_REMOVE_ROW_BUTTON).click(); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_REMOVE_ROW_BUTTON).click(); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_TOPIC_INPUT).should('not.exist'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT).should('not.exist'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT).should('not.exist'); - - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_PANEL).within(() => { - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_KEY_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_VALUE_INPUT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).should('be.disabled'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_REMOVE_ROW_BUTTON).should('be.disabled'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_CLIENT_ID_INPUT); - }); + // Verify Hash fields + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_HASH_OPTION).click(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_HASH_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_RANDOM_OPTION).click(); - // Verify add header - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_KEY_INPUT).type('key'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_VALUE_INPUT).type('value'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).should('be.enabled'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_REMOVE_ROW_BUTTON).should('be.disabled'); + // Topics + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_PANEL).within(() => { + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_DEFAULT_TOPIC_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_ADD_ROW_BUTTON); + }); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).click(); - cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.HEADERS_KEY_INPUT, 1)); - cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.HEADERS_VALUE_INPUT, 1)); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).should('be.enabled'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_REMOVE_ROW_BUTTON).should('be.enabled'); - - // Verify remove header - cy.getBySel( - getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.HEADERS_REMOVE_ROW_BUTTON, 1) - ).click(); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).should('be.enabled'); + // Verify one topic processor fields + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_ADD_ROW_BUTTON).click(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_TOPIC_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT); + + // Verify additional topic processor fields + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_ADD_ROW_BUTTON).click(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_TOPIC_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT); + cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.TOPICS_TOPIC_INPUT, 1)); + cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT, 1)); + cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT, 1)); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_DRAG_HANDLE_ICON); + + // Verify remove topic processors + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_REMOVE_ROW_BUTTON).click(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_REMOVE_ROW_BUTTON).click(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_TOPIC_INPUT).should('not.exist'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT).should('not.exist'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT).should('not.exist'); + + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_PANEL).within(() => { + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_KEY_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_VALUE_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).should('be.disabled'); cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_REMOVE_ROW_BUTTON).should('be.disabled'); - - // Compression - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_CODEC_INPUT).should('not.exist'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_SWITCH).click(); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_LEVEL_INPUT).should('not.exist'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_CODEC_INPUT).select('gzip'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_LEVEL_INPUT).should('exist'); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_LEVEL_INPUT).select('1'); - - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.BROKER_PANEL).within(() => { - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.BROKER_ACK_RELIABILITY_SELECT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.BROKER_CHANNEL_BUFFER_SIZE_SELECT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.BROKER_TIMEOUT_SELECT); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.BROKER_REACHABILITY_TIMEOUT_SELECT); - }); - cy.getBySel(SETTINGS_OUTPUTS_KAFKA.KEY_INPUT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_CLIENT_ID_INPUT).should( + 'have.value', + 'Elastic' + ); }); - it('displays proper error messages', () => { - selectKafkaOutput(); - cy.getBySel(SETTINGS_SAVE_BTN).click(); - - cy.contains('Name is required'); - cy.contains('URL is required'); - cy.contains('Username is required'); - cy.contains('Password is required'); - cy.contains('Default topic is required'); - shouldDisplayError(SETTINGS_OUTPUTS.NAME_INPUT); - shouldDisplayError(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_INPUT); - shouldDisplayError(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_PASSWORD_INPUT); - shouldDisplayError(SETTINGS_OUTPUTS_KAFKA.TOPICS_DEFAULT_TOPIC_INPUT); + // Verify add header + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_KEY_INPUT).type('key'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_VALUE_INPUT).type('value'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).should('be.enabled'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_REMOVE_ROW_BUTTON).should('be.disabled'); + + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).click(); + cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.HEADERS_KEY_INPUT, 1)); + cy.getBySel(getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.HEADERS_VALUE_INPUT, 1)); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).should('be.enabled'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_REMOVE_ROW_BUTTON).should('be.enabled'); + + // Verify remove header + cy.getBySel( + getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.HEADERS_REMOVE_ROW_BUTTON, 1) + ).click(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_ADD_ROW_BUTTON).should('be.enabled'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_REMOVE_ROW_BUTTON).should('be.disabled'); + + // Compression + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_CODEC_INPUT).should('not.exist'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_SWITCH).click(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_LEVEL_INPUT).should('not.exist'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_CODEC_INPUT).select('gzip'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_LEVEL_INPUT).should('exist'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.COMPRESSION_LEVEL_INPUT).select('1'); + + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.BROKER_PANEL).within(() => { + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.BROKER_ACK_RELIABILITY_SELECT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.BROKER_TIMEOUT_SELECT); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.BROKER_REACHABILITY_TIMEOUT_SELECT); }); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.KEY_INPUT); }); - // Test buttons presence before accessing output directly via url and delete via api - describe('Output operations', () => { - let kafkaOutputId: string; + it('displays proper error messages', () => { + selectKafkaOutput(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.HEADERS_CLIENT_ID_INPUT).clear(); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.TOPICS_ADD_ROW_BUTTON).click(); + cy.getBySel(SETTINGS_SAVE_BTN).click(); + + cy.contains('Name is required'); + cy.contains('Host is required'); + cy.contains('Username is required'); + cy.contains('Password is required'); + cy.contains('Default topic is required'); + cy.contains('Topic is required'); + cy.contains( + 'Client ID is invalid. Only letters, numbers, dots, underscores, and dashes are allowed.' + ); + cy.contains('Must be a key, value pair i.e. "http.response.code: 200"'); + shouldDisplayError(SETTINGS_OUTPUTS.NAME_INPUT); + shouldDisplayError(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_INPUT); + shouldDisplayError(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_PASSWORD_INPUT); + shouldDisplayError(SETTINGS_OUTPUTS_KAFKA.TOPICS_DEFAULT_TOPIC_INPUT); + shouldDisplayError(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT); + shouldDisplayError(SETTINGS_OUTPUTS_KAFKA.TOPICS_TOPIC_INPUT); + shouldDisplayError(SETTINGS_OUTPUTS_KAFKA.HEADERS_CLIENT_ID_INPUT); + }); + }); - before(() => { - loadKafkaOutput().then((data) => { - kafkaOutputId = data.item.id; - }); - }); + // Test buttons presence before accessing output directly via url and delete via api + describe('Output operations', () => { + let kafkaOutputId: string; - it('opens edit modal', () => { - visit('/app/fleet/settings'); - cy.get(`a[href="/app/fleet/settings/outputs/${kafkaOutputId}"]`) - .parents('tr') - .within(() => { - cy.contains(kafkaOutputBody.name); - cy.contains(kafkaOutputBody.type); - cy.contains(kafkaOutputBody.hosts[0]); - cy.getBySel('editOutputBtn').click(); - cy.url().should('include', `/app/fleet/settings/outputs/${kafkaOutputId}`); - }); - }); - it('delete output', () => { - visit('/app/fleet/settings'); - cy.get(`a[href="/app/fleet/settings/outputs/${kafkaOutputId}"]`) - .parents('tr') - .within(() => { - cy.get('[title="Delete"]').click(); - }); - cy.getBySel(SETTINGS_CONFIRM_MODAL_BTN).click(); - cy.get(`a[href="app/fleet/settings/outputs/${kafkaOutputId}"]`).should('not.exist'); + before(() => { + loadKafkaOutput().then((data) => { + kafkaOutputId = data.item.id; }); }); - describe('Form submit', () => { - let kafkaOutputId: string; - - before(() => { - interceptOutputId((id) => { - kafkaOutputId = id; + it('opens edit modal', () => { + visit('/app/fleet/settings'); + cy.get(`a[href="/app/fleet/settings/outputs/${kafkaOutputId}"]`) + .parents('tr') + .within(() => { + cy.contains(kafkaOutputBody.name); + cy.contains(kafkaOutputBody.type); + cy.contains(kafkaOutputBody.hosts[0]); + cy.getBySel('editOutputBtn').click(); + cy.url().should('include', `/app/fleet/settings/outputs/${kafkaOutputId}`); }); - }); + }); + it('delete output', () => { + visit('/app/fleet/settings'); + cy.get(`a[href="/app/fleet/settings/outputs/${kafkaOutputId}"]`) + .parents('tr') + .within(() => { + cy.get('[title="Delete"]').click(); + }); + cy.getBySel(SETTINGS_CONFIRM_MODAL_BTN).click(); + cy.get(`a[href="app/fleet/settings/outputs/${kafkaOutputId}"]`).should('not.exist'); + }); + }); - after(() => { - cleanupOutput(kafkaOutputId); + describe('Form submit', () => { + let kafkaOutputId: string; + + before(() => { + interceptOutputId((id) => { + kafkaOutputId = id; }); + }); - it('saves the output', () => { - selectKafkaOutput(); + after(() => { + cleanupOutput(kafkaOutputId); + }); - fillInKafkaOutputForm(); + it('saves the output', () => { + selectKafkaOutput(); - cy.intercept('POST', '**/api/fleet/outputs').as('saveOutput'); + fillInKafkaOutputForm(); - cy.getBySel(SETTINGS_SAVE_BTN).click(); + cy.intercept('POST', '**/api/fleet/outputs').as('saveOutput'); - cy.wait('@saveOutput').then((interception) => { - const responseBody = interception.response?.body; - cy.visit(`/app/fleet/settings/outputs/${responseBody?.item?.id}`); - }); + cy.getBySel(SETTINGS_SAVE_BTN).click(); - validateSavedKafkaOutputForm(); + cy.wait('@saveOutput').then((interception) => { + const responseBody = interception.response?.body; + cy.visit(`/app/fleet/settings/outputs/${responseBody?.item?.id}`); }); + + validateSavedKafkaOutputForm(); }); + }); - describe('Form edit', () => { - let kafkaOutputId: string; + describe('Form edit', () => { + let kafkaOutputId: string; - before(() => { - loadKafkaOutput().then((data) => { - kafkaOutputId = data.item.id; - }); - }); - after(() => { - cleanupOutput(kafkaOutputId); + before(() => { + loadKafkaOutput().then((data) => { + kafkaOutputId = data.item.id; }); + }); + after(() => { + cleanupOutput(kafkaOutputId); + }); - it('edits the output', () => { - visit(`/app/fleet/settings/outputs/${kafkaOutputId}`); + it('edits the output', () => { + visit(`/app/fleet/settings/outputs/${kafkaOutputId}`); - resetKafkaOutputForm(); + resetKafkaOutputForm(); - fillInKafkaOutputForm(); + fillInKafkaOutputForm(); - cy.getBySel(SETTINGS_SAVE_BTN).click(); - cy.getBySel(SETTINGS_CONFIRM_MODAL_BTN).click(); - visit(`/app/fleet/settings/outputs/${kafkaOutputId}`); + cy.getBySel(SETTINGS_SAVE_BTN).click(); + cy.getBySel(SETTINGS_CONFIRM_MODAL_BTN).click(); + visit(`/app/fleet/settings/outputs/${kafkaOutputId}`); - validateSavedKafkaOutputForm(); - }); + validateSavedKafkaOutputForm(); }); + }); - describe('Form output type change', () => { - let kafkaOutputToESId: string; - let kafkaOutputToLogstashId: string; - let logstashOutputToKafkaId: string; - let esOutputToKafkaId: string; + describe('Form output type change', () => { + let kafkaOutputToESId: string; + let kafkaOutputToLogstashId: string; + let logstashOutputToKafkaId: string; + let esOutputToKafkaId: string; - before(() => { - loadKafkaOutput().then((data) => { - kafkaOutputToESId = data.item.id; - }); - loadKafkaOutput().then((data) => { - kafkaOutputToLogstashId = data.item.id; - }); - loadESOutput().then((data) => { - esOutputToKafkaId = data.item.id; - }); - loadLogstashOutput().then((data) => { - logstashOutputToKafkaId = data.item.id; - }); + before(() => { + loadKafkaOutput().then((data) => { + kafkaOutputToESId = data.item.id; }); - after(() => { - cleanupOutput(kafkaOutputToESId); - cleanupOutput(kafkaOutputToLogstashId); - cleanupOutput(logstashOutputToKafkaId); - cleanupOutput(esOutputToKafkaId); + loadKafkaOutput().then((data) => { + kafkaOutputToLogstashId = data.item.id; }); - it('changes output type from es to kafka', () => { - validateOutputTypeChangeToKafka(esOutputToKafkaId); + loadESOutput().then((data) => { + esOutputToKafkaId = data.item.id; }); - - it('changes output type from logstash to kafka', () => { - validateOutputTypeChangeToKafka(logstashOutputToKafkaId); + loadLogstashOutput().then((data) => { + logstashOutputToKafkaId = data.item.id; }); + }); + after(() => { + cleanupOutput(kafkaOutputToESId); + cleanupOutput(kafkaOutputToLogstashId); + cleanupOutput(logstashOutputToKafkaId); + cleanupOutput(esOutputToKafkaId); + }); + it('changes output type from es to kafka', () => { + validateOutputTypeChangeToKafka(esOutputToKafkaId); + }); - it('changes output type from kafka to es', () => { - visit(`/app/fleet/settings/outputs/${kafkaOutputToESId}`); - cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).select('elasticsearch'); - cy.getBySel(kafkaOutputFormValues.name.selector).clear().type('kafka_to_es'); + it('changes output type from logstash to kafka', () => { + validateOutputTypeChangeToKafka(logstashOutputToKafkaId); + }); - cy.intercept('PUT', '**/api/fleet/outputs/**').as('saveOutput'); + it('changes output type from kafka to es', () => { + visit(`/app/fleet/settings/outputs/${kafkaOutputToESId}`); + cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).select('elasticsearch'); + cy.getBySel(kafkaOutputFormValues.name.selector).clear().type('kafka_to_es'); + cy.get('[placeholder="Specify host URL"').clear().type('https://localhost:5000'); - cy.getBySel(SETTINGS_SAVE_BTN).click(); - cy.getBySel(SETTINGS_CONFIRM_MODAL_BTN).click(); + cy.intercept('PUT', '**/api/fleet/outputs/**').as('saveOutput'); - // wait for the save request to finish to avoid race condition - cy.wait('@saveOutput').then(() => { - visit(`/app/fleet/settings/outputs/${kafkaOutputToESId}`); - }); + cy.getBySel(SETTINGS_SAVE_BTN).click(); + cy.getBySel(SETTINGS_CONFIRM_MODAL_BTN).click(); - cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).should('have.value', 'elasticsearch'); - cy.getBySel(kafkaOutputFormValues.name.selector).should('have.value', 'kafka_to_es'); + // wait for the save request to finish to avoid race condition + cy.wait('@saveOutput').then(() => { + visit(`/app/fleet/settings/outputs/${kafkaOutputToESId}`); }); - it('changes output type from kafka to logstash', () => { - visit(`/app/fleet/settings/outputs/${kafkaOutputToLogstashId}`); - cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).select('logstash'); - cy.getBySel(kafkaOutputFormValues.name.selector).clear().type('kafka_to_logstash'); - cy.get('[placeholder="Specify host"').clear().type('localhost:5000'); - cy.get('[placeholder="Specify ssl certificate"]').clear().type('SSL CERTIFICATE'); - cy.get('[placeholder="Specify certificate key"]').clear().type('SSL KEY'); + cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).should('have.value', 'elasticsearch'); + cy.getBySel(kafkaOutputFormValues.name.selector).should('have.value', 'kafka_to_es'); + }); - cy.intercept('PUT', '**/api/fleet/outputs/**').as('saveOutput'); + it('changes output type from kafka to logstash', () => { + visit(`/app/fleet/settings/outputs/${kafkaOutputToLogstashId}`); + cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).select('logstash'); + cy.getBySel(kafkaOutputFormValues.name.selector).clear().type('kafka_to_logstash'); + cy.get('[placeholder="Specify host"').clear().type('localhost:5000'); + cy.get('[placeholder="Specify ssl certificate"]').clear().type('SSL CERTIFICATE'); + cy.get('[placeholder="Specify certificate key"]').clear().type('SSL KEY'); - cy.getBySel(SETTINGS_SAVE_BTN).click(); - cy.getBySel(SETTINGS_CONFIRM_MODAL_BTN).click(); + cy.intercept('PUT', '**/api/fleet/outputs/**').as('saveOutput'); - // wait for the save request to finish to avoid race condition - cy.wait('@saveOutput').then(() => { - visit(`/app/fleet/settings/outputs/${kafkaOutputToLogstashId}`); - }); + cy.getBySel(SETTINGS_SAVE_BTN).click(); + cy.getBySel(SETTINGS_CONFIRM_MODAL_BTN).click(); - cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).should('have.value', 'logstash'); - cy.getBySel(kafkaOutputFormValues.name.selector).should( - 'have.value', - 'kafka_to_logstash' - ); + // wait for the save request to finish to avoid race condition + cy.wait('@saveOutput').then(() => { + visit(`/app/fleet/settings/outputs/${kafkaOutputToLogstashId}`); }); + + cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).should('have.value', 'logstash'); + cy.getBySel(kafkaOutputFormValues.name.selector).should('have.value', 'kafka_to_logstash'); }); - } + }); }); }); diff --git a/x-pack/plugins/fleet/cypress/screens/fleet.ts b/x-pack/plugins/fleet/cypress/screens/fleet.ts index b21dfa7c4e66c..e6b6ac1f47008 100644 --- a/x-pack/plugins/fleet/cypress/screens/fleet.ts +++ b/x-pack/plugins/fleet/cypress/screens/fleet.ts @@ -136,11 +136,16 @@ export const getSpecificSelectorId = (selector: string, id: number) => { export const SETTINGS_OUTPUTS_KAFKA = { VERSION_SELECT: 'settingsOutputsFlyout.kafkaVersionInput', AUTHENTICATION_SELECT: 'settingsOutputsFlyout.kafkaAuthenticationRadioInput', + AUTHENTICATION_NONE_OPTION: 'kafkaAuthenticationNoneRadioButton', AUTHENTICATION_USERNAME_PASSWORD_OPTION: 'kafkaAuthenticationUsernamePasswordRadioButton', AUTHENTICATION_SSL_OPTION: 'kafkaAuthenticationSSLRadioButton', AUTHENTICATION_KERBEROS_OPTION: 'kafkaAuthenticationKerberosRadioButton', AUTHENTICATION_USERNAME_INPUT: 'settingsOutputsFlyout.kafkaUsernameInput', AUTHENTICATION_PASSWORD_INPUT: 'settingsOutputsFlyout.kafkaPasswordInput', + AUTHENTICATION_VERIFICATION_MODE_INPUT: 'settingsOutputsFlyout.kafkaVerificationModeInput', + AUTHENTICATION_CONNECTION_TYPE_SELECT: 'settingsOutputsFlyout.kafkaConnectionTypeRadioInput', + AUTHENTICATION_CONNECTION_TYPE_PLAIN_OPTION: 'kafkaConnectionTypePlaintextRadioButton', + AUTHENTICATION_CONNECTION_TYPE_ENCRYPTION_OPTION: 'kafkaConnectionTypeEncryptionRadioButton', AUTHENTICATION_SASL_SELECT: 'settingsOutputsFlyout.kafkaSaslInput', AUTHENTICATION_SASL_PLAIN_OPTION: 'kafkaSaslPlainRadioButton', AUTHENTICATION_SASL_SCRAM_256_OPTION: 'kafkaSaslScramSha256RadioButton', @@ -173,7 +178,6 @@ export const SETTINGS_OUTPUTS_KAFKA = { BROKER_PANEL: 'settingsOutputsFlyout.kafkaBrokerSettingsPanel', BROKER_TIMEOUT_SELECT: 'settingsOutputsFlyout.kafkaBrokerTimeoutInput', BROKER_REACHABILITY_TIMEOUT_SELECT: 'settingsOutputsFlyout.kafkaBrokerReachabilityTimeoutInput', - BROKER_CHANNEL_BUFFER_SIZE_SELECT: 'settingsOutputsFlyout.kafkaBrokerChannelBufferSizeInput', BROKER_ACK_RELIABILITY_SELECT: 'settingsOutputsFlyout.kafkaBrokerAckReliabilityInputLabel', KEY_INPUT: 'settingsOutputsFlyout.kafkaKeyInput', }; diff --git a/x-pack/plugins/fleet/cypress/screens/fleet_outputs.ts b/x-pack/plugins/fleet/cypress/screens/fleet_outputs.ts index c5f7a852197c1..de6ef1097b74a 100644 --- a/x-pack/plugins/fleet/cypress/screens/fleet_outputs.ts +++ b/x-pack/plugins/fleet/cypress/screens/fleet_outputs.ts @@ -21,6 +21,7 @@ export const selectKafkaOutput = () => { visit('/app/fleet/settings'); cy.getBySel(SETTINGS_OUTPUTS.ADD_BTN).click(); cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).select('kafka'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_PASSWORD_OPTION).click(); }; export const shouldDisplayError = (handler: string) => { @@ -56,7 +57,7 @@ export const kafkaOutputBody = { name: 'kafka_test1', type: 'kafka', is_default: false, - hosts: ['https://example.com'], + hosts: ['example.com:2000'], topics: [{ topic: 'test' }], auth_type: 'user_pass', username: 'kafka', @@ -96,6 +97,10 @@ export const kafkaOutputFormValues = { selector: SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_PASSWORD_INPUT, value: 'test_password', }, + verificationMode: { + selector: SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_VERIFICATION_MODE_INPUT, + value: 'certificate', + }, hash: { selector: SETTINGS_OUTPUTS_KAFKA.PARTITIONING_HASH_INPUT, value: 'testHash', @@ -110,7 +115,7 @@ export const kafkaOutputFormValues = { }, firstTopicCondition: { selector: SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT, - value: 'testCondition', + value: 'testCondition: abc', }, firstTopicWhen: { selector: SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT, @@ -122,7 +127,7 @@ export const kafkaOutputFormValues = { }, secondTopicCondition: { selector: getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.TOPICS_CONDITION_INPUT, 1), - value: 'testCondition1', + value: 'testCondition1: dca', }, secondTopicWhen: { selector: getSpecificSelectorId(SETTINGS_OUTPUTS_KAFKA.TOPICS_WHEN_INPUT, 1), @@ -154,11 +159,7 @@ export const kafkaOutputFormValues = { }, brokerAckReliability: { selector: SETTINGS_OUTPUTS_KAFKA.BROKER_ACK_RELIABILITY_SELECT, - value: 'Do not wait', - }, - brokerChannelBufferSize: { - selector: SETTINGS_OUTPUTS_KAFKA.BROKER_CHANNEL_BUFFER_SIZE_SELECT, - value: '512', + value: '0', }, brokerTimeout: { selector: SETTINGS_OUTPUTS_KAFKA.BROKER_TIMEOUT_SELECT, @@ -185,9 +186,13 @@ export const resetKafkaOutputForm = () => { export const fillInKafkaOutputForm = () => { cy.getBySel(kafkaOutputFormValues.name.selector).type(kafkaOutputFormValues.name.value); - cy.get('[placeholder="Specify host"').clear().type('http://localhost:5000'); + cy.get('[placeholder="Specify host"').clear().type('localhost:5000'); cy.getBySel(kafkaOutputFormValues.username.selector).type(kafkaOutputFormValues.username.value); cy.getBySel(kafkaOutputFormValues.password.selector).type(kafkaOutputFormValues.password.value); + cy.getBySel(kafkaOutputFormValues.verificationMode.selector).select( + kafkaOutputFormValues.verificationMode.value + ); + cy.get('[placeholder="Specify certificate authority"]').clear().type('testCA'); cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_SCRAM_256_OPTION).click(); cy.getBySel(SETTINGS_OUTPUTS_KAFKA.PARTITIONING_HASH_OPTION).click(); @@ -249,9 +254,6 @@ export const fillInKafkaOutputForm = () => { cy.getBySel(kafkaOutputFormValues.brokerAckReliability.selector).select( kafkaOutputFormValues.brokerAckReliability.value ); - cy.getBySel(kafkaOutputFormValues.brokerChannelBufferSize.selector).select( - kafkaOutputFormValues.brokerChannelBufferSize.value - ); cy.getBySel(kafkaOutputFormValues.brokerTimeout.selector).select( kafkaOutputFormValues.brokerTimeout.value ); @@ -267,6 +269,9 @@ export const validateSavedKafkaOutputForm = () => { cy.getBySel(selector).should('have.value', value); }); + cy.get('[placeholder="Specify host"').should('have.value', 'localhost:5000'); + cy.get('[placeholder="Specify certificate authority"]').should('have.value', 'testCA'); + cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).should('have.value', 'kafka'); cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_SASL_SCRAM_256_OPTION) @@ -285,6 +290,8 @@ export const validateOutputTypeChangeToKafka = (outputId: string) => { visit(`/app/fleet/settings/outputs/${outputId}`); cy.getBySel(kafkaOutputFormValues.name.selector).clear(); cy.getBySel(SETTINGS_OUTPUTS.TYPE_INPUT).select('kafka'); + cy.getBySel(SETTINGS_OUTPUTS_KAFKA.AUTHENTICATION_USERNAME_PASSWORD_OPTION).click(); + fillInKafkaOutputForm(); cy.intercept('PUT', '**/api/fleet/outputs/**').as('saveOutput'); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.test.tsx index d577a1643ac0c..46b367011395c 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.test.tsx @@ -43,9 +43,6 @@ const logstashInputsLabels = [ ]; const kafkaInputsLabels = [ - 'Username', - 'Password', - 'SASL Mechanism', 'Partitioning strategy', 'Number of events', 'Default topic', @@ -53,7 +50,6 @@ const kafkaInputsLabels = [ 'Value', 'Broker timeout', 'Broker reachability timeout', - 'Channel buffer size', 'ACK Reliability', 'Key (optional)', ]; @@ -143,7 +139,7 @@ describe('EditOutputFlyout', () => { }); // Does not show logstash inputs - logstashInputsLabels.forEach((label) => { + ['Client SSL certificate key', 'Client SSL certificate'].forEach((label) => { expect(utils.queryByLabelText(label)).toBeNull(); }); }); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka.tsx index 222def40b5a75..f6af3270487be 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka.tsx @@ -84,13 +84,13 @@ export const OutputFormKafkaSection: React.FunctionComponent = (props) => helpText={ ), @@ -105,6 +105,7 @@ export const OutputFormKafkaSection: React.FunctionComponent = (props) => + diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_authentication.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_authentication.tsx index 271f3fe144aca..42a7b66727597 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_authentication.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_authentication.tsx @@ -5,14 +5,16 @@ * 2.0. */ -import React from 'react'; +import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { + EuiFieldPassword, EuiFieldText, EuiFormRow, EuiPanel, EuiRadioGroup, + EuiSelect, EuiSpacer, EuiTextArea, EuiTitle, @@ -20,7 +22,13 @@ import { import { FormattedMessage } from '@kbn/i18n-react'; import { MultiRowInput } from '../multi_row_input'; -import { kafkaAuthType, kafkaSaslMechanism } from '../../../../../../../common/constants'; + +import { + kafkaAuthType, + kafkaConnectionType, + kafkaSaslMechanism, + kafkaVerificationModes, +} from '../../../../../../../common/constants'; import type { OutputFormInputsType } from './use_output_form'; @@ -43,6 +51,11 @@ const kafkaSaslOptions = [ ]; const kafkaAuthenticationsOptions = [ + { + id: kafkaAuthType.None, + label: 'None', + 'data-test-subj': 'kafkaAuthenticationNoneRadioButton', + }, { id: kafkaAuthType.Userpass, label: 'Username / Password', @@ -53,11 +66,6 @@ const kafkaAuthenticationsOptions = [ label: 'SSL', 'data-test-subj': 'kafkaAuthenticationSSLRadioButton', }, - { - id: kafkaAuthType.Kerberos, - label: 'Kerberos', - 'data-test-subj': 'kafkaAuthenticationKerberosRadioButton', - }, ]; export const OutputFormKafkaAuthentication: React.FunctionComponent<{ @@ -65,28 +73,56 @@ export const OutputFormKafkaAuthentication: React.FunctionComponent<{ }> = (props) => { const { inputs } = props; + const kafkaVerificationModeOptions = useMemo( + () => + (Object.keys(kafkaVerificationModes) as Array).map( + (key) => { + return { + text: kafkaVerificationModes[key], + label: key, + }; + } + ), + [] + ); + + const kafkaConnectionTypeOptions = useMemo( + () => + (Object.keys(kafkaConnectionType) as Array).map((key) => { + return { + id: kafkaConnectionType[key], + label: key, + 'data-test-subj': `kafkaConnectionType${key}RadioButton`, + }; + }), + [] + ); + const renderAuthentication = () => { switch (inputs.kafkaAuthMethodInput.value) { + case kafkaAuthType.None: + return ( + + } + > + + + ); case kafkaAuthType.Ssl: return ( <> - ); - case kafkaAuthType.Kerberos: - return null; default: case kafkaAuthType.Userpass: return ( @@ -165,7 +199,8 @@ export const OutputFormKafkaAuthentication: React.FunctionComponent<{ } {...inputs.kafkaAuthPasswordInput.formRowProps} > - { + const displayEncryptionSection = + inputs.kafkaConnectionTypeInput.value !== kafkaConnectionType.Plaintext || + inputs.kafkaAuthMethodInput.value !== kafkaAuthType.None; + + if (!displayEncryptionSection) { + return null; + } + + return ( + <> + + + + + + } + > + + + + ); + }; + return ( - - -

    - + + +

    + +

    +
    + + + -

    -
    - - - - - {renderAuthentication()} -
    +
    + {renderAuthentication()} +
    + {renderEncryptionSection()} + ); }; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_broker.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_broker.tsx index f6b0477c81515..2fb40f3e5e376 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_broker.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_broker.tsx @@ -27,14 +27,18 @@ export const OutputFormKafkaBroker: React.FunctionComponent<{ inputs: OutputForm [] ); - const kafkaBrokerChannelBufferSizeOptions = useMemo( - () => - Array.from({ length: 4 }, (_, i) => Math.pow(2, i + 7)).map((buffer) => ({ - text: buffer, - label: `${buffer}`, - })), - [] - ); + const getAckReliabilityLabel = (value: number) => { + switch (value) { + case kafkaAcknowledgeReliabilityLevel.DoNotWait: + return 'No response'; + case kafkaAcknowledgeReliabilityLevel.Replica: + return 'Wait for all replicas to commit'; + default: + case kafkaAcknowledgeReliabilityLevel.Commit: + return 'Wait for local commit'; + } + }; + const kafkaBrokerAckReliabilityOptions = useMemo( () => ( @@ -44,7 +48,7 @@ export const OutputFormKafkaBroker: React.FunctionComponent<{ inputs: OutputForm ).map((key) => { return { text: kafkaAcknowledgeReliabilityLevel[key], - label: kafkaAcknowledgeReliabilityLevel[key], + label: getAckReliabilityLabel(kafkaAcknowledgeReliabilityLevel[key]), }; }), [] @@ -111,28 +115,6 @@ export const OutputFormKafkaBroker: React.FunctionComponent<{ inputs: OutputForm options={kafkaBrokerTimeoutOptions} /> - - } - helpText={ - - } - > - - } > diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_headers.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_headers.tsx index 3f605463a65bc..89ff4b5d0de7a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_headers.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_kafka_headers.tsx @@ -114,7 +114,7 @@ export const OutputFormKafkaHeaders: React.FunctionComponent<{ inputs: OutputFor const keyErrors = matchErrorsByIndex(index, 'key'); const valueErrors = matchErrorsByIndex(index, 'value'); return ( - <> +
    {index > 0 && } @@ -173,7 +173,7 @@ export const OutputFormKafkaHeaders: React.FunctionComponent<{ inputs: OutputFor /> - +
    ); })} {displayErrors(globalErrors)} @@ -198,6 +198,7 @@ export const OutputFormKafkaHeaders: React.FunctionComponent<{ inputs: OutputFor defaultMessage="Client ID" /> } + {...inputs.kafkaClientIdInput.formRowProps} > { @@ -64,7 +63,30 @@ export const OutputFormKafkaTopics: React.FunctionComponent<{ inputs: OutputForm acc[err.index] = []; } - acc[err.index].push(err.message); + if (!err.condition) { + acc[err.index].push(err.message); + } + + return acc; + }, []); + }, [errors]); + + const indexedConditionErrors = useMemo(() => { + if (!errors) { + return []; + } + return errors.reduce((acc, err) => { + if (err.index === undefined) { + return acc; + } + + if (!acc[err.index]) { + acc[err.index] = []; + } + + if (err.condition) { + acc[err.index].push(err.message); + } return acc; }, []); @@ -97,9 +119,10 @@ export const OutputFormKafkaTopics: React.FunctionComponent<{ inputs: OutputForm (index: number) => { const updatedTopics = topics.filter((_, i) => i !== index); indexedErrors.splice(index, 1); + indexedConditionErrors.splice(index, 1); onChange(updatedTopics); }, - [topics, indexedErrors, onChange] + [topics, indexedErrors, indexedConditionErrors, onChange] ); const displayErrors = (errorMessages?: string[]) => { @@ -132,10 +155,13 @@ export const OutputFormKafkaTopics: React.FunctionComponent<{ inputs: OutputForm const sourceErrors = indexedErrors[source.index]; indexedErrors.splice(source.index, 1); indexedErrors.splice(destination.index, 0, sourceErrors); + const sourceConditionErrors = indexedConditionErrors[source.index]; + indexedConditionErrors.splice(source.index, 1); + indexedConditionErrors.splice(destination.index, 0, sourceConditionErrors); onChange(items); } }, - [topics, indexedErrors, onChange] + [topics, indexedErrors, indexedConditionErrors, onChange] ); return ( @@ -187,6 +213,7 @@ export const OutputFormKafkaTopics: React.FunctionComponent<{ inputs: OutputForm {topics.map((topic, index) => { const topicErrors = indexedErrors[index]; + const topicConditionErrors = indexedConditionErrors[index]; return (
    - + 0} + > 0} onChange={(e) => handleTopicProcessorChange(index, 'condition', e.target.value) } @@ -301,6 +333,7 @@ export const OutputFormKafkaTopics: React.FunctionComponent<{ inputs: OutputForm <> {topics.map((topic, index) => { const topicErrors = indexedErrors[index]; + const topicConditionErrors = indexedConditionErrors[index]; return ( <> @@ -320,10 +353,15 @@ export const OutputFormKafkaTopics: React.FunctionComponent<{ inputs: OutputForm - + 0} + > 0} onChange={(e) => handleTopicProcessorChange(index, 'condition', e.target.value) } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.test.tsx index 04b07ac9c8b4a..d5da6f553cf89 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.test.tsx @@ -11,9 +11,71 @@ import { validateYamlConfig, validateCATrustedFingerPrint, validateKafkaHeaders, + validateKafkaHosts, } from './output_form_validators'; describe('Output form validation', () => { + describe('validateKafkaHosts', () => { + it('should not work without any urls', () => { + const res = validateKafkaHosts([]); + + expect(res).toEqual([{ message: 'Host is required' }]); + }); + + it('should work with valid url', () => { + const res = validateKafkaHosts(['test.fr:9200']); + + expect(res).toBeUndefined(); + }); + + it('should work with multiple valid urls', () => { + const res = validateKafkaHosts(['test.fr:9200', 'test2.fr:9200', 'test.fr:9999']); + + expect(res).toBeUndefined(); + }); + + it('should return an error with invalid url', () => { + const res = validateKafkaHosts(['toto']); + + expect(res).toEqual([ + { index: 0, message: 'Invalid format. Expected "host:port" without protocol.' }, + ]); + }); + + it('should return an error with url with defined protocol', () => { + const res = validateKafkaHosts(['https://test.fr:9200']); + + expect(res).toEqual([ + { index: 0, message: 'Invalid format. Expected "host:port" without protocol.' }, + ]); + }); + + it('should return an error with url with invalid port', () => { + const res = validateKafkaHosts(['test.fr:qwerty9200']); + + expect(res).toEqual([ + { index: 0, message: 'Invalid port number. Expected a number between 1 and 65535' }, + ]); + }); + + it('should return an error with multiple invalid urls', () => { + const res = validateKafkaHosts(['toto', 'tata']); + + expect(res).toEqual([ + { index: 0, message: 'Invalid format. Expected "host:port" without protocol.' }, + { index: 1, message: 'Invalid format. Expected "host:port" without protocol.' }, + ]); + }); + it('should return an error with duplicate urls', () => { + const res = validateKafkaHosts(['test.fr:2000', 'test.fr:2000']); + + expect(res).toEqual([ + { index: 0, message: 'Duplicate URL' }, + { index: 1, message: 'Duplicate URL' }, + ]); + }); + }); + describe('validateESHosts', () => { it('should not work without any urls', () => { const res = validateESHosts([]); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.tsx index 8d658e545a854..bbb5b5dda3e91 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.tsx @@ -8,6 +8,73 @@ import { i18n } from '@kbn/i18n'; import { safeLoad } from 'js-yaml'; +export function validateKafkaHosts(value: string[]) { + const res: Array<{ message: string; index?: number }> = []; + const urlIndexes: { [key: string]: number[] } = {}; + + value.forEach((val, idx) => { + if (!val) { + res.push({ + message: i18n.translate('xpack.fleet.settings.outputForm.kafkaHostFieldRequiredError', { + defaultMessage: 'Host is required', + }), + }); + return; + } + + // Split the URL into parts based on ":" + const urlParts = val.split(':'); + if (urlParts.length !== 2 || !urlParts[0] || !urlParts[1]) { + res.push({ + message: i18n.translate('xpack.fleet.settings.outputForm.kafkaHostPortError', { + defaultMessage: 'Invalid format. Expected "host:port" without protocol.', + }), + index: idx, + }); + return; + } + + // Validate that the port is a valid number + const port = parseInt(urlParts[1], 10); + if (isNaN(port) || port < 1 || port > 65535) { + res.push({ + message: i18n.translate('xpack.fleet.settings.outputForm.kafkaPortError', { + defaultMessage: 'Invalid port number. Expected a number between 1 and 65535', + }), + index: idx, + }); + } + + const curIndexes = urlIndexes[val] || []; + urlIndexes[val] = [...curIndexes, idx]; + }); + + Object.values(urlIndexes) + .filter(({ length }) => length > 1) + .forEach((indexes) => { + indexes.forEach((index) => + res.push({ + message: i18n.translate('xpack.fleet.settings.outputForm.kafkaHostDuplicateError', { + defaultMessage: 'Duplicate URL', + }), + index, + }) + ); + }); + + if (value.length === 0) { + res.push({ + message: i18n.translate('xpack.fleet.settings.outputForm.kafkaHostRequiredError', { + defaultMessage: 'Host is required', + }), + }); + } + + if (res.length) { + return res; + } +} + export function validateESHosts(value: string[]) { const res: Array<{ message: string; index?: number }> = []; const urlIndexes: { [key: string]: number[] } = {}; @@ -211,14 +278,31 @@ export function validateKafkaDefaultTopic(value: string) { } } +export function validateKafkaClientId(value: string) { + const regex = /^[A-Za-z0-9._-]+$/; + return regex.test(value) + ? undefined + : [ + i18n.translate('xpack.fleet.settings.outputForm.kafkaClientIdFormattingMessage', { + defaultMessage: + 'Client ID is invalid. Only letters, numbers, dots, underscores, and dashes are allowed.', + }), + ]; +} + export function validateKafkaTopics( topics: Array<{ topic: string; + when?: { + condition?: string; + type?: string; + }; }> ) { const errors: Array<{ message: string; index: number; + condition?: boolean; }> = []; topics.forEach((topic, index) => { @@ -230,6 +314,19 @@ export function validateKafkaTopics( index, }); } + if ( + !topic.when?.condition || + topic.when.condition === '' || + topic.when.condition.split(':').length - 1 !== 1 + ) { + errors.push({ + message: i18n.translate('xpack.fleet.settings.outputForm.kafkaTopicConditionRequired', { + defaultMessage: 'Must be a key, value pair i.e. "http.response.code: 200"', + }), + index, + condition: true, + }); + } }); if (errors.length) { return errors; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/use_output_form.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/use_output_form.tsx index dbd1b4b0c7a30..bd1891f3ebc12 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/use_output_form.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/use_output_form.tsx @@ -21,8 +21,10 @@ import { kafkaAcknowledgeReliabilityLevel, kafkaAuthType, kafkaCompressionType, + kafkaConnectionType, kafkaPartitionType, kafkaSaslMechanism, + kafkaVerificationModes, outputType, } from '../../../../../../../common/constants'; @@ -57,6 +59,8 @@ import { validateKafkaHeaders, validateKafkaDefaultTopic, validateKafkaTopics, + validateKafkaClientId, + validateKafkaHosts, } from './output_form_validators'; import { confirmUpdate } from './confirm_update'; @@ -87,7 +91,9 @@ export interface OutputFormInputsType { maxBatchBytes: ReturnType; kafkaHostsInput: ReturnType; kafkaVersionInput: ReturnType; + kafkaVerificationModeInput: ReturnType; kafkaAuthMethodInput: ReturnType; + kafkaConnectionTypeInput: ReturnType; kafkaSaslMechanismInput: ReturnType; kafkaAuthUsernameInput: ReturnType; kafkaAuthPasswordInput: ReturnType; @@ -104,7 +110,6 @@ export interface OutputFormInputsType { kafkaCompressionCodecInput: ReturnType; kafkaBrokerTimeoutInput: ReturnType; kafkaBrokerReachabilityTimeoutInput: ReturnType; - kafkaBrokerChannelBufferSizeInput: ReturnType; kafkaBrokerAckReliabilityInput: ReturnType; kafkaKeyInput: ReturnType; kafkaSslCertificateInput: ReturnType; @@ -278,15 +283,20 @@ export function useOutputForm(onSucess: () => void, output?: Output) { const kafkaHostsInput = useComboInput( 'kafkaHostsComboBox', output?.hosts ?? [], - validateESHosts, + validateKafkaHosts, isDisabled('hosts') ); const kafkaAuthMethodInput = useRadioInput( - kafkaOutput?.auth_type ?? kafkaAuthType.Userpass, + kafkaOutput?.auth_type ?? kafkaAuthType.None, isDisabled('auth_type') ); + const kafkaConnectionTypeInput = useRadioInput( + kafkaOutput?.connection_type ?? kafkaConnectionType.Plaintext, + isDisabled('connection_type') + ); + const kafkaAuthUsernameInput = useInput( kafkaOutput?.username, kafkaAuthMethodInput.value === kafkaAuthType.Userpass ? validateKafkaUsername : undefined, @@ -315,6 +325,12 @@ export function useOutputForm(onSucess: () => void, output?: Output) { isSSLEditable ); + const kafkaVerificationModeInput = useInput( + kafkaOutput?.ssl?.verification_mode ?? kafkaVerificationModes.Full, + undefined, + isSSLEditable + ); + const kafkaSaslMechanismInput = useRadioInput( kafkaOutput?.sasl?.mechanism ?? kafkaSaslMechanism.Plain, isDisabled('sasl') @@ -360,8 +376,8 @@ export function useOutputForm(onSucess: () => void, output?: Output) { ); const kafkaClientIdInput = useInput( - kafkaOutput?.client_id ?? 'Elastic agent', - undefined, + kafkaOutput?.client_id ?? 'Elastic', + validateKafkaClientId, isDisabled('client_id') ); @@ -392,16 +408,10 @@ export function useOutputForm(onSucess: () => void, output?: Output) { isDisabled('timeout') ); - const kafkaBrokerChannelBufferSizeInput = useInput( - `${kafkaOutput?.broker_buffer_size ?? 256}`, - undefined, - isDisabled('broker_buffer_size') - ); - const kafkaBrokerAckReliabilityInput = useInput( - kafkaOutput?.broker_ack_reliability ?? kafkaAcknowledgeReliabilityLevel.Commit, + `${kafkaOutput?.required_acks ?? kafkaAcknowledgeReliabilityLevel.Commit}`, undefined, - isDisabled('broker_ack_reliability') + isDisabled('required_acks') ); const kafkaKeyInput = useInput(kafkaOutput?.key, undefined, isDisabled('key')); @@ -434,7 +444,9 @@ export function useOutputForm(onSucess: () => void, output?: Output) { maxBatchBytes, kafkaVersionInput, kafkaHostsInput, + kafkaVerificationModeInput, kafkaAuthMethodInput, + kafkaConnectionTypeInput, kafkaAuthUsernameInput, kafkaAuthPasswordInput, kafkaSaslMechanismInput, @@ -449,7 +461,6 @@ export function useOutputForm(onSucess: () => void, output?: Output) { kafkaCompressionCodecInput, kafkaBrokerTimeoutInput, kafkaBrokerReachabilityTimeoutInput, - kafkaBrokerChannelBufferSizeInput, kafkaBrokerAckReliabilityInput, kafkaKeyInput, kafkaSslCertificateAuthoritiesInput, @@ -467,6 +478,7 @@ export function useOutputForm(onSucess: () => void, output?: Output) { const kafkaHostsValid = kafkaHostsInput.validate(); const kafkaUsernameValid = kafkaAuthUsernameInput.validate(); const kafkaPasswordValid = kafkaAuthPasswordInput.validate(); + const kafkaClientIDValid = kafkaClientIdInput.validate(); const kafkaSslCertificateValid = kafkaSslCertificateInput.validate(); const kafkaSslKeyValid = kafkaSslKeyInput.validate(); const kafkaDefaultTopicValid = kafkaDefaultTopicInput.validate(); @@ -501,7 +513,8 @@ export function useOutputForm(onSucess: () => void, output?: Output) { kafkaHeadersValid && kafkaDefaultTopicValid && kafkaTopicsValid && - additionalYamlConfigValid + additionalYamlConfigValid && + kafkaClientIDValid ); } else { // validate ES @@ -519,6 +532,7 @@ export function useOutputForm(onSucess: () => void, output?: Output) { kafkaHostsInput, kafkaAuthUsernameInput, kafkaAuthPasswordInput, + kafkaClientIdInput, kafkaSslCertificateInput, kafkaSslKeyInput, kafkaDefaultTopicInput, @@ -582,7 +596,7 @@ export function useOutputForm(onSucess: () => void, output?: Output) { const payload: NewOutput = (() => { const parseIntegerIfStringDefined = (value: string | undefined): number | undefined => { if (value !== undefined) { - const parsedInt = parseInt(value, 10); // Specify the base as 10 for decimal numbers + const parsedInt = parseInt(value, 10); if (!isNaN(parsedInt)) { return parsedInt; } @@ -592,6 +606,10 @@ export function useOutputForm(onSucess: () => void, output?: Output) { switch (typeInput.value) { case outputType.Kafka: + const definedCA = kafkaSslCertificateAuthoritiesInput.value.filter( + (val) => val !== '' + ).length; + return { name: nameInput.value, type: outputType.Kafka, @@ -599,18 +617,26 @@ export function useOutputForm(onSucess: () => void, output?: Output) { is_default: defaultOutputInput.value, is_default_monitoring: defaultMonitoringOutputInput.value, config_yaml: additionalYamlConfigInput.value, - ...(kafkaAuthMethodInput.value === kafkaAuthType.Ssl + ...(kafkaConnectionTypeInput.value !== kafkaConnectionType.Plaintext || + kafkaAuthMethodInput.value !== kafkaAuthType.None ? { ssl: { - certificate: kafkaSslCertificateInput.value, - key: kafkaSslKeyInput.value, - certificate_authorities: kafkaSslCertificateAuthoritiesInput.value.filter( - (val) => val !== '' - ), + ...(definedCA + ? { + certificate_authorities: + kafkaSslCertificateAuthoritiesInput.value.filter((val) => val !== ''), + } + : {}), + ...(kafkaAuthMethodInput.value === kafkaAuthType.Ssl + ? { + certificate: kafkaSslCertificateInput.value, + key: kafkaSslKeyInput.value, + } + : {}), + verification_mode: kafkaVerificationModeInput.value, }, } : {}), - proxy_id: proxyIdValue, client_id: kafkaClientIdInput.value || undefined, @@ -626,8 +652,17 @@ export function useOutputForm(onSucess: () => void, output?: Output) { : {}), auth_type: kafkaAuthMethodInput.value, - ...(kafkaAuthUsernameInput.value ? { username: kafkaAuthUsernameInput.value } : {}), - ...(kafkaAuthPasswordInput.value ? { password: kafkaAuthPasswordInput.value } : {}), + ...(kafkaAuthMethodInput.value === kafkaAuthType.None + ? { connection_type: kafkaConnectionTypeInput.value } + : {}), + ...(kafkaAuthMethodInput.value === kafkaAuthType.Userpass && + kafkaAuthUsernameInput.value + ? { username: kafkaAuthUsernameInput.value } + : {}), + ...(kafkaAuthMethodInput.value === kafkaAuthType.Userpass && + kafkaAuthPasswordInput.value + ? { password: kafkaAuthPasswordInput.value } + : {}), ...(kafkaAuthMethodInput.value === kafkaAuthType.Userpass && kafkaSaslMechanismInput.value ? { sasl: { mechanism: kafkaSaslMechanismInput.value } } @@ -665,10 +700,7 @@ export function useOutputForm(onSucess: () => void, output?: Output) { broker_timeout: parseIntegerIfStringDefined( kafkaBrokerReachabilityTimeoutInput.value ), - broker_ack_reliability: kafkaBrokerAckReliabilityInput.value, - broker_buffer_size: parseIntegerIfStringDefined( - kafkaBrokerChannelBufferSizeInput.value - ), + required_acks: parseIntegerIfStringDefined(kafkaBrokerAckReliabilityInput.value), ...shipperParams, } as KafkaOutput; case outputType.Logstash: @@ -752,6 +784,7 @@ export function useOutputForm(onSucess: () => void, output?: Output) { compressionLevelInput.value, loadBalanceEnabledInput.value, typeInput.value, + kafkaSslCertificateAuthoritiesInput.value, nameInput.value, kafkaHostsInput.value, defaultOutputInput.value, @@ -760,12 +793,13 @@ export function useOutputForm(onSucess: () => void, output?: Output) { kafkaAuthMethodInput.value, kafkaSslCertificateInput.value, kafkaSslKeyInput.value, - kafkaSslCertificateAuthoritiesInput.value, + kafkaVerificationModeInput.value, kafkaClientIdInput.value, kafkaVersionInput.value, kafkaKeyInput.value, kafkaCompressionCodecInput.value, kafkaCompressionLevelInput.value, + kafkaConnectionTypeInput.value, kafkaAuthUsernameInput.value, kafkaAuthPasswordInput.value, kafkaSaslMechanismInput.value, @@ -779,7 +813,6 @@ export function useOutputForm(onSucess: () => void, output?: Output) { kafkaBrokerTimeoutInput.value, kafkaBrokerReachabilityTimeoutInput.value, kafkaBrokerAckReliabilityInput.value, - kafkaBrokerChannelBufferSizeInput.value, logstashHostsInput.value, sslCertificateInput.value, sslKeyInput.value, diff --git a/x-pack/plugins/fleet/public/hooks/use_input.ts b/x-pack/plugins/fleet/public/hooks/use_input.ts index a48e3075d7a42..dbc60eafda833 100644 --- a/x-pack/plugins/fleet/public/hooks/use_input.ts +++ b/x-pack/plugins/fleet/public/hooks/use_input.ts @@ -86,6 +86,16 @@ export function useInput( export function useRadioInput(defaultValue: string, disabled = false) { const [value, setValue] = useState(defaultValue); + const [hasChanged, setHasChanged] = useState(false); + + useEffect(() => { + if (hasChanged) { + return; + } + if (value !== defaultValue) { + setHasChanged(true); + } + }, [hasChanged, value, defaultValue]); const onChange = useCallback(setValue, [setValue]); @@ -97,6 +107,7 @@ export function useRadioInput(defaultValue: string, disabled = false) { }, setValue, value, + hasChanged, }; } @@ -137,11 +148,15 @@ export function useSwitchInput(defaultValue = false, disabled = false) { function useCustomInput( id: string, defaultValue: T, - validate?: (value: T) => Array<{ message: string; index?: number }> | undefined, + validate?: ( + value: T + ) => Array<{ message: string; index?: number; condition?: boolean }> | undefined, disabled = false ) { const [value, setValue] = useState(defaultValue); - const [errors, setErrors] = useState | undefined>(); + const [errors, setErrors] = useState< + Array<{ message: string; index?: number; condition?: boolean }> | undefined + >(); const [hasChanged, setHasChanged] = useState(false); useEffect(() => { @@ -237,7 +252,9 @@ type Topic = Array<{ export function useTopicsInput( id: string, defaultValue: Topic = [], - validate?: (value: Topic) => Array<{ message: string; index: number }> | undefined, + validate?: ( + value: Topic + ) => Array<{ message: string; index: number; condition?: boolean }> | undefined, disabled = false ) { return useCustomInput(id, defaultValue, validate, disabled); diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 43e0069d3be48..b7013bf43ff84 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -25,6 +25,8 @@ import { UNINSTALL_TOKENS_SAVED_OBJECT_TYPE, } from '../constants'; +import { migrateOutputEvictionsFromV8100, migrateOutputToV8100 } from './migrations/to_v8_10_0'; + import { migrateSyntheticsPackagePolicyToV8100 } from './migrations/synthetics/to_v8_10_0'; import { migratePackagePolicyEvictionsFromV8100 } from './migrations/security_solution/to_v8_10_0'; @@ -177,6 +179,7 @@ const getSavedObjectTypes = (): { [key: string]: SavedObjectsType } => ({ compression_level: { type: 'integer' }, client_id: { type: 'keyword' }, auth_type: { type: 'keyword' }, + connection_type: { type: 'keyword' }, username: { type: 'keyword' }, password: { type: 'text', index: false }, sasl: { @@ -229,6 +232,29 @@ const getSavedObjectTypes = (): { [key: string]: SavedObjectsType } => ({ broker_timeout: { type: 'integer' }, broker_ack_reliability: { type: 'text' }, broker_buffer_size: { type: 'integer' }, + required_acks: { type: 'integer' }, + channel_buffer_size: { type: 'integer' }, + }, + }, + modelVersions: { + '1': { + changes: [ + { + type: 'mappings_deprecation', + deprecatedMappings: [ + 'broker_ack_reliability', + 'broker_buffer_size', + 'channel_buffer_size', + ], + }, + { + type: 'data_backfill', + backfillFn: migrateOutputToV8100, + }, + ], + schemas: { + forwardCompatibility: migrateOutputEvictionsFromV8100, + }, }, }, migrations: { @@ -528,6 +554,24 @@ export function registerEncryptedSavedObjects( 'config_yaml', 'is_preconfigured', 'proxy_id', + 'version', + 'key', + 'compression', + 'compression_level', + 'client_id', + 'auth_type', + 'connection_type', + 'username', + 'sasl', + 'partition', + 'random', + 'round_robin', + 'hash', + 'topics', + 'headers', + 'timeout', + 'broker_timeout', + 'required_acks', ]), }); // Encrypted saved objects diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_10_0.test.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_10_0.test.ts new file mode 100644 index 0000000000000..92b8c2c2d34b6 --- /dev/null +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_10_0.test.ts @@ -0,0 +1,62 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObjectModelTransformationContext } from '@kbn/core-saved-objects-server'; + +import { + migrateOutputToV8100 as migration, + migrateOutputEvictionsFromV8100 as eviction, +} from './to_v8_10_0'; + +describe('8.10.0 migration', () => { + describe('Migrate output to v8.10.0', () => { + const outputDoc = (connectionType = {}) => ({ + id: 'mock-saved-object-id', + attributes: { + id: 'id', + name: 'Test', + type: 'kafka' as const, + is_default: false, + is_default_monitoring: false, + hosts: ['localhost:9092'], + ca_sha256: 'sha', + ca_trusted_fingerprint: 'fingerprint', + version: '7.10.0', + key: 'key', + compression: 'gzip' as const, + compression_level: 4, + client_id: 'Elastic', + auth_type: 'none' as const, + ...connectionType, + topics: [{ topic: 'topic' }], + }, + type: 'nested', + }); + + it('adds connection type field to output and sets it to plaintext', () => { + const initialDoc = outputDoc({}); + + const migratedDoc = outputDoc({ + connection_type: 'plaintext', + }); + + expect(migration(initialDoc, {} as SavedObjectModelTransformationContext)).toEqual({ + attributes: migratedDoc.attributes, + }); + }); + + it('removes connection type field from output', () => { + const initialDoc = outputDoc({ + connection_type: 'plaintext', + }); + + const migratedDoc = outputDoc({}); + + expect(eviction(initialDoc.attributes)).toEqual(migratedDoc.attributes); + }); + }); +}); diff --git a/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_10_0.ts b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_10_0.ts new file mode 100644 index 0000000000000..fc0ebda76086b --- /dev/null +++ b/x-pack/plugins/fleet/server/saved_objects/migrations/to_v8_10_0.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + SavedObjectModelDataBackfillFn, + SavedObjectUnsanitizedDoc, +} from '@kbn/core-saved-objects-server'; + +import type { SavedObjectModelVersionForwardCompatibilityFn } from '@kbn/core-saved-objects-server'; + +import { omit } from 'lodash'; + +import type { Output } from '../../../common'; + +export const migrateOutputToV8100: SavedObjectModelDataBackfillFn = (outputDoc) => { + const updatedOutputDoc: SavedObjectUnsanitizedDoc = outputDoc; + + if (updatedOutputDoc.attributes.type === 'kafka') { + updatedOutputDoc.attributes.connection_type = 'plaintext'; + } + + return { + attributes: updatedOutputDoc.attributes, + }; +}; + +export const migrateOutputEvictionsFromV8100: SavedObjectModelVersionForwardCompatibilityFn = ( + unknownAttributes +) => { + const attributes = unknownAttributes as Output; + if (attributes.type !== 'kafka') { + return attributes; + } + + let updatedAttributes = attributes; + + updatedAttributes = omit(updatedAttributes, ['connection_type']); + + return updatedAttributes; +}; diff --git a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts index 1da8187744091..d50e12541063a 100644 --- a/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policies/full_agent_policy.ts @@ -291,7 +291,6 @@ export function transformOutputToFullPolicyOutput( key, compression, compression_level, - auth_type, username, password, sasl, @@ -303,31 +302,69 @@ export function transformOutputToFullPolicyOutput( headers, timeout, broker_timeout, - broker_buffer_size, - broker_ack_reliability, + required_acks, } = output; - /* eslint-enable @typescript-eslint/naming-convention */ + const transformPartition = () => { + if (!partition) return {}; + switch (partition) { + case 'random': + return { + random: { + ...(random?.group_events + ? { group_events: random.group_events } + : { group_events: 1 }), + }, + }; + case 'round_robin': + return { + round_robin: { + ...(round_robin?.group_events + ? { group_events: round_robin.group_events } + : { group_events: 1 }), + }, + }; + case 'hash': + default: + return { hash: { ...(hash?.hash ? { hash: hash.hash } : { hash: '' }) } }; + } + }; + + /* eslint-enable @typescript-eslint/naming-convention */ kafkaData = { client_id, version, key, compression, compression_level, - auth_type, - username, - password, - sasl, - partition, - random, - round_robin, - hash, - topics, - headers, + ...(username ? { username } : {}), + ...(password ? { password } : {}), + ...(sasl ? { sasl } : {}), + partition: transformPartition(), + topics: (topics ?? []).map((topic) => { + const { topic: topicName, ...rest } = topic; + const whenKeys = Object.keys(rest); + + if (whenKeys.length === 0) { + return { topic: topicName }; + } + if (rest.when && rest.when.condition) { + const [keyName, value] = rest.when.condition.split(':'); + + return { + topic: topicName, + when: { + [rest.when.type as string]: { + [keyName.replace(/\s/g, '')]: value.replace(/\s/g, ''), + }, + }, + }; + } + }), + headers: (headers ?? []).filter((item) => item.key !== '' || item.value !== ''), timeout, broker_timeout, - broker_buffer_size, - broker_ack_reliability, + required_acks, }; } diff --git a/x-pack/plugins/fleet/server/services/output.test.ts b/x-pack/plugins/fleet/server/services/output.test.ts index 31efb22834cdb..12abc7c0bec70 100644 --- a/x-pack/plugins/fleet/server/services/output.test.ts +++ b/x-pack/plugins/fleet/server/services/output.test.ts @@ -916,9 +916,9 @@ describe('Output Service', () => { type: 'elasticsearch', hosts: ['http://test:4343'], auth_type: null, + connection_type: null, broker_timeout: null, - broker_ack_reliability: null, - broker_buffer_size: null, + required_acks: null, client_id: null, compression: null, compression_level: null, @@ -1033,13 +1033,14 @@ describe('Output Service', () => { ca_sha256: null, ca_trusted_fingerprint: null, auth_type: null, + connection_type: null, broker_timeout: null, - broker_ack_reliability: null, - broker_buffer_size: null, + required_acks: null, client_id: null, compression: null, compression_level: null, hash: null, + ssl: null, key: null, partition: null, password: null, @@ -1257,10 +1258,13 @@ describe('Output Service', () => { hosts: ['test:4343'], ca_sha256: null, ca_trusted_fingerprint: null, + password: null, + username: null, + ssl: null, + sasl: null, broker_timeout: 10, - broker_ack_reliability: 'Wait for local commit', - broker_buffer_size: 256, - client_id: 'Elastic Agent', + required_acks: 1, + client_id: 'Elastic', compression: 'gzip', compression_level: 4, partition: 'hash', @@ -1285,11 +1289,14 @@ describe('Output Service', () => { expect(soClient.update).toBeCalledWith(expect.anything(), expect.anything(), { hosts: ['test:4343'], broker_timeout: 10, - broker_ack_reliability: 'Wait for local commit', - broker_buffer_size: 256, + required_acks: 1, ca_sha256: null, ca_trusted_fingerprint: null, - client_id: 'Elastic Agent', + password: null, + username: null, + ssl: null, + sasl: null, + client_id: 'Elastic', compression: 'gzip', compression_level: 4, partition: 'hash', @@ -1310,25 +1317,28 @@ describe('Output Service', () => { await outputService.update(soClient, esClientMock, 'output-test', { type: 'kafka', - hosts: ['http://test:4343'], + hosts: ['test:4343'], is_default: true, }); expect(soClient.update).toBeCalledWith(expect.anything(), expect.anything(), { type: 'kafka', - hosts: ['http://test:4343'], + hosts: ['test:4343'], is_default: true, ca_sha256: null, ca_trusted_fingerprint: null, - client_id: 'Elastic Agent', + password: null, + username: null, + ssl: null, + sasl: null, + client_id: 'Elastic', compression: 'gzip', compression_level: 4, partition: 'hash', timeout: 30, version: '1.0.0', broker_timeout: 10, - broker_ack_reliability: 'Wait for local commit', - broker_buffer_size: 256, + required_acks: 1, }); expect(mockedAgentPolicyService.update).toBeCalledWith( expect.anything(), @@ -1354,7 +1364,7 @@ describe('Output Service', () => { 'output-test', { type: 'kafka', - hosts: ['http://test:4343'], + hosts: ['test:4343'], is_default: true, }, { @@ -1364,19 +1374,22 @@ describe('Output Service', () => { expect(soClient.update).toBeCalledWith(expect.anything(), expect.anything(), { type: 'kafka', - hosts: ['http://test:4343'], + hosts: ['test:4343'], is_default: true, ca_sha256: null, ca_trusted_fingerprint: null, - client_id: 'Elastic Agent', + password: null, + username: null, + ssl: null, + sasl: null, + client_id: 'Elastic', compression: 'gzip', compression_level: 4, partition: 'hash', timeout: 30, version: '1.0.0', broker_timeout: 10, - broker_ack_reliability: 'Wait for local commit', - broker_buffer_size: 256, + required_acks: 1, }); expect(mockedAgentPolicyService.update).toBeCalledWith( expect.anything(), @@ -1396,25 +1409,28 @@ describe('Output Service', () => { await outputService.update(soClient, esClientMock, 'output-test', { type: 'kafka', - hosts: ['http://test:4343'], + hosts: ['test:4343'], is_default: true, }); expect(soClient.update).toBeCalledWith(expect.anything(), expect.anything(), { type: 'kafka', - hosts: ['http://test:4343'], + hosts: ['test:4343'], is_default: true, ca_sha256: null, ca_trusted_fingerprint: null, - client_id: 'Elastic Agent', + password: null, + username: null, + ssl: null, + sasl: null, + client_id: 'Elastic', compression: 'gzip', compression_level: 4, partition: 'hash', timeout: 30, version: '1.0.0', broker_timeout: 10, - broker_ack_reliability: 'Wait for local commit', - broker_buffer_size: 256, + required_acks: 1, }); expect(mockedAgentPolicyService.update).toBeCalledWith( expect.anything(), @@ -1438,7 +1454,7 @@ describe('Output Service', () => { 'output-test', { type: 'kafka', - hosts: ['http://test:4343'], + hosts: ['test:4343'], is_default: true, }, { @@ -1448,19 +1464,22 @@ describe('Output Service', () => { expect(soClient.update).toBeCalledWith(expect.anything(), expect.anything(), { type: 'kafka', - hosts: ['http://test:4343'], + hosts: ['test:4343'], is_default: true, ca_sha256: null, ca_trusted_fingerprint: null, - client_id: 'Elastic Agent', + password: null, + username: null, + ssl: null, + sasl: null, + client_id: 'Elastic', compression: 'gzip', compression_level: 4, partition: 'hash', timeout: 30, version: '1.0.0', broker_timeout: 10, - broker_ack_reliability: 'Wait for local commit', - broker_buffer_size: 256, + required_acks: 1, }); expect(mockedAgentPolicyService.update).toBeCalledWith( expect.anything(), diff --git a/x-pack/plugins/fleet/server/services/output.ts b/x-pack/plugins/fleet/server/services/output.ts index d95771eb48238..2cf1764a78f59 100644 --- a/x-pack/plugins/fleet/server/services/output.ts +++ b/x-pack/plugins/fleet/server/services/output.ts @@ -493,7 +493,7 @@ class OutputService { data.compression_level = 4; } if (!output.client_id) { - data.client_id = 'Elastic Agent'; + data.client_id = 'Elastic'; } if (output.username && output.password && !output.sasl?.mechanism) { data.sasl = { @@ -519,11 +519,9 @@ class OutputService { if (!output.broker_timeout) { data.broker_timeout = 10; } - if (!output.broker_ack_reliability) { - data.broker_ack_reliability = kafkaAcknowledgeReliabilityLevel.Commit; - } - if (!output.broker_buffer_size) { - data.broker_buffer_size = 256; + if (output.required_acks === null || output.required_acks === undefined) { + // required_acks can be 0 + data.required_acks = kafkaAcknowledgeReliabilityLevel.Commit; } } @@ -712,6 +710,7 @@ class OutputService { target.key = null; target.compression = null; target.compression_level = null; + target.connection_type = null; target.client_id = null; target.auth_type = null; target.username = null; @@ -725,8 +724,8 @@ class OutputService { target.headers = null; target.timeout = null; target.broker_timeout = null; - target.broker_ack_reliability = null; - target.broker_buffer_size = null; + target.required_acks = null; + target.ssl = null; }; // If the output type changed @@ -766,7 +765,7 @@ class OutputService { updateData.compression_level = 4; } if (!data.client_id) { - updateData.client_id = 'Elastic Agent'; + updateData.client_id = 'Elastic'; } if (data.username && data.password && !data.sasl?.mechanism) { updateData.sasl = { @@ -792,11 +791,9 @@ class OutputService { if (!data.broker_timeout) { updateData.broker_timeout = 10; } - if (!data.broker_ack_reliability) { - updateData.broker_ack_reliability = kafkaAcknowledgeReliabilityLevel.Commit; - } - if (!data.broker_buffer_size) { - updateData.broker_buffer_size = 256; + if (updateData.required_acks === null || updateData.required_acks === undefined) { + // required_acks can be 0 + updateData.required_acks = kafkaAcknowledgeReliabilityLevel.Commit; } } } @@ -808,6 +805,21 @@ class OutputService { updateData.ssl = null; } + if (data.type === outputType.Kafka && updateData.type === outputType.Kafka) { + if (!data.password) { + updateData.password = null; + } + if (!data.username) { + updateData.username = null; + } + if (!data.ssl) { + updateData.ssl = null; + } + if (!data.sasl) { + updateData.sasl = null; + } + } + // ensure only default output exists if (data.is_default) { if (defaultDataOutputId && defaultDataOutputId !== id) { diff --git a/x-pack/plugins/fleet/server/types/models/output.test.ts b/x-pack/plugins/fleet/server/types/models/output.test.ts index 4441630653a99..06edd900fec2a 100644 --- a/x-pack/plugins/fleet/server/types/models/output.test.ts +++ b/x-pack/plugins/fleet/server/types/models/output.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { validateLogstashHost } from './output'; +import { validateKafkaHost, validateLogstashHost } from './output'; describe('Output model', () => { describe('validateLogstashHost', () => { @@ -23,4 +23,22 @@ describe('Output model', () => { ); }); }); + + describe('validateKafkaHost', () => { + it('should support valid host', () => { + expect(validateKafkaHost('test.fr:5044')).toBeUndefined(); + }); + + it('should return an error for an invalid host', () => { + expect(validateKafkaHost('!@#%&!#!@')).toBe( + 'Invalid format. Expected "host:port" without protocol' + ); + }); + + it('should return an error for an invalid host with http scheme', () => { + expect(validateKafkaHost('https://test.fr:5044')).toBe( + 'Invalid format. Expected "host:port" without protocol' + ); + }); + }); }); diff --git a/x-pack/plugins/fleet/server/types/models/output.ts b/x-pack/plugins/fleet/server/types/models/output.ts index b18d2baa25103..845361116d732 100644 --- a/x-pack/plugins/fleet/server/types/models/output.ts +++ b/x-pack/plugins/fleet/server/types/models/output.ts @@ -8,12 +8,13 @@ import { schema } from '@kbn/config-schema'; import { - kafkaAcknowledgeReliabilityLevel, kafkaAuthType, kafkaCompressionType, + kafkaConnectionType, kafkaPartitionType, kafkaSaslMechanism, kafkaTopicWhenType, + kafkaVerificationModes, outputType, } from '../../../common/constants'; @@ -33,6 +34,21 @@ export function validateLogstashHost(val: string) { } } +export const validateKafkaHost = (input: string): string | undefined => { + const parts = input.split(':'); + + if (parts.length !== 2 || !parts[0] || parts[0].includes('://')) { + return 'Invalid format. Expected "host:port" without protocol'; + } + + const port = parseInt(parts[1], 10); + if (isNaN(port) || port < 1 || port > 65535) { + return 'Invalid port number. Expected a number between 1 and 65535'; + } + + return undefined; +}; + /** * Base schemas */ @@ -50,6 +66,14 @@ const BaseSchema = { certificate_authorities: schema.maybe(schema.arrayOf(schema.string())), certificate: schema.maybe(schema.string()), key: schema.maybe(schema.string()), + verification_mode: schema.maybe( + schema.oneOf([ + schema.literal(kafkaVerificationModes.Full), + schema.literal(kafkaVerificationModes.None), + schema.literal(kafkaVerificationModes.Certificate), + schema.literal(kafkaVerificationModes.Strict), + ]) + ), }) ), proxy_id: schema.nullable(schema.string()), @@ -121,15 +145,9 @@ const KafkaTopicsSchema = schema.arrayOf( schema.object({ type: schema.maybe( schema.oneOf([ - schema.literal(kafkaTopicWhenType.And), - schema.literal(kafkaTopicWhenType.Not), - schema.literal(kafkaTopicWhenType.Or), schema.literal(kafkaTopicWhenType.Equals), schema.literal(kafkaTopicWhenType.Contains), schema.literal(kafkaTopicWhenType.Regexp), - schema.literal(kafkaTopicWhenType.HasFields), - schema.literal(kafkaTopicWhenType.Network), - schema.literal(kafkaTopicWhenType.Range), ]) ), condition: schema.maybe(schema.string()), @@ -142,7 +160,7 @@ const KafkaTopicsSchema = schema.arrayOf( export const KafkaSchema = { ...BaseSchema, type: schema.literal(outputType.Kafka), - hosts: schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }), { minSize: 1 }), + hosts: schema.arrayOf(schema.string({ validate: validateKafkaHost }), { minSize: 1 }), version: schema.maybe(schema.string()), key: schema.maybe(schema.string()), compression: schema.maybe( @@ -161,10 +179,20 @@ export const KafkaSchema = { ), client_id: schema.maybe(schema.string()), auth_type: schema.oneOf([ + schema.literal(kafkaAuthType.None), schema.literal(kafkaAuthType.Userpass), schema.literal(kafkaAuthType.Ssl), schema.literal(kafkaAuthType.Kerberos), ]), + connection_type: schema.conditional( + schema.siblingRef('auth_type'), + kafkaAuthType.None, + schema.oneOf([ + schema.literal(kafkaConnectionType.Plaintext), + schema.literal(kafkaConnectionType.Encryption), + ]), + schema.never() + ), username: schema.conditional( schema.siblingRef('auth_type'), kafkaAuthType.Userpass, @@ -206,13 +234,8 @@ export const KafkaSchema = { ), timeout: schema.maybe(schema.number()), broker_timeout: schema.maybe(schema.number()), - broker_buffer_size: schema.maybe(schema.number()), - broker_ack_reliability: schema.maybe( - schema.oneOf([ - schema.literal(kafkaAcknowledgeReliabilityLevel.Commit), - schema.literal(kafkaAcknowledgeReliabilityLevel.Replica), - schema.literal(kafkaAcknowledgeReliabilityLevel.DoNotWait), - ]) + required_acks: schema.maybe( + schema.oneOf([schema.literal(1), schema.literal(0), schema.literal(-1)]) ), }; @@ -220,9 +243,12 @@ const KafkaUpdateSchema = { ...UpdateSchema, ...KafkaSchema, type: schema.maybe(schema.literal(outputType.Kafka)), - hosts: schema.maybe(schema.arrayOf(schema.uri({ scheme: ['http', 'https'] }), { minSize: 1 })), + hosts: schema.maybe( + schema.arrayOf(schema.string({ validate: validateKafkaHost }), { minSize: 1 }) + ), auth_type: schema.maybe( schema.oneOf([ + schema.literal(kafkaAuthType.None), schema.literal(kafkaAuthType.Userpass), schema.literal(kafkaAuthType.Ssl), schema.literal(kafkaAuthType.Kerberos), diff --git a/x-pack/plugins/fleet/server/types/so_attributes.ts b/x-pack/plugins/fleet/server/types/so_attributes.ts index 13ccff751c38d..941f27cde7c4d 100644 --- a/x-pack/plugins/fleet/server/types/so_attributes.ts +++ b/x-pack/plugins/fleet/server/types/so_attributes.ts @@ -14,6 +14,7 @@ import type { OutputType, ShipperOutput, KafkaAcknowledgeReliabilityLevel, + KafkaConnectionTypeType, } from '../../common/types'; import type { AgentType, FleetServerAgentComponent } from '../../common/types/models'; @@ -159,6 +160,7 @@ export interface OutputSoKafkaAttributes extends OutputSoBaseAttributes { compression?: ValueOf; compression_level?: number; auth_type?: ValueOf; + connection_type?: ValueOf; username?: string; password?: string; sasl?: { @@ -188,8 +190,7 @@ export interface OutputSoKafkaAttributes extends OutputSoBaseAttributes { }>; timeout?: number; broker_timeout?: number; - broker_buffer_size?: number; - broker_ack_reliability?: ValueOf; + required_acks?: ValueOf; } export type OutputSOAttributes = diff --git a/x-pack/test/fleet_api_integration/apis/outputs/crud.ts b/x-pack/test/fleet_api_integration/apis/outputs/crud.ts index c870e4bca0ab1..3cc860433eb69 100644 --- a/x-pack/test/fleet_api_integration/apis/outputs/crud.ts +++ b/x-pack/test/fleet_api_integration/apis/outputs/crud.ts @@ -197,7 +197,7 @@ export default function (providerContext: FtrProviderContext) { .send({ name: 'My Kafka Output', type: 'kafka', - hosts: ['https://test.fr'], + hosts: ['test.fr:2000'], auth_type: 'user_pass', username: 'user', password: 'pass', @@ -565,7 +565,7 @@ export default function (providerContext: FtrProviderContext) { .send({ name: 'My Kafka Output', type: 'kafka', - hosts: ['https://test.fr'], + hosts: ['test.fr:2000'], auth_type: 'user_pass', username: 'user', password: 'pass', @@ -579,15 +579,14 @@ export default function (providerContext: FtrProviderContext) { is_default_monitoring: false, name: 'My Kafka Output', type: 'kafka', - hosts: ['https://test.fr'], + hosts: ['test.fr:2000'], auth_type: 'user_pass', username: 'user', password: 'pass', topics: [{ topic: 'topic1' }], broker_timeout: 10, - broker_ack_reliability: 'Wait for local commit', - broker_buffer_size: 256, - client_id: 'Elastic Agent', + required_acks: 1, + client_id: 'Elastic', compression: 'gzip', compression_level: 4, sasl: { @@ -606,7 +605,7 @@ export default function (providerContext: FtrProviderContext) { .send({ name: 'Default Kafka Output', type: 'kafka', - hosts: ['https://test.fr'], + hosts: ['test.fr:2000'], auth_type: 'user_pass', username: 'user', password: 'pass', @@ -619,7 +618,7 @@ export default function (providerContext: FtrProviderContext) { expect(itemWithoutId).to.eql({ name: 'Default Kafka Output', type: 'kafka', - hosts: ['https://test.fr'], + hosts: ['test.fr:2000'], auth_type: 'user_pass', username: 'user', password: 'pass', @@ -627,9 +626,8 @@ export default function (providerContext: FtrProviderContext) { is_default: true, is_default_monitoring: false, broker_timeout: 10, - broker_ack_reliability: 'Wait for local commit', - broker_buffer_size: 256, - client_id: 'Elastic Agent', + required_acks: 1, + client_id: 'Elastic', compression: 'gzip', compression_level: 4, sasl: { @@ -847,7 +845,7 @@ export default function (providerContext: FtrProviderContext) { .send({ name: 'Kafka Output', type: 'kafka', - hosts: ['https://test.fr'], + hosts: ['test.fr:2000'], auth_type: 'user_pass', username: 'user', password: 'pass', @@ -960,7 +958,7 @@ export default function (providerContext: FtrProviderContext) { const kafkaOutputPayload = { name: 'Output to delete test', type: 'kafka', - hosts: ['https://test.fr'], + hosts: ['test.fr:2000'], auth_type: 'user_pass', username: 'user', password: 'pass', From 764fa8aaef38149a2bd5151773887974ac845add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Wed, 9 Aug 2023 17:02:02 +0100 Subject: [PATCH 17/41] [UserProfiles] Move React hook to package (#162888) --- packages/kbn-user-profile-components/index.ts | 13 +- .../src/hooks/index.ts | 9 + .../hooks}/use_update_user_profile.test.tsx | 114 ++++---- .../src/hooks/use_update_user_profile.tsx | 136 +++++++++ .../src/services.tsx | 109 +++++++ .../kbn-user-profile-components/src/types.ts | 47 ++++ .../src/user_avatar.tsx | 3 +- .../src/user_profile.ts | 24 +- .../src/user_tooltip.tsx | 3 +- .../kbn-user-profile-components/tsconfig.json | 6 +- .../cloud_links/kibana.jsonc | 3 + .../maybe_add_cloud_links.test.ts.snap | 51 ++++ .../maybe_add_cloud_links.test.ts | 266 ++++-------------- .../maybe_add_cloud_links.ts | 30 +- .../theme_darkmode_hook.ts | 7 +- .../theme_darkmode_toggle.test.tsx | 28 +- .../theme_darkmode_toggle.tsx | 19 +- .../maybe_add_cloud_links/user_menu_links.tsx | 10 +- .../cloud_links/public/plugin.tsx | 4 +- .../cloud_links/tsconfig.json | 3 + x-pack/plugins/security/common/index.ts | 1 - x-pack/plugins/security/common/model/index.ts | 1 - .../security/common/model/user_profile.ts | 29 +- .../account_management_app.tsx | 19 +- .../public/account_management/index.ts | 1 - .../account_management/user_profile/index.ts | 2 - .../user_profile/use_update_user_profile.tsx | 150 ---------- .../user_profile/user_profile.tsx | 24 +- .../user_profile/user_profile_api_client.ts | 2 +- x-pack/plugins/security/public/index.ts | 1 - x-pack/plugins/security/public/mocks.ts | 3 - .../nav_control/nav_control_component.tsx | 3 +- .../plugins/security/public/plugin.test.tsx | 3 - x-pack/plugins/security/public/plugin.tsx | 15 - .../translations/translations/fr-FR.json | 3 - .../translations/translations/ja-JP.json | 3 - .../translations/translations/zh-CN.json | 3 - .../common/lib/api/user_profiles.ts | 7 +- 38 files changed, 584 insertions(+), 571 deletions(-) create mode 100644 packages/kbn-user-profile-components/src/hooks/index.ts rename {x-pack/plugins/security/public/account_management/user_profile => packages/kbn-user-profile-components/src/hooks}/use_update_user_profile.test.tsx (52%) create mode 100644 packages/kbn-user-profile-components/src/hooks/use_update_user_profile.tsx create mode 100644 packages/kbn-user-profile-components/src/services.tsx create mode 100644 packages/kbn-user-profile-components/src/types.ts create mode 100644 x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/__snapshots__/maybe_add_cloud_links.test.ts.snap delete mode 100644 x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx diff --git a/packages/kbn-user-profile-components/index.ts b/packages/kbn-user-profile-components/index.ts index 5f8d1db6fcf62..c3f5650c17837 100644 --- a/packages/kbn-user-profile-components/index.ts +++ b/packages/kbn-user-profile-components/index.ts @@ -19,6 +19,17 @@ export { getUserDisplayName } from './src/user_profile'; export type { UserProfile, UserProfileUserInfo, - UserProfileAvatarData, GetUserDisplayNameParams, } from './src/user_profile'; +export type { + UserProfileData, + UserSettingsData, + DarkModeValue, + UserProfileAvatarData, +} from './src/types'; +export { useUpdateUserProfile, type UpdateUserProfileHook } from './src/hooks'; +export { + UserProfilesKibanaProvider, + UserProfilesProvider, + type UserProfilesKibanaDependencies, +} from './src/services'; diff --git a/packages/kbn-user-profile-components/src/hooks/index.ts b/packages/kbn-user-profile-components/src/hooks/index.ts new file mode 100644 index 0000000000000..c3f6c8f3b973f --- /dev/null +++ b/packages/kbn-user-profile-components/src/hooks/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { useUpdateUserProfile, type UpdateUserProfileHook } from './use_update_user_profile'; diff --git a/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.test.tsx b/packages/kbn-user-profile-components/src/hooks/use_update_user_profile.test.tsx similarity index 52% rename from x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.test.tsx rename to packages/kbn-user-profile-components/src/hooks/use_update_user_profile.test.tsx index 6690e9b6cf946..3f3621b8aae18 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.test.tsx +++ b/packages/kbn-user-profile-components/src/hooks/use_update_user_profile.test.tsx @@ -1,58 +1,82 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. */ -import { act, renderHook } from '@testing-library/react-hooks'; -import { BehaviorSubject, first, lastValueFrom } from 'rxjs'; -import { coreMock } from '@kbn/core/public/mocks'; - -import { getUseUpdateUserProfile } from './use_update_user_profile'; -import { UserProfileAPIClient } from './user_profile_api_client'; +import React from 'react'; +import { act, renderHook, type WrapperComponent } from '@testing-library/react-hooks'; +import { BehaviorSubject, first, lastValueFrom, of } from 'rxjs'; -const { notifications, http } = coreMock.createStart(); -const userProfileApiClient = new UserProfileAPIClient(http); -const useUpdateUserProfile = getUseUpdateUserProfile({ - apiClient: userProfileApiClient, - notifications, -}); +import { coreMock } from '@kbn/core/public/mocks'; -describe('useUpdateUserProfile', () => { - let spy: jest.SpyInstance; +import { useUpdateUserProfile } from './use_update_user_profile'; +import { UserProfilesKibanaProvider } from '../services'; + +const core = coreMock.createStart(); +const security = { + authc: {}, + navControlService: {}, + userProfiles: { + getCurrent: jest.fn(), + bulkGet: jest.fn(), + suggest: jest.fn(), + update: jest.fn(), + userProfile$: of({}), + }, + uiApi: {}, +}; + +const { http, notifications } = core; + +const wrapper: WrapperComponent = ({ children }) => ( + () => () => undefined} + > + {children} + +); + +describe('useUpdateUserProfile() hook', () => { + const updateUserProfiles = jest.fn(); beforeEach(() => { - spy = jest.spyOn(userProfileApiClient, 'update'); + security.userProfiles = { + ...security.userProfiles, + update: updateUserProfiles, + userProfile$: of({}), + }; + + updateUserProfiles.mockReset().mockResolvedValue({}); http.get.mockReset(); http.post.mockReset().mockResolvedValue(undefined); notifications.toasts.addSuccess.mockReset(); }); - afterEach(() => { - spy.mockRestore(); - }); - test('should call the apiClient with the updated user profile data', async () => { - const { result } = renderHook(() => useUpdateUserProfile()); + const { result } = renderHook(() => useUpdateUserProfile(), { wrapper }); const { update } = result.current; await act(async () => { update({ userSettings: { darkMode: 'dark' } }); }); - expect(spy).toHaveBeenCalledWith({ userSettings: { darkMode: 'dark' } }); + expect(updateUserProfiles).toHaveBeenCalledWith({ userSettings: { darkMode: 'dark' } }); }); test('should update the isLoading state while updating', async () => { - const { result, waitForNextUpdate } = renderHook(() => useUpdateUserProfile()); - const { update } = result.current; - const httpPostDone = new BehaviorSubject(false); - - http.post.mockImplementationOnce(async () => { - await lastValueFrom(httpPostDone.pipe(first((v) => v === true))); + const updateDone = new BehaviorSubject(false); + updateUserProfiles.mockImplementationOnce(async () => { + await lastValueFrom(updateDone.pipe(first((v) => v === true))); }); + const { result, waitForNextUpdate } = renderHook(() => useUpdateUserProfile(), { wrapper }); + const { update } = result.current; + expect(result.current.isLoading).toBeFalsy(); await act(async () => { @@ -61,16 +85,18 @@ describe('useUpdateUserProfile', () => { expect(result.current.isLoading).toBeTruthy(); - httpPostDone.next(true); // Resolve the http.post promise + updateDone.next(true); // Resolve the http.post promise await waitForNextUpdate(); expect(result.current.isLoading).toBeFalsy(); }); test('should show a success notification by default', async () => { - const { result } = renderHook(() => useUpdateUserProfile()); + const { result } = renderHook(() => useUpdateUserProfile(), { wrapper }); const { update } = result.current; + expect(notifications.toasts.addSuccess).not.toHaveBeenCalled(); + await act(async () => { await update({ userSettings: { darkMode: 'dark' } }); }); @@ -88,11 +114,7 @@ describe('useUpdateUserProfile', () => { return true; }; - const { result } = renderHook(() => - useUpdateUserProfile({ - pageReloadChecker, - }) - ); + const { result } = renderHook(() => useUpdateUserProfile({ pageReloadChecker }), { wrapper }); const { update } = result.current; await act(async () => { @@ -114,21 +136,17 @@ describe('useUpdateUserProfile', () => { const pageReloadChecker = jest.fn(); const initialValue = { foo: 'bar' }; - http.get.mockReset().mockResolvedValue({ data: initialValue }); - const userProfileApiClient2 = new UserProfileAPIClient(http); - await userProfileApiClient2.getCurrent(); // Sets the initial value of the userProfile$ Observable - - const { result } = renderHook(() => - getUseUpdateUserProfile({ - apiClient: userProfileApiClient2, - notifications, - })({ - pageReloadChecker, - }) - ); + + security.userProfiles = { + ...security.userProfiles, + userProfile$: of(initialValue), + }; + + const { result } = renderHook(() => useUpdateUserProfile({ pageReloadChecker }), { wrapper }); const { update } = result.current; const nextValue = { userSettings: { darkMode: 'light' as const } }; + await act(async () => { await update(nextValue); }); diff --git a/packages/kbn-user-profile-components/src/hooks/use_update_user_profile.tsx b/packages/kbn-user-profile-components/src/hooks/use_update_user_profile.tsx new file mode 100644 index 0000000000000..3e015fe92eac5 --- /dev/null +++ b/packages/kbn-user-profile-components/src/hooks/use_update_user_profile.tsx @@ -0,0 +1,136 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import React, { useCallback, useRef, useState } from 'react'; +import useObservable from 'react-use/lib/useObservable'; +import { i18n } from '@kbn/i18n'; + +import type { UserProfileData } from '../types'; +import { useUserProfiles } from '../services'; + +interface Props { + notificationSuccess?: { + /** Flag to indicate if a notification is shown after update. Default: `true` */ + enabled?: boolean; + /** Customize the title of the notification */ + title?: string; + /** Customize the "page reload needed" text of the notification */ + pageReloadText?: string; + }; + /** Predicate to indicate if the update requires a page reload */ + pageReloadChecker?: ( + previsous: UserProfileData | null | undefined, + next: UserProfileData + ) => boolean; +} + +const i18nTexts = { + notificationSuccess: { + title: i18n.translate( + 'userProfileComponents.updateUserProfile.notification.submitSuccessTitle', + { + defaultMessage: 'Profile updated', + } + ), + pageReloadText: i18n.translate( + 'userProfileComponents.updateUserProfile.notification.requiresPageReloadDescription', + { + defaultMessage: 'One or more settings require you to reload the page to take effect.', + } + ), + }, +}; + +export const useUpdateUserProfile = ({ + notificationSuccess = {}, + pageReloadChecker, +}: Props = {}) => { + const { userProfileApiClient, notifySuccess } = useUserProfiles(); + const { userProfile$ } = userProfileApiClient; + const { + enabled: notificationSuccessEnabled = true, + title: notificationTitle = i18nTexts.notificationSuccess.title, + pageReloadText = i18nTexts.notificationSuccess.pageReloadText, + } = notificationSuccess; + const [isLoading, setIsLoading] = useState(false); + const userProfileData = useObservable(userProfile$); + // Keep a snapshot before updating the user profile so we can compare previous and updated values + const userProfileSnapshot = useRef(); + + const showSuccessNotification = useCallback( + ({ isRefreshRequired = false }: { isRefreshRequired?: boolean } = {}) => { + if (isRefreshRequired) { + notifySuccess( + { + title: notificationTitle, + text: ( + + +

    {pageReloadText}

    + window.location.reload()} + data-test-subj="windowReloadButton" + > + {i18n.translate( + 'userProfileComponents.updateUserProfile.notification.requiresPageReloadButtonLabel', + { + defaultMessage: 'Reload page', + } + )} + +
    +
    + ), + }, + { + durationMs: 1000 * 60 * 5, + } + ); + } else { + notifySuccess({ title: notificationTitle }); + } + }, + [notificationTitle, notifySuccess, pageReloadText] + ); + + const onUserProfileUpdate = useCallback( + (updatedData: UserProfileData) => { + setIsLoading(false); + + if (notificationSuccessEnabled) { + const isRefreshRequired = pageReloadChecker?.(userProfileSnapshot.current, updatedData); + showSuccessNotification({ isRefreshRequired }); + } + }, + [notificationSuccessEnabled, showSuccessNotification, pageReloadChecker] + ); + + const update = useCallback( + (updatedData: D) => { + userProfileSnapshot.current = userProfileData; + setIsLoading(true); + return userProfileApiClient.update(updatedData).then(() => onUserProfileUpdate(updatedData)); + }, + [userProfileApiClient, onUserProfileUpdate, userProfileData] + ); + + return { + /** Update the user profile */ + update, + /** Handler to show a notification after the user profile has been updated */ + showSuccessNotification, + /** The current user profile data */ + userProfileData, + /** Flag to indicate if currently updating */ + isLoading, + }; +}; + +export type UpdateUserProfileHook = typeof useUpdateUserProfile; diff --git a/packages/kbn-user-profile-components/src/services.tsx b/packages/kbn-user-profile-components/src/services.tsx new file mode 100644 index 0000000000000..0e08ca911eb61 --- /dev/null +++ b/packages/kbn-user-profile-components/src/services.tsx @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React, { FC, useContext } from 'react'; +import type { Observable } from 'rxjs'; +import type { NotificationsStart, ToastOptions } from '@kbn/core-notifications-browser'; +import type { MountPoint } from '@kbn/core-mount-utils-browser'; +import type { ThemeServiceStart } from '@kbn/core-theme-browser'; + +import type { UserProfileAPIClient } from './types'; + +type NotifyFn = ( + data: { title: string; text?: JSX.Element }, + options?: { durationMs?: number } +) => void; + +export interface Services { + userProfileApiClient: UserProfileAPIClient; + notifySuccess: NotifyFn; +} + +const UserProfilesContext = React.createContext(null); + +/** + * Abstract external service Provider. + */ +export const UserProfilesProvider: FC = ({ children, ...services }) => { + return {children}; +}; + +/** + * Kibana-specific service types. + */ +export interface UserProfilesKibanaDependencies { + /** CoreStart contract */ + core: { + notifications: NotificationsStart; + theme: ThemeServiceStart; + }; + security: { + userProfiles: UserProfileAPIClient; + }; + /** + * Handler from the '@kbn/kibana-react-plugin/public' Plugin + * + * ``` + * import { toMountPoint } from '@kbn/kibana-react-plugin/public'; + * ``` + */ + toMountPoint: ( + node: React.ReactNode, + options?: { theme$: Observable<{ readonly darkMode: boolean }> } + ) => MountPoint; +} + +/** + * Kibana-specific Provider that maps to known dependency types. + */ +export const UserProfilesKibanaProvider: FC = ({ + children, + ...services +}) => { + const { + core: { notifications, theme }, + security: { userProfiles: userProfileApiClient }, + toMountPoint, + } = services; + + return ( + { + const toastOptions: ToastOptions = {}; + if (options?.durationMs) { + toastOptions.toastLifeTimeMs = options.durationMs; + } + notifications.toasts.addSuccess( + { + title, + text: text ? toMountPoint(text, { theme$: theme.theme$ }) : undefined, + }, + toastOptions + ); + }} + > + {children} + + ); +}; + +/** + * React hook for accessing pre-wired services. + */ +export function useUserProfiles() { + const context = useContext(UserProfilesContext); + + if (!context) { + throw new Error( + 'UserProfilesContext is missing. Ensure your component or React root is wrapped with or .' + ); + } + + return context; +} diff --git a/packages/kbn-user-profile-components/src/types.ts b/packages/kbn-user-profile-components/src/types.ts new file mode 100644 index 0000000000000..77b6895756bdf --- /dev/null +++ b/packages/kbn-user-profile-components/src/types.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { Observable } from 'rxjs'; + +/** + * Avatar stored in user profile. + */ +export interface UserProfileAvatarData { + /** + * Optional initials (two letters) of the user to use as avatar if avatar picture isn't specified. + */ + initials?: string; + /** + * Background color of the avatar when initials are used. + */ + color?: string; + /** + * Base64 data URL for the user avatar image. + */ + imageUrl?: string | null; +} + +export type DarkModeValue = '' | 'dark' | 'light'; + +/** + * User settings stored in the data object of the User Profile + */ +export interface UserSettingsData { + darkMode?: DarkModeValue; +} + +export interface UserProfileData { + avatar?: UserProfileAvatarData; + userSettings?: UserSettingsData; + [key: string]: unknown; +} + +export interface UserProfileAPIClient { + userProfile$: Observable; + update: (data: D) => Promise; +} diff --git a/packages/kbn-user-profile-components/src/user_avatar.tsx b/packages/kbn-user-profile-components/src/user_avatar.tsx index 2413694317c27..1b2a2152f27fc 100644 --- a/packages/kbn-user-profile-components/src/user_avatar.tsx +++ b/packages/kbn-user-profile-components/src/user_avatar.tsx @@ -10,8 +10,9 @@ import type { EuiAvatarProps } from '@elastic/eui'; import { EuiAvatar, useEuiTheme } from '@elastic/eui'; import type { FunctionComponent } from 'react'; import React from 'react'; +import { UserProfileAvatarData } from './types'; -import type { UserProfile, UserProfileUserInfo, UserProfileAvatarData } from './user_profile'; +import type { UserProfile, UserProfileUserInfo } from './user_profile'; import { getUserAvatarColor, getUserAvatarInitials, diff --git a/packages/kbn-user-profile-components/src/user_profile.ts b/packages/kbn-user-profile-components/src/user_profile.ts index 4d0803ad6dbec..965f5e9706e8e 100644 --- a/packages/kbn-user-profile-components/src/user_profile.ts +++ b/packages/kbn-user-profile-components/src/user_profile.ts @@ -7,6 +7,7 @@ */ import { VISUALIZATION_COLORS } from '@elastic/eui'; +import type { UserProfileAvatarData, UserProfileData } from './types'; /** * IMPORTANT: @@ -60,29 +61,6 @@ export interface UserProfileUserInfo { full_name?: string; } -/** - * Placeholder for data stored in user profile. - */ -export type UserProfileData = Record; - -/** - * Avatar stored in user profile. - */ -export interface UserProfileAvatarData { - /** - * Optional initials (two letters) of the user to use as avatar if avatar picture isn't specified. - */ - initials?: string; - /** - * Background color of the avatar when initials are used. - */ - color?: string; - /** - * Base64 data URL for the user avatar image. - */ - imageUrl?: string | null; -} - export const USER_AVATAR_FALLBACK_CODE_POINT = 97; // code point for lowercase "a" export const USER_AVATAR_MAX_INITIALS = 2; diff --git a/packages/kbn-user-profile-components/src/user_tooltip.tsx b/packages/kbn-user-profile-components/src/user_tooltip.tsx index c2678996aebb3..76b7ca1414274 100644 --- a/packages/kbn-user-profile-components/src/user_tooltip.tsx +++ b/packages/kbn-user-profile-components/src/user_tooltip.tsx @@ -11,9 +11,10 @@ import { EuiToolTip, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import type { FunctionComponent } from 'react'; import React from 'react'; -import type { UserProfileUserInfo, UserProfileAvatarData } from './user_profile'; +import type { UserProfileUserInfo } from './user_profile'; import { UserAvatar } from './user_avatar'; import { getUserDisplayName } from './user_profile'; +import { UserProfileAvatarData } from './types'; /** * Props of {@link UserToolTip} component diff --git a/packages/kbn-user-profile-components/tsconfig.json b/packages/kbn-user-profile-components/tsconfig.json index 6f64745691be8..a602ca242d733 100644 --- a/packages/kbn-user-profile-components/tsconfig.json +++ b/packages/kbn-user-profile-components/tsconfig.json @@ -13,7 +13,11 @@ ], "kbn_references": [ "@kbn/i18n", - "@kbn/i18n-react" + "@kbn/i18n-react", + "@kbn/core-notifications-browser", + "@kbn/core", + "@kbn/core-theme-browser", + "@kbn/core-mount-utils-browser", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/cloud_integrations/cloud_links/kibana.jsonc b/x-pack/plugins/cloud_integrations/cloud_links/kibana.jsonc index b9b9a0f629b64..4b6625f842f79 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/kibana.jsonc +++ b/x-pack/plugins/cloud_integrations/cloud_links/kibana.jsonc @@ -11,6 +11,9 @@ "cloud", "security", "guidedOnboarding" + ], + "requiredBundles": [ + "kibanaReact" ] } } diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/__snapshots__/maybe_add_cloud_links.test.ts.snap b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/__snapshots__/maybe_add_cloud_links.test.ts.snap new file mode 100644 index 0000000000000..7a957943fe2f0 --- /dev/null +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/__snapshots__/maybe_add_cloud_links.test.ts.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`maybeAddCloudLinks when cloud enabled and it fails to fetch the user, it sets the links 2`] = ` +Array [ + Object { + "href": "profile-url", + "iconType": "user", + "label": "Profile", + "order": 100, + "setAsProfile": true, + }, + Object { + "href": "billing-url", + "iconType": "visGauge", + "label": "Billing", + "order": 200, + }, + Object { + "href": "organization-url", + "iconType": "gear", + "label": "Organization", + "order": 300, + }, + Any, +] +`; + +exports[`maybeAddCloudLinks when cloud enabled and the user is an Elastic Cloud user, it sets the links 2`] = ` +Array [ + Object { + "href": "profile-url", + "iconType": "user", + "label": "Profile", + "order": 100, + "setAsProfile": true, + }, + Object { + "href": "billing-url", + "iconType": "visGauge", + "label": "Billing", + "order": 200, + }, + Object { + "href": "organization-url", + "iconType": "gear", + "label": "Organization", + "order": 300, + }, + Any, +] +`; diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts index f2e14d1a08526..b9045fdc9a59f 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.test.ts @@ -14,12 +14,11 @@ import { maybeAddCloudLinks } from './maybe_add_cloud_links'; describe('maybeAddCloudLinks', () => { it('should skip if cloud is disabled', async () => { const security = securityMock.createStart(); + const core = coreMock.createStart(); maybeAddCloudLinks({ + core, security, - chrome: coreMock.createStart().chrome, cloud: { ...cloudMock.createStart(), isCloudEnabled: false }, - docLinks: coreMock.createStart().docLinks, - uiSettingsClient: coreMock.createStart().uiSettings, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); @@ -31,13 +30,12 @@ describe('maybeAddCloudLinks', () => { security.authc.getCurrentUser.mockResolvedValue( securityMock.createMockAuthenticatedUser({ elastic_cloud_user: true }) ); - const { chrome, docLinks, uiSettings } = coreMock.createStart(); + const core = coreMock.createStart(); + const { chrome } = core; maybeAddCloudLinks({ security, - chrome, + core, cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, - docLinks, - uiSettingsClient: uiSettings, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); @@ -53,104 +51,28 @@ describe('maybeAddCloudLinks', () => { ] `); expect(security.navControlService.addUserMenuLinks).toHaveBeenCalledTimes(1); - expect(security.navControlService.addUserMenuLinks.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - Array [ - Object { - "href": "profile-url", - "iconType": "user", - "label": "Profile", - "order": 100, - "setAsProfile": true, - }, - Object { - "href": "billing-url", - "iconType": "visGauge", - "label": "Billing", - "order": 200, - }, - Object { - "href": "organization-url", - "iconType": "gear", - "label": "Organization", - "order": 300, - }, - Object { - "content": , - "href": "", - "iconType": "", - "label": "", - "order": 400, - }, - ], - ] - `); + expect(security.navControlService.addUserMenuLinks.mock.calls[0][0]).toMatchSnapshot([ + { + href: 'profile-url', + iconType: 'user', + label: 'Profile', + order: 100, + setAsProfile: true, + }, + { + href: 'billing-url', + iconType: 'visGauge', + label: 'Billing', + order: 200, + }, + { + href: 'organization-url', + iconType: 'gear', + label: 'Organization', + order: 300, + }, + expect.any(Object), + ]); expect(chrome.setHelpMenuLinks).toHaveBeenCalledTimes(1); expect(chrome.setHelpMenuLinks.mock.calls[0]).toMatchInlineSnapshot(` @@ -176,13 +98,12 @@ describe('maybeAddCloudLinks', () => { it('when cloud enabled and it fails to fetch the user, it sets the links', async () => { const security = securityMock.createStart(); security.authc.getCurrentUser.mockRejectedValue(new Error('Something went terribly wrong')); - const { chrome, docLinks, uiSettings } = coreMock.createStart(); + const core = coreMock.createStart(); + const { chrome } = core; maybeAddCloudLinks({ security, - chrome, + core, cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, - docLinks, - uiSettingsClient: uiSettings, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); @@ -198,104 +119,28 @@ describe('maybeAddCloudLinks', () => { ] `); expect(security.navControlService.addUserMenuLinks).toHaveBeenCalledTimes(1); - expect(security.navControlService.addUserMenuLinks.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - Array [ - Object { - "href": "profile-url", - "iconType": "user", - "label": "Profile", - "order": 100, - "setAsProfile": true, - }, - Object { - "href": "billing-url", - "iconType": "visGauge", - "label": "Billing", - "order": 200, - }, - Object { - "href": "organization-url", - "iconType": "gear", - "label": "Organization", - "order": 300, - }, - Object { - "content": , - "href": "", - "iconType": "", - "label": "", - "order": 400, - }, - ], - ] - `); + expect(security.navControlService.addUserMenuLinks.mock.calls[0][0]).toMatchSnapshot([ + { + href: 'profile-url', + iconType: 'user', + label: 'Profile', + order: 100, + setAsProfile: true, + }, + { + href: 'billing-url', + iconType: 'visGauge', + label: 'Billing', + order: 200, + }, + { + href: 'organization-url', + iconType: 'gear', + label: 'Organization', + order: 300, + }, + expect.any(Object), + ]); expect(chrome.setHelpMenuLinks).toHaveBeenCalledTimes(1); expect(chrome.setHelpMenuLinks.mock.calls[0]).toMatchInlineSnapshot(` Array [ @@ -322,13 +167,12 @@ describe('maybeAddCloudLinks', () => { security.authc.getCurrentUser.mockResolvedValue( securityMock.createMockAuthenticatedUser({ elastic_cloud_user: false }) ); - const { chrome, docLinks, uiSettings } = coreMock.createStart(); + const core = coreMock.createStart(); + const { chrome } = core; maybeAddCloudLinks({ security, - chrome, + core, cloud: { ...cloudMock.createStart(), isCloudEnabled: true }, - docLinks, - uiSettingsClient: uiSettings, }); // Since there's a promise, let's wait for the next tick await new Promise((resolve) => process.nextTick(resolve)); diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts index 1becd2cdf7254..33fb4df7bfce2 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/maybe_add_cloud_links.ts @@ -9,28 +9,18 @@ import { catchError, defer, filter, map, of, combineLatest } from 'rxjs'; import { i18n } from '@kbn/i18n'; import type { CloudStart } from '@kbn/cloud-plugin/public'; -import type { ChromeStart } from '@kbn/core/public'; +import type { CoreStart } from '@kbn/core/public'; import type { SecurityPluginStart } from '@kbn/security-plugin/public'; -import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; -import type { DocLinksStart } from '@kbn/core-doc-links-browser'; import { createUserMenuLinks } from './user_menu_links'; import { createHelpMenuLinks } from './help_menu_links'; export interface MaybeAddCloudLinksDeps { + core: CoreStart; security: SecurityPluginStart; - chrome: ChromeStart; cloud: CloudStart; - docLinks: DocLinksStart; - uiSettingsClient: IUiSettingsClient; } -export function maybeAddCloudLinks({ - security, - chrome, - cloud, - docLinks, - uiSettingsClient, -}: MaybeAddCloudLinksDeps): void { +export function maybeAddCloudLinks({ core, security, cloud }: MaybeAddCloudLinksDeps): void { const userObservable = defer(() => security.authc.getCurrentUser()).pipe( // Check if user is a cloud user. map((user) => user.elastic_cloud_user), @@ -39,7 +29,7 @@ export function maybeAddCloudLinks({ filter((isElasticCloudUser) => isElasticCloudUser === true), map(() => { if (cloud.deploymentUrl) { - chrome.setCustomNavLink({ + core.chrome.setCustomNavLink({ title: i18n.translate('xpack.cloudLinks.deploymentLinkLabel', { defaultMessage: 'Manage this deployment', }), @@ -47,22 +37,26 @@ export function maybeAddCloudLinks({ href: cloud.deploymentUrl, }); } - const userMenuLinks = createUserMenuLinks({ cloud, security, uiSettingsClient }); + const userMenuLinks = createUserMenuLinks({ + core, + cloud, + security, + }); security.navControlService.addUserMenuLinks(userMenuLinks); }) ); - const helpObservable = chrome.getHelpSupportUrl$(); + const helpObservable = core.chrome.getHelpSupportUrl$(); if (cloud.isCloudEnabled) { combineLatest({ user: userObservable, helpSupportUrl: helpObservable }).subscribe( ({ helpSupportUrl }) => { const helpMenuLinks = createHelpMenuLinks({ - docLinks, + docLinks: core.docLinks, helpSupportUrl, }); - chrome.setHelpMenuLinks(helpMenuLinks); + core.chrome.setHelpMenuLinks(helpMenuLinks); } ); } diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_hook.ts b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_hook.ts index 75d6ae4d1d329..c0a4fcc3a09ac 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_hook.ts +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_hook.ts @@ -7,21 +7,20 @@ import { useCallback, useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import type { SecurityPluginStart } from '@kbn/security-plugin/public'; import { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; +import { useUpdateUserProfile } from '@kbn/user-profile-components'; interface Deps { uiSettingsClient: IUiSettingsClient; - security: SecurityPluginStart; } -export const useThemeDarkmodeToggle = ({ uiSettingsClient, security }: Deps) => { +export const useThemeDarkmodeToggle = ({ uiSettingsClient }: Deps) => { const [isDarkModeOn, setIsDarkModeOn] = useState(false); // If a value is set in kibana.yml (uiSettings.overrides.theme:darkMode) // we don't allow the user to change the theme color. const valueSetInKibanaConfig = uiSettingsClient.isOverridden('theme:darkMode'); - const { userProfileData, isLoading, update } = security.hooks.useUpdateUserProfile({ + const { userProfileData, isLoading, update } = useUpdateUserProfile({ notificationSuccess: { title: i18n.translate('xpack.cloudLinks.userMenuLinks.darkMode.successNotificationTitle', { defaultMessage: 'Color theme updated', diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.test.tsx b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.test.tsx index 2bebdad488498..6b06cd64b9e23 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.test.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.test.tsx @@ -11,18 +11,22 @@ import '@testing-library/jest-dom'; import { coreMock } from '@kbn/core/public/mocks'; import { securityMock } from '@kbn/security-plugin/public/mocks'; -import { ThemDarkModeToggle } from './theme_darkmode_toggle'; +import { ThemeDarkModeToggle } from './theme_darkmode_toggle'; -describe('ThemDarkModeToggle', () => { - const mockUseUpdateUserProfile = jest.fn(); - const mockGetSpaceDarkModeValue = jest.fn(); +const mockUseUpdateUserProfile = jest.fn(); +jest.mock('@kbn/user-profile-components', () => { + const original = jest.requireActual('@kbn/user-profile-components'); + return { + ...original, + useUpdateUserProfile: () => mockUseUpdateUserProfile(), + }; +}); + +describe('ThemeDarkModeToggle', () => { it('renders correctly and toggles dark mode', () => { - const security = { - ...securityMock.createStart(), - hooks: { useUpdateUserProfile: mockUseUpdateUserProfile }, - }; - const { uiSettings } = coreMock.createStart(); + const security = securityMock.createStart(); + const core = coreMock.createStart(); const mockUpdate = jest.fn(); mockUseUpdateUserProfile.mockReturnValue({ @@ -31,10 +35,8 @@ describe('ThemDarkModeToggle', () => { update: mockUpdate, }); - mockGetSpaceDarkModeValue.mockReturnValue(false); - const { getByTestId, rerender } = render( - + ); const toggleSwitch = getByTestId('darkModeToggleSwitch'); @@ -49,7 +51,7 @@ describe('ThemDarkModeToggle', () => { }); // Rerender the component to apply the new props - rerender(); + rerender(); fireEvent.click(toggleSwitch); expect(mockUpdate).toHaveBeenLastCalledWith({ userSettings: { darkMode: 'light' } }); diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx index 3f85c2ed63a76..20085172b2c68 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx @@ -17,19 +17,30 @@ import { import { i18n } from '@kbn/i18n'; import type { SecurityPluginStart } from '@kbn/security-plugin/public'; import { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; +import { UserProfilesKibanaProvider } from '@kbn/user-profile-components'; +import { CoreStart } from '@kbn/core-lifecycle-browser'; +import { toMountPoint } from '@kbn/kibana-react-plugin/public'; + import { useThemeDarkmodeToggle } from './theme_darkmode_hook'; interface Props { - uiSettingsClient: IUiSettingsClient; security: SecurityPluginStart; + core: CoreStart; } -export const ThemDarkModeToggle = ({ security, uiSettingsClient }: Props) => { +export const ThemeDarkModeToggle = ({ security, core }: Props) => { + return ( + + + + ); +}; + +function ThemeDarkModeToggleUi({ uiSettingsClient }: { uiSettingsClient: IUiSettingsClient }) { const toggleTextSwitchId = useGeneratedHtmlId({ prefix: 'toggleTextSwitch' }); const { euiTheme } = useEuiTheme(); const { isVisible, toggle, isDarkModeOn, colorScheme } = useThemeDarkmodeToggle({ - security, uiSettingsClient, }); @@ -77,4 +88,4 @@ export const ThemDarkModeToggle = ({ security, uiSettingsClient }: Props) => { ); -}; +} diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.tsx b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.tsx index 1eae5d6ed0c58..16ffa32360f25 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/user_menu_links.tsx @@ -9,17 +9,17 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import type { CloudStart } from '@kbn/cloud-plugin/public'; import type { SecurityPluginStart, UserMenuLink } from '@kbn/security-plugin/public'; -import { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; -import { ThemDarkModeToggle } from './theme_darkmode_toggle'; +import type { CoreStart } from '@kbn/core/public'; +import { ThemeDarkModeToggle } from './theme_darkmode_toggle'; export const createUserMenuLinks = ({ + core, cloud, security, - uiSettingsClient, }: { + core: CoreStart; cloud: CloudStart; security: SecurityPluginStart; - uiSettingsClient: IUiSettingsClient; }): UserMenuLink[] => { const { profileUrl, billingUrl, organizationUrl } = cloud; @@ -60,7 +60,7 @@ export const createUserMenuLinks = ({ } userMenuLinks.push({ - content: , + content: , order: 400, label: '', iconType: '', diff --git a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx index 7ee3f0969251d..38b568791b70b 100755 --- a/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx +++ b/x-pack/plugins/cloud_integrations/cloud_links/public/plugin.tsx @@ -44,11 +44,9 @@ export class CloudLinksPlugin } if (security) { maybeAddCloudLinks({ + core, security, - chrome: core.chrome, cloud, - docLinks: core.docLinks, - uiSettingsClient: core.uiSettings, }); } } diff --git a/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json b/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json index 0dfa7ce42858d..f1a67895cdd5e 100644 --- a/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json +++ b/x-pack/plugins/cloud_integrations/cloud_links/tsconfig.json @@ -20,6 +20,9 @@ "@kbn/core-chrome-browser", "@kbn/core-doc-links-browser", "@kbn/core-ui-settings-browser", + "@kbn/user-profile-components", + "@kbn/core-lifecycle-browser", + "@kbn/kibana-react-plugin", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/security/common/index.ts b/x-pack/plugins/security/common/index.ts index f7ee13c610a45..c547833949ded 100644 --- a/x-pack/plugins/security/common/index.ts +++ b/x-pack/plugins/security/common/index.ts @@ -23,7 +23,6 @@ export type { UserProfileWithSecurity, UserProfileData, UserProfileLabels, - UserProfileAvatarData, UserProfileUserInfoWithSecurity, ApiKey, UserRealm, diff --git a/x-pack/plugins/security/common/model/index.ts b/x-pack/plugins/security/common/model/index.ts index 822d6036efc06..c8505a644503f 100644 --- a/x-pack/plugins/security/common/model/index.ts +++ b/x-pack/plugins/security/common/model/index.ts @@ -22,7 +22,6 @@ export type { UserProfileData, UserProfileLabels, UserProfileUserInfoWithSecurity, - UserProfileAvatarData, } from './user_profile'; export { getUserAvatarColor, diff --git a/x-pack/plugins/security/common/model/user_profile.ts b/x-pack/plugins/security/common/model/user_profile.ts index c4dd6addd51fc..152b0d0266bbe 100644 --- a/x-pack/plugins/security/common/model/user_profile.ts +++ b/x-pack/plugins/security/common/model/user_profile.ts @@ -7,6 +7,8 @@ import { VISUALIZATION_COLORS } from '@elastic/eui'; +import type { UserProfileAvatarData } from '@kbn/user-profile-components'; + import type { AuthenticatedUser } from './authenticated_user'; import { getUserDisplayName } from './user'; @@ -72,33 +74,6 @@ export type UserProfileData = Record; */ export type UserProfileLabels = Record; -/** - * Avatar stored in user profile. - */ -export interface UserProfileAvatarData { - /** - * Optional initials (two letters) of the user to use as avatar if avatar picture isn't specified. - */ - initials?: string; - /** - * Background color of the avatar when initials are used. - */ - color?: string; - /** - * Base64 data URL for the user avatar image. - */ - imageUrl?: string | null; -} - -export type DarkModeValue = '' | 'dark' | 'light'; - -/** - * User settings stored in the data object of the User Profile - */ -export interface UserSettingsData { - darkMode?: DarkModeValue; -} - /** * Extended user information returned in user profile (both basic and security related properties). */ diff --git a/x-pack/plugins/security/public/account_management/account_management_app.tsx b/x-pack/plugins/security/public/account_management/account_management_app.tsx index 29722c10ea84d..a5b98d66d46ff 100644 --- a/x-pack/plugins/security/public/account_management/account_management_app.tsx +++ b/x-pack/plugins/security/public/account_management/account_management_app.tsx @@ -21,8 +21,13 @@ import type { import { AppNavLinkStatus } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { I18nProvider } from '@kbn/i18n-react'; -import { KibanaContextProvider, KibanaThemeProvider } from '@kbn/kibana-react-plugin/public'; +import { + KibanaContextProvider, + KibanaThemeProvider, + toMountPoint, +} from '@kbn/kibana-react-plugin/public'; import { Router } from '@kbn/shared-ux-router'; +import { UserProfilesKibanaProvider } from '@kbn/user-profile-components'; import type { AuthenticationServiceSetup } from '../authentication'; import type { SecurityApiClients } from '../components'; @@ -96,7 +101,17 @@ export const Providers: FunctionComponent = ({ - {children} + + + {children} + + diff --git a/x-pack/plugins/security/public/account_management/index.ts b/x-pack/plugins/security/public/account_management/index.ts index eca7287537318..e1a4957aa71e7 100644 --- a/x-pack/plugins/security/public/account_management/index.ts +++ b/x-pack/plugins/security/public/account_management/index.ts @@ -11,5 +11,4 @@ export type { UserProfileBulkGetParams, UserProfileGetCurrentParams, UserProfileSuggestParams, - UpdateUserProfileHook, } from './user_profile'; diff --git a/x-pack/plugins/security/public/account_management/user_profile/index.ts b/x-pack/plugins/security/public/account_management/user_profile/index.ts index 93a1c7d04d315..ed34d7d4a4339 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/index.ts +++ b/x-pack/plugins/security/public/account_management/user_profile/index.ts @@ -13,5 +13,3 @@ export type { UserProfileBulkGetParams, UserProfileSuggestParams, } from './user_profile_api_client'; - -export type { UpdateUserProfileHook } from './use_update_user_profile'; diff --git a/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx b/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx deleted file mode 100644 index 2dafa61496fe8..0000000000000 --- a/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import React, { useCallback, useRef, useState } from 'react'; -import useObservable from 'react-use/lib/useObservable'; - -import type { NotificationsStart, ToastInput, ToastOptions } from '@kbn/core/public'; -import { i18n } from '@kbn/i18n'; -import { toMountPoint } from '@kbn/kibana-react-plugin/public'; - -import type { UserProfileData } from './user_profile'; -import type { UserProfileAPIClient } from './user_profile_api_client'; - -interface Deps { - apiClient: UserProfileAPIClient; - notifications: NotificationsStart; -} - -interface Props { - notificationSuccess?: { - /** Flag to indicate if a notification is shown after update. Default: `true` */ - enabled?: boolean; - /** Customize the title of the notification */ - title?: string; - /** Customize the "page reload needed" text of the notification */ - pageReloadText?: string; - }; - /** Predicate to indicate if the update requires a page reload */ - pageReloadChecker?: ( - previsous: UserProfileData | null | undefined, - next: UserProfileData - ) => boolean; -} - -export type UpdateUserProfileHook = (props?: Props) => { - /** Update the user profile */ - update: (data: UserProfileData) => void; - /** Handler to show a notification after the user profile has been updated */ - showSuccessNotification: (props: { isRefreshRequired: boolean }) => void; - /** Flag to indicate if currently updating */ - isLoading: boolean; - /** The current user profile data */ - userProfileData?: UserProfileData | null; -}; - -const i18nTexts = { - notificationSuccess: { - title: i18n.translate('xpack.security.accountManagement.userProfile.submitSuccessTitle', { - defaultMessage: 'Profile updated', - }), - pageReloadText: i18n.translate( - 'xpack.security.accountManagement.userProfile.requiresPageReloadToastDescription', - { - defaultMessage: 'One or more settings require you to reload the page to take effect.', - } - ), - }, -}; - -export const getUseUpdateUserProfile = ({ apiClient, notifications }: Deps) => { - const { userProfile$ } = apiClient; - - const useUpdateUserProfile = ({ notificationSuccess = {}, pageReloadChecker }: Props = {}) => { - const { - enabled: notificationSuccessEnabled = true, - title: notificationTitle = i18nTexts.notificationSuccess.title, - pageReloadText = i18nTexts.notificationSuccess.pageReloadText, - } = notificationSuccess; - const [isLoading, setIsLoading] = useState(false); - const userProfileData = useObservable(userProfile$); - // Keep a snapshot before updating the user profile so we can compare previous and updated values - const userProfileSnapshot = useRef(); - - const showSuccessNotification = useCallback( - ({ isRefreshRequired = false }: { isRefreshRequired?: boolean } = {}) => { - let successToastInput: ToastInput = { - title: notificationTitle, - }; - let successToastOptions: ToastOptions = {}; - - if (isRefreshRequired) { - successToastOptions = { - toastLifeTimeMs: 1000 * 60 * 5, - }; - - successToastInput = { - ...successToastInput, - text: toMountPoint( - - -

    {pageReloadText}

    - window.location.reload()} - data-test-subj="windowReloadButton" - > - {i18n.translate( - 'xpack.security.accountManagement.userProfile.requiresPageReloadToastButtonLabel', - { - defaultMessage: 'Reload page', - } - )} - -
    -
    - ), - }; - } - - notifications.toasts.addSuccess(successToastInput, successToastOptions); - }, - [notificationTitle, pageReloadText] - ); - - const onUserProfileUpdate = useCallback( - (updatedData: UserProfileData) => { - setIsLoading(false); - - if (notificationSuccessEnabled) { - const isRefreshRequired = pageReloadChecker?.(userProfileSnapshot.current, updatedData); - showSuccessNotification({ isRefreshRequired }); - } - }, - [notificationSuccessEnabled, showSuccessNotification, pageReloadChecker] - ); - - const update = useCallback( - (udpatedData: D) => { - userProfileSnapshot.current = userProfileData; - setIsLoading(true); - return apiClient.update(udpatedData).then(() => onUserProfileUpdate(udpatedData)); - }, - [onUserProfileUpdate, userProfileData] - ); - - return { - update, - showSuccessNotification, - userProfileData, - isLoading, - }; - }; - - return useUpdateUserProfile; -}; diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx b/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx index 2632f73e99d07..a6227baee4061 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile.tsx @@ -39,7 +39,8 @@ import type { CoreStart, IUiSettingsClient } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { useKibana } from '@kbn/kibana-react-plugin/public'; -import { UserAvatar } from '@kbn/user-profile-components'; +import type { DarkModeValue, UserProfileData } from '@kbn/user-profile-components'; +import { UserAvatar, useUpdateUserProfile } from '@kbn/user-profile-components'; import type { AuthenticatedUser } from '../../../common'; import { @@ -48,11 +49,6 @@ import { getUserAvatarColor, getUserAvatarInitials, } from '../../../common/model'; -import type { - DarkModeValue, - UserProfileAvatarData, - UserSettingsData, -} from '../../../common/model/user_profile'; import { useSecurityApiClients } from '../../components'; import { Breadcrumb } from '../../components/breadcrumb'; import { @@ -65,15 +61,8 @@ import { FormLabel } from '../../components/form_label'; import { FormRow, OptionalText } from '../../components/form_row'; import { ChangePasswordModal } from '../../management/users/edit_user/change_password_modal'; import { isUserReserved } from '../../management/users/user_utils'; -import { getUseUpdateUserProfile } from './use_update_user_profile'; import { createImageHandler, getRandomColor, IMAGE_FILE_TYPES, VALID_HEX_COLOR } from './utils'; -export interface UserProfileData { - avatar?: UserProfileAvatarData; - userSettings?: UserSettingsData; - [key: string]: unknown; -} - export interface UserProfileProps { user: AuthenticatedUser; data?: UserProfileData; @@ -833,12 +822,11 @@ export const UserProfile: FunctionComponent = ({ user, data }) export function useUserProfileForm({ user, data }: UserProfileProps) { const { services } = useKibana(); - const { userProfiles, users } = useSecurityApiClients(); + const { users } = useSecurityApiClients(); - const { update, showSuccessNotification } = getUseUpdateUserProfile({ - apiClient: userProfiles, - notifications: services.notifications, - })({ notificationSuccess: { enabled: false } }); + const { update, showSuccessNotification } = useUpdateUserProfile({ + notificationSuccess: { enabled: false }, + }); const [initialValues, resetInitialValues] = useState({ user: { diff --git a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts index 4b992f616ca14..4760aa15ab0b3 100644 --- a/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts +++ b/x-pack/plugins/security/public/account_management/user_profile/user_profile_api_client.ts @@ -10,9 +10,9 @@ import type { Observable } from 'rxjs'; import { BehaviorSubject, Subject } from 'rxjs'; import type { HttpStart } from '@kbn/core/public'; +import type { UserProfileData } from '@kbn/user-profile-components'; import type { GetUserProfileResponse, UserProfile } from '../../../common'; -import type { UserProfileData } from './user_profile'; /** * Parameters for the get user profile for the current user API. diff --git a/x-pack/plugins/security/public/index.ts b/x-pack/plugins/security/public/index.ts index b51bb3d25092e..209bc5ff576b6 100644 --- a/x-pack/plugins/security/public/index.ts +++ b/x-pack/plugins/security/public/index.ts @@ -24,7 +24,6 @@ export type { UserProfileBulkGetParams, UserProfileGetCurrentParams, UserProfileSuggestParams, - UpdateUserProfileHook, } from './account_management'; export type { AuthenticationServiceStart, AuthenticationServiceSetup } from './authentication'; diff --git a/x-pack/plugins/security/public/mocks.ts b/x-pack/plugins/security/public/mocks.ts index f0081307ef33f..8a9232869b430 100644 --- a/x-pack/plugins/security/public/mocks.ts +++ b/x-pack/plugins/security/public/mocks.ts @@ -32,9 +32,6 @@ function createStartMock() { userProfile$: of({}), }, uiApi: getUiApiMock.createStart(), - hooks: { - useUpdateUserProfile: jest.fn(), - }, }; } diff --git a/x-pack/plugins/security/public/nav_control/nav_control_component.tsx b/x-pack/plugins/security/public/nav_control/nav_control_component.tsx index 4a5e8ad545d64..13bcb3bcb4341 100644 --- a/x-pack/plugins/security/public/nav_control/nav_control_component.tsx +++ b/x-pack/plugins/security/public/nav_control/nav_control_component.tsx @@ -22,9 +22,8 @@ import type { Observable } from 'rxjs'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { UserAvatar } from '@kbn/user-profile-components'; +import { UserAvatar, type UserProfileAvatarData } from '@kbn/user-profile-components'; -import type { UserProfileAvatarData } from '../../common'; import { getUserDisplayName, isUserAnonymous } from '../../common/model'; import { useCurrentUser, useUserProfile } from '../components'; diff --git a/x-pack/plugins/security/public/plugin.test.tsx b/x-pack/plugins/security/public/plugin.test.tsx index 87ce15a19202d..fdab78a1f91d0 100644 --- a/x-pack/plugins/security/public/plugin.test.tsx +++ b/x-pack/plugins/security/public/plugin.test.tsx @@ -96,9 +96,6 @@ describe('Security Plugin', () => { "areAPIKeysEnabled": [Function], "getCurrentUser": [Function], }, - "hooks": Object { - "useUpdateUserProfile": [Function], - }, "navControlService": Object { "addUserMenuLinks": [Function], "getUserMenuLinks$": [Function], diff --git a/x-pack/plugins/security/public/plugin.tsx b/x-pack/plugins/security/public/plugin.tsx index e8c2c13ab0eb6..49c0a14e2fd9c 100644 --- a/x-pack/plugins/security/public/plugin.tsx +++ b/x-pack/plugins/security/public/plugin.tsx @@ -24,9 +24,7 @@ import type { SpacesPluginStart } from '@kbn/spaces-plugin/public'; import type { SecurityLicense } from '../common/licensing'; import { SecurityLicenseService } from '../common/licensing'; -import type { UpdateUserProfileHook } from './account_management'; import { accountManagementApp, UserProfileAPIClient } from './account_management'; -import { getUseUpdateUserProfile } from './account_management/user_profile/use_update_user_profile'; import { AnalyticsService } from './analytics'; import { AnonymousAccessService } from './anonymous_access'; import type { AuthenticationServiceSetup, AuthenticationServiceStart } from './authentication'; @@ -213,12 +211,6 @@ export class SecurityPlugin ), userProfile$: this.securityApiClients.userProfiles.userProfile$, }, - hooks: { - useUpdateUserProfile: getUseUpdateUserProfile({ - apiClient: this.securityApiClients.userProfiles, - notifications: core.notifications, - }), - }, }; } @@ -263,13 +255,6 @@ export interface SecurityPluginStart { 'getCurrent' | 'bulkGet' | 'suggest' | 'update' | 'userProfile$' >; - /** - * A set of hooks to work with Kibana user profiles - */ - hooks: { - useUpdateUserProfile: UpdateUserProfileHook; - }; - /** * Exposes UI components that will be loaded asynchronously. * @deprecated diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 11f22770bec5f..f70caee66aec9 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -29231,10 +29231,7 @@ "xpack.security.accountManagement.userProfile.passwordLabel": "Mot de passe", "xpack.security.accountManagement.userProfile.prepopulatedImageUrlPromptText": "Sélectionner ou glisser-déposer une image de remplacement", "xpack.security.accountManagement.userProfile.randomizeButton": "Randomiser", - "xpack.security.accountManagement.userProfile.requiresPageReloadToastButtonLabel": "Actualiser la page", - "xpack.security.accountManagement.userProfile.requiresPageReloadToastDescription": "Un ou plusieurs paramètres nécessitent d’actualiser la page pour pouvoir prendre effet.", "xpack.security.accountManagement.userProfile.submitErrorTitle": "Impossible de mettre à jour le profil", - "xpack.security.accountManagement.userProfile.submitSuccessTitle": "Profil mis à jour", "xpack.security.accountManagement.userProfile.themeFormGroupDescription": "Sélectionnez l'apparence de votre interface.", "xpack.security.accountManagement.userProfile.title": "Profil", "xpack.security.accountManagement.userProfile.usernameHelpText": "Le nom de l'utilisateur ne peut pas être modifié après la création du compte.", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 15960dbd920ed..ca71e8c833cb5 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -29230,10 +29230,7 @@ "xpack.security.accountManagement.userProfile.passwordLabel": "パスワード", "xpack.security.accountManagement.userProfile.prepopulatedImageUrlPromptText": "置換画像を選択するかドラッグアンドドロップします", "xpack.security.accountManagement.userProfile.randomizeButton": "ランダム化", - "xpack.security.accountManagement.userProfile.requiresPageReloadToastButtonLabel": "ページを再読み込み", - "xpack.security.accountManagement.userProfile.requiresPageReloadToastDescription": "設定を有効にするためにページの再読み込みが必要です。", "xpack.security.accountManagement.userProfile.submitErrorTitle": "プロファイルを更新できませんでした", - "xpack.security.accountManagement.userProfile.submitSuccessTitle": "プロファイルが更新されました", "xpack.security.accountManagement.userProfile.themeFormGroupDescription": "インターフェースの表示を選択します。", "xpack.security.accountManagement.userProfile.title": "プロフィール", "xpack.security.accountManagement.userProfile.usernameHelpText": "アカウントの作成後は、ユーザー名を変更できません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 0cff43087c67f..ef71636689383 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -29226,10 +29226,7 @@ "xpack.security.accountManagement.userProfile.passwordLabel": "密码", "xpack.security.accountManagement.userProfile.prepopulatedImageUrlPromptText": "选择或拖放替换图像", "xpack.security.accountManagement.userProfile.randomizeButton": "随机化", - "xpack.security.accountManagement.userProfile.requiresPageReloadToastButtonLabel": "重新加载页面", - "xpack.security.accountManagement.userProfile.requiresPageReloadToastDescription": "一个或多个设置需要您重新加载页面才能生效。", "xpack.security.accountManagement.userProfile.submitErrorTitle": "无法更新配置文件", - "xpack.security.accountManagement.userProfile.submitSuccessTitle": "配置文件已更新", "xpack.security.accountManagement.userProfile.themeFormGroupDescription": "选择您界面的外观。", "xpack.security.accountManagement.userProfile.title": "配置文件", "xpack.security.accountManagement.userProfile.usernameHelpText": "创建帐户后无法更改用户名。", diff --git a/x-pack/test/cases_api_integration/common/lib/api/user_profiles.ts b/x-pack/test/cases_api_integration/common/lib/api/user_profiles.ts index 25c7f7a7a9ba4..bc78feab4070c 100644 --- a/x-pack/test/cases_api_integration/common/lib/api/user_profiles.ts +++ b/x-pack/test/cases_api_integration/common/lib/api/user_profiles.ts @@ -10,8 +10,11 @@ import { parse as parseCookie, Cookie } from 'tough-cookie'; import { INTERNAL_SUGGEST_USER_PROFILES_URL } from '@kbn/cases-plugin/common/constants'; import { UserProfileService } from '@kbn/cases-plugin/server/services'; -import { UserProfileAvatarData } from '@kbn/security-plugin/common'; -import { UserProfile, UserProfileWithAvatar } from '@kbn/user-profile-components'; +import type { + UserProfile, + UserProfileAvatarData, + UserProfileWithAvatar, +} from '@kbn/user-profile-components'; import { SuggestUserProfilesRequest } from '@kbn/cases-plugin/common/types/api'; import { superUser } from '../authentication/users'; import { User } from '../authentication/types'; From 9d6ebdda4e630f0973ab6ece2803a878cea09227 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Wed, 9 Aug 2023 18:21:37 +0200 Subject: [PATCH 18/41] [Synthetics] Fix 404 not found monitor view (#163501) --- .../synthetics/server/routes/monitor_cruds/get_monitor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts index 16d63c60c4e1b..770fb102c5369 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/get_monitor.ts @@ -59,7 +59,7 @@ export const getSyntheticsMonitorRoute: SyntheticsRestApiRouteFactory = () => ({ const encryptedSavedObjectsClient = encryptedSavedObjects.getClient(); - return getSyntheticsMonitor({ + return await getSyntheticsMonitor({ monitorId, encryptedSavedObjectsClient, savedObjectsClient, From b9fd22bd11c69b641e418c0a9832b195f665f4d0 Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Wed, 9 Aug 2023 18:36:07 +0200 Subject: [PATCH 19/41] [Lens] Top values hints for time series dimensions when counter/gauges fields are used (#162916) ## Summary Fixes #154832 This PR is a first attempt to provide a visual feedback to users while configuring a visualization that use a time series metric, showing a new category in the field picker that highlights time series dimensions by which the gauge/counter are mapped against. Current idea: * Works with XY and Heatmap visualizations only * Works only for Breakdown (XY) and Y axis (Heatmap) only * Top values on the horizontal axis for both visualizations won't show the new field category * The feature is enabled only when a metric using a time series metric field (like gauge or counter) is detected in the configuration, otherwise the category is hidden. * The feature is disabled for multi terms - it means that just the group is hidden, no impact on the actual field * Fields for this group are taken from both `Available` and `Empty` fields but the rendering styles for the empty case is retained. Screenshot 2023-08-01 at 17 52 38 Empty field but within the Time series dimension: Screenshot 2023-08-08 at 16 29 17 While the actual implementation of the ES aggs is not leveraging yet this information, this is still useful to indicate to the user which dimension the index/dataView mapping author thought it makes sense that metric. With #152537 also the aggregation request will benefit from this. ### Checklist Delete any items that are not applicable to this PR. - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios --------- Co-authored-by: Stratoula Kalafateli --- .../public/data_views_service/loader.test.ts | 59 +++++++++++ .../lens/public/data_views_service/loader.ts | 4 +- .../dimension_panel/field_input.test.tsx | 97 +++++++++++++++++-- .../dimension_panel/field_input.tsx | 7 ++ .../dimension_panel/field_select.tsx | 52 ++++++++-- .../dimension_panel/reference_editor.tsx | 1 + .../public/datasources/form_based/mocks.ts | 12 +++ .../definitions/terms/field_inputs.tsx | 3 + .../operations/definitions/terms/index.tsx | 7 ++ .../datasources/form_based/pure_utils.ts | 29 +++++- x-pack/plugins/lens/public/types.ts | 1 + .../heatmap/visualization.test.ts | 3 + .../visualizations/heatmap/visualization.tsx | 1 + .../visualizations/xy/visualization.tsx | 1 + .../test/functional/apps/lens/group4/tsdb.ts | 44 +++++++++ 15 files changed, 306 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/lens/public/data_views_service/loader.test.ts b/x-pack/plugins/lens/public/data_views_service/loader.test.ts index e7e2bab166a70..f91d236986b11 100644 --- a/x-pack/plugins/lens/public/data_views_service/loader.test.ts +++ b/x-pack/plugins/lens/public/data_views_service/loader.test.ts @@ -159,6 +159,65 @@ describe('loader', () => { expect(cache.foo.getFieldByName('timestamp')!.meta).toEqual(true); }); + it('should move over any time series meta data', async () => { + const cache = await loadIndexPatterns({ + cache: {}, + patterns: ['foo'], + dataViews: { + get: jest.fn(async () => ({ + id: 'foo', + title: 'Foo index', + metaFields: ['timestamp'], + isPersisted: () => true, + toSpec: () => ({}), + typeMeta: {}, + fields: [ + { + name: 'timestamp', + displayName: 'timestampLabel', + type: 'date', + aggregatable: true, + searchable: true, + }, + { + name: 'bytes_counter', + displayName: 'bytes_counter', + type: 'number', + aggregatable: true, + searchable: true, + timeSeriesMetric: 'counter', + }, + { + name: 'bytes_gauge', + displayName: 'bytes_gauge', + type: 'number', + aggregatable: true, + searchable: true, + timeSeriesMetric: 'gauge', + }, + { + name: 'dimension', + displayName: 'dimension', + type: 'string', + aggregatable: true, + searchable: true, + timeSeriesDimension: true, + }, + ], + })), + getIdsWithTitle: jest.fn(async () => ({ + id: 'foo', + title: 'Foo index', + })), + create: jest.fn(), + } as unknown as Pick, + }); + + expect(cache.foo.getFieldByName('bytes_counter')!.timeSeriesMetric).toEqual('counter'); + expect(cache.foo.getFieldByName('bytes_gauge')!.timeSeriesMetric).toEqual('gauge'); + expect(cache.foo.getFieldByName('dimension')!.timeSeriesDimension).toEqual(true); + }); + it('should call the refresh callback when loading new indexpatterns', async () => { const onIndexPatternRefresh = jest.fn(); await loadIndexPatterns({ diff --git a/x-pack/plugins/lens/public/data_views_service/loader.ts b/x-pack/plugins/lens/public/data_views_service/loader.ts index f38a84cc60b48..784c97d832e34 100644 --- a/x-pack/plugins/lens/public/data_views_service/loader.ts +++ b/x-pack/plugins/lens/public/data_views_service/loader.ts @@ -29,6 +29,7 @@ export function convertDataViewIntoLensIndexPattern( dataView: DataView, restrictionRemapper: (name: string) => string = onRestrictionMapping ): IndexPattern { + const metaKeys = new Set(dataView.metaFields); const newFields = dataView.fields .filter(isFieldLensCompatible) .map((field): IndexPatternField => { @@ -40,13 +41,14 @@ export function convertDataViewIntoLensIndexPattern( aggregatable: field.aggregatable, filterable: field.filterable, searchable: field.searchable, - meta: dataView.metaFields.includes(field.name), + meta: metaKeys.has(field.name), esTypes: field.esTypes, scripted: field.scripted, isMapped: field.isMapped, customLabel: field.customLabel, runtimeField: field.runtimeField, runtime: Boolean(field.runtimeField), + timeSeriesDimension: field.timeSeriesDimension, timeSeriesMetric: field.timeSeriesMetric, timeSeriesRollup: field.isRolledUpField, partiallyApplicableFunctions: field.isRolledUpField diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx index 1a22e34e0a3ec..d307e0eb094a2 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.test.tsx @@ -17,12 +17,15 @@ import { FieldBasedIndexPatternColumn, termsOperation, staticValueOperation, + minOperation, } from '../operations/definitions'; import { FieldInput, getErrorMessage } from './field_input'; -import { createMockedIndexPattern } from '../mocks'; +import { createMockedIndexPattern, createMockedIndexPatternWithAdditionalFields } from '../mocks'; import { getOperationSupportMatrix } from '.'; import { GenericIndexPatternColumn, FormBasedLayer, FormBasedPrivateState } from '../types'; import { ReferenceBasedIndexPatternColumn } from '../operations/definitions/column_types'; +import { FieldSelect } from './field_select'; +import { IndexPattern, VisualizationDimensionGroupConfig } from '../../../types'; jest.mock('../operations/layer_helpers', () => { const original = jest.requireActual('../operations/layer_helpers'); @@ -41,7 +44,7 @@ const defaultProps = { incompleteField: null, incompleteOperation: undefined, incompleteParams: {}, - dimensionGroups: [], + dimensionGroups: [] as VisualizationDimensionGroupConfig[], groupId: 'any', operationDefinitionMap: { terms: termsOperation, @@ -49,6 +52,7 @@ const defaultProps = { count: countOperation, differences: derivativeOperation, staticValue: staticValueOperation, + min: minOperation, } as unknown as Record, }; @@ -102,9 +106,12 @@ function getCountOperationColumn(): GenericIndexPatternColumn { operationType: 'count', }; } -function getLayer(col1: GenericIndexPatternColumn = getStringBasedOperationColumn()) { +function getLayer( + col1: GenericIndexPatternColumn = getStringBasedOperationColumn(), + indexPattern?: IndexPattern +) { return { - indexPatternId: '1', + indexPatternId: defaultProps.indexPattern.id, columnOrder: ['col1', 'col2'], columns: { col1, @@ -112,7 +119,11 @@ function getLayer(col1: GenericIndexPatternColumn = getStringBasedOperationColum }, }; } -function getDefaultOperationSupportMatrix(layer: FormBasedLayer, columnId: string) { +function getDefaultOperationSupportMatrix( + layer: FormBasedLayer, + columnId: string, + indexPattern?: IndexPattern +) { return getOperationSupportMatrix({ state: { layers: { layer1: layer }, @@ -121,7 +132,7 @@ function getDefaultOperationSupportMatrix(layer: FormBasedLayer, columnId: strin filterOperations: () => true, columnId, indexPatterns: { - [defaultProps.indexPattern.id]: defaultProps.indexPattern, + [defaultProps.indexPattern.id]: indexPattern ?? defaultProps.indexPattern, }, }); } @@ -421,6 +432,80 @@ describe('FieldInput', () => { expect(onDeleteColumn).toHaveBeenCalled(); expect(updateLayerSpy).not.toHaveBeenCalled(); }); + + describe('time series group', () => { + function getLayerWithTSDBMetric() { + const layer = getLayer(); + layer.columns.col2 = { + label: 'Min of TSDB counter', + dataType: 'number', + isBucketed: false, + sourceField: 'bytes_counter', + operationType: 'min', + }; + return layer; + } + it('should not render the time dimension category if it has tsdb metric column but the group is not a breakdown', () => { + const updateLayerSpy = jest.fn(); + const layer = getLayerWithTSDBMetric(); + const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1'); + const instance = mount( + + ); + + expect(instance.find(FieldSelect).prop('showTimeSeriesDimensions')).toBeFalsy(); + }); + + it('should render the time dimension category if it has tsdb metric column and the group is a breakdown one', () => { + const updateLayerSpy = jest.fn(); + const layer = getLayerWithTSDBMetric(); + const operationSupportMatrix = getDefaultOperationSupportMatrix(layer, 'col1'); + const instance = mount( + + ); + + expect(instance.find(FieldSelect).prop('showTimeSeriesDimensions')).toBeTruthy(); + }); + }); }); describe('getErrorMessage', () => { diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.tsx index 462cd0b546f22..5120c89c37b30 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_input.tsx @@ -16,6 +16,7 @@ import type { GenericIndexPatternColumn, } from '../operations/definitions'; import type { FieldBasedIndexPatternColumn } from '../operations/definitions/column_types'; +import { shouldShowTimeSeriesOption } from '../pure_utils'; export function FieldInput({ layer, @@ -83,6 +84,12 @@ export function FieldInput({ }) ); }} + showTimeSeriesDimensions={shouldShowTimeSeriesOption( + layer, + indexPattern, + groupId, + dimensionGroups + )} /> ); diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_select.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_select.tsx index cbfafbfbfd2c9..909bc64781399 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_select.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/field_select.tsx @@ -33,6 +33,7 @@ export interface FieldSelectProps extends EuiComboBoxProps { @@ -66,7 +68,15 @@ export function FieldSelect({ return fieldContainsData(fieldName, currentIndexPattern, hasFieldData); } - function fieldNamesToOptions(items: string[]) { + interface FieldOption { + label: string; + value: { type: 'field'; field: string; dataType: string | undefined; operationType: string }; + exists: boolean; + compatible: number; + 'data-test-subj': string; + } + + function fieldNamesToOptions(items: string[]): FieldOption[] { return items .filter((field) => currentIndexPattern.getFieldByName(field)?.displayName) .map((field) => { @@ -75,9 +85,9 @@ export function FieldSelect({ const exists = containsData(field); const fieldInstance = currentIndexPattern.getFieldByName(field); return { - label: currentIndexPattern.getFieldByName(field)?.displayName, + label: currentIndexPattern.getFieldByName(field)?.displayName ?? field, value: { - type: 'field', + type: 'field' as const, field, dataType: fieldInstance ? getFieldType(fieldInstance) : undefined, // Use the operation directly, or choose the first compatible operation. @@ -102,21 +112,47 @@ export function FieldSelect({ ); const [availableFields, emptyFields] = partition(nonMetaFields, containsData); - const constructFieldsOptions = (fieldsArr: string[], label: string) => + const constructFieldsOptions = ( + fieldsArr: string[], + label: string + ): { label: string; options: FieldOption[] } | false => fieldsArr.length > 0 && { label, options: fieldNamesToOptions(fieldsArr), }; - const availableFieldsOptions = constructFieldsOptions( + const isTimeSeriesFields = (field: string) => { + return ( + showTimeSeriesDimensions && currentIndexPattern.getFieldByName(field)?.timeSeriesDimension + ); + }; + + const [availableTimeSeriesFields, availableNonTimeseriesFields] = partition( availableFields, + isTimeSeriesFields + ); + const [emptyTimeSeriesFields, emptyNonTimeseriesFields] = partition( + emptyFields, + isTimeSeriesFields + ); + + const timeSeriesFieldsOptions = constructFieldsOptions( + // This group includes both available and empty fields + availableTimeSeriesFields.concat(emptyTimeSeriesFields), + i18n.translate('xpack.lens.indexPattern.timeSeriesFieldsLabel', { + defaultMessage: 'Time series dimensions', + }) + ); + + const availableFieldsOptions = constructFieldsOptions( + availableNonTimeseriesFields, i18n.translate('xpack.lens.indexPattern.availableFieldsLabel', { defaultMessage: 'Available fields', }) ); const emptyFieldsOptions = constructFieldsOptions( - emptyFields, + emptyNonTimeseriesFields, i18n.translate('xpack.lens.indexPattern.emptyFieldsLabel', { defaultMessage: 'Empty fields', }) @@ -131,17 +167,19 @@ export function FieldSelect({ return [ ...fieldNamesToOptions(specialFields), + timeSeriesFieldsOptions, availableFieldsOptions, emptyFieldsOptions, metaFieldsOptions, ].filter(Boolean); }, [ + operationByField, incompleteOperation, selectedOperationType, currentIndexPattern, - operationByField, hasFieldData, markAllFieldsCompatible, + showTimeSeriesDimensions, ]); return ( diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx index 28810825dd7a0..66a01daae0581 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/reference_editor.tsx @@ -317,6 +317,7 @@ export const ReferenceEditor = (props: ReferenceEditorProps) => { markAllFieldsCompatible={selectionStyle === 'field'} onDeleteColumn={onDeleteColumn} onChoose={onChooseField} + showTimeSeriesDimensions={false} /> ) : null} diff --git a/x-pack/plugins/lens/public/datasources/form_based/mocks.ts b/x-pack/plugins/lens/public/datasources/form_based/mocks.ts index c01495f1993e4..fcefa97ecd4b1 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/mocks.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/mocks.ts @@ -216,3 +216,15 @@ export const createMockedIndexPatternWithoutType = ( getFieldByName: getFieldByNameFactory(filteredFields), }; }; + +export const createMockedIndexPatternWithAdditionalFields = ( + newFields: IndexPatternField[] +): IndexPattern => { + const { fields, ...otherIndexPatternProps } = createMockedIndexPattern(); + const completeFields = fields.concat(newFields); + return { + ...otherIndexPatternProps, + fields: completeFields, + getFieldByName: getFieldByNameFactory(completeFields), + }; +}; diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/field_inputs.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/field_inputs.tsx index 72941739b24ed..428747b6cda75 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/field_inputs.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/field_inputs.tsx @@ -30,6 +30,7 @@ export interface FieldInputsProps { invalidFields?: string[]; operationSupportMatrix: Pick; onChange: (newValues: string[]) => void; + showTimeSeriesDimensions: boolean; } interface WrappedValue { @@ -50,6 +51,7 @@ export function FieldInputs({ indexPattern, operationSupportMatrix, invalidFields, + showTimeSeriesDimensions, }: FieldInputsProps) { const onChangeWrapped = useCallback( (values: WrappedValue[]) => @@ -165,6 +167,7 @@ export function FieldInputs({ data-test-subj={ localValues.length !== 1 ? `indexPattern-dimension-field-${index}` : undefined } + showTimeSeriesDimensions={localValues.length < 2 && showTimeSeriesDimensions} /> ); diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/index.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/index.tsx index 504abd15955e0..4aafe38ea39ee 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/index.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/index.tsx @@ -53,6 +53,7 @@ import { supportedTypes, } from './constants'; import { IncludeExcludeRow } from './include_exclude_options'; +import { shouldShowTimeSeriesOption } from '../../../pure_utils'; export function supportsRarityRanking(field?: IndexPatternField) { // these es field types can't be sorted by rarity @@ -591,6 +592,12 @@ export const termsOperation: OperationDefinition< operationSupportMatrix={operationSupportMatrix} onChange={onFieldSelectChange} invalidFields={invalidFields} + showTimeSeriesDimensions={shouldShowTimeSeriesOption( + layer, + indexPattern, + groupId, + dimensionGroups + )} /> ); diff --git a/x-pack/plugins/lens/public/datasources/form_based/pure_utils.ts b/x-pack/plugins/lens/public/datasources/form_based/pure_utils.ts index b13fd50a45e73..256c1de51f832 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/pure_utils.ts +++ b/x-pack/plugins/lens/public/datasources/form_based/pure_utils.ts @@ -5,7 +5,12 @@ * 2.0. */ -import type { DataType, IndexPattern, IndexPatternField } from '../../types'; +import type { + DataType, + IndexPattern, + IndexPatternField, + VisualizationDimensionGroupConfig, +} from '../../types'; import type { FormBasedLayer } from './types'; import type { BaseIndexPatternColumn, @@ -26,6 +31,28 @@ export function hasField(column: BaseIndexPatternColumn): column is FieldBasedIn return 'sourceField' in column; } +export function shouldShowTimeSeriesOption( + layer: FormBasedLayer, + indexPattern: IndexPattern, + groupId: string, + dimensionGroups: VisualizationDimensionGroupConfig[] +) { + return Boolean( + dimensionGroups.find(({ groupId: id }) => groupId === id)?.isBreakdownDimension && + containsColumnWithTimeSeriesMetric(layer, indexPattern) + ); +} + +function containsColumnWithTimeSeriesMetric( + layer: FormBasedLayer, + indexPattern: IndexPattern +): boolean { + return Object.values(layer.columns).some( + (column) => + hasField(column) && indexPattern.getFieldByName(column.sourceField)?.timeSeriesMetric + ); +} + export function getFieldType(field: IndexPatternField) { if (field.timeSeriesMetric) { return field.timeSeriesMetric; diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index 8b69929b4fb84..13651c3bc5e69 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -814,6 +814,7 @@ export type VisualizationDimensionGroupConfig = SharedDimensionProps & { supportStaticValue?: boolean; // used by text based datasource to restrict the field selection only to number fields for the metric dimensions isMetricDimension?: boolean; + isBreakdownDimension?: boolean; paramEditorCustomProps?: ParamEditorCustomProps; enableFormatSelector?: boolean; labels?: { buttonAriaLabel: string; buttonLabel: string }; diff --git a/x-pack/plugins/lens/public/visualizations/heatmap/visualization.test.ts b/x-pack/plugins/lens/public/visualizations/heatmap/visualization.test.ts index 596c334aeac9e..dc9202a4d7e92 100644 --- a/x-pack/plugins/lens/public/visualizations/heatmap/visualization.test.ts +++ b/x-pack/plugins/lens/public/visualizations/heatmap/visualization.test.ts @@ -150,6 +150,7 @@ describe('heatmap', () => { groupLabel: 'Vertical axis', accessors: [{ columnId: 'y-accessor' }], filterOperations: filterOperationsAxis, + isBreakdownDimension: true, supportsMoreColumns: false, requiredMinDimensionCount: 0, dataTestSubj: 'lnsHeatmap_yDimensionPanel', @@ -210,6 +211,7 @@ describe('heatmap', () => { accessors: [], filterOperations: filterOperationsAxis, supportsMoreColumns: true, + isBreakdownDimension: true, requiredMinDimensionCount: 0, dataTestSubj: 'lnsHeatmap_yDimensionPanel', }, @@ -267,6 +269,7 @@ describe('heatmap', () => { accessors: [{ columnId: 'y-accessor' }], filterOperations: filterOperationsAxis, supportsMoreColumns: false, + isBreakdownDimension: true, requiredMinDimensionCount: 0, dataTestSubj: 'lnsHeatmap_yDimensionPanel', }, diff --git a/x-pack/plugins/lens/public/visualizations/heatmap/visualization.tsx b/x-pack/plugins/lens/public/visualizations/heatmap/visualization.tsx index 654d69284718c..5d19c402a27e2 100644 --- a/x-pack/plugins/lens/public/visualizations/heatmap/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/heatmap/visualization.tsx @@ -197,6 +197,7 @@ export const getHeatmapVisualization = ({ filterOperations: filterOperationsAxis, supportsMoreColumns: !state.yAccessor, requiredMinDimensionCount: 0, + isBreakdownDimension: true, dataTestSubj: 'lnsHeatmap_yDimensionPanel', }, { diff --git a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx index 0d000db6e5206..9f5f9755d1781 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/visualization.tsx @@ -461,6 +461,7 @@ export const getXyVisualization = ({ requiredMinDimensionCount: dataLayer.seriesType.includes('percentage') && hasOnlyOneAccessor ? 1 : 0, enableDimensionEditor: true, + isBreakdownDimension: true, }, ], }; diff --git a/x-pack/test/functional/apps/lens/group4/tsdb.ts b/x-pack/test/functional/apps/lens/group4/tsdb.ts index 7f6045b6f7cf4..3200c7a073dc4 100644 --- a/x-pack/test/functional/apps/lens/group4/tsdb.ts +++ b/x-pack/test/functional/apps/lens/group4/tsdb.ts @@ -248,6 +248,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const elasticChart = getService('elasticChart'); const indexPatterns = getService('indexPatterns'); const esArchiver = getService('esArchiver'); + const comboBox = getService('comboBox'); const createDocs = async ( esIndex: string, @@ -545,6 +546,49 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); } } + + describe('show time series dimension groups within breakdown', () => { + it('should show the time series dimension group on field picker when configuring a breakdown', async () => { + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'date_histogram', + field: '@timestamp', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'min', + field: 'bytes_counter', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_splitDimensionPanel > lns-empty-dimension', + operation: 'terms', + keepOpen: true, + }); + + const list = await comboBox.getOptionsList('indexPattern-dimension-field'); + expect(list).to.contain('Time series dimensions'); + await PageObjects.lens.closeDimensionEditor(); + }); + + it("should not show the time series dimension group on field picker if it's not a breakdown", async () => { + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'min', + field: 'bytes_counter', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'date_histogram', + keepOpen: true, + }); + const list = await comboBox.getOptionsList('indexPattern-dimension-field'); + expect(list).to.not.contain('Time series dimensions'); + await PageObjects.lens.closeDimensionEditor(); + }); + }); }); describe('Scenarios with changing stream type', () => { From a371022b8f4e2ffa6fc5f7ed3f92e50a4664d1f9 Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Wed, 9 Aug 2023 18:36:24 +0200 Subject: [PATCH 20/41] [EsAggs] Fix other request merge behaviour when empty string key is retrieved (#163187) ## Summary Fixes #163040 This PR generialize the fix in #150321 to handle also the empty string at parent level when the `Other` response is merged. Added few unit tests to cover some more scenarios. Added some functional tests for top and nested `empty` + `Other` scenarios at higher level (XY + table) The fix affects both Visualize and Lens: Screenshot 2023-08-04 at 18 21 32 Screenshot 2023-08-04 at 18 21 18 Screenshot 2023-08-04 at 18 21 04 Screenshot 2023-08-04 at 18 20 57 Screenshot 2023-08-04 at 18 20 48 Screenshot 2023-08-04 at 18 20 36 Screenshot 2023-08-04 at 18 20 15 Screenshot 2023-08-04 at 18 20 01 Screenshot 2023-08-04 at 18 19 49 Screenshot 2023-08-04 at 18 19 36 Screenshot 2023-08-04 at 18 19 22 Screenshot 2023-08-04 at 18 26 35 ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Stratoula Kalafateli --- .../_terms_other_bucket_helper.test.ts | 577 ++++++++++++------ .../buckets/_terms_other_bucket_helper.ts | 48 +- .../definitions/terms/values_input.tsx | 1 + .../test/functional/apps/lens/group3/terms.ts | 155 ++++- .../test/functional/page_objects/lens_page.ts | 14 + 5 files changed, 569 insertions(+), 226 deletions(-) diff --git a/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts b/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts index e39c858f3e903..981ff3664fbec 100644 --- a/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts +++ b/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.test.ts @@ -10,7 +10,7 @@ import { buildOtherBucketAgg, mergeOtherBucketAggResponse, updateMissingBucket, - OTHER_BUCKET_SEPARATOR as SEP, + OTHER_NESTED_BUCKET_SEPARATOR as SEP, constructSingleTermOtherFilter, } from './_terms_other_bucket_helper'; import type { DataViewField, DataView } from '@kbn/data-views-plugin/common'; @@ -97,188 +97,121 @@ const nestedTerm = { ], }; -const singleTermResponse = { - took: 10, - timed_out: false, - _shards: { - total: 1, - successful: 1, - skipped: 0, - failed: 0, +function wrapResponse(aggregationResponse: Record) { + return { + took: 3, + timed_out: false, + _shards: { total: 1, successful: 1, skipped: 0, failed: 0 }, + hits: { total: 14005, max_score: 0, hits: [] }, + aggregations: aggregationResponse, + status: 200, + }; +} + +const singleTermResponse = wrapResponse({ + '1': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 8325, + buckets: [ + { key: 'ios', doc_count: 2850 }, + { key: 'win xp', doc_count: 2830 }, + { key: '__missing__', doc_count: 1430 }, + ], }, - hits: { - total: 14005, - max_score: 0, - hits: [], - }, - aggregations: { - '1': { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 8325, - buckets: [ - { key: 'ios', doc_count: 2850 }, - { key: 'win xp', doc_count: 2830 }, - { key: '__missing__', doc_count: 1430 }, - ], - }, - }, - status: 200, -}; +}); -const nestedTermResponse = { - took: 10, - timed_out: false, - _shards: { - total: 1, - successful: 1, - skipped: 0, - failed: 0, - }, - hits: { - total: 14005, - max_score: 0, - hits: [], - }, - aggregations: { - '1': { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 8325, - buckets: [ - { - '2': { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 8325, - buckets: [ - { key: 'ios', doc_count: 2850 }, - { key: 'win xp', doc_count: 2830 }, - { key: '__missing__', doc_count: 1430 }, - ], - }, - key: 'US-with-dash', - doc_count: 2850, +const nestedTermResponse = wrapResponse({ + '1': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 8325, + buckets: [ + { + '2': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 8325, + buckets: [ + { key: 'ios', doc_count: 2850 }, + { key: 'win xp', doc_count: 2830 }, + { key: '__missing__', doc_count: 1430 }, + ], }, - { - '2': { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 8325, - buckets: [ - { key: 'ios', doc_count: 1850 }, - { key: 'win xp', doc_count: 1830 }, - { key: '__missing__', doc_count: 130 }, - ], - }, - key: 'IN-with-dash', - doc_count: 2830, + key: 'US-with-dash', + doc_count: 2850, + }, + { + '2': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 8325, + buckets: [ + { key: 'ios', doc_count: 1850 }, + { key: 'win xp', doc_count: 1830 }, + { key: '__missing__', doc_count: 130 }, + ], }, - ], - }, + key: 'IN-with-dash', + doc_count: 2830, + }, + ], }, - status: 200, -}; +}); -const exhaustiveNestedTermResponse = { - took: 10, - timed_out: false, - _shards: { - total: 1, - successful: 1, - skipped: 0, - failed: 0, - }, - hits: { - total: 14005, - max_score: 0, - hits: [], - }, - aggregations: { - '1': { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 8325, - buckets: [ - { - '2': { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 0, - buckets: [ - { key: 'ios', doc_count: 2850 }, - { key: 'win xp', doc_count: 2830 }, - { key: '__missing__', doc_count: 1430 }, - ], - }, - key: 'US-with-dash', - doc_count: 2850, +const exhaustiveNestedTermResponse = wrapResponse({ + '1': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 8325, + buckets: [ + { + '2': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'ios', doc_count: 2850 }, + { key: 'win xp', doc_count: 2830 }, + { key: '__missing__', doc_count: 1430 }, + ], }, - { - '2': { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 0, - buckets: [ - { key: 'ios', doc_count: 1850 }, - { key: 'win xp', doc_count: 1830 }, - { key: '__missing__', doc_count: 130 }, - ], - }, - key: 'IN-with-dash', - doc_count: 2830, + key: 'US-with-dash', + doc_count: 2850, + }, + { + '2': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [ + { key: 'ios', doc_count: 1850 }, + { key: 'win xp', doc_count: 1830 }, + { key: '__missing__', doc_count: 130 }, + ], }, - ], - }, + key: 'IN-with-dash', + doc_count: 2830, + }, + ], }, - status: 200, -}; +}); -const nestedTermResponseNoResults = { - took: 10, - timed_out: false, - _shards: { - total: 1, - successful: 1, - skipped: 0, - failed: 0, - }, - hits: { - total: 0, - max_score: null, - hits: [], - }, - aggregations: { - '1': { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 0, - buckets: [], - }, +const nestedTermResponseNoResults = wrapResponse({ + '1': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 0, + buckets: [], }, - status: 200, -}; +}); -const singleOtherResponse = { - took: 3, - timed_out: false, - _shards: { total: 1, successful: 1, skipped: 0, failed: 0 }, - hits: { total: 14005, max_score: 0, hits: [] }, - aggregations: { - 'other-filter': { - buckets: { '': { doc_count: 2805 } }, - }, +const singleOtherResponse = wrapResponse({ + 'other-filter': { + buckets: { '': { doc_count: 2805 } }, }, - status: 200, -}; +}); -const nestedOtherResponse = { - took: 3, - timed_out: false, - _shards: { total: 1, successful: 1, skipped: 0, failed: 0 }, - hits: { total: 14005, max_score: 0, hits: [] }, - aggregations: { - 'other-filter': { - buckets: { - [`${SEP}US-with-dash`]: { doc_count: 2805 }, - [`${SEP}IN-with-dash`]: { doc_count: 2804 }, - }, +const nestedOtherResponse = wrapResponse({ + 'other-filter': { + buckets: { + [`${SEP}US-with-dash`]: { doc_count: 2805 }, + [`${SEP}IN-with-dash`]: { doc_count: 2804 }, }, }, - status: 200, -}; +}); describe('Terms Agg Other bucket helper', () => { const typesRegistry = mockAggTypesRegistry(); @@ -326,28 +259,12 @@ describe('Terms Agg Other bucket helper', () => { }); test('returns a function for undefined agg buckets', () => { - const response = { - took: 10, - timed_out: false, - _shards: { - total: 1, - successful: 1, - skipped: 0, - failed: 0, - }, - hits: { - total: 14005, - max_score: 0, - hits: [], - }, - aggregations: { - 2: { - doc_count_error_upper_bound: 0, - sum_other_doc_count: 8325, - }, + const response = wrapResponse({ + 2: { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 8325, }, - status: 200, - }; + }); const aggConfigs = getAggConfigs(nestedTerm.aggs); const agg = buildOtherBucketAgg( aggConfigs, @@ -706,22 +623,15 @@ describe('Terms Agg Other bucket helper', () => { }, }; - const otherResponse = { - took: 3, - timed_out: false, - _shards: { total: 1, successful: 1, skipped: 0, failed: 0 }, - hits: { total: 14005, max_score: 0, hits: [] }, - aggregations: { - 'other-filter': { - buckets: { - [`${SEP}US-with-dash`]: { doc_count: 2805 }, - [`${SEP}IN-with-dash`]: { doc_count: 2804 }, - [`${SEP}`]: { doc_count: 2804 }, - }, + const otherResponse = wrapResponse({ + 'other-filter': { + buckets: { + [`${SEP}US-with-dash`]: { doc_count: 2805 }, + [`${SEP}IN-with-dash`]: { doc_count: 2804 }, + [`${SEP}`]: { doc_count: 2804 }, }, }, - status: 200, - }; + }); const aggConfigs = getAggConfigs(nestedTerm.aggs); const otherAggConfig = buildOtherBucketAgg( aggConfigs, @@ -745,6 +655,269 @@ describe('Terms Agg Other bucket helper', () => { expect((topAgg['1'] as any).buckets[2]['2'].buckets[3].key).toEqual('__other__'); } }); + + test('correctly merges other bucket when the term response contains an empty string', () => { + const response = wrapResponse({ + '0': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 82, + buckets: [ + { + key: '', + doc_count: 657, + }, + { + key: 'ios', + doc_count: 300, + }, + { + key: 'win xp', + doc_count: 284, + }, + { + doc_count: 82, + filters: [ + { + meta: { + type: 'phrases', + key: 'machine.os.raw', + params: ['ios', 'win xp', ''], + negate: true, + }, + query: { + bool: { + should: [ + { + match_phrase: { + 'machine.os.raw': '', + }, + }, + { + match_phrase: { + 'machine.os.raw': 'ios', + }, + }, + { + match_phrase: { + 'machine.os.raw': 'win xp', + }, + }, + ], + minimum_should_match: 1, + }, + }, + }, + ], + key: '__other__', + }, + ], + }, + }); + + const otherResponse = wrapResponse({ + 'other-filter': { + buckets: { + '': { + doc_count: 82, + filters: [ + { + meta: { + type: 'phrases', + key: 'machine.os.raw', + params: ['ios', 'win xp', ''], + negate: true, + }, + query: { + bool: { + should: [ + { + match_phrase: { + 'machine.os.raw': 'ios', + }, + }, + { + match_phrase: { + 'machine.os.raw': 'win xp', + }, + }, + { + match_phrase: { + 'machine.os.raw': '', + }, + }, + ], + minimum_should_match: 1, + }, + }, + }, + ], + key: '__other__', + }, + }, + }, + }); + const aggConfigs = getAggConfigs(singleTerm.aggs); + const otherAggConfig = buildOtherBucketAgg( + aggConfigs, + aggConfigs.aggs[0] as IBucketAggConfig, + enrichResponseWithSampling(response) + ); + + expect(otherAggConfig).toBeDefined(); + if (otherAggConfig) { + const mergedResponse = mergeOtherBucketAggResponse( + aggConfigs, + enrichResponseWithSampling(response), + enrichResponseWithSampling(otherResponse), + aggConfigs.aggs[0] as IBucketAggConfig, + otherAggConfig(), + constructSingleTermOtherFilter + ); + + const topAgg = getTopAggregations(mergedResponse); + const topBuckets = (topAgg['1'] as any).buckets; + expect(topBuckets[2].key).toEqual(''); + expect(topBuckets[2]['2'].buckets[3].key).toEqual('__other__'); + } + }); + + test('correctly merges other bucket with both top and nested terms agg have empty string', () => { + const response = wrapResponse({ + ...nestedTermResponse.aggregations, + '1': { + ...nestedTermResponse.aggregations['1'], + buckets: [ + ...nestedTermResponse.aggregations['1'].buckets, + { + '2': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 8325, + buckets: [ + { key: 'ios', doc_count: 1850 }, + { key: 'win xp', doc_count: 1830 }, + { key: '__missing__', doc_count: 130 }, + { key: '', doc_count: 130 }, + ], + }, + key: '', + doc_count: 2830, + }, + ], + }, + }); + + const otherRootResponse = wrapResponse({ + 'other-filter': { + buckets: { + '': { + '2': { + doc_count_error_upper_bound: 0, + sum_other_doc_count: 59, + buckets: [ + { + key: 'US-with-dash', + doc_count: 13, + }, + { + key: 'IN-with-dash', + doc_count: 12, + }, + { + key: '', + doc_count: 12, + }, + ], + }, + doc_count: 84, + key: '__other__', + filters: [ + { + meta: { + type: 'phrases', + key: 'machine.os.raw', + params: ['', 'ios', 'win xp'], + negate: true, + }, + query: { + bool: { + should: [ + { + match_phrase: { + 'machine.os.raw': '', + }, + }, + { + match_phrase: { + 'machine.os.raw': 'ios', + }, + }, + { + match_phrase: { + 'machine.os.raw': 'win xp', + }, + }, + ], + minimum_should_match: 1, + }, + }, + }, + ], + }, + }, + }, + }); + + const otherResponse = wrapResponse({ + 'other-filter': { + buckets: { + [`${SEP}US-with-dash`]: { doc_count: 2805 }, + [`${SEP}IN-with-dash`]: { doc_count: 2804 }, + [`${SEP}`]: { doc_count: 2804 }, + [`${SEP}__other__`]: { doc_count: 3000 }, + }, + }, + }); + const aggConfigs = getAggConfigs(nestedTerm.aggs); + const otherRootAggConfig = buildOtherBucketAgg( + aggConfigs, + aggConfigs.aggs[0] as IBucketAggConfig, + enrichResponseWithSampling(response) + ); + + if (otherRootAggConfig) { + const mergedTopResponse = mergeOtherBucketAggResponse( + aggConfigs, + enrichResponseWithSampling(response), + enrichResponseWithSampling(otherRootResponse), + aggConfigs.aggs[0] as IBucketAggConfig, + otherRootAggConfig(), + constructSingleTermOtherFilter + ); + + const otherAggConfig = buildOtherBucketAgg( + aggConfigs, + aggConfigs.aggs[1] as IBucketAggConfig, + enrichResponseWithSampling(mergedTopResponse) + ); + if (otherAggConfig) { + const mergedResponse = mergeOtherBucketAggResponse( + aggConfigs, + enrichResponseWithSampling(mergedTopResponse), + enrichResponseWithSampling(otherResponse), + aggConfigs.aggs[1] as IBucketAggConfig, + otherAggConfig(), + constructSingleTermOtherFilter + ); + + const topAgg = getTopAggregations(mergedResponse); + expect((topAgg['1'] as any).buckets[2].key).toEqual(''); + expect((topAgg['1'] as any).buckets[2]['2'].buckets[4].key).toEqual('__other__'); + + expect((topAgg['1'] as any).buckets[3].key).toEqual('__other__'); + expect((topAgg['1'] as any).buckets[3]['2'].buckets[3].key).toEqual('__other__'); + } + } + }); }); describe(`updateMissingBucket${getTitlePostfix()}`, () => { diff --git a/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.ts b/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.ts index d4542d1513f16..9737883733266 100644 --- a/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.ts +++ b/src/plugins/data/common/search/aggs/buckets/_terms_other_bucket_helper.ts @@ -22,7 +22,9 @@ import { IAggType } from '../agg_type'; import { IAggConfig } from '../agg_config'; import { createSamplerAgg } from '../utils/sampler'; -export const OTHER_BUCKET_SEPARATOR = '╰┄►'; +const MISSING_KEY_STRING = '__missing__'; +export const OTHER_NESTED_BUCKET_SEPARATOR = '╰┄►'; +const otherBucketRegexp = new RegExp(`^${OTHER_NESTED_BUCKET_SEPARATOR}`); /** * walks the aggregation DSL and returns DSL starting at aggregation with id of startFromAggId @@ -56,10 +58,11 @@ const getAggResultBuckets = ( aggWithOtherBucket: IAggConfig, key: string ) => { - const keyParts = key.split(OTHER_BUCKET_SEPARATOR); + const keyParts = key.split(OTHER_NESTED_BUCKET_SEPARATOR); let responseAgg = response; for (const i in keyParts) { - if (keyParts[i] || keyParts[i] === '') { + // enable also the empty string + if (keyParts[i] != null) { const responseAggs: Array> = values(responseAgg); // If you have multi aggs, we cannot just assume the first one is the `other` bucket, // so we need to loop over each agg until we find it. @@ -75,8 +78,13 @@ const getAggResultBuckets = ( return bucketKey === keyParts[i]; }); if (aggResultBucket) { - responseAgg = aggResultBucket; - break; + // this is a special check in order to avoid an overwrite when + // there's an empty string term at root level for the data request + // as the other request will default to empty string category as well + if (!responseAgg?.[aggWithOtherBucket.id] || keyParts[i] !== '') { + responseAgg = aggResultBucket; + break; + } } } } @@ -94,19 +102,20 @@ const getAggResultBuckets = ( * @param aggId: id of the aggregation with missing bucket */ const getAggConfigResultMissingBuckets = (responseAggs: any, aggId: string) => { - const missingKey = '__missing__'; - let resultBuckets: Array> = []; + const resultBuckets: Array> = []; if (responseAggs[aggId]) { const matchingBucket = responseAggs[aggId].buckets.find( - (bucket: Record) => bucket.key === missingKey + (bucket: Record) => bucket.key === MISSING_KEY_STRING ); - if (matchingBucket) resultBuckets.push(matchingBucket); + if (matchingBucket) { + resultBuckets.push(matchingBucket); + } return resultBuckets; } each(responseAggs, (agg) => { if (agg.buckets) { each(agg.buckets, (bucket) => { - resultBuckets = [...resultBuckets, ...getAggConfigResultMissingBuckets(bucket, aggId)]; + resultBuckets.push(...getAggConfigResultMissingBuckets(bucket, aggId)); }); } }); @@ -124,7 +133,7 @@ const getOtherAggTerms = (requestAgg: Record, key: string, otherAgg return requestAgg['other-filter'].filters.filters[key].bool.must_not .filter( (filter: Record) => - filter.match_phrase && filter.match_phrase[otherAgg.params.field.name] + filter.match_phrase && filter.match_phrase[otherAgg.params.field.name] != null // mind empty strings! ) .map((filter: Record) => filter.match_phrase[otherAgg.params.field.name]); }; @@ -220,7 +229,7 @@ export const buildOtherBucketAgg = ( bucket, newAgg.id, newFilters, - `${key}${OTHER_BUCKET_SEPARATOR}${bucketKey.toString()}` + `${key}${OTHER_NESTED_BUCKET_SEPARATOR}${bucketKey.toString()}` ); }); return; @@ -229,7 +238,7 @@ export const buildOtherBucketAgg = ( const hasScriptedField = !!aggWithOtherBucket.params.field?.scripted; const hasMissingBucket = !!aggWithOtherBucket.params.missingBucket; const hasMissingBucketKey = agg.buckets.some( - (bucket: { key: string }) => bucket.key === '__missing__' + (bucket: { key: string }) => bucket.key === MISSING_KEY_STRING ); if ( aggWithOtherBucket.params.field && @@ -246,7 +255,7 @@ export const buildOtherBucketAgg = ( // create not filters for all the buckets each(agg.buckets, (bucket) => { - if (bucket.key === '__missing__') return; + if (bucket.key === MISSING_KEY_STRING) return; const filter = currentAgg.createFilter(currentAgg.getKey(bucket, bucket.key)); filter.meta.negate = true; filters.push(filter); @@ -302,7 +311,7 @@ export const mergeOtherBucketAggResponse = ( 'buckets' in aggregationsRoot!['other-filter'] ? aggregationsRoot!['other-filter'].buckets : {}; each(buckets, (bucket, key) => { if (!bucket.doc_count || key === undefined) return; - const bucketKey = key.replace(new RegExp(`^${OTHER_BUCKET_SEPARATOR}`), ''); + const bucketKey = key.replace(otherBucketRegexp, ''); const aggResultBuckets = getAggResultBuckets( aggsConfig, updatedAggregationsRoot, @@ -319,7 +328,7 @@ export const mergeOtherBucketAggResponse = ( if ( aggResultBuckets.some( - (aggResultBucket: Record) => aggResultBucket.key === '__missing__' + (aggResultBucket: Record) => aggResultBucket.key === MISSING_KEY_STRING ) ) { bucket.filters.push( @@ -330,7 +339,6 @@ export const mergeOtherBucketAggResponse = ( }); return updatedResponse; }; - export const updateMissingBucket = ( response: estypes.SearchResponse, aggConfigs: IAggConfigs, @@ -342,7 +350,7 @@ export const updateMissingBucket = ( agg.id ); aggResultBuckets.forEach((bucket) => { - bucket.key = '__missing__'; + bucket.key = MISSING_KEY_STRING; }); return updatedResponse; }; @@ -394,7 +402,7 @@ export const createOtherBucketPostFlightRequest = ( nestedSearchSource.setField('aggs', filterAgg); - const { rawResponse: response } = await lastValueFrom( + const { rawResponse: otherResponse } = await lastValueFrom( nestedSearchSource.fetch$({ abortSignal, sessionId: searchSessionId, @@ -416,7 +424,7 @@ export const createOtherBucketPostFlightRequest = ( resp = mergeOtherBucketAggResponse( aggConfigs, resp, - response, + otherResponse, aggConfig, filterAgg(), otherFilterBuilder diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/values_input.tsx b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/values_input.tsx index 33dd5b7206008..a776227986d68 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/values_input.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/terms/values_input.tsx @@ -94,6 +94,7 @@ export const ValuesInput = ({ const inputNumber = Number(inputValue); setInputValue(String(Math.min(maxValue, Math.max(inputNumber, minValue)))); }} + data-test-subj={'indexPattern-terms-values'} /> ); diff --git a/x-pack/test/functional/apps/lens/group3/terms.ts b/x-pack/test/functional/apps/lens/group3/terms.ts index 3b93c39eb7a6b..f93df80d52589 100644 --- a/x-pack/test/functional/apps/lens/group3/terms.ts +++ b/x-pack/test/functional/apps/lens/group3/terms.ts @@ -6,6 +6,7 @@ */ import expect from '@kbn/expect'; +import moment from 'moment'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { @@ -15,6 +16,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const comboBox = getService('comboBox'); const find = getService('find'); const retry = getService('retry'); + const es = getService('es'); + const indexPatterns = getService('indexPatterns'); + const log = getService('log'); describe('lens terms', () => { describe('lens multi terms suite', () => { @@ -127,11 +131,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await retry.try(async () => { // Can not use testSubjects because data-test-subj is placed range input and number input - const percentileInput = await find.byCssSelector( - `input[data-test-subj="lns-indexPattern-percentile-input"][type='number']` + const percentileInput = await PageObjects.lens.getNumericFieldReady( + 'lns-indexPattern-percentile-input' ); - await percentileInput.click(); - await percentileInput.clearValue(); await percentileInput.type('60'); const percentileValue = await percentileInput.getAttribute('value'); @@ -152,5 +154,150 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(data!.bars![0].bars[0].y).to.eql(19265); }); }); + + describe('Enable Other group', () => { + const esIndexPrefix = 'terms-empty-string-index'; + before(async () => { + log.info(`Creating index ${esIndexPrefix} with mappings`); + await es.indices.create({ + index: esIndexPrefix, + mappings: { + properties: { + '@timestamp': { + type: 'date', + }, + a: { + type: 'keyword', + }, + b: { + type: 'keyword', + }, + }, + }, + }); + + log.info(`Adding 100 documents to ${esIndexPrefix} at Sep 20, 2015 @ 06:31:44.000`); + const timestamp = moment + .utc('Sep 20, 2015 @ 06:31:44.000', 'MMM D, YYYY [@] HH:mm:ss.SSS') + .format(); + + await es.bulk({ + index: esIndexPrefix, + body: Array<{ + a: string; + b: string; + '@timestamp': string; + }>(100) + .fill({ a: '', b: '', '@timestamp': timestamp }) + .map((template, i) => { + return { + ...template, + a: i > 50 ? `${(i % 5) + 1}` : '', // generate 5 values for the index + empty string + b: i < 50 ? `${(i % 5) + 1}` : '', // generate 5 values for the index + empty string + }; + }) + .map((d) => `{"index": {}}\n${JSON.stringify(d)}\n`), + }); + + log.info(`Creating dataView ${esIndexPrefix}`); + await indexPatterns.create( + { + title: esIndexPrefix, + timeFieldName: '@timestamp', + }, + { override: true } + ); + }); + + after(async () => { + await es.indices.delete({ + index: esIndexPrefix, + }); + }); + it('should work with empty string values as buckets', async () => { + await PageObjects.visualize.navigateToNewVisualization(); + await PageObjects.visualize.clickVisType('lens'); + await elasticChart.setNewChartUiDebugFlag(true); + await PageObjects.lens.goToTimeRange(); + await PageObjects.lens.switchDataPanelIndexPattern(esIndexPrefix); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_yDimensionPanel > lns-empty-dimension', + operation: 'count', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'terms', + field: 'a', + }); + + await PageObjects.lens.waitForVisualization('xyVisChart'); + const data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); + const seriesBar = data!.bars![0].bars; + expect(seriesBar[0].x).to.eql('(empty)'); + expect(seriesBar[seriesBar.length - 1].x).to.eql('Other'); + }); + + it('should work with empty string as breakdown', async () => { + await PageObjects.lens.removeDimension('lnsXY_xDimensionPanel'); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_xDimensionPanel > lns-empty-dimension', + operation: 'date_histogram', + field: '@timestamp', + }); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsXY_splitDimensionPanel > lns-empty-dimension', + operation: 'terms', + field: 'a', + }); + + await PageObjects.lens.waitForVisualization('xyVisChart'); + const data = await PageObjects.lens.getCurrentChartDebugState('xyVisChart'); + expect(data!.bars![0].name).to.eql('(empty)'); + expect(data!.bars![data!.bars!.length - 1].name).to.eql('Other'); + }); + + it('should work with nested empty string values', async () => { + await PageObjects.lens.switchToVisualization('lnsDatatable'); + + await PageObjects.lens.removeLayer(); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsDatatable_rows > lns-empty-dimension', + operation: 'terms', + field: 'a', + keepOpen: true, + }); + await PageObjects.lens.setTermsNumberOfValues(4); + await PageObjects.lens.closeDimensionEditor(); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsDatatable_rows > lns-empty-dimension', + operation: 'terms', + field: 'b', + keepOpen: true, + }); + await PageObjects.lens.setTermsNumberOfValues(1); + await PageObjects.lens.closeDimensionEditor(); + + await PageObjects.lens.configureDimension({ + dimension: 'lnsDatatable_metrics > lns-empty-dimension', + operation: 'count', + }); + await PageObjects.lens.waitForVisualization(); + await PageObjects.common.sleep(20000); + // a empty value + expect(await PageObjects.lens.getDatatableCellText(1, 0)).to.eql('(empty)'); + // b Other value + expect(await PageObjects.lens.getDatatableCellText(1, 1)).to.eql('Other'); + // a Other value + expect(await PageObjects.lens.getDatatableCellText(5, 0)).to.eql('Other'); + // b empty value + expect(await PageObjects.lens.getDatatableCellText(5, 1)).to.eql('(empty)'); + }); + }); }); } diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts index 7f95964e0e5d4..a46d90eb915e0 100644 --- a/x-pack/test/functional/page_objects/lens_page.ts +++ b/x-pack/test/functional/page_objects/lens_page.ts @@ -689,6 +689,20 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont await this.selectOptionFromComboBox(`indexPattern-dimension-field-${lastIndex}`, field); }); }, + async getNumericFieldReady(testSubj: string) { + const numericInput = await find.byCssSelector( + `input[data-test-subj=${testSubj}][type='number']` + ); + await numericInput.click(); + await numericInput.clearValue(); + return numericInput; + }, + + async setTermsNumberOfValues(value: number) { + const valuesInput = await this.getNumericFieldReady('indexPattern-terms-values'); + await valuesInput.type(`${value}`); + await PageObjects.common.sleep(500); + }, async checkTermsAreNotAvailableToAgg(fields: string[]) { const lastIndex = ( From 949c2fb9db6c35830ccd391339c270e40526c45a Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Wed, 9 Aug 2023 18:42:50 +0200 Subject: [PATCH 21/41] [Infra UI] Fix flyout-related tests (#163469) closes [#162672](https://github.com/elastic/kibana/issues/162672) ## Summary This PR fixes the `should render alerts count for a host inside a flyout`. It also moves all flyout-related tests to the `#Single Host Flyout` test. ### How to test ```bash yarn test:ftr:server --config x-pack/test/functional/apps/infra/config.ts ``` ```bash yarn test:ftr:runner --config x-pack/test/functional/apps/infra/config.ts --include x-pack/test/functional/apps/infra/hosts_view.ts ``` https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2830 --- .../test/functional/apps/infra/hosts_view.ts | 383 +++++++++--------- .../page_objects/infra_hosts_view.ts | 12 - 2 files changed, 202 insertions(+), 193 deletions(-) diff --git a/x-pack/test/functional/apps/infra/hosts_view.ts b/x-pack/test/functional/apps/infra/hosts_view.ts index f5dc470587c37..11d0a9675573b 100644 --- a/x-pack/test/functional/apps/infra/hosts_view.ts +++ b/x-pack/test/functional/apps/infra/hosts_view.ts @@ -155,8 +155,15 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { return !!currentUrl.match(path); }); - // Failing: See https://github.com/elastic/kibana/issues/162672 - describe.skip('Hosts View', function () { + const waitForPageToLoad = async () => + await retry.waitFor( + 'wait for table and KPI charts to load', + async () => + (await pageObjects.infraHostsView.isHostTableLoading()) && + (await pageObjects.infraHostsView.isKPIChartsLoaded()) + ); + + describe('Hosts View', function () { before(async () => { await Promise.all([ esArchiver.load('x-pack/test/functional/es_archives/infra/alerts'), @@ -247,189 +254,243 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - describe('#Single host Flyout', () => { + describe('#Single Host Flyout', () => { before(async () => { await setHostViewEnabled(true); await pageObjects.common.navigateToApp(HOSTS_VIEW_PATH); await pageObjects.header.waitUntilLoadingHasFinished(); - await pageObjects.timePicker.setAbsoluteRange( - START_HOST_PROCESSES_DATE.format(timepickerFormat), - END_HOST_PROCESSES_DATE.format(timepickerFormat) - ); - await pageObjects.infraHostsView.clickTableOpenFlyoutButton(); }); - after(async () => { - await retry.try(async () => { - await pageObjects.infraHostsView.clickCloseFlyoutButton(); + describe('Tabs', () => { + before(async () => { + await pageObjects.timePicker.setAbsoluteRange( + START_HOST_PROCESSES_DATE.format(timepickerFormat), + END_HOST_PROCESSES_DATE.format(timepickerFormat) + ); + + await waitForPageToLoad(); + + await pageObjects.infraHostsView.clickTableOpenFlyoutButton(); }); - }); - describe('Overview Tab', () => { - before(async () => { - await pageObjects.infraHostsView.clickOverviewFlyoutTab(); + after(async () => { + await retry.try(async () => { + await pageObjects.infraHostsView.clickCloseFlyoutButton(); + }); }); - [ - { metric: 'cpuUsage', value: '13.9%' }, - { metric: 'normalizedLoad1m', value: '18.8%' }, - { metric: 'memoryUsage', value: '94.9%' }, - { metric: 'diskSpaceUsage', value: 'N/A' }, - ].forEach(({ metric, value }) => { - it(`${metric} tile should show ${value}`, async () => { - await retry.try(async () => { - const tileValue = await pageObjects.infraHostsView.getAssetDetailsKPITileValue( - metric - ); - expect(tileValue).to.eql(value); + describe('Overview Tab', () => { + before(async () => { + await pageObjects.infraHostsView.clickOverviewFlyoutTab(); + }); + + [ + { metric: 'cpuUsage', value: '13.9%' }, + { metric: 'normalizedLoad1m', value: '18.8%' }, + { metric: 'memoryUsage', value: '94.9%' }, + { metric: 'diskSpaceUsage', value: 'N/A' }, + ].forEach(({ metric, value }) => { + it(`${metric} tile should show ${value}`, async () => { + await retry.try(async () => { + const tileValue = await pageObjects.infraHostsView.getAssetDetailsKPITileValue( + metric + ); + expect(tileValue).to.eql(value); + }); }); }); - }); - it('should render 8 charts in the Metrics section', async () => { - const hosts = await pageObjects.infraHostsView.getAssetDetailsMetricsCharts(); - expect(hosts.length).to.equal(8); - }); + it('should render 8 charts in the Metrics section', async () => { + const hosts = await pageObjects.infraHostsView.getAssetDetailsMetricsCharts(); + expect(hosts.length).to.equal(8); + }); - it('should navigate to metadata tab', async () => { - await pageObjects.infraHostsView.clickShowAllMetadataOverviewTab(); - await pageObjects.header.waitUntilLoadingHasFinished(); - await pageObjects.infraHostsView.metadataTableExist(); - await pageObjects.infraHostsView.clickOverviewFlyoutTab(); - }); + it('should navigate to metadata tab', async () => { + await pageObjects.infraHostsView.clickShowAllMetadataOverviewTab(); + await pageObjects.header.waitUntilLoadingHasFinished(); + await pageObjects.infraHostsView.metadataTableExist(); + await pageObjects.infraHostsView.clickOverviewFlyoutTab(); + }); - it('should show alerts', async () => { - await pageObjects.header.waitUntilLoadingHasFinished(); - await pageObjects.infraHostsView.overviewAlertsTitleExist(); - }); + it('should show alerts', async () => { + await pageObjects.header.waitUntilLoadingHasFinished(); + await pageObjects.infraHostsView.overviewAlertsTitleExist(); + }); - it('should open alerts flyout', async () => { - await pageObjects.header.waitUntilLoadingHasFinished(); - await pageObjects.infraHostsView.clickOverviewOpenAlertsFlyout(); - // There are 2 flyouts open (asset details and alerts) - // so we need a stricter selector - // to be sure that we are closing the alerts flyout - const closeAlertFlyout = await find.byCssSelector( - '[aria-labelledby="flyoutRuleAddTitle"] > [data-test-subj="euiFlyoutCloseButton"]' - ); - await closeAlertFlyout.click(); - }); + it('should open alerts flyout', async () => { + await pageObjects.header.waitUntilLoadingHasFinished(); + await pageObjects.infraHostsView.clickOverviewOpenAlertsFlyout(); + // There are 2 flyouts open (asset details and alerts) + // so we need a stricter selector + // to be sure that we are closing the alerts flyout + const closeAlertFlyout = await find.byCssSelector( + '[aria-labelledby="flyoutRuleAddTitle"] > [data-test-subj="euiFlyoutCloseButton"]' + ); + await closeAlertFlyout.click(); + }); - it('should navigate to alerts', async () => { - await pageObjects.infraHostsView.clickOverviewLinkToAlerts(); - await pageObjects.header.waitUntilLoadingHasFinished(); - const url = parse(await browser.getCurrentUrl()); + it('should navigate to alerts', async () => { + await pageObjects.infraHostsView.clickOverviewLinkToAlerts(); + await pageObjects.header.waitUntilLoadingHasFinished(); + const url = parse(await browser.getCurrentUrl()); - const query = decodeURIComponent(url.query ?? ''); + const query = decodeURIComponent(url.query ?? ''); - const alertsQuery = - "_a=(kuery:'host.name:\"Jennys-MBP.fritz.box\"',rangeFrom:'2023-03-28T18:20:00.000Z',rangeTo:'2023-03-28T18:21:00.000Z',status:all)"; + const alertsQuery = + "_a=(kuery:'host.name:\"Jennys-MBP.fritz.box\"',rangeFrom:'2023-03-28T18:20:00.000Z',rangeTo:'2023-03-28T18:21:00.000Z',status:all)"; - expect(url.pathname).to.eql('/app/observability/alerts'); - expect(query).to.contain(alertsQuery); + expect(url.pathname).to.eql('/app/observability/alerts'); + expect(query).to.contain(alertsQuery); - await returnTo(HOSTS_VIEW_PATH); + await returnTo(HOSTS_VIEW_PATH); + }); }); - }); - describe('Metadata Tab', () => { - before(async () => { - await pageObjects.infraHostsView.clickMetadataFlyoutTab(); - }); + describe('Metadata Tab', () => { + before(async () => { + await pageObjects.infraHostsView.clickMetadataFlyoutTab(); + }); - it('should render metadata tab, add and remove filter', async () => { - await pageObjects.infraHostsView.metadataTableExist(); + it('should render metadata tab, add and remove filter', async () => { + await pageObjects.infraHostsView.metadataTableExist(); - // Add Pin - await pageObjects.infraHostsView.clickAddMetadataPin(); - expect(await pageObjects.infraHostsView.getRemovePinExist()).to.be(true); + // Add Pin + await pageObjects.infraHostsView.clickAddMetadataPin(); + expect(await pageObjects.infraHostsView.getRemovePinExist()).to.be(true); - // Persist pin after refresh - await browser.refresh(); - await retry.try(async () => { - await pageObjects.infraHome.waitForLoading(); - const removePinExist = await pageObjects.infraHostsView.getRemovePinExist(); - expect(removePinExist).to.be(true); - }); + // Persist pin after refresh + await browser.refresh(); + await retry.try(async () => { + await pageObjects.infraHome.waitForLoading(); + const removePinExist = await pageObjects.infraHostsView.getRemovePinExist(); + expect(removePinExist).to.be(true); + }); - // Remove Pin - await pageObjects.infraHostsView.clickRemoveMetadataPin(); - expect(await pageObjects.infraHostsView.getRemovePinExist()).to.be(false); + // Remove Pin + await pageObjects.infraHostsView.clickRemoveMetadataPin(); + expect(await pageObjects.infraHostsView.getRemovePinExist()).to.be(false); + + await pageObjects.infraHostsView.clickAddMetadataFilter(); + await pageObjects.header.waitUntilLoadingHasFinished(); + + // Add Filter + const addedFilter = await pageObjects.infraHostsView.getAppliedFilter(); + expect(addedFilter).to.contain('host.architecture: arm64'); + const removeFilterExists = await pageObjects.infraHostsView.getRemoveFilterExist(); + expect(removeFilterExists).to.be(true); + + // Remove filter + await pageObjects.infraHostsView.clickRemoveMetadataFilter(); + await pageObjects.header.waitUntilLoadingHasFinished(); + const removeFilterShouldNotExist = + await pageObjects.infraHostsView.getRemoveFilterExist(); + expect(removeFilterShouldNotExist).to.be(false); + }); - await pageObjects.infraHostsView.clickAddMetadataFilter(); - await pageObjects.header.waitUntilLoadingHasFinished(); + it('should render metadata tab, pin and unpin table row', async () => { + // Add Pin + await pageObjects.infraHostsView.clickAddMetadataPin(); + expect(await pageObjects.infraHostsView.getRemovePinExist()).to.be(true); - // Add Filter - const addedFilter = await pageObjects.infraHostsView.getAppliedFilter(); - expect(addedFilter).to.contain('host.architecture: arm64'); - const removeFilterExists = await pageObjects.infraHostsView.getRemoveFilterExist(); - expect(removeFilterExists).to.be(true); + // Persist pin after refresh + await browser.refresh(); + await retry.try(async () => { + await pageObjects.infraHome.waitForLoading(); + const removePinExist = await pageObjects.infraHostsView.getRemovePinExist(); + expect(removePinExist).to.be(true); + }); - // Remove filter - await pageObjects.infraHostsView.clickRemoveMetadataFilter(); - await pageObjects.header.waitUntilLoadingHasFinished(); - const removeFilterShouldNotExist = - await pageObjects.infraHostsView.getRemoveFilterExist(); - expect(removeFilterShouldNotExist).to.be(false); + // Remove Pin + await pageObjects.infraHostsView.clickRemoveMetadataPin(); + expect(await pageObjects.infraHostsView.getRemovePinExist()).to.be(false); + }); }); - it('should render metadata tab, pin and unpin table row', async () => { - // Add Pin - await pageObjects.infraHostsView.clickAddMetadataPin(); - expect(await pageObjects.infraHostsView.getRemovePinExist()).to.be(true); - - // Persist pin after refresh - await browser.refresh(); - await retry.try(async () => { - await pageObjects.infraHome.waitForLoading(); - const removePinExist = await pageObjects.infraHostsView.getRemovePinExist(); - expect(removePinExist).to.be(true); + describe('Processes Tab', () => { + before(async () => { + await pageObjects.infraHostsView.clickProcessesFlyoutTab(); + }); + it('should render processes tab and with Total Value summary', async () => { + const processesTotalValue = + await pageObjects.infraHostsView.getProcessesTabContentTotalValue(); + const processValue = await processesTotalValue.getVisibleText(); + expect(processValue).to.eql('313'); }); - // Remove Pin - await pageObjects.infraHostsView.clickRemoveMetadataPin(); - expect(await pageObjects.infraHostsView.getRemovePinExist()).to.be(false); + it('should expand processes table row', async () => { + await pageObjects.infraHostsView.getProcessesTable(); + await pageObjects.infraHostsView.getProcessesTableBody(); + await pageObjects.infraHostsView.clickProcessesTableExpandButton(); + }); }); - }); - describe('Processes Tab', () => { - before(async () => { - await pageObjects.infraHostsView.clickProcessesFlyoutTab(); - }); - it('should render processes tab and with Total Value summary', async () => { - const processesTotalValue = - await pageObjects.infraHostsView.getProcessesTabContentTotalValue(); - const processValue = await processesTotalValue.getVisibleText(); - expect(processValue).to.eql('313'); + describe('Logs Tab', () => { + before(async () => { + await pageObjects.infraHostsView.clickLogsFlyoutTab(); + }); + it('should render logs tab', async () => { + await testSubjects.existOrFail('infraAssetDetailsLogsTabContent'); + }); }); - it('should expand processes table row', async () => { - await pageObjects.infraHostsView.getProcessesTable(); - await pageObjects.infraHostsView.getProcessesTableBody(); - await pageObjects.infraHostsView.clickProcessesTableExpandButton(); + describe('Flyout links', () => { + it('should navigate to APM services after click', async () => { + await pageObjects.infraHostsView.clickFlyoutApmServicesLink(); + const url = parse(await browser.getCurrentUrl()); + const query = decodeURIComponent(url.query ?? ''); + const kuery = 'kuery=host.hostname:"Jennys-MBP.fritz.box"'; + + expect(url.pathname).to.eql('/app/apm/services'); + expect(query).to.contain(kuery); + + await returnTo(HOSTS_VIEW_PATH); + }); }); }); - describe('Logs Tab', () => { + describe('Host with alerts', () => { before(async () => { - await pageObjects.infraHostsView.clickLogsFlyoutTab(); + await pageObjects.timePicker.setAbsoluteRange( + START_DATE.format(timepickerFormat), + END_DATE.format(timepickerFormat) + ); + await pageObjects.infraHostsView.clickHostCheckbox('demo-stack-mysql-01', '-'); + await pageObjects.infraHostsView.clickSelectedHostsButton(); + await pageObjects.infraHostsView.clickSelectedHostsAddFilterButton(); + + await waitForPageToLoad(); + + await pageObjects.infraHostsView.clickTableOpenFlyoutButton(); }); - it('should render logs tab', async () => { - await testSubjects.existOrFail('infraAssetDetailsLogsTabContent'); + + after(async () => { + await retry.try(async () => { + await pageObjects.infraHostsView.clickCloseFlyoutButton(); + }); }); - }); - describe('Flyout links', () => { - it('should navigate to APM services after click', async () => { - await pageObjects.infraHostsView.clickFlyoutApmServicesLink(); - const url = parse(await browser.getCurrentUrl()); - const query = decodeURIComponent(url.query ?? ''); - const kuery = 'kuery=host.hostname:"Jennys-MBP.fritz.box"'; + it('should render alerts count for a host inside a flyout', async () => { + await pageObjects.infraHostsView.clickOverviewFlyoutTab(); - expect(url.pathname).to.eql('/app/apm/services'); - expect(query).to.contain(kuery); + retry.tryForTime(30 * 1000, async () => { + await observability.components.alertSummaryWidget.getFullSizeComponentSelectorOrFail(); + }); - await returnTo(HOSTS_VIEW_PATH); + const activeAlertsCount = + await observability.components.alertSummaryWidget.getActiveAlertCount(); + const totalAlertsCount = + await observability.components.alertSummaryWidget.getTotalAlertCount(); + + expect(activeAlertsCount.trim()).to.equal('2'); + expect(totalAlertsCount.trim()).to.equal('3'); + }); + + it('should render "N/A" when processes summary is not available in flyout', async () => { + await pageObjects.infraHostsView.clickProcessesFlyoutTab(); + const processesTotalValue = + await pageObjects.infraHostsView.getProcessesTabContentTotalValue(); + const processValue = await processesTotalValue.getVisibleText(); + expect(processValue).to.eql('N/A'); }); }); }); @@ -444,12 +505,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { END_DATE.format(timepickerFormat) ); - await retry.waitFor( - 'wait for table and KPI charts to load', - async () => - (await pageObjects.infraHostsView.isHostTableLoading()) && - (await pageObjects.infraHostsView.isKPIChartsLoaded()) - ); + await waitForPageToLoad(); }); it('should render the correct page title', async () => { @@ -509,37 +565,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - it('should render alerts count for a host inside a flyout', async () => { - await pageObjects.infraHostsView.clickHostCheckbox('demo-stack-mysql-01', '-'); - await pageObjects.infraHostsView.clickSelectedHostsButton(); - await pageObjects.infraHostsView.clickSelectedHostsAddFilterButton(); - await pageObjects.infraHostsView.clickTableOpenFlyoutButton(); - - const activeAlertsCount = await pageObjects.infraHostsView.getActiveAlertsCountText(); - const totalAlertsCount = await pageObjects.infraHostsView.getTotalAlertsCountText(); - - expect(activeAlertsCount).to.equal('2 '); - expect(totalAlertsCount).to.equal('3'); - - const deleteFilterButton = await find.byCssSelector( - `[title="Delete host.name: demo-stack-mysql-01"]` - ); - await deleteFilterButton.click(); - - await pageObjects.infraHostsView.clickCloseFlyoutButton(); - }); - - it('should render "N/A" when processes summary is not available in flyout', async () => { - await pageObjects.infraHostsView.clickTableOpenFlyoutButton(); - await pageObjects.infraHostsView.clickProcessesFlyoutTab(); - const processesTotalValue = - await pageObjects.infraHostsView.getProcessesTabContentTotalValue(); - const processValue = await processesTotalValue.getVisibleText(); - expect(processValue).to.eql('N/A'); - await pageObjects.infraHostsView.clickCloseFlyoutButton(); - }); - - describe('KPI tiles', () => { + describe('KPIs', () => { [ { metric: 'hostsCount', value: '6' }, { metric: 'cpuUsage', value: '0.8%' }, @@ -673,12 +699,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { before(async () => { await browser.scrollTop(); await pageObjects.infraHostsView.submitQuery(query); - await retry.waitFor( - 'wait for table and KPI charts to load', - async () => - (await pageObjects.infraHostsView.isHostTableLoading()) && - (await pageObjects.infraHostsView.isKPIChartsLoaded()) - ); + await await waitForPageToLoad(); }); after(async () => { diff --git a/x-pack/test/functional/page_objects/infra_hosts_view.ts b/x-pack/test/functional/page_objects/infra_hosts_view.ts index 00ae0af08cf07..6bad2bf1630e5 100644 --- a/x-pack/test/functional/page_objects/infra_hosts_view.ts +++ b/x-pack/test/functional/page_objects/infra_hosts_view.ts @@ -215,18 +215,6 @@ export function InfraHostsViewProvider({ getService }: FtrProviderContext) { return testSubjects.exists('assetDetailsAlertsTitle'); }, - async getActiveAlertsCountText() { - const container = await testSubjects.find('activeAlertCount'); - const containerText = await container.getVisibleText(); - return containerText; - }, - - async getTotalAlertsCountText() { - const container = await testSubjects.find('totalAlertCount'); - const containerText = await container.getVisibleText(); - return containerText; - }, - async getAssetDetailsMetricsCharts() { const container = await testSubjects.find('assetDetailsMetricsChartGrid'); return container.findAllByCssSelector('[data-test-subj*="infraAssetDetailsMetricsChart"]'); From fb6c9f0898c507029d9196094b7789406a4d8401 Mon Sep 17 00:00:00 2001 From: Achyut Jhunjhunwala Date: Wed, 9 Aug 2023 18:53:12 +0200 Subject: [PATCH 22/41] [APM] FIX trace waterfall loading logic to handle empty scenarios (#163397) ## Summary Closes https://github.com/elastic/kibana/issues/154705 ## List of Issues - Trace Waterfall not clearing and persisting old data ![Trace Explorer Not clearing](https://github.com/elastic/kibana/assets/7416358/5302c5ed-0c92-44ab-81a5-115e32dc8ace) - Infinite Loading of Trace Waterfall where no traces are present and page is reloaded ![Infinite Loading](https://github.com/elastic/kibana/assets/7416358/c5ae1cda-099e-4968-96e5-ad85db38d83a) - After Fixing these 2 issues, found issue with Container Height ![Container Height Issue](https://github.com/elastic/kibana/assets/7416358/7fc7ef1b-68dc-4f52-bc2f-c346cfd5f67e) ## All issues fixed ![All issues resolved](https://github.com/elastic/kibana/assets/7416358/227fe648-d6b9-4788-8961-7369f6ed621a) --- .../transaction_details.cy.ts | 26 +++++++++++++++++++ .../distribution/index.tsx | 6 ++--- .../use_waterfall_fetcher.ts | 5 +++- .../waterfall_with_summary/index.tsx | 5 +++- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/e2e/read_only_user/transaction_details/transaction_details.cy.ts b/x-pack/plugins/apm/ftr_e2e/cypress/e2e/read_only_user/transaction_details/transaction_details.cy.ts index dd73051be9f2e..6886fc582f631 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/e2e/read_only_user/transaction_details/transaction_details.cy.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/e2e/read_only_user/transaction_details/transaction_details.cy.ts @@ -151,4 +151,30 @@ describe('Transaction details', () => { }); }); }); + + describe('when changing filters which results in no trace samples', () => { + it('trace waterfall must reset to empty state', () => { + cy.visitKibana( + `/app/apm/services/opbeans-java/transactions/view?${new URLSearchParams( + { + ...timeRange, + transactionName: 'GET /api/product', + } + )}` + ); + + cy.getByTestSubj('apmWaterfallButton').should('exist'); + + cy.getByTestSubj('apmUnifiedSearchBar') + .type(`_id: "123"`) + .type('{enter}'); + + cy.getByTestSubj('apmWaterfallButton').should('not.exist'); + cy.getByTestSubj('apmNoTraceFound').should('exist'); + + cy.reload(); + + cy.getByTestSubj('apmNoTraceFound').should('exist'); + }); + }); }); diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx index 0c05b945c1b70..47642ebbdc6dc 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/distribution/index.tsx @@ -20,7 +20,7 @@ import { useApmServiceContext } from '../../../../context/apm_service/use_apm_se import { useAnyOfApmParams } from '../../../../hooks/use_apm_params'; import { useTimeRange } from '../../../../hooks/use_time_range'; import { DurationDistributionChartWithScrubber } from '../../../shared/charts/duration_distribution_chart_with_scrubber'; -import { HeightRetainer } from '../../../shared/height_retainer'; +import { ResettingHeightRetainer } from '../../../shared/height_retainer/resetting_height_container'; import { fromQuery, push, toQuery } from '../../../shared/links/url_helpers'; import { TransactionTab } from '../waterfall_with_summary/transaction_tabs'; import { useTransactionDistributionChartData } from './use_transaction_distribution_chart_data'; @@ -99,7 +99,7 @@ export function TransactionDistribution({ ); return ( - +
    -
    + ); } diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/use_waterfall_fetcher.ts b/x-pack/plugins/apm/public/components/app/transaction_details/use_waterfall_fetcher.ts index 81e0d736aee19..a01bb00ea0e44 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/use_waterfall_fetcher.ts +++ b/x-pack/plugins/apm/public/components/app/transaction_details/use_waterfall_fetcher.ts @@ -56,7 +56,10 @@ export function useWaterfallFetcher({ [traceId, start, end, transactionId] ); - const waterfall = useMemo(() => getWaterfall(data), [data]); + const waterfall = useMemo( + () => getWaterfall(traceId ? data : INITIAL_DATA), + [data, traceId] + ); return { waterfall, status, error }; } diff --git a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx index e19400490133b..a14572f089137 100644 --- a/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx +++ b/x-pack/plugins/apm/public/components/app/transaction_details/waterfall_with_summary/index.tsx @@ -60,8 +60,10 @@ export function WaterfallWithSummary({ const isLoading = waterfallFetchResult.status === FETCH_STATUS.LOADING || traceSamplesFetchStatus === FETCH_STATUS.LOADING; + // When traceId is not present, call to waterfallFetchResult will not be initiated const isSucceded = - waterfallFetchResult.status === FETCH_STATUS.SUCCESS && + (waterfallFetchResult.status === FETCH_STATUS.SUCCESS || + waterfallFetchResult.status === FETCH_STATUS.NOT_INITIATED) && traceSamplesFetchStatus === FETCH_STATUS.SUCCESS; useEffect(() => { @@ -96,6 +98,7 @@ export function WaterfallWithSummary({ })} } + data-test-subj="apmNoTraceFound" titleSize="s" /> ); From 9fb83fed865c51e0834fc50c0e4cc19fca2ce649 Mon Sep 17 00:00:00 2001 From: Alison Goryachev Date: Wed, 9 Aug 2023 13:17:07 -0400 Subject: [PATCH 23/41] [Watcher] Re-enable jest tests (#162592) --- .buildkite/disabled_jest_configs.json | 4 +- .../helpers/watch_create_json_page.helpers.ts | 33 ++-- .../watch_create_threshold_page.helpers.ts | 43 ++++-- .../helpers/watch_edit_page.helpers.ts | 11 +- .../helpers/watch_list_page.helpers.ts | 23 ++- .../helpers/watch_status_page.helpers.ts | 24 +-- ...est.ts => watch_create_json_page.test.tsx} | 71 +++++---- .../watch_create_threshold_page.test.tsx | 143 ++++++++++-------- .../watch_edit_page.test.tsx | 20 +-- .../watch_list_page.test.ts | 6 +- .../watch_status_page.test.ts | 14 +- 11 files changed, 233 insertions(+), 159 deletions(-) rename x-pack/plugins/watcher/__jest__/client_integration/{watch_create_json_page.test.ts => watch_create_json_page.test.tsx} (88%) diff --git a/.buildkite/disabled_jest_configs.json b/.buildkite/disabled_jest_configs.json index a64c34ae741b4..fe51488c7066f 100644 --- a/.buildkite/disabled_jest_configs.json +++ b/.buildkite/disabled_jest_configs.json @@ -1,3 +1 @@ -[ - "x-pack/plugins/watcher/jest.config.js" -] +[] diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_json_page.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_json_page.helpers.ts index 6b70f3bdece88..15c9b5b01fe88 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_json_page.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_json_page.helpers.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { act } from 'react-dom/test-utils'; + import { registerTestBed, TestBed, AsyncTestBedConfig } from '@kbn/test-jest-helpers'; import { HttpSetup } from '@kbn/core/public'; @@ -24,32 +26,45 @@ const testBedConfig: AsyncTestBedConfig = { export interface WatchCreateJsonTestBed extends TestBed { actions: { - selectTab: (tab: 'edit' | 'simulate') => void; - clickSubmitButton: () => void; - clickSimulateButton: () => void; + selectTab: (tab: 'edit' | 'simulate') => Promise; + clickSubmitButton: () => Promise; + clickSimulateButton: () => Promise; }; } export const setup = async (httpSetup: HttpSetup): Promise => { const initTestBed = registerTestBed(WithAppDependencies(WatchEditPage, httpSetup), testBedConfig); const testBed = await initTestBed(); + const { find, component } = testBed; /** * User Actions */ - const selectTab = (tab: 'edit' | 'simulate') => { + const selectTab = async (tab: 'edit' | 'simulate') => { const tabs = ['edit', 'simulate']; - testBed.find('tab').at(tabs.indexOf(tab)).simulate('click'); + await act(async () => { + find('tab').at(tabs.indexOf(tab)).simulate('click'); + }); + + component.update(); }; - const clickSubmitButton = () => { - testBed.find('saveWatchButton').simulate('click'); + const clickSubmitButton = async () => { + await act(async () => { + testBed.find('saveWatchButton').simulate('click'); + }); + + component.update(); }; - const clickSimulateButton = () => { - testBed.find('simulateWatchButton').simulate('click'); + const clickSimulateButton = async () => { + await act(async () => { + testBed.find('simulateWatchButton').simulate('click'); + }); + + component.update(); }; return { diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_threshold_page.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_threshold_page.helpers.ts index d2bb49a861167..b64ea8b003843 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_threshold_page.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_create_threshold_page.helpers.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { act } from 'react-dom/test-utils'; + import { registerTestBed, TestBed, AsyncTestBedConfig } from '@kbn/test-jest-helpers'; import { HttpSetup } from '@kbn/core/public'; @@ -24,39 +26,56 @@ const testBedConfig: AsyncTestBedConfig = { export interface WatchCreateThresholdTestBed extends TestBed { actions: { - clickSubmitButton: () => void; - clickAddActionButton: () => void; + clickSubmitButton: () => Promise; + clickAddActionButton: () => Promise; clickActionLink: ( actionType: 'logging' | 'email' | 'webhook' | 'index' | 'slack' | 'jira' | 'pagerduty' - ) => void; - clickSimulateButton: () => void; + ) => Promise; + clickSimulateButton: () => Promise; }; } export const setup = async (httpSetup: HttpSetup): Promise => { const initTestBed = registerTestBed(WithAppDependencies(WatchEditPage, httpSetup), testBedConfig); const testBed = await initTestBed(); + const { find, component } = testBed; /** * User Actions */ - const clickSubmitButton = () => { - testBed.find('saveWatchButton').simulate('click'); + const clickSubmitButton = async () => { + await act(async () => { + find('saveWatchButton').simulate('click'); + }); + + component.update(); }; - const clickAddActionButton = () => { - testBed.find('addWatchActionButton').simulate('click'); + const clickAddActionButton = async () => { + await act(async () => { + find('addWatchActionButton').simulate('click'); + }); + + component.update(); }; - const clickSimulateButton = () => { - testBed.find('simulateActionButton').simulate('click'); + const clickSimulateButton = async () => { + await act(async () => { + find('simulateActionButton').simulate('click'); + }); + + component.update(); }; - const clickActionLink = ( + const clickActionLink = async ( actionType: 'logging' | 'email' | 'webhook' | 'index' | 'slack' | 'jira' | 'pagerduty' ) => { - testBed.find(`${actionType}ActionButton`).simulate('click'); + await act(async () => { + find(`${actionType}ActionButton`).simulate('click'); + }); + + component.update(); }; return { diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_edit_page.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_edit_page.helpers.ts index 20f8389c0fec7..8e528af2b3366 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_edit_page.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_edit_page.helpers.ts @@ -4,6 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { act } from 'react-dom/test-utils'; import { registerTestBed, TestBed, AsyncTestBedConfig } from '@kbn/test-jest-helpers'; import { HttpSetup } from '@kbn/core/public'; @@ -25,7 +26,7 @@ const testBedConfig: AsyncTestBedConfig = { export interface WatchEditTestBed extends TestBed { actions: { - clickSubmitButton: () => void; + clickSubmitButton: () => Promise; }; } @@ -37,8 +38,12 @@ export const setup = async (httpSetup: HttpSetup): Promise => * User Actions */ - const clickSubmitButton = () => { - testBed.find('saveWatchButton').simulate('click'); + const clickSubmitButton = async () => { + await act(async () => { + testBed.find('saveWatchButton').simulate('click'); + }); + + testBed.component.update(); }; return { diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_list_page.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_list_page.helpers.ts index 3361619ee9dbb..cd4fd2ab2cfba 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_list_page.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_list_page.helpers.ts @@ -27,9 +27,9 @@ const testBedConfig: AsyncTestBedConfig = { export interface WatchListTestBed extends TestBed { actions: { - selectWatchAt: (index: number) => void; - clickWatchActionAt: (index: number, action: 'delete' | 'edit') => void; - searchWatches: (term: string) => void; + selectWatchAt: (index: number) => Promise; + clickWatchActionAt: (index: number, action: 'delete' | 'edit') => Promise; + searchWatches: (term: string) => Promise; advanceTimeToTableRefresh: () => Promise; }; } @@ -42,11 +42,15 @@ export const setup = async (httpSetup: HttpSetup): Promise => * User Actions */ - const selectWatchAt = (index: number) => { + const selectWatchAt = async (index: number) => { const { rows } = testBed.table.getMetaData('watchesTable'); const row = rows[index]; const checkBox = row.reactWrapper.find('input').hostNodes(); - checkBox.simulate('change', { target: { checked: true } }); + + await act(async () => { + checkBox.simulate('change', { target: { checked: true } }); + }); + testBed.component.update(); }; const clickWatchActionAt = async (index: number, action: 'delete' | 'edit') => { @@ -58,18 +62,21 @@ export const setup = async (httpSetup: HttpSetup): Promise => await act(async () => { button.simulate('click'); - component.update(); }); + component.update(); }; - const searchWatches = (term: string) => { + const searchWatches = async (term: string) => { const { find, component } = testBed; const searchInput = find('watchesTableContainer').find('.euiFieldSearch'); // Enter input into the search box // @ts-ignore searchInput.instance().value = term; - searchInput.simulate('keyup', { key: 'Enter', keyCode: 13, which: 13 }); + + await act(async () => { + searchInput.simulate('keyup', { key: 'Enter', keyCode: 13, which: 13 }); + }); component.update(); }; diff --git a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_status_page.helpers.ts b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_status_page.helpers.ts index 601857ca941f0..7c6da257b1700 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_status_page.helpers.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/helpers/watch_status_page.helpers.ts @@ -32,11 +32,11 @@ const testBedConfig: AsyncTestBedConfig = { export interface WatchStatusTestBed extends TestBed { actions: { - selectTab: (tab: 'execution history' | 'action statuses') => void; - clickToggleActivationButton: () => void; - clickAcknowledgeButton: (index: number) => void; - clickDeleteWatchButton: () => void; - clickWatchExecutionAt: (index: number, tableCellText: string) => void; + selectTab: (tab: 'execution history' | 'action statuses') => Promise; + clickToggleActivationButton: () => Promise; + clickAcknowledgeButton: (index: number) => Promise; + clickDeleteWatchButton: () => Promise; + clickWatchExecutionAt: (index: number, tableCellText: string) => Promise; }; } @@ -51,10 +51,14 @@ export const setup = async (httpSetup: HttpSetup): Promise = * User Actions */ - const selectTab = (tab: 'execution history' | 'action statuses') => { + const selectTab = async (tab: 'execution history' | 'action statuses') => { + const { component, find } = testBed; const tabs = ['execution history', 'action statuses']; - testBed.find('tab').at(tabs.indexOf(tab)).simulate('click'); + await act(async () => { + find('tab').at(tabs.indexOf(tab)).simulate('click'); + }); + component.update(); }; const clickToggleActivationButton = async () => { @@ -63,8 +67,8 @@ export const setup = async (httpSetup: HttpSetup): Promise = await act(async () => { button.simulate('click'); - component.update(); }); + component.update(); }; const clickAcknowledgeButton = async (index: number) => { @@ -76,8 +80,8 @@ export const setup = async (httpSetup: HttpSetup): Promise = await act(async () => { button.simulate('click'); - component.update(); }); + component.update(); }; const clickDeleteWatchButton = async () => { @@ -86,8 +90,8 @@ export const setup = async (httpSetup: HttpSetup): Promise = await act(async () => { button.simulate('click'); - component.update(); }); + component.update(); }; const clickWatchExecutionAt = async (index: number, tableCellText: string) => { diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.ts b/x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.tsx similarity index 88% rename from x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.ts rename to x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.tsx index f79a72b456afb..f6231ab328d25 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_create_json_page.test.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import React from 'react'; import { act } from 'react-dom/test-utils'; import { getExecuteDetails } from '../../__fixtures__'; @@ -16,12 +17,29 @@ import { WATCH } from './helpers/jest_constants'; const { setup } = pageHelpers.watchCreateJsonPage; +jest.mock('@kbn/kibana-react-plugin/public', () => { + const original = jest.requireActual('@kbn/kibana-react-plugin/public'); + return { + ...original, + // Mocking CodeEditor, which uses React Monaco under the hood + CodeEditor: (props: any) => ( + { + props.onChange(e.jsonContent); + }} + /> + ), + }; +}); + describe(' create route', () => { const { httpSetup, httpRequestsMockHelpers } = setupEnvironment(); let testBed: WatchCreateJsonTestBed; beforeAll(() => { - jest.useFakeTimers({ legacyFakeTimers: true }); + jest.useFakeTimers(); }); afterAll(() => { @@ -30,7 +48,10 @@ describe(' create route', () => { describe('on component mount', () => { beforeEach(async () => { - testBed = await setup(httpSetup); + await act(async () => { + testBed = await setup(httpSetup); + }); + testBed.component.update(); }); @@ -47,13 +68,13 @@ describe(' create route', () => { expect(find('tab').map((t) => t.text())).toEqual(['Edit', 'Simulate']); }); - test('should navigate to the "Simulate" tab', () => { + test('should navigate to the "Simulate" tab', async () => { const { exists, actions } = testBed; expect(exists('jsonWatchForm')).toBe(true); expect(exists('jsonWatchSimulateForm')).toBe(false); - actions.selectTab('simulate'); + await actions.selectTab('simulate'); expect(exists('jsonWatchForm')).toBe(false); expect(exists('jsonWatchSimulateForm')).toBe(true); @@ -62,19 +83,19 @@ describe(' create route', () => { describe('create', () => { describe('form validation', () => { - test('should not allow empty ID field', () => { + test('should not allow empty ID field', async () => { const { form, actions } = testBed; form.setInputValue('idInput', ''); - actions.clickSubmitButton(); + await actions.clickSubmitButton(); expect(form.getErrorsMessages()).toContain('ID is required'); }); - test('should not allow invalid characters for ID field', () => { + test('should not allow invalid characters for ID field', async () => { const { form, actions } = testBed; form.setInputValue('idInput', 'invalid$id*field/'); - actions.clickSubmitButton(); + await actions.clickSubmitButton(); expect(form.getErrorsMessages()).toContain( 'ID can only contain letters, underscores, dashes, periods and numbers.' @@ -90,9 +111,7 @@ describe(' create route', () => { form.setInputValue('nameInput', watch.name); form.setInputValue('idInput', watch.id); - await act(async () => { - actions.clickSubmitButton(); - }); + await actions.clickSubmitButton(); const DEFAULT_LOGGING_ACTION_ID = 'logging_1'; const DEFAULT_LOGGING_ACTION_TYPE = 'logging'; @@ -125,7 +144,7 @@ describe(' create route', () => { }); test('should surface the API errors from the "save" HTTP request', async () => { - const { form, actions, component, exists, find } = testBed; + const { form, actions, exists, find } = testBed; const { watch } = WATCH; form.setInputValue('nameInput', watch.name); @@ -140,10 +159,7 @@ describe(' create route', () => { httpRequestsMockHelpers.setSaveWatchResponse(watch.id, undefined, error); - await act(async () => { - actions.clickSubmitButton(); - }); - component.update(); + await actions.clickSubmitButton(); expect(exists('sectionError')).toBe(true); expect(find('sectionError').text()).toContain(error.message); @@ -152,12 +168,13 @@ describe(' create route', () => { }); describe('simulate', () => { - beforeEach(() => { + beforeEach(async () => { const { actions, form } = testBed; // Set watch id (required field) and switch to simulate tab form.setInputValue('idInput', WATCH.watch.id); - actions.selectTab('simulate'); + + await actions.selectTab('simulate'); }); describe('form payload & API errors', () => { @@ -167,9 +184,7 @@ describe(' create route', () => { watch: { id, type }, } = WATCH; - await act(async () => { - actions.clickSimulateButton(); - }); + await actions.clickSimulateButton(); const actionModes = Object.keys(defaultWatch.actions).reduce( (actionAccum: any, action) => { @@ -202,7 +217,7 @@ describe(' create route', () => { }); test('should execute a watch with a valid payload', async () => { - const { actions, form, find, exists, component } = testBed; + const { actions, form, find, exists } = testBed; const { watch: { id, type }, } = WATCH; @@ -228,10 +243,7 @@ describe(' create route', () => { }, }); - await act(async () => { - actions.clickSimulateButton(); - }); - component.update(); + await actions.clickSimulateButton(); const actionModes = Object.keys(defaultWatch.actions).reduce( (actionAccum: any, action) => { @@ -303,7 +315,7 @@ describe(' create route', () => { conditionMet ? 'when the condition is met' : 'when the condition is not met', () => { beforeEach(async () => { - const { actions, component, form } = testBed; + const { actions, form } = testBed; form.setInputValue('actionModesSelect', actionMode); httpRequestsMockHelpers.setLoadExecutionResultResponse({ @@ -335,10 +347,7 @@ describe(' create route', () => { }, }); - await act(async () => { - actions.clickSimulateButton(); - }); - component.update(); + await actions.clickSimulateButton(); }); test('should set the correct condition met status', () => { diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_create_threshold_page.test.tsx b/x-pack/plugins/watcher/__jest__/client_integration/watch_create_threshold_page.test.tsx index d7df7efd7be12..8260bd75ebb04 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_create_threshold_page.test.tsx +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_create_threshold_page.test.tsx @@ -23,16 +23,6 @@ const MATCH_INDICES = ['index1']; const ES_FIELDS = [{ name: '@timestamp', type: 'date' }]; -// Since watchID's are dynamically created, we have to mock -// the function that generates them in order to be able to match -// against it. -jest.mock('uuid', () => ({ - v4: () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - return require('./helpers/jest_constants').WATCH_ID; - }, -})); - const SETTINGS = { action_types: { email: { enabled: true }, @@ -55,6 +45,37 @@ const WATCH_VISUALIZE_DATA = { }, }; +// Since watchID's are dynamically created, we have to mock +// the function that generates them in order to be able to match +// against it. +jest.mock('uuid', () => ({ + v4: () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + return require('./helpers/jest_constants').WATCH_ID; + }, + v1: () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + return require('./helpers/jest_constants').WATCH_ID; + }, +})); + +jest.mock('@kbn/kibana-react-plugin/public', () => { + const original = jest.requireActual('@kbn/kibana-react-plugin/public'); + return { + ...original, + // Mocking CodeEditor, which uses React Monaco under the hood + CodeEditor: (props: any) => ( + { + props.onChange(e.jsonContent); + }} + /> + ), + }; +}); + jest.mock('@elastic/eui', () => { const original = jest.requireActual('@elastic/eui'); @@ -82,22 +103,27 @@ describe(' create route', () => { let testBed: WatchCreateThresholdTestBed; beforeAll(() => { - jest.useFakeTimers({ legacyFakeTimers: true }); + jest.useFakeTimers(); }); afterAll(() => { jest.useRealTimers(); }); - describe('on component mount', () => { - beforeEach(async () => { - await act(async () => { - testBed = await setup(httpSetup); - }); + httpRequestsMockHelpers.setLoadMatchingIndicesResponse({ indices: MATCH_INDICES }); + httpRequestsMockHelpers.setLoadEsFieldsResponse({ fields: ES_FIELDS }); + httpRequestsMockHelpers.setLoadSettingsResponse(SETTINGS); + httpRequestsMockHelpers.setLoadWatchVisualizeResponse(WATCH_VISUALIZE_DATA); - testBed.component.update(); + beforeEach(async () => { + await act(async () => { + testBed = await setup(httpSetup); }); + testBed.component.update(); + }); + + describe('on component mount', () => { test('should set the correct page title', () => { const { find } = testBed; @@ -105,13 +131,6 @@ describe(' create route', () => { }); describe('create', () => { - beforeEach(async () => { - httpRequestsMockHelpers.setLoadMatchingIndicesResponse({ indices: MATCH_INDICES }); - httpRequestsMockHelpers.setLoadEsFieldsResponse({ fields: ES_FIELDS }); - httpRequestsMockHelpers.setLoadSettingsResponse(SETTINGS); - httpRequestsMockHelpers.setLoadWatchVisualizeResponse(WATCH_VISUALIZE_DATA); - }); - describe('form validation', () => { test('should not allow empty name field', () => { const { form } = testBed; @@ -216,14 +235,21 @@ describe(' create route', () => { describe('actions', () => { beforeEach(async () => { + await act(async () => { + testBed = await setup(httpSetup); + }); + const { form, find, component } = testBed; + component.update(); + // Set up valid fields needed for actions component to render await act(async () => { form.setInputValue('nameInput', WATCH_NAME); find('indicesComboBox').simulate('change', [{ label: 'index1', value: 'index1' }]); form.setInputValue('watchTimeFieldSelect', WATCH_TIME_FIELD); }); + component.update(); }); @@ -232,8 +258,8 @@ describe(' create route', () => { const LOGGING_MESSAGE = 'test log message'; - actions.clickAddActionButton(); - actions.clickActionLink('logging'); + await actions.clickAddActionButton(); + await actions.clickActionLink('logging'); expect(exists('watchActionAccordion')).toBe(true); @@ -246,9 +272,7 @@ describe(' create route', () => { // Next, provide valid field and verify form.setInputValue('loggingTextInput', LOGGING_MESSAGE); - await act(async () => { - actions.clickSimulateButton(); - }); + await actions.clickSimulateButton(); const thresholdWatch = { id: WATCH_ID, @@ -300,17 +324,15 @@ describe(' create route', () => { test('should simulate an index action', async () => { const { form, actions, exists } = testBed; - actions.clickAddActionButton(); - actions.clickActionLink('index'); + await actions.clickAddActionButton(); + await actions.clickActionLink('index'); expect(exists('watchActionAccordion')).toBe(true); // Verify an empty index is allowed form.setInputValue('indexInput', ''); - await act(async () => { - actions.clickSimulateButton(); - }); + await actions.clickSimulateButton(); const thresholdWatch = { id: WATCH_ID, @@ -363,16 +385,14 @@ describe(' create route', () => { const SLACK_MESSAGE = 'test slack message'; - actions.clickAddActionButton(); - actions.clickActionLink('slack'); + await actions.clickAddActionButton(); + await actions.clickActionLink('slack'); expect(exists('watchActionAccordion')).toBe(true); form.setInputValue('slackMessageTextarea', SLACK_MESSAGE); - await act(async () => { - actions.clickSimulateButton(); - }); + await actions.clickSimulateButton(); const thresholdWatch = { id: WATCH_ID, @@ -430,8 +450,8 @@ describe(' create route', () => { const EMAIL_SUBJECT = 'test email subject'; const EMAIL_BODY = 'this is a test email body'; - actions.clickAddActionButton(); - actions.clickActionLink('email'); + await actions.clickAddActionButton(); + await actions.clickActionLink('email'); expect(exists('watchActionAccordion')).toBe(true); @@ -442,9 +462,7 @@ describe(' create route', () => { form.setInputValue('emailSubjectInput', EMAIL_SUBJECT); form.setInputValue('emailBodyInput', EMAIL_BODY); - await act(async () => { - actions.clickSimulateButton(); - }); + await actions.clickSimulateButton(); const thresholdWatch = { id: WATCH_ID, @@ -510,8 +528,8 @@ describe(' create route', () => { const USERNAME = 'test_user'; const PASSWORD = 'test_password'; - actions.clickAddActionButton(); - actions.clickActionLink('webhook'); + await actions.clickAddActionButton(); + await actions.clickActionLink('webhook'); expect(exists('watchActionAccordion')).toBe(true); @@ -534,9 +552,7 @@ describe(' create route', () => { form.setInputValue('webhookUsernameInput', USERNAME); form.setInputValue('webhookPasswordInput', PASSWORD); - await act(async () => { - actions.clickSimulateButton(); - }); + await actions.clickSimulateButton(); const thresholdWatch = { id: WATCH_ID, @@ -600,14 +616,18 @@ describe(' create route', () => { const ISSUE_TYPE = 'Bug'; const SUMMARY = 'test Jira summary'; - actions.clickAddActionButton(); - actions.clickActionLink('jira'); + await actions.clickAddActionButton(); + await actions.clickActionLink('jira'); expect(exists('watchActionAccordion')).toBe(true); - // First, provide invalid fields and verify - form.setInputValue('jiraProjectKeyInput', ''); + // Set issue type value and clear it to trigger required error message + form.setInputValue('jiraIssueTypeInput', 'myissue'); form.setInputValue('jiraIssueTypeInput', ''); + // Set project type value and clear it to trigger required error message + form.setInputValue('jiraProjectKeyInput', 'my key'); + form.setInputValue('jiraProjectKeyInput', ''); + // Clear default summary to trigger required error message form.setInputValue('jiraSummaryInput', ''); expect(form.getErrorsMessages()).toEqual([ @@ -622,9 +642,7 @@ describe(' create route', () => { form.setInputValue('jiraIssueTypeInput', ISSUE_TYPE); form.setInputValue('jiraSummaryInput', SUMMARY); - await act(async () => { - actions.clickSimulateButton(); - }); + await actions.clickSimulateButton(); const thresholdWatch = { id: WATCH_ID, @@ -688,8 +706,8 @@ describe(' create route', () => { const DESCRIPTION = 'test pagerduty description'; - actions.clickAddActionButton(); - actions.clickActionLink('pagerduty'); + await actions.clickAddActionButton(); + await actions.clickActionLink('pagerduty'); expect(exists('watchActionAccordion')).toBe(true); @@ -702,9 +720,7 @@ describe(' create route', () => { // Next, provide valid fields and verify form.setInputValue('pagerdutyDescriptionInput', DESCRIPTION); - await act(async () => { - actions.clickSimulateButton(); - }); + await actions.clickSimulateButton(); const thresholdWatch = { id: WATCH_ID, @@ -757,7 +773,6 @@ describe(' create route', () => { describe('watch visualize data payload', () => { test('should send the correct payload', async () => { const { form, find, component } = testBed; - // Set up required fields await act(async () => { form.setInputValue('nameInput', WATCH_NAME); @@ -807,9 +822,7 @@ describe(' create route', () => { }); component.update(); - await act(async () => { - actions.clickSubmitButton(); - }); + await actions.clickSubmitButton(); expect(httpSetup.put).toHaveBeenLastCalledWith( `${API_BASE_PATH}/watch/${WATCH_ID}`, diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_edit_page.test.tsx b/x-pack/plugins/watcher/__jest__/client_integration/watch_edit_page.test.tsx index ba38fbd5b3cc7..b00f9916970b9 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_edit_page.test.tsx +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_edit_page.test.tsx @@ -39,7 +39,7 @@ describe('', () => { let testBed: WatchEditTestBed; beforeAll(() => { - jest.useFakeTimers({ legacyFakeTimers: true }); + jest.useFakeTimers(); }); afterAll(() => { @@ -50,7 +50,10 @@ describe('', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadWatchResponse(WATCH_ID, WATCH); - testBed = await setup(httpSetup); + await act(async () => { + testBed = await setup(httpSetup); + }); + testBed.component.update(); }); @@ -82,9 +85,7 @@ describe('', () => { form.setInputValue('nameInput', EDITED_WATCH_NAME); - await act(async () => { - actions.clickSubmitButton(); - }); + await actions.clickSubmitButton(); const DEFAULT_LOGGING_ACTION_ID = 'logging_1'; const DEFAULT_LOGGING_ACTION_TYPE = 'logging'; @@ -137,7 +138,10 @@ describe('', () => { beforeEach(async () => { httpRequestsMockHelpers.setLoadWatchResponse(WATCH_ID, { watch }); - testBed = await setup(httpSetup); + await act(async () => { + testBed = await setup(httpSetup); + }); + testBed.component.update(); }); @@ -162,9 +166,7 @@ describe('', () => { form.setInputValue('nameInput', EDITED_WATCH_NAME); - await act(async () => { - actions.clickSubmitButton(); - }); + await actions.clickSubmitButton(); const { id, diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_list_page.test.ts b/x-pack/plugins/watcher/__jest__/client_integration/watch_list_page.test.ts index c9116f45c9314..8eacd4841c666 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_list_page.test.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_list_page.test.ts @@ -18,7 +18,7 @@ describe('', () => { let testBed: WatchListTestBed; beforeAll(() => { - jest.useFakeTimers({ legacyFakeTimers: true }); + jest.useFakeTimers(); }); afterAll(() => { @@ -79,7 +79,7 @@ describe('', () => { test('should show error callout if search is invalid', async () => { const { exists, actions } = testBed; - actions.searchWatches('or'); + await actions.searchWatches('or'); expect(exists('watcherListSearchError')).toBe(true); }); @@ -87,7 +87,7 @@ describe('', () => { test('should retain the search query', async () => { const { table, actions } = testBed; - actions.searchWatches(watch1.name); + await actions.searchWatches(watch1.name); const { tableCellsValues } = table.getMetaData('watchesTable'); diff --git a/x-pack/plugins/watcher/__jest__/client_integration/watch_status_page.test.ts b/x-pack/plugins/watcher/__jest__/client_integration/watch_status_page.test.ts index 20b503d82ad1d..d40015776065f 100644 --- a/x-pack/plugins/watcher/__jest__/client_integration/watch_status_page.test.ts +++ b/x-pack/plugins/watcher/__jest__/client_integration/watch_status_page.test.ts @@ -45,7 +45,7 @@ describe('', () => { let testBed: WatchStatusTestBed; beforeAll(() => { - jest.useFakeTimers({ legacyFakeTimers: true }); + jest.useFakeTimers(); }); afterAll(() => { @@ -57,7 +57,9 @@ describe('', () => { httpRequestsMockHelpers.setLoadWatchResponse(WATCH_ID, { watch }); httpRequestsMockHelpers.setLoadWatchHistoryResponse(WATCH_ID, watchHistoryItems); - testBed = await setup(httpSetup); + await act(async () => { + testBed = await setup(httpSetup); + }); testBed.component.update(); }); @@ -75,13 +77,13 @@ describe('', () => { expect(find('tab').map((t) => t.text())).toEqual(['Execution history', 'Action statuses']); }); - test('should navigate to the "Action statuses" tab', () => { + test('should navigate to the "Action statuses" tab', async () => { const { exists, actions } = testBed; expect(exists('watchHistorySection')).toBe(true); expect(exists('watchDetailSection')).toBe(false); - actions.selectTab('action statuses'); + await actions.selectTab('action statuses'); expect(exists('watchHistorySection')).toBe(false); expect(exists('watchDetailSection')).toBe(true); @@ -222,10 +224,10 @@ describe('', () => { }); describe('action statuses', () => { - beforeEach(() => { + beforeEach(async () => { const { actions } = testBed; - actions.selectTab('action statuses'); + await actions.selectTab('action statuses'); }); test('should list the watch actions in a table', () => { From 6673e9dc59f8199b5eea8531a924b51a09622b58 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 9 Aug 2023 18:32:46 +0100 Subject: [PATCH 24/41] [ML] Fixing capabilites polling in manage page (#163399) On ML's management page a new capabilities poll is created every time the user changes tabs. `getMlGlobalServices` gets called every time the jobs list renders, which creates a new `MlCapabilitiesService` which creates a new timer to poll for ml's capabilities. This change moves the `mlServices` so it isn't called on each render. It also bumps up the interval from 1 min to 5 mins as think 1 min is a bit too frequent. --- .../public/application/capabilities/check_capabilities.ts | 2 +- .../jobs_list/components/jobs_list_page/jobs_list_page.tsx | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/public/application/capabilities/check_capabilities.ts b/x-pack/plugins/ml/public/application/capabilities/check_capabilities.ts index 72a6100c15a7c..c5325f4aa7614 100644 --- a/x-pack/plugins/ml/public/application/capabilities/check_capabilities.ts +++ b/x-pack/plugins/ml/public/application/capabilities/check_capabilities.ts @@ -24,7 +24,7 @@ import { type MlApiServices } from '../services/ml_api_service'; let _capabilities: MlCapabilities = getDefaultCapabilities(); -const CAPABILITIES_REFRESH_INTERVAL = 60000; +const CAPABILITIES_REFRESH_INTERVAL = 5 * 60 * 1000; // 5min; export class MlCapabilitiesService { private _isLoading$ = new BehaviorSubject(true); diff --git a/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx b/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx index e4b79eafb896d..6941e53cd68b2 100644 --- a/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx +++ b/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx @@ -70,6 +70,11 @@ export const JobsListPage: FC<{ const I18nContext = coreStart.i18n.Context; const theme$ = coreStart.theme.theme$; + const mlServices = useMemo( + () => getMlGlobalServices(coreStart.http, usageCollection), + [coreStart.http, usageCollection] + ); + const check = async () => { try { await checkGetManagementMlJobsResolver(mlApiServices); @@ -122,7 +127,7 @@ export const JobsListPage: FC<{ usageCollection, fieldFormats, spacesApi, - mlServices: getMlGlobalServices(coreStart.http, usageCollection), + mlServices, }} > From 4637b744d80686a2f9cbdfaf2f8b24a0c92f79c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Wed, 9 Aug 2023 20:02:11 +0200 Subject: [PATCH 25/41] Add SentinelOne connector (#159157) ## Summary Adds new connector type to support https://www.sentinelone.com/ The scope of this PR was limited to the Connector logic, schemas, and types to make PR more digestible. In the current PR, the connector is NOT registered, so it's not going to be available to the users. In the follow-up PR I'm going to improve the UX of Param's form and then enable the connector Zrzut ekranu 2023-08-3 o 11 18 54 visual changes include a screenshot or gif. image image --- .github/CODEOWNERS | 5 + packages/kbn-optimizer/limits.yml | 2 +- .../event_details/flyout/use_sub_action.tsx | 43 ++ .../flyout/use_sub_action_mutation.tsx | 38 ++ .../common/sentinelone/constants.ts | 21 + .../common/sentinelone/schema.ts | 495 ++++++++++++++++++ .../common/sentinelone/types.ts | 50 ++ .../connector_types/sentinelone/index.ts | 8 + .../connector_types/sentinelone/logo.tsx | 84 +++ .../sentinelone/sentinelone.ts | 64 +++ .../sentinelone/sentinelone_connector.tsx | 47 ++ .../sentinelone/sentinelone_params.tsx | 333 ++++++++++++ .../sentinelone/translations.ts | 270 ++++++++++ .../connector_types/sentinelone/types.ts | 23 + .../connector_types/sentinelone/index.ts | 38 ++ .../connector_types/sentinelone/render.ts | 79 +++ .../sentinelone/sentinelone.ts | 276 ++++++++++ x-pack/plugins/stack_connectors/tsconfig.json | 1 + .../server/queries/oldest_idle_action_task.ts | 1 + .../server/saved_objects/index.ts | 1 + .../text_area_with_message_variables.tsx | 3 + .../public/application/lib/index.ts | 2 +- .../triggers_actions_ui/public/index.ts | 1 + 23 files changed, 1883 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action.tsx create mode 100644 x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action_mutation.tsx create mode 100644 x-pack/plugins/stack_connectors/common/sentinelone/constants.ts create mode 100644 x-pack/plugins/stack_connectors/common/sentinelone/schema.ts create mode 100644 x-pack/plugins/stack_connectors/common/sentinelone/types.ts create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/sentinelone/index.ts create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/sentinelone/logo.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone.ts create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_connector.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_params.tsx create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/sentinelone/translations.ts create mode 100644 x-pack/plugins/stack_connectors/public/connector_types/sentinelone/types.ts create mode 100644 x-pack/plugins/stack_connectors/server/connector_types/sentinelone/index.ts create mode 100644 x-pack/plugins/stack_connectors/server/connector_types/sentinelone/render.ts create mode 100644 x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 06e0d2478429f..0ba3f7fdcc32a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1146,6 +1146,11 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib /x-pack/plugins/stack_connectors/server/connector_types/gen_ai @elastic/security-threat-hunting-explore /x-pack/plugins/stack_connectors/common/gen_ai @elastic/security-threat-hunting-explore +## Defend Workflows owner connectors +/x-pack/plugins/stack_connectors/public/connector_types/sentinelone @elastic/security-defend-workflows +/x-pack/plugins/stack_connectors/server/connector_types/sentinelone @elastic/security-defend-workflows +/x-pack/plugins/stack_connectors/common/sentinelone @elastic/security-defend-workflows + ## Security Solution sub teams - Detection Rule Management /x-pack/plugins/security_solution/common/api/detection_engine/model/rule_schema @elastic/security-detection-rule-management @elastic/security-detection-engine /x-pack/plugins/security_solution/common/api/detection_engine/fleet_integrations @elastic/security-detection-rule-management diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index b08ff89b5dd09..d63b19f67f783 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -129,7 +129,7 @@ pageLoadAssetSize: snapshotRestore: 79032 spaces: 57868 stackAlerts: 58316 - stackConnectors: 36314 + stackConnectors: 52131 synthetics: 40958 telemetry: 51957 telemetryManagementSection: 38586 diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action.tsx new file mode 100644 index 0000000000000..44f9099a5b816 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { executeAction } from '@kbn/triggers-actions-ui-plugin/public'; +import { useQuery } from '@tanstack/react-query'; +import { useKibana } from '../../../../../common/lib/kibana/kibana_react'; + +export interface UseSubActionParams

    { + connectorId: string; + subAction: string; + subActionParams?: P; + disabled?: boolean; +} + +export const useSubAction = ({ + connectorId, + subAction, + subActionParams, + disabled = false, + ...rest +}: UseSubActionParams

    ) => { + const { http } = useKibana().services; + + return useQuery({ + queryKey: ['useSubAction', connectorId, subAction, subActionParams], + queryFn: ({ signal }) => + executeAction({ + id: connectorId, + params: { + subAction, + subActionParams, + }, + http, + signal, + }), + enabled: !disabled && !!connectorId && !!subAction, + ...rest, + }); +}; diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action_mutation.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action_mutation.tsx new file mode 100644 index 0000000000000..78c48ccca1491 --- /dev/null +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/event_details/flyout/use_sub_action_mutation.tsx @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { executeAction } from '@kbn/triggers-actions-ui-plugin/public'; +import { useMutation } from '@tanstack/react-query'; +import { useKibana } from '../../../../../common/lib/kibana/kibana_react'; + +export interface UseSubActionParams

    { + connectorId: string; + subAction: string; + subActionParams?: P; + disabled?: boolean; +} + +export const useSubActionMutation = ({ + connectorId, + subAction, + subActionParams, + disabled = false, +}: UseSubActionParams

    ) => { + const { http } = useKibana().services; + + return useMutation({ + mutationFn: () => + executeAction({ + id: connectorId, + params: { + subAction, + subActionParams, + }, + http, + }), + }); +}; diff --git a/x-pack/plugins/stack_connectors/common/sentinelone/constants.ts b/x-pack/plugins/stack_connectors/common/sentinelone/constants.ts new file mode 100644 index 0000000000000..a77e070a71056 --- /dev/null +++ b/x-pack/plugins/stack_connectors/common/sentinelone/constants.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const SENTINELONE_TITLE = 'Sentinel One'; +export const SENTINELONE_CONNECTOR_ID = '.sentinelone'; +export const API_MAX_RESULTS = 1000; + +export enum SUB_ACTION { + KILL_PROCESS = 'killProcess', + EXECUTE_SCRIPT = 'executeScript', + GET_AGENTS = 'getAgents', + ISOLATE_AGENT = 'isolateAgent', + RELEASE_AGENT = 'releaseAgent', + GET_REMOTE_SCRIPTS = 'getRemoteScripts', + GET_REMOTE_SCRIPT_STATUS = 'getRemoteScriptStatus', + GET_REMOTE_SCRIPT_RESULTS = 'getRemoteScriptResults', +} diff --git a/x-pack/plugins/stack_connectors/common/sentinelone/schema.ts b/x-pack/plugins/stack_connectors/common/sentinelone/schema.ts new file mode 100644 index 0000000000000..f475a9e6a83f6 --- /dev/null +++ b/x-pack/plugins/stack_connectors/common/sentinelone/schema.ts @@ -0,0 +1,495 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* eslint-disable @typescript-eslint/naming-convention */ + +import { schema } from '@kbn/config-schema'; +import { SUB_ACTION } from './constants'; + +// Connector schema +export const SentinelOneConfigSchema = schema.object({ url: schema.string() }); +export const SentinelOneSecretsSchema = schema.object({ + token: schema.string(), +}); + +export const SentinelOneBaseApiResponseSchema = schema.object({}, { unknowns: 'allow' }); + +export const SentinelOneGetAgentsResponseSchema = schema.object({ + pagination: schema.object({ + totalItems: schema.number(), + nextCursor: schema.nullable(schema.string()), + }), + errors: schema.nullable(schema.arrayOf(schema.string())), + data: schema.arrayOf( + schema.object({ + modelName: schema.string(), + firewallEnabled: schema.boolean(), + totalMemory: schema.number(), + osName: schema.string(), + cloudProviders: schema.recordOf(schema.string(), schema.any()), + siteName: schema.string(), + cpuId: schema.string(), + isPendingUninstall: schema.boolean(), + isUpToDate: schema.boolean(), + osArch: schema.string(), + accountId: schema.string(), + locationEnabled: schema.boolean(), + consoleMigrationStatus: schema.string(), + scanFinishedAt: schema.nullable(schema.string()), + operationalStateExpiration: schema.nullable(schema.string()), + agentVersion: schema.string(), + isActive: schema.boolean(), + locationType: schema.string(), + activeThreats: schema.number(), + inRemoteShellSession: schema.boolean(), + allowRemoteShell: schema.boolean(), + serialNumber: schema.nullable(schema.string()), + updatedAt: schema.string(), + lastActiveDate: schema.string(), + firstFullModeTime: schema.nullable(schema.string()), + operationalState: schema.string(), + externalId: schema.string(), + mitigationModeSuspicious: schema.string(), + licenseKey: schema.string(), + cpuCount: schema.number(), + mitigationMode: schema.string(), + networkStatus: schema.string(), + installerType: schema.string(), + uuid: schema.string(), + detectionState: schema.nullable(schema.string()), + infected: schema.boolean(), + registeredAt: schema.string(), + lastIpToMgmt: schema.string(), + storageName: schema.nullable(schema.string()), + osUsername: schema.string(), + groupIp: schema.string(), + createdAt: schema.string(), + remoteProfilingState: schema.string(), + groupUpdatedAt: schema.nullable(schema.string()), + scanAbortedAt: schema.nullable(schema.string()), + isUninstalled: schema.boolean(), + networkQuarantineEnabled: schema.boolean(), + tags: schema.object({ + sentinelone: schema.arrayOf( + schema.object({ + assignedBy: schema.string(), + assignedAt: schema.string(), + assignedById: schema.string(), + key: schema.string(), + value: schema.string(), + id: schema.string(), + }) + ), + }), + externalIp: schema.string(), + siteId: schema.string(), + machineType: schema.string(), + domain: schema.string(), + scanStatus: schema.string(), + osStartTime: schema.string(), + accountName: schema.string(), + lastLoggedInUserName: schema.string(), + showAlertIcon: schema.boolean(), + rangerStatus: schema.string(), + groupName: schema.string(), + threatRebootRequired: schema.boolean(), + remoteProfilingStateExpiration: schema.nullable(schema.string()), + policyUpdatedAt: schema.nullable(schema.string()), + activeDirectory: schema.object({ + userPrincipalName: schema.nullable(schema.string()), + lastUserDistinguishedName: schema.nullable(schema.string()), + computerMemberOf: schema.arrayOf(schema.object({ type: schema.string() })), + lastUserMemberOf: schema.arrayOf(schema.object({ type: schema.string() })), + mail: schema.nullable(schema.string()), + computerDistinguishedName: schema.nullable(schema.string()), + }), + isDecommissioned: schema.boolean(), + rangerVersion: schema.string(), + userActionsNeeded: schema.arrayOf( + schema.object({ + type: schema.string(), + example: schema.string(), + enum: schema.arrayOf(schema.string()), + }) + ), + locations: schema.nullable( + schema.arrayOf( + schema.object({ name: schema.string(), scope: schema.string(), id: schema.string() }) + ) + ), + id: schema.string(), + coreCount: schema.number(), + osRevision: schema.string(), + osType: schema.string(), + groupId: schema.string(), + computerName: schema.string(), + scanStartedAt: schema.string(), + encryptedApplications: schema.boolean(), + storageType: schema.nullable(schema.string()), + networkInterfaces: schema.arrayOf( + schema.object({ + gatewayMacAddress: schema.nullable(schema.string()), + inet6: schema.arrayOf(schema.string()), + name: schema.string(), + inet: schema.arrayOf(schema.string()), + physical: schema.string(), + gatewayIp: schema.nullable(schema.string()), + id: schema.string(), + }) + ), + fullDiskScanLastUpdatedAt: schema.string(), + appsVulnerabilityStatus: schema.string(), + }) + ), +}); + +export const SentinelOneIsolateAgentResponseSchema = schema.object({ + errors: schema.nullable(schema.arrayOf(schema.string())), + data: schema.object({ + affected: schema.number(), + }), +}); + +export const SentinelOneGetRemoteScriptsParamsSchema = schema.object({ + query: schema.nullable(schema.string()), + osTypes: schema.nullable(schema.arrayOf(schema.string())), +}); + +export const SentinelOneGetRemoteScriptsResponseSchema = schema.object({ + errors: schema.nullable(schema.arrayOf(schema.string())), + pagination: schema.object({ + nextCursor: schema.nullable(schema.string()), + totalItems: schema.number(), + }), + data: schema.arrayOf( + schema.object({ + id: schema.string(), + updater: schema.nullable(schema.string()), + isAvailableForLite: schema.boolean(), + isAvailableForArs: schema.boolean(), + fileSize: schema.number(), + mgmtId: schema.number(), + scopeLevel: schema.string(), + shortFileName: schema.string(), + scriptName: schema.string(), + creator: schema.string(), + package: schema.nullable( + schema.object({ + id: schema.string(), + bucketName: schema.string(), + endpointExpiration: schema.string(), + fileName: schema.string(), + endpointExpirationSeconds: schema.nullable(schema.number()), + fileSize: schema.number(), + signatureType: schema.string(), + signature: schema.string(), + }) + ), + bucketName: schema.string(), + inputRequired: schema.boolean(), + fileName: schema.string(), + supportedDestinations: schema.nullable(schema.arrayOf(schema.string())), + scopeName: schema.nullable(schema.string()), + signatureType: schema.string(), + outputFilePaths: schema.nullable(schema.arrayOf(schema.string())), + scriptDescription: schema.nullable(schema.string()), + createdByUserId: schema.string(), + scopeId: schema.string(), + updatedAt: schema.string(), + scriptType: schema.string(), + scopePath: schema.string(), + creatorId: schema.string(), + osTypes: schema.arrayOf(schema.string()), + scriptRuntimeTimeoutSeconds: schema.number(), + version: schema.string(), + updaterId: schema.nullable(schema.string()), + createdAt: schema.string(), + inputExample: schema.nullable(schema.string()), + inputInstructions: schema.nullable(schema.string()), + signature: schema.string(), + createdByUser: schema.string(), + requiresApproval: schema.maybe(schema.boolean()), + }) + ), +}); + +export const SentinelOneExecuteScriptParamsSchema = schema.object({ + computerName: schema.maybe(schema.string()), + script: schema.object({ + scriptId: schema.string(), + scriptName: schema.maybe(schema.string()), + apiKey: schema.maybe(schema.string()), + outputDirectory: schema.maybe(schema.string()), + requiresApproval: schema.maybe(schema.boolean()), + taskDescription: schema.maybe(schema.string()), + singularityxdrUrl: schema.maybe(schema.string()), + inputParams: schema.maybe(schema.string()), + singularityxdrKeyword: schema.maybe(schema.string()), + scriptRuntimeTimeoutSeconds: schema.maybe(schema.number()), + passwordFromScope: schema.maybe( + schema.object({ + scopeLevel: schema.maybe(schema.string()), + scopeId: schema.maybe(schema.string()), + }) + ), + password: schema.maybe(schema.string()), + }), +}); + +export const SentinelOneGetRemoteScriptStatusParamsSchema = schema.object( + { + parentTaskId: schema.string(), + }, + { unknowns: 'allow' } +); + +export const SentinelOneGetRemoteScriptStatusResponseSchema = schema.object({ + pagination: schema.object({ + totalItems: schema.number(), + nextCursor: schema.nullable(schema.string()), + }), + errors: schema.arrayOf(schema.object({ type: schema.string() })), + data: schema.arrayOf( + schema.object({ + agentIsDecommissioned: schema.boolean(), + agentComputerName: schema.string(), + status: schema.string(), + groupName: schema.string(), + initiatedById: schema.string(), + parentTaskId: schema.string(), + updatedAt: schema.string(), + createdAt: schema.string(), + agentIsActive: schema.boolean(), + agentOsType: schema.string(), + agentMachineType: schema.string(), + id: schema.string(), + siteName: schema.string(), + detailedStatus: schema.string(), + siteId: schema.string(), + scriptResultsSignature: schema.nullable(schema.string()), + initiatedBy: schema.string(), + accountName: schema.string(), + groupId: schema.string(), + statusDescription: schema.object({ + readOnly: schema.boolean(), + description: schema.string(), + }), + agentUuid: schema.string(), + accountId: schema.string(), + type: schema.string(), + scriptResultsPath: schema.string(), + scriptResultsBucket: schema.string(), + description: schema.string(), + agentId: schema.string(), + }) + ), +}); + +export const SentinelOneBaseFilterSchema = schema.object({ + K8SNodeName__contains: schema.nullable(schema.string()), + coreCount__lt: schema.nullable(schema.string()), + rangerStatuses: schema.nullable(schema.string()), + adUserQuery__contains: schema.nullable(schema.string()), + rangerVersionsNin: schema.nullable(schema.string()), + rangerStatusesNin: schema.nullable(schema.string()), + coreCount__gte: schema.nullable(schema.string()), + threatCreatedAt__gte: schema.nullable(schema.string()), + decommissionedAt__lte: schema.nullable(schema.string()), + operationalStatesNin: schema.nullable(schema.string()), + appsVulnerabilityStatusesNin: schema.nullable(schema.string()), + mitigationMode: schema.nullable(schema.string()), + createdAt__gte: schema.nullable(schema.string()), + gatewayIp: schema.nullable(schema.string()), + cloudImage__contains: schema.nullable(schema.string()), + registeredAt__between: schema.nullable(schema.string()), + threatMitigationStatus: schema.nullable(schema.string()), + installerTypesNin: schema.nullable(schema.string()), + appsVulnerabilityStatuses: schema.nullable(schema.string()), + threatResolved: schema.nullable(schema.string()), + mitigationModeSuspicious: schema.nullable(schema.string()), + isUpToDate: schema.nullable(schema.string()), + adComputerQuery__contains: schema.nullable(schema.string()), + updatedAt__gte: schema.nullable(schema.string()), + azureResourceGroup__contains: schema.nullable(schema.string()), + scanStatus: schema.nullable(schema.string()), + threatContentHash: schema.nullable(schema.string()), + osTypesNin: schema.nullable(schema.string()), + threatRebootRequired: schema.nullable(schema.string()), + totalMemory__between: schema.nullable(schema.string()), + firewallEnabled: schema.nullable(schema.string()), + gcpServiceAccount__contains: schema.nullable(schema.string()), + updatedAt__gt: schema.nullable(schema.string()), + remoteProfilingStates: schema.nullable(schema.string()), + filteredGroupIds: schema.nullable(schema.string()), + agentVersions: schema.nullable(schema.string()), + activeThreats: schema.nullable(schema.string()), + machineTypesNin: schema.nullable(schema.string()), + lastActiveDate__gt: schema.nullable(schema.string()), + awsSubnetIds__contains: schema.nullable(schema.string()), + installerTypes: schema.nullable(schema.string()), + registeredAt__gte: schema.nullable(schema.string()), + migrationStatus: schema.nullable(schema.string()), + cloudTags__contains: schema.nullable(schema.string()), + totalMemory__gte: schema.nullable(schema.string()), + decommissionedAt__lt: schema.nullable(schema.string()), + threatCreatedAt__lt: schema.nullable(schema.string()), + updatedAt__lte: schema.nullable(schema.string()), + osArch: schema.nullable(schema.string()), + registeredAt__gt: schema.nullable(schema.string()), + registeredAt__lt: schema.nullable(schema.string()), + siteIds: schema.nullable(schema.string()), + networkInterfaceInet__contains: schema.nullable(schema.string()), + groupIds: schema.nullable(schema.string()), + uuids: schema.nullable(schema.string()), + accountIds: schema.nullable(schema.string()), + scanStatusesNin: schema.nullable(schema.string()), + cpuCount__lte: schema.nullable(schema.string()), + locationIds: schema.nullable(schema.string()), + awsSecurityGroups__contains: schema.nullable(schema.string()), + networkStatusesNin: schema.nullable(schema.string()), + activeThreats__gt: schema.nullable(schema.string()), + infected: schema.nullable(schema.string()), + osVersion__contains: schema.nullable(schema.string()), + machineTypes: schema.nullable(schema.string()), + agentPodName__contains: schema.nullable(schema.string()), + computerName__like: schema.nullable(schema.string()), + threatCreatedAt__gt: schema.nullable(schema.string()), + consoleMigrationStatusesNin: schema.nullable(schema.string()), + computerName: schema.nullable(schema.string()), + decommissionedAt__between: schema.nullable(schema.string()), + cloudInstanceId__contains: schema.nullable(schema.string()), + createdAt__lte: schema.nullable(schema.string()), + coreCount__between: schema.nullable(schema.string()), + totalMemory__lte: schema.nullable(schema.string()), + remoteProfilingStatesNin: schema.nullable(schema.string()), + adComputerMember__contains: schema.nullable(schema.string()), + threatCreatedAt__between: schema.nullable(schema.string()), + totalMemory__gt: schema.nullable(schema.string()), + ids: schema.nullable(schema.string()), + agentVersionsNin: schema.nullable(schema.string()), + updatedAt__between: schema.nullable(schema.string()), + locationEnabled: schema.nullable(schema.string()), + locationIdsNin: schema.nullable(schema.string()), + osTypes: schema.nullable(schema.string()), + encryptedApplications: schema.nullable(schema.string()), + filterId: schema.nullable(schema.string()), + decommissionedAt__gt: schema.nullable(schema.string()), + adUserMember__contains: schema.nullable(schema.string()), + uuid: schema.nullable(schema.string()), + coreCount__lte: schema.nullable(schema.string()), + coreCount__gt: schema.nullable(schema.string()), + cloudNetwork__contains: schema.nullable(schema.string()), + clusterName__contains: schema.nullable(schema.string()), + cpuCount__gte: schema.nullable(schema.string()), + query: schema.nullable(schema.string()), + lastActiveDate__between: schema.nullable(schema.string()), + rangerStatus: schema.nullable(schema.string()), + domains: schema.nullable(schema.string()), + cloudProvider: schema.nullable(schema.string()), + lastActiveDate__lt: schema.nullable(schema.string()), + scanStatuses: schema.nullable(schema.string()), + hasLocalConfiguration: schema.nullable(schema.string()), + networkStatuses: schema.nullable(schema.string()), + isPendingUninstall: schema.nullable(schema.string()), + createdAt__gt: schema.nullable(schema.string()), + cpuCount__lt: schema.nullable(schema.string()), + consoleMigrationStatuses: schema.nullable(schema.string()), + adQuery: schema.nullable(schema.string()), + updatedAt__lt: schema.nullable(schema.string()), + createdAt__lt: schema.nullable(schema.string()), + adComputerName__contains: schema.nullable(schema.string()), + cloudInstanceSize__contains: schema.nullable(schema.string()), + registeredAt__lte: schema.nullable(schema.string()), + networkQuarantineEnabled: schema.nullable(schema.string()), + cloudAccount__contains: schema.nullable(schema.string()), + cloudLocation__contains: schema.nullable(schema.string()), + rangerVersions: schema.nullable(schema.string()), + networkInterfaceGatewayMacAddress__contains: schema.nullable(schema.string()), + uuid__contains: schema.nullable(schema.string()), + agentNamespace__contains: schema.nullable(schema.string()), + K8SNodeLabels__contains: schema.nullable(schema.string()), + adQuery__contains: schema.nullable(schema.string()), + K8SType__contains: schema.nullable(schema.string()), + countsFor: schema.nullable(schema.string()), + totalMemory__lt: schema.nullable(schema.string()), + externalId__contains: schema.nullable(schema.string()), + filteredSiteIds: schema.nullable(schema.string()), + decommissionedAt__gte: schema.nullable(schema.string()), + cpuCount__gt: schema.nullable(schema.string()), + threatHidden: schema.nullable(schema.string()), + isUninstalled: schema.nullable(schema.string()), + computerName__contains: schema.nullable(schema.string()), + lastActiveDate__lte: schema.nullable(schema.string()), + adUserName__contains: schema.nullable(schema.string()), + isActive: schema.nullable(schema.string()), + userActionsNeeded: schema.nullable(schema.string()), + threatCreatedAt__lte: schema.nullable(schema.string()), + domainsNin: schema.nullable(schema.string()), + operationalStates: schema.nullable(schema.string()), + externalIp__contains: schema.nullable(schema.string()), + isDecommissioned: schema.nullable(schema.string()), + networkInterfacePhysical__contains: schema.nullable(schema.string()), + lastActiveDate__gte: schema.nullable(schema.string()), + createdAt__between: schema.nullable(schema.string()), + cpuCount__between: schema.nullable(schema.string()), + lastLoggedInUserName__contains: schema.nullable(schema.string()), + awsRole__contains: schema.nullable(schema.string()), + K8SVersion__contains: schema.nullable(schema.string()), +}); + +export const SentinelOneKillProcessParamsSchema = SentinelOneBaseFilterSchema.extends({ + processName: schema.string(), +}); + +export const SentinelOneIsolateAgentParamsSchema = SentinelOneBaseFilterSchema; + +export const SentinelOneGetAgentsParamsSchema = SentinelOneBaseFilterSchema; + +export const SentinelOneGetRemoteScriptsStatusParams = schema.object({ + parentTaskId: schema.string(), +}); + +export const SentinelOneExecuteScriptResponseSchema = schema.object({ + errors: schema.nullable(schema.arrayOf(schema.object({}, { unknowns: 'allow' }))), + data: schema.nullable( + schema.object({ + pendingExecutionId: schema.nullable(schema.string()), + affected: schema.nullable(schema.number()), + parentTaskId: schema.nullable(schema.string()), + pending: schema.nullable(schema.boolean()), + }) + ), +}); + +export const SentinelOneKillProcessResponseSchema = SentinelOneExecuteScriptResponseSchema; + +export const SentinelOneKillProcessSchema = schema.object({ + subAction: schema.literal(SUB_ACTION.KILL_PROCESS), + subActionParams: SentinelOneKillProcessParamsSchema, +}); + +export const SentinelOneIsolateAgentSchema = schema.object({ + subAction: schema.literal(SUB_ACTION.ISOLATE_AGENT), + subActionParams: SentinelOneIsolateAgentParamsSchema, +}); + +export const SentinelOneReleaseAgentSchema = schema.object({ + subAction: schema.literal(SUB_ACTION.RELEASE_AGENT), + subActionParams: SentinelOneIsolateAgentParamsSchema, +}); + +export const SentinelOneExecuteScriptSchema = schema.object({ + subAction: schema.literal(SUB_ACTION.EXECUTE_SCRIPT), + subActionParams: SentinelOneExecuteScriptParamsSchema, +}); + +export const SentinelOneActionParamsSchema = schema.oneOf([ + SentinelOneKillProcessSchema, + SentinelOneIsolateAgentSchema, + SentinelOneReleaseAgentSchema, + SentinelOneExecuteScriptSchema, +]); diff --git a/x-pack/plugins/stack_connectors/common/sentinelone/types.ts b/x-pack/plugins/stack_connectors/common/sentinelone/types.ts new file mode 100644 index 0000000000000..ab50e316d03f7 --- /dev/null +++ b/x-pack/plugins/stack_connectors/common/sentinelone/types.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { TypeOf } from '@kbn/config-schema'; +import { + SentinelOneBaseApiResponseSchema, + SentinelOneConfigSchema, + SentinelOneExecuteScriptParamsSchema, + SentinelOneGetAgentsParamsSchema, + SentinelOneGetAgentsResponseSchema, + SentinelOneGetRemoteScriptsParamsSchema, + SentinelOneGetRemoteScriptsResponseSchema, + SentinelOneGetRemoteScriptsStatusParams, + SentinelOneIsolateAgentParamsSchema, + SentinelOneKillProcessParamsSchema, + SentinelOneSecretsSchema, + SentinelOneActionParamsSchema, +} from './schema'; + +export type SentinelOneConfig = TypeOf; +export type SentinelOneSecrets = TypeOf; + +export type SentinelOneBaseApiResponse = TypeOf; + +export type SentinelOneGetAgentsParams = TypeOf; +export type SentinelOneGetAgentsResponse = TypeOf; + +export type SentinelOneKillProcessParams = TypeOf; + +export type SentinelOneExecuteScriptParams = TypeOf; + +export type SentinelOneGetRemoteScriptStatusParams = TypeOf< + typeof SentinelOneGetRemoteScriptsStatusParams +>; + +export type SentinelOneGetRemoteScriptsParams = TypeOf< + typeof SentinelOneGetRemoteScriptsParamsSchema +>; + +export type SentinelOneGetRemoteScriptsResponse = TypeOf< + typeof SentinelOneGetRemoteScriptsResponseSchema +>; + +export type SentinelOneIsolateAgentParams = TypeOf; + +export type SentinelOneActionParams = TypeOf; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/index.ts b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/index.ts new file mode 100644 index 0000000000000..7bb5159f87525 --- /dev/null +++ b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { getConnectorType as getSentinelOneConnectorType } from './sentinelone'; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/logo.tsx b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/logo.tsx new file mode 100644 index 0000000000000..656e75d07d67c --- /dev/null +++ b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/logo.tsx @@ -0,0 +1,84 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +const Logo = () => ( + + + + + + + + + + + + + + + + + + + + +); + +// eslint-disable-next-line import/no-default-export +export { Logo as default }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone.ts b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone.ts new file mode 100644 index 0000000000000..469613621bf05 --- /dev/null +++ b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { lazy } from 'react'; +import { i18n } from '@kbn/i18n'; +import type { + ActionTypeModel as ConnectorTypeModel, + GenericValidationResult, +} from '@kbn/triggers-actions-ui-plugin/public'; +import { + SENTINELONE_CONNECTOR_ID, + SENTINELONE_TITLE, + SUB_ACTION, +} from '../../../common/sentinelone/constants'; +import type { + SentinelOneConfig, + SentinelOneSecrets, + SentinelOneActionParams, +} from '../../../common/sentinelone/types'; + +interface ValidationErrors { + subAction: string[]; +} + +export function getConnectorType(): ConnectorTypeModel< + SentinelOneConfig, + SentinelOneSecrets, + SentinelOneActionParams +> { + return { + id: SENTINELONE_CONNECTOR_ID, + actionTypeTitle: SENTINELONE_TITLE, + iconClass: lazy(() => import('./logo')), + selectMessage: i18n.translate( + 'xpack.stackConnectors.security.sentinelone.config.selectMessageText', + { + defaultMessage: 'Execute SentinelOne scripts', + } + ), + validateParams: async ( + actionParams: SentinelOneActionParams + ): Promise> => { + const translations = await import('./translations'); + const errors: ValidationErrors = { + subAction: [], + }; + const { subAction } = actionParams; + + // The internal "subAction" param should always be valid, ensure it is only if "subActionParams" are valid + if (!subAction) { + errors.subAction.push(translations.ACTION_REQUIRED); + } else if (!(subAction in SUB_ACTION)) { + errors.subAction.push(translations.INVALID_ACTION); + } + return { errors }; + }, + actionConnectorFields: lazy(() => import('./sentinelone_connector')), + actionParamsFields: lazy(() => import('./sentinelone_params')), + }; +} diff --git a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_connector.tsx b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_connector.tsx new file mode 100644 index 0000000000000..785dc5d05832d --- /dev/null +++ b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_connector.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { + ActionConnectorFieldsProps, + ConfigFieldSchema, + SecretsFieldSchema, + SimpleConnectorForm, +} from '@kbn/triggers-actions-ui-plugin/public'; +import * as i18n from './translations'; + +const configFormSchema: ConfigFieldSchema[] = [ + { + id: 'url', + label: i18n.URL_LABEL, + isUrlField: true, + }, +]; + +const secretsFormSchema: SecretsFieldSchema[] = [ + { + id: 'token', + label: i18n.TOKEN_LABEL, + isPasswordField: true, + }, +]; + +const SentinelOneActionConnectorFields: React.FunctionComponent = ({ + readOnly, + isEdit, +}) => ( + +); + +// eslint-disable-next-line import/no-default-export +export { SentinelOneActionConnectorFields as default }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_params.tsx b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_params.tsx new file mode 100644 index 0000000000000..f74e1c897b97b --- /dev/null +++ b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/sentinelone_params.tsx @@ -0,0 +1,333 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useCallback, useEffect, useMemo, useState, ReactNode } from 'react'; +import { reduce } from 'lodash'; +import { + EuiButtonIcon, + EuiComboBox, + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiInMemoryTable, + EuiSuperSelect, +} from '@elastic/eui'; +import { + ActionConnectorMode, + ActionParamsProps, + TextAreaWithMessageVariables, +} from '@kbn/triggers-actions-ui-plugin/public'; +import { useSubAction, useKibana } from '@kbn/triggers-actions-ui-plugin/public'; +import { EuiBasicTableColumn, EuiSearchBarProps, EuiLink } from '@elastic/eui'; +import { SUB_ACTION } from '../../../common/sentinelone/constants'; +import type { + SentinelOneGetAgentsParams, + SentinelOneGetAgentsResponse, + SentinelOneGetRemoteScriptsParams, + SentinelOneGetRemoteScriptsResponse, + SentinelOneActionParams, +} from '../../../common/sentinelone/types'; +import type { SentinelOneExecuteSubActionParams } from './types'; +import * as i18n from './translations'; + +type ScriptOption = SentinelOneGetRemoteScriptsResponse['data'][0]; + +const SentinelOneParamsFields: React.FunctionComponent< + ActionParamsProps +> = ({ actionConnector, actionParams, editAction, index, executionMode, errors, ...rest }) => { + const { toasts } = useKibana().notifications; + const { subAction, subActionParams } = actionParams; + const [selectedScript, setSelectedScript] = useState(); + + const [selectedAgent, setSelectedAgent] = useState>(() => { + if (subActionParams?.computerName) { + return [{ label: subActionParams?.computerName }]; + } + return []; + }); + const [connectorId] = useState(actionConnector?.id); + + const isTest = useMemo(() => executionMode === ActionConnectorMode.Test, [executionMode]); + + const editSubActionParams = useCallback( + (params: Partial) => { + editAction('subActionParams', { ...subActionParams, ...params }, index); + }, + [editAction, index, subActionParams] + ); + + const { + response: { data: agents } = {}, + isLoading: isLoadingAgents, + error: agentsError, + } = useSubAction({ + connectorId, + subAction: SUB_ACTION.GET_AGENTS, + disabled: isTest, + }); + + const agentOptions = useMemo( + () => + reduce( + agents, + (acc, item) => { + acc.push({ + label: item.computerName, + }); + return acc; + }, + [] as Array<{ label: string }> + ), + [agents] + ); + + const { + response: { data: remoteScripts } = {}, + isLoading: isLoadingScripts, + error: scriptsError, + } = useSubAction({ + connectorId, + subAction: SUB_ACTION.GET_REMOTE_SCRIPTS, + }); + + useEffect(() => { + if (agentsError) { + toasts.danger({ title: i18n.AGENTS_ERROR, body: agentsError.message }); + } + if (scriptsError) { + toasts.danger({ title: i18n.REMOTE_SCRIPTS_ERROR, body: scriptsError.message }); + } + }, [toasts, scriptsError, agentsError]); + + const pagination = { + initialPageSize: 10, + pageSizeOptions: [10, 20, 50], + }; + + const search: EuiSearchBarProps = { + defaultQuery: 'scriptType:action', + box: { + incremental: true, + }, + filters: [ + { + type: 'field_value_selection', + field: 'scriptType', + name: i18n.SCRIPT_TYPE_FILTER_LABEL, + multiSelect: true, + options: [ + { + value: 'action', + }, + { value: 'dataCollection' }, + ], + }, + { + type: 'field_value_selection', + field: 'osTypes', + name: i18n.OS_TYPES_FILTER_LABEL, + multiSelect: true, + options: [ + { + value: 'Windows', + }, + { + value: 'macos', + }, + { + value: 'linux', + }, + ], + }, + ], + }; + + const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState>( + {} + ); + + const toggleDetails = (script: ScriptOption) => { + const itemIdToExpandedRowMapValues = { ...itemIdToExpandedRowMap }; + + if (script.id) { + if (itemIdToExpandedRowMapValues[script.id]) { + delete itemIdToExpandedRowMapValues[script.id]; + } else { + itemIdToExpandedRowMapValues[script.id] = <>More details true; + } + } + setItemIdToExpandedRowMap(itemIdToExpandedRowMapValues); + }; + + const columns: Array> = [ + { + field: 'scriptName', + name: 'Script name', + }, + { + field: 'scriptType', + name: 'Script type', + }, + { + field: 'osTypes', + name: 'OS types', + }, + { + actions: [ + { + name: 'Choose', + description: 'Choose this script', + isPrimary: true, + onClick: (item) => { + setSelectedScript(item); + editSubActionParams({ + script: { + scriptId: item.id, + scriptRuntimeTimeoutSeconds: 3600, + taskDescription: item.scriptName, + requiresApproval: item.requiresApproval ?? false, + }, + }); + }, + }, + ], + }, + { + align: 'right', + width: '40px', + isExpander: true, + render: (script: ScriptOption) => { + const itemIdToExpandedRowMapValues = { ...itemIdToExpandedRowMap }; + + return ( + toggleDetails(script)} + aria-label={itemIdToExpandedRowMapValues[script.id] ? 'Collapse' : 'Expand'} + iconType={itemIdToExpandedRowMapValues[script.id] ? 'arrowDown' : 'arrowRight'} + /> + ); + }, + }, + ]; + + const actionTypeOptions = [ + { + value: SUB_ACTION.KILL_PROCESS, + inputDisplay: i18n.KILL_PROCESS_ACTION_LABEL, + }, + { + value: SUB_ACTION.ISOLATE_AGENT, + inputDisplay: i18n.ISOLATE_AGENT_ACTION_LABEL, + }, + { + value: SUB_ACTION.RELEASE_AGENT, + inputDisplay: i18n.RELEASE_AGENT_ACTION_LABEL, + }, + ]; + + const handleEditSubAction = useCallback( + (payload) => { + if (subAction !== payload) { + editSubActionParams({}); + editAction('subAction', payload, index); + } + }, + [editAction, editSubActionParams, index, subAction] + ); + + return ( + + {isTest && ( + + + { + setSelectedAgent(item); + editSubActionParams({ computerName: item[0].label }); + }} + isDisabled={isLoadingAgents} + /> + + + )} + + + + + + {subAction === SUB_ACTION.EXECUTE_SCRIPT && ( + <> + + setSelectedScript(undefined)}> + {i18n.CHANGE_ACTION_LABEL} + + ) : null + } + > + {selectedScript?.scriptName ? ( + + ) : ( + + items={remoteScripts ?? []} + itemId="scriptId" + loading={isLoadingScripts} + columns={columns} + search={search} + pagination={pagination} + sorting + hasActions + itemIdToExpandedRowMap={itemIdToExpandedRowMap} + /> + )} + + + + <> + {selectedScript && ( + + + + )} + + + )} + + ); +}; + +// eslint-disable-next-line import/no-default-export +export { SentinelOneParamsFields as default }; diff --git a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/translations.ts b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/translations.ts new file mode 100644 index 0000000000000..a5b9a274857c3 --- /dev/null +++ b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/translations.ts @@ -0,0 +1,270 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { API_MAX_RESULTS } from '../../../common/sentinelone/constants'; + +// config form +export const URL_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.config.urlTextFieldLabel', + { + defaultMessage: 'SentinelOne tenant URL', + } +); + +export const TOKEN_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.config.tokenTextFieldLabel', + { + defaultMessage: 'API token', + } +); + +// params form +export const ASC = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.storyFieldLabel', + { + defaultMessage: 'SentinelOne Script', + } +); + +export const SCRIPT_TYPE_FILTER_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.scriptTypeFilterLabel', + { + defaultMessage: 'Script type', + } +); + +export const OS_TYPES_FILTER_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.osTypesFilterLabel', + { + defaultMessage: 'OS', + } +); + +export const STORY_ARIA_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.storyFieldAriaLabel', + { + defaultMessage: 'Select a SentinelOne script', + } +); + +export const KILL_PROCESS_ACTION_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.killProcessActionLabel', + { + defaultMessage: 'Kill process', + } +); + +export const ISOLATE_AGENT_ACTION_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.isolateAgentActionLabel', + { + defaultMessage: 'Isolate agent', + } +); + +export const RELEASE_AGENT_ACTION_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.releaseAgentActionLabel', + { + defaultMessage: 'Release agent', + } +); + +export const AGENTS_FIELD_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.agentsFieldLabel', + { + defaultMessage: 'SentinelOne agent', + } +); + +export const AGENTS_FIELD_PLACEHOLDER = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.agentsFieldPlaceholder', + { + defaultMessage: 'Select a single agent', + } +); + +export const ACTION_TYPE_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.actionTypeFieldLabel', + { + defaultMessage: 'Action Type', + } +); + +export const COMMAND_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.commandFieldLabel', + { + defaultMessage: 'Command', + } +); + +export const CHANGE_ACTION_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.changeActionButton', + { + defaultMessage: 'Change action', + } +); + +export const WEBHOOK_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.webhookFieldLabel', + { + defaultMessage: 'SentinelOne Webhook action', + } +); +export const WEBHOOK_HELP = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.webhookHelp', + { + defaultMessage: 'The data entry action in the story', + } +); +export const WEBHOOK_PLACEHOLDER = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.webhookPlaceholder', + { + defaultMessage: 'Select a webhook action', + } +); +export const WEBHOOK_DISABLED_PLACEHOLDER = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.webhookDisabledPlaceholder', + { + defaultMessage: 'Select a story first', + } +); +export const WEBHOOK_ARIA_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.webhookFieldAriaLabel', + { + defaultMessage: 'Select a SentinelOne webhook action', + } +); + +export const WEBHOOK_URL_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.webhookUrlFieldLabel', + { + defaultMessage: 'Webhook URL', + } +); +export const WEBHOOK_URL_FALLBACK_TITLE = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.webhookUrlFallbackTitle', + { + defaultMessage: 'SentinelOne API results limit reached', + } +); +export const WEBHOOK_URL_FALLBACK_TEXT = (entity: 'Story' | 'Webhook') => + i18n.translate('xpack.stackConnectors.security.sentinelone.params.webhookUrlFallbackText', { + values: { entity, limit: API_MAX_RESULTS }, + defaultMessage: `Not possible to retrieve more than {limit} results from the SentinelOne {entity} API. If your {entity} does not appear in the list, please fill the Webhook URL below`, + }); +export const WEBHOOK_URL_HELP = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.webhookUrlHelp', + { + defaultMessage: 'The Story and Webhook selectors will be ignored if the Webhook URL is defined', + } +); +export const WEBHOOK_URL_PLACEHOLDER = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.webhookUrlPlaceholder', + { + defaultMessage: 'Paste the Webhook URL here', + } +); +export const DISABLED_BY_WEBHOOK_URL_PLACEHOLDER = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.disabledByWebhookUrlPlaceholder', + { + defaultMessage: 'Remove the Webhook URL to use this selector', + } +); + +export const BODY_LABEL = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.bodyFieldLabel', + { + defaultMessage: 'Body', + } +); +export const AGENTS_ERROR = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.componentError.storiesRequestFailed', + { + defaultMessage: 'Error retrieving agent from SentinelOne', + } +); + +export const REMOTE_SCRIPTS_ERROR = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.componentError.remoteScriptsRequestFailed', + { + defaultMessage: 'Error retrieving remote scripts from SentinelOne', + } +); + +export const WEBHOOKS_ERROR = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.componentError.webhooksRequestFailed', + { + defaultMessage: 'Error retrieving webhook actions from SentinelOne', + } +); + +export const STORY_NOT_FOUND_WARNING = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.componentWarning.storyNotFound', + { + defaultMessage: 'Cannot find the saved story. Please select a valid story from the selector', + } +); +export const WEBHOOK_NOT_FOUND_WARNING = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.componentWarning.webhookNotFound', + { + defaultMessage: + 'Cannot find the saved webhook. Please select a valid webhook from the selector', + } +); + +export const ACTION_REQUIRED = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.error.requiredActionText', + { + defaultMessage: 'Action is required.', + } +); + +export const INVALID_ACTION = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.error.invalidActionText', + { + defaultMessage: 'Invalid action name.', + } +); + +export const BODY_REQUIRED = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.error.requiredBodyText', + { + defaultMessage: 'Body is required.', + } +); + +export const BODY_INVALID = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.error.invalidBodyText', + { + defaultMessage: 'Body does not have a valid JSON format.', + } +); + +export const STORY_REQUIRED = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.error.requiredStoryText', + { + defaultMessage: 'Story is required.', + } +); +export const WEBHOOK_REQUIRED = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.error.requiredWebhookText', + { + defaultMessage: 'Webhook is required.', + } +); +export const WEBHOOK_PATH_REQUIRED = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.error.requiredWebhookPathText', + { + defaultMessage: 'Webhook action path is missing.', + } +); +export const WEBHOOK_SECRET_REQUIRED = i18n.translate( + 'xpack.stackConnectors.security.sentinelone.params.error.requiredWebhookSecretText', + { + defaultMessage: 'Webhook action secret is missing.', + } +); diff --git a/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/types.ts b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/types.ts new file mode 100644 index 0000000000000..ac97bdaf224f4 --- /dev/null +++ b/x-pack/plugins/stack_connectors/public/connector_types/sentinelone/types.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { + SentinelOneKillProcessParams, + SentinelOneExecuteScriptParams, + SentinelOneIsolateAgentParams, +} from '../../../common/sentinelone/types'; +import type { SUB_ACTION } from '../../../common/sentinelone/constants'; + +export type SentinelOneExecuteSubActionParams = + | SentinelOneKillProcessParams + | SentinelOneExecuteScriptParams + | SentinelOneIsolateAgentParams; + +export interface SentinelOneExecuteActionParams { + subAction: SUB_ACTION; + subActionParams: SentinelOneExecuteSubActionParams; +} diff --git a/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/index.ts new file mode 100644 index 0000000000000..1ce534079e829 --- /dev/null +++ b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/index.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + SubActionConnectorType, + ValidatorType, +} from '@kbn/actions-plugin/server/sub_action_framework/types'; +import { SecurityConnectorFeatureId } from '@kbn/actions-plugin/common'; +import { urlAllowListValidator } from '@kbn/actions-plugin/server'; +import { SENTINELONE_CONNECTOR_ID, SENTINELONE_TITLE } from '../../../common/sentinelone/constants'; +import { + SentinelOneConfigSchema, + SentinelOneSecretsSchema, +} from '../../../common/sentinelone/schema'; +import { SentinelOneConfig, SentinelOneSecrets } from '../../../common/sentinelone/types'; +import { SentinelOneConnector } from './sentinelone'; +import { renderParameterTemplates } from './render'; + +export const getSentinelOneConnectorType = (): SubActionConnectorType< + SentinelOneConfig, + SentinelOneSecrets +> => ({ + id: SENTINELONE_CONNECTOR_ID, + name: SENTINELONE_TITLE, + Service: SentinelOneConnector, + schema: { + config: SentinelOneConfigSchema, + secrets: SentinelOneSecretsSchema, + }, + validators: [{ type: ValidatorType.CONFIG, validator: urlAllowListValidator('url') }], + supportedFeatureIds: [SecurityConnectorFeatureId], + minimumLicenseRequired: 'enterprise' as const, + renderParameterTemplates, +}); diff --git a/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/render.ts b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/render.ts new file mode 100644 index 0000000000000..9d852510ea7b7 --- /dev/null +++ b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/render.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { set } from '@kbn/safer-lodash-set/fp'; +import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; +import { ExecutorParams } from '@kbn/actions-plugin/server/sub_action_framework/types'; +import { SUB_ACTION } from '../../../common/sentinelone/constants'; + +interface Context { + alerts: Ecs[]; +} + +export const renderParameterTemplates = ( + params: ExecutorParams, + variables: Record +) => { + const context = variables?.context as Context; + if (params?.subAction === SUB_ACTION.KILL_PROCESS) { + return { + subAction: SUB_ACTION.KILL_PROCESS, + subActionParams: { + processName: context.alerts[0].process?.name, + computerName: context.alerts[0].host?.name, + }, + }; + } + + if (params?.subAction === SUB_ACTION.ISOLATE_AGENT) { + return { + subAction: SUB_ACTION.ISOLATE_AGENT, + subActionParams: { + computerName: context.alerts[0].host?.name, + }, + }; + } + + if (params?.subAction === SUB_ACTION.RELEASE_AGENT) { + return { + subAction: SUB_ACTION.RELEASE_AGENT, + subActionParams: { + computerName: context.alerts[0].host?.name, + }, + }; + } + + if (params?.subAction === SUB_ACTION.EXECUTE_SCRIPT) { + return { + subAction: SUB_ACTION.EXECUTE_SCRIPT, + subActionParams: { + computerName: context.alerts[0].host?.name, + ...params.subActionParams, + }, + }; + } + + let body: string; + try { + let bodyObject; + const alerts = context.alerts; + if (alerts) { + // Remove the "kibana" entry from all alerts to reduce weight, the same data can be found in other parts of the alert object. + bodyObject = set( + 'context.alerts', + alerts.map(({ kibana, ...alert }) => alert), + variables + ); + } else { + bodyObject = variables; + } + body = JSON.stringify(bodyObject); + } catch (err) { + body = JSON.stringify({ error: { message: err.message } }); + } + return set('subActionParams.body', body, params); +}; diff --git a/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts new file mode 100644 index 0000000000000..d27f7dcc5588b --- /dev/null +++ b/x-pack/plugins/stack_connectors/server/connector_types/sentinelone/sentinelone.ts @@ -0,0 +1,276 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ServiceParams, SubActionConnector } from '@kbn/actions-plugin/server'; +import type { AxiosError } from 'axios'; +import { SubActionRequestParams } from '@kbn/actions-plugin/server/sub_action_framework/types'; +import type { + SentinelOneConfig, + SentinelOneSecrets, + SentinelOneGetAgentsResponse, + SentinelOneGetAgentsParams, + SentinelOneGetRemoteScriptStatusParams, + SentinelOneBaseApiResponse, + SentinelOneGetRemoteScriptsParams, + SentinelOneGetRemoteScriptsResponse, + SentinelOneIsolateAgentParams, + SentinelOneKillProcessParams, + SentinelOneExecuteScriptParams, +} from '../../../common/sentinelone/types'; +import { + SentinelOneKillProcessResponseSchema, + SentinelOneExecuteScriptParamsSchema, + SentinelOneGetRemoteScriptsParamsSchema, + SentinelOneGetRemoteScriptsResponseSchema, + SentinelOneGetAgentsResponseSchema, + SentinelOneIsolateAgentResponseSchema, + SentinelOneIsolateAgentParamsSchema, + SentinelOneGetRemoteScriptStatusParamsSchema, + SentinelOneGetRemoteScriptStatusResponseSchema, + SentinelOneGetAgentsParamsSchema, + SentinelOneExecuteScriptResponseSchema, +} from '../../../common/sentinelone/schema'; +import { SUB_ACTION } from '../../../common/sentinelone/constants'; + +export const API_MAX_RESULTS = 1000; +export const API_PATH = '/web/api/v2.1'; + +export class SentinelOneConnector extends SubActionConnector< + SentinelOneConfig, + SentinelOneSecrets +> { + private urls: { + agents: string; + isolateAgent: string; + releaseAgent: string; + remoteScripts: string; + remoteScriptStatus: string; + remoteScriptsExecute: string; + }; + + constructor(params: ServiceParams) { + super(params); + + this.urls = { + isolateAgent: `${this.config.url}${API_PATH}/agents/actions/disconnect`, + releaseAgent: `${this.config.url}${API_PATH}/agents/actions/connect`, + remoteScripts: `${this.config.url}${API_PATH}/remote-scripts`, + remoteScriptStatus: `${this.config.url}${API_PATH}/remote-scripts/status`, + remoteScriptsExecute: `${this.config.url}${API_PATH}/remote-scripts/execute`, + agents: `${this.config.url}${API_PATH}/agents`, + }; + + this.registerSubActions(); + } + + private registerSubActions() { + this.registerSubAction({ + name: SUB_ACTION.GET_REMOTE_SCRIPTS, + method: 'getRemoteScripts', + schema: SentinelOneGetRemoteScriptsParamsSchema, + }); + + this.registerSubAction({ + name: SUB_ACTION.GET_REMOTE_SCRIPT_STATUS, + method: 'getRemoteScriptStatus', + schema: SentinelOneGetRemoteScriptStatusParamsSchema, + }); + + this.registerSubAction({ + name: SUB_ACTION.GET_AGENTS, + method: 'getAgents', + schema: SentinelOneGetAgentsParamsSchema, + }); + + this.registerSubAction({ + name: SUB_ACTION.ISOLATE_AGENT, + method: 'isolateAgent', + schema: SentinelOneIsolateAgentParamsSchema, + }); + + this.registerSubAction({ + name: SUB_ACTION.RELEASE_AGENT, + method: 'releaseAgent', + schema: SentinelOneIsolateAgentParamsSchema, + }); + + this.registerSubAction({ + name: SUB_ACTION.KILL_PROCESS, + method: 'killProcess', + schema: SentinelOneKillProcessResponseSchema, + }); + + this.registerSubAction({ + name: SUB_ACTION.EXECUTE_SCRIPT, + method: 'executeScript', + schema: SentinelOneExecuteScriptParamsSchema, + }); + } + + public async executeScript(payload: SentinelOneExecuteScriptParams) { + return this.sentinelOneApiRequest({ + url: this.urls.remoteScriptsExecute, + method: 'post', + data: { + data: { + outputDestination: 'SentinelCloud', + ...payload.script, + }, + filter: { + computerName: payload.computerName, + }, + }, + responseSchema: SentinelOneExecuteScriptResponseSchema, + }); + } + + public async killProcess({ processName, ...payload }: SentinelOneKillProcessParams) { + const agentData = await this.getAgents(payload); + + const agentId = agentData.data[0]?.id; + + if (!agentId) { + throw new Error(`No agent found for filter ${JSON.stringify(payload)}`); + } + + const terminateScriptResponse = await this.getRemoteScripts({ + query: 'terminate', + osTypes: [agentData?.data[0]?.osType], + }); + + if (!processName) { + throw new Error('No process name provided'); + } + + return this.sentinelOneApiRequest({ + url: this.urls.remoteScriptsExecute, + method: 'post', + data: { + data: { + outputDestination: 'SentinelCloud', + scriptId: terminateScriptResponse.data[0].id, + scriptRuntimeTimeoutSeconds: terminateScriptResponse.data[0].scriptRuntimeTimeoutSeconds, + taskDescription: terminateScriptResponse.data[0].scriptName, + inputParams: `--terminate --processes ${processName}`, + }, + filter: { + ids: agentId, + }, + }, + responseSchema: SentinelOneKillProcessResponseSchema, + }); + } + + public async isolateAgent(payload: SentinelOneIsolateAgentParams) { + const response = await this.getAgents(payload); + + if (response.data.length === 0) { + throw new Error('No agents found'); + } + + if (response.data[0].networkStatus === 'disconnected') { + throw new Error('Agent already isolated'); + } + + const agentId = response.data[0].id; + + return this.sentinelOneApiRequest({ + url: this.urls.isolateAgent, + method: 'post', + data: { + filter: { + ids: agentId, + }, + }, + responseSchema: SentinelOneIsolateAgentResponseSchema, + }); + } + + public async releaseAgent(payload: SentinelOneIsolateAgentParams) { + const response = await this.getAgents(payload); + + if (response.data.length === 0) { + throw new Error('No agents found'); + } + + if (response.data[0].networkStatus !== 'disconnected') { + throw new Error('Agent not isolated'); + } + + const agentId = response.data[0].id; + + return this.sentinelOneApiRequest({ + url: this.urls.releaseAgent, + method: 'post', + data: { + filter: { + ids: agentId, + }, + }, + responseSchema: SentinelOneIsolateAgentResponseSchema, + }); + } + + public async getAgents( + payload: SentinelOneGetAgentsParams + ): Promise { + return this.sentinelOneApiRequest({ + url: this.urls.agents, + params: { + ...payload, + }, + responseSchema: SentinelOneGetAgentsResponseSchema, + }); + } + + public async getRemoteScriptStatus(payload: SentinelOneGetRemoteScriptStatusParams) { + return this.sentinelOneApiRequest({ + url: this.urls.remoteScriptStatus, + params: { + parent_task_id: payload.parentTaskId, + }, + responseSchema: SentinelOneGetRemoteScriptStatusResponseSchema, + }); + } + + private async sentinelOneApiRequest( + req: SubActionRequestParams + ): Promise { + const response = await this.request({ + ...req, + params: { + ...req.params, + APIToken: this.secrets.token, + }, + }); + + return response.data; + } + + protected getResponseErrorMessage(error: AxiosError): string { + if (!error.response?.status) { + return 'Unknown API Error'; + } + if (error.response.status === 401) { + return 'Unauthorized API Error'; + } + return `API Error: ${error.response?.statusText}`; + } + + public async getRemoteScripts( + payload: SentinelOneGetRemoteScriptsParams + ): Promise { + return this.sentinelOneApiRequest({ + url: this.urls.remoteScripts, + params: { + limit: API_MAX_RESULTS, + ...payload, + }, + responseSchema: SentinelOneGetRemoteScriptsResponseSchema, + }); + } +} diff --git a/x-pack/plugins/stack_connectors/tsconfig.json b/x-pack/plugins/stack_connectors/tsconfig.json index 7cc6696f04368..f18dfaea77cca 100644 --- a/x-pack/plugins/stack_connectors/tsconfig.json +++ b/x-pack/plugins/stack_connectors/tsconfig.json @@ -33,6 +33,7 @@ "@kbn/core-saved-objects-common", "@kbn/core-http-browser-mocks", "@kbn/core-saved-objects-api-server-mocks", + "@kbn/securitysolution-ecs", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.ts b/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.ts index 49e7bc1e8d9e3..69947cb08fc8d 100644 --- a/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.ts +++ b/x-pack/plugins/task_manager/server/queries/oldest_idle_action_task.ts @@ -44,6 +44,7 @@ export const getOldestIdleActionTask = async ( 'actions:.jira', 'actions:.resilient', 'actions:.teams', + 'actions:.sentinelone', ], }, }, diff --git a/x-pack/plugins/task_manager/server/saved_objects/index.ts b/x-pack/plugins/task_manager/server/saved_objects/index.ts index 53d09d4baf131..0bb12906708de 100644 --- a/x-pack/plugins/task_manager/server/saved_objects/index.ts +++ b/x-pack/plugins/task_manager/server/saved_objects/index.ts @@ -50,6 +50,7 @@ export function setupSavedObjects( 'actions:.jira', 'actions:.resilient', 'actions:.teams', + 'actions:.sentinelone', ], }, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_message_variables.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_message_variables.tsx index 3bb65037d5c93..346dce44af60b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_message_variables.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_message_variables.tsx @@ -20,6 +20,7 @@ interface Props { isDisabled?: boolean; editAction: (property: string, value: any, index: number) => void; label: string; + helpText?: string; errors?: string[]; } @@ -32,6 +33,7 @@ export const TextAreaWithMessageVariables: React.FunctionComponent = ({ editAction, label, errors, + helpText, }) => { const [currentTextElement, setCurrentTextElement] = useState(null); @@ -64,6 +66,7 @@ export const TextAreaWithMessageVariables: React.FunctionComponent = ({ paramsProperty={paramsProperty} /> } + helpText={helpText} > Date: Wed, 9 Aug 2023 20:18:57 +0200 Subject: [PATCH 26/41] [Security Solution] Removing discontinued Cypress tests and code (#163496) --- .buildkite/ftr_configs.yml | 3 - ...nkins_security_solution_cypress_firefox.sh | 14 - .../security_solution/cypress/README.md | 286 +----------------- .../detection_alerts/alerts_details.cy.ts | 41 --- .../event_correlation_rule.cy.ts | 53 ---- .../detection_rules/custom_query_rule.cy.ts | 141 --------- .../detection_rules/threshold_rule.cy.ts | 138 --------- .../threat_hunting/cases/import_case.cy.ts | 153 ---------- .../timeline/import_timeline.cy.ts | 201 ------------ x-pack/plugins/security_solution/package.json | 6 - .../security_solution_cypress/ccs_config.ts | 19 -- .../config.firefox.ts | 50 --- .../test/security_solution_cypress/runner.ts | 59 ---- .../upgrade_config.ts | 21 -- 14 files changed, 2 insertions(+), 1183 deletions(-) delete mode 100755 test/scripts/jenkins_security_solution_cypress_firefox.sh delete mode 100644 x-pack/plugins/security_solution/cypress/ccs_e2e/detection_alerts/alerts_details.cy.ts delete mode 100644 x-pack/plugins/security_solution/cypress/ccs_e2e/detection_rules/event_correlation_rule.cy.ts delete mode 100644 x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/custom_query_rule.cy.ts delete mode 100644 x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/threshold_rule.cy.ts delete mode 100644 x-pack/plugins/security_solution/cypress/upgrade_e2e/threat_hunting/cases/import_case.cy.ts delete mode 100644 x-pack/plugins/security_solution/cypress/upgrade_e2e/threat_hunting/timeline/import_timeline.cy.ts delete mode 100644 x-pack/test/security_solution_cypress/ccs_config.ts delete mode 100644 x-pack/test/security_solution_cypress/config.firefox.ts delete mode 100644 x-pack/test/security_solution_cypress/upgrade_config.ts diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index 2e7f5a815c6ea..e6eb1cec755c8 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -34,11 +34,8 @@ disabled: - x-pack/test/osquery_cypress/cli_config.ts - x-pack/test/osquery_cypress/config.ts - x-pack/test/osquery_cypress/visual_config.ts - - x-pack/test/security_solution_cypress/ccs_config.ts - x-pack/test/security_solution_cypress/cli_config.ts - - x-pack/test/security_solution_cypress/config.firefox.ts - x-pack/test/security_solution_cypress/config.ts - - x-pack/test/security_solution_cypress/upgrade_config.ts - x-pack/test/threat_intelligence_cypress/cli_config_parallel.ts - x-pack/test/threat_intelligence_cypress/config.ts - x-pack/test/functional_enterprise_search/visual_config.ts diff --git a/test/scripts/jenkins_security_solution_cypress_firefox.sh b/test/scripts/jenkins_security_solution_cypress_firefox.sh deleted file mode 100755 index 79623d5a2a23b..0000000000000 --- a/test/scripts/jenkins_security_solution_cypress_firefox.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash - -source test/scripts/jenkins_test_setup_xpack.sh - -echo " -> Running security solution cypress tests" -cd "$XPACK_DIR" - -node scripts/functional_tests \ - --debug --bail \ - --kibana-install-dir "$KIBANA_INSTALL_DIR" \ - --config test/security_solution_cypress/config.firefox.ts - -echo "" -echo "" diff --git a/x-pack/plugins/security_solution/cypress/README.md b/x-pack/plugins/security_solution/cypress/README.md index db67eac909b19..6b3b641e8e59c 100644 --- a/x-pack/plugins/security_solution/cypress/README.md +++ b/x-pack/plugins/security_solution/cypress/README.md @@ -2,17 +2,12 @@ The `security_solution/cypress` directory contains functional UI tests that execute using [Cypress](https://www.cypress.io/). -Currently with Cypress you can develop `functional` tests and coming soon `CCS` and `Upgrade` functional tests. +Currently with Cypress you can develop `functional` tests. If you are still having doubts, questions or queries, please feel free to ping our Cypress champions: - Functional Tests: - Gloria Hornero and Patryk Kopycinsky -- CCS Tests: - - Technical questions around the https://github.com/elastic/integration-test repo: - - Domenico Andreoli - - Doubts regarding testing CCS and Cypress best practices: - - Gloria Hornero ## Table of Contents @@ -51,246 +46,17 @@ Run the tests with the following yarn scripts: | Script Name | Description | | ----------- | ----------- | | cypress | Runs the default Cypress command | -| cypress:open | Opens the Cypress UI with all tests in the `e2e` directory. This also runs a local kibana and ES instance. The kibana instance will reload when you make code changes. This is the recommended way to debug and develop tests. | -| cypress:open:ccs | Opens the Cypress UI and runs all tests in the `ccs_e2e` directory | -| cypress:open:upgrade | Opens the Cypress UI and runs all tests in the `upgrade_e2e` directory | +| cypress:open | Opens the Cypress UI with all tests in the `e2e` directory. This also runs a local kibana and ES instance. The kibana instance will reload when you make code changes. This is the recommended way to debug and develop tests. |C | cypress:run | Runs all tests in the `e2e` directory excluding `investigations` and `explore` directories in headless mode | | cypress:run:cases | Runs all tests under `explore/cases` in the `e2e` directory related to the Cases area team in headless mode | | cypress:run:reporter | Runs all tests with the specified configuration in headless mode and produces a report using `cypress-multi-reporters` | | cypress:run:respops | Runs all tests related to the Response Ops area team, specifically tests in `detection_alerts`, `detection_rules`, and `exceptions` directories in headless mode | -| cypress:run:ccs | Runs all tests in the `ccs_e2e` directory in headless mode | -| cypress:run:upgrade | Runs all tests in the `upgrade_e2e` directory in headless mode | | cypress:investigations:run | Runs all tests in the `e2e/investigations` directory in headless mode | | cypress:explore:run | Runs all tests in the `e2e/explore` directory in headless mode | | junit:merge | Merges individual test reports into a single report and moves the report to the `junit` directory | Please note that all the headless mode commands do not open the Cypress UI and are typically used in CI/CD environments. The scripts that open the Cypress UI are useful for development and debugging. -### Execution modes - -There are currently four ways to run the tests, comprised of two execution modes and two target environments, which will be detailed below. - -#### Interactive mode - -When you run Cypress in interactive mode, an interactive runner is displayed that allows you to see commands as they execute while also viewing the application under test. For more information, please see [cypress documentation](https://docs.cypress.io/guides/core-concepts/test-runner.html#Overview). - -#### Headless mode - -A headless browser is a browser simulation program that does not have a user interface. These programs operate like any other browser, but do not display any UI. This is why meanwhile you are executing the tests on this mode you are not going to see the application under test. Just the output of the test is displayed on the terminal once the execution is finished. - -### Target environments - -#### FTR (CI) - -This is the configuration used by CI. It uses the FTR to spawn both a Kibana instance (http://localhost:5620) and an Elasticsearch instance (http://localhost:9220) with a preloaded minimum set of data (see preceding "Test data" section), and then executes cypress against this stack. You can find this configuration in `x-pack/test/security_solution_cypress` - -Tests run on buildkite PR pipeline is parallelized. It can be configured in [.buildkite/pipelines/pull_request/security_solution.yml](https://github.com/elastic/kibana/blob/main/.buildkite/pipelines/pull_request/security_solution.yml) with property `parallelism` - -```yml - ... - agents: - queue: n2-4-spot - depends_on: build - timeout_in_minutes: 120 - parallelism: 4 - ... -``` - -#### Custom Targets - -This configuration runs cypress tests against an arbitrary host. -**WARNING**: When using your own instances you need to take into account that if you already have data on it, the tests may fail, as well as, they can put your instances in an undesired state, since our tests uses es_archive to populate data. - -#### integration-test (CI) - -This configuration is driven by [elastic/integration-test](https://github.com/elastic/integration-test) which, as part of a bigger set of tests, provisions one VM with two instances configured in CCS mode and runs the [CCS Cypress test specs](./ccs_e2e). - -The two clusters are named `admin` and `data` and are reachable as follows: - -| | Elasticsearch | Kibana | -| ----- | ---------------------- | ---------------------- | -| admin | https://localhost:9200 | https://localhost:5601 | -| data | https://localhost:9210 | https://localhost:5602 | - -### Working with integration-test - -#### Initial setup and prerequisites - -The entry point is [integration-test/jenkins_test.sh](https://github.com/elastic/integration-test/blob/master/jenkins_test.sh), it essentially prepares the VMs and there runs tests. Some snapshots (`phase1` and `phase2`) are taken along the way so that it's possible to short cut the VM preparation when iterating over tests for development or debugging. - -The VMs are managed with Vagrant using the VirtualBox provider therefore you need to install both these tools. The host OS can be either Windows, Linux or MacOS. - -`jenkins_test.sh` assumes that a `kibana` folder is present alongside the `integration-test` where it's executed from. The `kibana` folder is used only for loading the test suites though, the actual packages for the VMs preparation are downloaded from elastic.co according to the `BUILD` environment variable or the branch which `jenkins_test.sh` is invoked from. It's your responsibility to checkout the matching branches in `kibana` and `integration-test` as needed. - -Read [integration-test#readme](https://github.com/elastic/integration-test#readme) for further details. - -#### Use cases - -There is no way to just set up the test environment without also executing tests at least once. On the other hand it's time consuming to go throught the whole CI procedure to just iterate over the tests therefore the following instructions support the two use cases: - -- reproduce e2e the CI execution locally, ie. for debugging a CI failure -- use the CI script to easily setup the environment for tests development/debugging - -The missing use case, application TDD, requires a different solution that runs from the checked out repositories instead of the pre-built packages and it's yet to be developed. - -#### Run the CI flow - -This is the CI flow narrowed down to the execution of CCS Cypress tests: - -```shell -cd integration-test -VMS=ubuntu16_tar_ccs_cypress ./jenkins_test.sh -``` - -It destroys and rebuilds the VM. There installs, provisions and starts the stack according to the configuration in [integration-test/provision/ubuntu16_tar_ccs_cypress.sh](https://github.com/elastic/integration-test/blob/master/provision/ubuntu16_tar_ccs_cypress.sh). - -The tests are executed using the FTR runner `SecuritySolutionCypressCcsTestRunner` defined in [x-pack/test/security_solution_cypress/runner.ts](../../../test/security_solution_cypress/runner.ts) as configured in [x-pack/test/security_solution_cypress/ccs_config.ts](../../../test/security_solution_cypress/ccs_config.ts). - -#### Re-run the tests - -After the first run it's possible to restore the VM at `phase2`, right before tests were executed, and run them again: - -```shell -cd integration-test -MODE=retest ./jenkins_test.sh -``` - -It remembers which VM the first round was executed on, you don't need to specify `VMS` any more. - -In case your tests are cleaning after themselves and therefore result idempotent, you can skip the restoration to `phase2` and directly run the Cypress command line. See [CCS Custom Target + Headless](#ccs-custom-target--headless) further below for details but ensure you'll define the `CYPRESS_*` following the correspondence: - -| Cypress command line | [integration-test/provision/ubuntu16_tar_ccs_cypress.sh](https://github.com/elastic/integration-test/blob/master/provision/ubuntu16_tar_ccs_cypress.sh) | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| CYPRESS_BASE_URL | TEST_KIBANA_URL | -| CYPRESS_ELASTICSEARCH_URL | TEST_ES_URL | -| CYPRESS_CCS_KIBANA_URL | TEST_KIBANA_URLDATA | -| CYPRESS_CCS_ELASTICSEARCH_URL | TEST_ES_URLDATA | -| CYPRESS_CCS_REMOTE_NAME | TEST_CCS_REMOTE_NAME | -| CYPRESS_ELASTICSEARCH_USERNAME | ELASTICSEARCH_USERNAME | -| CYPRESS_ELASTICSEARCH_PASSWORD | ELASTICSEARCH_PASSWORD | -| TEST_CA_CERT_PATH | integration-test/certs/ca/ca.crt | - -Note: `TEST_CA_CERT_PATH` above is truly without `CYPRESS_` prefix. - -### Test Execution: Examples - -#### FTR + Headless (Chrome) - -Since this is how tests are run on CI, this will likely be the configuration you want to reproduce failures locally, etc. - -```shell -# bootstrap kibana from the project root -yarn kbn bootstrap - -# build the plugins/assets that cypress will execute against -node scripts/build_kibana_platform_plugins - -# launch the cypress test runner -cd x-pack/plugins/security_solution -yarn cypress:run-as-ci -``` - -#### FTR + Headless (Firefox) - -Since this is how tests are run on CI, this will likely be the configuration you want to reproduce failures locally, etc. - -```shell -# bootstrap kibana from the project root -yarn kbn bootstrap - -# build the plugins/assets that cypress will execute against -node scripts/build_kibana_platform_plugins - -# launch the cypress test runner -cd x-pack/plugins/security_solution -yarn cypress:run-as-ci:firefox -``` - -#### FTR + Interactive - -This is the preferred mode for developing new tests. - -```shell -# bootstrap kibana from the project root -yarn kbn bootstrap - -# build the plugins/assets that cypress will execute against -node scripts/build_kibana_platform_plugins - -# launch the cypress test runner -cd x-pack/plugins/security_solution -yarn cypress:open-as-ci -``` - -Note that you can select the browser you want to use on the top right side of the interactive runner. - -#### Custom Target + Headless (Chrome) - -This mode may be useful for testing a release, e.g. spin up a build candidate -and point cypress at it to catch regressions. - -```shell -# bootstrap kibana from the project root -yarn kbn bootstrap - -# load auditbeat data needed for test execution (which FTR normally does for us) -cd x-pack/plugins/security_solution -node ../../../scripts/es_archiver load auditbeat --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.base.js --es-url http(s)://:@ --kibana-url http(s)://:@ - -# launch the cypress test runner with overridden environment variables -cd x-pack/plugins/security_solution -CYPRESS_BASE_URL=http(s)://:@ CYPRESS_ELASTICSEARCH_URL=http(s)://:@ CYPRESS_ELASTICSEARCH_USERNAME= CYPRESS_ELASTICSEARCH_PASSWORD= yarn cypress:run -``` - -#### Custom Target + Headless (Firefox) - -This mode may be useful for testing a release, e.g. spin up a build candidate -and point cypress at it to catch regressions. - -```shell -# bootstrap kibana from the project root -yarn kbn bootstrap - -# load auditbeat data needed for test execution (which FTR normally does for us) -cd x-pack/plugins/security_solution -node ../../../scripts/es_archiver load auditbeat --dir ../../test/security_solution_cypress/es_archives --config ../../../test/functional/config.base.js --es-url http(s)://:@ --kibana-url http(s)://:@ - -# launch the cypress test runner with overridden environment variables -cd x-pack/plugins/security_solution -CYPRESS_BASE_URL=http(s)://:@ CYPRESS_ELASTICSEARCH_URL=http(s)://:@ CYPRESS_ELASTICSEARCH_USERNAME= CYPRESS_ELASTICSEARCH_PASSWORD= yarn cypress:run:firefox -``` - -#### CCS Custom Target + Headless - -This test execution requires two clusters configured for CCS. See [Search across clusters](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-cross-cluster-search.html) for instructions on how to prepare such setup. - -The instructions below assume: - -- Search cluster is on server1 -- Remote cluster is on server2 -- Remote cluster is accessible from the search cluster with name `remote` -- Security and TLS are enabled - -```shell -# bootstrap Kibana from the project root -yarn kbn bootstrap - -# launch the Cypress test runner with overridden environment variables -cd x-pack/plugins/security_solution -CYPRESS_ELASTICSEARCH_USERNAME="user" \ -CYPRESS_ELASTICSEARCH_PASSWORD="pass" \ -CYPRESS_BASE_URL="https://user:pass@server1:5601" \ -CYPRESS_ELASTICSEARCH_URL="https://user:pass@server1:9200" \ -CYPRESS_CCS_KIBANA_URL="https://user:pass@server2:5601" \ -CYPRESS_CCS_ELASTICSEARCH_URL="https://user:pass@server2:9200" \ -CYPRESS_CCS_REMOTE_NAME="remote" \ -yarn cypress:run:ccs -``` - -Similar sequence, just ending with `yarn cypress:open:ccs`, can be used for interactive test running via Cypress UI. - -Appending `--browser firefox` to the `yarn cypress:run:ccs` command above will run the tests on Firefox instead of Chrome. - ## Debugging your test In order to be able to debug any Cypress test you need to open Cypress on visual mode. [Here](https://docs.cypress.io/guides/guides/debugging) @@ -302,10 +68,6 @@ If you are debugging a flaky test, a good tip is to insert a `cy.wait('); -``` - -They will use the `CYPRESS_CCS_*_URL` environment variables for accessing the remote cluster. Complex tests involving local and remote data can interleave them with `esArchiverLoad` and `esArchiverUnload` as needed. - -#### Remote indices queries - -Queries accessing remote indices follow the usual `:` notation but should not hard-code the remote name in the test itself. - -For such reason the environemnt variable `CYPRESS_CCS_REMOTE_NAME` is defined and, in the case of detection rules, used as shown below: - -```javascript -const ccsRemoteName: string = Cypress.env('CCS_REMOTE_NAME'); - -export const unmappedCCSRule: CustomRule = { - customQuery: '*:*', - index: [`${ccsRemoteName}:unmapped*`], - ... -}; - -``` - -Similar approach should be used in defining all index patterns, rules, and queries to be applied on remote data. - ## Development Best Practices Below you will a set of best practices that should be followed when writing Cypress tests. @@ -478,12 +202,6 @@ taken into consideration until another solution is implemented: Remember that minimizing the number of times the web page is loaded, we minimize as well the execution time. -### CCS test specific - -When testing CCS we want to put our focus in making sure that our `Source` instance is receiving properly the data that comes from the `Remote` instances, as well as the data is displayed as we expect on the `Source`. - -For that reason and in order to make our test more stable, use the API to execute all the actions needed before the assertions, and use Cypress to assert that the UI is displaying all the expected things. - ## Test Artifacts When Cypress tests are run headless on the command line, artifacts diff --git a/x-pack/plugins/security_solution/cypress/ccs_e2e/detection_alerts/alerts_details.cy.ts b/x-pack/plugins/security_solution/cypress/ccs_e2e/detection_alerts/alerts_details.cy.ts deleted file mode 100644 index 2865eb6e5ee9b..0000000000000 --- a/x-pack/plugins/security_solution/cypress/ccs_e2e/detection_alerts/alerts_details.cy.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { JSON_TEXT } from '../../screens/alerts_details'; - -import { expandFirstAlert, waitForAlerts } from '../../tasks/alerts'; -import { openJsonView } from '../../tasks/alerts_details'; -import { createRule } from '../../tasks/api_calls/rules'; -import { cleanKibana } from '../../tasks/common'; -import { login, visitWithoutDateRange } from '../../tasks/login'; - -import { getUnmappedCCSRule } from '../../objects/rule'; - -import { ALERTS_URL } from '../../urls/navigation'; - -describe('Alert details with unmapped fields', () => { - beforeEach(() => { - login(); - cleanKibana(); - cy.task('esArchiverCCSLoad', 'unmapped_fields'); - createRule(getUnmappedCCSRule()); - visitWithoutDateRange(ALERTS_URL); - waitForAlerts(); - expandFirstAlert(); - }); - - it('Displays the unmapped field on the JSON view', () => { - const expectedUnmappedValue = 'This is the unmapped field'; - - openJsonView(); - - cy.get(JSON_TEXT).then((x) => { - const parsed = JSON.parse(x.text()); - expect(parsed.fields.unmapped[0]).to.equal(expectedUnmappedValue); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/cypress/ccs_e2e/detection_rules/event_correlation_rule.cy.ts b/x-pack/plugins/security_solution/cypress/ccs_e2e/detection_rules/event_correlation_rule.cy.ts deleted file mode 100644 index ea2a1797fec5b..0000000000000 --- a/x-pack/plugins/security_solution/cypress/ccs_e2e/detection_rules/event_correlation_rule.cy.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { getCCSEqlRule } from '../../objects/rule'; - -import { ALERTS_COUNT, ALERT_DATA_GRID } from '../../screens/alerts'; - -import { - filterByCustomRules, - goToRuleDetails, - waitForRulesTableToBeLoaded, -} from '../../tasks/alerts_detection_rules'; -import { createRule } from '../../tasks/api_calls/rules'; -import { cleanKibana } from '../../tasks/common'; -import { waitForAlertsToPopulate, waitForTheRuleToBeExecuted } from '../../tasks/create_new_rule'; -import { login, visitWithoutDateRange } from '../../tasks/login'; - -import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../urls/navigation'; - -describe('Detection rules', function () { - const expectedNumberOfAlerts = '1 alert'; - - beforeEach('Reset signals index', function () { - cleanKibana(); - }); - - it('EQL rule on remote indices generates alerts', function () { - cy.task('esArchiverCCSLoad', 'linux_process'); - const rule = getCCSEqlRule(); - login(); - createRule(rule); - visitWithoutDateRange(DETECTIONS_RULE_MANAGEMENT_URL); - waitForRulesTableToBeLoaded(); - filterByCustomRules(); - goToRuleDetails(); - waitForTheRuleToBeExecuted(); - waitForAlertsToPopulate(); - - cy.get(ALERTS_COUNT).should('have.text', expectedNumberOfAlerts); - cy.get(ALERT_DATA_GRID) - .invoke('text') - .then((text) => { - cy.log('ALERT_DATA_GRID', text); - expect(text).contains(rule.name); - expect(text).contains(rule.severity); - expect(text).contains(rule.risk_score); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/custom_query_rule.cy.ts b/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/custom_query_rule.cy.ts deleted file mode 100644 index a9950f840fa72..0000000000000 --- a/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/custom_query_rule.cy.ts +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import semver from 'semver'; -import { - ALERT_GRID_CELL, - DESTINATION_IP, - HOST_NAME, - PROCESS_NAME_COLUMN, - PROCESS_NAME, - REASON, - RISK_SCORE, - RULE_NAME, - SEVERITY, - SOURCE_IP, - USER_NAME, -} from '../../../screens/alerts'; -import { SERVER_SIDE_EVENT_COUNT } from '../../../screens/alerts_detection_rules'; -import { - ADDITIONAL_LOOK_BACK_DETAILS, - ABOUT_DETAILS, - ABOUT_RULE_DESCRIPTION, - CUSTOM_QUERY_DETAILS, - DEFINITION_DETAILS, - INDEX_PATTERNS_DETAILS, - RISK_SCORE_DETAILS, - RULE_NAME_HEADER, - RULE_TYPE_DETAILS, - RUNS_EVERY_DETAILS, - SCHEDULE_DETAILS, - SEVERITY_DETAILS, - TIMELINE_TEMPLATE_DETAILS, -} from '../../../screens/rule_details'; - -import { getDetails } from '../../../tasks/rule_details'; -import { waitForPageToBeLoaded } from '../../../tasks/common'; -import { - waitForRulesTableToBeLoaded, - goToTheRuleDetailsOf, -} from '../../../tasks/alerts_detection_rules'; -import { login, visit } from '../../../tasks/login'; - -import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../../urls/navigation'; - -const EXPECTED_NUMBER_OF_ALERTS = '1'; - -const alert = { - rule: 'Custom query rule for upgrade', - severity: 'low', - riskScore: '7', - reason: - 'file event with process test, file The file to test, by Security Solution on security-solution.local created low alert Custom query rule for upgrade.', - reasonAlt: '—', - hostName: 'security-solution.local', - username: 'Security Solution', - processName: 'test', - fileName: 'The file to test', - sourceIp: '127.0.0.1', - destinationIp: '127.0.0.2', -}; - -const rule = { - customQuery: '*:*', - name: 'Custom query rule for upgrade', - description: 'My description', - index: ['auditbeat-custom*'], - severity: 'Low', - riskScore: '7', - timelineTemplate: 'none', - runsEvery: '24h', - lookBack: '49976h', - timeline: 'None', -}; - -describe('After an upgrade, the custom query rule', () => { - before(() => { - login(); - visit(DETECTIONS_RULE_MANAGEMENT_URL); - waitForRulesTableToBeLoaded(); - goToTheRuleDetailsOf(rule.name); - waitForPageToBeLoaded(); - // Possible bug on first attempt sometimes redirects page back to alerts - // Going to retry the block once - cy.url().then((url) => { - const currentUrl = url; - cy.log(`Current URL is : ${currentUrl}`); - if (!currentUrl.includes(DETECTIONS_RULE_MANAGEMENT_URL)) { - cy.log('Retrying not on correct page!'); - visit(DETECTIONS_RULE_MANAGEMENT_URL); - waitForRulesTableToBeLoaded(); - goToTheRuleDetailsOf(rule.name); - waitForPageToBeLoaded(); - } - }); - cy.url().should('include', DETECTIONS_RULE_MANAGEMENT_URL); - }); - - it('Has the expected alerts number', () => { - cy.get(SERVER_SIDE_EVENT_COUNT).contains(EXPECTED_NUMBER_OF_ALERTS); - }); - - it('Displays the rule details', () => { - cy.get(RULE_NAME_HEADER).should('contain', `${rule.name}`); - cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', rule.description); - cy.get(ABOUT_DETAILS).within(() => { - getDetails(SEVERITY_DETAILS).should('have.text', rule.severity); - getDetails(RISK_SCORE_DETAILS).should('have.text', rule.riskScore); - }); - cy.get(DEFINITION_DETAILS).within(() => { - getDetails(INDEX_PATTERNS_DETAILS).should('have.text', rule.index.join('')); - getDetails(CUSTOM_QUERY_DETAILS).should('have.text', rule.customQuery); - getDetails(RULE_TYPE_DETAILS).should('have.text', 'Query'); - getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', rule.timeline); - }); - cy.get(SCHEDULE_DETAILS).within(() => { - getDetails(RUNS_EVERY_DETAILS).should('have.text', rule.runsEvery); - getDetails(ADDITIONAL_LOOK_BACK_DETAILS).should('have.text', rule.lookBack); - }); - }); - - it('Displays the alert details at the tgrid', () => { - let expectedReason = alert.reason; - if (semver.lt(Cypress.env('ORIGINAL_VERSION'), '7.15.0')) { - expectedReason = alert.reasonAlt; - } - cy.get(ALERT_GRID_CELL).first().focus(); - cy.get(RULE_NAME).should('have.text', alert.rule); - cy.get(SEVERITY).should('have.text', alert.severity); - cy.get(RISK_SCORE).should('have.text', alert.riskScore); - cy.get(REASON).contains(expectedReason); - cy.get(HOST_NAME).should('have.text', alert.hostName); - cy.get(USER_NAME).should('have.text', alert.username); - cy.get(PROCESS_NAME_COLUMN).eq(0).scrollIntoView(); - cy.get(PROCESS_NAME).should('have.text', alert.processName); - cy.get(SOURCE_IP).should('have.text', alert.sourceIp); - cy.get(DESTINATION_IP).should('have.text', alert.destinationIp); - }); -}); diff --git a/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/threshold_rule.cy.ts b/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/threshold_rule.cy.ts deleted file mode 100644 index 78c34dfd43a7e..0000000000000 --- a/x-pack/plugins/security_solution/cypress/upgrade_e2e/detections/detection_rules/threshold_rule.cy.ts +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import semver from 'semver'; -import { REASON, RISK_SCORE, RULE_NAME, SEVERITY } from '../../../screens/alerts'; -import { SERVER_SIDE_EVENT_COUNT } from '../../../screens/alerts_detection_rules'; -import { - ADDITIONAL_LOOK_BACK_DETAILS, - ABOUT_DETAILS, - ABOUT_RULE_DESCRIPTION, - CUSTOM_QUERY_DETAILS, - DEFINITION_DETAILS, - INDEX_PATTERNS_DETAILS, - RISK_SCORE_DETAILS, - RULE_NAME_HEADER, - RULE_TYPE_DETAILS, - RUNS_EVERY_DETAILS, - SCHEDULE_DETAILS, - SEVERITY_DETAILS, - THRESHOLD_DETAILS, - TIMELINE_TEMPLATE_DETAILS, -} from '../../../screens/rule_details'; - -import { getDetails } from '../../../tasks/rule_details'; -import { expandFirstAlert } from '../../../tasks/alerts'; -import { waitForPageToBeLoaded } from '../../../tasks/common'; -import { - goToTheRuleDetailsOf, - waitForRulesTableToBeLoaded, -} from '../../../tasks/alerts_detection_rules'; -import { login, visit } from '../../../tasks/login'; - -import { DETECTIONS_RULE_MANAGEMENT_URL } from '../../../urls/navigation'; -import { - OVERVIEW_RISK_SCORE, - OVERVIEW_RULE, - OVERVIEW_SEVERITY, - OVERVIEW_STATUS, - OVERVIEW_RULE_TYPE, -} from '../../../screens/alerts_details'; - -const EXPECTED_NUMBER_OF_ALERTS = '1'; - -const alert = { - rule: 'Threshold rule', - severity: 'medium', - riskScore: '17', - reason: 'event created medium alert Threshold rule.', - reasonAlt: '—', - hostName: 'security-solution.local', - thresholdCount: '2', -}; - -const rule = { - customQuery: '*:*', - name: 'Threshold rule', - description: 'Threshold rule for testing upgrade', - index: ['auditbeat-threshold*'], - severity: 'Medium', - riskScore: '17', - timelineTemplate: 'none', - runsEvery: '24h', - lookBack: '49976h', - timeline: 'None', - ruleType: 'threshold', - thresholdField: 'host.name', - thresholdValue: '1', -}; - -describe('After an upgrade, the threshold rule', () => { - before(() => { - login(); - visit(DETECTIONS_RULE_MANAGEMENT_URL); - waitForRulesTableToBeLoaded(); - goToTheRuleDetailsOf(rule.name); - waitForPageToBeLoaded(); - }); - - it('Has the expected alerts number', () => { - cy.get(SERVER_SIDE_EVENT_COUNT).contains(EXPECTED_NUMBER_OF_ALERTS); - }); - - it('Displays the rule details', () => { - cy.get(RULE_NAME_HEADER).should('contain', rule.name); - cy.get(ABOUT_RULE_DESCRIPTION).should('have.text', rule.description); - cy.get(ABOUT_DETAILS).within(() => { - getDetails(SEVERITY_DETAILS).should('have.text', rule.severity); - getDetails(RISK_SCORE_DETAILS).should('have.text', rule.riskScore); - }); - cy.get(DEFINITION_DETAILS).within(() => { - getDetails(INDEX_PATTERNS_DETAILS).should('have.text', rule.index.join('')); - getDetails(CUSTOM_QUERY_DETAILS).should('have.text', rule.customQuery); - getDetails(RULE_TYPE_DETAILS).should('have.text', 'Threshold'); - getDetails(TIMELINE_TEMPLATE_DETAILS).should('have.text', rule.timeline); - getDetails(THRESHOLD_DETAILS).should( - 'have.text', - `Results aggregated by ${rule.thresholdField} >= ${rule.thresholdValue}` - ); - }); - cy.get(SCHEDULE_DETAILS).within(() => { - getDetails(RUNS_EVERY_DETAILS).should('have.text', rule.runsEvery); - getDetails(ADDITIONAL_LOOK_BACK_DETAILS).should('have.text', rule.lookBack); - }); - }); - - it('Displays the alert details in the TGrid', () => { - let expectedReason = alert.reason; - if (semver.lt(Cypress.env('ORIGINAL_VERSION'), '7.15.0')) { - expectedReason = alert.reasonAlt; - } - cy.scrollTo('bottom'); - cy.get(RULE_NAME).should('have.text', alert.rule); - cy.get(SEVERITY).should('have.text', alert.severity); - cy.get(RISK_SCORE).should('have.text', alert.riskScore); - cy.get(REASON).contains(expectedReason); - // TODO: Needs data-test-subj - // cy.get(HOST_NAME).should('have.text', alert.hostName); - }); - - it('Displays the Overview alert details in the alert flyout', () => { - expandFirstAlert(); - - cy.get(OVERVIEW_STATUS).should('have.text', 'open'); - cy.get(OVERVIEW_RULE).should('have.text', alert.rule); - cy.get(OVERVIEW_SEVERITY).contains(alert.severity, { matchCase: false }); - cy.get(OVERVIEW_RISK_SCORE).should('have.text', alert.riskScore); - // TODO: Find out what this is - // cy.get(OVERVIEW_HOST_NAME).should('have.text', alert.hostName); - // TODO: Needs data-test-subj - // cy.get(OVERVIEW_THRESHOLD_COUNT).should('have.text', alert.thresholdCount); - cy.get(OVERVIEW_RULE_TYPE).should('have.text', rule.ruleType); - // TODO: Needs data-test-subj - // cy.get(OVERVIEW_THRESHOLD_VALUE).should('have.text', rule.thresholdValue); - }); -}); diff --git a/x-pack/plugins/security_solution/cypress/upgrade_e2e/threat_hunting/cases/import_case.cy.ts b/x-pack/plugins/security_solution/cypress/upgrade_e2e/threat_hunting/cases/import_case.cy.ts deleted file mode 100644 index 4eecc36fe928a..0000000000000 --- a/x-pack/plugins/security_solution/cypress/upgrade_e2e/threat_hunting/cases/import_case.cy.ts +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - ALL_CASES_CLOSED_CASES_STATS, - ALL_CASES_COMMENTS_COUNT, - ALL_CASES_IN_PROGRESS_CASES_STATS, - ALL_CASES_NAME, - ALL_CASES_NOT_PUSHED, - ALL_CASES_NUMBER_OF_ALERTS, - ALL_CASES_OPEN_CASES_STATS, - ALL_CASES_IN_PROGRESS_STATUS, -} from '../../../screens/all_cases'; -import { - CASES_TAGS, - CASE_CONNECTOR, - CASE_DETAILS_PAGE_TITLE, - CASE_DETAILS_USERNAMES, - CASE_EVENT_UPDATE, - CASE_IN_PROGRESS_STATUS, - CASE_SWITCH, - CASE_USER_ACTION, -} from '../../../screens/case_details'; -import { CASES_PAGE } from '../../../screens/kibana_navigation'; - -import { goToCaseDetails } from '../../../tasks/all_cases'; -import { deleteCase } from '../../../tasks/case_details'; -import { - navigateFromKibanaCollapsibleTo, - openKibanaNavigation, -} from '../../../tasks/kibana_navigation'; -import { login, visitWithoutDateRange } from '../../../tasks/login'; -import { importCase } from '../../../tasks/saved_objects'; - -import { KIBANA_SAVED_OBJECTS } from '../../../urls/navigation'; - -const CASE_NDJSON = '7_16_case.ndjson'; -const importedCase = { - title: '7.16 case to export', - user: 'glo', - initial: 'g', - reporter: 'glo@test.co', - tags: 'export case', - numberOfAlerts: '1', - numberOfComments: '2', - description: - "This is the description of the 7.16 case that I'm going to import in future versions.", - timeline: 'This is just a timeline', - status: 'In progress', - ruleName: 'This is a test', - participants: ['test', 'elastic'], - connector: 'Jira test', -}; -const updateStatusRegex = new RegExp( - `\\S${importedCase.user}marked case as${importedCase.status}\\S*\\s?(\\S*)?\\s?(\\S*)?` -); -const alertUpdateRegex = new RegExp( - `\\S${importedCase.user}added an alert from Unknown\\S*\\s?(\\S*)?\\s?(\\S*)?` -); -const incidentManagementSystemRegex = new RegExp( - `\\S${importedCase.participants[0]}selected ${importedCase.connector} as incident management system\\S*\\s?(\\S*)?\\s?(\\S*)?` -); -const DESCRIPTION = 0; -const TIMELINE = 1; -const LENS = 2; -const STATUS_UPDATE = 0; -const FIRST_ALERT_UPDATE = 1; -const SECOND_ALERT_UPDATE = 2; -const INCIDENT_MANAGEMENT_SYSTEM_UPDATE = 3; -const EXPECTED_NUMBER_OF_UPDATES = 4; -const REPORTER = 0; - -describe('Import case after upgrade', () => { - before(() => { - login(); - visitWithoutDateRange(KIBANA_SAVED_OBJECTS); - importCase(CASE_NDJSON); - openKibanaNavigation(); - navigateFromKibanaCollapsibleTo(CASES_PAGE); - }); - - after(() => { - deleteCase(); - }); - - it('Displays the correct number of opened cases on the cases page', () => { - const EXPECTED_NUMBER_OF_OPENED_CASES = '0'; - cy.get(ALL_CASES_OPEN_CASES_STATS).should('have.text', EXPECTED_NUMBER_OF_OPENED_CASES); - }); - - it('Displays the correct number of in progress cases on the cases page', () => { - const EXPECTED_NUMBER_OF_IN_PROGRESS_CASES = '1'; - cy.get(ALL_CASES_IN_PROGRESS_CASES_STATS).should( - 'have.text', - EXPECTED_NUMBER_OF_IN_PROGRESS_CASES - ); - }); - - it('Displays the correct number of closed cases on the cases page', () => { - const EXPECTED_NUMBER_OF_CLOSED_CASES = '0'; - cy.get(ALL_CASES_CLOSED_CASES_STATS).should('have.text', EXPECTED_NUMBER_OF_CLOSED_CASES); - }); - - it('Displays the correct case details on the cases page', () => { - cy.get(ALL_CASES_NAME).should('have.text', importedCase.title); - cy.get(ALL_CASES_NUMBER_OF_ALERTS).should('have.text', importedCase.numberOfAlerts); - cy.get(ALL_CASES_COMMENTS_COUNT).should('have.text', importedCase.numberOfComments); - cy.get(ALL_CASES_NOT_PUSHED).should('be.visible'); - cy.get(ALL_CASES_IN_PROGRESS_STATUS).should('be.visible'); - }); - - it('Displays the correct case details on the case details page', () => { - goToCaseDetails(); - - cy.get(CASE_DETAILS_PAGE_TITLE).should('have.text', importedCase.title); - cy.get(CASE_IN_PROGRESS_STATUS).should('exist'); - cy.get(CASE_SWITCH).should('have.attr', 'aria-checked', 'false'); - cy.get(CASE_USER_ACTION).eq(DESCRIPTION).should('have.text', importedCase.description); - cy.get(CASE_USER_ACTION).eq(TIMELINE).should('have.text', importedCase.timeline); - cy.get(CASE_USER_ACTION).eq(LENS).should('have.text', ''); - cy.get(CASE_EVENT_UPDATE).should('have.length', EXPECTED_NUMBER_OF_UPDATES); - cy.get(CASE_EVENT_UPDATE).eq(STATUS_UPDATE).invoke('text').should('match', updateStatusRegex); - cy.get(CASE_EVENT_UPDATE) - .eq(FIRST_ALERT_UPDATE) - .invoke('text') - .should('match', alertUpdateRegex); - cy.get(CASE_EVENT_UPDATE) - .eq(SECOND_ALERT_UPDATE) - .invoke('text') - .should('match', alertUpdateRegex); - cy.get(CASE_EVENT_UPDATE) - .eq(INCIDENT_MANAGEMENT_SYSTEM_UPDATE) - .invoke('text') - .should('match', incidentManagementSystemRegex); - // TODO: Needs data-test-subj - // cy.get(CASE_DETAILS_USERNAMES).should('have.length', EXPECTED_NUMBER_OF_PARTICIPANTS); - // TODO: Investigate why this changes, not reliable to verify - // cy.get(CASE_DETAILS_USERNAMES).eq(FIRST_PARTICIPANT).should('have.text', importedCase.user); - // cy.get(CASE_DETAILS_USERNAMES) - // .eq(SECOND_PARTICIPANT) - // .should('have.text', importedCase.participants[0]); - // cy.get(CASE_DETAILS_USERNAMES) - // .eq(THIRD_PARTICIPANT) - // .should('have.text', importedCase.participants[1]); - cy.get(CASE_DETAILS_USERNAMES).eq(REPORTER).should('have.text', importedCase.user); - cy.get(CASES_TAGS(importedCase.tags)).should('exist'); - cy.get(CASE_CONNECTOR).should('have.text', importedCase.connector); - }); -}); diff --git a/x-pack/plugins/security_solution/cypress/upgrade_e2e/threat_hunting/timeline/import_timeline.cy.ts b/x-pack/plugins/security_solution/cypress/upgrade_e2e/threat_hunting/timeline/import_timeline.cy.ts deleted file mode 100644 index 476ad34652a63..0000000000000 --- a/x-pack/plugins/security_solution/cypress/upgrade_e2e/threat_hunting/timeline/import_timeline.cy.ts +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import semver from 'semver'; -import { - CORRELATION_EVENT_TABLE_CELL, - DATA_PROVIDERS, - DATE_PICKER_END, - DATE_PICKER_START, - DESTINATION_IP_KPI, - GRAPH_TAB_BUTTON, - HOST_KPI, - QUERY_TAB_BUTTON, - NOTE_DESCRIPTION, - NOTE_PREVIEW, - NOTES_TAB_BUTTON, - PINNED_TAB_BUTTON, - PROCESS_KPI, - QUERY_EVENT_TABLE_CELL, - SOURCE_IP_KPI, - TIMELINE_CORRELATION_TAB, - TIMELINE_CORRELATION_INPUT, - TIMELINE_DESCRIPTION, - TIMELINE_QUERY, - TIMELINE_TITLE, - USER_KPI, -} from '../../../screens/timeline'; -import { - NOTE, - TIMELINES_USERNAME, - TIMELINE_NAME, - TIMELINES_DESCRIPTION, - TIMELINES_NOTES_COUNT, - TIMELINES_PINNED_EVENT_COUNT, -} from '../../../screens/timelines'; - -import { login, visitWithoutDateRange } from '../../../tasks/login'; -import { - closeTimeline, - deleteTimeline, - goToCorrelationTab, - goToNotesTab, - setKibanaTimezoneToUTC, -} from '../../../tasks/timeline'; -import { expandNotes, importTimeline, openTimeline } from '../../../tasks/timelines'; - -import { TIMELINES_URL } from '../../../urls/navigation'; - -const timeline = '7_15_timeline.ndjson'; -const username = 'elastic'; - -const timelineDetails = { - dateStart: 'Oct 10, 2020 @ 22:00:00.000', - dateEnd: 'Oct 11, 2030 @ 15:13:15.851', - queryTab: 'Query4', - queryTabAlt: 'Query2', - correlationTab: 'Correlation', - analyzerTab: 'Analyzer', - notesTab: 'Notes2', - pinnedTab: 'Pinned1', -}; - -const detectionAlert = { - message: '—', - eventCategory: 'file', - eventAction: 'initial_scan', - hostName: 'security-solution.local', - sourceIp: '127.0.0.1', - destinationIp: '127.0.0.2', - userName: 'Security Solution', -}; - -const event = { - timestamp: 'Nov 4, 2021 @ 10:09:29.438', - message: '—', - eventCategory: 'file', - eventAction: 'initial_scan', - hostName: 'security-solution.local', - sourceIp: '127.0.0.1', - destinationIp: '127.0.0.2', - userName: 'Security Solution', -}; - -describe('Import timeline after upgrade', () => { - before(() => { - login(); - visitWithoutDateRange(TIMELINES_URL); - importTimeline(timeline); - setKibanaTimezoneToUTC(); - }); - - after(() => { - closeTimeline(); - deleteTimeline(); - }); - - it('Displays the correct timeline details on the timelines page', () => { - cy.readFile(`cypress/fixtures/${timeline}`).then((file) => { - const timelineJson = JSON.parse(file); - const regex = new RegExp( - `\\S${timelineJson.globalNotes[0].createdBy}added a note\\S*\\s?(\\S*)?\\s?(\\S*)?${timelineJson.globalNotes[0].createdBy} added a note${timelineJson.globalNotes[0].note}` - ); - - cy.get(TIMELINE_NAME).should('have.text', timelineJson.title); - cy.get(TIMELINES_DESCRIPTION).should('have.text', timelineJson.description); - cy.get(TIMELINES_USERNAME).should('have.text', username); - cy.get(TIMELINES_NOTES_COUNT).should('have.text', timelineJson.globalNotes.length.toString()); - cy.get(TIMELINES_PINNED_EVENT_COUNT).should( - 'have.text', - timelineJson.pinnedEventIds.length.toString() - ); - - expandNotes(); - - cy.get(NOTE).invoke('text').should('match', regex); - }); - }); - - it('Displays the correct timeline details inside the query tab', () => { - let expectedQueryTab = timelineDetails.queryTab; - if (semver.lt(Cypress.env('ORIGINAL_VERSION'), '7.10.0')) { - expectedQueryTab = timelineDetails.queryTabAlt; - } - - openTimeline(); - - cy.readFile(`cypress/fixtures/${timeline}`).then((file) => { - const timelineJson = JSON.parse(file); - - cy.get(TIMELINE_TITLE).should('have.text', timelineJson.title); - cy.get(TIMELINE_DESCRIPTION).should('have.text', timelineJson.description); - cy.get(DATA_PROVIDERS).should('have.length', timelineJson.dataProviders.length.toString()); - cy.get(DATA_PROVIDERS) - .invoke('text') - .then((value) => { - expect(value.replace(/"/g, '')).to.eq(timelineJson.dataProviders[0].name); - }); - cy.get(PROCESS_KPI).should('contain', '0'); - cy.get(USER_KPI).should('contain', '0'); - cy.get(HOST_KPI).should('contain', '1'); - cy.get(SOURCE_IP_KPI).should('contain', '1'); - cy.get(DESTINATION_IP_KPI).should('contain', '1'); - cy.get(DATE_PICKER_START).should('contain', timelineDetails.dateStart); - cy.get(DATE_PICKER_END).should('contain', timelineDetails.dateEnd); - cy.get(TIMELINE_QUERY).should( - 'have.text', - timelineJson.kqlQuery.filterQuery.kuery.expression - ); - cy.get(QUERY_TAB_BUTTON).should('have.text', expectedQueryTab); - cy.get(TIMELINE_CORRELATION_TAB).should('have.text', timelineDetails.correlationTab); - cy.get(GRAPH_TAB_BUTTON).should('have.text', timelineDetails.analyzerTab).and('be.disabled'); - cy.get(NOTES_TAB_BUTTON).should('have.text', timelineDetails.notesTab); - cy.get(PINNED_TAB_BUTTON).should('have.text', timelineDetails.pinnedTab); - - cy.get(QUERY_EVENT_TABLE_CELL).eq(1).should('contain', detectionAlert.message); - cy.get(QUERY_EVENT_TABLE_CELL).eq(2).should('contain', detectionAlert.eventCategory); - cy.get(QUERY_EVENT_TABLE_CELL).eq(3).should('contain', detectionAlert.eventAction); - cy.get(QUERY_EVENT_TABLE_CELL).eq(4).should('contain', detectionAlert.hostName); - cy.get(QUERY_EVENT_TABLE_CELL).eq(5).should('contain', detectionAlert.sourceIp); - cy.get(QUERY_EVENT_TABLE_CELL).eq(6).should('contain', detectionAlert.destinationIp); - cy.get(QUERY_EVENT_TABLE_CELL).eq(7).should('contain', detectionAlert.userName); - - cy.get(QUERY_EVENT_TABLE_CELL).eq(8).should('contain', event.timestamp); - cy.get(QUERY_EVENT_TABLE_CELL).eq(9).should('contain', event.message); - cy.get(QUERY_EVENT_TABLE_CELL).eq(10).should('contain', event.eventCategory); - cy.get(QUERY_EVENT_TABLE_CELL).eq(11).should('contain', event.eventAction); - cy.get(QUERY_EVENT_TABLE_CELL).eq(12).should('contain', event.hostName); - cy.get(QUERY_EVENT_TABLE_CELL).eq(13).should('contain', event.sourceIp); - cy.get(QUERY_EVENT_TABLE_CELL).eq(14).should('contain', event.destinationIp); - cy.get(QUERY_EVENT_TABLE_CELL).eq(15).should('contain', event.userName); - }); - }); - - it('Displays the correct timeline details inside the correlation tab', () => { - goToCorrelationTab(); - - cy.get(TIMELINE_CORRELATION_INPUT).should('be.empty'); - cy.get(CORRELATION_EVENT_TABLE_CELL).should('not.exist'); - }); - - it('Displays the correct timeline details inside the notes tab', () => { - goToNotesTab(); - - cy.readFile(`cypress/fixtures/${timeline}`).then((file) => { - const timelineJson = JSON.parse(file); - const descriptionRegex = new RegExp( - `\\S${username}added description\\S*\\s?(\\S*)?\\s?(\\S*)?${timelineJson.description}` - ); - const noteRegex = new RegExp( - `\\S${timelineJson.globalNotes[0].createdBy}added a note\\S*\\s?(\\S*)?\\s?(\\S*)?${timelineJson.globalNotes[0].createdBy} added a note${timelineJson.globalNotes[0].note}` - ); - - cy.get(NOTE_DESCRIPTION).invoke('text').should('match', descriptionRegex); - cy.get(NOTE_PREVIEW).last().invoke('text').should('match', noteRegex); - }); - }); -}); diff --git a/x-pack/plugins/security_solution/package.json b/x-pack/plugins/security_solution/package.json index a564416154176..e5e4b0b71caf8 100644 --- a/x-pack/plugins/security_solution/package.json +++ b/x-pack/plugins/security_solution/package.json @@ -9,16 +9,10 @@ "build-beat-doc": "node scripts/beat_docs/build.js && node ../../../scripts/eslint ../timelines/server/utils/beat_schema/fields.ts --fix", "cypress": "../../../node_modules/.bin/cypress", "cypress:open": "TZ=UTC node ./scripts/start_cypress_parallel open --spec './cypress/e2e/**/*.cy.ts' --config-file ./cypress/cypress.config.ts --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config", - "cypress:open:ccs": "yarn cypress:open --config specPattern=./cypress/ccs_e2e/**/*.cy.ts", - "cypress:open:upgrade": "yarn cypress:open --config specPattern=./cypress/upgrade_e2e/**/*.cy.ts", "cypress:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/{,!(investigations,explore)/**/}*.cy.ts'; status=$?; yarn junit:merge && exit $status", "cypress:run:cases": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/explore/cases/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", - "cypress:run:firefox": "yarn cypress:run:reporter --browser firefox --spec './cypress/e2e/**/*.cy.ts'; status=$?; yarn junit:merge && exit $status", "cypress:run:reporter": "TZ=UTC node ./scripts/start_cypress_parallel run --config-file ./cypress/cypress_ci.config.ts --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json", "cypress:run:respops": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/(detection_alerts|detection_rules|exceptions)/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", - "cypress:run:ccs": "yarn cypress:run:reporter --browser chrome --config specPattern=./cypress/ccs_e2e/**/*.cy.ts; status=$?; yarn junit:merge && exit $status", - "cypress:run-as-ci:firefox": "node --max-old-space-size=2048 ../../../scripts/functional_tests --config ../../test/security_solution_cypress/config.firefox.ts", - "cypress:run:upgrade": "yarn cypress:run:reporter --browser chrome --config specPattern=./cypress/upgrade_e2e/**/*.cy.ts", "cypress:dw:open": "node ./scripts/start_cypress_parallel open --config-file ./public/management/cypress.config.ts ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/cli_config", "cypress:dw:run": "node ./scripts/start_cypress_parallel run --config-file ./public/management/cypress.config.ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/cli_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json; status=$?; yarn junit:merge && exit $status", "cypress:dw:endpoint:run": "node ./scripts/start_cypress_parallel run --config-file ./public/management/cypress_endpoint.config.ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/endpoint_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json --concurrency 1; status=$?; yarn junit:merge && exit $status", diff --git a/x-pack/test/security_solution_cypress/ccs_config.ts b/x-pack/test/security_solution_cypress/ccs_config.ts deleted file mode 100644 index 8e679c071ac0f..0000000000000 --- a/x-pack/test/security_solution_cypress/ccs_config.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { FtrConfigProviderContext } from '@kbn/test'; - -import { SecuritySolutionCypressCcsTestRunner } from './runner'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const securitySolutionCypressConfig = await readConfigFile(require.resolve('./config.ts')); - return { - ...securitySolutionCypressConfig.getAll(), - - testRunner: SecuritySolutionCypressCcsTestRunner, - }; -} diff --git a/x-pack/test/security_solution_cypress/config.firefox.ts b/x-pack/test/security_solution_cypress/config.firefox.ts deleted file mode 100644 index d7047c043443d..0000000000000 --- a/x-pack/test/security_solution_cypress/config.firefox.ts +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { FtrConfigProviderContext } from '@kbn/test'; -import { CA_CERT_PATH } from '@kbn/dev-utils'; -import { SecuritySolutionConfigurableCypressTestRunner } from './runner'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const kibanaCommonTestsConfig = await readConfigFile( - require.resolve('../../../test/common/config.js') - ); - const xpackFunctionalTestsConfig = await readConfigFile( - require.resolve('../functional/config.base.js') - ); - - return { - ...kibanaCommonTestsConfig.getAll(), - - browser: { - type: 'firefox', - acceptInsecureCerts: true, - }, - - esTestCluster: { - ...xpackFunctionalTestsConfig.get('esTestCluster'), - serverArgs: [ - ...xpackFunctionalTestsConfig.get('esTestCluster.serverArgs'), - // define custom es server here - // API Keys is enabled at the top level - 'xpack.security.enabled=true', - ], - }, - - kbnTestServer: { - ...xpackFunctionalTestsConfig.get('kbnTestServer'), - serverArgs: [ - ...xpackFunctionalTestsConfig.get('kbnTestServer.serverArgs'), - '--csp.strict=false', - // define custom kibana server args here - `--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`, - ], - }, - - testRunner: SecuritySolutionConfigurableCypressTestRunner, - }; -} diff --git a/x-pack/test/security_solution_cypress/runner.ts b/x-pack/test/security_solution_cypress/runner.ts index 3a82fc8e14a62..9514e63a12634 100644 --- a/x-pack/test/security_solution_cypress/runner.ts +++ b/x-pack/test/security_solution_cypress/runner.ts @@ -5,12 +5,8 @@ * 2.0. */ -import { resolve } from 'path'; import Url from 'url'; -import { withProcRunner } from '@kbn/dev-proc-runner'; -import semver from 'semver'; - import { FtrProviderContext } from '../common/ftr_provider_context'; export type { FtrProviderContext } from '../common/ftr_provider_context'; @@ -36,58 +32,3 @@ export async function SecuritySolutionConfigurableCypressTestRunner({ ELASTICSEARCH_PASSWORD: config.get('servers.elasticsearch.password'), }; } - -export async function SecuritySolutionCypressCcsTestRunner({ getService }: FtrProviderContext) { - const log = getService('log'); - - await withProcRunner(log, async (procs) => { - await procs.run('cypress', { - cmd: 'yarn', - args: ['cypress:run:ccs'], - cwd: resolve(__dirname, '../../plugins/security_solution'), - env: { - FORCE_COLOR: '1', - CYPRESS_BASE_URL: process.env.TEST_KIBANA_URL, - CYPRESS_ELASTICSEARCH_URL: process.env.TEST_ES_URL, - CYPRESS_ELASTICSEARCH_USERNAME: process.env.ELASTICSEARCH_USERNAME, - CYPRESS_ELASTICSEARCH_PASSWORD: process.env.ELASTICSEARCH_PASSWORD, - CYPRESS_CCS_KIBANA_URL: process.env.TEST_KIBANA_URLDATA, - CYPRESS_CCS_ELASTICSEARCH_URL: process.env.TEST_ES_URLDATA, - CYPRESS_CCS_REMOTE_NAME: process.env.TEST_CCS_REMOTE_NAME, - ...process.env, - }, - wait: true, - }); - }); -} - -export async function SecuritySolutionCypressUpgradeCliTestRunner({ - getService, -}: FtrProviderContext) { - const log = getService('log'); - let command = ''; - - if (semver.gt(process.env.ORIGINAL_VERSION!, '7.10.0')) { - command = 'cypress:run:upgrade'; - } else { - command = 'cypress:run:upgrade:old'; - } - - await withProcRunner(log, async (procs) => { - await procs.run('cypress', { - cmd: 'yarn', - args: [command], - cwd: resolve(__dirname, '../../plugins/security_solution'), - env: { - FORCE_COLOR: '1', - CYPRESS_BASE_URL: process.env.TEST_KIBANA_URL, - CYPRESS_ELASTICSEARCH_URL: process.env.TEST_ES_URL, - CYPRESS_ELASTICSEARCH_USERNAME: process.env.TEST_ES_USER, - CYPRESS_ELASTICSEARCH_PASSWORD: process.env.TEST_ES_PASS, - CYPRESS_ORIGINAL_VERSION: process.env.ORIGINAL_VERSION, - ...process.env, - }, - wait: true, - }); - }); -} diff --git a/x-pack/test/security_solution_cypress/upgrade_config.ts b/x-pack/test/security_solution_cypress/upgrade_config.ts deleted file mode 100644 index 221cf7b30e061..0000000000000 --- a/x-pack/test/security_solution_cypress/upgrade_config.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { FtrConfigProviderContext } from '@kbn/test'; - -import { SecuritySolutionCypressUpgradeCliTestRunner } from './runner'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const kibanaCommonTestsConfig = await readConfigFile( - require.resolve('../../../test/common/config.js') - ); - - return { - ...kibanaCommonTestsConfig.getAll(), - testRunner: SecuritySolutionCypressUpgradeCliTestRunner, - }; -} From 924b8e90742f6899a54e123149513fdc3b00b1bb Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 9 Aug 2023 20:28:41 +0100 Subject: [PATCH 27/41] chore(NA): upgrade chromedriver to v115 (#163520) This PR upgrades chromedriver into the latest version available. --- package.json | 2 +- src/dev/ci_setup/setup_env.sh | 1 + yarn.lock | 18 +++++++++--------- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 53f5526bf73dd..115408ec8a9ff 100644 --- a/package.json +++ b/package.json @@ -1395,7 +1395,7 @@ "blob-polyfill": "^7.0.20220408", "callsites": "^3.1.0", "chance": "1.0.18", - "chromedriver": "^114.0.2", + "chromedriver": "^115.0.1", "clean-webpack-plugin": "^3.0.0", "cli-table3": "^0.6.1", "compression-webpack-plugin": "^4.0.0", diff --git a/src/dev/ci_setup/setup_env.sh b/src/dev/ci_setup/setup_env.sh index 085f433a2218b..2bcf3775183e5 100644 --- a/src/dev/ci_setup/setup_env.sh +++ b/src/dev/ci_setup/setup_env.sh @@ -128,6 +128,7 @@ export PATH="$PATH:$yarnGlobalDir" # use a proxy to fetch chromedriver/geckodriver asset export GECKODRIVER_CDNURL="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache" +export CHROMEDRIVER_LEGACY_CDNURL="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache" export CHROMEDRIVER_CDNURL="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache" export CHROMEDRIVER_CDNBINARIESURL="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache" export RE2_DOWNLOAD_MIRROR="https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache" diff --git a/yarn.lock b/yarn.lock index 952c808afb066..b6a5b22115b05 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12432,14 +12432,14 @@ chrome-trace-event@^1.0.2: dependencies: tslib "^1.9.0" -chromedriver@^114.0.2: - version "114.0.2" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-114.0.2.tgz#1ddaa6738f2b60e6b832a39f791c8c54bf840837" - integrity sha512-v0qrXRBknbxqmtklG7RWOe3TJ/dLaHhtB0jVxE7BAdYERxUjEaNRyqBwoGgVfQDibHCB0swzvzsj158nnfPgZw== +chromedriver@^115.0.1: + version "115.0.1" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-115.0.1.tgz#76cbf35f16e0c1f5e29ab821fb3b8b06d22c3e40" + integrity sha512-faE6WvIhXfhnoZ3nAxUXYzeDCKy612oPwpkUp0mVkA7fZPg2JHSUiYOQhUYgzHQgGvDWD5Fy2+M2xV55GKHBVQ== dependencies: "@testim/chrome-version" "^1.1.3" axios "^1.4.0" - compare-versions "^5.0.3" + compare-versions "^6.0.0" extract-zip "^2.0.1" https-proxy-agent "^5.0.1" proxy-from-env "^1.1.0" @@ -12846,10 +12846,10 @@ compare-versions@3.5.1: resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.5.1.tgz#26e1f5cf0d48a77eced5046b9f67b6b61075a393" integrity sha512-9fGPIB7C6AyM18CJJBHt5EnCZDG3oiTJYy0NjfIAGjKpzv0tkxWko7TNQHF5ymqm7IH03tqmeuBxtvD+Izh6mg== -compare-versions@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-5.0.3.tgz#a9b34fea217472650ef4a2651d905f42c28ebfd7" - integrity sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A== +compare-versions@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.0.tgz#3f2131e3ae93577df111dba133e6db876ffe127a" + integrity sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg== component-emitter@^1.2.0, component-emitter@^1.2.1: version "1.2.1" From 13a74337bd8526565262ba21c16d4df016bbc49e Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Wed, 9 Aug 2023 15:05:00 -0500 Subject: [PATCH 28/41] [Enterprise Search] chore: break-up public tests (#163358) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Our public folder tests are taking 35-40+m to run in CI. To try and mitigate this we are splitting the jest tests configs to each of the application folders to allow workers to run them separately. I also added a `jest.config.dev.js` file to the `enterprise_search` plugin root which allows you to run `./jest.sh` to run all of the projects with a single command locally. On my laptop I am seeing this take a similar amount of time to run all the projects, but it can vary. before (3 projects) ``` Test Suites: 880 passed, 880 total Tests: 5513 passed, 5513 total Snapshots: 29 passed, 29 total Time: 286.798 s Ran all test suites in 3 projects. ✨ Done in 289.12s. ``` after (14 projects) ``` Test Suites: 884 passed, 884 total Tests: 5513 passed, 5513 total Snapshots: 29 passed, 29 total Time: 301.281 s Ran all test suites in 14 projects. ✨ Done in 303.59s. ``` --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../enterprise_search/jest.config.dev.js | 16 +++++++++++ .../applications/analytics/jest.config.js | 26 +++++++++++++++++ .../applications/app_search/jest.config.js | 26 +++++++++++++++++ .../applications/applications/jest.config.js | 26 +++++++++++++++++ .../applications/elasticsearch/jest.config.js | 26 +++++++++++++++++ .../enterprise_search_content/jest.config.js | 28 +++++++++++++++++++ .../enterprise_search_overview/jest.config.js | 28 +++++++++++++++++++ .../public/applications/esre/jest.config.js | 26 +++++++++++++++++ .../search_experiences/jest.config.js | 26 +++++++++++++++++ .../public/applications/shared/jest.config.js | 26 +++++++++++++++++ .../applications/vector_search/jest.config.js | 26 +++++++++++++++++ .../workplace_search/jest.config.js | 26 +++++++++++++++++ .../enterprise_search/public/jest.config.js | 6 +++- 13 files changed, 311 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/enterprise_search/jest.config.dev.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/analytics/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/app_search/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/applications/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/elasticsearch/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/esre/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/search_experiences/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/shared/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/vector_search/jest.config.js create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/jest.config.js diff --git a/x-pack/plugins/enterprise_search/jest.config.dev.js b/x-pack/plugins/enterprise_search/jest.config.dev.js new file mode 100644 index 0000000000000..638235a6deef5 --- /dev/null +++ b/x-pack/plugins/enterprise_search/jest.config.dev.js @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../', + projects: [ + '/x-pack/plugins/enterprise_search/public/**/jest.config.js', + '/x-pack/plugins/enterprise_search/common/**/jest.config.js', + '/x-pack/plugins/enterprise_search/server/**/jest.config.js', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/analytics/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/analytics/jest.config.js new file mode 100644 index 0000000000000..58b5334165ec5 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/analytics/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/plugins/enterprise_search/public/applications/analytics'], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/analytics', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/app_search/jest.config.js new file mode 100644 index 0000000000000..7d591c369c18b --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/plugins/enterprise_search/public/applications/app_search'], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/app_search', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/applications/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/applications/jest.config.js new file mode 100644 index 0000000000000..1e04c0845ec9f --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/applications/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/plugins/enterprise_search/public/applications/applications'], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/applications', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/elasticsearch/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/elasticsearch/jest.config.js new file mode 100644 index 0000000000000..ab90da605f2b3 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/elasticsearch/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/plugins/enterprise_search/public/applications/elasticsearch'], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/elasticsearch', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/jest.config.js new file mode 100644 index 0000000000000..a55b8bbc715f4 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/jest.config.js @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: [ + '/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content', + ], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/jest.config.js new file mode 100644 index 0000000000000..fd5a6db3b8e0c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/jest.config.js @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: [ + '/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview', + ], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/esre/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/esre/jest.config.js new file mode 100644 index 0000000000000..e6ef9e507cf27 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/esre/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/plugins/enterprise_search/public/applications/esre'], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/esre', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/search_experiences/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/search_experiences/jest.config.js new file mode 100644 index 0000000000000..1e39c00ae9893 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/search_experiences/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/plugins/enterprise_search/public/applications/search_experiences'], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/search_experiences', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/shared/jest.config.js new file mode 100644 index 0000000000000..5ee13cc30aeaf --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/plugins/enterprise_search/public/applications/shared'], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/shared', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/vector_search/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/vector_search/jest.config.js new file mode 100644 index 0000000000000..24158650aa75f --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/vector_search/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/plugins/enterprise_search/public/applications/vector_search'], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/vector_search', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/jest.config.js b/x-pack/plugins/enterprise_search/public/applications/workplace_search/jest.config.js new file mode 100644 index 0000000000000..6ae1b5b9b1a84 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/jest.config.js @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../../../..', + roots: ['/x-pack/plugins/enterprise_search/public/applications/workplace_search'], + collectCoverage: true, + coverageReporters: ['text', 'html'], + collectCoverageFrom: [ + '/x-pack/plugins/enterprise_search/public/applications/**/*.{ts,tsx}', + '!/x-pack/plugins/enterprise_search/public/*.ts', + '!/x-pack/plugins/enterprise_search/server/*.ts', + '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', + ], + coverageDirectory: + '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search/public/applications/workplace_search', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], +}; diff --git a/x-pack/plugins/enterprise_search/public/jest.config.js b/x-pack/plugins/enterprise_search/public/jest.config.js index c527b85707b42..fec5a831f2fee 100644 --- a/x-pack/plugins/enterprise_search/public/jest.config.js +++ b/x-pack/plugins/enterprise_search/public/jest.config.js @@ -8,11 +8,15 @@ module.exports = { preset: '@kbn/test', rootDir: '../../../..', + /** all nested directories have their own Jest config file */ + testMatch: [ + '/x-pack/plugins/enterprise_search/public/applications/*.test.{js,mjs,ts,tsx}', + ], roots: ['/x-pack/plugins/enterprise_search/public'], collectCoverage: true, coverageReporters: ['text', 'html'], collectCoverageFrom: [ - '/x-pack/plugins/enterprise_search/**/*.{ts,tsx}', + '/x-pack/plugins/enterprise_search/public/applications/*.{ts,tsx}', '!/x-pack/plugins/enterprise_search/public/*.ts', '!/x-pack/plugins/enterprise_search/server/*.ts', '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', From 53965c97a1176127916870d2ac01f2ec2fdb95bb Mon Sep 17 00:00:00 2001 From: Jeramy Soucy Date: Wed, 9 Aug 2023 16:39:34 -0400 Subject: [PATCH 29/41] Bump elastic-apm-node 3.49.0 -> 3.49.1 (#163522) ## Summary Upgrades `elastic-apm-node` from 3.49.0 to 3.49.1 --- package.json | 2 +- yarn.lock | 42 +++++++++++++++++++++++++----------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/package.json b/package.json index 115408ec8a9ff..5197b38d33fa0 100644 --- a/package.json +++ b/package.json @@ -837,7 +837,7 @@ "deep-freeze-strict": "^1.1.1", "deepmerge": "^4.2.2", "del": "^6.1.0", - "elastic-apm-node": "^3.49.0", + "elastic-apm-node": "^3.49.1", "email-addresses": "^5.0.0", "execa": "^4.0.2", "expiry-js": "0.1.7", diff --git a/yarn.lock b/yarn.lock index b6a5b22115b05..55a4546d3fa43 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10314,10 +10314,10 @@ acorn-globals@^7.0.0: acorn "^8.1.0" acorn-walk "^8.0.2" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-assertions@^1.7.6, acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== acorn-jsx@^5.3.1: version "5.3.2" @@ -10358,10 +10358,10 @@ acorn@^7.0.0, acorn@^7.4.0, acorn@^7.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.4, acorn@^8.1.0, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" - integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== +acorn@^8.0.4, acorn@^8.1.0, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0, acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== address@^1.0.1: version "1.1.2" @@ -12475,6 +12475,11 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== +cjs-module-lexer@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + clamp@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/clamp/-/clamp-1.0.1.tgz#66a0e64011816e37196828fdc8c8c147312c8634" @@ -14763,10 +14768,10 @@ elastic-apm-node@3.46.0: traverse "^0.6.6" unicode-byte-truncate "^1.0.0" -elastic-apm-node@^3.49.0: - version "3.49.0" - resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.49.0.tgz#89ae052fbd81787ef012fe0f304756d9249584ab" - integrity sha512-6EyysTNdJqBxd13ZyPHaew1IDdiQKvG29K/rvbYZPyNRL4T7Asi8yoVBs3/mfVWOjheLqoxeyPq2EL1lSO/dtg== +elastic-apm-node@^3.49.1: + version "3.49.1" + resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.49.1.tgz#c000936a1b7f062e4dd502cd3617ebe97d4d9786" + integrity sha512-k1kQ/exFqodZOoZSRJ3Csbdo7dtRs/uORBlRTyV2takYa1OIN7o9dvZwd8+eEPOUz4qaeRyVY8X9X2krk9GO/g== dependencies: "@elastic/ecs-pino-format" "^1.2.0" "@opentelemetry/api" "^1.4.1" @@ -14787,7 +14792,7 @@ elastic-apm-node@^3.49.0: fast-safe-stringify "^2.0.7" fast-stream-to-buffer "^1.0.0" http-headers "^3.0.2" - import-in-the-middle "1.3.5" + import-in-the-middle "1.4.2" is-native "^1.0.1" lru-cache "^6.0.0" measured-reporting "^1.51.1" @@ -18033,11 +18038,14 @@ import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" -import-in-the-middle@1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.3.5.tgz#78384fbcfc7c08faf2b1f61cb94e7dd25651df9c" - integrity sha512-yzHlBqi1EBFrkieAnSt8eTgO5oLSl+YJ7qaOpUH/PMqQOMZoQ/RmDlwnTLQrwYto+gHYjRG+i/IbsB1eDx32NQ== +import-in-the-middle@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz#2a266676e3495e72c04bbaa5ec14756ba168391b" + integrity sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw== dependencies: + acorn "^8.8.2" + acorn-import-assertions "^1.9.0" + cjs-module-lexer "^1.2.2" module-details-from-path "^1.0.3" import-lazy@^2.1.0: From 0cfea614242c7a64fc6dff3dab0b135d00b58940 Mon Sep 17 00:00:00 2001 From: Steph Milovic Date: Wed, 9 Aug 2023 15:05:28 -0600 Subject: [PATCH 30/41] Add `getExistingIndices` method to data views client api (#163448) --- .../common/data_views/data_views.test.ts | 32 +++++++++++ .../common/data_views/data_views.ts | 43 ++++++++++++++ .../data_views/common/data_views/utils.ts | 29 ++++++++++ .../common/containers/source/index.test.tsx | 1 + .../sourcerer/get_sourcerer_data_view.test.ts | 56 +++++++++++++++++++ .../sourcerer/get_sourcerer_data_view.ts | 25 +-------- 6 files changed, 162 insertions(+), 24 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/common/containers/sourcerer/get_sourcerer_data_view.test.ts diff --git a/src/plugins/data_views/common/data_views/data_views.test.ts b/src/plugins/data_views/common/data_views/data_views.test.ts index e6d09710fe016..2ea7726cc2bb9 100644 --- a/src/plugins/data_views/common/data_views/data_views.test.ts +++ b/src/plugins/data_views/common/data_views/data_views.test.ts @@ -629,4 +629,36 @@ describe('IndexPatterns', () => { expect(apiClient.getFieldsForWildcard.mock.calls[0][0].allowNoIndex).toBe(true); }); }); + + describe('getExistingIndices', () => { + test('getExistingIndices returns the valid matched indices', async () => { + apiClient.getFieldsForWildcard = jest + .fn() + .mockResolvedValueOnce({ fields: ['length'] }) + .mockResolvedValue({ fields: [] }); + const patternList = await indexPatterns.getExistingIndices(['packetbeat-*', 'filebeat-*']); + expect(apiClient.getFieldsForWildcard).toBeCalledTimes(2); + expect(patternList.length).toBe(1); + }); + + test('getExistingIndices checks the positive pattern if provided with a negative pattern', async () => { + const mockFn = jest.fn().mockResolvedValue({ fields: ['length'] }); + apiClient.getFieldsForWildcard = mockFn; + const patternList = await indexPatterns.getExistingIndices(['-filebeat-*', 'filebeat-*']); + expect(mockFn.mock.calls[0][0].pattern).toEqual('filebeat-*'); + expect(mockFn.mock.calls[1][0].pattern).toEqual('filebeat-*'); + expect(patternList).toEqual(['-filebeat-*', 'filebeat-*']); + }); + + test('getExistingIndices handles an error', async () => { + apiClient.getFieldsForWildcard = jest + .fn() + .mockImplementationOnce(async () => { + throw new DataViewMissingIndices('Catch me if you can!'); + }) + .mockImplementation(() => Promise.resolve({ fields: ['length'] })); + const patternList = await indexPatterns.getExistingIndices(['packetbeat-*', 'filebeat-*']); + expect(patternList).toEqual(['filebeat-*']); + }); + }); }); diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts index 469fd2a1fa61e..9537526046266 100644 --- a/src/plugins/data_views/common/data_views/data_views.ts +++ b/src/plugins/data_views/common/data_views/data_views.ts @@ -7,10 +7,12 @@ */ import { i18n } from '@kbn/i18n'; +import { defer, from } from 'rxjs'; import type { PublicMethodsOf } from '@kbn/utility-types'; import { castEsToKbnFieldTypeName } from '@kbn/field-types'; import { FieldFormatsStartCommon, FORMATS_UI_SETTINGS } from '@kbn/field-formats-plugin/common'; import { v4 as uuidv4 } from 'uuid'; +import { rateLimitingForkJoin } from './utils'; import { PersistenceAPI } from '../types'; import { createDataViewCache } from '.'; @@ -236,6 +238,12 @@ export interface DataViewsServicePublicMethods { * @param options - options for getting fields */ getFieldsForWildcard: (options: GetFieldsOptions) => Promise; + /** + * Get existing index pattern list by providing string array index pattern list. + * @param indices - index pattern list + * @returns index pattern list of index patterns that match indices + */ + getExistingIndices: (indices: string[]) => Promise; /** * Get list of data view ids. * @param refresh - clear cache and fetch from server @@ -505,6 +513,41 @@ export class DataViewsService { return fields; }; + /** + * Get existing index pattern list by providing string array index pattern list. + * @param indices index pattern list + * @returns index pattern list + */ + getExistingIndices = async (indices: string[]): Promise => { + const indicesObs = indices.map((pattern) => { + // when checking a negative pattern, check if the positive pattern exists + const indexToQuery = pattern.trim().startsWith('-') + ? pattern.trim().substring(1) + : pattern.trim(); + return defer(() => + from( + this.getFieldsForWildcard({ + // check one field to keep request fast/small + fields: ['_id'], + // true so no errors thrown in browser + allowNoIndex: true, + pattern: indexToQuery, + }) + ) + ); + }); + + return new Promise((resolve) => { + rateLimitingForkJoin(indicesObs, 3, []).subscribe((value) => { + resolve(value.map((v) => v.length > 0)); + }); + }) + .then((allPatterns: boolean[]) => + indices.filter((pattern, i, self) => self.indexOf(pattern) === i && allPatterns[i]) + ) + .catch(() => indices); + }; + /** * Get field list by providing an index patttern (or spec). * @param options options for getting field list diff --git a/src/plugins/data_views/common/data_views/utils.ts b/src/plugins/data_views/common/data_views/utils.ts index a5d0447f79339..ec1c41fc3eaca 100644 --- a/src/plugins/data_views/common/data_views/utils.ts +++ b/src/plugins/data_views/common/data_views/utils.ts @@ -6,6 +6,8 @@ * Side Public License, v 1. */ +import { catchError, from, Observable, of } from 'rxjs'; +import { mergeMap, last, map, toArray } from 'rxjs/operators'; import type { RuntimeField, RuntimeFieldSpec, RuntimePrimitiveTypes } from '../types'; export const removeFieldAttrs = (runtimeField: RuntimeField): RuntimeFieldSpec => { @@ -23,3 +25,30 @@ export const removeFieldAttrs = (runtimeField: RuntimeField): RuntimeFieldSpec = ...fieldsTypeOnly, }; }; + +const MAX_CONCURRENT_REQUESTS = 3; +/** + * Helper function to run forkJoin + * with restrictions on how many input observables can be subscribed to concurrently + */ +export function rateLimitingForkJoin( + observables: Array>, + maxConcurrentRequests = MAX_CONCURRENT_REQUESTS, + failValue: T +): Observable { + return from(observables).pipe( + mergeMap( + (observable, index) => + observable.pipe( + last(), + map((value) => ({ index, value })), + catchError(() => of({ index, value: failValue })) + ), + maxConcurrentRequests + ), + toArray(), + map((indexedObservables) => + indexedObservables.sort((l, r) => l.index - r.index).map((obs) => obs.value) + ) + ); +} diff --git a/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx index 84c94f81d026f..c5251dba05744 100644 --- a/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/source/index.test.tsx @@ -67,6 +67,7 @@ describe('source/index.tsx', () => { }); }, getFieldsForWildcard: async () => Promise.resolve(), + getExistingIndices: async (indices: string[]) => Promise.resolve(indices), }, search: { search: jest.fn().mockReturnValue({ diff --git a/x-pack/plugins/security_solution/public/common/containers/sourcerer/get_sourcerer_data_view.test.ts b/x-pack/plugins/security_solution/public/common/containers/sourcerer/get_sourcerer_data_view.test.ts new file mode 100644 index 0000000000000..cc4921380fac8 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/containers/sourcerer/get_sourcerer_data_view.test.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getSourcererDataView } from './get_sourcerer_data_view'; +import type { DataViewsService } from '@kbn/data-views-plugin/common'; + +const dataViewId = 'test-id'; +const dataViewsService = { + get: jest.fn().mockResolvedValue({ + toSpec: jest.fn().mockReturnValue({ + id: 'test-id', + fields: {}, + runtimeFieldMap: {}, + }), + getIndexPattern: jest.fn().mockReturnValue('test-pattern'), + fields: {}, + }), + getExistingIndices: jest.fn().mockResolvedValue(['test-pattern']), +} as unknown as jest.Mocked; +describe('getSourcererDataView', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + // Tests that the function returns a SourcererDataView object with the expected properties + it('should return a SourcererDataView object with the expected properties', async () => { + const result = await getSourcererDataView(dataViewId, dataViewsService); + expect(result).toEqual({ + loading: false, + id: 'test-id', + title: 'test-pattern', + indexFields: {}, + fields: {}, + patternList: ['test-pattern'], + dataView: { + id: 'test-id', + fields: {}, + runtimeFieldMap: {}, + }, + browserFields: {}, + runtimeMappings: {}, + }); + }); + it('should call dataViewsService.get with the correct arguments', async () => { + await getSourcererDataView(dataViewId, dataViewsService); + expect(dataViewsService.get).toHaveBeenCalledWith(dataViewId, true, false); + }); + + it('should call dataViewsService.getExistingIndices with the correct arguments', async () => { + await getSourcererDataView(dataViewId, dataViewsService); + expect(dataViewsService.getExistingIndices).toHaveBeenCalledWith(['test-pattern']); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/containers/sourcerer/get_sourcerer_data_view.ts b/x-pack/plugins/security_solution/public/common/containers/sourcerer/get_sourcerer_data_view.ts index 7f40819bfb41d..a3cc1a8041b4c 100644 --- a/x-pack/plugins/security_solution/public/common/containers/sourcerer/get_sourcerer_data_view.ts +++ b/x-pack/plugins/security_solution/public/common/containers/sourcerer/get_sourcerer_data_view.ts @@ -18,30 +18,7 @@ export const getSourcererDataView = async ( const dataView = await dataViewsService.get(dataViewId, true, refreshFields); const dataViewData = dataView.toSpec(); const defaultPatternsList = ensurePatternFormat(dataView.getIndexPattern().split(',')); - - // typeguard used to assert that pattern is a string, otherwise - // typescript expects patternList to be (string | null)[] - // but we want it to always be string[] - const filterTypeGuard = (str: unknown): str is string => str != null; - const patternList = await Promise.all( - defaultPatternsList.map(async (pattern) => { - try { - await dataViewsService.getFieldsForWildcard({ - type: dataViewData.type, - rollupIndex: dataViewData?.typeMeta?.params?.rollup_index, - allowNoIndex: false, - pattern, - }); - return pattern; - } catch { - return null; - } - }) - ) - .then((allPatterns) => - allPatterns.filter((pattern): pattern is string => filterTypeGuard(pattern)) - ) - .catch(() => defaultPatternsList); + const patternList = await dataViewsService.getExistingIndices(defaultPatternsList); return { loading: false, From a038fb09ca7cfb3984fb642b91683ddfe4b3f53d Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 9 Aug 2023 15:26:18 -0600 Subject: [PATCH 31/41] add x-elastic-internal-origin header to vector tile, glyphs, and fonts APIs (#163331) Closes https://github.com/elastic/kibana/issues/163311 To test * create map with documents layer (that uses vector tile scaling, default). * verify header is provided in request Screen Shot 2023-08-07 at 10 25 11 AM --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../mb_map/transform_request.ts | 20 +++++++++++++++---- .../api_integration/apis/maps/fonts_api.js | 9 ++++++++- .../apis/maps/get_grid_tile.js | 13 +++++++++++- .../api_integration/apis/maps/get_tile.js | 8 +++++++- 4 files changed, 43 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/transform_request.ts b/x-pack/plugins/maps/public/connected_components/mb_map/transform_request.ts index 47f14956d6dca..c30fc533a322f 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/transform_request.ts +++ b/x-pack/plugins/maps/public/connected_components/mb_map/transform_request.ts @@ -5,7 +5,10 @@ * 2.0. */ -import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { + ELASTIC_HTTP_VERSION_HEADER, + X_ELASTIC_INTERNAL_ORIGIN_REQUEST, +} from '@kbn/core-http-common'; import { FONTS_API_PATH, MVT_GETTILE_API_PATH, @@ -22,7 +25,10 @@ export function transformRequest(url: string, resourceType: string | undefined) return { url, method: 'GET' as 'GET', - headers: { [ELASTIC_HTTP_VERSION_HEADER]: '1' }, + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '1', + [X_ELASTIC_INTERNAL_ORIGIN_REQUEST]: 'kibana', + }, }; } @@ -30,7 +36,10 @@ export function transformRequest(url: string, resourceType: string | undefined) return { url, method: 'GET' as 'GET', - headers: { [ELASTIC_HTTP_VERSION_HEADER]: '1' }, + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '1', + [X_ELASTIC_INTERNAL_ORIGIN_REQUEST]: 'kibana', + }, }; } @@ -38,7 +47,10 @@ export function transformRequest(url: string, resourceType: string | undefined) return { url, method: 'GET' as 'GET', - headers: { [ELASTIC_HTTP_VERSION_HEADER]: '1' }, + headers: { + [ELASTIC_HTTP_VERSION_HEADER]: '1', + [X_ELASTIC_INTERNAL_ORIGIN_REQUEST]: 'kibana', + }, }; } diff --git a/x-pack/test/api_integration/apis/maps/fonts_api.js b/x-pack/test/api_integration/apis/maps/fonts_api.js index c8c636e8f6ddc..ae4891c4d7b95 100644 --- a/x-pack/test/api_integration/apis/maps/fonts_api.js +++ b/x-pack/test/api_integration/apis/maps/fonts_api.js @@ -6,7 +6,10 @@ */ import expect from '@kbn/expect'; -import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { + ELASTIC_HTTP_VERSION_HEADER, + X_ELASTIC_INTERNAL_ORIGIN_REQUEST, +} from '@kbn/core-http-common'; import path from 'path'; import { copyFile, rm } from 'fs/promises'; @@ -38,6 +41,7 @@ export default function ({ getService }) { const resp = await supertest .get(`/internal/maps/fonts/Open%20Sans%20Regular,Arial%20Unicode%20MS%20Regular/0-255`) .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .expect(200); expect(resp.body.length).to.be(74696); @@ -49,6 +53,7 @@ export default function ({ getService }) { `/internal/maps/fonts/Open%20Sans%20Regular,Arial%20Unicode%20MS%20Regular/noGonaFindMe` ) .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .expect(404); }); @@ -56,6 +61,7 @@ export default function ({ getService }) { await supertest .get(`/internal/maps/fonts/open_sans/..%2f0-255`) .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .expect(404); }); @@ -63,6 +69,7 @@ export default function ({ getService }) { await supertest .get(`/internal/maps/fonts/open_sans/.%2f..%2f0-255`) .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .expect(404); }); }); diff --git a/x-pack/test/api_integration/apis/maps/get_grid_tile.js b/x-pack/test/api_integration/apis/maps/get_grid_tile.js index 5b44b43e50e43..2a627e3793ee2 100644 --- a/x-pack/test/api_integration/apis/maps/get_grid_tile.js +++ b/x-pack/test/api_integration/apis/maps/get_grid_tile.js @@ -9,7 +9,10 @@ import { VectorTile } from '@mapbox/vector-tile'; import Protobuf from 'pbf'; import expect from '@kbn/expect'; import { getTileUrlParams } from '@kbn/maps-vector-tile-utils'; -import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { + ELASTIC_HTTP_VERSION_HEADER, + X_ELASTIC_INTERNAL_ORIGIN_REQUEST, +} from '@kbn/core-http-common'; function findFeature(layer, callbackFn) { for (let i = 0; i < layer.length; i++) { @@ -75,6 +78,7 @@ export default function ({ getService }) { .get('/internal/maps/mvt/getGridTile/3/2/3.pbf?' + getTileUrlParams(defaultParams)) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(200); @@ -89,6 +93,7 @@ export default function ({ getService }) { .get('/internal/maps/mvt/getGridTile/3/2/3.pbf?' + getTileUrlParams(defaultParams)) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(200); @@ -120,6 +125,7 @@ export default function ({ getService }) { .get('/internal/maps/mvt/getGridTile/3/2/3.pbf?' + tileUrlParams) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(200); @@ -151,6 +157,7 @@ export default function ({ getService }) { .get('/internal/maps/mvt/getGridTile/3/2/3.pbf?' + tileUrlParams) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(200); @@ -189,6 +196,7 @@ export default function ({ getService }) { .get('/internal/maps/mvt/getGridTile/3/2/3.pbf?' + tileUrlParams) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(200); @@ -230,6 +238,7 @@ export default function ({ getService }) { .get('/internal/maps/mvt/getGridTile/3/2/3.pbf?' + tileUrlParams) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(200); @@ -258,6 +267,7 @@ export default function ({ getService }) { .get('/internal/maps/mvt/getGridTile/3/2/3.pbf?' + getTileUrlParams(defaultParams)) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(200); @@ -304,6 +314,7 @@ export default function ({ getService }) { .get('/internal/maps/mvt/getGridTile/3/2/3.pbf?' + tileUrlParams) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(404); }); diff --git a/x-pack/test/api_integration/apis/maps/get_tile.js b/x-pack/test/api_integration/apis/maps/get_tile.js index 8b466fe1554b5..4246141dd7c61 100644 --- a/x-pack/test/api_integration/apis/maps/get_tile.js +++ b/x-pack/test/api_integration/apis/maps/get_tile.js @@ -8,7 +8,10 @@ import { VectorTile } from '@mapbox/vector-tile'; import Protobuf from 'pbf'; import expect from '@kbn/expect'; -import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common'; +import { + ELASTIC_HTTP_VERSION_HEADER, + X_ELASTIC_INTERNAL_ORIGIN_REQUEST, +} from '@kbn/core-http-common'; import { getTileUrlParams } from '@kbn/maps-vector-tile-utils'; function findFeature(layer, callbackFn) { @@ -75,6 +78,7 @@ export default function ({ getService }) { .get(`/internal/maps/mvt/getTile/2/1/1.pbf?${getTileUrlParams(defaultParams)}`) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(200); @@ -138,6 +142,7 @@ export default function ({ getService }) { .get(`/internal/maps/mvt/getTile/2/1/1.pbf?${tileUrlParams}`) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(200); @@ -182,6 +187,7 @@ export default function ({ getService }) { .get(`/internal/maps/mvt/getTile/2/1/1.pbf?${tileUrlParams}`) .set('kbn-xsrf', 'kibana') .set(ELASTIC_HTTP_VERSION_HEADER, '1') + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') .responseType('blob') .expect(404); }); From 5d813006a3340be74a8465cdd52312eb35c451ef Mon Sep 17 00:00:00 2001 From: Kevin Delemme Date: Wed, 9 Aug 2023 17:38:02 -0400 Subject: [PATCH 32/41] feat(slo): add group by field selector in forms (#163202) --- .../slo/use_fetch_index_pattern_fields.ts | 2 + .../common/group_by_field_selector.tsx | 90 +++++++++++++++++++ .../components/common/query_builder.tsx | 1 - .../custom_kql_indicator_type_form.tsx | 5 +- .../custom_metric/custom_metric_type_form.tsx | 8 +- .../histogram_indicator_type_form.tsx | 4 + .../helpers/process_slo_form_values.ts | 2 +- .../slos/components/badges/slo_badges.tsx | 2 +- .../pages/slos/components/slo_summary.tsx | 4 +- .../services/slo/fetch_historical_summary.ts | 12 +-- .../server/services/slo/summary_client.ts | 2 - .../services/slo/summary_search_client.ts | 2 +- 12 files changed, 117 insertions(+), 17 deletions(-) create mode 100644 x-pack/plugins/observability/public/pages/slo_edit/components/common/group_by_field_selector.tsx diff --git a/x-pack/plugins/observability/public/hooks/slo/use_fetch_index_pattern_fields.ts b/x-pack/plugins/observability/public/hooks/slo/use_fetch_index_pattern_fields.ts index bd83b069133c3..2f51e4d7faf26 100644 --- a/x-pack/plugins/observability/public/hooks/slo/use_fetch_index_pattern_fields.ts +++ b/x-pack/plugins/observability/public/hooks/slo/use_fetch_index_pattern_fields.ts @@ -18,6 +18,8 @@ export interface UseFetchIndexPatternFieldsResponse { export interface Field { name: string; type: string; + aggregatable: boolean; + searchable: boolean; } export function useFetchIndexPatternFields( diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/common/group_by_field_selector.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/common/group_by_field_selector.tsx new file mode 100644 index 0000000000000..0733e682e9ba7 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/common/group_by_field_selector.tsx @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiComboBox, + EuiComboBoxOptionOption, + EuiFlexItem, + EuiFormRow, + EuiIconTip, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { ALL_VALUE } from '@kbn/slo-schema'; +import React from 'react'; +import { Controller, useFormContext } from 'react-hook-form'; +import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_index_pattern_fields'; +import { createOptionsFromFields } from '../../helpers/create_options'; +import { CreateSLOForm } from '../../types'; + +interface Props { + index?: string; +} +export function GroupByFieldSelector({ index }: Props) { + const { control, getFieldState } = useFormContext(); + const { isLoading, data: indexFields = [] } = useFetchIndexPatternFields(index); + const groupableFields = indexFields.filter((field) => field.aggregatable); + + const label = i18n.translate('xpack.observability.slo.sloEdit.groupBy.placeholder', { + defaultMessage: 'Select an optional field to partition by', + }); + + return ( + + + {i18n.translate('xpack.observability.slo.sloEdit.groupBy.label', { + defaultMessage: 'Partition by', + })}{' '} + + + } + isInvalid={getFieldState('groupBy').invalid} + > + ( + { + if (selected.length) { + return field.onChange(selected[0].value); + } + + field.onChange(ALL_VALUE); + }} + options={createOptionsFromFields(groupableFields)} + selectedOptions={ + !!index && + !!field.value && + groupableFields.some((groupableField) => groupableField.name === field.value) + ? [{ value: field.value, label: field.value }] + : [] + } + singleSelection + /> + )} + /> + + + ); +} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/common/query_builder.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/common/query_builder.tsx index c33f5646ff8d9..954b89991f528 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/common/query_builder.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/common/query_builder.tsx @@ -36,7 +36,6 @@ export function QueryBuilder({ useKibana().services; const { control, getFieldState } = useFormContext(); - const { dataView } = useCreateDataView({ indexPatternString }); return ( diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx index c07ce5d132489..6d7ae6c012a2e 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_kql/custom_kql_indicator_type_form.tsx @@ -20,6 +20,7 @@ import { useFetchIndexPatternFields } from '../../../../hooks/slo/use_fetch_inde import { createOptionsFromFields } from '../../helpers/create_options'; import { CreateSLOForm } from '../../types'; import { DataPreviewChart } from '../common/data_preview_chart'; +import { GroupByFieldSelector } from '../common/group_by_field_selector'; import { QueryBuilder } from '../common/query_builder'; import { IndexSelection } from '../custom_common/index_selection'; @@ -81,7 +82,7 @@ export function CustomKqlIndicatorTypeForm() { ? [{ value: field.value, label: field.value }] : [] } - singleSelection={{ asPlainText: true }} + singleSelection /> )} /> @@ -175,6 +176,8 @@ export function CustomKqlIndicatorTypeForm() { /> + + ); diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx index e9a96fbc0c929..25de4568dc06c 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/custom_metric/custom_metric_type_form.tsx @@ -27,15 +27,15 @@ import { DataPreviewChart } from '../common/data_preview_chart'; import { QueryBuilder } from '../common/query_builder'; import { IndexSelection } from '../custom_common/index_selection'; import { MetricIndicator } from './metric_indicator'; +import { GroupByFieldSelector } from '../common/group_by_field_selector'; export { NEW_CUSTOM_METRIC } from './metric_indicator'; export function CustomMetricIndicatorTypeForm() { const { control, watch, getFieldState } = useFormContext(); - const { isLoading, data: indexFields } = useFetchIndexPatternFields( - watch('indicator.params.index') - ); + const index = watch('indicator.params.index'); + const { isLoading, data: indexFields } = useFetchIndexPatternFields(index); const timestampFields = (indexFields ?? []).filter((field) => field.type === 'date'); return ( @@ -181,6 +181,8 @@ export function CustomMetricIndicatorTypeForm() { + + diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx index 323cd48a67cc0..56a867ab2e332 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/histogram/histogram_indicator_type_form.tsx @@ -27,6 +27,7 @@ import { DataPreviewChart } from '../common/data_preview_chart'; import { QueryBuilder } from '../common/query_builder'; import { IndexSelection } from '../custom_common/index_selection'; import { HistogramIndicator } from './histogram_indicator'; +import { GroupByFieldSelector } from '../common/group_by_field_selector'; export function HistogramIndicatorTypeForm() { const { control, watch, getFieldState } = useFormContext(); @@ -163,6 +164,9 @@ export function HistogramIndicatorTypeForm() { + + + diff --git a/x-pack/plugins/observability/public/pages/slo_edit/helpers/process_slo_form_values.ts b/x-pack/plugins/observability/public/pages/slo_edit/helpers/process_slo_form_values.ts index d87dd10450f3d..a4ecec640e2df 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/helpers/process_slo_form_values.ts +++ b/x-pack/plugins/observability/public/pages/slo_edit/helpers/process_slo_form_values.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { CreateSLOInput, SLOWithSummaryResponse, UpdateSLOInput } from '@kbn/slo-schema'; +import { CreateSLOInput, SLOWithSummaryResponse, UpdateSLOInput } from '@kbn/slo-schema'; import { toDuration } from '../../../utils/slo/duration'; import { CreateSLOForm } from '../types'; diff --git a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.tsx b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.tsx index 93b4e2802bc1c..f9c7cc3faeeb8 100644 --- a/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.tsx +++ b/x-pack/plugins/observability/public/pages/slos/components/badges/slo_badges.tsx @@ -29,7 +29,7 @@ export interface Props { export function SloBadges({ activeAlerts, isLoading, rules, slo, onClickRuleBadge }: Props) { return ( - + {isLoading ? ( <> - + - + slo.sloId); const sloList = await this.repository.findAllByIds(sloIds); - const list: SLOWithInstanceId[] = params.list.map(({ sloId, instanceId }) => ({ - sloId, - instanceId, - slo: sloList.find((slo) => slo.id === sloId)!, - })); + const list: SLOWithInstanceId[] = params.list + .filter(({ sloId }) => sloList.find((slo) => slo.id === sloId)) + .map(({ sloId, instanceId }) => ({ + sloId, + instanceId, + slo: sloList.find((slo) => slo.id === sloId)!, + })); const historicalSummary = await this.historicalSummaryClient.fetch(list); diff --git a/x-pack/plugins/observability/server/services/slo/summary_client.ts b/x-pack/plugins/observability/server/services/slo/summary_client.ts index b12a376be532a..3f799b2ca3473 100644 --- a/x-pack/plugins/observability/server/services/slo/summary_client.ts +++ b/x-pack/plugins/observability/server/services/slo/summary_client.ts @@ -20,8 +20,6 @@ import { DateRange, SLO, Summary } from '../../domain/models'; import { computeSLI, computeSummaryStatus, toErrorBudget } from '../../domain/services'; import { toDateRange } from '../../domain/services/date_range'; -// TODO: Change name of this service... -// It does compute a summary but from the rollup data. export interface SummaryClient { computeSummary(slo: SLO, instanceId?: string): Promise

    ; } diff --git a/x-pack/plugins/observability/server/services/slo/summary_search_client.ts b/x-pack/plugins/observability/server/services/slo/summary_search_client.ts index c7d87ac8b322c..f2bfa1ed29df3 100644 --- a/x-pack/plugins/observability/server/services/slo/summary_search_client.ts +++ b/x-pack/plugins/observability/server/services/slo/summary_search_client.ts @@ -125,7 +125,7 @@ export class DefaultSummarySearchClient implements SummarySearchClient { page: pagination.page, results: finalResults.map((doc) => ({ id: doc._source!.slo.id, - instanceId: doc._source?.slo.instanceId ?? ALL_VALUE, + instanceId: doc._source!.slo.instanceId ?? ALL_VALUE, summary: { errorBudget: { initial: toHighPrecision(doc._source!.errorBudgetInitial), From 09aaecb59d5e82e17bf6f274de3cedd394bbe25b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patryk=20Kopyci=C5=84ski?= Date: Wed, 9 Aug 2023 23:58:04 +0200 Subject: [PATCH 33/41] [security_solution] Cypress flaky tests catcher (#162376) ## Summary Inspired by https://glebbahmutov.com/blog/burning-tests/ Implements the idea presented here https://glebbahmutov.com/blog/burning-tests/#bonus-3-burning-new-or-changed-specs In short, on PR that is changing/adding new Cypress spec files we will try to "burn" them, it means we will try to run each `it` `2` times to make sure tests are written in a way that gives Cypress a chance to recover from the failed test. Also adding a command that allows to "burn" tests locally ``` yarn cypress:burn --spec "<>" ``` Right now the job is set to `soft_fail`, so it is not going to block the PR from merging, but hopefully will help the Team to recognize potential flakiness before it is merged to `main` --- .../pull_request/security_solution.yml | 11 + .../functional/security_solution_burn.sh | 15 + package.json | 2 + typings/index.d.ts | 2 + .../security_solution/cypress/support/e2e.js | 3 + x-pack/plugins/security_solution/package.json | 14 +- .../scripts/run_cypress/parallel.ts | 42 +- yarn.lock | 540 +++++++++++++++++- 8 files changed, 610 insertions(+), 19 deletions(-) create mode 100755 .buildkite/scripts/steps/functional/security_solution_burn.sh diff --git a/.buildkite/pipelines/pull_request/security_solution.yml b/.buildkite/pipelines/pull_request/security_solution.yml index a30609ac5ca21..9444c821d5db1 100644 --- a/.buildkite/pipelines/pull_request/security_solution.yml +++ b/.buildkite/pipelines/pull_request/security_solution.yml @@ -12,3 +12,14 @@ steps: limit: 1 artifact_paths: - "target/kibana-security-solution/**/*" + + - command: .buildkite/scripts/steps/functional/security_solution_burn.sh + label: 'Security Solution Cypress tests, burning changed specs' + agents: + queue: n2-4-spot + depends_on: build + timeout_in_minutes: 120 + parallelism: 1 + soft_fail: true + artifact_paths: + - "target/kibana-security-solution/**/*" diff --git a/.buildkite/scripts/steps/functional/security_solution_burn.sh b/.buildkite/scripts/steps/functional/security_solution_burn.sh new file mode 100755 index 0000000000000..f8b809dbbdac1 --- /dev/null +++ b/.buildkite/scripts/steps/functional/security_solution_burn.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +set -euo pipefail + +source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/steps/functional/common_cypress.sh + +export JOB=kibana-security-solution-chrome +export KIBANA_INSTALL_DIR=${KIBANA_BUILD_LOCATION} + +buildkite-agent meta-data set "${BUILDKITE_JOB_ID}_is_test_execution_step" 'false' + +echo "--- Security Solution Cypress tests, burning changed specs (Chrome)" + +yarn --cwd x-pack/plugins/security_solution cypress:changed-specs-only diff --git a/package.json b/package.json index 5197b38d33fa0..8962b9736814b 100644 --- a/package.json +++ b/package.json @@ -1444,6 +1444,7 @@ "faker": "^5.1.0", "fetch-mock": "^7.3.9", "file-loader": "^4.2.0", + "find-cypress-specs": "^1.35.1", "form-data": "^4.0.0", "geckodriver": "^4.0.0", "gulp-brotli": "^3.0.0", @@ -1526,6 +1527,7 @@ "sinon": "^7.4.2", "sort-package-json": "^1.53.1", "source-map": "^0.7.4", + "spec-change": "^1.7.1", "string-replace-loader": "^2.2.0", "style-loader": "^1.1.3", "stylelint": "^14.9.1", diff --git a/typings/index.d.ts b/typings/index.d.ts index d561c1444a77a..0134f5be84018 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -20,3 +20,5 @@ declare module 'react-syntax-highlighter/dist/cjs/prism-light'; declare module 'monaco-editor/esm/vs/basic-languages/markdown/markdown'; declare module 'monaco-editor/esm/vs/basic-languages/css/css'; declare module 'monaco-editor/esm/vs/basic-languages/yaml/yaml'; + +declare module 'find-cypress-specs'; diff --git a/x-pack/plugins/security_solution/cypress/support/e2e.js b/x-pack/plugins/security_solution/cypress/support/e2e.js index 3984b4be49727..477c2606153b7 100644 --- a/x-pack/plugins/security_solution/cypress/support/e2e.js +++ b/x-pack/plugins/security_solution/cypress/support/e2e.js @@ -23,6 +23,9 @@ // Import commands.js using ES2015 syntax: import './commands'; import 'cypress-real-events/support'; +import registerCypressGrep from '@cypress/grep'; + +registerCypressGrep(); Cypress.on('uncaught:exception', () => { return false; diff --git a/x-pack/plugins/security_solution/package.json b/x-pack/plugins/security_solution/package.json index e5e4b0b71caf8..19c02e030d391 100644 --- a/x-pack/plugins/security_solution/package.json +++ b/x-pack/plugins/security_solution/package.json @@ -8,17 +8,19 @@ "extract-mitre-attacks": "node scripts/extract_tactics_techniques_mitre.js && node ../../../scripts/eslint ./public/detections/mitre/mitre_tactics_techniques.ts --fix", "build-beat-doc": "node scripts/beat_docs/build.js && node ../../../scripts/eslint ../timelines/server/utils/beat_schema/fields.ts --fix", "cypress": "../../../node_modules/.bin/cypress", + "cypress:burn": "yarn cypress:run:reporter --env burn=2 --concurrency=1 --headed", + "cypress:changed-specs-only": "yarn cypress:run:reporter --changed-specs-only --env burn=2", "cypress:open": "TZ=UTC node ./scripts/start_cypress_parallel open --spec './cypress/e2e/**/*.cy.ts' --config-file ./cypress/cypress.config.ts --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config", - "cypress:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/{,!(investigations,explore)/**/}*.cy.ts'; status=$?; yarn junit:merge && exit $status", - "cypress:run:cases": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/explore/cases/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", - "cypress:run:reporter": "TZ=UTC node ./scripts/start_cypress_parallel run --config-file ./cypress/cypress_ci.config.ts --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json", - "cypress:run:respops": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/(detection_alerts|detection_rules|exceptions)/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", + "cypress:run": "yarn cypress:run:reporter --spec './cypress/e2e/{,!(investigations,explore)/**/}*.cy.ts'; status=$?; yarn junit:merge && exit $status", + "cypress:run:cases": "yarn cypress:run:reporter --spec './cypress/e2e/explore/cases/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", + "cypress:run:reporter": "TZ=UTC node ./scripts/start_cypress_parallel run --browser chrome --config-file ./cypress/cypress_ci.config.ts --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json", + "cypress:run:respops": "yarn cypress:run:reporter --spec './cypress/e2e/(detection_alerts|detection_rules|exceptions)/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", "cypress:dw:open": "node ./scripts/start_cypress_parallel open --config-file ./public/management/cypress.config.ts ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/cli_config", "cypress:dw:run": "node ./scripts/start_cypress_parallel run --config-file ./public/management/cypress.config.ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/cli_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json; status=$?; yarn junit:merge && exit $status", "cypress:dw:endpoint:run": "node ./scripts/start_cypress_parallel run --config-file ./public/management/cypress_endpoint.config.ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/endpoint_config --reporter ../../../node_modules/cypress-multi-reporters --reporter-options configFile=./cypress/reporter_config.json --concurrency 1; status=$?; yarn junit:merge && exit $status", "cypress:dw:endpoint:open": "node ./scripts/start_cypress_parallel open --config-file ./public/management/cypress_endpoint.config.ts ts --ftr-config-file ../../../../../../x-pack/test/defend_workflows_cypress/endpoint_config", - "cypress:investigations:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/investigations/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", - "cypress:explore:run": "yarn cypress:run:reporter --browser chrome --spec './cypress/e2e/explore/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", + "cypress:investigations:run": "yarn cypress:run:reporter --spec './cypress/e2e/investigations/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", + "cypress:explore:run": "yarn cypress:run:reporter --spec './cypress/e2e/explore/**/*.cy.ts' --ftr-config-file ../../../../../../x-pack/test/security_solution_cypress/cli_config; status=$?; yarn junit:merge && exit $status", "junit:merge": "../../../node_modules/.bin/mochawesome-merge ../../../target/kibana-security-solution/cypress/results/mochawesome*.json > ../../../target/kibana-security-solution/cypress/results/output.json && ../../../node_modules/.bin/marge ../../../target/kibana-security-solution/cypress/results/output.json --reportDir ../../../target/kibana-security-solution/cypress/results && yarn junit:transform && mkdir -p ../../../target/junit && cp ../../../target/kibana-security-solution/cypress/results/*.xml ../../../target/junit/", "test:generate": "node scripts/endpoint/resolver_generator", "mappings:generate": "node scripts/mappings/mappings_generator", diff --git a/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts b/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts index 351b38f91f47e..cf2f3897bd5ab 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/parallel.ts @@ -13,6 +13,9 @@ import pMap from 'p-map'; import { ToolingLog } from '@kbn/tooling-log'; import { withProcRunner } from '@kbn/dev-proc-runner'; import cypress from 'cypress'; +import { findChangedFiles } from 'find-cypress-specs'; +import minimatch from 'minimatch'; +import path from 'path'; import { EsVersion, @@ -68,13 +71,39 @@ const retrieveIntegrations = ( export const cli = () => { run( async () => { - const { argv } = yargs(process.argv.slice(2)); + const { argv } = yargs(process.argv.slice(2)).coerce('env', (arg: string) => + arg.split(',').reduce((acc, curr) => { + const [key, value] = curr.split('='); + if (key === 'burn') { + acc[key] = parseInt(value, 10); + } else { + acc[key] = value; + } + return acc; + }, {} as Record) + ); const isOpen = argv._[0] === 'open'; const cypressConfigFilePath = require.resolve(`../../${argv.configFile}`) as string; const cypressConfigFile = await import(require.resolve(`../../${argv.configFile}`)); const spec: string | undefined = argv?.spec as string; - const files = retrieveIntegrations(spec ? [spec] : cypressConfigFile?.e2e?.specPattern); + let files = retrieveIntegrations(spec ? [spec] : cypressConfigFile?.e2e?.specPattern); + + if (argv.changedSpecsOnly) { + const basePath = process.cwd().split('kibana/')[1]; + files = findChangedFiles('main', false) + .filter( + minimatch.filter(path.join(basePath, cypressConfigFile?.e2e?.specPattern), { + matchBase: true, + }) + ) + .map((filePath: string) => filePath.replace(basePath, '.')); + + if (!files?.length) { + // eslint-disable-next-line no-process-exit + return process.exit(0); + } + } if (!files?.length) { throw new Error('No files found'); @@ -323,8 +352,8 @@ ${JSON.stringify(config.getAll(), null, 2)} type: 'elasticsearch' | 'kibana' | 'fleetserver', withAuth: boolean = false ): string => { - const getKeyPath = (path: string = ''): string => { - return `servers.${type}${path ? `.${path}` : ''}`; + const getKeyPath = (keyPath: string = ''): string => { + return `servers.${type}${keyPath ? `.${keyPath}` : ''}`; }; if (!config.get(getKeyPath())) { @@ -361,7 +390,7 @@ ${JSON.stringify(config.getAll(), null, 2)} ...ftrEnv, // NOTE: - // ELASTICSEARCH_URL needs to be crated here with auth because SIEM cypress setup depends on it. At some + // ELASTICSEARCH_URL needs to be created here with auth because SIEM cypress setup depends on it. At some // points we should probably try to refactor that code to use `ELASTICSEARCH_URL_WITH_AUTH` instead ELASTICSEARCH_URL: ftrEnv.ELASTICSEARCH_URL ?? createUrlFromFtrConfig('elasticsearch', true), @@ -377,6 +406,8 @@ ${JSON.stringify(config.getAll(), null, 2)} KIBANA_URL_WITH_AUTH: createUrlFromFtrConfig('kibana', true), KIBANA_USERNAME: config.get('servers.kibana.username'), KIBANA_PASSWORD: config.get('servers.kibana.password'), + + ...argv.env, }; log.info(` @@ -407,6 +438,7 @@ ${JSON.stringify(cyCustomEnv, null, 2)} configFile: cypressConfigFilePath, reporter: argv.reporter as string, reporterOptions: argv.reporterOptions, + headed: argv.headed as boolean, config: { e2e: { baseUrl, diff --git a/yarn.lock b/yarn.lock index 55a4546d3fa43..39981aa19923e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,21 @@ # yarn lockfile v1 +"@actions/core@^1.10.0": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.10.0.tgz#44551c3c71163949a2f06e94d9ca2157a0cfac4f" + integrity sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug== + dependencies: + "@actions/http-client" "^2.0.1" + uuid "^8.3.2" + +"@actions/http-client@^2.0.1": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-2.1.0.tgz#b6d8c3934727d6a50d10d19f00a711a964599a9f" + integrity sha512-BonhODnXr3amchh4qkmjPMUO8mFi/zLaaCeCAJZqch8iQqyDnVIkySjB38VHAC8IJ+bnlgfOqlhpyCUZHlQsqw== + dependencies: + tunnel "^0.0.6" + "@adobe/css-tools@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.0.1.tgz#b38b444ad3aa5fedbb15f2f746dcd934226a12dd" @@ -398,6 +413,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.2.tgz#dacafadfc6d7654c3051a66d6fe55b6cb2f2a0b3" integrity sha512-URpaIJQwEkEC2T9Kn+Ai6Xe/02iNaVCuT/PtoRz3GPVJVDpPd7mLo+VddTbhCRU9TXqW5mSrQfXZyi8kDKOVpQ== +"@babel/parser@^7.21.8": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" + integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" @@ -1302,6 +1322,13 @@ resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@csstools/selector-specificity@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.1.tgz#b6b8d81780b9a9f6459f4bfe9226ac6aefaefe87" @@ -1395,6 +1422,14 @@ enabled "2.0.x" kuler "^2.0.0" +"@dependents/detective-less@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@dependents/detective-less/-/detective-less-4.1.0.tgz#4a979ee7a6a79eb33602862d6a1263e30f98002e" + integrity sha512-KrkT6qO5NxqNfy68sBl6CTSoJ4SNDIS5iQArkibhlbGU4LaDukZ3q2HIkh8aUKDio6o4itU4xDR7t82Y2eP1Bg== + dependencies: + gonzales-pe "^4.3.0" + node-source-walk "^6.0.1" + "@discoveryjs/json-ext@^0.5.0", "@discoveryjs/json-ext@^0.5.3": version "0.5.5" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3" @@ -2792,7 +2827,7 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0": +"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -2815,6 +2850,14 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": version "0.3.17" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" @@ -8088,6 +8131,26 @@ mkdirp "^1.0.4" path-browserify "^1.0.1" +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + "@tsd/typescript@~4.6.3": version "4.6.3" resolved "https://registry.yarnpkg.com/@tsd/typescript/-/typescript-4.6.3.tgz#9b4c8198da7614fe1547436fbd5657cfe8327c1d" @@ -9892,6 +9955,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.54.0.tgz#7d519df01f50739254d89378e0dcac504cab2740" integrity sha512-nExy+fDCBEgqblasfeE3aQ3NuafBUxZxgxXcYfzYRZFHdVvk5q60KhCSkG0noHgHRo/xQ/BOzURLZAafFpTkmQ== +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + "@typescript-eslint/typescript-estree@5.54.0", "@typescript-eslint/typescript-estree@^5.54.0": version "5.54.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.54.0.tgz#f6f3440cabee8a43a0b25fa498213ebb61fdfe99" @@ -9905,6 +9973,19 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@^5.59.5": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + "@typescript-eslint/utils@5.54.0", "@typescript-eslint/utils@^5.10.0": version "5.54.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.54.0.tgz#3db758aae078be7b54b8ea8ea4537ff6cd3fbc21" @@ -9927,6 +10008,14 @@ "@typescript-eslint/types" "5.54.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== + dependencies: + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" + "@wdio/logger@^8.6.6": version "8.6.6" resolved "https://registry.yarnpkg.com/@wdio/logger/-/logger-8.6.6.tgz#6f3844a2506730ae1e4151dca0ed0242b5b69b63" @@ -10338,7 +10427,7 @@ acorn-walk@^7.0.0, acorn-walk@^7.2.0: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn-walk@^8.0.0, acorn-walk@^8.0.2, acorn-walk@^8.2.0: +acorn-walk@^8.0.0, acorn-walk@^8.0.2, acorn-walk@^8.1.1, acorn-walk@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== @@ -10363,6 +10452,11 @@ acorn@^8.0.4, acorn@^8.1.0, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0, acorn@^8.8 resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== +acorn@^8.4.1: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + address@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" @@ -10670,6 +10764,11 @@ apidoc-markdown@^7.2.4: update-notifier "^5.1.0" yargs "^17.6.0" +app-module-path@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5" + integrity sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ== + app-root-dir@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" @@ -10742,6 +10841,16 @@ are-we-there-yet@^3.0.0: delegates "^1.0.0" readable-stream "^3.6.0" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +arg@^5.0.1, arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -10986,6 +11095,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +ast-module-types@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ast-module-types/-/ast-module-types-5.0.0.tgz#32b2b05c56067ff38e95df66f11d6afd6c9ba16b" + integrity sha512-JvqziE0Wc0rXQfma0HZC/aY7URXHFuZV84fJRtP8u+lhp0JYCNd5wJzVXP45t0PH0Mej3ynlzvdyITYIu0G4LQ== + ast-transform@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/ast-transform/-/ast-transform-0.0.0.tgz#74944058887d8283e189d954600947bc98fe0062" @@ -12974,6 +13088,13 @@ console-log-level@^1.4.1: resolved "https://registry.yarnpkg.com/console-log-level/-/console-log-level-1.4.1.tgz#9c5a6bb9ef1ef65b05aba83028b0ff894cdf630a" integrity sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ== +console.table@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/console.table/-/console.table-0.10.0.tgz#0917025588875befd70cf2eff4bef2c6e2d75d04" + integrity sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g== + dependencies: + easy-table "1.1.0" + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -13218,6 +13339,11 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + cronstrue@^1.51.0: version "1.51.0" resolved "https://registry.yarnpkg.com/cronstrue/-/cronstrue-1.51.0.tgz#7a63153d61d940344049037628da38a60784c8e2" @@ -14256,6 +14382,16 @@ dependency-check@^4.1.0: read-package-json "^2.0.10" resolve "^1.1.7" +dependency-tree@^10.0.9: + version "10.0.9" + resolved "https://registry.yarnpkg.com/dependency-tree/-/dependency-tree-10.0.9.tgz#0c6c0dbeb0c5ec2cf83bf755f30e9cb12e7b4ac7" + integrity sha512-dwc59FRIsht+HfnTVM0BCjJaEWxdq2YAvEDy4/Hn6CwS3CBWMtFnL3aZGAkQn3XCYxk/YcTDE4jX2Q7bFTwCjA== + dependencies: + commander "^10.0.1" + filing-cabinet "^4.1.6" + precinct "^11.0.5" + typescript "^5.0.4" + deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" @@ -14326,6 +14462,71 @@ detect-port@^1.3.0: address "^1.0.1" debug "^2.6.0" +detective-amd@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/detective-amd/-/detective-amd-5.0.2.tgz#579900f301c160efe037a6377ec7e937434b2793" + integrity sha512-XFd/VEQ76HSpym80zxM68ieB77unNuoMwopU2TFT/ErUk5n4KvUTwW4beafAVUugrjV48l4BmmR0rh2MglBaiA== + dependencies: + ast-module-types "^5.0.0" + escodegen "^2.0.0" + get-amd-module-type "^5.0.1" + node-source-walk "^6.0.1" + +detective-cjs@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/detective-cjs/-/detective-cjs-5.0.1.tgz#836ad51c6de4863efc7c419ec243694f760ff8b2" + integrity sha512-6nTvAZtpomyz/2pmEmGX1sXNjaqgMplhQkskq2MLrar0ZAIkHMrDhLXkRiK2mvbu9wSWr0V5/IfiTrZqAQMrmQ== + dependencies: + ast-module-types "^5.0.0" + node-source-walk "^6.0.0" + +detective-es6@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/detective-es6/-/detective-es6-4.0.1.tgz#38d5d49a6d966e992ef8f2d9bffcfe861a58a88a" + integrity sha512-k3Z5tB4LQ8UVHkuMrFOlvb3GgFWdJ9NqAa2YLUU/jTaWJIm+JJnEh4PsMc+6dfT223Y8ACKOaC0qcj7diIhBKw== + dependencies: + node-source-walk "^6.0.1" + +detective-postcss@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/detective-postcss/-/detective-postcss-6.1.3.tgz#51a2d4419327ad85d0af071c7054c79fafca7e73" + integrity sha512-7BRVvE5pPEvk2ukUWNQ+H2XOq43xENWbH0LcdCE14mwgTBEAMoAx+Fc1rdp76SmyZ4Sp48HlV7VedUnP6GA1Tw== + dependencies: + is-url "^1.2.4" + postcss "^8.4.23" + postcss-values-parser "^6.0.2" + +detective-sass@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/detective-sass/-/detective-sass-5.0.3.tgz#63e54bc9b32f4bdbd9d5002308f9592a3d3a508f" + integrity sha512-YsYT2WuA8YIafp2RVF5CEfGhhyIVdPzlwQgxSjK+TUm3JoHP+Tcorbk3SfG0cNZ7D7+cYWa0ZBcvOaR0O8+LlA== + dependencies: + gonzales-pe "^4.3.0" + node-source-walk "^6.0.1" + +detective-scss@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/detective-scss/-/detective-scss-4.0.3.tgz#79758baa0158f72bfc4481eb7e21cc3b5f1ea6eb" + integrity sha512-VYI6cHcD0fLokwqqPFFtDQhhSnlFWvU614J42eY6G0s8c+MBhi9QAWycLwIOGxlmD8I/XvGSOUV1kIDhJ70ZPg== + dependencies: + gonzales-pe "^4.3.0" + node-source-walk "^6.0.1" + +detective-stylus@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detective-stylus/-/detective-stylus-4.0.0.tgz#ce97b6499becdc291de7b3c11df8c352c1eee46e" + integrity sha512-TfPotjhszKLgFBzBhTOxNHDsutIxx9GTWjrL5Wh7Qx/ydxKhwUrlSFeLIn+ZaHPF+h0siVBkAQSuy6CADyTxgQ== + +detective-typescript@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/detective-typescript/-/detective-typescript-11.1.0.tgz#2deea5364cae1f0d9d3688bc596e662b049438cc" + integrity sha512-Mq8egjnW2NSCkzEb/Az15/JnBI/Ryyl6Po0Y+0mABTFvOS6DAyUGRZqz1nyhu4QJmWWe0zaGs/ITIBeWkvCkGw== + dependencies: + "@typescript-eslint/typescript-estree" "^5.59.5" + ast-module-types "^5.0.0" + node-source-walk "^6.0.1" + typescript "^5.0.4" + detective@^5.0.2: version "5.2.0" resolved "https://registry.yarnpkg.com/detective/-/detective-5.2.0.tgz#feb2a77e85b904ecdea459ad897cc90a99bd2a7b" @@ -14676,6 +14877,13 @@ eastasianwidth@^0.2.0: resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +easy-table@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/easy-table/-/easy-table-1.1.0.tgz#86f9ab4c102f0371b7297b92a651d5824bc8cb73" + integrity sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA== + optionalDependencies: + wcwidth ">=1.0.1" + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -14936,6 +15144,14 @@ enhanced-resolve@^5.10.0: graceful-fs "^4.2.4" tapable "^2.2.0" +enhanced-resolve@^5.14.1: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + enquirer@^2.3.5, enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -16239,6 +16455,24 @@ filelist@^1.0.1: dependencies: minimatch "^5.0.1" +filing-cabinet@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/filing-cabinet/-/filing-cabinet-4.1.6.tgz#8d6d12cf3a84365bbd94e1cbf07d71c113420dd2" + integrity sha512-C+HZbuQTER36sKzGtUhrAPAoK6+/PrrUhYDBQEh3kBRdsyEhkLbp1ML8S0+6e6gCUrUlid+XmubxJrhvL2g/Zw== + dependencies: + app-module-path "^2.2.0" + commander "^10.0.1" + enhanced-resolve "^5.14.1" + is-relative-path "^1.0.2" + module-definition "^5.0.1" + module-lookup-amd "^8.0.5" + resolve "^1.22.3" + resolve-dependency-path "^3.0.2" + sass-lookup "^5.0.1" + stylus-lookup "^5.0.1" + tsconfig-paths "^4.2.0" + typescript "^5.0.4" + fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" @@ -16287,11 +16521,41 @@ find-cache-dir@^3.2.0, find-cache-dir@^3.3.1: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-cypress-specs@^1.35.1: + version "1.35.1" + resolved "https://registry.yarnpkg.com/find-cypress-specs/-/find-cypress-specs-1.35.1.tgz#89f633de14ab46c2afc6fee992a470596526f721" + integrity sha512-ngLPf/U/I8jAS6vn5ljClETa6seG+fmr3oXw6BcYX3xVIk7D8jNljHUIJCTDvnK90XOI1cflYGuNFDezhRBNvQ== + dependencies: + "@actions/core" "^1.10.0" + arg "^5.0.1" + console.table "^0.10.0" + debug "^4.3.3" + find-test-names "1.28.13" + globby "^11.1.0" + minimatch "^3.0.4" + pluralize "^8.0.0" + require-and-forget "^1.0.1" + shelljs "^0.8.5" + spec-change "^1.7.1" + ts-node "^10.9.1" + find-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== +find-test-names@1.28.13: + version "1.28.13" + resolved "https://registry.yarnpkg.com/find-test-names/-/find-test-names-1.28.13.tgz#871d5585d1f618ed772ffe544ea475ab4657ca83" + integrity sha512-hVatCLbiZmvBwqYNGTkVNbeJwK/8pvkXKQGji+23GzW8fVFHcEaRID77eQYItLKGwa1Tmu0AK2LjcUtuid57FQ== + dependencies: + "@babel/parser" "^7.21.2" + "@babel/plugin-syntax-jsx" "^7.18.6" + acorn-walk "^8.2.0" + debug "^4.3.3" + globby "^11.0.4" + simple-bin-help "^1.8.0" + find-test-names@^1.19.0: version "1.28.6" resolved "https://registry.yarnpkg.com/find-test-names/-/find-test-names-1.28.6.tgz#2840916b42815ce1286bfbfad04cf08f066f727e" @@ -16791,6 +17055,14 @@ geojson-vt@^3.2.1: resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-3.2.1.tgz#f8adb614d2c1d3f6ee7c4265cad4bbf3ad60c8b7" integrity sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg== +get-amd-module-type@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-amd-module-type/-/get-amd-module-type-5.0.1.tgz#bef38ea3674e1aa1bda9c59c8b0da598582f73f2" + integrity sha512-jb65zDeHyDjFR1loOVk0HQGM5WNwoGB8aLWy3LKCieMKol0/ProHkhO2X1JxojuN10vbz1qNn09MJ7tNp7qMzw== + dependencies: + ast-module-types "^5.0.0" + node-source-walk "^6.0.1" + get-assigned-identifiers@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz#6dbf411de648cbaf8d9169ebb0d2d576191e2ff1" @@ -16816,6 +17088,11 @@ get-nonce@^1.0.0: resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" + integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -16995,7 +17272,7 @@ glob@^10.2.2: minipass "^5.0.0 || ^6.0.2" path-scurry "^1.7.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0, glob@~7.2.0: +glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.0, glob@^7.2.3, glob@~7.2.0: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -17171,6 +17448,13 @@ globule@^1.0.0: lodash "~4.17.10" minimatch "~3.0.2" +gonzales-pe@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/gonzales-pe/-/gonzales-pe-4.3.0.tgz#fe9dec5f3c557eead09ff868c65826be54d067b3" + integrity sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ== + dependencies: + minimist "^1.2.5" + google-protobuf@^3.6.1: version "3.19.4" resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.19.4.tgz#8d32c3e34be9250956f28c0fb90955d13f311888" @@ -18203,6 +18487,11 @@ internmap@^1.0.0: resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" @@ -18393,6 +18682,13 @@ is-ci@^3.0.0: dependencies: ci-info "^3.2.0" +is-core-module@^2.12.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== + dependencies: + has "^1.0.3" + is-core-module@^2.6.0, is-core-module@^2.9.0: version "2.10.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" @@ -18605,6 +18901,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + is-obj@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" @@ -18710,11 +19011,21 @@ is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.2, is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + is-regexp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-2.1.0.tgz#cd734a56864e23b956bf4e7c66c396a4c0b22c2d" integrity sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA== +is-relative-path@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-relative-path/-/is-relative-path-1.0.2.tgz#091b46a0d67c1ed0fe85f1f8cfdde006bb251d46" + integrity sha512-i1h+y50g+0hRbBD+dbnInl3JlJ702aar58snAeX+MxBAPvzXGej7sYoPMhlnykabt0ZzCJNBEyzMlekuQZN7fA== + is-relative@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" @@ -18787,7 +19098,12 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-url@^1.2.2: +is-url-superb@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-url-superb/-/is-url-superb-4.0.0.tgz#b54d1d2499bb16792748ac967aa3ecb41a33a8c2" + integrity sha512-GI+WjezhPPcbM+tqE9LnmsY5qqjwHzTvjJ36wxYX5ujNXefSUJ/T17r5bqDV8yLhcgB59KTPNOc9O9cmHTPWsA== + +is-url@^1.2.2, is-url@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== @@ -20160,6 +20476,11 @@ lazy-ass@1.6.0, lazy-ass@^1.6.0: resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" integrity sha1-eZllXoZGwX8In90YfRUNMyTVRRM= +lazy-ass@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-2.0.3.tgz#1e8451729f2bebdff1218bb18921566a08f81b36" + integrity sha512-/O3/DoQmI1XAhklDvF1dAjFf/epE8u3lzOZegQfLZ8G7Ud5bTRSZiFOpukHCu6jODrCA4gtIdwUCC7htxcDACA== + lazy-cache@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-2.0.2.tgz#b9190a4f913354694840859f8a8f7084d8822264" @@ -20787,6 +21108,11 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: dependencies: semver "^6.0.0" +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + make-fetch-happen@^10.0.4: version "10.2.1" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" @@ -21711,11 +22037,29 @@ mock-fs@^5.1.2: resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-5.1.2.tgz#6fa486e06d00f8793a8d2228de980eff93ce6db7" integrity sha512-YkjQkdLulFrz0vD4BfNQdQRVmgycXTV7ykuHMlyv+C8WCHazpkiQRDthwa02kSyo8wKnY9wRptHfQLgmf0eR+A== +module-definition@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/module-definition/-/module-definition-5.0.1.tgz#62d1194e5d5ea6176b7dc7730f818f466aefa32f" + integrity sha512-kvw3B4G19IXk+BOXnYq/D/VeO9qfHaapMeuS7w7sNUqmGaA6hywdFHMi+VWeR9wUScXM7XjoryTffCZ5B0/8IA== + dependencies: + ast-module-types "^5.0.0" + node-source-walk "^6.0.1" + module-details-from-path@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/module-details-from-path/-/module-details-from-path-1.0.3.tgz#114c949673e2a8a35e9d35788527aa37b679da2b" integrity sha1-EUyUlnPiqKNenTV4hSeqN7Z52is= +module-lookup-amd@^8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/module-lookup-amd/-/module-lookup-amd-8.0.5.tgz#aaeea41979105b49339380ca3f7d573db78c32a5" + integrity sha512-vc3rYLjDo5Frjox8NZpiyLXsNWJ5BWshztc/5KSOMzpg9k5cHH652YsJ7VKKmtM4SvaxuE9RkrYGhiSjH3Ehow== + dependencies: + commander "^10.0.1" + glob "^7.2.3" + requirejs "^2.3.6" + requirejs-config-file "^4.0.0" + moment-duration-format@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/moment-duration-format/-/moment-duration-format-2.3.2.tgz#5fa2b19b941b8d277122ff3f87a12895ec0d6212" @@ -21914,6 +22258,11 @@ nanoid@^3.3.1, nanoid@^3.3.4: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + nanomatch@^1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" @@ -22233,6 +22582,13 @@ node-sass@^8.0.0: stdout-stream "^1.4.0" "true-case-path" "^2.2.1" +node-source-walk@^6.0.0, node-source-walk@^6.0.1, node-source-walk@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/node-source-walk/-/node-source-walk-6.0.2.tgz#ba81bc4bc0f6f05559b084bea10be84c3f87f211" + integrity sha512-jn9vOIK/nfqoFCcpK89/VCVaLg1IHE6UVfDOzvqmANaJ/rWCTEdH8RZ1V278nv2jr36BJdyQXIAavBLXpzdlag== + dependencies: + "@babel/parser" "^7.21.8" + nodemailer@^6.6.2: version "6.6.2" resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.6.2.tgz#e184c9ed5bee245a3e0bcabc7255866385757114" @@ -23416,6 +23772,11 @@ pluralize@3.1.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-3.1.0.tgz#84213d0a12356069daa84060c559242633161368" integrity sha1-hCE9ChI1YGnaqEBgxVkkJjMWE2g= +pluralize@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" + integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== + png-js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/png-js/-/png-js-1.0.0.tgz#e5484f1e8156996e383aceebb3789fd75df1874d" @@ -23756,6 +24117,15 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== +postcss-values-parser@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-6.0.2.tgz#636edc5b86c953896f1bb0d7a7a6615df00fb76f" + integrity sha512-YLJpK0N1brcNJrs9WatuJFtHaV9q5aAOj+S4DI5S7jgHlRfm0PIbDCAFRYMQD5SHq7Fy6xsDhyutgS0QOAs0qw== + dependencies: + color-name "^1.1.4" + is-url-superb "^4.0.0" + quote-unquote "^1.0.0" + postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: version "7.0.39" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" @@ -23773,6 +24143,15 @@ postcss@^8.4.14: picocolors "^1.0.0" source-map-js "^1.0.2" +postcss@^8.4.23: + version "8.4.25" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.25.tgz#4a133f5e379eda7f61e906c3b1aaa9b81292726f" + integrity sha512-7taJ/8t2av0Z+sQEvNzCkpDynl0tX3uJMCODi6nT3PfASC7dYCWV9aQ+uiCf+KBD4SEFcu+GvJdGdwzQ6OSjCw== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + potpack@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/potpack/-/potpack-2.0.0.tgz#61f4dd2dc4b3d5e996e3698c0ec9426d0e169104" @@ -23803,6 +24182,24 @@ prebuild-install@^7.1.1: tar-fs "^2.0.0" tunnel-agent "^0.6.0" +precinct@^11.0.5: + version "11.0.5" + resolved "https://registry.yarnpkg.com/precinct/-/precinct-11.0.5.tgz#3e15b3486670806f18addb54b8533e23596399ff" + integrity sha512-oHSWLC8cL/0znFhvln26D14KfCQFFn4KOLSw6hmLhd+LQ2SKt9Ljm89but76Pc7flM9Ty1TnXyrA2u16MfRV3w== + dependencies: + "@dependents/detective-less" "^4.1.0" + commander "^10.0.1" + detective-amd "^5.0.2" + detective-cjs "^5.0.1" + detective-es6 "^4.0.1" + detective-postcss "^6.1.3" + detective-sass "^5.0.3" + detective-scss "^4.0.3" + detective-stylus "^4.0.0" + detective-typescript "^11.1.0" + module-definition "^5.0.1" + node-source-walk "^6.0.2" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -24293,6 +24690,11 @@ quote-stream@^1.0.1: minimist "^1.1.3" through2 "^2.0.0" +quote-unquote@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/quote-unquote/-/quote-unquote-1.0.0.tgz#67a9a77148effeaf81a4d428404a710baaac8a0b" + integrity sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg== + raf-schd@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/raf-schd/-/raf-schd-4.0.2.tgz#bd44c708188f2e84c810bf55fcea9231bcaed8a0" @@ -25103,6 +25505,13 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= + dependencies: + resolve "^1.1.6" + rechoir@^0.7.0: version "0.7.1" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" @@ -25564,6 +25973,13 @@ request-progress@^3.0.0: dependencies: throttleit "^1.0.0" +require-and-forget@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-and-forget/-/require-and-forget-1.0.1.tgz#b535a1b8f0f0dd6a48ab05b0ab15d26135d61142" + integrity sha512-Sea861D/seGo3cptxc857a34Df0oEijXit8Q3IDodiwZMzVmyXrRI9EgQQa3hjkhoEjNzCBvv0t/0fMgebmWLg== + dependencies: + debug "4.3.4" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -25593,6 +26009,19 @@ requireindex@~1.2.0: resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== +requirejs-config-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/requirejs-config-file/-/requirejs-config-file-4.0.0.tgz#4244da5dd1f59874038cc1091d078d620abb6ebc" + integrity sha512-jnIre8cbWOyvr8a5F2KuqBnY+SDA4NXr/hzEZJG79Mxm2WiFQz2dzhC8ibtPJS7zkmBEl1mxSwp5HhC1W4qpxw== + dependencies: + esprima "^4.0.0" + stringify-object "^3.2.1" + +requirejs@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9" + integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg== + requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -25620,6 +26049,11 @@ resolve-cwd@^3.0.0: dependencies: resolve-from "^5.0.0" +resolve-dependency-path@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/resolve-dependency-path/-/resolve-dependency-path-3.0.2.tgz#012816717bcbe8b846835da11af9d2beb5acef50" + integrity sha512-Tz7zfjhLfsvR39ADOSk9us4421J/1ztVBo4rWUkF38hgHK5m0OCZ3NxFVpqHRkjctnwVa15igEUHFJp8MCS7vA== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -25664,7 +26098,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.5, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1, resolve@^1.3.2, resolve@^1.9.0: +resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1, resolve@^1.3.2, resolve@^1.9.0: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -25673,6 +26107,15 @@ resolve@^1.1.5, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12. path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@^1.22.3: + version "1.22.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.3.tgz#4b4055349ffb962600972da1fdc33c46a4eb3283" + integrity sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw== + dependencies: + is-core-module "^2.12.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^2.0.0-next.4: version "2.0.0-next.4" resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" @@ -25971,6 +26414,13 @@ sass-loader@^10.4.1: schema-utils "^3.0.0" semver "^7.3.2" +sass-lookup@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/sass-lookup/-/sass-lookup-5.0.1.tgz#1f01d7ff21e09d8c9dcf8d05b3fca28f2f96e6ed" + integrity sha512-t0X5PaizPc2H4+rCwszAqHZRtr4bugo4pgiCvrBFvIX0XFxnr29g77LJcpyj9A0DcKf7gXMLcgvRjsonYI6x4g== + dependencies: + commander "^10.0.1" + sax@>=0.6.0, sax@^1.2.1: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -26321,6 +26771,15 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shelljs@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + side-channel@^1.0.2, side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -26804,6 +27263,17 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" +spec-change@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/spec-change/-/spec-change-1.7.1.tgz#3c56185c887a15482f1fbb3362916fc97c8fdb9f" + integrity sha512-bZmtSmS5w6M6Snae+AGp+y89MZ7QG2SZW1v3Au83+YWcZzCu0YtH2hXruJWXg6VdYUpQ3n+m9bRrWmwLaPkFjQ== + dependencies: + arg "^5.0.2" + debug "^4.3.4" + dependency-tree "^10.0.9" + globby "^11.1.0" + lazy-ass "^2.0.3" + specificity@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/specificity/-/specificity-0.4.1.tgz#aab5e645012db08ba182e151165738d00887b019" @@ -27207,6 +27677,15 @@ stringify-entities@^3.0.0, stringify-entities@^3.0.1: is-decimal "^1.0.2" is-hexadecimal "^1.0.0" +stringify-object@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -27409,6 +27888,13 @@ stylis@4.2.0: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== +stylus-lookup@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-5.0.1.tgz#3c4d116c3b1e8e1a8169c0d9cd20e608595560f4" + integrity sha512-tLtJEd5AGvnVy4f9UHQMw4bkJJtaAcmo54N+ovQBjDY3DuWyK9Eltxzr5+KG0q4ew6v2EHyuWWNnHeiw/Eo7rQ== + dependencies: + commander "^10.0.1" + success-symbol@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/success-symbol/-/success-symbol-0.1.0.tgz#24022e486f3bf1cdca094283b769c472d3b72897" @@ -28129,6 +28615,25 @@ ts-morph@^13.0.2: "@ts-morph/common" "~0.12.2" code-block-writer "^11.0.0" +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" @@ -28144,6 +28649,15 @@ tsconfig-paths@^3.11.0: minimist "^1.2.0" strip-bom "^3.0.0" +tsconfig-paths@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" + integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + dependencies: + json5 "^2.2.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + tsd@^0.20.0: version "0.20.0" resolved "https://registry.yarnpkg.com/tsd/-/tsd-0.20.0.tgz#0346321ee3c506545486227e488e753109164248" @@ -28195,7 +28709,7 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel@0.0.6: +tunnel@0.0.6, tunnel@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== @@ -28337,7 +28851,7 @@ typescript-tuple@^2.2.1: dependencies: typescript-compare "^0.0.2" -typescript@4.6.3, typescript@^3.3.3333, typescript@^4.6.3, typescript@^4.8.4: +typescript@4.6.3, typescript@^3.3.3333, typescript@^4.6.3, typescript@^4.8.4, typescript@^5.0.4: version "4.6.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== @@ -28917,6 +29431,11 @@ uuid@^8.3.0, uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" @@ -29511,7 +30030,7 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -wcwidth@^1.0.1: +wcwidth@>=1.0.1, wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= @@ -30322,6 +30841,11 @@ yazl@^2.5.1: dependencies: buffer-crc32 "~0.2.3" +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" From b1b80fe5820910255886fe72e239fcaf29534b1e Mon Sep 17 00:00:00 2001 From: Paulo Henrique Date: Wed, 9 Aug 2023 16:58:39 -0700 Subject: [PATCH 34/41] [Cloud Security] [Fleet] Get CloudFormation template accordingly with the current integration version to support auto-upgrade (#162206) --- .../post_install_cloud_formation_modal.tsx | 8 +- .../single_page_layout/hooks/form.tsx | 4 +- .../cloud_formation_instructions.tsx | 15 +-- .../agent_enrollment_flyout/hooks.tsx | 79 ++++++++--- .../agent_enrollment_flyout/instructions.tsx | 9 +- .../steps/compute_steps.tsx | 7 +- ...all_cloud_formation_managed_agent_step.tsx | 20 +-- .../agent_enrollment_flyout/types.ts | 11 +- .../hooks/use_create_cloud_formation_url.ts | 38 +++--- .../fleet/public/hooks/use_request/epm.ts | 28 ++-- ...ormation_props_from_package_policy.test.ts | 126 ++++++++++++++++++ ...ud_formation_props_from_package_policy.ts} | 21 ++- ...ion_template_url_from_package_info.test.ts | 66 +++++++++ ...ormation_template_url_from_package_info.ts | 32 +++++ ...n_template_url_from_package_policy.test.ts | 61 --------- x-pack/plugins/fleet/public/services/index.ts | 3 +- 16 files changed, 376 insertions(+), 152 deletions(-) create mode 100644 x-pack/plugins/fleet/public/services/get_cloud_formation_props_from_package_policy.test.ts rename x-pack/plugins/fleet/public/services/{get_cloud_formation_template_url_from_package_policy.ts => get_cloud_formation_props_from_package_policy.ts} (52%) create mode 100644 x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_info.test.ts create mode 100644 x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_info.ts delete mode 100644 x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_policy.test.ts diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/post_install_cloud_formation_modal.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/post_install_cloud_formation_modal.tsx index e8300e35d0862..7ed959e40efa0 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/post_install_cloud_formation_modal.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/components/post_install_cloud_formation_modal.tsx @@ -22,7 +22,7 @@ import { useQuery } from '@tanstack/react-query'; import type { AgentPolicy, PackagePolicy } from '../../../../../types'; import { sendGetEnrollmentAPIKeys, useCreateCloudFormationUrl } from '../../../../../hooks'; -import { getCloudFormationTemplateUrlFromPackagePolicy } from '../../../../../services'; +import { getCloudFormationPropsFromPackagePolicy } from '../../../../../services'; import { CloudFormationGuide } from '../../../../../components'; export const PostInstallCloudFormationModal: React.FunctionComponent<{ @@ -39,13 +39,11 @@ export const PostInstallCloudFormationModal: React.FunctionComponent<{ }) ); - const cloudFormationTemplateUrl = - getCloudFormationTemplateUrlFromPackagePolicy(packagePolicy) || ''; + const cloudFormationProps = getCloudFormationPropsFromPackagePolicy(packagePolicy); const { cloudFormationUrl, error, isError, isLoading } = useCreateCloudFormationUrl({ - cloudFormationTemplateUrl, enrollmentAPIKey: apyKeysData?.data?.items[0]?.api_key, - packagePolicy, + cloudFormationProps, }); return ( diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/hooks/form.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/hooks/form.tsx index 52d02d93c8097..dbb901316cece 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/hooks/form.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/hooks/form.tsx @@ -39,7 +39,7 @@ import type { PackagePolicyFormState } from '../../types'; import { SelectedPolicyTab } from '../../components'; import { useOnSaveNavigate } from '../../hooks'; import { prepareInputPackagePolicyDataset } from '../../services/prepare_input_pkg_policy_dataset'; -import { getCloudFormationTemplateUrlFromPackagePolicy } from '../../../../../services'; +import { getCloudFormationPropsFromPackagePolicy } from '../../../../../services'; async function createAgentPolicy({ packagePolicy, @@ -301,7 +301,7 @@ export function useOnSubmit({ }); const hasCloudFormation = data?.item - ? getCloudFormationTemplateUrlFromPackagePolicy(data.item) + ? getCloudFormationPropsFromPackagePolicy(data.item).templateUrl : false; if (hasCloudFormation) { diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/cloud_formation_instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/cloud_formation_instructions.tsx index 0edbe5316409b..83031548293f7 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/cloud_formation_instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/cloud_formation_instructions.tsx @@ -10,26 +10,23 @@ import { EuiButton, EuiSpacer, EuiCallOut, EuiSkeletonText } from '@elastic/eui' import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import type { PackagePolicy } from '../../../common'; - import { useCreateCloudFormationUrl } from '../../hooks'; import { CloudFormationGuide } from '../cloud_formation_guide'; +import type { CloudSecurityIntegration } from './types'; + interface Props { enrollmentAPIKey?: string; - cloudFormationTemplateUrl: string; - packagePolicy?: PackagePolicy; + cloudSecurityIntegration: CloudSecurityIntegration; } export const CloudFormationInstructions: React.FunctionComponent = ({ enrollmentAPIKey, - cloudFormationTemplateUrl, - packagePolicy, + cloudSecurityIntegration, }) => { const { isLoading, cloudFormationUrl, error, isError } = useCreateCloudFormationUrl({ enrollmentAPIKey, - cloudFormationTemplateUrl, - packagePolicy, + cloudFormationProps: cloudSecurityIntegration?.cloudFormationProps, }); if (error && isError) { @@ -45,7 +42,7 @@ export const CloudFormationInstructions: React.FunctionComponent = ({ { - if (!agentPolicy) { + const cloudSecurityPackagePolicy = useMemo(() => { + return getCloudSecurityPackagePolicyFromAgentPolicy(agentPolicy); + }, [agentPolicy]); + + const integrationVersion = cloudSecurityPackagePolicy?.package?.version; + + // Fetch the package info to get the CloudFormation template URL only + // if the package policy is a Cloud Security policy + const { data: packageInfoData, isLoading } = useGetPackageInfoByKeyQuery( + FLEET_CLOUD_SECURITY_POSTURE_PACKAGE, + integrationVersion, + { full: true }, + { enabled: Boolean(cloudSecurityPackagePolicy) } + ); + + const cloudSecurityIntegration: CloudSecurityIntegration | undefined = useMemo(() => { + if (!agentPolicy || !cloudSecurityPackagePolicy) { return undefined; } - const integrationType = getCloudSecurityIntegrationTypeFromPackagePolicy(agentPolicy); - const cloudformationUrl = getCloudFormationTemplateUrlFromAgentPolicy(agentPolicy); + const integrationType = cloudSecurityPackagePolicy.inputs?.find((input) => input.enabled) + ?.policy_template as CloudSecurityIntegrationType; + + if (!integrationType) return undefined; + + const cloudFormationTemplateFromAgentPolicy = + getCloudFormationTemplateUrlFromAgentPolicy(agentPolicy); + + // Use the latest CloudFormation template for the current version + // So it guarantee that the template version matches the integration version + // when the integration is upgraded. + // In case it can't find the template for the current version, + // it will fallback to the one from the agent policy. + const cloudFormationTemplateUrl = packageInfoData?.item + ? getCloudFormationTemplateUrlFromPackageInfo(packageInfoData.item, integrationType) + : cloudFormationTemplateFromAgentPolicy; + + const AWS_ACCOUNT_TYPE = 'aws.account_type'; + + const cloudFormationAwsAccountType: CloudSecurityIntegrationAwsAccountType | undefined = + cloudSecurityPackagePolicy?.inputs?.find((input) => input.enabled)?.streams?.[0]?.vars?.[ + AWS_ACCOUNT_TYPE + ]?.value; return { + isLoading, integrationType, - cloudformationUrl, + isCloudFormation: Boolean(cloudFormationTemplateFromAgentPolicy), + cloudFormationProps: { + awsAccountType: cloudFormationAwsAccountType, + templateUrl: cloudFormationTemplateUrl, + }, }; - }, [agentPolicy]); + }, [agentPolicy, packageInfoData?.item, isLoading, cloudSecurityPackagePolicy]); return { cloudSecurityIntegration }; } @@ -97,13 +147,10 @@ const isK8sPackage = (pkg: PackagePolicy) => { return K8S_PACKAGES.has(name); }; -const getCloudSecurityIntegrationTypeFromPackagePolicy = ( - agentPolicy: AgentPolicy -): CloudSecurityIntegrationType | undefined => { - const packagePolicy = agentPolicy?.package_policies?.find( +const getCloudSecurityPackagePolicyFromAgentPolicy = ( + agentPolicy?: AgentPolicy +): PackagePolicy | undefined => { + return agentPolicy?.package_policies?.find( (input) => input.package?.name === FLEET_CLOUD_SECURITY_POSTURE_PACKAGE ); - if (!packagePolicy) return undefined; - return packagePolicy?.inputs?.find((input) => input.enabled) - ?.policy_template as CloudSecurityIntegrationType; }; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx index b602b9fd8931d..d88c9cedb4bcd 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/instructions.tsx @@ -80,8 +80,8 @@ export const Instructions = (props: InstructionProps) => { (fleetStatus.missingRequirements ?? []).some((r) => r === FLEET_SERVER_PACKAGE)); useEffect(() => { - // If we have a cloudFormationTemplateUrl, we want to hide the selection type - if (props.cloudSecurityIntegration?.cloudformationUrl) { + // If we detect a CloudFormation integration, we want to hide the selection type + if (props.cloudSecurityIntegration?.isCloudFormation) { setSelectionType(undefined); } else if (!isIntegrationFlow && showAgentEnrollment) { setSelectionType('radio'); @@ -117,10 +117,7 @@ export const Instructions = (props: InstructionProps) => { {isFleetServerPolicySelected ? ( undefined} /> ) : ( - + )} ); diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/compute_steps.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/compute_steps.tsx index 3977cdd5db576..a750fa48aae7f 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/compute_steps.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/compute_steps.tsx @@ -200,7 +200,6 @@ export const ManagedSteps: React.FunctionComponent = ({ isK8s, cloudSecurityIntegration, installedPackagePolicy, - cloudFormationTemplateUrl, }) => { const kibanaVersion = useKibanaVersion(); const core = useStartServices(); @@ -247,14 +246,13 @@ export const ManagedSteps: React.FunctionComponent = ({ ); } - if (cloudFormationTemplateUrl) { + if (cloudSecurityIntegration?.isCloudFormation) { steps.push( InstallCloudFormationManagedAgentStep({ apiKeyData, selectedApiKeyId, enrollToken, - cloudFormationTemplateUrl, - agentPolicy, + cloudSecurityIntegration, }) ); } else { @@ -314,7 +312,6 @@ export const ManagedSteps: React.FunctionComponent = ({ link, agentDataConfirmed, installedPackagePolicy, - cloudFormationTemplateUrl, ]); return ; diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_cloud_formation_managed_agent_step.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_cloud_formation_managed_agent_step.tsx index 75fec5be125f5..7826d1648ae64 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_cloud_formation_managed_agent_step.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/steps/install_cloud_formation_managed_agent_step.tsx @@ -11,46 +11,38 @@ import { i18n } from '@kbn/i18n'; import type { EuiContainedStepProps } from '@elastic/eui/src/components/steps/steps'; -import type { AgentPolicy } from '../../../../common'; - import type { GetOneEnrollmentAPIKeyResponse } from '../../../../common/types/rest_spec/enrollment_api_key'; import { CloudFormationInstructions } from '../cloud_formation_instructions'; -import { FLEET_CLOUD_SECURITY_POSTURE_PACKAGE } from '../../../../common'; + +import type { CloudSecurityIntegration } from '../types'; export const InstallCloudFormationManagedAgentStep = ({ selectedApiKeyId, apiKeyData, enrollToken, isComplete, - cloudFormationTemplateUrl, - agentPolicy, + cloudSecurityIntegration, }: { selectedApiKeyId?: string; apiKeyData?: GetOneEnrollmentAPIKeyResponse | null; enrollToken?: string; isComplete?: boolean; - cloudFormationTemplateUrl: string; - agentPolicy?: AgentPolicy; + cloudSecurityIntegration?: CloudSecurityIntegration | undefined; }): EuiContainedStepProps => { const nonCompleteStatus = selectedApiKeyId ? undefined : 'disabled'; const status = isComplete ? 'complete' : nonCompleteStatus; - const cloudSecurityPackagePolicy = agentPolicy?.package_policies?.find( - (p) => p.package?.name === FLEET_CLOUD_SECURITY_POSTURE_PACKAGE - ); - return { status, title: i18n.translate('xpack.fleet.agentEnrollment.cloudFormation.stepEnrollAndRunAgentTitle', { defaultMessage: 'Install Elastic Agent on your cloud', }), children: - selectedApiKeyId && apiKeyData ? ( + selectedApiKeyId && apiKeyData && cloudSecurityIntegration ? ( ) : ( diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/types.ts b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/types.ts index 79c8029e4ec01..f1cd44ea5348b 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/types.ts +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/types.ts @@ -16,13 +16,21 @@ export type K8sMode = | 'IS_KUBERNETES_MULTIPAGE'; export type CloudSecurityIntegrationType = 'kspm' | 'vuln_mgmt' | 'cspm'; +export type CloudSecurityIntegrationAwsAccountType = 'single-account' | 'organization-account'; export type FlyoutMode = 'managed' | 'standalone'; export type SelectionType = 'tabs' | 'radio' | undefined; +export interface CloudFormationProps { + templateUrl: string | undefined; + awsAccountType: CloudSecurityIntegrationAwsAccountType | undefined; +} + export interface CloudSecurityIntegration { integrationType: CloudSecurityIntegrationType | undefined; - cloudformationUrl: string | undefined; + isLoading: boolean; + isCloudFormation: boolean; + cloudFormationProps?: CloudFormationProps; } export interface BaseProps { @@ -65,5 +73,4 @@ export interface InstructionProps extends BaseProps { setSelectedAPIKeyId: (key?: string) => void; fleetServerHosts: string[]; fleetProxy?: FleetProxy; - cloudFormationTemplateUrl?: string; } diff --git a/x-pack/plugins/fleet/public/hooks/use_create_cloud_formation_url.ts b/x-pack/plugins/fleet/public/hooks/use_create_cloud_formation_url.ts index a28b0f46adb41..45e5b259afd15 100644 --- a/x-pack/plugins/fleet/public/hooks/use_create_cloud_formation_url.ts +++ b/x-pack/plugins/fleet/public/hooks/use_create_cloud_formation_url.ts @@ -7,34 +7,27 @@ import { i18n } from '@kbn/i18n'; -import type { PackagePolicy, PackagePolicyInput } from '../../common'; +import type { + CloudFormationProps, + CloudSecurityIntegrationAwsAccountType, +} from '../components/agent_enrollment_flyout/types'; import { useKibanaVersion } from './use_kibana_version'; import { useGetSettings } from './use_request'; -type AwsAccountType = 'single_account' | 'organization_account'; - -const CLOUDBEAT_AWS = 'cloudbeat/cis_aws'; - -const getAwsAccountType = (input?: PackagePolicyInput): AwsAccountType | undefined => - input?.streams[0].vars?.['aws.account_type']?.value; +const CLOUD_FORMATION_DEFAULT_ACCOUNT_TYPE = 'single-account'; export const useCreateCloudFormationUrl = ({ enrollmentAPIKey, - cloudFormationTemplateUrl, - packagePolicy, + cloudFormationProps, }: { enrollmentAPIKey: string | undefined; - cloudFormationTemplateUrl: string; - packagePolicy?: PackagePolicy; + cloudFormationProps: CloudFormationProps | undefined; }) => { const { data, isLoading } = useGetSettings(); const kibanaVersion = useKibanaVersion(); - const awsInput = packagePolicy?.inputs?.find((input) => input.type === CLOUDBEAT_AWS); - const awsAccountType = getAwsAccountType(awsInput) || ''; - let isError = false; let error: string | undefined; @@ -56,13 +49,13 @@ export const useCreateCloudFormationUrl = ({ } const cloudFormationUrl = - enrollmentAPIKey && fleetServerHost && cloudFormationTemplateUrl + enrollmentAPIKey && fleetServerHost && cloudFormationProps?.templateUrl ? createCloudFormationUrl( - cloudFormationTemplateUrl, + cloudFormationProps?.templateUrl, enrollmentAPIKey, fleetServerHost, kibanaVersion, - awsAccountType + cloudFormationProps?.awsAccountType ) : undefined; @@ -79,7 +72,7 @@ const createCloudFormationUrl = ( enrollmentToken: string, fleetUrl: string, kibanaVersion: string, - awsAccountType: string + awsAccountType: CloudSecurityIntegrationAwsAccountType | undefined ) => { let cloudFormationUrl; @@ -89,8 +82,15 @@ const createCloudFormationUrl = ( .replace('KIBANA_VERSION', kibanaVersion); if (cloudFormationUrl.includes('ACCOUNT_TYPE')) { - cloudFormationUrl = cloudFormationUrl.replace('ACCOUNT_TYPE', awsAccountType); + cloudFormationUrl = cloudFormationUrl.replace( + 'ACCOUNT_TYPE', + getAwsAccountType(awsAccountType) + ); } return new URL(cloudFormationUrl).toString(); }; + +const getAwsAccountType = (awsAccountType: CloudSecurityIntegrationAwsAccountType | undefined) => { + return awsAccountType ? awsAccountType : CLOUD_FORMATION_DEFAULT_ACCOUNT_TYPE; +}; diff --git a/x-pack/plugins/fleet/public/hooks/use_request/epm.ts b/x-pack/plugins/fleet/public/hooks/use_request/epm.ts index cc381c20ecd97..df8ceb8a4c2e2 100644 --- a/x-pack/plugins/fleet/public/hooks/use_request/epm.ts +++ b/x-pack/plugins/fleet/public/hooks/use_request/epm.ts @@ -105,6 +105,13 @@ export const useGetPackageInfoByKeyQuery = ( ignoreUnverified?: boolean; prerelease?: boolean; full?: boolean; + }, + // Additional options for the useQuery hook + queryOptions: { + // If enabled is false, the query will not be fetched + enabled?: boolean; + } = { + enabled: true, } ) => { const confirmOpenUnverified = useConfirmOpenUnverified(); @@ -112,15 +119,18 @@ export const useGetPackageInfoByKeyQuery = ( options?.ignoreUnverified ); - const response = useQuery([pkgName, pkgVersion, options], () => - sendRequestForRq({ - path: epmRouteService.getInfoPath(pkgName, pkgVersion), - method: 'get', - query: { - ...options, - ...(ignoreUnverifiedQueryParam && { ignoreUnverified: ignoreUnverifiedQueryParam }), - }, - }) + const response = useQuery( + [pkgName, pkgVersion, options], + () => + sendRequestForRq({ + path: epmRouteService.getInfoPath(pkgName, pkgVersion), + method: 'get', + query: { + ...options, + ...(ignoreUnverifiedQueryParam && { ignoreUnverified: ignoreUnverifiedQueryParam }), + }, + }), + { enabled: queryOptions.enabled } ); const confirm = async () => { diff --git a/x-pack/plugins/fleet/public/services/get_cloud_formation_props_from_package_policy.test.ts b/x-pack/plugins/fleet/public/services/get_cloud_formation_props_from_package_policy.test.ts new file mode 100644 index 0000000000000..f84d5c839dd40 --- /dev/null +++ b/x-pack/plugins/fleet/public/services/get_cloud_formation_props_from_package_policy.test.ts @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { getCloudFormationPropsFromPackagePolicy } from './get_cloud_formation_props_from_package_policy'; + +describe('getCloudFormationPropsFromPackagePolicy', () => { + test('returns empty CloudFormationProps when packagePolicy is undefined', () => { + const result = getCloudFormationPropsFromPackagePolicy(undefined); + expect(result).toEqual({ + templateUrl: undefined, + awsAccountType: undefined, + }); + }); + + test('returns empty CloudFormationProps when packagePolicy has no inputs', () => { + const packagePolicy = { otherProperty: 'value' }; + // @ts-expect-error + const result = getCloudFormationPropsFromPackagePolicy(packagePolicy); + expect(result).toEqual({ + templateUrl: undefined, + awsAccountType: undefined, + }); + }); + + test('returns empty CloudFormationProps when no enabled input has a cloudFormationTemplateUrl', () => { + const packagePolicy = { + inputs: [ + { enabled: false, config: { cloud_formation_template_url: { value: 'template1' } } }, + { enabled: false, config: { cloud_formation_template_url: { value: 'template2' } } }, + ], + }; + // @ts-expect-error + const result = getCloudFormationPropsFromPackagePolicy(packagePolicy); + expect(result).toEqual({ + templateUrl: undefined, + awsAccountType: undefined, + }); + }); + + test('returns the cloudFormationTemplateUrl and awsAccountType when found in the enabled input', () => { + const packagePolicy = { + inputs: [ + { + enabled: true, + config: { cloud_formation_template_url: { value: 'template1' } }, + streams: [ + { + vars: { + ['aws.account_type']: { value: 'aws_account_type_value' }, + }, + }, + ], + }, + { + enabled: false, + config: { cloud_formation_template_url: { value: 'template2' } }, + streams: [ + { + vars: { + ['aws.account_type']: { value: 'aws_account_type_value2' }, + }, + }, + ], + }, + ], + }; + // @ts-expect-error + const result = getCloudFormationPropsFromPackagePolicy(packagePolicy); + expect(result).toEqual({ + templateUrl: 'template1', + awsAccountType: 'aws_account_type_value', + }); + }); + + test('returns the first cloudFormationTemplateUrl and awsAccountType when multiple enabled inputs have them', () => { + const packagePolicy = { + inputs: [ + { + enabled: true, + config: { + cloud_formation_template_url: { value: 'template1' }, + }, + streams: [ + { + vars: { + ['aws.account_type']: { value: 'aws_account_type_value1' }, + }, + }, + { + vars: { + ['aws.account_type']: { value: 'aws_account_type_value2' }, + }, + }, + ], + }, + { + enabled: true, + config: { + cloud_formation_template_url: { value: 'template2' }, + }, + streams: [ + { + vars: { + ['aws.account_type']: { value: 'aws_account_type_value1' }, + }, + }, + { + vars: { + ['aws.account_type']: { value: 'aws_account_type_value2' }, + }, + }, + ], + }, + ], + }; + // @ts-expect-error + const result = getCloudFormationPropsFromPackagePolicy(packagePolicy); + expect(result).toEqual({ + templateUrl: 'template1', + awsAccountType: 'aws_account_type_value1', + }); + }); +}); diff --git a/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_policy.ts b/x-pack/plugins/fleet/public/services/get_cloud_formation_props_from_package_policy.ts similarity index 52% rename from x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_policy.ts rename to x-pack/plugins/fleet/public/services/get_cloud_formation_props_from_package_policy.ts index 598e71709fdc7..b56659b21db99 100644 --- a/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_policy.ts +++ b/x-pack/plugins/fleet/public/services/get_cloud_formation_props_from_package_policy.ts @@ -5,15 +5,23 @@ * 2.0. */ +import type { + CloudFormationProps, + CloudSecurityIntegrationAwsAccountType, +} from '../components/agent_enrollment_flyout/types'; import type { PackagePolicy } from '../types'; +const AWS_ACCOUNT_TYPE = 'aws.account_type'; + /** * Get the cloud formation template url from a package policy * It looks for a config with a cloud_formation_template_url object present in * the enabled inputs of the package policy */ -export const getCloudFormationTemplateUrlFromPackagePolicy = (packagePolicy?: PackagePolicy) => { - const cloudFormationTemplateUrl = packagePolicy?.inputs?.reduce((accInput, input) => { +export const getCloudFormationPropsFromPackagePolicy = ( + packagePolicy?: PackagePolicy +): CloudFormationProps => { + const templateUrl = packagePolicy?.inputs?.reduce((accInput, input) => { if (accInput !== '') { return accInput; } @@ -23,5 +31,12 @@ export const getCloudFormationTemplateUrlFromPackagePolicy = (packagePolicy?: Pa return accInput; }, ''); - return cloudFormationTemplateUrl !== '' ? cloudFormationTemplateUrl : undefined; + const awsAccountType: CloudSecurityIntegrationAwsAccountType | undefined = + packagePolicy?.inputs?.find((input) => input.enabled)?.streams?.[0]?.vars?.[AWS_ACCOUNT_TYPE] + ?.value; + + return { + templateUrl: templateUrl !== '' ? templateUrl : undefined, + awsAccountType, + }; }; diff --git a/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_info.test.ts b/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_info.test.ts new file mode 100644 index 0000000000000..8ed2fb3ae389a --- /dev/null +++ b/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_info.test.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getCloudFormationTemplateUrlFromPackageInfo } from './get_cloud_formation_template_url_from_package_info'; + +describe('getCloudFormationTemplateUrlFromPackageInfo', () => { + test('returns undefined when packageInfo is undefined', () => { + const result = getCloudFormationTemplateUrlFromPackageInfo(undefined, 'test'); + expect(result).toBeUndefined(); + }); + + test('returns undefined when packageInfo has no policy_templates', () => { + const packageInfo = { inputs: [] }; + // @ts-expect-error + const result = getCloudFormationTemplateUrlFromPackageInfo(packageInfo, 'test'); + expect(result).toBeUndefined(); + }); + + test('returns undefined when integrationType is not found in policy_templates', () => { + const packageInfo = { policy_templates: [{ name: 'template1' }, { name: 'template2' }] }; + // @ts-expect-error + const result = getCloudFormationTemplateUrlFromPackageInfo(packageInfo, 'nonExistentTemplate'); + expect(result).toBeUndefined(); + }); + + test('returns undefined when no input in the policy template has a cloudFormationTemplate', () => { + const packageInfo = { + policy_templates: [ + { + name: 'template1', + inputs: [ + { name: 'input1', vars: [] }, + { name: 'input2', vars: [{ name: 'var1', default: 'value1' }] }, + ], + }, + ], + }; + // @ts-expect-error + const result = getCloudFormationTemplateUrlFromPackageInfo(packageInfo, 'template1'); + expect(result).toBeUndefined(); + }); + + test('returns the cloudFormationTemplate from the policy template', () => { + const packageInfo = { + policy_templates: [ + { + name: 'template1', + inputs: [ + { name: 'input1', vars: [] }, + { + name: 'input2', + vars: [{ name: 'cloud_formation_template', default: 'cloud_formation_template_url' }], + }, + ], + }, + ], + }; + // @ts-expect-error + const result = getCloudFormationTemplateUrlFromPackageInfo(packageInfo, 'template1'); + expect(result).toBe('cloud_formation_template_url'); + }); +}); diff --git a/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_info.ts b/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_info.ts new file mode 100644 index 0000000000000..4f5381ccedb3f --- /dev/null +++ b/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_info.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PackageInfo } from '../types'; + +/** + * Get the cloud formation template url from the PackageInfo + * It looks for a input var with a object containing cloud_formation_template_url present in + * the package_policies inputs of the given integration type + */ +export const getCloudFormationTemplateUrlFromPackageInfo = ( + packageInfo: PackageInfo | undefined, + integrationType: string +): string | undefined => { + if (!packageInfo?.policy_templates) return undefined; + + const policyTemplate = packageInfo.policy_templates.find((p) => p.name === integrationType); + if (!policyTemplate) return undefined; + + if ('inputs' in policyTemplate) { + const cloudFormationTemplate = policyTemplate.inputs?.reduce((acc, input): string => { + if (!input.vars) return acc; + const template = input.vars.find((v) => v.name === 'cloud_formation_template')?.default; + return template ? String(template) : acc; + }, ''); + return cloudFormationTemplate !== '' ? cloudFormationTemplate : undefined; + } +}; diff --git a/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_policy.test.ts b/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_policy.test.ts deleted file mode 100644 index 523641b10eb1b..0000000000000 --- a/x-pack/plugins/fleet/public/services/get_cloud_formation_template_url_from_package_policy.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { getCloudFormationTemplateUrlFromPackagePolicy } from './get_cloud_formation_template_url_from_package_policy'; - -describe('getCloudFormationTemplateUrlFromPackagePolicy', () => { - test('returns undefined when packagePolicy is undefined', () => { - const result = getCloudFormationTemplateUrlFromPackagePolicy(undefined); - expect(result).toBeUndefined(); - }); - - test('returns undefined when packagePolicy is defined but inputs are empty', () => { - const packagePolicy = { inputs: [] }; - // @ts-expect-error - const result = getCloudFormationTemplateUrlFromPackagePolicy(packagePolicy); - expect(result).toBeUndefined(); - }); - - test('returns undefined when no enabled input has a cloudFormationTemplateUrl', () => { - const packagePolicy = { - inputs: [ - { enabled: false, config: { cloud_formation_template_url: { value: 'template1' } } }, - { enabled: false, config: { cloud_formation_template_url: { value: 'template2' } } }, - ], - }; - // @ts-expect-error - const result = getCloudFormationTemplateUrlFromPackagePolicy(packagePolicy); - expect(result).toBeUndefined(); - }); - - test('returns the cloudFormationTemplateUrl of the first enabled input', () => { - const packagePolicy = { - inputs: [ - { enabled: false, config: { cloud_formation_template_url: { value: 'template1' } } }, - { enabled: true, config: { cloud_formation_template_url: { value: 'template2' } } }, - { enabled: true, config: { cloud_formation_template_url: { value: 'template3' } } }, - ], - }; - // @ts-expect-error - const result = getCloudFormationTemplateUrlFromPackagePolicy(packagePolicy); - expect(result).toBe('template2'); - }); - - test('returns the cloudFormationTemplateUrl of the first enabled input and ignores subsequent inputs', () => { - const packagePolicy = { - inputs: [ - { enabled: true, config: { cloud_formation_template_url: { value: 'template1' } } }, - { enabled: true, config: { cloud_formation_template_url: { value: 'template2' } } }, - { enabled: true, config: { cloud_formation_template_url: { value: 'template3' } } }, - ], - }; - // @ts-expect-error - const result = getCloudFormationTemplateUrlFromPackagePolicy(packagePolicy); - expect(result).toBe('template1'); - }); - - // Add more test cases as needed -}); diff --git a/x-pack/plugins/fleet/public/services/index.ts b/x-pack/plugins/fleet/public/services/index.ts index 1da10c7384cdc..44bf6b965742c 100644 --- a/x-pack/plugins/fleet/public/services/index.ts +++ b/x-pack/plugins/fleet/public/services/index.ts @@ -48,5 +48,6 @@ export { isPackageUpdatable } from './is_package_updatable'; export { pkgKeyFromPackageInfo } from './pkg_key_from_package_info'; export { createExtensionRegistrationCallback } from './ui_extensions'; export { incrementPolicyName } from './increment_policy_name'; -export { getCloudFormationTemplateUrlFromPackagePolicy } from './get_cloud_formation_template_url_from_package_policy'; +export { getCloudFormationPropsFromPackagePolicy } from './get_cloud_formation_props_from_package_policy'; export { getCloudFormationTemplateUrlFromAgentPolicy } from './get_cloud_formation_template_url_from_agent_policy'; +export { getCloudFormationTemplateUrlFromPackageInfo } from './get_cloud_formation_template_url_from_package_info'; From d5d34c661d41dddbfebacccbd010aa63ed6afa81 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 10 Aug 2023 00:52:53 -0400 Subject: [PATCH 35/41] [api-docs] 2023-08-10 Daily api_docs build (#163551) Generated by https://buildkite.com/elastic/kibana-api-docs-daily/builds/425 --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.devdocs.json | 159 +- api_docs/aiops.mdx | 10 +- api_docs/alerting.devdocs.json | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.devdocs.json | 34 +- api_docs/apm.mdx | 2 +- api_docs/asset_manager.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.devdocs.json | 15 +- api_docs/cases.mdx | 4 +- api_docs/charts.devdocs.json | 10 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_chat.mdx | 2 +- api_docs/cloud_chat_provider.mdx | 2 +- api_docs/cloud_data_migration.mdx | 2 +- api_docs/cloud_defend.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/content_management.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.devdocs.json | 117 +- api_docs/data.mdx | 4 +- api_docs/data_query.mdx | 4 +- api_docs/data_search.devdocs.json | 14 + api_docs/data_search.mdx | 4 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.devdocs.json | 244 +- api_docs/data_views.mdx | 4 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 15 +- api_docs/deprecations_by_plugin.mdx | 29 +- api_docs/deprecations_by_team.mdx | 4 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/ecs_data_quality_dashboard.mdx | 2 +- api_docs/embeddable.devdocs.json | 30 +- api_docs/embeddable.mdx | 4 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.devdocs.json | 59 +- api_docs/event_annotation.mdx | 4 +- api_docs/event_log.devdocs.json | 79 - api_docs/event_log.mdx | 4 +- api_docs/exploratory_view.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.devdocs.json | 18 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.devdocs.json | 12 + api_docs/files.mdx | 2 +- api_docs/files_management.mdx | 2 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/image_embeddable.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.devdocs.json | 284 +- api_docs/kbn_aiops_components.mdx | 7 +- api_docs/kbn_aiops_utils.devdocs.json | 201 +- api_docs/kbn_aiops_utils.mdx | 10 +- api_docs/kbn_alerting_state_types.mdx | 2 +- api_docs/kbn_alerts_as_data_utils.mdx | 2 +- api_docs/kbn_alerts_ui_shared.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.devdocs.json | 8 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_analytics_shippers_gainsight.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_synthtrace_client.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_cases_components.mdx | 2 +- api_docs/kbn_cell_actions.mdx | 2 +- api_docs/kbn_chart_expressions_common.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_code_editor.mdx | 2 +- api_docs/kbn_code_editor_mocks.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_content_editor.mdx | 2 +- ...tent_management_tabbed_table_list_view.mdx | 2 +- ...kbn_content_management_table_list_view.mdx | 2 +- ...ntent_management_table_list_view_table.mdx | 2 +- .../kbn_content_management_utils.devdocs.json | 18 +- api_docs/kbn_content_management_utils.mdx | 4 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_apps_server_internal.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_custom_branding_browser.mdx | 2 +- ..._core_custom_branding_browser_internal.mdx | 2 +- ...kbn_core_custom_branding_browser_mocks.mdx | 2 +- api_docs/kbn_core_custom_branding_common.mdx | 2 +- api_docs/kbn_core_custom_branding_server.mdx | 2 +- ...n_core_custom_branding_server_internal.mdx | 2 +- .../kbn_core_custom_branding_server_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- ...re_http_request_handler_context_server.mdx | 2 +- api_docs/kbn_core_http_resources_server.mdx | 2 +- ...bn_core_http_resources_server_internal.mdx | 2 +- .../kbn_core_http_resources_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.devdocs.json | 76 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_browser.mdx | 2 +- api_docs/kbn_core_lifecycle_browser_mocks.mdx | 2 +- api_docs/kbn_core_lifecycle_server.mdx | 2 +- api_docs/kbn_core_lifecycle_server_mocks.mdx | 2 +- api_docs/kbn_core_logging_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_common_internal.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_browser.mdx | 2 +- api_docs/kbn_core_plugins_browser_mocks.mdx | 2 +- api_docs/kbn_core_plugins_server.mdx | 2 +- api_docs/kbn_core_plugins_server_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_rendering_server_internal.mdx | 2 +- api_docs/kbn_core_rendering_server_mocks.mdx | 2 +- api_docs/kbn_core_root_server_internal.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_test_helpers_kbn_server.mdx | 2 +- ...n_core_test_helpers_so_type_serializer.mdx | 2 +- api_docs/kbn_core_test_helpers_test_utils.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_core_user_settings_server.mdx | 2 +- ...kbn_core_user_settings_server_internal.mdx | 2 +- .../kbn_core_user_settings_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_cypress_config.mdx | 2 +- api_docs/kbn_data_service.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_deeplinks_analytics.mdx | 2 +- api_docs/kbn_deeplinks_devtools.mdx | 2 +- api_docs/kbn_deeplinks_management.mdx | 2 +- api_docs/kbn_deeplinks_ml.mdx | 2 +- api_docs/kbn_deeplinks_observability.mdx | 2 +- api_docs/kbn_deeplinks_search.mdx | 2 +- api_docs/kbn_default_nav_analytics.mdx | 2 +- api_docs/kbn_default_nav_devtools.mdx | 2 +- api_docs/kbn_default_nav_management.mdx | 2 +- api_docs/kbn_default_nav_ml.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_discover_utils.mdx | 2 +- api_docs/kbn_doc_links.devdocs.json | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_dom_drag_drop.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_ecs.mdx | 2 +- api_docs/kbn_ecs_data_quality_dashboard.mdx | 2 +- api_docs/kbn_elastic_assistant.mdx | 2 +- api_docs/kbn_es.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_event_annotation_common.mdx | 2 +- ...n_event_annotation_components.devdocs.json | 38 +- api_docs/kbn_event_annotation_components.mdx | 2 +- api_docs/kbn_expandable_flyout.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- .../kbn_ftr_common_functional_services.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_generate_console_definitions.mdx | 2 +- api_docs/kbn_generate_csv.mdx | 2 +- api_docs/kbn_generate_csv_types.mdx | 2 +- api_docs/kbn_guided_onboarding.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_health_gateway_server.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_i18n_react.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_infra_forge.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.devdocs.json | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_journeys.mdx | 2 +- api_docs/kbn_json_ast.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- .../kbn_language_documentation_popover.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_management_cards_navigation.mdx | 2 +- api_docs/kbn_management_storybook_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_maps_vector_tile_utils.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_anomaly_utils.mdx | 2 +- api_docs/kbn_ml_category_validator.mdx | 2 +- .../kbn_ml_data_frame_analytics_utils.mdx | 2 +- api_docs/kbn_ml_data_grid.mdx | 2 +- api_docs/kbn_ml_date_picker.mdx | 2 +- api_docs/kbn_ml_date_utils.mdx | 2 +- api_docs/kbn_ml_error_utils.mdx | 2 +- api_docs/kbn_ml_in_memory_table.mdx | 2 +- api_docs/kbn_ml_is_defined.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_kibana_theme.mdx | 2 +- api_docs/kbn_ml_local_storage.mdx | 2 +- api_docs/kbn_ml_nested_property.mdx | 2 +- api_docs/kbn_ml_number_utils.mdx | 2 +- api_docs/kbn_ml_query_utils.mdx | 2 +- api_docs/kbn_ml_random_sampler_utils.mdx | 2 +- api_docs/kbn_ml_route_utils.mdx | 2 +- api_docs/kbn_ml_runtime_field_utils.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_ml_trained_models_utils.mdx | 2 +- api_docs/kbn_ml_url_state.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_object_versioning.mdx | 2 +- api_docs/kbn_observability_alert_details.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- api_docs/kbn_osquery_io_ts_types.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_random_sampling.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_react_kibana_context_common.mdx | 2 +- api_docs/kbn_react_kibana_context_render.mdx | 2 +- api_docs/kbn_react_kibana_context_root.mdx | 2 +- api_docs/kbn_react_kibana_context_styled.mdx | 2 +- api_docs/kbn_react_kibana_context_theme.mdx | 2 +- api_docs/kbn_react_kibana_mount.mdx | 2 +- api_docs/kbn_repo_file_maps.mdx | 2 +- api_docs/kbn_repo_linter.mdx | 2 +- api_docs/kbn_repo_path.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_reporting_common.mdx | 2 +- api_docs/kbn_rison.mdx | 2 +- api_docs/kbn_rrule.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- api_docs/kbn_saved_objects_settings.mdx | 2 +- api_docs/kbn_security_solution_navigation.mdx | 2 +- api_docs/kbn_security_solution_side_nav.mdx | 2 +- ...kbn_security_solution_storybook_config.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_data_table.mdx | 2 +- api_docs/kbn_securitysolution_ecs.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- ...ritysolution_exception_list_components.mdx | 2 +- api_docs/kbn_securitysolution_grouping.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_serverless_project_switcher.mdx | 2 +- api_docs/kbn_serverless_storybook_config.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- api_docs/kbn_shared_ux_avatar_solution.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- .../kbn_shared_ux_button_exit_full_screen.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_chrome_navigation.mdx | 2 +- api_docs/kbn_shared_ux_file_context.mdx | 2 +- api_docs/kbn_shared_ux_file_image.mdx | 2 +- api_docs/kbn_shared_ux_file_image_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_mocks.mdx | 2 +- api_docs/kbn_shared_ux_file_picker.mdx | 2 +- api_docs/kbn_shared_ux_file_types.mdx | 2 +- api_docs/kbn_shared_ux_file_upload.mdx | 2 +- api_docs/kbn_shared_ux_file_util.mdx | 2 +- api_docs/kbn_shared_ux_link_redirect_app.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- api_docs/kbn_shared_ux_markdown.mdx | 2 +- api_docs/kbn_shared_ux_markdown_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_prompt_not_found.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_slo_schema.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_text_based_editor.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_ts_projects.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_actions_browser.mdx | 2 +- api_docs/kbn_ui_shared_deps_src.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_unified_field_list.mdx | 2 +- api_docs/kbn_url_state.mdx | 2 +- .../kbn_user_profile_components.devdocs.json | 453 +- api_docs/kbn_user_profile_components.mdx | 4 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_visualization_ui_components.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.devdocs.json | 220 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.devdocs.json | 4 + api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/logs_shared.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/notifications.mdx | 2 +- api_docs/observability.devdocs.json | 23 +- api_docs/observability.mdx | 4 +- .../observability_a_i_assistant.devdocs.json | 16798 +++++++++++++++- api_docs/observability_a_i_assistant.mdx | 4 +- api_docs/observability_onboarding.mdx | 2 +- api_docs/observability_shared.devdocs.json | 2 +- api_docs/observability_shared.mdx | 2 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 42 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.devdocs.json | 356 +- api_docs/saved_objects_finder.mdx | 4 +- .../saved_objects_management.devdocs.json | 147 + api_docs/saved_objects_management.mdx | 4 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.devdocs.json | 162 +- api_docs/security.mdx | 4 +- api_docs/security_solution.devdocs.json | 44 +- api_docs/security_solution.mdx | 4 +- api_docs/security_solution_ess.mdx | 2 +- api_docs/security_solution_serverless.mdx | 2 +- api_docs/serverless.mdx | 2 +- api_docs/serverless_observability.mdx | 2 +- api_docs/serverless_search.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/text_based_languages.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.devdocs.json | 110 +- api_docs/triggers_actions_ui.mdx | 4 +- api_docs/ui_actions.devdocs.json | 21 + api_docs/ui_actions.mdx | 4 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_histogram.mdx | 2 +- api_docs/unified_search.mdx | 2 +- api_docs/unified_search_autocomplete.mdx | 2 +- api_docs/uptime.mdx | 2 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.mdx | 2 +- 589 files changed, 19380 insertions(+), 1633 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 4830d43d5a5e1..86783d0ca2341 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index cbdf72e9b3f17..3bad125ce9a95 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/aiops.devdocs.json b/api_docs/aiops.devdocs.json index b4ce7cfd2e208..a5d2c0392ddfb 100644 --- a/api_docs/aiops.devdocs.json +++ b/api_docs/aiops.devdocs.json @@ -591,6 +591,69 @@ "path": "x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "aiops", + "id": "def-public.AiopsAppDependencies.presentationUtil", + "type": "Object", + "tags": [], + "label": "presentationUtil", + "description": [], + "signature": [ + { + "pluginId": "presentationUtil", + "scope": "public", + "docId": "kibPresentationUtilPluginApi", + "section": "def-public.PresentationUtilPluginStart", + "text": "PresentationUtilPluginStart" + }, + " | undefined" + ], + "path": "x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "aiops", + "id": "def-public.AiopsAppDependencies.embeddable", + "type": "Object", + "tags": [], + "label": "embeddable", + "description": [], + "signature": [ + { + "pluginId": "embeddable", + "scope": "public", + "docId": "kibEmbeddablePluginApi", + "section": "def-public.EmbeddableStart", + "text": "EmbeddableStart" + }, + " | undefined" + ], + "path": "x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "aiops", + "id": "def-public.AiopsAppDependencies.cases", + "type": "Object", + "tags": [], + "label": "cases", + "description": [], + "signature": [ + { + "pluginId": "cases", + "scope": "public", + "docId": "kibCasesPluginApi", + "section": "def-public.CasesUiStart", + "text": "CasesUiStart" + }, + " | undefined" + ], + "path": "x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -895,29 +958,6 @@ "deprecated": false, "trackAdoption": false }, - { - "parentPluginId": "aiops", - "id": "def-public.LogRateAnalysisContentWrapperProps.analysisType", - "type": "CompoundType", - "tags": [], - "label": "analysisType", - "description": [ - "The type of analysis, whether it's a spike or dip" - ], - "signature": [ - { - "pluginId": "aiops", - "scope": "common", - "docId": "kibAiopsPluginApi", - "section": "def-common.LogRateAnalysisType", - "text": "LogRateAnalysisType" - }, - " | undefined" - ], - "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content_wrapper.tsx", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "aiops", "id": "def-public.LogRateAnalysisContentWrapperProps.stickyHistogram", @@ -1127,6 +1167,22 @@ "deprecated": false, "trackAdoption": false, "children": [ + { + "parentPluginId": "aiops", + "id": "def-public.LogRateAnalysisResultsData.analysisType", + "type": "CompoundType", + "tags": [], + "label": "analysisType", + "description": [ + "The type of analysis, whether it's a spike or dip" + ], + "signature": [ + "\"spike\" | \"dip\"" + ], + "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "aiops", "id": "def-public.LogRateAnalysisResultsData.significantTerms", @@ -1178,44 +1234,8 @@ } ], "enums": [], - "misc": [ - { - "parentPluginId": "aiops", - "id": "def-public.LogRateAnalysisType", - "type": "Type", - "tags": [], - "label": "LogRateAnalysisType", - "description": [ - "\nUnion type of log rate analysis types." - ], - "signature": [ - "\"spike\" | \"dip\"" - ], - "path": "x-pack/plugins/aiops/common/constants.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - } - ], - "objects": [ - { - "parentPluginId": "aiops", - "id": "def-public.LOG_RATE_ANALYSIS_TYPE", - "type": "Object", - "tags": [], - "label": "LOG_RATE_ANALYSIS_TYPE", - "description": [ - "\nThe type of log rate analysis (spike or dip) will affect how parameters are\npassed to the analysis API endpoint." - ], - "signature": [ - "{ readonly SPIKE: \"spike\"; readonly DIP: \"dip\"; }" - ], - "path": "x-pack/plugins/aiops/common/constants.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - } - ] + "misc": [], + "objects": [] }, "server": { "classes": [], @@ -1280,23 +1300,6 @@ "trackAdoption": false, "initialIsOpen": false }, - { - "parentPluginId": "aiops", - "id": "def-common.LogRateAnalysisType", - "type": "Type", - "tags": [], - "label": "LogRateAnalysisType", - "description": [ - "\nUnion type of log rate analysis types." - ], - "signature": [ - "\"spike\" | \"dip\"" - ], - "path": "x-pack/plugins/aiops/common/constants.ts", - "deprecated": false, - "trackAdoption": false, - "initialIsOpen": false - }, { "parentPluginId": "aiops", "id": "def-common.PLUGIN_ID", diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 370b7d66dafcd..9c5930a694dc4 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; @@ -21,22 +21,16 @@ Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 60 | 1 | 0 | 0 | +| 60 | 1 | 3 | 0 | ## Client -### Objects - - ### Functions ### Interfaces -### Consts, variables and types - - ## Server ### Setup diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index d0680f21fb288..3998967eaef3e 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -3303,7 +3303,7 @@ "section": "def-common.FieldSpec", "text": "FieldSpec" }, - "[]>; getFieldsForIndexPattern: (indexPattern: ", + "[]>; getExistingIndices: (indices: string[]) => Promise; getFieldsForIndexPattern: (indexPattern: ", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index b6e940f0c1c8f..a6dba1264568f 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json index f54b33efb04e3..1ec2a49338bdc 100644 --- a/api_docs/apm.devdocs.json +++ b/api_docs/apm.devdocs.json @@ -81,7 +81,7 @@ "label": "featureFlags", "description": [], "signature": [ - "{ agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; fastRefreshAvailable: boolean; }" + "{ agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; }" ], "path": "x-pack/plugins/apm/public/index.ts", "deprecated": false, @@ -265,7 +265,7 @@ "Observable", "; enabled: boolean; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; serviceMapTerminateAfter: number; serviceMapMaxTraces: number; ui: Readonly<{} & { enabled: boolean; maxTraceItems: number; }>; searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", - "; telemetryCollectionEnabled: boolean; metricsInterval: number; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; forceSyntheticSource: boolean; latestAgentVersionsUrl: string; serverlessOnboarding: boolean; serverless: Readonly<{} & { enabled: true; }>; managedServiceUrl: string; featureFlags: Readonly<{} & { agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; fastRefreshAvailable: boolean; }>; }>>; getApmIndices: () => Promise>; createApmEventClient: ({ request, context, debug, }: { debug?: boolean | undefined; request: ", + "; telemetryCollectionEnabled: boolean; metricsInterval: number; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; forceSyntheticSource: boolean; latestAgentVersionsUrl: string; serverlessOnboarding: boolean; serverless: Readonly<{} & { enabled: true; }>; managedServiceUrl: string; featureFlags: Readonly<{} & { agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; }>; }>>; getApmIndices: () => Promise>; createApmEventClient: ({ request, context, debug, }: { debug?: boolean | undefined; request: ", { "pluginId": "@kbn/core-http-server", "scope": "common", @@ -511,7 +511,7 @@ "signature": [ "{ readonly indices: Readonly<{} & { error: string; metric: string; span: string; transaction: string; onboarding: string; }>; readonly enabled: boolean; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly serviceMapTerminateAfter: number; readonly serviceMapMaxTraces: number; readonly ui: Readonly<{} & { enabled: boolean; maxTraceItems: number; }>; readonly searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", - "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; readonly forceSyntheticSource: boolean; readonly latestAgentVersionsUrl: string; readonly serverlessOnboarding: boolean; readonly serverless: Readonly<{} & { enabled: true; }>; readonly managedServiceUrl: string; readonly featureFlags: Readonly<{} & { agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; fastRefreshAvailable: boolean; }>; }" + "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; readonly forceSyntheticSource: boolean; readonly latestAgentVersionsUrl: string; readonly serverlessOnboarding: boolean; readonly serverless: Readonly<{} & { enabled: true; }>; readonly managedServiceUrl: string; readonly featureFlags: Readonly<{} & { agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; }>; }" ], "path": "x-pack/plugins/apm/server/routes/typings.ts", "deprecated": false, @@ -525,7 +525,7 @@ "label": "featureFlags", "description": [], "signature": [ - "{ agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; fastRefreshAvailable: boolean; }" + "{ agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; }" ], "path": "x-pack/plugins/apm/server/routes/typings.ts", "deprecated": false, @@ -963,7 +963,7 @@ "signature": [ "{ readonly indices: Readonly<{} & { error: string; metric: string; span: string; transaction: string; onboarding: string; }>; readonly enabled: boolean; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly serviceMapTerminateAfter: number; readonly serviceMapMaxTraces: number; readonly ui: Readonly<{} & { enabled: boolean; maxTraceItems: number; }>; readonly searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", - "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; readonly forceSyntheticSource: boolean; readonly latestAgentVersionsUrl: string; readonly serverlessOnboarding: boolean; readonly serverless: Readonly<{} & { enabled: true; }>; readonly managedServiceUrl: string; readonly featureFlags: Readonly<{} & { agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; fastRefreshAvailable: boolean; }>; }" + "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; readonly forceSyntheticSource: boolean; readonly latestAgentVersionsUrl: string; readonly serverlessOnboarding: boolean; readonly serverless: Readonly<{} & { enabled: true; }>; readonly managedServiceUrl: string; readonly featureFlags: Readonly<{} & { agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; }>; }" ], "path": "x-pack/plugins/apm/server/index.ts", "deprecated": false, @@ -1795,11 +1795,11 @@ "TypeC", "<{ useSpanName: ", "Type", - "; enableServiceTransactionMetrics: ", + "; enableServiceTransactionMetrics: ", "Type", - "; enableContinuousRollups: ", + "; enableContinuousRollups: ", "Type", - "; }>, ", + "; }>, ", "TypeC", "<{ kuery: ", "StringC", @@ -3169,7 +3169,7 @@ "StringC", "; searchServiceDestinationMetrics: ", "Type", - "; }>]>; }> | undefined; handler: ({}: ", + "; }>]>; }> | undefined; handler: ({}: ", { "pluginId": "apm", "scope": "server", @@ -3203,7 +3203,7 @@ "StringC", "; searchServiceDestinationMetrics: ", "Type", - "; }>, ", + "; }>, ", "TypeC", "<{ start: ", "Type", @@ -3269,7 +3269,7 @@ "StringC", "; searchServiceDestinationMetrics: ", "Type", - "; }>, ", + "; }>, ", "TypeC", "<{ start: ", "Type", @@ -3337,7 +3337,7 @@ "StringC", "; searchServiceDestinationMetrics: ", "Type", - "; }>, ", + "; }>, ", "TypeC", "<{ start: ", "Type", @@ -4115,7 +4115,7 @@ "PartialC", "<{ overwrite: ", "Type", - "; }>; }>, ", + "; }>; }>, ", "TypeC", "<{ body: ", "IntersectionC", @@ -4903,7 +4903,7 @@ "Type", "; useDurationSummary: ", "Type", - "; }>, ", + "; }>, ", "PartialC", "<{ transactionName: ", "StringC", @@ -5089,7 +5089,7 @@ "Type", "; useDurationSummary: ", "Type", - "; }>]>, ", + "; }>]>, ", "TypeC", "<{ transactionNames: ", "Type", @@ -5181,7 +5181,7 @@ "TypeC", "<{ useDurationSummary: ", "Type", - "; transactionType: ", + "; transactionType: ", "StringC", "; latencyAggregationType: ", "UnionC", @@ -8116,7 +8116,7 @@ "Observable", "; enabled: boolean; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; serviceMapTerminateAfter: number; serviceMapMaxTraces: number; ui: Readonly<{} & { enabled: boolean; maxTraceItems: number; }>; searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", - "; telemetryCollectionEnabled: boolean; metricsInterval: number; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; forceSyntheticSource: boolean; latestAgentVersionsUrl: string; serverlessOnboarding: boolean; serverless: Readonly<{} & { enabled: true; }>; managedServiceUrl: string; featureFlags: Readonly<{} & { agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; fastRefreshAvailable: boolean; }>; }>>" + "; telemetryCollectionEnabled: boolean; metricsInterval: number; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; forceSyntheticSource: boolean; latestAgentVersionsUrl: string; serverlessOnboarding: boolean; serverless: Readonly<{} & { enabled: true; }>; managedServiceUrl: string; featureFlags: Readonly<{} & { agentConfigurationAvailable: boolean; configurableIndicesAvailable: boolean; infrastructureTabAvailable: boolean; infraUiAvailable: boolean; migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; }>; }>>" ], "path": "x-pack/plugins/apm/server/types.ts", "deprecated": false, diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index f9d18e273f7c8..4b9ffe1f2e5ac 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index f4d18f9705670..c8b9efdabad36 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 40c84072b6875..17ab8f80be077 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] --- import bannersObj from './banners.devdocs.json'; diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index a09991262233c..e7757cb287952 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] --- import bfetchObj from './bfetch.devdocs.json'; diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index 6015bb6745617..b4a40940e23de 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] --- import canvasObj from './canvas.devdocs.json'; diff --git a/api_docs/cases.devdocs.json b/api_docs/cases.devdocs.json index c0de3e16ac6a6..b749532e5f360 100644 --- a/api_docs/cases.devdocs.json +++ b/api_docs/cases.devdocs.json @@ -1091,7 +1091,7 @@ "\nReturn the UI capabilities for each type of operation. These strings must match the values defined in the UI\nhere: x-pack/plugins/cases/public/client/helpers/capabilities.ts" ], "signature": [ - "() => { all: readonly [\"create_cases\", \"read_cases\", \"update_cases\", \"push_cases\"]; read: readonly [\"read_cases\"]; delete: readonly [\"delete_cases\"]; }" + "() => { all: readonly [\"create_cases\", \"read_cases\", \"update_cases\", \"push_cases\", \"cases_connectors\"]; read: readonly [\"read_cases\", \"cases_connectors\"]; delete: readonly [\"delete_cases\"]; }" ], "path": "x-pack/plugins/cases/common/utils/capabilities.ts", "deprecated": false, @@ -1108,7 +1108,7 @@ "label": "getApiTags", "description": [], "signature": [ - "(owner: \"cases\" | \"observability\" | \"securitySolution\") => { all: readonly [\"casesSuggestUserProfiles\", \"bulkGetUserProfiles\", string, string]; read: readonly [\"casesSuggestUserProfiles\", \"bulkGetUserProfiles\", string]; delete: readonly [string]; }" + "(owner: \"cases\" | \"observability\" | \"securitySolution\") => { all: readonly [\"casesSuggestUserProfiles\", \"bulkGetUserProfiles\", \"casesGetConnectorsConfigure\", string, string]; read: readonly [\"casesSuggestUserProfiles\", \"bulkGetUserProfiles\", \"casesGetConnectorsConfigure\", string]; delete: readonly [string]; }" ], "path": "x-pack/plugins/cases/common/utils/api_tags.ts", "deprecated": false, @@ -1312,6 +1312,17 @@ "path": "x-pack/plugins/cases/common/ui/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "cases", + "id": "def-common.CasesPermissions.connectors", + "type": "boolean", + "tags": [], + "label": "connectors", + "description": [], + "path": "x-pack/plugins/cases/common/ui/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 5b9296c2f8cac..a40e4198326a2 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] --- import casesObj from './cases.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 93 | 0 | 74 | 27 | +| 94 | 0 | 75 | 27 | ## Client diff --git a/api_docs/charts.devdocs.json b/api_docs/charts.devdocs.json index abf1df8307859..b8c332abcc153 100644 --- a/api_docs/charts.devdocs.json +++ b/api_docs/charts.devdocs.json @@ -1350,7 +1350,15 @@ "section": "def-common.Datatable", "text": "Datatable" }, - ", \"rows\" | \"columns\">; column: number; value: any[]; }; timeFieldName?: string | undefined; negate?: boolean | undefined; }" + ", \"rows\" | \"columns\">; cells: { column: number; row: number; }[]; relation?: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.BooleanRelation", + "text": "BooleanRelation" + }, + " | undefined; }[]; timeFieldName?: string | undefined; negate?: boolean | undefined; }" ], "path": "src/plugins/charts/public/index.ts", "deprecated": false, diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 0386ec84baa3e..9ddb4d651b7b3 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 917ce1dd5e70d..257ae7fc83e29 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index 2439ac29b2acd..2f8dfaa9ba409 100644 --- a/api_docs/cloud_chat.mdx +++ b/api_docs/cloud_chat.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat title: "cloudChat" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChat plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index 09e274f8d6ac2..bb35de3db20ac 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 904c4a2398b07..d49d837df6d07 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index 50651cb15c6eb..1b083e68a4f3d 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 19630e2129c64..948087b9508f8 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index e5d9d6c84093e..5746fc75f656f 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] --- import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json'; diff --git a/api_docs/console.mdx b/api_docs/console.mdx index c26eb4445b0d2..584fc4bafb0c9 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index 375156d7a08a5..ad7ba3b1ac02f 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index b86db1ce03475..aaa9ba738aa2d 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 48852fd3e96b2..853c2d8170e26 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 2bb3f88bcfd8e..b68f871091838 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index f5efa0a0d205f..8139bcd458a66 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index 0ff7fe1f1bdc7..4f47b2094fb4d 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -12999,7 +12999,7 @@ "section": "def-server.DataPluginStart", "text": "DataPluginStart" }, - ">, { bfetch, expressions, usageCollection, fieldFormats, taskManager, security, }: ", + ">, { bfetch, expressions, usageCollection, fieldFormats, security }: ", "DataPluginSetupDependencies", ") => { search: ", "ISearchSetup", @@ -13056,7 +13056,7 @@ "id": "def-server.DataServerPlugin.setup.$2", "type": "Object", "tags": [], - "label": "{\n bfetch,\n expressions,\n usageCollection,\n fieldFormats,\n taskManager,\n security,\n }", + "label": "{ bfetch, expressions, usageCollection, fieldFormats, security }", "description": [], "signature": [ "DataPluginSetupDependencies" @@ -13085,7 +13085,7 @@ "section": "def-common.CoreStart", "text": "CoreStart" }, - ", { fieldFormats, dataViews, taskManager }: ", + ", { fieldFormats, dataViews }: ", "DataPluginStartDependencies", ") => { datatableUtilities: ", "DatatableUtilitiesService", @@ -13155,7 +13155,7 @@ "id": "def-server.DataServerPlugin.start.$2", "type": "Object", "tags": [], - "label": "{ fieldFormats, dataViews, taskManager }", + "label": "{ fieldFormats, dataViews }", "description": [], "signature": [ "DataPluginStartDependencies" @@ -13568,6 +13568,10 @@ "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/public/update_data_view.ts" }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" @@ -13604,10 +13608,6 @@ "plugin": "apm", "path": "x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts" }, - { - "plugin": "triggersActionsUi", - "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" - }, { "plugin": "exploratoryView", "path": "x-pack/plugins/exploratory_view/public/utils/observability_data_views/observability_data_views.ts" @@ -16322,6 +16322,44 @@ "FieldSpec[]" ] }, + { + "parentPluginId": "data", + "id": "def-server.DataViewsService.getExistingIndices", + "type": "Function", + "tags": [], + "label": "getExistingIndices", + "description": [ + "\nGet existing index pattern list by providing string array index pattern list." + ], + "signature": [ + "(indices: string[]) => Promise" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-server.DataViewsService.getExistingIndices.$1", + "type": "Array", + "tags": [], + "label": "indices", + "description": [ + "index pattern list" + ], + "signature": [ + "string[]" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [ + "index pattern list" + ] + }, { "parentPluginId": "data", "id": "def-server.DataViewsService.getFieldsForIndexPattern", @@ -17299,6 +17337,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "data", + "id": "def-server.IndexPatternsFetcher.Unnamed.$3", + "type": "boolean", + "tags": [], + "label": "rollupsEnabled", + "description": [], + "signature": [ + "boolean" + ], + "path": "src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], "returnComment": [] @@ -21247,6 +21300,10 @@ "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/public/update_data_view.ts" }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" @@ -21283,10 +21340,6 @@ "plugin": "apm", "path": "x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts" }, - { - "plugin": "triggersActionsUi", - "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" - }, { "plugin": "exploratoryView", "path": "x-pack/plugins/exploratory_view/public/utils/observability_data_views/observability_data_views.ts" @@ -24872,6 +24925,44 @@ "FieldSpec[]" ] }, + { + "parentPluginId": "data", + "id": "def-common.DataViewsService.getExistingIndices", + "type": "Function", + "tags": [], + "label": "getExistingIndices", + "description": [ + "\nGet existing index pattern list by providing string array index pattern list." + ], + "signature": [ + "(indices: string[]) => Promise" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "data", + "id": "def-common.DataViewsService.getExistingIndices.$1", + "type": "Array", + "tags": [], + "label": "indices", + "description": [ + "index pattern list" + ], + "signature": [ + "string[]" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [ + "index pattern list" + ] + }, { "parentPluginId": "data", "id": "def-common.DataViewsService.getFieldsForIndexPattern", @@ -28292,7 +28383,7 @@ "section": "def-common.FieldSpec", "text": "FieldSpec" }, - "[]>; getFieldsForIndexPattern: (indexPattern: ", + "[]>; getExistingIndices: (indices: string[]) => Promise; getFieldsForIndexPattern: (indexPattern: ", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/data.mdx b/api_docs/data.mdx index ed440a37583cb..d48b3a6a3e082 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3295 | 119 | 2573 | 27 | +| 3301 | 119 | 2575 | 27 | ## Client diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 6f4cdc678a730..d3a2a0dc456e3 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3295 | 119 | 2573 | 27 | +| 3301 | 119 | 2575 | 27 | ## Client diff --git a/api_docs/data_search.devdocs.json b/api_docs/data_search.devdocs.json index b4c44781b50fa..2a246bcc16312 100644 --- a/api_docs/data_search.devdocs.json +++ b/api_docs/data_search.devdocs.json @@ -3889,6 +3889,20 @@ "path": "src/plugins/data/server/search/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-server.SearchStrategyDependencies.rollupsEnabled", + "type": "CompoundType", + "tags": [], + "label": "rollupsEnabled", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/data/server/search/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 2ba7fae435d5f..a54d159e299bb 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3295 | 119 | 2573 | 27 | +| 3301 | 119 | 2575 | 27 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 0afb9c6cc38d6..765d65b328eb1 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 88b56f7be7bf5..81f5c42e6652e 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 4a6c796e4e163..6708b3bbd5e58 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.devdocs.json b/api_docs/data_views.devdocs.json index c82f54e715564..cb3003d20cac3 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -379,6 +379,10 @@ "plugin": "lens", "path": "x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx" }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" @@ -415,10 +419,6 @@ "plugin": "apm", "path": "x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts" }, - { - "plugin": "triggersActionsUi", - "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" - }, { "plugin": "exploratoryView", "path": "x-pack/plugins/exploratory_view/public/utils/observability_data_views/observability_data_views.ts" @@ -4410,6 +4410,44 @@ "FieldSpec[]" ] }, + { + "parentPluginId": "dataViews", + "id": "def-public.DataViewsService.getExistingIndices", + "type": "Function", + "tags": [], + "label": "getExistingIndices", + "description": [ + "\nGet existing index pattern list by providing string array index pattern list." + ], + "signature": [ + "(indices: string[]) => Promise" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-public.DataViewsService.getExistingIndices.$1", + "type": "Array", + "tags": [], + "label": "indices", + "description": [ + "index pattern list" + ], + "signature": [ + "string[]" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [ + "index pattern list" + ] + }, { "parentPluginId": "dataViews", "id": "def-public.DataViewsService.getFieldsForIndexPattern", @@ -8229,6 +8267,10 @@ "plugin": "lens", "path": "x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx" }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" @@ -8265,10 +8307,6 @@ "plugin": "apm", "path": "x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts" }, - { - "plugin": "triggersActionsUi", - "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" - }, { "plugin": "exploratoryView", "path": "x-pack/plugins/exploratory_view/public/utils/observability_data_views/observability_data_views.ts" @@ -10576,7 +10614,7 @@ "section": "def-server.DataViewsServerPluginSetupDependencies", "text": "DataViewsServerPluginSetupDependencies" }, - ") => {}" + ") => { enableRollups: () => boolean; }" ], "path": "src/plugins/data_views/server/plugin.ts", "deprecated": false, @@ -11301,6 +11339,44 @@ "FieldSpec[]" ] }, + { + "parentPluginId": "dataViews", + "id": "def-server.DataViewsService.getExistingIndices", + "type": "Function", + "tags": [], + "label": "getExistingIndices", + "description": [ + "\nGet existing index pattern list by providing string array index pattern list." + ], + "signature": [ + "(indices: string[]) => Promise" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-server.DataViewsService.getExistingIndices.$1", + "type": "Array", + "tags": [], + "label": "indices", + "description": [ + "index pattern list" + ], + "signature": [ + "string[]" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [ + "index pattern list" + ] + }, { "parentPluginId": "dataViews", "id": "def-server.DataViewsService.getFieldsForIndexPattern", @@ -12278,6 +12354,21 @@ "deprecated": false, "trackAdoption": false, "isRequired": true + }, + { + "parentPluginId": "dataViews", + "id": "def-server.IndexPatternsFetcher.Unnamed.$3", + "type": "boolean", + "tags": [], + "label": "rollupsEnabled", + "description": [], + "signature": [ + "boolean" + ], + "path": "src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true } ], "returnComment": [] @@ -13451,6 +13542,39 @@ } ], "objects": [], + "setup": { + "parentPluginId": "dataViews", + "id": "def-server.DataViewsServerPluginSetup", + "type": "Interface", + "tags": [], + "label": "DataViewsServerPluginSetup", + "description": [ + "\nDataViews server plugin setup api" + ], + "path": "src/plugins/data_views/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-server.DataViewsServerPluginSetup.enableRollups", + "type": "Function", + "tags": [], + "label": "enableRollups", + "description": [], + "signature": [ + "() => void" + ], + "path": "src/plugins/data_views/server/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "lifecycle": "setup", + "initialIsOpen": true + }, "start": { "parentPluginId": "dataViews", "id": "def-server.DataViewsServerPluginStart", @@ -14803,22 +14927,6 @@ ], "lifecycle": "start", "initialIsOpen": true - }, - "setup": { - "parentPluginId": "dataViews", - "id": "def-server.DataViewsServerPluginSetup", - "type": "Interface", - "tags": [], - "label": "DataViewsServerPluginSetup", - "description": [ - "\nDataViews server plugin setup api" - ], - "path": "src/plugins/data_views/server/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [], - "lifecycle": "setup", - "initialIsOpen": true } }, "common": { @@ -15200,6 +15308,10 @@ "plugin": "lens", "path": "x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx" }, + { + "plugin": "triggersActionsUi", + "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts" @@ -15236,10 +15348,6 @@ "plugin": "apm", "path": "x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts" }, - { - "plugin": "triggersActionsUi", - "path": "x-pack/plugins/triggers_actions_ui/public/common/lib/data_apis.ts" - }, { "plugin": "exploratoryView", "path": "x-pack/plugins/exploratory_view/public/utils/observability_data_views/observability_data_views.ts" @@ -18936,6 +19044,44 @@ "FieldSpec[]" ] }, + { + "parentPluginId": "dataViews", + "id": "def-common.DataViewsService.getExistingIndices", + "type": "Function", + "tags": [], + "label": "getExistingIndices", + "description": [ + "\nGet existing index pattern list by providing string array index pattern list." + ], + "signature": [ + "(indices: string[]) => Promise" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.DataViewsService.getExistingIndices.$1", + "type": "Array", + "tags": [], + "label": "indices", + "description": [ + "index pattern list" + ], + "signature": [ + "string[]" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [ + "index pattern list" + ] + }, { "parentPluginId": "dataViews", "id": "def-common.DataViewsService.getFieldsForIndexPattern", @@ -22036,6 +22182,44 @@ ], "returnComment": [] }, + { + "parentPluginId": "dataViews", + "id": "def-common.DataViewsServicePublicMethods.getExistingIndices", + "type": "Function", + "tags": [], + "label": "getExistingIndices", + "description": [ + "\nGet existing index pattern list by providing string array index pattern list." + ], + "signature": [ + "(indices: string[]) => Promise" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "dataViews", + "id": "def-common.DataViewsServicePublicMethods.getExistingIndices.$1", + "type": "Array", + "tags": [], + "label": "indices", + "description": [ + "- index pattern list" + ], + "signature": [ + "string[]" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [ + "index pattern list of index patterns that match indices" + ] + }, { "parentPluginId": "dataViews", "id": "def-common.DataViewsServicePublicMethods.getIds", @@ -24907,7 +25091,7 @@ "section": "def-common.FieldSpec", "text": "FieldSpec" }, - "[]>; getFieldsForIndexPattern: (indexPattern: ", + "[]>; getExistingIndices: (indices: string[]) => Promise; getFieldsForIndexPattern: (indexPattern: ", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 939dbf86bcc32..4d03a36b92878 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1012 | 0 | 243 | 2 | +| 1024 | 0 | 246 | 2 | ## Client diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 121bea50c1589..1336377ffa864 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index acc2067839829..64b0db70a4bdc 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -18,12 +18,12 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | ---------------|-----------|-----------| | | ml, stackAlerts | - | | | ruleRegistry, observability, ml, infra, monitoring, securitySolution, stackAlerts, synthetics, transform, uptime | - | -| | @kbn/es-query, @kbn/visualization-ui-components, observability, securitySolution, timelines, lists, threatIntelligence, savedSearch, dataViews, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, @kbn/event-annotation-components, lens, ml, logsShared, visTypeTimeseries, apm, triggersActionsUi, exploratoryView, fleet, dataVisualizer, stackAlerts, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | -| | @kbn/es-query, @kbn/visualization-ui-components, observability, securitySolution, timelines, lists, threatIntelligence, savedSearch, dataViews, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, @kbn/event-annotation-components, lens, ml, logsShared, visTypeTimeseries, apm, triggersActionsUi, exploratoryView, fleet, dataVisualizer, stackAlerts, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | -| | @kbn/es-query, @kbn/visualization-ui-components, observability, securitySolution, timelines, lists, threatIntelligence, savedSearch, data, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, @kbn/event-annotation-components, lens, ml, logsShared, visTypeTimeseries, apm, triggersActionsUi, exploratoryView, fleet, dataVisualizer, stackAlerts, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega | - | -| | inspector, data, advancedSettings, savedObjects, embeddable, dataViewEditor, unifiedSearch, visualizations, controls, dashboard, licensing, savedObjectsTagging, eventAnnotation, dataViewFieldEditor, lens, @kbn/ml-date-picker, aiops, security, triggersActionsUi, cases, observabilityShared, discover, exploratoryView, fleet, maps, telemetry, dataVisualizer, ml, observability, banners, reporting, timelines, runtimeFields, indexManagement, dashboardEnhanced, imageEmbeddable, graph, monitoring, securitySolution, synthetics, transform, uptime, console, dataViewManagement, filesManagement, uiActions, visTypeVislib | - | +| | @kbn/es-query, @kbn/visualization-ui-components, observability, securitySolution, timelines, lists, threatIntelligence, savedSearch, dataViews, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, @kbn/event-annotation-components, lens, triggersActionsUi, ml, logsShared, visTypeTimeseries, apm, exploratoryView, fleet, dataVisualizer, stackAlerts, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | +| | @kbn/es-query, @kbn/visualization-ui-components, observability, securitySolution, timelines, lists, threatIntelligence, savedSearch, dataViews, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, @kbn/event-annotation-components, lens, triggersActionsUi, ml, logsShared, visTypeTimeseries, apm, exploratoryView, fleet, dataVisualizer, stackAlerts, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega, data | - | +| | @kbn/es-query, @kbn/visualization-ui-components, observability, securitySolution, timelines, lists, threatIntelligence, savedSearch, data, savedObjectsManagement, unifiedSearch, controls, @kbn/unified-field-list, @kbn/event-annotation-components, lens, triggersActionsUi, ml, logsShared, visTypeTimeseries, apm, exploratoryView, fleet, dataVisualizer, stackAlerts, infra, canvas, enterpriseSearch, graph, transform, upgradeAssistant, uptime, ux, maps, dataViewManagement, inputControlVis, visDefaultEditor, presentationUtil, visTypeTimelion, visTypeVega | - | +| | inspector, data, advancedSettings, savedObjects, embeddable, dataViewEditor, unifiedSearch, visualizations, controls, dashboard, licensing, savedObjectsTagging, eventAnnotation, dataViewFieldEditor, lens, security, triggersActionsUi, cases, @kbn/ml-date-picker, aiops, observabilityShared, discover, exploratoryView, fleet, maps, telemetry, dataVisualizer, ml, observability, banners, reporting, timelines, cloudSecurityPosture, runtimeFields, indexManagement, dashboardEnhanced, imageEmbeddable, graph, monitoring, securitySolution, synthetics, transform, uptime, cloudLinks, console, dataViewManagement, filesManagement, uiActions, visTypeVislib | - | | | home, data, esUiShared, savedObjectsManagement, exploratoryView, fleet, ml, observability, apm, indexLifecycleManagement, observabilityOnboarding, synthetics, upgradeAssistant, uptime, ux, kibanaOverview | - | -| | share, uiActions, guidedOnboarding, home, management, data, advancedSettings, spaces, savedObjects, visualizations, controls, dashboard, savedObjectsTagging, expressionXY, lens, expressionMetricVis, expressionGauge, alerting, security, triggersActionsUi, serverless, cases, discover, exploratoryView, fleet, maps, licenseManagement, dataVisualizer, ml, observability, infra, profiling, apm, canvas, expressionImage, expressionMetric, expressionError, expressionRevealImage, expressionRepeatImage, expressionShape, indexManagement, crossClusterReplication, enterpriseSearch, globalSearchBar, graph, grokdebugger, indexLifecycleManagement, ingestPipelines, logstash, monitoring, observabilityOnboarding, osquery, devTools, painlessLab, remoteClusters, rollup, searchprofiler, newsfeed, securitySolution, serverlessSearch, snapshotRestore, synthetics, transform, upgradeAssistant, uptime, ux, watcher, cloudDataMigration, console, dataViewManagement, filesManagement, kibanaOverview, visDefaultEditor, expressionHeatmap, expressionLegacyMetricVis, expressionPartitionVis, expressionTagcloud, visTypeTable, visTypeTimelion, visTypeTimeseries, visTypeVega, visTypeVislib | - | +| | share, uiActions, guidedOnboarding, home, management, data, advancedSettings, spaces, savedObjects, visualizations, serverless, controls, dashboard, savedObjectsTagging, expressionXY, lens, expressionMetricVis, expressionGauge, security, alerting, triggersActionsUi, cases, aiops, discover, exploratoryView, observabilityAIAssistant, fleet, maps, licenseManagement, dataVisualizer, ml, observability, infra, profiling, apm, canvas, expressionImage, expressionMetric, expressionError, expressionRevealImage, expressionRepeatImage, expressionShape, indexManagement, crossClusterReplication, enterpriseSearch, globalSearchBar, graph, grokdebugger, indexLifecycleManagement, ingestPipelines, logstash, monitoring, observabilityOnboarding, osquery, devTools, painlessLab, remoteClusters, rollup, searchprofiler, newsfeed, securitySolution, serverlessSearch, snapshotRestore, synthetics, transform, upgradeAssistant, uptime, ux, watcher, cloudDataMigration, console, dataViewManagement, filesManagement, kibanaOverview, visDefaultEditor, expressionHeatmap, expressionLegacyMetricVis, expressionPartitionVis, expressionTagcloud, visTypeTable, visTypeTimelion, visTypeTimeseries, visTypeVega, visTypeVislib | - | | | encryptedSavedObjects, actions, data, ml, logstash, securitySolution, cloudChat | - | | | actions, ml, savedObjectsTagging, enterpriseSearch | - | | | @kbn/core-saved-objects-browser-internal, @kbn/core, savedObjects, presentationUtil, visualizations, aiops, ml, dataVisualizer, dashboardEnhanced, graph, lens, securitySolution, eventAnnotation, @kbn/core-saved-objects-browser-mocks | - | @@ -102,6 +102,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | visTypeTimeseries, graph, dataViewManagement, dataViews | - | | | visTypeTimeseries, graph, dataViewManagement, dataViews | - | | | visTypeTimeseries, graph, dataViewManagement | - | +| | visualizations, graph | - | | | @kbn/core, lens, savedObjects | - | | | dataViews, maps | - | | | dataViewManagement, dataViews | - | @@ -140,7 +141,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | @kbn/core-lifecycle-browser-mocks, @kbn/core, @kbn/core-plugins-browser-internal | - | | | @kbn/core | - | | | @kbn/core-plugins-server-internal | - | -| | security, licenseManagement, ml, profiling, apm, crossClusterReplication, logstash, painlessLab, searchprofiler, watcher | 8.8.0 | +| | security, aiops, licenseManagement, ml, profiling, apm, crossClusterReplication, logstash, painlessLab, searchprofiler, watcher | 8.8.0 | | | spaces, security, actions, alerting, ml, remoteClusters, graph, indexLifecycleManagement, mapsEms, osquery, painlessLab, rollup, searchprofiler, securitySolution, snapshotRestore, transform, upgradeAssistant | 8.8.0 | | | apm, fleet, security, securitySolution | 8.8.0 | | | apm, fleet, security, securitySolution | 8.8.0 | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index cdf90dc6b2602..a061b8f8d595c 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -399,7 +399,9 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [log_categorization_app_state.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx#:~:text=toMountPoint), [log_categorization_app_state.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx#:~:text=toMountPoint), [show_flyout.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx#:~:text=toMountPoint), [show_flyout.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx#:~:text=toMountPoint), [show_flyout.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx#:~:text=toMountPoint), [log_rate_analysis_app_state.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx#:~:text=toMountPoint), [log_rate_analysis_app_state.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx#:~:text=toMountPoint), [log_rate_analysis_content_wrapper.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content_wrapper.tsx#:~:text=toMountPoint), [log_rate_analysis_content_wrapper.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content_wrapper.tsx#:~:text=toMountPoint), [change_point_detection_root.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_root.tsx#:~:text=toMountPoint)+ 1 more | - | +| | [embeddable_change_point_chart.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx#:~:text=toMountPoint), [embeddable_change_point_chart.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx#:~:text=toMountPoint), [handle_explicit_input.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/embeddable/handle_explicit_input.tsx#:~:text=toMountPoint), [handle_explicit_input.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/embeddable/handle_explicit_input.tsx#:~:text=toMountPoint), [log_categorization_app_state.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx#:~:text=toMountPoint), [log_categorization_app_state.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx#:~:text=toMountPoint), [show_flyout.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx#:~:text=toMountPoint), [show_flyout.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx#:~:text=toMountPoint), [show_flyout.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx#:~:text=toMountPoint), [log_rate_analysis_app_state.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx#:~:text=toMountPoint)+ 5 more | - | +| | [embeddable_change_point_chart.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx#:~:text=KibanaThemeProvider), [embeddable_change_point_chart.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx#:~:text=KibanaThemeProvider), [embeddable_change_point_chart.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx#:~:text=KibanaThemeProvider) | - | +| | [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/plugin.tsx#:~:text=license%24) | 8.8.0 | | | [search_utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/application/utils/search_utils.ts#:~:text=SimpleSavedObject), [search_utils.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/application/utils/search_utils.ts#:~:text=SimpleSavedObject) | - | @@ -502,11 +504,20 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] +## cloudLinks + +| Deprecated API | Reference location(s) | Remove By | +| ---------------|-----------|-----------| +| | [theme_darkmode_toggle.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx#:~:text=toMountPoint), [theme_darkmode_toggle.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx#:~:text=toMountPoint) | - | + + + ## cloudSecurityPosture | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [overview_tab.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/overview_tab.tsx#:~:text=indexPatternId) | - | +| | [take_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/components/take_action.tsx#:~:text=toMountPoint), [take_action.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/cloud_security_posture/public/components/take_action.tsx#:~:text=toMountPoint) | - | @@ -946,6 +957,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [confirm_modal_promise.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/helpers/saved_objects_utils/confirm_modal_promise.tsx#:~:text=toMountPoint), [confirm_modal_promise.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/helpers/saved_objects_utils/confirm_modal_promise.tsx#:~:text=toMountPoint), [workspace_top_nav_menu.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/components/workspace_layout/workspace_top_nav_menu.tsx#:~:text=toMountPoint), [workspace_top_nav_menu.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/components/workspace_layout/workspace_top_nav_menu.tsx#:~:text=toMountPoint), [application.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/application.tsx#:~:text=toMountPoint), [application.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/application.tsx#:~:text=toMountPoint) | - | | | [application.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/application.tsx#:~:text=KibanaThemeProvider), [application.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/application.tsx#:~:text=KibanaThemeProvider), [application.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/application.tsx#:~:text=KibanaThemeProvider) | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/server/plugin.ts#:~:text=license%24) | 8.8.0 | +| | [source_picker.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/components/source_picker.tsx#:~:text=includeFields) | - | | | [save_modal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal), [save_modal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/components/save_modal.tsx#:~:text=SavedObjectSaveModal) | 8.8.0 | | | [app_state.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/types/app_state.ts#:~:text=SimpleSavedObject), [app_state.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/types/app_state.ts#:~:text=SimpleSavedObject), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/helpers/saved_objects_utils/find_object_by_title.test.ts#:~:text=SimpleSavedObject), [find_object_by_title.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/helpers/saved_objects_utils/find_object_by_title.test.ts#:~:text=SimpleSavedObject) | - | | | [save_with_confirmation.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/helpers/saved_objects_utils/save_with_confirmation.ts#:~:text=SavedObjectsCreateOptions), [save_with_confirmation.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/graph/public/helpers/saved_objects_utils/save_with_confirmation.ts#:~:text=SavedObjectsCreateOptions) | - | @@ -1203,7 +1215,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [index_patterns.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts#:~:text=title), [rollup.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=title), [alerting_service.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts#:~:text=title), [data_recognizer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts#:~:text=title), [configuration_step_details.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx#:~:text=title), [data_loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title)+ 40 more | - | | | [index_patterns.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts#:~:text=title), [rollup.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=title), [alerting_service.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts#:~:text=title), [data_recognizer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts#:~:text=title), [configuration_step_details.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx#:~:text=title), [data_loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title)+ 40 more | - | | | [index_patterns.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/models/data_frame_analytics/index_patterns.ts#:~:text=title), [rollup.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/models/job_service/new_job_caps/rollup.ts#:~:text=title), [alerting_service.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/lib/alerts/alerting_service.ts#:~:text=title), [data_recognizer.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/models/data_recognizer/data_recognizer.ts#:~:text=title), [configuration_step_details.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_details.tsx#:~:text=title), [data_loader.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/datavisualizer/index_based/data_loader/data_loader.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title), [use_index_data.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts#:~:text=title)+ 15 more | - | -| | [clone_action_name.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx#:~:text=toMountPoint), [clone_action_name.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx#:~:text=toMountPoint), [force_stop_dialog.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/model_management/force_stop_dialog.tsx#:~:text=toMountPoint), [force_stop_dialog.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/model_management/force_stop_dialog.tsx#:~:text=toMountPoint), [deployment_setup.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/model_management/deployment_setup.tsx#:~:text=toMountPoint), [deployment_setup.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/model_management/deployment_setup.tsx#:~:text=toMountPoint), [header_menu_portal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/components/header_menu_portal/header_menu_portal.tsx#:~:text=toMountPoint), [header_menu_portal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/components/header_menu_portal/header_menu_portal.tsx#:~:text=toMountPoint), [create_flyout.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx#:~:text=toMountPoint), [create_flyout.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx#:~:text=toMountPoint)+ 10 more | - | +| | [clone_action_name.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx#:~:text=toMountPoint), [clone_action_name.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_clone/clone_action_name.tsx#:~:text=toMountPoint), [force_stop_dialog.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/model_management/force_stop_dialog.tsx#:~:text=toMountPoint), [force_stop_dialog.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/model_management/force_stop_dialog.tsx#:~:text=toMountPoint), [deployment_setup.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/model_management/deployment_setup.tsx#:~:text=toMountPoint), [deployment_setup.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/model_management/deployment_setup.tsx#:~:text=toMountPoint), [header_menu_portal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/components/header_menu_portal/header_menu_portal.tsx#:~:text=toMountPoint), [header_menu_portal.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/components/header_menu_portal/header_menu_portal.tsx#:~:text=toMountPoint), [resolve_job_selection.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx#:~:text=toMountPoint), [resolve_job_selection.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx#:~:text=toMountPoint)+ 10 more | - | | | [jobs_list_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx#:~:text=RedirectAppLinks), [jobs_list_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx#:~:text=RedirectAppLinks), [jobs_list_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx#:~:text=RedirectAppLinks) | - | | | [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_charts_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_swimlane_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_swimlane_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx#:~:text=KibanaThemeProvider), [anomaly_swimlane_embeddable.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_embeddable.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/app.tsx#:~:text=KibanaThemeProvider), [app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/app.tsx#:~:text=KibanaThemeProvider), [jobs_list_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/application/management/jobs_list/components/jobs_list_page/jobs_list_page.tsx#:~:text=KibanaThemeProvider)+ 2 more | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/plugin.ts#:~:text=license%24) | 8.8.0 | @@ -1257,6 +1269,14 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] +## observabilityAIAssistant + +| Deprecated API | Reference location(s) | Remove By | +| ---------------|-----------|-----------| +| | [application.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_ai_assistant/public/application.tsx#:~:text=KibanaThemeProvider), [application.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_ai_assistant/public/application.tsx#:~:text=KibanaThemeProvider), [application.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/observability_ai_assistant/public/application.tsx#:~:text=KibanaThemeProvider) | - | + + + ## observabilityOnboarding | Deprecated API | Reference location(s) | Remove By | @@ -1462,7 +1482,7 @@ This is relied on by the reporting feature, and should be removed once reporting migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/issues/19914 | | | [app_authorization.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/app_authorization.ts#:~:text=getKibanaFeatures), [privileges.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/privileges/privileges.ts#:~:text=getKibanaFeatures), [authorization_service.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/authorization_service.tsx#:~:text=getKibanaFeatures), [app_authorization.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/app_authorization.test.ts#:~:text=getKibanaFeatures), [privileges.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts#:~:text=getKibanaFeatures), [privileges.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts#:~:text=getKibanaFeatures), [privileges.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts#:~:text=getKibanaFeatures), [privileges.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts#:~:text=getKibanaFeatures), [privileges.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts#:~:text=getKibanaFeatures), [privileges.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/privileges/privileges.test.ts#:~:text=getKibanaFeatures)+ 15 more | 8.8.0 | | | [authorization_service.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/server/authorization/authorization_service.tsx#:~:text=getElasticsearchFeatures) | 8.8.0 | -| | [use_update_user_profile.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx#:~:text=toMountPoint), [use_update_user_profile.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx#:~:text=toMountPoint), [session_expiration_toast.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/session/session_expiration_toast.tsx#:~:text=toMountPoint), [session_expiration_toast.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/session/session_expiration_toast.tsx#:~:text=toMountPoint) | - | +| | [account_management_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/account_management/account_management_app.tsx#:~:text=toMountPoint), [account_management_app.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/account_management/account_management_app.tsx#:~:text=toMountPoint), [session_expiration_toast.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/session/session_expiration_toast.tsx#:~:text=toMountPoint), [session_expiration_toast.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/session/session_expiration_toast.tsx#:~:text=toMountPoint) | - | | | [access_agreement_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.tsx#:~:text=KibanaThemeProvider), [access_agreement_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.tsx#:~:text=KibanaThemeProvider), [access_agreement_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.tsx#:~:text=KibanaThemeProvider), [logged_out_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/logged_out/logged_out_page.tsx#:~:text=KibanaThemeProvider), [logged_out_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/logged_out/logged_out_page.tsx#:~:text=KibanaThemeProvider), [logged_out_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/logged_out/logged_out_page.tsx#:~:text=KibanaThemeProvider), [login_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/login/login_page.tsx#:~:text=KibanaThemeProvider), [login_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/login/login_page.tsx#:~:text=KibanaThemeProvider), [login_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/login/login_page.tsx#:~:text=KibanaThemeProvider), [overwritten_session_page.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/authentication/overwritten_session/overwritten_session_page.tsx#:~:text=KibanaThemeProvider)+ 20 more | - | | | [license_service.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/common/licensing/license_service.test.ts#:~:text=mode), [license_service.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/common/licensing/license_service.test.ts#:~:text=mode), [license_service.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/common/licensing/license_service.test.ts#:~:text=mode) | 8.8.0 | | | [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/security/public/plugin.tsx#:~:text=license%24) | 8.8.0 | @@ -1818,6 +1838,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | ---------------|-----------|-----------| | | [confirm_modal_promise.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/utils/saved_objects_utils/confirm_modal_promise.tsx#:~:text=toMountPoint), [confirm_modal_promise.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/utils/saved_objects_utils/confirm_modal_promise.tsx#:~:text=toMountPoint), [use_visualize_app_state.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/utils/use/use_visualize_app_state.tsx#:~:text=toMountPoint), [use_visualize_app_state.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/utils/use/use_visualize_app_state.tsx#:~:text=toMountPoint), [visualize_no_match.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/components/visualize_no_match.tsx#:~:text=toMountPoint), [visualize_no_match.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/components/visualize_no_match.tsx#:~:text=toMountPoint), [index.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=toMountPoint), [index.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/index.tsx#:~:text=toMountPoint) | - | | | [use_visualize_app_state.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/utils/use/use_visualize_app_state.tsx#:~:text=KibanaThemeProvider), [use_visualize_app_state.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/utils/use/use_visualize_app_state.tsx#:~:text=KibanaThemeProvider), [use_visualize_app_state.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/utils/use/use_visualize_app_state.tsx#:~:text=KibanaThemeProvider), [visualize_embeddable.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx#:~:text=KibanaThemeProvider), [visualize_embeddable.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx#:~:text=KibanaThemeProvider), [visualize_embeddable.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx#:~:text=KibanaThemeProvider), [show_new_vis.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/wizard/show_new_vis.tsx#:~:text=KibanaThemeProvider), [show_new_vis.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/wizard/show_new_vis.tsx#:~:text=KibanaThemeProvider), [show_new_vis.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/wizard/show_new_vis.tsx#:~:text=KibanaThemeProvider), [visualize_no_match.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/components/visualize_no_match.tsx#:~:text=KibanaThemeProvider)+ 5 more | - | +| | [search_selection.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/wizard/search_selection/search_selection.tsx#:~:text=includeFields), [visualize_embeddable_factory.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx#:~:text=includeFields) | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/plugin.ts#:~:text=savedObjects), [visualize_listing.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx#:~:text=savedObjects) | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/plugin.ts#:~:text=SavedObjectsClientContract), [plugin.ts](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/plugin.ts#:~:text=SavedObjectsClientContract) | - | | | [visualize_listing.tsx](https://github.com/elastic/kibana/tree/main/src/plugins/visualizations/public/visualize_app/components/visualize_listing.tsx#:~:text=delete) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 585d6b75de9aa..dd54d80679b38 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -120,7 +120,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Plugin | Deprecated API | Reference location(s) | Remove By | | --------|-------|-----------|-----------| -| ml | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/plugin.ts#:~:text=license%24) | 8.8.0 | +| ml | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/public/plugin.ts#:~:text=license%24), [plugin.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/aiops/public/plugin.tsx#:~:text=license%24) | 8.8.0 | | ml | | [plugin.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/ml/server/plugin.ts#:~:text=license%24), [license.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/transform/server/services/license.ts#:~:text=license%24) | 8.8.0 | diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 8a8540fc1360f..59884cb7a6a03 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 2bd1d80e8a7b2..9a15eabe616c8 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index bd072de583e44..2830cab0b59d7 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 7cf7dd6fd5681..7fd44fac756db 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.devdocs.json b/api_docs/embeddable.devdocs.json index cbb78b0f3defe..be7678ec89f33 100644 --- a/api_docs/embeddable.devdocs.json +++ b/api_docs/embeddable.devdocs.json @@ -7589,6 +7589,26 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "embeddable", + "id": "def-public.EmbeddableStartDependencies.contentManagement", + "type": "Object", + "tags": [], + "label": "contentManagement", + "description": [], + "signature": [ + { + "pluginId": "contentManagement", + "scope": "public", + "docId": "kibContentManagementPluginApi", + "section": "def-public.ContentManagementPublicStart", + "text": "ContentManagementPublicStart" + } + ], + "path": "src/plugins/embeddable/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "embeddable", "id": "def-public.EmbeddableStartDependencies.savedObjectsManagement", @@ -9155,7 +9175,15 @@ "section": "def-common.Datatable", "text": "Datatable" }, - ", \"rows\" | \"columns\">; column: number; value: any[]; }; timeFieldName?: string | undefined; negate?: boolean | undefined; }" + ", \"rows\" | \"columns\">; cells: { column: number; row: number; }[]; relation?: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.BooleanRelation", + "text": "BooleanRelation" + }, + " | undefined; }[]; timeFieldName?: string | undefined; negate?: boolean | undefined; }" ], "path": "src/plugins/embeddable/public/lib/triggers/triggers.ts", "deprecated": false, diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 5ca2ab1573fa9..59a2a6facb00c 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kib | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 535 | 11 | 437 | 7 | +| 536 | 11 | 438 | 7 | ## Client diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 9ec369a20e907..62400f8bfb19e 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index fd78a0506ea65..5c703ad47f6a6 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 142741b6ca029..b5b66595a7733 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index f72c796652692..2b22c7c3fdbc9 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.devdocs.json b/api_docs/event_annotation.devdocs.json index e61c8b977dd39..c6ce5b7227966 100644 --- a/api_docs/event_annotation.devdocs.json +++ b/api_docs/event_annotation.devdocs.json @@ -461,7 +461,15 @@ "section": "def-common.SavedObjectCommon", "text": "SavedObjectCommon" }, - "; }) => void; onCreateNew: () => void; }) => JSX.Element" + "<", + { + "pluginId": "savedObjectsFinder", + "scope": "common", + "docId": "kibSavedObjectsFinderPluginApi", + "section": "def-common.FinderAttributes", + "text": "FinderAttributes" + }, + ">; }) => void; onCreateNew: () => void; }) => JSX.Element" ], "path": "packages/kbn-event-annotation-components/types.ts", "deprecated": false, @@ -508,7 +516,15 @@ "section": "def-common.SavedObjectCommon", "text": "SavedObjectCommon" }, - "; }) => void" + "<", + { + "pluginId": "savedObjectsFinder", + "scope": "common", + "docId": "kibSavedObjectsFinderPluginApi", + "section": "def-common.FinderAttributes", + "text": "FinderAttributes" + }, + ">; }) => void" ], "path": "packages/kbn-event-annotation-components/types.ts", "deprecated": false, @@ -567,13 +583,21 @@ "description": [], "signature": [ { - "pluginId": "@kbn/core-saved-objects-common", + "pluginId": "@kbn/content-management-utils", "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" + "docId": "kibKbnContentManagementUtilsPluginApi", + "section": "def-common.SOWithMetadata", + "text": "SOWithMetadata" }, - "" + "<", + { + "pluginId": "savedObjectsFinder", + "scope": "common", + "docId": "kibSavedObjectsFinderPluginApi", + "section": "def-common.FinderAttributes", + "text": "FinderAttributes" + }, + ">" ], "path": "packages/kbn-event-annotation-components/types.ts", "deprecated": false, @@ -694,27 +718,6 @@ "deprecated": false, "trackAdoption": false, "isRequired": true - }, - { - "parentPluginId": "eventAnnotation", - "id": "def-public.EventAnnotationService.Unnamed.$3", - "type": "Object", - "tags": [], - "label": "savedObjectsManagement", - "description": [], - "signature": [ - { - "pluginId": "savedObjectsManagement", - "scope": "public", - "docId": "kibSavedObjectsManagementPluginApi", - "section": "def-public.SavedObjectsManagementPluginStart", - "text": "SavedObjectsManagementPluginStart" - } - ], - "path": "src/plugins/event_annotation/public/event_annotation_service/index.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true } ], "returnComment": [] diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index f50f62c4a8927..f65e74fe1426a 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 192 | 30 | 192 | 2 | +| 191 | 30 | 191 | 2 | ## Client diff --git a/api_docs/event_log.devdocs.json b/api_docs/event_log.devdocs.json index 6c4dd5d9e564e..c656ca3ece0e6 100644 --- a/api_docs/event_log.devdocs.json +++ b/api_docs/event_log.devdocs.json @@ -143,85 +143,6 @@ ], "returnComment": [] }, - { - "parentPluginId": "eventLog", - "id": "def-server.ClusterClientAdapter.doesIlmPolicyExist", - "type": "Function", - "tags": [], - "label": "doesIlmPolicyExist", - "description": [], - "signature": [ - "(policyName: string) => Promise" - ], - "path": "x-pack/plugins/event_log/server/es/cluster_client_adapter.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "eventLog", - "id": "def-server.ClusterClientAdapter.doesIlmPolicyExist.$1", - "type": "string", - "tags": [], - "label": "policyName", - "description": [], - "signature": [ - "string" - ], - "path": "x-pack/plugins/event_log/server/es/cluster_client_adapter.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, - { - "parentPluginId": "eventLog", - "id": "def-server.ClusterClientAdapter.createIlmPolicy", - "type": "Function", - "tags": [], - "label": "createIlmPolicy", - "description": [], - "signature": [ - "(policyName: string, policy: Record) => Promise" - ], - "path": "x-pack/plugins/event_log/server/es/cluster_client_adapter.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "eventLog", - "id": "def-server.ClusterClientAdapter.createIlmPolicy.$1", - "type": "string", - "tags": [], - "label": "policyName", - "description": [], - "signature": [ - "string" - ], - "path": "x-pack/plugins/event_log/server/es/cluster_client_adapter.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "eventLog", - "id": "def-server.ClusterClientAdapter.createIlmPolicy.$2", - "type": "Object", - "tags": [], - "label": "policy", - "description": [], - "signature": [ - "Record" - ], - "path": "x-pack/plugins/event_log/server/es/cluster_client_adapter.ts", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] - }, { "parentPluginId": "eventLog", "id": "def-server.ClusterClientAdapter.doesIndexTemplateExist", diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index e89fac58a2876..e1da7f64405f8 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 116 | 0 | 116 | 11 | +| 111 | 0 | 111 | 11 | ## Server diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index 935ec02b807e9..42857923c0755 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index e2041edf19373..fdc2f7061181e 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 7939c2f3076e7..c8c6008a375a5 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.devdocs.json b/api_docs/expression_heatmap.devdocs.json index 91fc345d8f6c3..e9ebf4fcbc4fe 100644 --- a/api_docs/expression_heatmap.devdocs.json +++ b/api_docs/expression_heatmap.devdocs.json @@ -897,7 +897,23 @@ "section": "def-common.Datatable", "text": "Datatable" }, - "; column: number; range: number[]; timeFieldName?: string | undefined; }) => void; paletteService: ", + "; column: number; range: number[]; timeFieldName?: string | undefined; }) => void; onClickMultiValue: (data: { data: { table: Pick<", + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.Datatable", + "text": "Datatable" + }, + ", \"rows\" | \"columns\">; cells: { column: number; row: number; }[]; relation?: ", + { + "pluginId": "@kbn/es-query", + "scope": "common", + "docId": "kibKbnEsQueryPluginApi", + "section": "def-common.BooleanRelation", + "text": "BooleanRelation" + }, + " | undefined; }[]; timeFieldName?: string | undefined; negate?: boolean | undefined; }) => void; paletteService: ", { "pluginId": "@kbn/coloring", "scope": "common", diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index c6cf3ed57d316..a16712c92ffe7 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index cd90df87cb30a..c99cc4f7ffa55 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 40193204df51f..b83b37db8b594 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 8456e45c43aa7..ef651f20382d1 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 6e1c7fff5b9cb..3ce0102964ccd 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 40c1ec352d684..391ae05dfda30 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index fdfc5024941dc..d7c9f4b7c3d4d 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index f12b98a3ef638..ad4e5aae94dfd 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index 0b38793ebf1d1..4e6acabab2e13 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index fdd5a6e7434a1..954f34351c103 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index 13291fe251db6..3d3a703604593 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 46144bdd70a71..2cfb8da03bab3 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index c84e5990a374f..87032206bd767 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index d0a6e1861cdcb..eb519823e0afd 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 4ad74f547420c..2f98ac1236833 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.devdocs.json b/api_docs/files.devdocs.json index c6085d88884ac..e361a3c2a6336 100644 --- a/api_docs/files.devdocs.json +++ b/api_docs/files.devdocs.json @@ -577,6 +577,14 @@ "plugin": "cases", "path": "x-pack/plugins/cases/public/plugin.ts" }, + { + "plugin": "cases", + "path": "x-pack/plugins/cases/public/plugin.test.ts" + }, + { + "plugin": "cases", + "path": "x-pack/plugins/cases/public/plugin.test.ts" + }, { "plugin": "imageEmbeddable", "path": "src/plugins/image_embeddable/public/plugin.ts" @@ -5458,6 +5466,10 @@ { "plugin": "cases", "path": "x-pack/plugins/cases/server/client/factory.ts" + }, + { + "plugin": "cases", + "path": "x-pack/plugins/cases/server/plugin.test.ts" } ] } diff --git a/api_docs/files.mdx b/api_docs/files.mdx index 459bc877566b3..fc314b289752a 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index d7b28cd1617f8..6aa91c16d3b1e 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index a5600ae945a8e..10d05a3e19944 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 1bb35a9da4b34..3ecfb4969ccc2 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 649eab3e58dab..7a5a09f7ae7f4 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 37986e0e5531e..f354f40dab1a1 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index 84f6acf3fc8e9..33c414a76476c 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index bbac09985808e..30d558400d2a5 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 39520e4f5fd12..6f1bd38953fe1 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index 43b6b1f6d5fec..55b6de533eb18 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index f8fb7c62396c0..d48e479972b6c 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index f24b897b682f1..7efd702cfa51e 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 66b909ccff85d..e941d12298554 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.devdocs.json b/api_docs/kbn_aiops_components.devdocs.json index 1b99ef4188fb6..702a63d266bef 100644 --- a/api_docs/kbn_aiops_components.devdocs.json +++ b/api_docs/kbn_aiops_components.devdocs.json @@ -23,15 +23,13 @@ "parentPluginId": "@kbn/aiops-components", "id": "def-common.DocumentCountChart", "type": "Function", - "tags": [ - "constructor" - ], + "tags": [], "label": "DocumentCountChart", "description": [ - "\nDocument count chart with draggable brushes to select time ranges\nby default use `Baseline` and `Deviation` for the badge names" + "\nDocument count chart with draggable brushes to select time ranges\nby default use `Baseline` and `Deviation` for the badge names\n" ], "signature": [ - "({ dependencies, brushSelectionUpdateHandler, width, chartPoints, chartPointsSplit, timeRangeEarliest, timeRangeLatest, interval, chartPointsSplitLabel, isBrushCleared, autoAnalysisStart, barColorOverride, barStyleAccessor, barHighlightColorOverride, deviationBrush, baselineBrush, }: React.PropsWithChildren<", + "(props: React.PropsWithChildren<", { "pluginId": "@kbn/aiops-components", "scope": "common", @@ -50,8 +48,10 @@ "id": "def-common.DocumentCountChart.$1", "type": "CompoundType", "tags": [], - "label": "{\n dependencies,\n brushSelectionUpdateHandler,\n width,\n chartPoints,\n chartPointsSplit,\n timeRangeEarliest,\n timeRangeLatest,\n interval,\n chartPointsSplitLabel,\n isBrushCleared,\n autoAnalysisStart,\n barColorOverride,\n barStyleAccessor,\n barHighlightColorOverride,\n deviationBrush = {},\n baselineBrush = {},\n}", - "description": [], + "label": "props", + "description": [ + "DocumentCountChart component props" + ], "signature": [ "React.PropsWithChildren<", { @@ -69,22 +69,22 @@ "isRequired": true } ], - "returnComment": [], + "returnComment": [ + "The DocumentCountChart component." + ], "initialIsOpen": false }, { "parentPluginId": "@kbn/aiops-components", "id": "def-common.DualBrush", "type": "Function", - "tags": [ - "type" - ], + "tags": [], "label": "DualBrush", "description": [ - "\nDualBrush React Component\nDual brush component that overlays the document count chart" + "\nDualBrush React Component\nDual brush component that overlays the document count chart\n" ], "signature": [ - "({\n /**\n * Min and max numeric timestamps for the two brushes\n */\n windowParameters,\n /**\n * Min timestamp for x domain\n */\n min,\n /**\n * Max timestamp for x domain\n */\n max,\n /**\n * Callback function whenever the brush changes\n */\n onChange,\n /**\n * Margin left\n */\n marginLeft,\n /**\n * Nearest timestamps to snap to the brushes to\n */\n snapTimestamps,\n /**\n * Width\n */\n width,\n}: DualBrushProps) => JSX.Element" + "(props: React.PropsWithChildren) => JSX.Element" ], "path": "x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx", "deprecated": false, @@ -93,12 +93,14 @@ { "parentPluginId": "@kbn/aiops-components", "id": "def-common.DualBrush.$1", - "type": "Object", + "type": "CompoundType", "tags": [], - "label": "{\n /**\n * Min and max numeric timestamps for the two brushes\n */\n windowParameters,\n /**\n * Min timestamp for x domain\n */\n min,\n /**\n * Max timestamp for x domain\n */\n max,\n /**\n * Callback function whenever the brush changes\n */\n onChange,\n /**\n * Margin left\n */\n marginLeft,\n /**\n * Nearest timestamps to snap to the brushes to\n */\n snapTimestamps,\n /**\n * Width\n */\n width,\n}", - "description": [], + "label": "props", + "description": [ + "DualBrushProps component props" + ], "signature": [ - "DualBrushProps" + "React.PropsWithChildren" ], "path": "x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush.tsx", "deprecated": false, @@ -115,15 +117,13 @@ "parentPluginId": "@kbn/aiops-components", "id": "def-common.DualBrushAnnotation", "type": "Function", - "tags": [ - "type" - ], + "tags": [], "label": "DualBrushAnnotation", "description": [ - "\nDualBrushAnnotation React Component\nDual brush annotation component that overlays the document count chart" + "\nDualBrushAnnotation React Component\nDual brush annotation component that overlays the document count chart\n" ], "signature": [ - "({ id, min, max, style }: React.PropsWithChildren) => JSX.Element" + "(props: React.PropsWithChildren) => JSX.Element" ], "path": "x-pack/packages/ml/aiops_components/src/dual_brush/dual_brush_annotation.tsx", "deprecated": false, @@ -134,8 +134,10 @@ "id": "def-common.DualBrushAnnotation.$1", "type": "CompoundType", "tags": [], - "label": "{ id, min, max, style }", - "description": [], + "label": "props", + "description": [ + "BrushAnnotationProps component props" + ], "signature": [ "React.PropsWithChildren" ], @@ -154,15 +156,13 @@ "parentPluginId": "@kbn/aiops-components", "id": "def-common.ProgressControls", "type": "Function", - "tags": [ - "type" - ], + "tags": [], "label": "ProgressControls", "description": [ - "\nProgressControls React Component\nComponent with ability to Run & cancel analysis\nby default use `Baseline` and `Deviation` for the badge name" + "\nProgressControls React Component\nComponent with ability to Run & cancel analysis\nby default uses `Baseline` and `Deviation` for the badge name\n" ], "signature": [ - "({ children, isBrushCleared, progress, progressMessage, onRefresh, onCancel, onReset, isRunning, shouldRerunAnalysis, runAnalysisDisabled, }: React.PropsWithChildren) => JSX.Element" + "(props: React.PropsWithChildren) => JSX.Element" ], "path": "x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx", "deprecated": false, @@ -173,8 +173,10 @@ "id": "def-common.ProgressControls.$1", "type": "CompoundType", "tags": [], - "label": "{\n children,\n isBrushCleared,\n progress,\n progressMessage,\n onRefresh,\n onCancel,\n onReset,\n isRunning,\n shouldRerunAnalysis,\n runAnalysisDisabled = false,\n}", - "description": [], + "label": "props", + "description": [ + "ProgressControls component props" + ], "signature": [ "React.PropsWithChildren" ], @@ -193,12 +195,12 @@ "interfaces": [ { "parentPluginId": "@kbn/aiops-components", - "id": "def-common.DocumentCountChartPoint", + "id": "def-common.BrushSettings", "type": "Interface", "tags": [], - "label": "DocumentCountChartPoint", + "label": "BrushSettings", "description": [ - "\nDatum for the bar chart" + "\nBrush settings" ], "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", "deprecated": false, @@ -206,15 +208,34 @@ "children": [ { "parentPluginId": "@kbn/aiops-components", - "id": "def-common.DocumentCountChartPoint.time", - "type": "CompoundType", + "id": "def-common.BrushSettings.label", + "type": "string", + "tags": [], + "label": "label", + "description": [ + "\nOptional label name for brush" + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/aiops-components", + "id": "def-common.BrushSettings.annotationStyle", + "type": "Object", "tags": [], - "label": "time", + "label": "annotationStyle", "description": [ - "\nTime of bucket" + "\nOptional style for brush" ], "signature": [ - "string | number" + "RecursivePartial", + "<", + "RectAnnotationStyle", + "> | undefined" ], "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", "deprecated": false, @@ -222,12 +243,15 @@ }, { "parentPluginId": "@kbn/aiops-components", - "id": "def-common.DocumentCountChartPoint.value", + "id": "def-common.BrushSettings.badgeWidth", "type": "number", "tags": [], - "label": "value", + "label": "badgeWidth", "description": [ - "\nNumber of doc count for that time bucket" + "\nOptional width for brush" + ], + "signature": [ + "number | undefined" ], "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", "deprecated": false, @@ -304,61 +328,21 @@ "tags": [], "label": "brushSelectionUpdateHandler", "description": [ - "Optional callback function which gets called the brush selection has changed" + "Optional callback for handling brush selection updates" ], "signature": [ - "((windowParameters: ", { - "pluginId": "@kbn/aiops-utils", + "pluginId": "@kbn/aiops-components", "scope": "common", - "docId": "kibKbnAiopsUtilsPluginApi", - "section": "def-common.WindowParameters", - "text": "WindowParameters" + "docId": "kibKbnAiopsComponentsPluginApi", + "section": "def-common.BrushSelectionUpdateHandler", + "text": "BrushSelectionUpdateHandler" }, - ", force: boolean) => void) | undefined" + " | undefined" ], "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "@kbn/aiops-components", - "id": "def-common.DocumentCountChartProps.brushSelectionUpdateHandler.$1", - "type": "Object", - "tags": [], - "label": "windowParameters", - "description": [], - "signature": [ - { - "pluginId": "@kbn/aiops-utils", - "scope": "common", - "docId": "kibKbnAiopsUtilsPluginApi", - "section": "def-common.WindowParameters", - "text": "WindowParameters" - } - ], - "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "@kbn/aiops-components", - "id": "def-common.DocumentCountChartProps.brushSelectionUpdateHandler.$2", - "type": "boolean", - "tags": [], - "label": "force", - "description": [], - "signature": [ - "boolean" - ], - "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - } - ], - "returnComment": [] + "trackAdoption": false }, { "parentPluginId": "@kbn/aiops-components", @@ -387,11 +371,11 @@ ], "signature": [ { - "pluginId": "@kbn/aiops-components", + "pluginId": "@kbn/aiops-utils", "scope": "common", - "docId": "kibKbnAiopsComponentsPluginApi", - "section": "def-common.DocumentCountChartPoint", - "text": "DocumentCountChartPoint" + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.LogRateHistogramItem", + "text": "LogRateHistogramItem" }, "[]" ], @@ -410,11 +394,11 @@ ], "signature": [ { - "pluginId": "@kbn/aiops-components", + "pluginId": "@kbn/aiops-utils", "scope": "common", - "docId": "kibKbnAiopsComponentsPluginApi", - "section": "def-common.DocumentCountChartPoint", - "text": "DocumentCountChartPoint" + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.LogRateHistogramItem", + "text": "LogRateHistogramItem" }, "[] | undefined" ], @@ -570,7 +554,13 @@ "Optional settings override for the 'deviation' brush" ], "signature": [ - "BrushSettings", + { + "pluginId": "@kbn/aiops-components", + "scope": "common", + "docId": "kibKbnAiopsComponentsPluginApi", + "section": "def-common.BrushSettings", + "text": "BrushSettings" + }, " | undefined" ], "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", @@ -587,7 +577,13 @@ "Optional settings override for the 'baseline' brush" ], "signature": [ - "BrushSettings", + { + "pluginId": "@kbn/aiops-components", + "scope": "common", + "docId": "kibKbnAiopsComponentsPluginApi", + "section": "def-common.BrushSettings", + "text": "BrushSettings" + }, " | undefined" ], "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", @@ -599,7 +595,95 @@ } ], "enums": [], - "misc": [], + "misc": [ + { + "parentPluginId": "@kbn/aiops-components", + "id": "def-common.BrushSelectionUpdateHandler", + "type": "Type", + "tags": [], + "label": "BrushSelectionUpdateHandler", + "description": [ + "\nCallback function which gets called when the brush selection has changed\n" + ], + "signature": [ + "(windowParameters: ", + { + "pluginId": "@kbn/aiops-utils", + "scope": "common", + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.WindowParameters", + "text": "WindowParameters" + }, + ", force: boolean, logRateAnalysisType: ", + { + "pluginId": "@kbn/aiops-utils", + "scope": "common", + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.LogRateAnalysisType", + "text": "LogRateAnalysisType" + }, + ") => void" + ], + "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/aiops-components", + "id": "def-common.BrushSelectionUpdateHandler.$1", + "type": "Object", + "tags": [], + "label": "windowParameters", + "description": [ + "Baseline and deviation time ranges." + ], + "signature": [ + { + "pluginId": "@kbn/aiops-utils", + "scope": "common", + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.WindowParameters", + "text": "WindowParameters" + } + ], + "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/aiops-components", + "id": "def-common.BrushSelectionUpdateHandler.$2", + "type": "boolean", + "tags": [], + "label": "force", + "description": [ + "Force update" + ], + "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/aiops-components", + "id": "def-common.BrushSelectionUpdateHandler.$3", + "type": "CompoundType", + "tags": [], + "label": "logRateAnalysisType", + "description": [ + "`spike` or `dip` based on median log rate bucket size" + ], + "signature": [ + "\"spike\" | \"dip\"" + ], + "path": "x-pack/packages/ml/aiops_components/src/document_count_chart/document_count_chart.tsx", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + } + ], "objects": [] } } \ No newline at end of file diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index e4e3eed672b02..77111d5895f85 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 30 | 0 | 6 | 1 | +| 33 | 0 | 0 | 0 | ## Common @@ -31,3 +31,6 @@ Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questi ### Interfaces +### Consts, variables and types + + diff --git a/api_docs/kbn_aiops_utils.devdocs.json b/api_docs/kbn_aiops_utils.devdocs.json index c84540e90ecf6..4ab34fcaf1db4 100644 --- a/api_docs/kbn_aiops_utils.devdocs.json +++ b/api_docs/kbn_aiops_utils.devdocs.json @@ -19,6 +19,98 @@ "common": { "classes": [], "functions": [ + { + "parentPluginId": "@kbn/aiops-utils", + "id": "def-common.getLogRateAnalysisType", + "type": "Function", + "tags": [], + "label": "getLogRateAnalysisType", + "description": [ + "\nIdentify the log rate analysis type based on the baseline/deviation\ntime ranges on a given log rate histogram.\n" + ], + "signature": [ + "(logRateHistogram: ", + { + "pluginId": "@kbn/aiops-utils", + "scope": "common", + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.LogRateHistogramItem", + "text": "LogRateHistogramItem" + }, + "[], windowParameters: ", + { + "pluginId": "@kbn/aiops-utils", + "scope": "common", + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.WindowParameters", + "text": "WindowParameters" + }, + ") => ", + { + "pluginId": "@kbn/aiops-utils", + "scope": "common", + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.LogRateAnalysisType", + "text": "LogRateAnalysisType" + } + ], + "path": "x-pack/packages/ml/aiops_utils/get_log_rate_analysis_type.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/aiops-utils", + "id": "def-common.getLogRateAnalysisType.$1", + "type": "Array", + "tags": [], + "label": "logRateHistogram", + "description": [ + "The log rate histogram." + ], + "signature": [ + { + "pluginId": "@kbn/aiops-utils", + "scope": "common", + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.LogRateHistogramItem", + "text": "LogRateHistogramItem" + }, + "[]" + ], + "path": "x-pack/packages/ml/aiops_utils/get_log_rate_analysis_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/aiops-utils", + "id": "def-common.getLogRateAnalysisType.$2", + "type": "Object", + "tags": [], + "label": "windowParameters", + "description": [ + "The window parameters with baseline and deviation time range." + ], + "signature": [ + { + "pluginId": "@kbn/aiops-utils", + "scope": "common", + "docId": "kibKbnAiopsUtilsPluginApi", + "section": "def-common.WindowParameters", + "text": "WindowParameters" + } + ], + "path": "x-pack/packages/ml/aiops_utils/get_log_rate_analysis_type.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [ + "The log rate analysis type." + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/aiops-utils", "id": "def-common.getSnappedWindowParameters", @@ -46,7 +138,7 @@ "text": "WindowParameters" } ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -68,7 +160,7 @@ "text": "WindowParameters" } ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -85,7 +177,7 @@ "signature": [ "number[]" ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -115,7 +207,7 @@ "text": "WindowParameters" } ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -131,7 +223,7 @@ "signature": [ "number" ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -148,7 +240,7 @@ "signature": [ "number" ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -165,7 +257,7 @@ "signature": [ "number" ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false, "isRequired": true @@ -178,6 +270,51 @@ } ], "interfaces": [ + { + "parentPluginId": "@kbn/aiops-utils", + "id": "def-common.LogRateHistogramItem", + "type": "Interface", + "tags": [], + "label": "LogRateHistogramItem", + "description": [ + "\nLog rate histogram item" + ], + "path": "x-pack/packages/ml/aiops_utils/log_rate_histogram_item.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/aiops-utils", + "id": "def-common.LogRateHistogramItem.time", + "type": "CompoundType", + "tags": [], + "label": "time", + "description": [ + "\nTime of bucket" + ], + "signature": [ + "string | number" + ], + "path": "x-pack/packages/ml/aiops_utils/log_rate_histogram_item.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/aiops-utils", + "id": "def-common.LogRateHistogramItem.value", + "type": "number", + "tags": [], + "label": "value", + "description": [ + "\nNumber of doc count for that time bucket" + ], + "path": "x-pack/packages/ml/aiops_utils/log_rate_histogram_item.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/aiops-utils", "id": "def-common.WindowParameters", @@ -191,7 +328,7 @@ "description": [ "\nTime range definition for baseline and deviation to be used by log rate analysis.\n" ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -206,7 +343,7 @@ "description": [ "\nBaseline minimum value" ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false }, @@ -221,7 +358,7 @@ "description": [ "\nBaseline maximum value" ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false }, @@ -236,7 +373,7 @@ "description": [ "\nDeviation minimum value" ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false }, @@ -251,7 +388,7 @@ "description": [ "\nDeviation maximum value" ], - "path": "x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts", + "path": "x-pack/packages/ml/aiops_utils/window_parameters.ts", "deprecated": false, "trackAdoption": false } @@ -260,7 +397,43 @@ } ], "enums": [], - "misc": [], - "objects": [] + "misc": [ + { + "parentPluginId": "@kbn/aiops-utils", + "id": "def-common.LogRateAnalysisType", + "type": "Type", + "tags": [], + "label": "LogRateAnalysisType", + "description": [ + "\nUnion type of log rate analysis types." + ], + "signature": [ + "\"spike\" | \"dip\"" + ], + "path": "x-pack/packages/ml/aiops_utils/log_rate_analysis_type.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ], + "objects": [ + { + "parentPluginId": "@kbn/aiops-utils", + "id": "def-common.LOG_RATE_ANALYSIS_TYPE", + "type": "Object", + "tags": [], + "label": "LOG_RATE_ANALYSIS_TYPE", + "description": [ + "\nThe type of log rate analysis (spike or dip) will affect how parameters are\npassed to the analysis API endpoint." + ], + "signature": [ + "{ readonly SPIKE: \"spike\"; readonly DIP: \"dip\"; }" + ], + "path": "x-pack/packages/ml/aiops_utils/log_rate_analysis_type.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + } + ] } } \ No newline at end of file diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 8ab1310b76c47..5abc5d88e118c 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; @@ -21,13 +21,19 @@ Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 12 | 0 | 0 | 0 | +| 20 | 0 | 0 | 0 | ## Common +### Objects + + ### Functions ### Interfaces +### Consts, variables and types + + diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 748be1e48ebf4..418e8b1ba5cbf 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index c7101ea8fa22b..1a2bfdb84ca88 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index d3929a4dea717..6d7a5d4431245 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index f3bf145144bb5..0696cb1f1333a 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.devdocs.json b/api_docs/kbn_analytics_client.devdocs.json index 88e2702e0c82f..1af5ff6be1368 100644 --- a/api_docs/kbn_analytics_client.devdocs.json +++ b/api_docs/kbn_analytics_client.devdocs.json @@ -1316,14 +1316,14 @@ "plugin": "cloud", "path": "x-pack/plugins/cloud/common/register_cloud_deployment_id_analytics_context.ts" }, - { - "plugin": "telemetry", - "path": "src/plugins/telemetry/server/plugin.ts" - }, { "plugin": "security", "path": "x-pack/plugins/security/public/analytics/register_user_context.ts" }, + { + "plugin": "telemetry", + "path": "src/plugins/telemetry/server/plugin.ts" + }, { "plugin": "telemetry", "path": "src/plugins/telemetry/public/plugin.ts" diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 0dec0bae902c6..32f4324c0b45f 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index ad3639f903acd..a338b46b94f30 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 579d8f9c06d06..1421c801f0f97 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index ea346f0f543ae..ad83c7e663383 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 32ea46da84ad8..1d88dbb364a46 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index 534625a620b5a..5f1c1de0ad4cc 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 19b3c53dc1fa6..12df92a5bdf59 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 9082cac1d53cf..38658ba9378bf 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 0793199486530..e2a9b389ca3cd 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 35fd8b188e4bb..c91252fd33610 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index 8796a2577f2e8..a022b36191609 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 60115e5095ec3..5c3a636ae44af 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index f1ea4d738f4e6..3766d6c35e77e 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index 965afdd0dd7b4..c5ea02975d07e 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index e23a54e6cfde5..dd478068217b3 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index bcdaad75b0888..88633fead7a31 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index c9afcf2d42fe4..da44070bf0374 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 3db876a7ee320..ba30db316a708 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index f05ae46a3609a..0db9769db14d3 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 8bf30ebb4b9d0..65373570a0e98 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index b8bf6bc9537dd..db828f46c981b 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 33fd7a4d6418b..fb50d2bb20a3f 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index b74fada882cdd..5c12a2fc8086f 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 3524e6e8d82aa..df5e89ed1a7ce 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 71e8e4fea5a34..33ec97ec50893 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index 3db5874410372..44f11f4a4dda3 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index 74fe7e277a2ec..e68db52cba0d5 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index 0a393870c35cf..cd03b964fe93e 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index 2560ce1238725..08e9fe08765a3 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.devdocs.json b/api_docs/kbn_content_management_utils.devdocs.json index e58246c889b47..871287406cc8f 100644 --- a/api_docs/kbn_content_management_utils.devdocs.json +++ b/api_docs/kbn_content_management_utils.devdocs.json @@ -74,7 +74,7 @@ "id": "def-common.SOContentStorage.Unnamed.$1", "type": "Object", "tags": [], - "label": "{\n savedObjectType,\n cmServicesDefinition,\n createArgsToSoCreateOptions,\n updateArgsToSoUpdateOptions,\n searchArgsToSOFindOptions,\n enableMSearch,\n allowedSavedObjectAttributes,\n }", + "label": "{\n savedObjectType,\n cmServicesDefinition,\n createArgsToSoCreateOptions,\n updateArgsToSoUpdateOptions,\n searchArgsToSOFindOptions,\n enableMSearch,\n allowedSavedObjectAttributes,\n mSearchAdditionalSearchFields,\n }", "description": [], "signature": [ { @@ -118,7 +118,7 @@ "section": "def-common.SavedObjectsFindResult", "text": "SavedObjectsFindResult" }, - ") => Types[\"Item\"]; } | undefined" + ") => Types[\"Item\"]; additionalSearchFields?: string[] | undefined; } | undefined" ], "path": "packages/kbn-content-management-utils/src/saved_object_content_storage.ts", "deprecated": false, @@ -2865,6 +2865,20 @@ "path": "packages/kbn-content-management-utils/src/saved_object_content_storage.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/content-management-utils", + "id": "def-common.SOContentStorageConstrutorParams.mSearchAdditionalSearchFields", + "type": "Array", + "tags": [], + "label": "mSearchAdditionalSearchFields", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "packages/kbn-content-management-utils/src/saved_object_content_storage.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 4b8b9829a1a50..55af16f30d880 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 187 | 1 | 122 | 0 | +| 188 | 1 | 123 | 0 | ## Common diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 54b1c35b9669f..a3d2aa0c4415e 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 56dacaceda3e6..7e25cbeda0a88 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index f0bbbf320541d..7caeee42494af 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index cb51ca86bda86..9fc02fe58fa4f 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index 03048cb389098..ca9f1516bec86 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index 8d63466db6756..bc0795bf6158f 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 90fab26c3bf54..2c0d6086d55a3 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index e5c429b13bc13..d0a5218b0ceae 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index 025d1bd9e42cb..a9b59dae2cdc3 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index 253dcb5d92671..dbd536efd4af8 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index b305c86fe1c93..28432533e8282 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index 7c776934de2fc..8bc2bb6c0354d 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index 284e58f106333..c3cdc773148c1 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index c017c2b09c5fc..3c4070c221909 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 730462673de14..ff57bebc5c3a5 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index cf5ab5cb40877..981ca2d333281 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 07cbfbfb0af7e..b417fb5efe040 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index 98eedb888c16a..8d9dd57cfc8bc 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 8effd8f79e6e2..cb5c8d84690da 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index 133401c40993b..37895f8d77f79 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index 7b1538003a8be..49fed84525600 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 7128a9710b907..2ead6c497949c 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 228624d0ecaf2..437ee4fdd75fc 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index 4251ce1a56b61..ead55725566be 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index 670995a4a05c8..e84f5576a9ec7 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 35e42e0ea93dc..b37f87902aff2 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index 88779b741c0f6..1cff1fd02a433 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 11415cb9894d6..53e46ff803c2b 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index c6cef5d82d103..d94fb747f4731 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index d021591eff678..ee237e02ad449 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index 68c2414844881..0ff4dc99b1ca1 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 947af0a1b0da4..a2f9efd771efe 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index f94179345c264..b178fb5e76a4e 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 1d15fcc40b881..4b2a04a993b7d 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index 582190d70f7b8..fca4609153d74 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index 5be7399218312..646787175c940 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index 89421e8bdb148..f2c041d63f34b 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index f25e1c8a0ee66..61ffa6dd89dc4 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index b81abcc8258de..783da1f326902 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 735b84c1b0079..9ca5d0b80a63b 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 67eedbc41794e..4f9fa2f6d4e2b 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index b839841f35de9..7df248651d145 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 686e5e9661d4c..34d5df5e1d5ca 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 24e3759ce4b8a..8a374a174da77 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index dadbf28ea6332..48bc60defbb9d 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index e903616263fb4..d872809f9fbcd 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index 8fe13951442ca..769af6390cbb8 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 1256a5eb245e7..78956563fd545 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 04ea7169eb666..ec60e78f18e7c 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index 90009c29c89cc..ea02ea43a5abd 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index 7716f62714f6b..62a7277f4da84 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index f4c2a8115015b..6a38822734be7 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index cb08d0340717d..be9d12fb509e6 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index 321b72ad4e2f5..9cf6a0c2945aa 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 78bcb9afedc40..6b9c1e9531847 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index d6aa6ab279e28..c51c1c80290ff 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index 19aa36087e3fd..16641ee0f9618 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 1d63ca16b335c..7203a607e4f16 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index 787454514e00e..9837e89fcd2bb 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 87e0876cc677d..a5b7c23ba23f6 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index 57abe05b1e9a3..9ca62691cf917 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index 6d0f2c07a925c..81fc4f5ea6bf9 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 8ee889cbcf8ad..05a1daf171451 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index 3d3161cb7cbb3..faaac088132f2 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index fa1fa17e20bb6..b7a801fa451e8 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index 636c73bcfe78f..6a55ec423723a 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index c63fcf2523f89..6b1d80bbaa14b 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index 45554c9823289..1e222721df01d 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index a9c57abc605a1..0aa09c0f91cdf 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.devdocs.json b/api_docs/kbn_core_http_server.devdocs.json index 45aa782bcbd31..82728a75430e6 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -3599,18 +3599,6 @@ "plugin": "alerting", "path": "x-pack/plugins/alerting/server/routes/maintenance_window/active_maintenance_windows.ts" }, - { - "plugin": "guidedOnboarding", - "path": "src/plugins/guided_onboarding/server/routes/guide_state_routes.ts" - }, - { - "plugin": "guidedOnboarding", - "path": "src/plugins/guided_onboarding/server/routes/plugin_state_routes.ts" - }, - { - "plugin": "guidedOnboarding", - "path": "src/plugins/guided_onboarding/server/routes/config_routes.ts" - }, { "plugin": "ruleRegistry", "path": "x-pack/plugins/rule_registry/server/routes/get_alert_by_id.ts" @@ -3631,6 +3619,18 @@ "plugin": "ruleRegistry", "path": "x-pack/plugins/rule_registry/server/routes/get_aad_fields_by_rule_type.ts" }, + { + "plugin": "guidedOnboarding", + "path": "src/plugins/guided_onboarding/server/routes/guide_state_routes.ts" + }, + { + "plugin": "guidedOnboarding", + "path": "src/plugins/guided_onboarding/server/routes/plugin_state_routes.ts" + }, + { + "plugin": "guidedOnboarding", + "path": "src/plugins/guided_onboarding/server/routes/config_routes.ts" + }, { "plugin": "observability", "path": "x-pack/plugins/observability/server/lib/annotations/register_annotation_apis.ts" @@ -4687,10 +4687,6 @@ "plugin": "interactiveSetup", "path": "src/plugins/interactive_setup/server/routes/status.ts" }, - { - "plugin": "savedObjectsFinder", - "path": "src/plugins/saved_objects_finder/server/routes/find.ts" - }, { "plugin": "savedObjectsManagement", "path": "src/plugins/saved_objects_management/server/routes/find.ts" @@ -13778,10 +13774,6 @@ "plugin": "@kbn/core-http-router-server-mocks", "path": "packages/core/http/core-http-router-server-mocks/src/versioned_router.mock.ts" }, - { - "plugin": "bfetch", - "path": "src/plugins/bfetch/server/plugin.ts" - }, { "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/public/runtime_fields/get_runtime_field.ts" @@ -13814,6 +13806,10 @@ "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/internal/has_data_views.ts" }, + { + "plugin": "bfetch", + "path": "src/plugins/bfetch/server/plugin.ts" + }, { "plugin": "data", "path": "src/plugins/data/server/search/routes/session.ts" @@ -14042,6 +14038,10 @@ "plugin": "ml", "path": "x-pack/plugins/ml/server/routes/trained_models.ts" }, + { + "plugin": "ml", + "path": "x-pack/plugins/ml/server/routes/trained_models.ts" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/server/routes/management.ts" @@ -14510,10 +14510,6 @@ "plugin": "@kbn/core-http-router-server-mocks", "path": "packages/core/http/core-http-router-server-mocks/src/versioned_router.mock.ts" }, - { - "plugin": "bfetch", - "path": "src/plugins/bfetch/server/plugin.ts" - }, { "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/public/runtime_fields/put_runtime_field.ts" @@ -14526,6 +14522,10 @@ "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts" }, + { + "plugin": "bfetch", + "path": "src/plugins/bfetch/server/plugin.ts" + }, { "plugin": "data", "path": "src/plugins/data/server/search/routes/session.ts" @@ -14698,10 +14698,6 @@ "plugin": "@kbn/core-http-router-server-mocks", "path": "packages/core/http/core-http-router-server-mocks/src/versioned_router.mock.ts" }, - { - "plugin": "bfetch", - "path": "src/plugins/bfetch/server/plugin.ts" - }, { "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/public/fields/update_fields.ts" @@ -14742,6 +14738,10 @@ "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts" }, + { + "plugin": "bfetch", + "path": "src/plugins/bfetch/server/plugin.ts" + }, { "plugin": "data", "path": "src/plugins/data/server/search/routes/session.ts" @@ -14778,6 +14778,10 @@ "plugin": "data", "path": "src/plugins/data/server/kql_telemetry/route.ts" }, + { + "plugin": "unifiedSearch", + "path": "src/plugins/unified_search/server/autocomplete/value_suggestions_route.ts" + }, { "plugin": "aiops", "path": "x-pack/plugins/aiops/server/routes/log_rate_analysis.ts" @@ -14786,10 +14790,6 @@ "plugin": "aiops", "path": "x-pack/plugins/aiops/server/routes/log_categorization.ts" }, - { - "plugin": "unifiedSearch", - "path": "src/plugins/unified_search/server/autocomplete/value_suggestions_route.ts" - }, { "plugin": "ml", "path": "x-pack/plugins/ml/server/routes/annotations.ts" @@ -15074,6 +15074,10 @@ "plugin": "ml", "path": "x-pack/plugins/ml/server/routes/trained_models.ts" }, + { + "plugin": "ml", + "path": "x-pack/plugins/ml/server/routes/trained_models.ts" + }, { "plugin": "ml", "path": "x-pack/plugins/ml/server/routes/alerting.ts" @@ -15418,10 +15422,6 @@ "plugin": "@kbn/core-http-router-server-mocks", "path": "packages/core/http/core-http-router-server-mocks/src/versioned_router.mock.ts" }, - { - "plugin": "bfetch", - "path": "src/plugins/bfetch/server/plugin.ts" - }, { "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/public/runtime_fields/delete_runtime_field.ts" @@ -15434,6 +15434,10 @@ "plugin": "dataViews", "path": "src/plugins/data_views/server/rest_api_routes/public/delete_data_view.ts" }, + { + "plugin": "bfetch", + "path": "src/plugins/bfetch/server/plugin.ts" + }, { "plugin": "data", "path": "src/plugins/data/server/search/routes/session.ts" diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 04b45513b45c5..99d0bfed889dd 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index df28c49f0862d..8cb45c96afba6 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 71fd4602c628d..fae37a80af603 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index dedebc31e31fd..4d5eb5471bd82 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index d196e9513ab6c..0253dae1815ba 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index a4f118dfa303d..222e7c93daf9e 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 1c1d80320475a..1c5e29a1b819b 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index 5f6215c2b0e27..22aebb96c496a 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 5391d2f281be5..037cc811c3a54 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index df5e3bb4349d7..c29d40f5f7313 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index 56086553b00dc..e6ba4de3c1fb1 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index 99531b81e8574..aa5e529950a8a 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 2a0f438edb26b..5587dcb2c4b83 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index a02bdb3c0101e..954d92db64bf5 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index 7d2581f42e4f6..d9dfcd3237c55 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index ba13559eba6bf..908787f976911 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 29169fb4371cd..bbadb69f2a581 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 123e3aa3e7619..703169e0049ca 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 4fb6a77b9b04d..575f90597d2d3 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index 3d86ef8947788..94453374d508a 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index dc7e196ccdf06..1203a3ea18a91 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index 317ba2ee9e774..964eada8d67a9 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index ace69d608a26d..65b165872eab4 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index 751b14ef4a567..6b5f2599ab21e 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index b8bc5cfc50f5b..b8075163f5f03 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index f558d06a364d1..4a47840063206 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index 010eab5713a79..4fee677a2e341 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index b142c9f37285f..a0c126ef3ff94 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 6c94ef3afbb40..ed03155a5ed93 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index c2638a4737c23..326dc303a3b1c 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 0e95009b0cb85..58a476462aba0 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index a25e35d4e19ba..b09dceee0054e 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index 69b5674fe89ab..791e5bb452ac0 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index 079aed26d91d7..536239c5f598a 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index b39ee812ab659..a0fd9d020d751 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 916c6fafc8bd0..4ecac68faabf8 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index a6f60b7e0e965..212070fdb5bca 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index c2a5349922e0d..e6594e6507489 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index 18f595bde6978..6b3fc9263cdbf 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 78e0717918e17..3234e959b51c7 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index 86670bcafb4ae..5b503dd6ca04f 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index 6aec9dfd84597..8c0c299eb62d8 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index abb1fb3e8afe6..67ade810a2659 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index ff0bc3ad493e7..e658945d42019 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index b38e9d98875bb..7b2c53aaa9659 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index a62569321db1f..43e10686ceb1a 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index b4501b269354e..b23c95b79201f 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index 95fa85cab16b5..a7a431da29a06 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index d1e46f4c1ee5e..630637ff9c9c1 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index a987dc60dc8d8..03eda68dd88f5 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index c493c59bc1b4a..73189853b8392 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index d6b01343a214b..ad0b541c70c20 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index 99a7f0976ded9..e8a44056f0121 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 7d5ba1632a8d4..94bb7cb8e1b23 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 758ebdab3d222..2df414cb3785c 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index 99235c2ce242a..2b80851350953 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 845cab1c1d84b..f67a0413da870 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index d8ae52e1c5cd1..46ff072146b36 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index d54b0c18fa7f9..f9fdbea16f255 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index 48c029ae6a3fa..2eff7e0f56a05 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index 7b0108f47de19..c4449475b455a 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index 4cd54142fc9d2..d6644b87e6e2c 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index f1c9d87eab6cf..c0517668bd3e6 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 1d759a21ce701..f1cbd7a5d8f57 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index e654990475f5d..8a5f1c295ab8b 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index 117678763edcb..20f2eed5b139b 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index 6695ef9c86476..43033b1972ce6 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index 271a06dbd26e7..a4dcb69ed3fcb 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index 1bf1a38c714f5..0517bdd2d1419 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index 56b267ba84572..62dd992d0d761 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index bc776395968b5..7194e3044a2a7 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index c6feaf4650780..c152eb2c4ed2d 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index cdbe74136748f..4c82c21c3a216 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 9ddf2c57ce822..a5c94c3afbba7 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index 7abf2e74bf987..d394eec62e530 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index 1931ac3b26fff..8206d774761f4 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index 532c7adad3e1c..c70b178a72abc 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index 0ab8e28aa0df9..e509dac371cfa 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index 7a75e89ea4150..1efa419d1f86f 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index c67e252addd2f..5d9a8b6c67582 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index 4e6b67b9852b3..36f34c6b24b90 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index d4cbd84c11c56..c5f0b02883e09 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 79c868879899d..41b6f57546a9b 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index 25757579a4fbd..3421fa3113701 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index 935179f08e439..88521aaf6d709 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index dddf1ef343884..3a11aeb9c3c0c 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 45056ff08f1af..287c621493ea6 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-mocks'] --- import kbnCoreUserSettingsServerMocksObj from './kbn_core_user_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index cc016eec8bfc8..72ddc4913f2ac 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 56ce772d5b1d1..78daead4149fe 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 4c969ab0e95fa..d06760255e077 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index b53458717153d..97f28f5ce3d72 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 4a9f76a2bf852..196e1c6c87297 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_analytics.mdx b/api_docs/kbn_deeplinks_analytics.mdx index 395daccf034c6..0495d60d6de22 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-analytics'] --- import kbnDeeplinksAnalyticsObj from './kbn_deeplinks_analytics.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_devtools.mdx b/api_docs/kbn_deeplinks_devtools.mdx index 4f65a2c1d09d1..67a71ba210d32 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 1517e4387cf9b..2de85cf9a9346 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_management.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index 3d1bc0ada81d1..9663d229135ae 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index 1ff762c760aa7..9e3b1781e5d4b 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index e3d1e559f3f0d..d8666f439297d 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index 544a84a94c069..0f019717f1a3e 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-analytics'] --- import kbnDefaultNavAnalyticsObj from './kbn_default_nav_analytics.devdocs.json'; diff --git a/api_docs/kbn_default_nav_devtools.mdx b/api_docs/kbn_default_nav_devtools.mdx index 20667b6757a8d..4166cd3a51e6a 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-devtools'] --- import kbnDefaultNavDevtoolsObj from './kbn_default_nav_devtools.devdocs.json'; diff --git a/api_docs/kbn_default_nav_management.mdx b/api_docs/kbn_default_nav_management.mdx index 7c20d850bdd3d..f5b98d82c200b 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-management'] --- import kbnDefaultNavManagementObj from './kbn_default_nav_management.devdocs.json'; diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index 332dab42ea5ec..7e7c53bfb029a 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-ml'] --- import kbnDefaultNavMlObj from './kbn_default_nav_ml.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 08a9a3fb7df56..b859b6745a213 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index 337ba8695482a..c5f9514bc0c65 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 7558dc4339d3f..853a7dd951ca2 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 89db217814781..3d176057d5edd 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index b4fad8a137581..e336c9f6f8a6a 100644 --- a/api_docs/kbn_discover_utils.mdx +++ b/api_docs/kbn_discover_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-utils title: "@kbn/discover-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index 3e8d6352e66f7..e21a5090c6edb 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -493,7 +493,7 @@ "label": "upgradeAssistant", "description": [], "signature": [ - "{ readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; }" + "{ readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; readonly reindexWithPipeline: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 5939e5a135fa4..d9075a7e7934a 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 06fbb1b04042e..c90eb47fc8ebf 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_dom_drag_drop.mdx b/api_docs/kbn_dom_drag_drop.mdx index 9423dfb94366c..ac85c4ff798d8 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dom-drag-drop'] --- import kbnDomDragDropObj from './kbn_dom_drag_drop.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 9fa55673ed2b0..18cdd3e94731b 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 7ba02853d106f..1fd2511549f56 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 0dbcabd54280f..e8184cd642a77 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index 3d27411f79c8a..55c35b7e146ee 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 265c4b5b4b2e5..5050f95627ecc 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index 06d97ea2e6c09..c96bdbd286d34 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index d6cef59c85df9..6b88702a88dc1 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index b152de1a0efad..07413ad66ef3a 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index f5bfbca78eb95..ed6d8ead4aa3a 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index cda3ff57e110d..e5d1042aec594 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index 4ce21cb4603ce..2498132adc226 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-common'] --- import kbnEventAnnotationCommonObj from './kbn_event_annotation_common.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_components.devdocs.json b/api_docs/kbn_event_annotation_components.devdocs.json index e835390ba84ac..54b9e95eb01e1 100644 --- a/api_docs/kbn_event_annotation_components.devdocs.json +++ b/api_docs/kbn_event_annotation_components.devdocs.json @@ -1131,7 +1131,15 @@ "section": "def-common.SavedObjectCommon", "text": "SavedObjectCommon" }, - "; }) => void; onCreateNew: () => void; }) => JSX.Element" + "<", + { + "pluginId": "savedObjectsFinder", + "scope": "common", + "docId": "kibSavedObjectsFinderPluginApi", + "section": "def-common.FinderAttributes", + "text": "FinderAttributes" + }, + ">; }) => void; onCreateNew: () => void; }) => JSX.Element" ], "path": "packages/kbn-event-annotation-components/types.ts", "deprecated": false, @@ -1178,7 +1186,15 @@ "section": "def-common.SavedObjectCommon", "text": "SavedObjectCommon" }, - "; }) => void" + "<", + { + "pluginId": "savedObjectsFinder", + "scope": "common", + "docId": "kibSavedObjectsFinderPluginApi", + "section": "def-common.FinderAttributes", + "text": "FinderAttributes" + }, + ">; }) => void" ], "path": "packages/kbn-event-annotation-components/types.ts", "deprecated": false, @@ -1237,13 +1253,21 @@ "description": [], "signature": [ { - "pluginId": "@kbn/core-saved-objects-common", + "pluginId": "@kbn/content-management-utils", + "scope": "common", + "docId": "kibKbnContentManagementUtilsPluginApi", + "section": "def-common.SOWithMetadata", + "text": "SOWithMetadata" + }, + "<", + { + "pluginId": "savedObjectsFinder", "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" + "docId": "kibSavedObjectsFinderPluginApi", + "section": "def-common.FinderAttributes", + "text": "FinderAttributes" }, - "" + ">" ], "path": "packages/kbn-event-annotation-components/types.ts", "deprecated": false, diff --git a/api_docs/kbn_event_annotation_components.mdx b/api_docs/kbn_event_annotation_components.mdx index 9cd8f7214cfa8..02b3d4b1a216d 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-components'] --- import kbnEventAnnotationComponentsObj from './kbn_event_annotation_components.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 732812f7a79b7..365b3085bd27c 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 5bdbfb13a0efb..6b93bad46d751 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 2c8eb05ed00fb..3d3c6614c75f7 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index dcd7828d8f729..f95efa21d1831 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 5ab4aeed0523f..0e46c21e56371 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index a40025b07062d..ebf4aa2ab79ff 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index 195dc456047cf..d64302ecba7d3 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index de8d08099659f..02d760595f265 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index e03dc06db9fa2..101b5f981a365 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 7e1396bcb3633..9ad0a5673680d 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index fe31787dee3e4..4886cf2557874 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index aa9e3fd4aeea1..3802212b8eb14 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 5f08767456ce9..3051660f3aede 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index c58cdd56cebd3..10a295a760f74 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 2f53834a6ea42..51da5c5b5baff 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index 5f867be9c59b2..23ca2e22cc6b8 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index abce71a506637..3ce1d23d09c4b 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 20c0060b80444..3244c174af0a6 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 769d75499448a..29ec1aaa8c593 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.devdocs.json b/api_docs/kbn_io_ts_utils.devdocs.json index 88c594ba2f1bc..06b7c2f9c5137 100644 --- a/api_docs/kbn_io_ts_utils.devdocs.json +++ b/api_docs/kbn_io_ts_utils.devdocs.json @@ -996,7 +996,7 @@ "description": [], "signature": [ "Type", - "" + "" ], "path": "packages/kbn-io-ts-utils/src/to_boolean_rt/index.ts", "deprecated": false, diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index 7871742ad90e1..6c7ec1976753a 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 5275a27b9dc42..367e2690e7bb1 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index ba7fc5802fd43..a98049fb4dd26 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index 9d53c0f40410b..67e9b1ddef60f 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index c81f36b2dd300..72ff23c059432 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index d55332c57262e..71799546b4e99 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 30e81fe7e6dce..85d66708cb65e 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index 23defe077087c..d85fa5685be5e 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index f2c347ff0d8e2..6e5ff13b5fb25 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index 7b2f34834dc06..0ea3f4156b07c 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index e1ee8679a1f9e..7135df80a0250 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index fe91a56bfe951..adf5e16447694 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index 6c99005c7825a..25ea6d1ddbf37 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 27d6a1535e2cd..9ab81cda021b0 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index e80999e46e2cc..3fd56d85c061c 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index 2f32314397b45..9450e44a5d613 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 046a864c1ba4a..1bec7154b1fac 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index 55bb1c3e001a9..4f5721186f436 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index 194920b61337e..8200185dd676d 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index 2332cec54f230..6887f9dfa1e00 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index b863f9b37db68..4be90bea3c796 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index 6807a03355675..ce2db9a911c85 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-in-memory-table'] --- import kbnMlInMemoryTableObj from './kbn_ml_in_memory_table.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 495dd2e996efb..11e1c61046bbf 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index ca1444af45137..b9b1bcc1d9b1c 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index 3b1ab520333fd..33fe3a77c0241 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index d000fb610f36c..f7621acc959af 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index 69e93bf55bcb8..015eba349a723 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index dc3aa4b33ce9c..f38f1b19de1e9 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index 70d162bde8b08..f1c63620a1d4c 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index ffd5f8a5881e1..f5304553a8aa4 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index ff84ab0ed20d7..92506805309af 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index 5086d30b3eb5d..ce9a687d1f9d1 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index 42c0c41ca1e7f..9e709e52bd482 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 41c37b3de7060..16a18c689ad81 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index 358eadfb73659..9d3a0ad27403d 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 64b83da073a33..2a4a66ba5623d 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index 4d20d05ca243f..a4579d6d21b55 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 894950a4c61ef..d2bbc5d60df94 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 6791b1d97fe5a..039fd169e81d3 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 85bf9046af977..68f6c2b8ba3ca 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index bda4fcd016615..04f327032e7da 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 051f8d90787bf..3c87b9c0a1a81 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 9efe6b300e30b..ce0d0e970141d 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 431a8af99adf6..2daac55d98b5f 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index 289486f09d428..106e8eb4f681d 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index da5d240964584..c01c73532ed54 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index b23eb4928089b..e964b0faaaa73 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-common'] --- import kbnReactKibanaContextCommonObj from './kbn_react_kibana_context_common.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_render.mdx b/api_docs/kbn_react_kibana_context_render.mdx index 1af5802080806..36f24195bb524 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-render'] --- import kbnReactKibanaContextRenderObj from './kbn_react_kibana_context_render.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_root.mdx b/api_docs/kbn_react_kibana_context_root.mdx index ac75bb3bdb311..1f5954d8df2ab 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-root'] --- import kbnReactKibanaContextRootObj from './kbn_react_kibana_context_root.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_styled.mdx b/api_docs/kbn_react_kibana_context_styled.mdx index 957713bb1a751..d3dbc3f7848bf 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-styled'] --- import kbnReactKibanaContextStyledObj from './kbn_react_kibana_context_styled.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_theme.mdx b/api_docs/kbn_react_kibana_context_theme.mdx index e2aa061cb4bea..e134d71dba66e 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-theme'] --- import kbnReactKibanaContextThemeObj from './kbn_react_kibana_context_theme.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_mount.mdx b/api_docs/kbn_react_kibana_mount.mdx index c7d6c27548c55..18336f8c9acc2 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index b9c9725d04ee6..740a64be48407 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index 7392e055177b3..3cdeed510f331 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index 62955e96811da..2dcf054899ac7 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index d7bab19e316ed..1ec1665d982a0 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index f2dcf6582a1a4..6d8bf92b0fd85 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index d39dc1c0385ae..9ae13dad59ab1 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index aa118bc496e35..473185e7ec57d 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 92409aa81aa38..4d410fa27c46a 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index bb0bc3382f502..6600a72923ae6 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_navigation.mdx b/api_docs/kbn_security_solution_navigation.mdx index 815a1197552d0..0a5fdef30287b 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-navigation'] --- import kbnSecuritySolutionNavigationObj from './kbn_security_solution_navigation.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 0a74cefaf140a..b1a2f5e29171e 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index ae4497a82d076..b1b81584c877c 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 8726c38268640..db72e41129b27 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index 235ece6579de9..998cd2d31a6b7 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index 5589b2f530f97..6fb69d797146b 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index c629a70eaeae3..1101bf7bed18e 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index 8784dae4ef7d8..04c11e6ab92b8 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 1435f7d61f57f..166de05b4763a 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 32ca05053289c..cb48b87491d7b 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 22a450072fd3e..d251ce0237e69 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index ebab6071e8d81..ae09f11f1fbae 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index 87a6fd81b10ea..091260a1e4bcf 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index e87c29be26fe1..5488a4d058e5b 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index 8d9f9842dc69f..fbba031701e5b 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index df6f0c1128ce5..850468aeafd84 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index c9430b91c1899..5605d23108058 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 7f4b2d4750f03..7b96c67b43423 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 650998ba6f321..329ecfa0fe9d9 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index 6108a52fc0879..1c8bc83eaa5c5 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index 047a13ff0e0fd..b07ecb81aaaf1 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 88150273d7da5..76af845693f60 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index f6196c49f2940..34f94831f29e5 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 6f280358cec5c..08d4986085710 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index 9a18e91b6ff78..58a79277bd948 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index f5a753bc3aaab..fbd77da2f7341 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index 41d395bf7e246..a193a2e99e497 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 4beb3231db452..9545b150e3749 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 919291ee2d24d..c7c3d427a869a 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 31f67a7732224..a22979f5b13c8 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index c7be5ae0d8d23..398025a683674 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 4923afb2f3563..a8b7cd7387f1c 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index 759df6f700995..37b6b3c8648bf 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index 8623b7e4f4d27..f99775fb830e6 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index 079cd7d6a5dcb..823cf69e0db54 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index 811357a139728..d6e4a179d27a9 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index 47814b8c7eb51..991285d262c13 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index 91388199fbe63..cae2eb79f4ca1 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index edddbc6f20c0b..fdb550af1e08b 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index 4cc3a68c3d1db..857d7a7f2b9aa 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index b521456e62f20..cb23e3c4bbdd5 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index e9b286aa5109f..6622922486287 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index 6451b59819e84..0dbcf32a88f15 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index e7b3f47baf8e7..98ec4209f7b67 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 21e9e7cf31995..14c9140cf23bc 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index 71229302d7c5b..7170a26c7c0f3 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 90f4bd8dcad84..31b7a060b7fd4 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index 6bb75d60c122f..fdebed3eae57d 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 5578bc12670a5..8404a52eeaabb 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index 7a25309d4728d..8bf4897074ffd 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 561b6e180acac..e5715200637da 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index 6b8591b832ca7..ac2d30496dcee 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index 77ff7acea5927..27d2cd32d78bf 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index a84303e13216c..3e68934c3f1c0 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index 0ea4839401c00..9f80c59c10f1d 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index 46a518352d9a9..16c403fdc4687 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index c3b6c74213720..a4a60ea678e59 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index e3edf8a67b8ea..3a5bfb3535ccf 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 42af8a9811ca5..64dc173a2b377 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index d5707fbb5792e..0a01bc802c924 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 65d2a81e0e5b3..cd222a033e70f 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index 5964795eb49d4..7c90908187da5 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index 74cbfba121c9c..598a397c9a7d2 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 8d6ff71719424..96c4501f84f30 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index ef0fe567eb189..0fbb5c73c78ab 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index 213dffb218e96..970a213cc8643 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index ec092e1d0296d..743b1866288fa 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index c680cf30e2b20..19a122703a83d 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 5d8ec59ecb184..cfe4fd52ff873 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 755ee9f447cd9..da3af1449decf 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index a046a972fb1af..358ccda31ce17 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 740c3f77368e1..f9dae23c767a7 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 67378b52f35ad..1d99d57a481b2 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index c520055faac88..4bbb77543c64f 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index da6967718d10a..c803989e4246d 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 4fbb7781ad46f..de2fdce4ded2d 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index 2c6610824c6e8..b81eb3f6eb438 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index d47a99ee54ce2..6248b21ab9ba7 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index 35e03a3ff3065..4b4187bf32ed9 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 8407eb4258544..7914f81c134df 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index 6cb41dc8c4f9c..96f6401319ff4 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 3b0bd687483b8..6df817423e527 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index 17cf7043cdaf1..52be8790127a8 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.devdocs.json b/api_docs/kbn_user_profile_components.devdocs.json index 73f567df595ef..6082e35d46bb9 100644 --- a/api_docs/kbn_user_profile_components.devdocs.json +++ b/api_docs/kbn_user_profile_components.devdocs.json @@ -172,6 +172,57 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesKibanaProvider", + "type": "Function", + "tags": [], + "label": "UserProfilesKibanaProvider", + "description": [ + "\nKibana-specific Provider that maps to known dependency types." + ], + "signature": [ + "({ children, ...services }: React.PropsWithChildren<", + { + "pluginId": "@kbn/user-profile-components", + "scope": "common", + "docId": "kibKbnUserProfileComponentsPluginApi", + "section": "def-common.UserProfilesKibanaDependencies", + "text": "UserProfilesKibanaDependencies" + }, + ">) => JSX.Element" + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesKibanaProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n children,\n ...services\n}", + "description": [], + "signature": [ + "React.PropsWithChildren<", + { + "pluginId": "@kbn/user-profile-components", + "scope": "common", + "docId": "kibKbnUserProfileComponentsPluginApi", + "section": "def-common.UserProfilesKibanaDependencies", + "text": "UserProfilesKibanaDependencies" + }, + ">" + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/user-profile-components", "id": "def-common.UserProfilesPopover", @@ -230,6 +281,45 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesProvider", + "type": "Function", + "tags": [], + "label": "UserProfilesProvider", + "description": [ + "\nAbstract external service Provider." + ], + "signature": [ + "({ children, ...services }: React.PropsWithChildren<", + "Services", + ">) => JSX.Element" + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{ children, ...services }", + "description": [], + "signature": [ + "React.PropsWithChildren<", + "Services", + ">" + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/user-profile-components", "id": "def-common.UserProfilesSelectable", @@ -338,6 +428,55 @@ ], "returnComment": [], "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.useUpdateUserProfile", + "type": "Function", + "tags": [], + "label": "useUpdateUserProfile", + "description": [], + "signature": [ + "({ notificationSuccess, pageReloadChecker, }?: Props) => { update: (updatedData: D) => Promise; showSuccessNotification: ({ isRefreshRequired }?: { isRefreshRequired?: boolean | undefined; }) => void; userProfileData: ", + { + "pluginId": "@kbn/user-profile-components", + "scope": "common", + "docId": "kibKbnUserProfileComponentsPluginApi", + "section": "def-common.UserProfileData", + "text": "UserProfileData" + }, + " | null | undefined; isLoading: boolean; }" + ], + "path": "packages/kbn-user-profile-components/src/hooks/use_update_user_profile.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.useUpdateUserProfile.$1", + "type": "Object", + "tags": [], + "label": "{\n notificationSuccess = {},\n pageReloadChecker,\n}", + "description": [], + "signature": [ + "Props" + ], + "path": "packages/kbn-user-profile-components/src/hooks/use_update_user_profile.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false } ], "interfaces": [ @@ -575,7 +714,7 @@ "description": [ "\nAvatar stored in user profile." ], - "path": "packages/kbn-user-profile-components/src/user_profile.ts", + "path": "packages/kbn-user-profile-components/src/types.ts", "deprecated": false, "trackAdoption": false, "children": [ @@ -591,7 +730,7 @@ "signature": [ "string | undefined" ], - "path": "packages/kbn-user-profile-components/src/user_profile.ts", + "path": "packages/kbn-user-profile-components/src/types.ts", "deprecated": false, "trackAdoption": false }, @@ -607,7 +746,7 @@ "signature": [ "string | undefined" ], - "path": "packages/kbn-user-profile-components/src/user_profile.ts", + "path": "packages/kbn-user-profile-components/src/types.ts", "deprecated": false, "trackAdoption": false }, @@ -623,13 +762,219 @@ "signature": [ "string | null | undefined" ], - "path": "packages/kbn-user-profile-components/src/user_profile.ts", + "path": "packages/kbn-user-profile-components/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfileData", + "type": "Interface", + "tags": [], + "label": "UserProfileData", + "description": [], + "path": "packages/kbn-user-profile-components/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfileData.avatar", + "type": "Object", + "tags": [], + "label": "avatar", + "description": [], + "signature": [ + { + "pluginId": "@kbn/user-profile-components", + "scope": "common", + "docId": "kibKbnUserProfileComponentsPluginApi", + "section": "def-common.UserProfileAvatarData", + "text": "UserProfileAvatarData" + }, + " | undefined" + ], + "path": "packages/kbn-user-profile-components/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfileData.userSettings", + "type": "Object", + "tags": [], + "label": "userSettings", + "description": [], + "signature": [ + { + "pluginId": "@kbn/user-profile-components", + "scope": "common", + "docId": "kibKbnUserProfileComponentsPluginApi", + "section": "def-common.UserSettingsData", + "text": "UserSettingsData" + }, + " | undefined" + ], + "path": "packages/kbn-user-profile-components/src/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfileData.Unnamed", + "type": "IndexSignature", + "tags": [], + "label": "[key: string]: unknown", + "description": [], + "signature": [ + "[key: string]: unknown" + ], + "path": "packages/kbn-user-profile-components/src/types.ts", "deprecated": false, "trackAdoption": false } ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesKibanaDependencies", + "type": "Interface", + "tags": [], + "label": "UserProfilesKibanaDependencies", + "description": [ + "\nKibana-specific service types." + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesKibanaDependencies.core", + "type": "Object", + "tags": [], + "label": "core", + "description": [ + "CoreStart contract" + ], + "signature": [ + "{ notifications: ", + { + "pluginId": "@kbn/core-notifications-browser", + "scope": "common", + "docId": "kibKbnCoreNotificationsBrowserPluginApi", + "section": "def-common.NotificationsStart", + "text": "NotificationsStart" + }, + "; theme: ", + { + "pluginId": "@kbn/core-theme-browser", + "scope": "common", + "docId": "kibKbnCoreThemeBrowserPluginApi", + "section": "def-common.ThemeServiceStart", + "text": "ThemeServiceStart" + }, + "; }" + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesKibanaDependencies.security", + "type": "Object", + "tags": [], + "label": "security", + "description": [], + "signature": [ + "{ userProfiles: ", + "UserProfileAPIClient", + "; }" + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesKibanaDependencies.toMountPoint", + "type": "Function", + "tags": [], + "label": "toMountPoint", + "description": [ + "\nHandler from the '@kbn/kibana-react-plugin/public' Plugin\n\n```\nimport { toMountPoint } from '@kbn/kibana-react-plugin/public';\n```" + ], + "signature": [ + "(node: React.ReactNode, options?: { theme$: ", + "Observable", + "<{ readonly darkMode: boolean; }>; } | undefined) => ", + { + "pluginId": "@kbn/core-mount-utils-browser", + "scope": "common", + "docId": "kibKbnCoreMountUtilsBrowserPluginApi", + "section": "def-common.MountPoint", + "text": "MountPoint" + }, + "" + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesKibanaDependencies.toMountPoint.$1", + "type": "CompoundType", + "tags": [], + "label": "node", + "description": [], + "signature": [ + "React.ReactNode" + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesKibanaDependencies.toMountPoint.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserProfilesKibanaDependencies.toMountPoint.$2.theme$", + "type": "Object", + "tags": [], + "label": "theme$", + "description": [], + "signature": [ + "Observable", + "<{ readonly darkMode: boolean; }>" + ], + "path": "packages/kbn-user-profile-components/src/services.tsx", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/user-profile-components", "id": "def-common.UserProfilesPopoverProps", @@ -1093,6 +1438,43 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserSettingsData", + "type": "Interface", + "tags": [], + "label": "UserSettingsData", + "description": [ + "\nUser settings stored in the data object of the User Profile" + ], + "path": "packages/kbn-user-profile-components/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UserSettingsData.darkMode", + "type": "CompoundType", + "tags": [], + "label": "darkMode", + "description": [], + "signature": [ + { + "pluginId": "@kbn/user-profile-components", + "scope": "common", + "docId": "kibKbnUserProfileComponentsPluginApi", + "section": "def-common.DarkModeValue", + "text": "DarkModeValue" + }, + " | undefined" + ], + "path": "packages/kbn-user-profile-components/src/types.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/user-profile-components", "id": "def-common.UserToolTipProps", @@ -1169,6 +1551,69 @@ ], "enums": [], "misc": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.DarkModeValue", + "type": "Type", + "tags": [], + "label": "DarkModeValue", + "description": [], + "signature": [ + "\"\" | \"light\" | \"dark\"" + ], + "path": "packages/kbn-user-profile-components/src/types.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UpdateUserProfileHook", + "type": "Type", + "tags": [], + "label": "UpdateUserProfileHook", + "description": [], + "signature": [ + "({ notificationSuccess, pageReloadChecker, }?: Props) => { update: (updatedData: D) => Promise; showSuccessNotification: ({ isRefreshRequired }?: { isRefreshRequired?: boolean | undefined; }) => void; userProfileData: ", + { + "pluginId": "@kbn/user-profile-components", + "scope": "common", + "docId": "kibKbnUserProfileComponentsPluginApi", + "section": "def-common.UserProfileData", + "text": "UserProfileData" + }, + " | null | undefined; isLoading: boolean; }" + ], + "path": "packages/kbn-user-profile-components/src/hooks/use_update_user_profile.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "@kbn/user-profile-components", + "id": "def-common.UpdateUserProfileHook.$1", + "type": "Object", + "tags": [], + "label": "__0", + "description": [], + "signature": [ + "Props" + ], + "path": "packages/kbn-user-profile-components/src/hooks/use_update_user_profile.tsx", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/user-profile-components", "id": "def-common.UserProfileWithAvatar", diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 25e3e061b5b02..691b204e0d289 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 58 | 0 | 5 | 0 | +| 80 | 0 | 21 | 2 | ## Common diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index a5f33d9761e5e..ae1e131251210 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 247cf97516111..79efc58af5a46 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 4483896e948fa..05d8ec753475f 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index 2399b8a856ad1..4979e45203494 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index b9927fd6e19f7..dac217dabfb5c 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 6e1f9222238c7..bec775fbd5cde 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index 7464f3e995e0b..1e490cd0d8e78 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -916,6 +916,18 @@ "plugin": "visualizations", "path": "src/plugins/visualizations/public/visualize_app/index.tsx" }, + { + "plugin": "serverless", + "path": "x-pack/plugins/serverless/public/plugin.tsx" + }, + { + "plugin": "serverless", + "path": "x-pack/plugins/serverless/public/plugin.tsx" + }, + { + "plugin": "serverless", + "path": "x-pack/plugins/serverless/public/plugin.tsx" + }, { "plugin": "controls", "path": "src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx" @@ -1136,18 +1148,6 @@ "plugin": "lens", "path": "x-pack/plugins/lens/public/embeddable/embeddable.tsx" }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/public/application/maintenance_windows.tsx" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/public/application/maintenance_windows.tsx" - }, - { - "plugin": "alerting", - "path": "x-pack/plugins/alerting/public/application/maintenance_windows.tsx" - }, { "plugin": "security", "path": "x-pack/plugins/security/public/authentication/access_agreement/access_agreement_page.tsx" @@ -1268,6 +1268,18 @@ "plugin": "security", "path": "x-pack/plugins/security/public/nav_control/nav_control_service.tsx" }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/public/application/maintenance_windows.tsx" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/public/application/maintenance_windows.tsx" + }, + { + "plugin": "alerting", + "path": "x-pack/plugins/alerting/public/application/maintenance_windows.tsx" + }, { "plugin": "triggersActionsUi", "path": "x-pack/plugins/triggers_actions_ui/public/application/app.tsx" @@ -1292,18 +1304,6 @@ "plugin": "triggersActionsUi", "path": "x-pack/plugins/triggers_actions_ui/public/application/connectors_app.tsx" }, - { - "plugin": "serverless", - "path": "x-pack/plugins/serverless/public/plugin.tsx" - }, - { - "plugin": "serverless", - "path": "x-pack/plugins/serverless/public/plugin.tsx" - }, - { - "plugin": "serverless", - "path": "x-pack/plugins/serverless/public/plugin.tsx" - }, { "plugin": "cases", "path": "x-pack/plugins/cases/public/application.tsx" @@ -1316,6 +1316,18 @@ "plugin": "cases", "path": "x-pack/plugins/cases/public/application.tsx" }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx" + }, { "plugin": "discover", "path": "src/plugins/discover/public/embeddable/saved_search_embeddable.tsx" @@ -1372,6 +1384,18 @@ "plugin": "exploratoryView", "path": "x-pack/plugins/exploratory_view/public/application/index.tsx" }, + { + "plugin": "observabilityAIAssistant", + "path": "x-pack/plugins/observability_ai_assistant/public/application.tsx" + }, + { + "plugin": "observabilityAIAssistant", + "path": "x-pack/plugins/observability_ai_assistant/public/application.tsx" + }, + { + "plugin": "observabilityAIAssistant", + "path": "x-pack/plugins/observability_ai_assistant/public/application.tsx" + }, { "plugin": "fleet", "path": "x-pack/plugins/fleet/public/applications/integrations/app.tsx" @@ -3634,61 +3658,13 @@ "plugin": "lens", "path": "x-pack/plugins/lens/public/trigger_actions/open_lens_config/helpers.ts" }, - { - "plugin": "@kbn/ml-date-picker", - "path": "x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content_wrapper.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content_wrapper.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_root.tsx" - }, - { - "plugin": "aiops", - "path": "x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_root.tsx" - }, { "plugin": "security", - "path": "x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx" + "path": "x-pack/plugins/security/public/account_management/account_management_app.tsx" }, { "plugin": "security", - "path": "x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx" + "path": "x-pack/plugins/security/public/account_management/account_management_app.tsx" }, { "plugin": "security", @@ -3758,6 +3734,70 @@ "plugin": "cases", "path": "x-pack/plugins/cases/public/components/visualizations/actions/add_to_existing_case.tsx" }, + { + "plugin": "@kbn/ml-date-picker", + "path": "x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/embeddable/embeddable_change_point_chart.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/embeddable/handle_explicit_input.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/embeddable/handle_explicit_input.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/log_categorization/log_categorization_app_state.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/log_categorization/show_flyout.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_app_state.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content_wrapper.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content_wrapper.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_root.tsx" + }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/components/change_point_detection/change_point_detection_root.tsx" + }, { "plugin": "observabilityShared", "path": "x-pack/plugins/observability_shared/public/components/header_menu/header_menu_portal.tsx" @@ -3992,35 +4032,35 @@ }, { "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx" + "path": "x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx" }, { "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx" + "path": "x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx" }, { "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx" + "path": "x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout.tsx" }, { "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/common/resolve_job_selection.tsx" + "path": "x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout.tsx" }, { "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_setup_flyout.tsx" + "path": "x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx" }, { "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_setup_flyout.tsx" + "path": "x-pack/plugins/ml/public/embeddables/job_creation/common/create_flyout.tsx" }, { "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout.tsx" + "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_setup_flyout.tsx" }, { "plugin": "ml", - "path": "x-pack/plugins/ml/public/embeddables/anomaly_swimlane/anomaly_swimlane_setup_flyout.tsx" + "path": "x-pack/plugins/ml/public/embeddables/anomaly_charts/anomaly_charts_setup_flyout.tsx" }, { "plugin": "ml", @@ -4138,6 +4178,14 @@ "plugin": "timelines", "path": "x-pack/plugins/timelines/public/components/hover_actions/actions/add_to_timeline.tsx" }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/take_action.tsx" + }, + { + "plugin": "cloudSecurityPosture", + "path": "x-pack/plugins/cloud_security_posture/public/components/take_action.tsx" + }, { "plugin": "runtimeFields", "path": "x-pack/plugins/runtime_fields/public/shared_imports.ts" @@ -4514,6 +4562,14 @@ "plugin": "uptime", "path": "x-pack/plugins/uptime/public/legacy_uptime/components/monitor/ml/ml_flyout_container.tsx" }, + { + "plugin": "cloudLinks", + "path": "x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx" + }, + { + "plugin": "cloudLinks", + "path": "x-pack/plugins/cloud_integrations/cloud_links/public/maybe_add_cloud_links/theme_darkmode_toggle.tsx" + }, { "plugin": "console", "path": "src/plugins/console/public/shared_imports.ts" diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index fd0b38bf12cb1..c7be1b62d86ec 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index d0010371e0fea..4dcb18805a70f 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 6f976bbdca7fa..d70815191743c 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index e33e34a0b36be..1a13adf50b509 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 0583a521ae2f9..ea90872093f0a 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 128e3d18314c0..95d2563383ae5 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.devdocs.json b/api_docs/licensing.devdocs.json index e78f38fff12e2..9e94dad897ead 100644 --- a/api_docs/licensing.devdocs.json +++ b/api_docs/licensing.devdocs.json @@ -810,6 +810,10 @@ "plugin": "security", "path": "x-pack/plugins/security/public/plugin.tsx" }, + { + "plugin": "aiops", + "path": "x-pack/plugins/aiops/public/plugin.tsx" + }, { "plugin": "licenseManagement", "path": "x-pack/plugins/license_management/public/plugin.ts" diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 98d216c70b6d6..9bdde79f8dd6f 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 0959f42b36730..e6be664391f64 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 4444e39542caf..2493ce0d839da 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 77219c568a9b9..28c2a79ba3ef0 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index 2191f1726b317..a760931ca5d51 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 4a596b8f87948..4f61e1abe3a12 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index aac94910e94b1..84fd36f31e5f5 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 1ac07084a95b9..d61214544d53b 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index b5e8501f6ebd4..f2ec25e486513 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index f0e8b14832169..5edf0c3638b1d 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index 3b494d9a2daad..4ab7b81595545 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index 8ebb28a12df00..ded2a49def137 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 60932d66f5c74..8cc7e821fa1a3 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -4371,7 +4371,7 @@ "label": "createOrUpdateIndex", "description": [], "signature": [ - "({\n index,\n mappings,\n settings,\n client,\n logger,\n}: { index: string; mappings: ", + "({\n index,\n mappings,\n client,\n logger,\n}: { index: string; mappings: ", "MappingTypeMapping", " & { date_detection?: boolean | undefined; dynamic?: ", "MappingDynamicMapping", @@ -4391,9 +4391,7 @@ "MappingSourceField", " | undefined; runtime?: ", "MappingRuntimeFields", - " | undefined; }; settings?: ", - "IndicesIndexSettings", - " | undefined; client: ", + " | undefined; }; client: ", { "pluginId": "@kbn/core-elasticsearch-server", "scope": "common", @@ -4420,7 +4418,7 @@ "id": "def-server.createOrUpdateIndex.$1", "type": "Object", "tags": [], - "label": "{\n index,\n mappings,\n settings,\n client,\n logger,\n}", + "label": "{\n index,\n mappings,\n client,\n logger,\n}", "description": [], "path": "x-pack/plugins/observability/server/utils/create_or_update_index.ts", "deprecated": false, @@ -4470,21 +4468,6 @@ "deprecated": false, "trackAdoption": false }, - { - "parentPluginId": "observability", - "id": "def-server.createOrUpdateIndex.$1.settings", - "type": "CompoundType", - "tags": [], - "label": "settings", - "description": [], - "signature": [ - "IndicesIndexSettings", - " | undefined" - ], - "path": "x-pack/plugins/observability/server/utils/create_or_update_index.ts", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "observability", "id": "def-server.createOrUpdateIndex.$1.client", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 2187ddd6940b1..0e2c22afa279d 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/actionable-observability](https://github.com/orgs/elastic/team | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 509 | 45 | 502 | 16 | +| 508 | 45 | 501 | 16 | ## Client diff --git a/api_docs/observability_a_i_assistant.devdocs.json b/api_docs/observability_a_i_assistant.devdocs.json index 6a07ae0c41f05..f2fd46f618d93 100644 --- a/api_docs/observability_a_i_assistant.devdocs.json +++ b/api_docs/observability_a_i_assistant.devdocs.json @@ -206,6 +206,17 @@ "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.Conversation.public", + "type": "boolean", + "tags": [], + "label": "public", + "description": [], + "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -240,7 +251,7 @@ "label": "message", "description": [], "signature": [ - "{ content?: string | undefined; name?: string | undefined; role: ", + "{ content?: string | undefined; name?: string | undefined; event?: string | undefined; role: ", { "pluginId": "observabilityAIAssistant", "scope": "common", @@ -248,15 +259,7 @@ "section": "def-common.MessageRole", "text": "MessageRole" }, - "; function_call?: { name: string; args?: ", - { - "pluginId": "@kbn/utility-types", - "scope": "common", - "docId": "kibKbnUtilityTypesPluginApi", - "section": "def-common.Serializable", - "text": "Serializable" - }, - "; trigger: ", + "; function_call?: { name: string; arguments?: string | undefined; trigger: ", { "pluginId": "observabilityAIAssistant", "scope": "common", @@ -280,15 +283,7 @@ "section": "def-common.MessageRole", "text": "MessageRole" }, - ".Elastic; } | undefined; data?: ", - { - "pluginId": "@kbn/utility-types", - "scope": "common", - "docId": "kibKbnUtilityTypesPluginApi", - "section": "def-common.Serializable", - "text": "Serializable" - }, - "; }" + ".Elastic; } | undefined; data?: string | undefined; }" ], "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", "deprecated": false, @@ -321,7 +316,115 @@ "label": "APIReturnType", "description": [], "signature": [ - "{ \"GET /internal/observability_ai_assistant/connectors\": { endpoint: \"GET /internal/observability_ai_assistant/connectors\"; params?: undefined; handler: ({}: ", + "{ \"POST /internal/observability_ai_assistant/functions/setup_kb\": { endpoint: \"POST /internal/observability_ai_assistant/functions/setup_kb\"; params?: undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + ") => Promise; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"POST /internal/observability_ai_assistant/functions/summarise\": { endpoint: \"POST /internal/observability_ai_assistant/functions/summarise\"; params?: ", + "TypeC", + "<{ body: ", + "TypeC", + "<{ id: ", + "StringC", + "; text: ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">; confidence: ", + "UnionC", + "<[", + "LiteralC", + "<\"low\">, ", + "LiteralC", + "<\"medium\">, ", + "LiteralC", + "<\"high\">]>; is_correction: ", + "Type", + "; public: ", + "Type", + "; }>; }> | undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + " & { params: { body: { id: string; text: ", + "Branded", + "; confidence: \"medium\" | \"high\" | \"low\"; is_correction: boolean; public: boolean; }; }; }) => Promise; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"POST /internal/observability_ai_assistant/functions/recall\": { endpoint: \"POST /internal/observability_ai_assistant/functions/recall\"; params?: ", + "TypeC", + "<{ body: ", + "TypeC", + "<{ query: ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">; }>; }> | undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + " & { params: { body: { query: ", + "Branded", + "; }; }; }) => Promise<{ entries: ", + "KnowledgeBaseEntry", + "[]; }>; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"POST /internal/observability_ai_assistant/functions/elasticsearch\": { endpoint: \"POST /internal/observability_ai_assistant/functions/elasticsearch\"; params?: ", + "TypeC", + "<{ body: ", + "IntersectionC", + "<[", + "TypeC", + "<{ method: ", + "UnionC", + "<[", + "LiteralC", + "<\"GET\">, ", + "LiteralC", + "<\"POST\">, ", + "LiteralC", + "<\"PATCH\">, ", + "LiteralC", + "<\"PUT\">, ", + "LiteralC", + "<\"DELETE\">]>; path: ", + "StringC", + "; }>, ", + "PartialC", + "<{ body: ", + "AnyC", + "; }>]>; }> | undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + " & { params: { body: { method: \"GET\" | \"DELETE\" | \"POST\" | \"PUT\" | \"PATCH\"; path: string; } & { body?: any; }; }; }) => Promise; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"GET /internal/observability_ai_assistant/connectors\": { endpoint: \"GET /internal/observability_ai_assistant/connectors\"; params?: undefined; handler: ({}: ", "ObservabilityAIAssistantRouteHandlerResources", ") => Promise<", { @@ -421,7 +524,15 @@ "StringC", "; }>; }> | undefined; handler: ({}: ", "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; }; }) => Promise; } & ", + " & { params: { path: { conversationId: string; }; }; }) => Promise<", + { + "pluginId": "observabilityAIAssistant", + "scope": "common", + "docId": "kibObservabilityAIAssistantPluginApi", + "section": "def-common.Conversation", + "text": "Conversation" + }, + ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", "TypeC", @@ -449,7 +560,21 @@ }, ", unknown>>; connectorId: ", "StringC", - "; }>; }> | undefined; handler: ({}: ", + "; functions: ", + "ArrayC", + "<", + "TypeC", + "<{ name: ", + "StringC", + "; description: ", + "StringC", + "; parameters: ", + "AnyC", + "; contexts: ", + "ArrayC", + "<", + "StringC", + ">; }>>; }>; }> | undefined; handler: ({}: ", "ObservabilityAIAssistantRouteHandlerResources", " & { params: { body: { messages: ", { @@ -459,7 +584,7 @@ "section": "def-common.Message", "text": "Message" }, - "[]; connectorId: string; }; }; }) => Promise<", + "[]; connectorId: string; functions: { name: string; description: string; parameters: any; contexts: string[]; }[]; }; }; }) => Promise<", "IncomingMessage", ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", @@ -480,7 +605,115 @@ "label": "ObservabilityAIAssistantAPIClientRequestParamsOf", "description": [], "signature": [ - "{ \"GET /internal/observability_ai_assistant/connectors\": { endpoint: \"GET /internal/observability_ai_assistant/connectors\"; params?: undefined; handler: ({}: ", + "{ \"POST /internal/observability_ai_assistant/functions/setup_kb\": { endpoint: \"POST /internal/observability_ai_assistant/functions/setup_kb\"; params?: undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + ") => Promise; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"POST /internal/observability_ai_assistant/functions/summarise\": { endpoint: \"POST /internal/observability_ai_assistant/functions/summarise\"; params?: ", + "TypeC", + "<{ body: ", + "TypeC", + "<{ id: ", + "StringC", + "; text: ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">; confidence: ", + "UnionC", + "<[", + "LiteralC", + "<\"low\">, ", + "LiteralC", + "<\"medium\">, ", + "LiteralC", + "<\"high\">]>; is_correction: ", + "Type", + "; public: ", + "Type", + "; }>; }> | undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + " & { params: { body: { id: string; text: ", + "Branded", + "; confidence: \"medium\" | \"high\" | \"low\"; is_correction: boolean; public: boolean; }; }; }) => Promise; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"POST /internal/observability_ai_assistant/functions/recall\": { endpoint: \"POST /internal/observability_ai_assistant/functions/recall\"; params?: ", + "TypeC", + "<{ body: ", + "TypeC", + "<{ query: ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">; }>; }> | undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + " & { params: { body: { query: ", + "Branded", + "; }; }; }) => Promise<{ entries: ", + "KnowledgeBaseEntry", + "[]; }>; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"POST /internal/observability_ai_assistant/functions/elasticsearch\": { endpoint: \"POST /internal/observability_ai_assistant/functions/elasticsearch\"; params?: ", + "TypeC", + "<{ body: ", + "IntersectionC", + "<[", + "TypeC", + "<{ method: ", + "UnionC", + "<[", + "LiteralC", + "<\"GET\">, ", + "LiteralC", + "<\"POST\">, ", + "LiteralC", + "<\"PATCH\">, ", + "LiteralC", + "<\"PUT\">, ", + "LiteralC", + "<\"DELETE\">]>; path: ", + "StringC", + "; }>, ", + "PartialC", + "<{ body: ", + "AnyC", + "; }>]>; }> | undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + " & { params: { body: { method: \"GET\" | \"DELETE\" | \"POST\" | \"PUT\" | \"PATCH\"; path: string; } & { body?: any; }; }; }) => Promise; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"GET /internal/observability_ai_assistant/connectors\": { endpoint: \"GET /internal/observability_ai_assistant/connectors\"; params?: undefined; handler: ({}: ", "ObservabilityAIAssistantRouteHandlerResources", ") => Promise<", { @@ -580,7 +813,15 @@ "StringC", "; }>; }> | undefined; handler: ({}: ", "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; }; }) => Promise; } & ", + " & { params: { path: { conversationId: string; }; }; }) => Promise<", + { + "pluginId": "observabilityAIAssistant", + "scope": "common", + "docId": "kibObservabilityAIAssistantPluginApi", + "section": "def-common.Conversation", + "text": "Conversation" + }, + ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", "TypeC", @@ -608,7 +849,21 @@ }, ", unknown>>; connectorId: ", "StringC", - "; }>; }> | undefined; handler: ({}: ", + "; functions: ", + "ArrayC", + "<", + "TypeC", + "<{ name: ", + "StringC", + "; description: ", + "StringC", + "; parameters: ", + "AnyC", + "; contexts: ", + "ArrayC", + "<", + "StringC", + ">; }>>; }>; }> | undefined; handler: ({}: ", "ObservabilityAIAssistantRouteHandlerResources", " & { params: { body: { messages: ", { @@ -618,7 +873,7 @@ "section": "def-common.Message", "text": "Message" }, - "[]; connectorId: string; }; }; }) => Promise<", + "[]; connectorId: string; functions: { name: string; description: string; parameters: any; contexts: string[]; }[]; }; }; }) => Promise<", "IncomingMessage", ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", @@ -647,7 +902,7 @@ "label": "ObservabilityAIAssistantAPIEndpoint", "description": [], "signature": [ - "\"POST /internal/observability_ai_assistant/chat\" | \"GET /internal/observability_ai_assistant/conversation/{conversationId}\" | \"POST /internal/observability_ai_assistant/conversations\" | \"PUT /internal/observability_ai_assistant/conversation\" | \"POST /internal/observability_ai_assistant/conversation/{conversationId}\" | \"DELETE /internal/observability_ai_assistant/conversation/{conversationId}\" | \"GET /internal/observability_ai_assistant/connectors\"" + "\"POST /internal/observability_ai_assistant/chat\" | \"GET /internal/observability_ai_assistant/conversation/{conversationId}\" | \"POST /internal/observability_ai_assistant/conversations\" | \"PUT /internal/observability_ai_assistant/conversation\" | \"POST /internal/observability_ai_assistant/conversation/{conversationId}\" | \"DELETE /internal/observability_ai_assistant/conversation/{conversationId}\" | \"GET /internal/observability_ai_assistant/connectors\" | \"POST /internal/observability_ai_assistant/functions/elasticsearch\" | \"POST /internal/observability_ai_assistant/functions/recall\" | \"POST /internal/observability_ai_assistant/functions/summarise\" | \"POST /internal/observability_ai_assistant/functions/setup_kb\"" ], "path": "x-pack/plugins/observability_ai_assistant/public/api/index.ts", "deprecated": false, @@ -691,7 +946,16321 @@ "path": "x-pack/plugins/observability_ai_assistant/public/types.ts", "deprecated": false, "trackAdoption": false, - "children": [], + "children": [ + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.registerContext", + "type": "Function", + "tags": [], + "label": "registerContext", + "description": [], + "signature": [ + "(options: ", + "ContextDefinition", + ") => void" + ], + "path": "x-pack/plugins/observability_ai_assistant/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.registerContext.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "ContextDefinition" + ], + "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.registerFunction", + "type": "Function", + "tags": [], + "label": "registerFunction", + "description": [], + "signature": [ + "(options: FunctionOptions, respond: RespondFunction, render?: RenderFunction | undefined) => void" + ], + "path": "x-pack/plugins/observability_ai_assistant/public/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.registerFunction.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "FunctionOptions" + ], + "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.registerFunction.$2", + "type": "Function", + "tags": [], + "label": "respond", + "description": [], + "signature": [ + "(options: { arguments: ", + "node_modules/ts-algebra/lib/meta-types/resolve", + "$Resolve<", + "JSONSchema7", + " extends (TParameters extends Record ? ", + "DeepWritable", + " : TParameters) ? ", + "Any", + " : (TParameters extends Record ? ", + "DeepWritable", + " : TParameters) extends string | true ? ", + "Any", + " : (TParameters extends Record ? ", + "DeepWritable", + " : TParameters) extends false ? ", + "Never", + " : (TParameters extends Record ? ", + "DeepWritable", + " : TParameters) extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends string | true ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends false ? ", + "Never", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"$ref\"], \"#\">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "JSONSchema7", + " extends Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> ? ", + "Any", + " : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends string | true ? ", + "Any", + " : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends false ? ", + "Never", + " : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "ReferenceSchema", + " ? any : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends string | true ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends false ? ", + "Never", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"$ref\"], \"#\">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "JSONSchema7", + " extends Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> ? ", + "Any", + " : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends string | true ? ", + "Any", + " : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends false ? ", + "Never", + " : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "ReferenceSchema", + " ? any : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"enum\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { ...; }> : Omit<...> extends ", + "AnyOfSchema", + " ? ", + "If", + "<...> : Omit<...> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<...> : Omit<...> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + "<...> | ... 1 more ... | ", + "ParseConstSchema", + "<...> : Omit<...> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<...> : Omit<...> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + "<...> | ... 1 more ... | ", + "ParseSingleTypeSchema", + "<...> : ", + "Any", + "<...>> | ", + "ParseNullableSchema", + "<...> : Omit<...> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<...> : Omit<...> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<...> : Omit<...> extends ", + "OneOfSchema", + " ? ", + "If", + "<...> : Omit<...> extends ", + "AnyOfSchema", + " ? ", + "If", + "<...> : Omit<...> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<...> : Omit<...> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + "<...> | ... 1 more ... | ", + "ParseConstSchema", + "<...> : Omit<...> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<...> : Omit<...> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + "<...> | ... 1 more ... | ", + "ParseSingleTypeSchema", + "<...> : ", + "Any", + "<...>> : (TParameters extends Record<...> ? ", + "DeepWritable", + "<...> : TParameters) extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<...> : (TParameters extends Record<...> ? ", + "DeepWritable", + "<...> : TParameters) extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<...> : (TParameters extends Record<...> ? ", + "DeepWritable", + "<...> : TParameters) extends ", + "OneOfSchema", + " ? ", + "If", + "<...> : (TParameters extends Record<...> ? ", + "DeepWritable", + "<...> : TParameters) extends ", + "AnyOfSchema", + " ? ", + "If", + "<...> : (TParameters extends Record<...> ? ", + "DeepWritable", + "<...> : TParameters) extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<...> : (TParameters extends Record<...> ? ", + "DeepWritable", + "<...> : TParameters) extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + "<...> | ... 1 more ... | ", + "ParseConstSchema", + "<...> : (TParameters extends Record<...> ? ", + "DeepWritable", + "<...> : TParameters) extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<...> : (TParameters extends Record<...> ? ", + "DeepWritable", + "<...> : TParameters) extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + "<...> | ... 1 more ... | ", + "ParseSingleTypeSchema", + "<...> : ", + "Any", + "<...>, ", + "ResolveDefaultOptions", + ">; }, signal: AbortSignal) => Promise<...>" + ], + "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.registerFunction.$2.$1", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "{ arguments: ", + "node_modules/ts-algebra/lib/meta-types/resolve", + "$Resolve<", + "JSONSchema7", + " extends (TParameters extends Record ? ", + "DeepWritable", + " : TParameters) ? ", + "Any", + " : (TParameters extends Record ? ", + "DeepWritable", + " : TParameters) extends string | true ? ", + "Any", + " : (TParameters extends Record ? ", + "DeepWritable", + " : TParameters) extends false ? ", + "Never", + " : (TParameters extends Record ? ", + "DeepWritable", + " : TParameters) extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends string | true ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends false ? ", + "Never", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"$ref\"], \"#\">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "MultipleTypesSchema", + " ? any : any> : any> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends string | true ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends false ? ", + "Never", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"$ref\"], \"#\">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "MultipleTypesSchema", + " ? any : any> : any> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends string | true ? ", + "Any", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends false ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "AnyOfSchema", + " ? ", + "Never", + " : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "MultipleTypesSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnMixedSchema<(", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">)[\"type\"], ", + "MultipleTypesSchema", + " & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\"> extends ", + "SingleTypeSchema", + " ? ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseSingleTypeSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { type: ", + "JSONSchema7TypeName", + "; } & Omit<", + "NullableSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : ", + "Any", + "> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"$ref\"], \"#\">> : Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "JSONSchema7", + " extends Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends string | true ? ", + "Any", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends false ? ", + "Never", + " : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "NullableSchema", + " ? ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> | ", + "ParseNullableSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { nullable: boolean; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ReferenceSchema", + " ? ", + "ParseReferenceSchema", + "<", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, RecSplit<(", + "ReferenceSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"$ref\"], \"#\">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AllOfSchema", + " ? RecurseOnAllOfSchema<(", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"allOf\"], ", + "AllOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "OneOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnOneOfSchema<(", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"oneOf\"], ", + "OneOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "AnyOfSchema", + " ? ", + "If", + "<", + "IsNever", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>>, ", + "Never", + ", ", + "DoesExtend", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>, ", + "Never", + "> extends true ? ", + "Never", + " : { type: \"union\"; values: RecurseOnAnyOfSchema<(", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"anyOf\"], ", + "AnyOfSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">, never>; }> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "EnumSchema", + " ? ", + "node_modules/ts-algebra/lib/meta-types/intersection/index", + "$Intersect<", + "If", + "<", + "IsNever", + "<", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>>, ", + "Never", + ", { type: \"enum\"; values: ", + "Compute", + "<(", + "EnumSchema", + " & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">)[\"enum\"][number], never>; isSerialized: false; deserialized: never; }>, ", + "Any", + "> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "ConstSchema", + " ? ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> | ", + "ParseConstSchema", + " & { const?: unknown; enum?: unknown; items?: ", + "JSONSchema7", + " | ", + "JSONSchema7", + "[] | undefined; additionalItems?: ", + "JSONSchema7", + " | undefined; contains?: ", + "JSONSchema7", + " | undefined; properties?: Record | undefined; patternProperties?: Record | undefined; additionalProperties?: ", + "JSONSchema7", + " | undefined; dependencies?: { [key: string]: string[] | ", + "JSONSchema7", + "; } | undefined; propertyNames?: ", + "JSONSchema7", + " | undefined; if?: ", + "JSONSchema7", + " | undefined; then?: ", + "JSONSchema7", + " | undefined; else?: ", + "JSONSchema7", + " | undefined; allOf?: ", + "JSONSchema7", + "[] | undefined; anyOf?: ", + "JSONSchema7", + "[] | undefined; oneOf?: ", + "JSONSchema7", + "[] | undefined; not?: ", + "JSONSchema7", + " | undefined; nullable?: boolean | undefined; definitions?: { [key: string]: ", + "JSONSchema7", + "; } | undefined; examples?: unknown[] | undefined; default?: unknown; [$JSONSchema7]?: typeof ", + "node_modules/json-schema-to-ts/lib/types/definitions/jsonSchema7", + "$JSONSchema7 | undefined; } & { const: unknown; } & Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\">, ", + "ParseOptions", + " ? ", + "DeepWritable", + " : TParameters, ", + "FromSchemaDefaultOptions", + ">> : Omit<", + "AllOfSchema", + " & Omit<", + "NullableSchema", + " & (TParameters extends Record ? ", + "DeepWritable", + " : TParameters), \"nullable\">, \"allOf\"> extends ", + "MultipleTypesSchema", + " ? any : any> : any> : any, ", + "ResolveDefaultOptions", + ">; }" + ], + "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.registerFunction.$2.$2", + "type": "Object", + "tags": [], + "label": "signal", + "description": [], + "signature": [ + "AbortSignal" + ], + "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-public.ObservabilityAIAssistantPluginStart.registerFunction.$3", + "type": "Function", + "tags": [], + "label": "render", + "description": [], + "signature": [ + "RenderFunction | undefined" + ], + "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], "lifecycle": "start", "initialIsOpen": true } @@ -710,7 +17279,115 @@ "label": "ObservabilityAIAssistantServerRouteRepository", "description": [], "signature": [ - "{ \"GET /internal/observability_ai_assistant/connectors\": { endpoint: \"GET /internal/observability_ai_assistant/connectors\"; params?: undefined; handler: ({}: ", + "{ \"POST /internal/observability_ai_assistant/functions/setup_kb\": { endpoint: \"POST /internal/observability_ai_assistant/functions/setup_kb\"; params?: undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + ") => Promise; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"POST /internal/observability_ai_assistant/functions/summarise\": { endpoint: \"POST /internal/observability_ai_assistant/functions/summarise\"; params?: ", + "TypeC", + "<{ body: ", + "TypeC", + "<{ id: ", + "StringC", + "; text: ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">; confidence: ", + "UnionC", + "<[", + "LiteralC", + "<\"low\">, ", + "LiteralC", + "<\"medium\">, ", + "LiteralC", + "<\"high\">]>; is_correction: ", + "Type", + "; public: ", + "Type", + "; }>; }> | undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + " & { params: { body: { id: string; text: ", + "Branded", + "; confidence: \"medium\" | \"high\" | \"low\"; is_correction: boolean; public: boolean; }; }; }) => Promise; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"POST /internal/observability_ai_assistant/functions/recall\": { endpoint: \"POST /internal/observability_ai_assistant/functions/recall\"; params?: ", + "TypeC", + "<{ body: ", + "TypeC", + "<{ query: ", + "BrandC", + "<", + "StringC", + ", ", + { + "pluginId": "@kbn/io-ts-utils", + "scope": "common", + "docId": "kibKbnIoTsUtilsPluginApi", + "section": "def-common.NonEmptyStringBrand", + "text": "NonEmptyStringBrand" + }, + ">; }>; }> | undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + " & { params: { body: { query: ", + "Branded", + "; }; }; }) => Promise<{ entries: ", + "KnowledgeBaseEntry", + "[]; }>; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"POST /internal/observability_ai_assistant/functions/elasticsearch\": { endpoint: \"POST /internal/observability_ai_assistant/functions/elasticsearch\"; params?: ", + "TypeC", + "<{ body: ", + "IntersectionC", + "<[", + "TypeC", + "<{ method: ", + "UnionC", + "<[", + "LiteralC", + "<\"GET\">, ", + "LiteralC", + "<\"POST\">, ", + "LiteralC", + "<\"PATCH\">, ", + "LiteralC", + "<\"PUT\">, ", + "LiteralC", + "<\"DELETE\">]>; path: ", + "StringC", + "; }>, ", + "PartialC", + "<{ body: ", + "AnyC", + "; }>]>; }> | undefined; handler: ({}: ", + "ObservabilityAIAssistantRouteHandlerResources", + " & { params: { body: { method: \"GET\" | \"DELETE\" | \"POST\" | \"PUT\" | \"PATCH\"; path: string; } & { body?: any; }; }; }) => Promise; } & ", + "ObservabilityAIAssistantRouteCreateOptions", + "; \"GET /internal/observability_ai_assistant/connectors\": { endpoint: \"GET /internal/observability_ai_assistant/connectors\"; params?: undefined; handler: ({}: ", "ObservabilityAIAssistantRouteHandlerResources", ") => Promise<", { @@ -810,7 +17487,15 @@ "StringC", "; }>; }> | undefined; handler: ({}: ", "ObservabilityAIAssistantRouteHandlerResources", - " & { params: { path: { conversationId: string; }; }; }) => Promise; } & ", + " & { params: { path: { conversationId: string; }; }; }) => Promise<", + { + "pluginId": "observabilityAIAssistant", + "scope": "common", + "docId": "kibObservabilityAIAssistantPluginApi", + "section": "def-common.Conversation", + "text": "Conversation" + }, + ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", "; \"POST /internal/observability_ai_assistant/chat\": { endpoint: \"POST /internal/observability_ai_assistant/chat\"; params?: ", "TypeC", @@ -838,7 +17523,21 @@ }, ", unknown>>; connectorId: ", "StringC", - "; }>; }> | undefined; handler: ({}: ", + "; functions: ", + "ArrayC", + "<", + "TypeC", + "<{ name: ", + "StringC", + "; description: ", + "StringC", + "; parameters: ", + "AnyC", + "; contexts: ", + "ArrayC", + "<", + "StringC", + ">; }>>; }>; }> | undefined; handler: ({}: ", "ObservabilityAIAssistantRouteHandlerResources", " & { params: { body: { messages: ", { @@ -848,7 +17547,7 @@ "section": "def-common.Message", "text": "Message" }, - "[]; connectorId: string; }; }; }) => Promise<", + "[]; connectorId: string; functions: { name: string; description: string; parameters: any; contexts: string[]; }[]; }; }; }) => Promise<", "IncomingMessage", ">; } & ", "ObservabilityAIAssistantRouteCreateOptions", @@ -975,6 +17674,17 @@ "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "observabilityAIAssistant", + "id": "def-common.Conversation.public", + "type": "boolean", + "tags": [], + "label": "public", + "description": [], + "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -1009,7 +17719,7 @@ "label": "message", "description": [], "signature": [ - "{ content?: string | undefined; name?: string | undefined; role: ", + "{ content?: string | undefined; name?: string | undefined; event?: string | undefined; role: ", { "pluginId": "observabilityAIAssistant", "scope": "common", @@ -1017,15 +17727,7 @@ "section": "def-common.MessageRole", "text": "MessageRole" }, - "; function_call?: { name: string; args?: ", - { - "pluginId": "@kbn/utility-types", - "scope": "common", - "docId": "kibKbnUtilityTypesPluginApi", - "section": "def-common.Serializable", - "text": "Serializable" - }, - "; trigger: ", + "; function_call?: { name: string; arguments?: string | undefined; trigger: ", { "pluginId": "observabilityAIAssistant", "scope": "common", @@ -1049,15 +17751,7 @@ "section": "def-common.MessageRole", "text": "MessageRole" }, - ".Elastic; } | undefined; data?: ", - { - "pluginId": "@kbn/utility-types", - "scope": "common", - "docId": "kibKbnUtilityTypesPluginApi", - "section": "def-common.Serializable", - "text": "Serializable" - }, - "; }" + ".Elastic; } | undefined; data?: string | undefined; }" ], "path": "x-pack/plugins/observability_ai_assistant/common/types.ts", "deprecated": false, diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index f2868024f51cb..fb04665ad7c31 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 35 | 0 | 33 | 5 | +| 45 | 0 | 43 | 7 | ## Client diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index 8499bbadd51b3..a876771d94e36 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.devdocs.json b/api_docs/observability_shared.devdocs.json index 3e93ed26a1aed..4f105830edc04 100644 --- a/api_docs/observability_shared.devdocs.json +++ b/api_docs/observability_shared.devdocs.json @@ -595,7 +595,7 @@ "label": "noCasesPermissions", "description": [], "signature": [ - "() => { all: boolean; create: boolean; read: boolean; update: boolean; delete: boolean; push: boolean; }" + "() => { all: boolean; create: boolean; read: boolean; update: boolean; delete: boolean; push: boolean; connectors: boolean; }" ], "path": "x-pack/plugins/observability_shared/public/utils/cases_permissions.ts", "deprecated": false, diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index b00388af882bc..49a91b491b06f 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 11d520ff3b5e0..a784ef7b6abfe 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 5836f5e27a50e..399e71eadb82b 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 71820 | 556 | 61367 | 1472 | +| 71867 | 556 | 61386 | 1474 | ## Plugin Directory @@ -29,14 +29,14 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] |--------------|----------------|-----------|--------------|----------|---------------|--------| | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 275 | 10 | 269 | 27 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 36 | 1 | 32 | 2 | -| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 60 | 1 | 0 | 0 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 60 | 1 | 3 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 780 | 1 | 749 | 46 | | | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 48 | 0 | 48 | 113 | | | [@elastic/infra-monitoring-ui](https://github.com/orgs/elastic/teams/infra-monitoring-ui) | Asset manager plugin for entity assets (inventory, topology, etc) | 3 | 0 | 3 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 9 | 0 | 9 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 91 | 1 | 75 | 2 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 93 | 0 | 74 | 27 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 94 | 0 | 75 | 27 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 268 | 16 | 253 | 10 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 16 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | Chat available on Elastic Cloud deployments for quicker assistance. | 3 | 0 | 2 | 0 | @@ -56,24 +56,24 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 268 | 0 | 249 | 1 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 100 | 0 | 98 | 9 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 54 | 0 | 51 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3295 | 119 | 2573 | 27 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3301 | 119 | 2575 | 27 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin provides the ability to create data views via a modal flyout inside Kibana apps | 16 | 0 | 7 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Reusable data view field editor across Kibana | 72 | 0 | 33 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data view management app | 2 | 0 | 2 | 0 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 1012 | 0 | 243 | 2 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 1024 | 0 | 246 | 2 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 31 | 3 | 25 | 1 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 12 | 0 | 10 | 3 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 78 | 0 | 51 | 15 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | discoverLogExplorer | [@elastic/infra-monitoring-ui](https://github.com/orgs/elastic/teams/infra-monitoring-ui) | This plugin exposes and registers Logs+ features. | 0 | 0 | 0 | 0 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | APIs used to assess the quality of data in Elasticsearch indexes | 2 | 0 | 0 | 0 | -| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 535 | 11 | 437 | 7 | +| | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 536 | 11 | 438 | 7 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 51 | 0 | 44 | 0 | | | [@elastic/enterprise-search-frontend](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 10 | 0 | 10 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 115 | 3 | 111 | 3 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | The Event Annotation service contains expressions for event annotations | 192 | 30 | 192 | 2 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 116 | 0 | 116 | 11 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | The Event Annotation service contains expressions for event annotations | 191 | 30 | 191 | 2 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 111 | 0 | 111 | 11 | | | [@elastic/uptime](https://github.com/orgs/elastic/teams/uptime) | - | 131 | 1 | 131 | 14 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'error' renderer to expressions | 17 | 0 | 15 | 2 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Expression Gauge plugin adds a `gauge` renderer and function to the expression plugin. The renderer will display the `gauge` chart. | 59 | 0 | 59 | 2 | @@ -132,8 +132,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 34 | 0 | 34 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 2 | 0 | 2 | 1 | -| | [@elastic/actionable-observability](https://github.com/orgs/elastic/teams/actionable-observability) | - | 509 | 45 | 502 | 16 | -| | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 35 | 0 | 33 | 5 | +| | [@elastic/actionable-observability](https://github.com/orgs/elastic/teams/actionable-observability) | - | 508 | 45 | 501 | 16 | +| | [@elastic/obs-ai-assistant](https://github.com/orgs/elastic/teams/obs-ai-assistant) | - | 45 | 0 | 43 | 7 | | | [@elastic/apm-ui](https://github.com/orgs/elastic/teams/apm-ui) | - | 14 | 0 | 14 | 0 | | | [@elastic/observability-ui](https://github.com/orgs/elastic/teams/observability-ui) | - | 277 | 1 | 276 | 11 | | | [@elastic/security-defend-workflows](https://github.com/orgs/elastic/teams/security-defend-workflows) | - | 24 | 0 | 24 | 7 | @@ -146,16 +146,16 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 264 | 0 | 235 | 14 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 24 | 0 | 19 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 129 | 2 | 118 | 4 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 44 | 0 | 44 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 154 | 0 | 140 | 2 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 25 | 0 | 25 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 161 | 0 | 147 | 2 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 79 | 0 | 73 | 3 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 100 | 0 | 52 | 1 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the definition and helper methods around saved searches, used by discover and visualizations. | 72 | 0 | 71 | 3 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 32 | 0 | 13 | 0 | | | [@elastic/kibana-reporting-services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 8 | 5 | | searchprofiler | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | -| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 277 | 0 | 89 | 4 | -| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 192 | 2 | 126 | 32 | +| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 270 | 0 | 87 | 3 | +| | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 194 | 2 | 128 | 32 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | ESS customizations for Security Solution. | 6 | 0 | 6 | 0 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | Serverless customizations for security. | 6 | 0 | 6 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | The core Serverless plugin, providing APIs to Serverless Project plugins. | 17 | 0 | 16 | 0 | @@ -178,8 +178,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 257 | 1 | 213 | 22 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [@elastic/kibana-localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | -| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 564 | 12 | 538 | 50 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Adds UI Actions service to Kibana | 144 | 2 | 102 | 9 | +| | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 570 | 12 | 544 | 50 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Adds UI Actions service to Kibana | 145 | 2 | 103 | 9 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Extends UI Actions plugin with more functionality | 206 | 0 | 140 | 9 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | The `unifiedHistogram` plugin provides UI components to create a layout including a resizable histogram and a main display. | 53 | 0 | 23 | 2 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 142 | 2 | 104 | 22 | @@ -210,8 +210,8 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | Package name           | Maintaining team | Description | API Cnt | Any Cnt | Missing
    comments | Missing
    exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 11 | 5 | 11 | 0 | -| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 30 | 0 | 6 | 1 | -| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 12 | 0 | 0 | 0 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 33 | 0 | 0 | 0 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | - | 20 | 0 | 0 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 16 | 0 | 15 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 24 | 0 | 24 | 0 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 8 | 0 | 7 | 1 | @@ -245,7 +245,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 14 | 0 | 14 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 9 | 0 | 9 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 58 | 0 | 40 | 4 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 187 | 1 | 122 | 0 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 188 | 1 | 123 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 4 | 0 | 0 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 7 | 0 | 7 | 1 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 4 | 0 | 4 | 0 | @@ -600,7 +600,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 7 | 0 | 6 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list and field stats which can be integrated into apps | 306 | 0 | 277 | 9 | | | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 4 | 0 | 0 | 0 | -| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 58 | 0 | 5 | 0 | +| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 80 | 0 | 21 | 2 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 36 | 0 | 15 | 1 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 2 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 24 | 0 | 14 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 0fe8f9a7d353e..99f4c28514e59 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 0b39ac1b4e63c..334556cc3774f 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 0ff4e46e2a510..559e1229116e7 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 112b4b29f3ae1..bc9d258b05d1d 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index f8272bfef1d9f..93d9d8abaf5e3 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 274209f68d7d7..8d5eced80baa4 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 589623de8182e..42b5675dedaa9 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index a71ec6f5e7609..272abd228e1af 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.devdocs.json b/api_docs/saved_objects_finder.devdocs.json index 9ae6255f9aefe..5de85a8979f27 100644 --- a/api_docs/saved_objects_finder.devdocs.json +++ b/api_docs/saved_objects_finder.devdocs.json @@ -11,7 +11,15 @@ "label": "getSavedObjectFinder", "description": [], "signature": [ - "(uiSettings: ", + "(contentClient: ", + { + "pluginId": "contentManagement", + "scope": "public", + "docId": "kibContentManagementPluginApi", + "section": "def-public.ContentClient", + "text": "ContentClient" + }, + ", uiSettings: ", { "pluginId": "@kbn/core-ui-settings-browser", "scope": "common", @@ -19,22 +27,6 @@ "section": "def-common.IUiSettingsClient", "text": "IUiSettingsClient" }, - ", http: ", - { - "pluginId": "@kbn/core-http-browser", - "scope": "common", - "docId": "kibKbnCoreHttpBrowserPluginApi", - "section": "def-common.HttpSetup", - "text": "HttpSetup" - }, - ", savedObjectsManagement: ", - { - "pluginId": "savedObjectsManagement", - "scope": "public", - "docId": "kibSavedObjectsManagementPluginApi", - "section": "def-public.SavedObjectsManagementPluginStart", - "text": "SavedObjectsManagementPluginStart" - }, ", savedObjectsTagging?: ", { "pluginId": "savedObjectsTaggingOss", @@ -62,15 +54,15 @@ "id": "def-public.getSavedObjectFinder.$1", "type": "Object", "tags": [], - "label": "uiSettings", + "label": "contentClient", "description": [], "signature": [ { - "pluginId": "@kbn/core-ui-settings-browser", - "scope": "common", - "docId": "kibKbnCoreUiSettingsBrowserPluginApi", - "section": "def-common.IUiSettingsClient", - "text": "IUiSettingsClient" + "pluginId": "contentManagement", + "scope": "public", + "docId": "kibContentManagementPluginApi", + "section": "def-public.ContentClient", + "text": "ContentClient" } ], "path": "src/plugins/saved_objects_finder/public/finder/index.tsx", @@ -83,15 +75,15 @@ "id": "def-public.getSavedObjectFinder.$2", "type": "Object", "tags": [], - "label": "http", + "label": "uiSettings", "description": [], "signature": [ { - "pluginId": "@kbn/core-http-browser", + "pluginId": "@kbn/core-ui-settings-browser", "scope": "common", - "docId": "kibKbnCoreHttpBrowserPluginApi", - "section": "def-common.HttpSetup", - "text": "HttpSetup" + "docId": "kibKbnCoreUiSettingsBrowserPluginApi", + "section": "def-common.IUiSettingsClient", + "text": "IUiSettingsClient" } ], "path": "src/plugins/saved_objects_finder/public/finder/index.tsx", @@ -104,27 +96,6 @@ "id": "def-public.getSavedObjectFinder.$3", "type": "Object", "tags": [], - "label": "savedObjectsManagement", - "description": [], - "signature": [ - { - "pluginId": "savedObjectsManagement", - "scope": "public", - "docId": "kibSavedObjectsManagementPluginApi", - "section": "def-public.SavedObjectsManagementPluginStart", - "text": "SavedObjectsManagementPluginStart" - } - ], - "path": "src/plugins/saved_objects_finder/public/finder/index.tsx", - "deprecated": false, - "trackAdoption": false, - "isRequired": true - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-public.getSavedObjectFinder.$4", - "type": "Object", - "tags": [], "label": "savedObjectsTagging", "description": [], "signature": [ @@ -431,29 +402,31 @@ "parentPluginId": "savedObjectsFinder", "id": "def-public.SavedObjectMetaData.includeFields", "type": "Array", - "tags": [], + "tags": [ + "deprecated" + ], "label": "includeFields", "description": [], "signature": [ "string[] | undefined" ], "path": "src/plugins/saved_objects_finder/public/finder/saved_object_finder.tsx", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-public.SavedObjectMetaData.defaultSearchField", - "type": "string", - "tags": [], - "label": "defaultSearchField", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/saved_objects_finder/public/finder/saved_object_finder.tsx", - "deprecated": false, - "trackAdoption": false + "deprecated": true, + "trackAdoption": false, + "references": [ + { + "plugin": "visualizations", + "path": "src/plugins/visualizations/public/wizard/search_selection/search_selection.tsx" + }, + { + "plugin": "visualizations", + "path": "src/plugins/visualizations/public/embeddable/visualize_embeddable_factory.tsx" + }, + { + "plugin": "graph", + "path": "x-pack/plugins/graph/public/components/source_picker.tsx" + } + ] } ], "initialIsOpen": false @@ -529,249 +502,6 @@ "path": "src/plugins/saved_objects_finder/common/types.ts", "deprecated": false, "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FinderAttributes.type", - "type": "string", - "tags": [], - "label": "type", - "description": [], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP", - "type": "Interface", - "tags": [], - "label": "FindQueryHTTP", - "description": [], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.perPage", - "type": "number", - "tags": [], - "label": "perPage", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.page", - "type": "number", - "tags": [], - "label": "page", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.type", - "type": "CompoundType", - "tags": [], - "label": "type", - "description": [], - "signature": [ - "string | string[]" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.search", - "type": "string", - "tags": [], - "label": "search", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.searchFields", - "type": "Array", - "tags": [], - "label": "searchFields", - "description": [], - "signature": [ - "string[] | undefined" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.defaultSearchOperator", - "type": "CompoundType", - "tags": [], - "label": "defaultSearchOperator", - "description": [], - "signature": [ - "\"AND\" | \"OR\" | undefined" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.sortField", - "type": "string", - "tags": [], - "label": "sortField", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.sortOrder", - "type": "CompoundType", - "tags": [], - "label": "sortOrder", - "description": [], - "signature": [ - "\"asc\" | \"desc\" | undefined" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.fields", - "type": "CompoundType", - "tags": [], - "label": "fields", - "description": [], - "signature": [ - "string | string[] | undefined" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindQueryHTTP.hasReference", - "type": "string", - "tags": [], - "label": "hasReference", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindResponseHTTP", - "type": "Interface", - "tags": [], - "label": "FindResponseHTTP", - "description": [], - "signature": [ - { - "pluginId": "savedObjectsFinder", - "scope": "common", - "docId": "kibSavedObjectsFinderPluginApi", - "section": "def-common.FindResponseHTTP", - "text": "FindResponseHTTP" - }, - "" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindResponseHTTP.saved_objects", - "type": "Array", - "tags": [], - "label": "saved_objects", - "description": [], - "signature": [ - { - "pluginId": "savedObjectsFinder", - "scope": "common", - "docId": "kibSavedObjectsFinderPluginApi", - "section": "def-common.SavedObjectCommon", - "text": "SavedObjectCommon" - }, - "[]" - ], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindResponseHTTP.total", - "type": "number", - "tags": [], - "label": "total", - "description": [], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindResponseHTTP.page", - "type": "number", - "tags": [], - "label": "page", - "description": [], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "savedObjectsFinder", - "id": "def-common.FindResponseHTTP.per_page", - "type": "number", - "tags": [], - "label": "per_page", - "description": [], - "path": "src/plugins/saved_objects_finder/common/types.ts", - "deprecated": false, - "trackAdoption": false } ], "initialIsOpen": false @@ -818,11 +548,11 @@ "description": [], "signature": [ { - "pluginId": "@kbn/core-saved-objects-common", + "pluginId": "@kbn/content-management-utils", "scope": "common", - "docId": "kibKbnCoreSavedObjectsCommonPluginApi", - "section": "def-common.SavedObject", - "text": "SavedObject" + "docId": "kibKbnContentManagementUtilsPluginApi", + "section": "def-common.SOWithMetadata", + "text": "SOWithMetadata" }, "" ], diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index e37e0a65e9f47..8d56eb66947c8 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 44 | 0 | 44 | 0 | +| 25 | 0 | 25 | 0 | ## Client diff --git a/api_docs/saved_objects_management.devdocs.json b/api_docs/saved_objects_management.devdocs.json index 44279045cfc47..958d4058e2682 100644 --- a/api_docs/saved_objects_management.devdocs.json +++ b/api_docs/saved_objects_management.devdocs.json @@ -457,6 +457,153 @@ } ], "functions": [ + { + "parentPluginId": "savedObjectsManagement", + "id": "def-public.getTagFindReferences", + "type": "Function", + "tags": [], + "label": "getTagFindReferences", + "description": [], + "signature": [ + "({ selectedTags, taggingApi, }: { selectedTags?: string[] | undefined; taggingApi?: ", + { + "pluginId": "savedObjectsTaggingOss", + "scope": "public", + "docId": "kibSavedObjectsTaggingOssPluginApi", + "section": "def-public.SavedObjectsTaggingApi", + "text": "SavedObjectsTaggingApi" + }, + " | undefined; }) => ", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-common.SavedObjectsFindOptionsReference", + "text": "SavedObjectsFindOptionsReference" + }, + "[] | undefined" + ], + "path": "src/plugins/saved_objects_management/public/lib/get_tag_references.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "savedObjectsManagement", + "id": "def-public.getTagFindReferences.$1", + "type": "Object", + "tags": [], + "label": "{\n selectedTags,\n taggingApi,\n}", + "description": [], + "path": "src/plugins/saved_objects_management/public/lib/get_tag_references.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "savedObjectsManagement", + "id": "def-public.getTagFindReferences.$1.selectedTags", + "type": "Array", + "tags": [], + "label": "selectedTags", + "description": [], + "signature": [ + "string[] | undefined" + ], + "path": "src/plugins/saved_objects_management/public/lib/get_tag_references.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "savedObjectsManagement", + "id": "def-public.getTagFindReferences.$1.taggingApi", + "type": "Object", + "tags": [], + "label": "taggingApi", + "description": [], + "signature": [ + { + "pluginId": "savedObjectsTaggingOss", + "scope": "public", + "docId": "kibSavedObjectsTaggingOssPluginApi", + "section": "def-public.SavedObjectsTaggingApi", + "text": "SavedObjectsTaggingApi" + }, + " | undefined" + ], + "path": "src/plugins/saved_objects_management/public/lib/get_tag_references.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "savedObjectsManagement", + "id": "def-public.parseQuery", + "type": "Function", + "tags": [], + "label": "parseQuery", + "description": [], + "signature": [ + "(query: ", + "Query", + ", types: ", + { + "pluginId": "savedObjectsManagement", + "scope": "common", + "docId": "kibSavedObjectsManagementPluginApi", + "section": "def-common.SavedObjectManagementTypeInfo", + "text": "SavedObjectManagementTypeInfo" + }, + "[]) => ParsedQuery" + ], + "path": "src/plugins/saved_objects_management/public/lib/parse_query.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "savedObjectsManagement", + "id": "def-public.parseQuery.$1", + "type": "Object", + "tags": [], + "label": "query", + "description": [], + "signature": [ + "Query" + ], + "path": "src/plugins/saved_objects_management/public/lib/parse_query.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "savedObjectsManagement", + "id": "def-public.parseQuery.$2", + "type": "Array", + "tags": [], + "label": "types", + "description": [], + "signature": [ + { + "pluginId": "savedObjectsManagement", + "scope": "common", + "docId": "kibSavedObjectsManagementPluginApi", + "section": "def-common.SavedObjectManagementTypeInfo", + "text": "SavedObjectManagementTypeInfo" + }, + "[]" + ], + "path": "src/plugins/saved_objects_management/public/lib/parse_query.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "savedObjectsManagement", "id": "def-public.processImportResponse", diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 2af10a0ba1a5c..d395a34dd7749 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 154 | 0 | 140 | 2 | +| 161 | 0 | 147 | 2 | ## Client diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 9453cbd5adb2c..1d089c75628e9 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 0461d38388a45..73d9712e702cb 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index e120f71b28e4b..fe238a6cb2d05 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index a2d304cc86e66..3c672d14ca80b 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 6f8e21a4b85fa..db5a6c76c83e6 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.devdocs.json b/api_docs/security.devdocs.json index 167308664bcd8..7246728a30a37 100644 --- a/api_docs/security.devdocs.json +++ b/api_docs/security.devdocs.json @@ -999,42 +999,6 @@ "deprecated": false, "trackAdoption": false, "initialIsOpen": false - }, - { - "parentPluginId": "security", - "id": "def-public.UpdateUserProfileHook", - "type": "Type", - "tags": [], - "label": "UpdateUserProfileHook", - "description": [], - "signature": [ - "(props?: Props | undefined) => { update: (data: ", - "UserProfileData", - ") => void; showSuccessNotification: (props: { isRefreshRequired: boolean; }) => void; isLoading: boolean; userProfileData?: ", - "UserProfileData", - " | null | undefined; }" - ], - "path": "x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx", - "deprecated": false, - "trackAdoption": false, - "returnComment": [], - "children": [ - { - "parentPluginId": "security", - "id": "def-public.UpdateUserProfileHook.$1", - "type": "Object", - "tags": [], - "label": "props", - "description": [], - "signature": [ - "Props | undefined" - ], - "path": "x-pack/plugins/security/public/account_management/user_profile/use_update_user_profile.tsx", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false } ], "objects": [], @@ -1163,9 +1127,21 @@ ], "signature": [ "{ update: (data: D) => Promise; suggest: (path: string, params: ", { "pluginId": "security", @@ -1183,7 +1159,13 @@ "text": "UserProfile" }, "[]>; bulkGet: (params: ", { "pluginId": "security", @@ -1201,7 +1183,13 @@ "text": "UserProfile" }, "[]>; getCurrent: (params?: ", { "pluginId": "security", @@ -1221,32 +1209,14 @@ ">; readonly userProfile$: ", "Observable", "<", - "UserProfileData", - " | null>; }" - ], - "path": "x-pack/plugins/security/public/plugin.tsx", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-public.SecurityPluginStart.hooks", - "type": "Object", - "tags": [], - "label": "hooks", - "description": [ - "\nA set of hooks to work with Kibana user profiles" - ], - "signature": [ - "{ useUpdateUserProfile: ", { - "pluginId": "security", - "scope": "public", - "docId": "kibSecurityPluginApi", - "section": "def-public.UpdateUserProfileHook", - "text": "UpdateUserProfileHook" + "pluginId": "@kbn/user-profile-components", + "scope": "common", + "docId": "kibKbnUserProfileComponentsPluginApi", + "section": "def-common.UserProfileData", + "text": "UserProfileData" }, - "; }" + " | null>; }" ], "path": "x-pack/plugins/security/public/plugin.tsx", "deprecated": false, @@ -4849,70 +4819,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "security", - "id": "def-common.UserProfileAvatarData", - "type": "Interface", - "tags": [], - "label": "UserProfileAvatarData", - "description": [ - "\nAvatar stored in user profile." - ], - "path": "x-pack/plugins/security/common/model/user_profile.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "security", - "id": "def-common.UserProfileAvatarData.initials", - "type": "string", - "tags": [], - "label": "initials", - "description": [ - "\nOptional initials (two letters) of the user to use as avatar if avatar picture isn't specified." - ], - "signature": [ - "string | undefined" - ], - "path": "x-pack/plugins/security/common/model/user_profile.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.UserProfileAvatarData.color", - "type": "string", - "tags": [], - "label": "color", - "description": [ - "\nBackground color of the avatar when initials are used." - ], - "signature": [ - "string | undefined" - ], - "path": "x-pack/plugins/security/common/model/user_profile.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.UserProfileAvatarData.imageUrl", - "type": "CompoundType", - "tags": [], - "label": "imageUrl", - "description": [ - "\nBase64 data URL for the user avatar image." - ], - "signature": [ - "string | null | undefined" - ], - "path": "x-pack/plugins/security/common/model/user_profile.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "security", "id": "def-common.UserProfileUserInfo", diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 292adb907ed5c..c11d842bd6a54 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 277 | 0 | 89 | 4 | +| 270 | 0 | 87 | 3 | ## Client diff --git a/api_docs/security_solution.devdocs.json b/api_docs/security_solution.devdocs.json index c662e145879ef..62ef5e036ebbd 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -698,6 +698,46 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.UpsellingService.getSectionsValue", + "type": "Function", + "tags": [], + "label": "getSectionsValue", + "description": [], + "signature": [ + "() => Map<", + { + "pluginId": "securitySolution", + "scope": "public", + "docId": "kibSecuritySolutionPluginApi", + "section": "def-public.UpsellingSectionId", + "text": "UpsellingSectionId" + }, + ", React.ComponentType<{}>>" + ], + "path": "x-pack/plugins/security_solution/public/common/lib/upsellings/upselling_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + }, + { + "parentPluginId": "securitySolution", + "id": "def-public.UpsellingService.getMessagesValue", + "type": "Function", + "tags": [], + "label": "getMessagesValue", + "description": [], + "signature": [ + "() => Map<\"investigation_guide\", string>" + ], + "path": "x-pack/plugins/security_solution/public/common/lib/upsellings/upselling_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false @@ -2045,7 +2085,7 @@ "label": "SectionUpsellings", "description": [], "signature": [ - "{ entity_analytics_panel?: React.ComponentType<{}> | undefined; endpointPolicyProtections?: React.ComponentType<{}> | undefined; }" + "{ entity_analytics_panel?: React.ComponentType<{}> | undefined; endpointPolicyProtections?: React.ComponentType<{}> | undefined; osquery_automated_response_actions?: React.ComponentType<{}> | undefined; }" ], "path": "x-pack/plugins/security_solution/public/common/lib/upsellings/types.ts", "deprecated": false, @@ -2060,7 +2100,7 @@ "label": "UpsellingSectionId", "description": [], "signature": [ - "\"entity_analytics_panel\" | \"endpointPolicyProtections\"" + "\"entity_analytics_panel\" | \"endpointPolicyProtections\" | \"osquery_automated_response_actions\"" ], "path": "x-pack/plugins/security_solution/public/common/lib/upsellings/types.ts", "deprecated": false, diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index c64f8c3f50052..90c9f0ff7cde5 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/security-solution](https://github.com/orgs/elastic/teams/secur | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 192 | 2 | 126 | 32 | +| 194 | 2 | 128 | 32 | ## Client diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index a9739d6975107..021a68466fba6 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index ba832361ce496..01b4591d7d5cb 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 459fdbaba17f1..d74013cbdb736 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index 5f07e440f3f62..3754e22fb88fa 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index d0d3c45b346be..d47db0b6fd0fd 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 36c1c386fe626..6253d454a38f7 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index dd82b7a7820c6..a0434ac17a210 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index f8ab5e8b4628b..0a17014d3618b 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index 53d46e39ab72c..2c72ab3b89813 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 7e05dfd474d7a..c7554bc62fcf2 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index 0bf6d4874a9a8..86bf629608c0a 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 868d29e007c8f..31642e5fbb806 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index 746ecac6f05e1..d8cc15b0e578c 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 0c6166a26328a..d6f986fc4a44c 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index ade3334eb49c2..40cb64ab84f17 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index b0ee09e8d8339..450979f04eccb 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 5caa041d59d6d..eed262ea515d7 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index e134dec835ed6..34122a05b3b95 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index a8e4b3b5a20f8..63d40f7edeff2 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 4d0f82ab99596..4b2f1c6453716 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index 2c72f5d31c911..4e3966581d22a 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -450,6 +450,112 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.executeAction", + "type": "Function", + "tags": [], + "label": "executeAction", + "description": [], + "signature": [ + "({\n id,\n params,\n http,\n signal,\n}: { id: string; http: ", + { + "pluginId": "@kbn/core-http-browser", + "scope": "common", + "docId": "kibKbnCoreHttpBrowserPluginApi", + "section": "def-common.HttpSetup", + "text": "HttpSetup" + }, + "; params: Record; signal?: AbortSignal | undefined; }) => Promise<", + { + "pluginId": "actions", + "scope": "common", + "docId": "kibActionsPluginApi", + "section": "def-common.ActionTypeExecutorResult", + "text": "ActionTypeExecutorResult" + }, + ">" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/execute.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.executeAction.$1", + "type": "Object", + "tags": [], + "label": "{\n id,\n params,\n http,\n signal,\n}", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/execute.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.executeAction.$1.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/execute.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.executeAction.$1.http", + "type": "Object", + "tags": [], + "label": "http", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-http-browser", + "scope": "common", + "docId": "kibKbnCoreHttpBrowserPluginApi", + "section": "def-common.HttpSetup", + "text": "HttpSetup" + } + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/execute.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.executeAction.$1.params", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "{ [x: string]: unknown; }" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/execute.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "triggersActionsUi", + "id": "def-public.executeAction.$1.signal", + "type": "Object", + "tags": [], + "label": "signal", + "description": [], + "signature": [ + "AbortSignal | undefined" + ], + "path": "x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api/execute.ts", + "deprecated": false, + "trackAdoption": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "triggersActionsUi", "id": "def-public.ForLastExpression", @@ -1429,7 +1535,7 @@ "label": "TextAreaWithMessageVariables", "description": [], "signature": [ - "({ messageVariables, paramsProperty, index, inputTargetValue, isDisabled, editAction, label, errors, }: React.PropsWithChildren) => JSX.Element" + "({ messageVariables, paramsProperty, index, inputTargetValue, isDisabled, editAction, label, errors, helpText, }: React.PropsWithChildren) => JSX.Element" ], "path": "x-pack/plugins/triggers_actions_ui/public/application/components/text_area_with_message_variables.tsx", "deprecated": false, @@ -1440,7 +1546,7 @@ "id": "def-public.TextAreaWithMessageVariables.$1", "type": "CompoundType", "tags": [], - "label": "{\n messageVariables,\n paramsProperty,\n index,\n inputTargetValue,\n isDisabled = false,\n editAction,\n label,\n errors,\n}", + "label": "{\n messageVariables,\n paramsProperty,\n index,\n inputTargetValue,\n isDisabled = false,\n editAction,\n label,\n errors,\n helpText,\n}", "description": [], "signature": [ "React.PropsWithChildren" diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index 9eafa3e8da610..84aba97cc4adc 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-o | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 564 | 12 | 538 | 50 | +| 570 | 12 | 544 | 50 | ## Client diff --git a/api_docs/ui_actions.devdocs.json b/api_docs/ui_actions.devdocs.json index 1335ccf655813..466038b9bb162 100644 --- a/api_docs/ui_actions.devdocs.json +++ b/api_docs/ui_actions.devdocs.json @@ -2241,6 +2241,27 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "uiActions", + "id": "def-public.VisualizeFieldContext.textBasedColumns", + "type": "Array", + "tags": [], + "label": "textBasedColumns", + "description": [], + "signature": [ + { + "pluginId": "expressions", + "scope": "common", + "docId": "kibExpressionsPluginApi", + "section": "def-common.DatatableColumn", + "text": "DatatableColumn" + }, + "[] | undefined" + ], + "path": "src/plugins/ui_actions/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "uiActions", "id": "def-public.VisualizeFieldContext.originatingApp", diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 01c5f50bac220..7cff9e38c01dc 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 144 | 2 | 102 | 9 | +| 145 | 2 | 103 | 9 | ## Client diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 3e22d68385fce..a574e50b1282b 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 3da5d56294975..e38231b65f207 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 03e9d55385d40..578b5f8165084 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 153cbbc053047..a352625e3e118 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/uptime.mdx b/api_docs/uptime.mdx index aeaf31dc6c99d..00c541219be11 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uptime'] --- import uptimeObj from './uptime.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 8d3fab6cb85b4..c0c067bb5ea27 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index a87f8530bd772..48e4afa5a952c 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 41ba7d449fded..cec241a512ef1 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index a0b85ee1fcbae..0f3ccf018e385 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index cf0915fb30f3c..c3b18a05c609f 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index b474cae15bc68..75a89ea4a40eb 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 5bc15be9f7c0f..5699386716742 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index 7643ddfaae90e..73ddb8d102d73 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index d7fc9723f84a0..4185e8265e10c 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index fe7f2cd1a24a0..c7f07b1d5229a 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index 925862995104a..e58e86f88b3ab 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 68339735ba1b9..2e8de9a940af1 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index c44837021f0c4..5df7d900f783c 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 7b2d1ab51cdeb..aeefc7168a6e5 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-08-08 +date: 2023-08-10 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; From 072ad967fc04e2b79bf75fd9e6618f3bf0e46b9f Mon Sep 17 00:00:00 2001 From: Dzmitry Lemechko Date: Thu, 10 Aug 2023 09:17:12 +0200 Subject: [PATCH 36/41] [FTR] unskip tsvb time series tests for Chrome (#163510) ## Summary Related to #162995 This PR unskip TSVB tests for Chrome browser since it is proved to be stable https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2836 100x passed https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2835 100x passed On Firefox the flakiness is related to Terms 2nd aggregation field sometimes is not selected. I tested it manually in Firefox 116 and was able to set fields, though I have a feeling that values are not always selected on click in the drop-down. But I didn't see any errors in console. I also returned back retry for dropdown selection I removed in #161202 though flaky-test-runner proves there is no need. Let's have just to keep logic as before my PR. --- .../visualize/group5/_tsvb_time_series.ts | 6 ++-- .../page_objects/visual_builder_page.ts | 29 ++++++++++++------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/test/functional/apps/visualize/group5/_tsvb_time_series.ts b/test/functional/apps/visualize/group5/_tsvb_time_series.ts index 28aa95ad24263..eec30c52018a7 100644 --- a/test/functional/apps/visualize/group5/_tsvb_time_series.ts +++ b/test/functional/apps/visualize/group5/_tsvb_time_series.ts @@ -23,8 +23,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const browser = getService('browser'); const kibanaServer = getService('kibanaServer'); - // Failing: See https://github.com/elastic/kibana/issues/162995 - describe.skip('visual builder', function describeIndexTests() { + describe('visual builder', function describeIndexTests() { before(async () => { await security.testUser.setRoles([ 'kibana_admin', @@ -167,7 +166,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); - describe('Clicking on the chart', () => { + describe('Clicking on the chart', function () { + this.tags('skipFirefox'); const act = async (visName: string, clickCoordinates: { x: number; y: number }) => { await testSubjects.click('visualizeSaveButton'); diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index 67a8dd42b9ec1..4c5939f728f01 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -7,7 +7,6 @@ */ import type { DebugState } from '@elastic/charts'; -import expect from '@kbn/expect'; import { FtrService } from '../ftr_provider_context'; import { WebElementWrapper } from '../services/lib/web_element_wrapper'; @@ -845,10 +844,14 @@ export class VisualBuilderPageObject extends FtrService { ) { await this.setMetricsGroupBy('terms'); await this.common.sleep(1000); - const byField = await this.testSubjects.find('groupByField'); - await this.comboBox.setElement(byField, field); - const isSelected = await this.comboBox.isOptionSelected(byField, field); - expect(isSelected).to.be(true); + await this.retry.try(async () => { + const byField = await this.testSubjects.find('groupByField'); + await this.comboBox.setElement(byField, field); + const isSelected = await this.comboBox.isOptionSelected(byField, field); + if (!isSelected) { + throw new Error(`setMetricsGroupByTerms: failed to set '${field}' field`); + } + }); await this.setMetricsGroupByFiltering(filtering.include, filtering.exclude); } @@ -860,13 +863,17 @@ export class VisualBuilderPageObject extends FtrService { // In case of StaleElementReferenceError 'browser' service will try to find element again await fieldSelectAddButtonLast.click(); await this.common.sleep(2000); - const selectedByField = await this.find.byXPath( - `(//*[@data-test-subj='fieldSelectItem'])[last()]` - ); - await this.comboBox.setElement(selectedByField, field); - const isSelected = await this.comboBox.isOptionSelected(selectedByField, field); - expect(isSelected).to.be(true); + await this.retry.try(async () => { + const selectedByField = await this.find.byXPath( + `(//*[@data-test-subj='fieldSelectItem'])[last()]` + ); + await this.comboBox.setElement(selectedByField, field); + const isSelected = await this.comboBox.isOptionSelected(selectedByField, field); + if (!isSelected) { + throw new Error(`setAnotherGroupByTermsField: failed to set '${field}' field`); + } + }); } public async setMetricsGroupByFiltering(include?: string, exclude?: string) { From 5e0e4487b8da8a9b21844acb4e688065c00d3fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loix?= Date: Thu, 10 Aug 2023 09:08:22 +0100 Subject: [PATCH 37/41] [Serverless Chrome] Fix fullscreen (#163317) --- .../src/utils/append_app_path.ts | 2 +- .../src/chrome_service.test.tsx | 19 +++++++ .../src/chrome_service.tsx | 52 ++++++++++++++++++- .../components/flyout/pane/index.tsx | 5 +- 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/packages/core/application/core-application-browser-internal/src/utils/append_app_path.ts b/packages/core/application/core-application-browser-internal/src/utils/append_app_path.ts index 575e1f10a553e..afcdbfb18196a 100644 --- a/packages/core/application/core-application-browser-internal/src/utils/append_app_path.ts +++ b/packages/core/application/core-application-browser-internal/src/utils/append_app_path.ts @@ -8,7 +8,7 @@ import { removeSlashes } from './remove_slashes'; -export const appendAppPath = (appBasePath: string, path: string = '') => { +export const appendAppPath = (appBasePath = '', path: string = '') => { // Only prepend slash if not a hash or query path path = path === '' || path.startsWith('#') || path.startsWith('?') ? path : `/${path}`; // Do not remove trailing slash when in hashbang or basePath diff --git a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.test.tsx b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.test.tsx index d8e409cad2e09..ad7c6d8fc52a5 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.test.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.test.tsx @@ -158,6 +158,7 @@ describe('start', () => { ] `); }); + it('strips off "snapshot" from the kibana version if present', async () => { const { chrome, service } = await start({ options: { browserSupportsCsp: false, kibanaVersion: '8.0.0-SnAPshot' }, @@ -339,6 +340,24 @@ describe('start', () => { ] `); }); + + it('change visibility when EUI component in full screen', async () => { + const body = document.body; + const startDeps = defaultStartDeps([new FakeApp('foo')], 'foo'); + const { chrome } = await start({ startDeps }); + + // Chrome is initially visible + let isVisible = await Rx.lastValueFrom(chrome.getIsVisible$().pipe(Rx.take(1))); + expect(isVisible).toBe(true); + + // Add EUI class that should hide the chrome + body.classList.add('euiDataGrid__restrictBody'); + await new Promise((resolve) => setTimeout(resolve)); // wait next tick + + // Chrome should be hidden + isVisible = await Rx.lastValueFrom(chrome.getIsVisible$().pipe(Rx.take(1))); + expect(isVisible).toBe(false); + }); }); describe('badge', () => { diff --git a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx index 0b575e4a0f215..76fef465d823c 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx @@ -79,6 +79,7 @@ export class ChromeService { private readonly recentlyAccessed = new RecentlyAccessedService(); private readonly docTitle = new DocTitleService(); private readonly projectNavigation = new ProjectNavigationService(); + private mutationObserver: MutationObserver | undefined; constructor(private readonly params: ConstructorParams) {} @@ -114,6 +115,53 @@ export class ChromeService { ); } + private setIsVisible = (isVisible: boolean) => this.isForceHidden$.next(!isVisible); + + /** + * Some EUI component can be toggled in Full screen (e.g. the EuiDataGrid). When they are toggled in full + * screen we want to hide the chrome, and when they are toggled back to normal we want to show the chrome. + */ + private handleEuiFullScreenChanges = () => { + const { body } = document; + // HTML class names that are added to the body when Eui components are toggled in full screen + const classesOnBodyWhenEuiFullScreen = ['euiDataGrid__restrictBody']; + + let isChromeHiddenForEuiFullScreen = false; + let isChromeVisible = false; + + this.isVisible$.pipe(takeUntil(this.stop$)).subscribe((isVisible) => { + isChromeVisible = isVisible; + }); + + const onBodyClassesChange = () => { + const { className } = body; + if ( + classesOnBodyWhenEuiFullScreen.some((name) => className.includes(name)) && + isChromeVisible + ) { + isChromeHiddenForEuiFullScreen = true; + this.setIsVisible(false); + } else if ( + classesOnBodyWhenEuiFullScreen.every((name) => !className.includes(name)) && + !isChromeVisible && + isChromeHiddenForEuiFullScreen + ) { + isChromeHiddenForEuiFullScreen = false; + this.setIsVisible(true); + } + }; + + this.mutationObserver = new MutationObserver((mutationList) => { + mutationList.forEach((mutation) => { + if (mutation.type === 'attributes' && mutation.attributeName === 'class') { + onBodyClassesChange(); + } + }); + }); + + this.mutationObserver.observe(body, { attributes: true }); + }; + public setup({ analytics }: SetupDeps) { const docTitle = this.docTitle.setup({ document: window.document }); registerAnalyticsContextProvider(analytics, docTitle.title$); @@ -128,6 +176,7 @@ export class ChromeService { customBranding, }: StartDeps): Promise { this.initVisibility(application); + this.handleEuiFullScreenChanges(); const globalHelpExtensionMenuLinks$ = new BehaviorSubject( [] @@ -379,7 +428,7 @@ export class ChromeService { getIsVisible$: () => this.isVisible$, - setIsVisible: (isVisible: boolean) => this.isForceHidden$.next(!isVisible), + setIsVisible: this.setIsVisible.bind(this), getBadge$: () => badge$.pipe(takeUntil(this.stop$)), @@ -463,5 +512,6 @@ export class ChromeService { this.navLinks.stop(); this.projectNavigation.stop(); this.stop$.next(); + this.mutationObserver?.disconnect(); } } diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx index cf00693623c43..d3007d0d6346a 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/pane/index.tsx @@ -46,8 +46,9 @@ const FlyoutPaneComponent: React.FC = ({ data-test-subj="timeline-flyout" css={css` min-width: 150px; - height: calc(100% - 96px); - top: 96px; + height: 100%; + top: 0; + left: 0; background: ${useEuiBackgroundColor('plain')}; position: fixed; width: 100%; From 5c57df27ed448150634f26198e7d29b36e5a197e Mon Sep 17 00:00:00 2001 From: Maxim Kholod Date: Thu, 10 Aug 2023 10:18:43 +0200 Subject: [PATCH 38/41] [Cloud Security] Do not filter vulnerabilities by CVE (#163402) ## Summary `{ match_phrase: { 'vulnerability.enumeration': 'CVE' } }` has been removed from the vulnerabilities filter so that documents from other sources are presented in CNVM features fixes: - https://github.com/elastic/security-team/issues/7287 ## Screenshots This is how CNVM features look like with GHSA data Screenshot 2023-08-08 at 15 47 10 Screenshot 2023-08-08 at 15 46 59 --- x-pack/plugins/cloud_security_posture/common/constants.ts | 2 -- .../common/utils/get_safe_vulnerabilities_query_filter.ts | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index 91d42c2544191..058b23e3477a5 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -123,5 +123,3 @@ export const VULNERABILITIES_SEVERITY: Record = { CRITICAL: 'CRITICAL', UNKNOWN: 'UNKNOWN', }; - -export const VULNERABILITIES_ENUMERATION = 'CVE'; diff --git a/x-pack/plugins/cloud_security_posture/common/utils/get_safe_vulnerabilities_query_filter.ts b/x-pack/plugins/cloud_security_posture/common/utils/get_safe_vulnerabilities_query_filter.ts index 5cbbf6dd054a7..fb2bbd1c51273 100644 --- a/x-pack/plugins/cloud_security_posture/common/utils/get_safe_vulnerabilities_query_filter.ts +++ b/x-pack/plugins/cloud_security_posture/common/utils/get_safe_vulnerabilities_query_filter.ts @@ -5,7 +5,7 @@ * 2.0. */ import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types'; -import { VULNERABILITIES_ENUMERATION, VULNERABILITIES_SEVERITY } from '../constants'; +import { VULNERABILITIES_SEVERITY } from '../constants'; export const getSafeVulnerabilitiesQueryFilter = (query?: QueryDslQueryContainer) => ({ ...query, @@ -29,7 +29,6 @@ export const getSafeVulnerabilitiesQueryFilter = (query?: QueryDslQueryContainer { exists: { field: 'vulnerability.severity' } }, { exists: { field: 'resource.id' } }, { exists: { field: 'resource.name' } }, - { match_phrase: { 'vulnerability.enumeration': VULNERABILITIES_ENUMERATION } }, ], }, }); From c8b1d983fb4dc9cfb4bd2d97088adf69bfa8e49e Mon Sep 17 00:00:00 2001 From: Ievgen Sorokopud Date: Thu, 10 Aug 2023 10:50:42 +0200 Subject: [PATCH 39/41] [Security Solution] Flaky ML rule execution tests (#163095) ## Summary Original ticket: https://github.com/elastic/kibana/issues/145776 Un-skip ML rule execution flaky tests. Currently these tests are failing due to these ML APIs changes (API versioning) https://github.com/elastic/kibana/pull/156949 --- .../rule_execution_logic/machine_learning.ts | 3 +-- .../utils/machine_learning_setup.ts | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/machine_learning.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/machine_learning.ts index be0d4876b59af..9450c32210009 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/machine_learning.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/rule_execution_logic/machine_learning.ts @@ -66,8 +66,7 @@ export default ({ getService }: FtrProviderContext) => { rule_id: 'ml-rule-id', }; - // FLAKY: https://github.com/elastic/kibana/issues/145776 - describe.skip('Machine learning type rules', () => { + describe('Machine learning type rules', () => { before(async () => { // Order is critical here: auditbeat data must be loaded before attempting to start the ML job, // as the job looks for certain indices on start diff --git a/x-pack/test/detection_engine_api_integration/utils/machine_learning_setup.ts b/x-pack/test/detection_engine_api_integration/utils/machine_learning_setup.ts index 84eeeea137cb0..47b870496642b 100644 --- a/x-pack/test/detection_engine_api_integration/utils/machine_learning_setup.ts +++ b/x-pack/test/detection_engine_api_integration/utils/machine_learning_setup.ts @@ -6,6 +6,7 @@ */ import type SuperTest from 'supertest'; +import { getCommonRequestHeader } from '../../functional/services/ml/common_api'; export const executeSetupModuleRequest = async ({ module, @@ -18,7 +19,7 @@ export const executeSetupModuleRequest = async ({ }) => { const { body } = await supertest .post(`/internal/ml/modules/setup/${module}`) - .set('kbn-xsrf', 'true') + .set(getCommonRequestHeader('1')) .send({ prefix: '', groups: ['auditbeat'], @@ -42,8 +43,8 @@ export const forceStartDatafeeds = async ({ supertest: SuperTest.SuperTest; }) => { const { body } = await supertest - .post(`/supertest/ml/jobs/force_start_datafeeds`) - .set('kbn-xsrf', 'true') + .post(`/internal/ml/jobs/force_start_datafeeds`) + .set(getCommonRequestHeader('1')) .send({ datafeedIds: [`datafeed-${jobId}`], start: new Date().getUTCMilliseconds(), From dba141320b204d4bb5229a928e084ff9861a10a9 Mon Sep 17 00:00:00 2001 From: Antonio Date: Thu, 10 Aug 2023 11:05:10 +0200 Subject: [PATCH 40/41] [Cases] Fix Host Isolation user action flaky test (#163508) Fixes #156742 ## Summary Most of this test's logic was about how this specific comment type is rendered. There was already some logic from the flaky test duplicated in `x-pack/plugins/cases/public/components/user_actions/comment/comment.test.tsx`. I moved the rest of the flaky test logic there. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../user_actions/comment/comment.test.tsx | 70 ++++++++++++++----- .../components/user_actions/index.test.tsx | 57 +-------------- 2 files changed, 52 insertions(+), 75 deletions(-) diff --git a/x-pack/plugins/cases/public/components/user_actions/comment/comment.test.tsx b/x-pack/plugins/cases/public/components/user_actions/comment/comment.test.tsx index 77d38e87a2c41..bab441edbe80c 100644 --- a/x-pack/plugins/cases/public/components/user_actions/comment/comment.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/comment/comment.test.tsx @@ -587,28 +587,60 @@ describe('createCommentUserActionBuilder', () => { }); }); - it('renders correctly an action', async () => { - const userAction = getHostIsolationUserAction(); - - const builder = createCommentUserActionBuilder({ - ...builderArgs, - caseData: { - ...builderArgs.caseData, - comments: [hostIsolationComment()], - }, - userAction, + describe('Host isolation action', () => { + it('renders correctly an action', async () => { + const userAction = getHostIsolationUserAction(); + + const builder = createCommentUserActionBuilder({ + ...builderArgs, + caseData: { + ...builderArgs.caseData, + comments: [hostIsolationComment()], + }, + userAction, + }); + + const createdUserAction = builder.build(); + render( + + + + ); + + expect(screen.getByTestId('endpoint-action')).toBeInTheDocument(); + expect(screen.getByText('submitted isolate request on host')).toBeInTheDocument(); + expect(screen.getByText('host1')).toBeInTheDocument(); + expect(screen.getByText('I just isolated the host!')).toBeInTheDocument(); }); - const createdUserAction = builder.build(); - render( - - - - ); + it('shows the correct username', async () => { + const createdBy = { profileUid: userProfiles[0].uid }; + const userAction = getHostIsolationUserAction({ + createdBy, + }); - expect(screen.getByText('submitted isolate request on host')).toBeInTheDocument(); - expect(screen.getByText('host1')).toBeInTheDocument(); - expect(screen.getByText('I just isolated the host!')).toBeInTheDocument(); + const builder = createCommentUserActionBuilder({ + ...builderArgs, + caseData: { + ...builderArgs.caseData, + comments: [hostIsolationComment({ createdBy })], + }, + userAction, + }); + + const createdUserAction = builder.build(); + render( + + + + ); + + expect( + screen.getAllByTestId('case-user-profile-avatar-damaged_raccoon')[0] + ).toBeInTheDocument(); + expect(screen.getAllByText('DR')[0]).toBeInTheDocument(); + expect(screen.getAllByText('Damaged Raccoon')[0]).toBeInTheDocument(); + }); }); describe('Attachment framework', () => { diff --git a/x-pack/plugins/cases/public/components/user_actions/index.test.tsx b/x-pack/plugins/cases/public/components/user_actions/index.test.tsx index 15c2a8661edb0..4530e115a2f04 100644 --- a/x-pack/plugins/cases/public/components/user_actions/index.test.tsx +++ b/x-pack/plugins/cases/public/components/user_actions/index.test.tsx @@ -13,18 +13,11 @@ import { waitForEuiPopoverOpen } from '@elastic/eui/lib/test/rtl'; import routeData from 'react-router'; import { useUpdateComment } from '../../containers/use_update_comment'; -import { - basicCase, - caseUserActions, - getHostIsolationUserAction, - getUserAction, - hostIsolationComment, -} from '../../containers/mock'; +import { basicCase, caseUserActions, getUserAction } from '../../containers/mock'; import { UserActions } from '.'; import type { AppMockRenderer } from '../../common/mock'; import { createAppMockRenderer } from '../../common/mock'; import { UserActionActions } from '../../../common/types/domain'; -import { userProfiles, userProfilesMap } from '../../containers/user_profiles/api.mock'; import { getCaseConnectorsMockResponse } from '../../common/mock/connectors'; import type { UserActivityParams } from '../user_actions_activity_bar/types'; import { useFindCaseUserActions } from '../../containers/use_find_case_user_actions'; @@ -325,52 +318,4 @@ describe.skip(`UserActions`, () => { expect(screen.getAllByTestId('add-comment')[1].textContent).toContain(newComment); }); }); - - // FLAKY: https://github.com/elastic/kibana/issues/156742 - describe.skip('Host isolation action', () => { - it('renders in the cases details view', async () => { - const isolateAction = [getHostIsolationUserAction()]; - const props = { - ...defaultProps, - data: { ...defaultProps.data, comments: [...basicCase.comments, hostIsolationComment()] }, - }; - - useFindCaseUserActionsMock.mockReturnValue({ - ...defaultUseFindCaseUserActions, - data: { userActions: isolateAction }, - }); - - appMockRender.render(); - await waitFor(() => { - expect(screen.getByTestId('endpoint-action')).toBeInTheDocument(); - }); - }); - - it('shows the correct username', async () => { - const isolateAction = [ - getHostIsolationUserAction({ createdBy: { profileUid: userProfiles[0].uid } }), - ]; - const props = { - ...defaultProps, - userProfiles: userProfilesMap, - data: { - ...defaultProps.data, - comments: [hostIsolationComment({ createdBy: { profileUid: userProfiles[0].uid } })], - }, - }; - - useFindCaseUserActionsMock.mockReturnValue({ - ...defaultUseFindCaseUserActions, - data: { userActions: isolateAction }, - }); - - appMockRender.render(); - - expect( - screen.getAllByTestId('case-user-profile-avatar-damaged_raccoon')[0] - ).toBeInTheDocument(); - expect(screen.getAllByText('DR')[0]).toBeInTheDocument(); - expect(screen.getAllByText('Damaged Raccoon')[0]).toBeInTheDocument(); - }); - }); }); From 92d4a6df7dcbf832c29cbea7939cb0f69355239f Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Thu, 10 Aug 2023 12:11:58 +0300 Subject: [PATCH 41/41] [ML] Add a throughput description in the Deployment stats table (#163481) ## Summary Resolves #161828 Adds a tooltip for the Throughput column explaining units. image ### Checklist - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [x] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [x] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [x] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --- .../nodes_overview/allocated_models.tsx | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/ml/public/application/memory_usage/nodes_overview/allocated_models.tsx b/x-pack/plugins/ml/public/application/memory_usage/nodes_overview/allocated_models.tsx index 5cdc922824ae7..02738f3bebe51 100644 --- a/x-pack/plugins/ml/public/application/memory_usage/nodes_overview/allocated_models.tsx +++ b/x-pack/plugins/ml/public/application/memory_usage/nodes_overview/allocated_models.tsx @@ -122,13 +122,27 @@ export const AllocatedModels: FC = ({ }, }, { - field: 'node.throughput_last_minute', - name: i18n.translate( - 'xpack.ml.trainedModels.nodesList.modelsList.throughputLastMinuteHeader', - { - defaultMessage: 'Throughput', - } + name: ( + + + {i18n.translate( + 'xpack.ml.trainedModels.nodesList.modelsList.throughputLastMinuteHeader', + { + defaultMessage: 'Throughput', + } + )} + + + ), + field: 'node.throughput_last_minute', width: '100px', truncateText: false, 'data-test-subj': 'mlAllocatedModelsTableThroughput',