-
Notifications
You must be signed in to change notification settings - Fork 8.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[core/ui] bootstrap the legacy platform within the new platform #20699
Changes from 4 commits
97c86a3
a7fd8fb
bb73252
0a8dcec
f1a698e
9984fa5
6624b58
e514979
4f8fe21
5357110
3c71d11
b662c4d
277f273
e404fa4
cc1d8f0
2151adf
04af61a
9c76bfb
3073159
450e6b1
5a5210b
675f032
7ec434b
33a74af
3e5a2ab
e6c5c0b
0ec8793
794ae2c
fad92a0
7442290
4567aed
4f9f64d
874029c
c210fef
7a4987f
5b0edf1
9710387
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
// import global polyfills before everything else | ||
import 'babel-polyfill'; | ||
import 'custom-event-polyfill'; | ||
import 'whatwg-fetch'; | ||
|
||
import { InjectedMetadata, InjectedMetadataService } from './injected_metadata'; | ||
import { LegacyPlatformService } from './legacy_platform'; | ||
|
||
interface CoreSystemParams { | ||
injectedMetadataForTesting?: InjectedMetadata; | ||
bootstrapLegacyPlatform: () => void; | ||
} | ||
|
||
export class CoreSystem { | ||
private injectedMetadata: InjectedMetadataService; | ||
private legacyPlatform: LegacyPlatformService; | ||
|
||
constructor(params: CoreSystemParams) { | ||
const { injectedMetadataForTesting, bootstrapLegacyPlatform } = params; | ||
|
||
this.injectedMetadata = new InjectedMetadataService(injectedMetadataForTesting); | ||
this.legacyPlatform = new LegacyPlatformService(bootstrapLegacyPlatform); | ||
} | ||
|
||
public start() { | ||
this.legacyPlatform.start({ | ||
injectedMetadata: this.injectedMetadata.start(), | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
export { CoreSystem } from './core_system'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
type Freezable = { [k: string]: any } | ArrayLike<any>; | ||
|
||
type RecursiveReadOnly<T> = T extends Freezable | ||
? Readonly<{ [K in keyof T]: RecursiveReadOnly<T[K]> }> | ||
: T; | ||
|
||
export function deepFreeze<T extends Freezable>(object: T) { | ||
// for any properties that reference an object, makes sure that object is | ||
// recursively frozen as well | ||
for (const value of Object.values(object)) { | ||
if (value !== null && typeof value === 'object') { | ||
deepFreeze(value); | ||
} | ||
} | ||
|
||
return Object.freeze(object) as RecursiveReadOnly<T>; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
export { InjectedMetadata, InjectedMetadataService } from './injected_metadata_service'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,33 +17,27 @@ | |
* under the License. | ||
*/ | ||
|
||
import sinon from 'sinon'; | ||
import expect from 'expect.js'; | ||
import { deepFreeze } from './deep_freeze'; | ||
import { readInjectedMetadataFromDom } from './read_injected_metadata_from_dom'; | ||
|
||
import { appEntryTemplate } from '../app_entry_template'; | ||
|
||
function createMockBundle() { | ||
return { | ||
getContext: sinon.stub().returns(''), | ||
getRequires: sinon.stub().returns([]) | ||
export interface InjectedMetadata { | ||
legacyMetadata: { | ||
[key: string]: any; | ||
}; | ||
} | ||
|
||
describe('ui bundles / appEntryTemplate', () => { | ||
it('embeds bundle.getContext() result', () => { | ||
const bundle = createMockBundle(); | ||
bundle.getContext.returns('foo bar baz'); | ||
expect(appEntryTemplate(bundle)).to.contain('foo bar baz'); | ||
}); | ||
export class InjectedMetadataService { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: could you please add a top level comment for this service as well? |
||
constructor(private injectedMetadataForTesting?: InjectedMetadata) {} | ||
|
||
public start() { | ||
const state = deepFreeze( | ||
this.injectedMetadataForTesting || (readInjectedMetadataFromDom() as InjectedMetadata) | ||
); | ||
|
||
it('joins requires into list', () => { | ||
const bundle = createMockBundle(); | ||
const requires = [ | ||
'foo', | ||
'bar', | ||
'baz' | ||
]; | ||
bundle.getRequires.returns(requires); | ||
expect(appEntryTemplate(bundle)).to.contain(requires.join('\n')); | ||
}); | ||
}); | ||
return { | ||
getLegacyMetadata() { | ||
return state.legacyMetadata; | ||
}, | ||
}; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
export function readInjectedMetadataFromDom() { | ||
const el = document.querySelector('kbn-injected-metadata'); | ||
|
||
if (!el) { | ||
throw new Error('unable to find <kbn-injected-metadata> element'); | ||
} | ||
|
||
const json = el.getAttribute('data'); | ||
if (!json) { | ||
throw new Error('<kbn-injected-metadata> does not have a data atttibute'); | ||
} | ||
|
||
return JSON.parse(json); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
export { LegacyPlatformService } from './legacy_platform_service'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: there is no need to change anything in this PR, just wondering if we should put all legacy related public stuff into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd be fine renaming the |
||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
|
||
import { InjectedMetadataService } from '../injected_metadata'; | ||
|
||
interface Deps { | ||
injectedMetadata: ReturnType<InjectedMetadataService['start']>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm really not sure what to name this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
export class LegacyPlatformService { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: same note about top level comment here as well. We can add these comments in the following PRs if you want though. |
||
constructor(private bootstrapLegacyPlatform: () => void) {} | ||
|
||
public start({ injectedMetadata }: Deps) { | ||
/** | ||
* Injects parts of the new platform into parts of the legacy platform | ||
* so that legacy APIs/modules can mimic their new platform counterparts | ||
*/ | ||
require('ui/metadata').__newPlatformInit__(injectedMetadata.getLegacyMetadata()); | ||
|
||
// call the legacy platform bootstrap function (bootstraps ui/chrome in apps and ui/test_harness in browser tests) | ||
this.bootstrapLegacyPlatform(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,8 +17,6 @@ | |
* under the License. | ||
*/ | ||
|
||
import { union } from 'lodash'; | ||
|
||
import { fromRoot } from '../../utils'; | ||
|
||
import findSourceFiles from './find_source_files'; | ||
|
@@ -36,7 +34,7 @@ export default (kibana) => { | |
|
||
uiExports: { | ||
async __bundleProvider__(kbnServer) { | ||
let modules = []; | ||
const modules = []; | ||
|
||
const { | ||
config, | ||
|
@@ -66,8 +64,8 @@ export default (kibana) => { | |
|
||
// add the modules from all of this plugins apps | ||
for (const app of uiApps) { | ||
if (app.getPluginId() === pluginId) { | ||
modules = union(modules, app.getModules()); | ||
if (app.getPluginId() === pluginId && !modules.includes(app.getMainModuleId())) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. optional nit: if we use |
||
modules.push(app.getMainModuleId()); | ||
} | ||
} | ||
|
||
|
@@ -76,7 +74,9 @@ export default (kibana) => { | |
} else { | ||
// add the modules from all of the apps | ||
for (const app of uiApps) { | ||
modules = union(modules, app.getModules()); | ||
if (!modules.includes(app.getMainModuleId())) { | ||
modules.push(app.getMainModuleId()); | ||
} | ||
} | ||
|
||
for (const plugin of plugins) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: would be really great if you can add a top level comment for
CoreSystem
explaining what its role and what it's supposed to do.