Serve static assets from NP (#60490)
* add hapi.inert plugin to NP * update tests * move serving static assets * update tests * add functional tests * fix type errors. Hapi.Request doesn't support typings for payload * update docs * remove comment * move assets to NP * update all assets references * address Spencer's comments * move ui settings migration to migration examples * document legacy plugin spec * move platform assets test to integration_tests * address Spencer's comment p.2 * try to fix type errors * fix merge commit * update tests
|
@ -65,7 +65,7 @@
|
|||
"uiFramework:documentComponent": "cd packages/kbn-ui-framework && yarn documentComponent",
|
||||
"kbn:watch": "node scripts/kibana --dev --logging.json=false",
|
||||
"build:types": "tsc --p tsconfig.types.json",
|
||||
"docs:acceptApiChanges": "node scripts/check_published_api_changes.js --accept",
|
||||
"docs:acceptApiChanges": "node --max-old-space-size=6144 scripts/check_published_api_changes.js --accept",
|
||||
"kbn:bootstrap": "yarn build:types && node scripts/register_git_hook",
|
||||
"spec_to_console": "node scripts/spec_to_console",
|
||||
"backport-skip-ci": "backport --prDescription \"[skip-ci]\"",
|
||||
|
@ -330,11 +330,13 @@
|
|||
"@types/glob": "^7.1.1",
|
||||
"@types/globby": "^8.0.0",
|
||||
"@types/graphql": "^0.13.2",
|
||||
"@types/h2o2": "^8.1.1",
|
||||
"@types/hapi": "^17.0.18",
|
||||
"@types/hapi-auth-cookie": "^9.1.0",
|
||||
"@types/has-ansi": "^3.0.0",
|
||||
"@types/history": "^4.7.3",
|
||||
"@types/hoek": "^4.1.3",
|
||||
"@types/inert": "^5.1.2",
|
||||
"@types/jest": "24.0.19",
|
||||
"@types/joi": "^13.4.2",
|
||||
"@types/jquery": "^3.3.31",
|
||||
|
|
|
@ -131,12 +131,21 @@ export function getWebpackConfig(bundle: Bundle, worker: WorkerConfig) {
|
|||
loader: 'resolve-url-loader',
|
||||
options: {
|
||||
join: (_: string, __: any) => (uri: string, base?: string) => {
|
||||
if (!base) {
|
||||
// apply only to legacy platform styles
|
||||
if (!base || !parseDirPath(base).dirs.includes('legacy')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (uri.startsWith('ui/assets')) {
|
||||
return Path.resolve(
|
||||
worker.repoRoot,
|
||||
'src/core/server/core_app/',
|
||||
uri.replace('ui/', '')
|
||||
);
|
||||
}
|
||||
|
||||
// manually force ui/* urls in legacy styles to resolve to ui/legacy/public
|
||||
if (uri.startsWith('ui/') && parseDirPath(base).dirs.includes('legacy')) {
|
||||
if (uri.startsWith('ui/')) {
|
||||
return Path.resolve(
|
||||
worker.repoRoot,
|
||||
'src/legacy/ui/public',
|
||||
|
|
|
@ -22,5 +22,5 @@ const path = require('path');
|
|||
|
||||
// Extend the Storybook Middleware to include a route to access Legacy UI assets
|
||||
module.exports = function(router) {
|
||||
router.get('/ui', serve(path.resolve(__dirname, '../../../../src/legacy/ui/public/assets')));
|
||||
router.get('/ui', serve(path.resolve(__dirname, '../../../src/core/server/core_app/assets')));
|
||||
};
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
- [Core services](#core-services-1)
|
||||
- [Plugin services](#plugin-services)
|
||||
- [UI Exports](#ui-exports)
|
||||
- [Plugin Spec](#plugin-spec)
|
||||
- [How to](#how-to)
|
||||
- [Configure plugin](#configure-plugin)
|
||||
- [Handle plugin configuration deprecations](#handle-plugin-configuration-deprecations)
|
||||
|
@ -1264,40 +1265,19 @@ This table shows where these uiExports have moved to in the New Platform. In mos
|
|||
| `visTypes` | `plugins.visualizations.types` | |
|
||||
| `visualize` | | |
|
||||
|
||||
Examples:
|
||||
|
||||
- **uiSettingDefaults**
|
||||
|
||||
Before:
|
||||
|
||||
```js
|
||||
uiExports: {
|
||||
uiSettingDefaults: {
|
||||
'my-plugin:my-setting': {
|
||||
name: 'just-work',
|
||||
value: true,
|
||||
description: 'make it work',
|
||||
category: ['my-category'],
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```ts
|
||||
// src/plugins/my-plugin/server/plugin.ts
|
||||
setup(core: CoreSetup){
|
||||
core.uiSettings.register({
|
||||
'my-plugin:my-setting': {
|
||||
name: 'just-work',
|
||||
value: true,
|
||||
description: 'make it work',
|
||||
category: ['my-category'],
|
||||
},
|
||||
})
|
||||
}
|
||||
```
|
||||
#### Plugin Spec
|
||||
| Legacy Platform | New Platform |
|
||||
| ----------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| `id` | [`manifest.id`](/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md) |
|
||||
| `require` | [`manifest.requiredPlugins`](/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md) |
|
||||
| `version` | [`manifest.version`](/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md) |
|
||||
| `kibanaVersion` | [`manifest.kibanaVersion`](/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md) |
|
||||
| `configPrefix` | [`manifest.configPath`](/docs/development/core/server/kibana-plugin-core-server.pluginmanifest.md) |
|
||||
| `config` | [export config](#configure-plugin) |
|
||||
| `deprecations` | [export config](#handle-plugin-configuration-deprecations) |
|
||||
| `uiExports` | `N/A`. Use platform & plugin public contracts |
|
||||
| `publicDir` | `N/A`. Platform serves static assets from `/public/assets` folder under `/plugins/{id}/assets/{path*}` URL. |
|
||||
| `preInit`, `init`, `postInit` | `N/A`. Use NP [lifecycle events](#services) |
|
||||
|
||||
## How to
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ APIs to their New Platform equivalents.
|
|||
- [Chromeless Applications](#chromeless-applications)
|
||||
- [Render HTML Content](#render-html-content)
|
||||
- [Saved Objects types](#saved-objects-types)
|
||||
- [UiSettings](#uisettings)
|
||||
|
||||
## Configuration
|
||||
|
||||
|
@ -975,4 +976,37 @@ const migration: SavedObjectMigrationFn = (doc, { log }) => {...}
|
|||
|
||||
The `registerType` API will throw if called after the service has started, and therefor cannot be used from
|
||||
legacy plugin code. Legacy plugins should use the legacy savedObjects service and the legacy way to register
|
||||
saved object types until migrated.
|
||||
saved object types until migrated.
|
||||
|
||||
## UiSettings
|
||||
UiSettings defaults registration performed during `setup` phase via `core.uiSettings.register` API.
|
||||
|
||||
```js
|
||||
// Before:
|
||||
uiExports: {
|
||||
uiSettingDefaults: {
|
||||
'my-plugin:my-setting': {
|
||||
name: 'just-work',
|
||||
value: true,
|
||||
description: 'make it work',
|
||||
category: ['my-category'],
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ts
|
||||
// After:
|
||||
// src/plugins/my-plugin/server/plugin.ts
|
||||
setup(core: CoreSetup){
|
||||
core.uiSettings.register({
|
||||
'my-plugin:my-setting': {
|
||||
name: 'just-work',
|
||||
value: true,
|
||||
description: 'make it work',
|
||||
category: ['my-category'],
|
||||
schema: schema.boolean(),
|
||||
},
|
||||
})
|
||||
}
|
||||
```
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 9 KiB After Width: | Height: | Size: 9 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 773 B After Width: | Height: | Size: 773 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -16,6 +16,9 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import Path from 'path';
|
||||
import { fromRoot } from '../../../core/server/utils';
|
||||
|
||||
import { InternalCoreSetup } from '../internal_types';
|
||||
import { CoreContext } from '../core_context';
|
||||
import { Logger } from '../logging';
|
||||
|
@ -29,6 +32,7 @@ export class CoreApp {
|
|||
setup(coreSetup: InternalCoreSetup) {
|
||||
this.logger.debug('Setting up core app.');
|
||||
this.registerDefaultRoutes(coreSetup);
|
||||
this.registerStaticDirs(coreSetup);
|
||||
}
|
||||
|
||||
private registerDefaultRoutes(coreSetup: InternalCoreSetup) {
|
||||
|
@ -49,4 +53,12 @@ export class CoreApp {
|
|||
res.ok({ body: { version: '0.0.1' } })
|
||||
);
|
||||
}
|
||||
private registerStaticDirs(coreSetup: InternalCoreSetup) {
|
||||
coreSetup.http.registerStaticDir('/ui/{path*}', Path.resolve(__dirname, './assets'));
|
||||
|
||||
coreSetup.http.registerStaticDir(
|
||||
'/node_modules/@kbn/ui-framework/dist/{path*}',
|
||||
fromRoot('node_modules/@kbn/ui-framework/dist')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 * as kbnTestServer from '../../../../test_utils/kbn_server';
|
||||
import { Root } from '../../root';
|
||||
|
||||
describe('Platform assets', function() {
|
||||
let root: Root;
|
||||
|
||||
beforeAll(async function() {
|
||||
root = kbnTestServer.createRoot();
|
||||
|
||||
await root.setup();
|
||||
await root.start();
|
||||
});
|
||||
|
||||
afterAll(async function() {
|
||||
await root.shutdown();
|
||||
});
|
||||
|
||||
it('exposes static assets', async () => {
|
||||
await kbnTestServer.request.get(root, '/ui/favicons/favicon.ico').expect(200);
|
||||
});
|
||||
|
||||
it('returns 404 if not found', async function() {
|
||||
await kbnTestServer.request.get(root, '/ui/favicons/not-a-favicon.ico').expect(404);
|
||||
});
|
||||
|
||||
it('does not expose folder content', async function() {
|
||||
await kbnTestServer.request.get(root, '/ui/favicons/').expect(403);
|
||||
});
|
||||
|
||||
it('does not allow file tree traversing', async function() {
|
||||
await kbnTestServer.request.get(root, '/ui/../../../../../README.md').expect(404);
|
||||
});
|
||||
});
|
|
@ -23,6 +23,7 @@ import { Agent as HttpsAgent, ServerOptions as TlsOptions } from 'https';
|
|||
import apm from 'elastic-apm-node';
|
||||
import { ByteSizeValue } from '@kbn/config-schema';
|
||||
import { Server, Request, ResponseToolkit } from 'hapi';
|
||||
import HapiProxy from 'h2o2';
|
||||
import { sample } from 'lodash';
|
||||
import BrowserslistUserAgent from 'browserslist-useragent';
|
||||
import * as Rx from 'rxjs';
|
||||
|
@ -102,7 +103,7 @@ export class BasePathProxyServer {
|
|||
|
||||
// Register hapi plugin that adds proxying functionality. It can be configured
|
||||
// through the route configuration object (see { handler: { proxy: ... } }).
|
||||
await this.server.register({ plugin: require('h2o2') });
|
||||
await this.server.register([HapiProxy]);
|
||||
|
||||
if (this.httpConfig.ssl.enabled) {
|
||||
const tlsOptions = serverOptions.tls as TlsOptions;
|
||||
|
@ -166,7 +167,8 @@ export class BasePathProxyServer {
|
|||
host: this.server.info.host,
|
||||
passThrough: true,
|
||||
port: this.devConfig.basePathProxyTargetPort,
|
||||
protocol: this.server.info.protocol,
|
||||
// typings mismatch. h2o2 doesn't support "socket"
|
||||
protocol: this.server.info.protocol as HapiProxy.ProxyHandlerOptions['protocol'],
|
||||
xforward: true,
|
||||
},
|
||||
},
|
||||
|
@ -195,7 +197,7 @@ export class BasePathProxyServer {
|
|||
agent: this.httpsAgent,
|
||||
passThrough: true,
|
||||
xforward: true,
|
||||
mapUri: (request: Request) => ({
|
||||
mapUri: async (request: Request) => ({
|
||||
uri: Url.format({
|
||||
hostname: request.server.info.host,
|
||||
port: this.devConfig.basePathProxyTargetPort,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
import { Server } from 'hapi';
|
||||
import HapiStaticFiles from 'inert';
|
||||
import url from 'url';
|
||||
|
||||
import { Logger, LoggerFactory } from '../logging';
|
||||
|
@ -44,6 +45,7 @@ export interface HttpServerSetup {
|
|||
* @param router {@link IRouter} - a router with registered route handlers.
|
||||
*/
|
||||
registerRouter: (router: IRouter) => void;
|
||||
registerStaticDir: (path: string, dirPath: string) => void;
|
||||
basePath: HttpServiceSetup['basePath'];
|
||||
csp: HttpServiceSetup['csp'];
|
||||
createCookieSessionStorageFactory: HttpServiceSetup['createCookieSessionStorageFactory'];
|
||||
|
@ -97,10 +99,11 @@ export class HttpServer {
|
|||
this.registeredRouters.add(router);
|
||||
}
|
||||
|
||||
public setup(config: HttpConfig): HttpServerSetup {
|
||||
public async setup(config: HttpConfig): Promise<HttpServerSetup> {
|
||||
const serverOptions = getServerOptions(config);
|
||||
const listenerOptions = getListenerOptions(config);
|
||||
this.server = createServer(serverOptions, listenerOptions);
|
||||
await this.server.register([HapiStaticFiles]);
|
||||
this.config = config;
|
||||
|
||||
const basePathService = new BasePath(config.basePath);
|
||||
|
@ -109,6 +112,7 @@ export class HttpServer {
|
|||
|
||||
return {
|
||||
registerRouter: this.registerRouter.bind(this),
|
||||
registerStaticDir: this.registerStaticDir.bind(this),
|
||||
registerOnPreAuth: this.registerOnPreAuth.bind(this),
|
||||
registerOnPostAuth: this.registerOnPostAuth.bind(this),
|
||||
registerOnPreResponse: this.registerOnPreResponse.bind(this),
|
||||
|
@ -339,4 +343,23 @@ export class HttpServer {
|
|||
return t.next({ headers: authResponseHeaders });
|
||||
});
|
||||
}
|
||||
|
||||
private registerStaticDir(path: string, dirPath: string) {
|
||||
if (this.server === undefined) {
|
||||
throw new Error('Http server is not setup up yet');
|
||||
}
|
||||
|
||||
this.server.route({
|
||||
path,
|
||||
method: 'GET',
|
||||
handler: {
|
||||
directory: {
|
||||
path: dirPath,
|
||||
listing: false,
|
||||
lookupCompressed: true,
|
||||
},
|
||||
},
|
||||
options: { auth: false },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ const createSetupContractMock = () => {
|
|||
registerRouteHandlerContext: jest.fn(),
|
||||
registerOnPreResponse: jest.fn(),
|
||||
createRouter: jest.fn().mockImplementation(() => mockRouter.create({})),
|
||||
registerStaticDir: jest.fn(),
|
||||
basePath: createBasePathMock(),
|
||||
csp: CspConfig.DEFAULT,
|
||||
auth: createAuthMock(),
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
|
||||
jest.mock('fs', () => ({
|
||||
// Hapi Inert patches native methods
|
||||
...jest.requireActual('fs'),
|
||||
readFileSync: jest.fn(),
|
||||
}));
|
||||
|
||||
|
|
|
@ -265,6 +265,7 @@ export interface InternalHttpServiceSetup
|
|||
auth: HttpServerSetup['auth'];
|
||||
server: HttpServerSetup['server'];
|
||||
createRouter: (path: string, plugin?: PluginOpaqueId) => IRouter;
|
||||
registerStaticDir: (path: string, dirPath: string) => void;
|
||||
getAuthHeaders: GetAuthHeaders;
|
||||
registerRouteHandlerContext: <T extends keyof RequestHandlerContext>(
|
||||
pluginOpaqueId: PluginOpaqueId,
|
||||
|
|
|
@ -91,7 +91,15 @@ beforeEach(() => {
|
|||
contracts: new Map([['plugin-id', 'plugin-value']]),
|
||||
uiPlugins: {
|
||||
public: new Map([['plugin-id', {} as DiscoveredPlugin]]),
|
||||
internal: new Map([['plugin-id', { publicTargetDir: 'path/to/target/public' }]]),
|
||||
internal: new Map([
|
||||
[
|
||||
'plugin-id',
|
||||
{
|
||||
publicTargetDir: 'path/to/target/public',
|
||||
publicAssetsDir: '/plugins/name/assets/',
|
||||
},
|
||||
],
|
||||
]),
|
||||
browserConfigs: new Map(),
|
||||
},
|
||||
},
|
||||
|
|
|
@ -334,6 +334,9 @@ export class LegacyService implements CoreService {
|
|||
plugins: startDeps.plugins,
|
||||
},
|
||||
__internals: {
|
||||
http: {
|
||||
registerStaticDir: setupDeps.core.http.registerStaticDir,
|
||||
},
|
||||
hapiServer: setupDeps.core.http.server,
|
||||
kibanaMigrator: startDeps.core.savedObjects.migrator,
|
||||
uiPlugins: setupDeps.core.plugins.uiPlugins,
|
||||
|
|
|
@ -540,13 +540,15 @@ describe('PluginsService', () => {
|
|||
it('includes disabled plugins', async () => {
|
||||
config$.next({ plugins: { initialize: true }, plugin1: { enabled: false } });
|
||||
await pluginsService.discover();
|
||||
const { uiPlugins } = await pluginsService.setup({} as any);
|
||||
const { uiPlugins } = await pluginsService.setup(setupDeps);
|
||||
expect(uiPlugins.internal).toMatchInlineSnapshot(`
|
||||
Map {
|
||||
"plugin-1" => Object {
|
||||
"publicAssetsDir": <absolute path>/path-1/public/assets,
|
||||
"publicTargetDir": <absolute path>/path-1/target/public,
|
||||
},
|
||||
"plugin-2" => Object {
|
||||
"publicAssetsDir": <absolute path>/path-2/public/assets,
|
||||
"publicTargetDir": <absolute path>/path-2/target/public,
|
||||
},
|
||||
}
|
||||
|
@ -558,7 +560,7 @@ describe('PluginsService', () => {
|
|||
it('does initialize if plugins.initialize is true', async () => {
|
||||
config$.next({ plugins: { initialize: true } });
|
||||
await pluginsService.discover();
|
||||
const { initialized } = await pluginsService.setup({} as any);
|
||||
const { initialized } = await pluginsService.setup(setupDeps);
|
||||
expect(mockPluginSystem.setupPlugins).toHaveBeenCalled();
|
||||
expect(initialized).toBe(true);
|
||||
});
|
||||
|
@ -566,7 +568,7 @@ describe('PluginsService', () => {
|
|||
it('does not initialize if plugins.initialize is false', async () => {
|
||||
config$.next({ plugins: { initialize: false } });
|
||||
await pluginsService.discover();
|
||||
const { initialized } = await pluginsService.setup({} as any);
|
||||
const { initialized } = await pluginsService.setup(setupDeps);
|
||||
expect(mockPluginSystem.setupPlugins).not.toHaveBeenCalled();
|
||||
expect(initialized).toBe(false);
|
||||
});
|
||||
|
|
|
@ -110,6 +110,7 @@ export class PluginsService implements CoreService<PluginsServiceSetup, PluginsS
|
|||
const initialize = config.initialize && !this.coreContext.env.isDevClusterMaster;
|
||||
if (initialize) {
|
||||
contracts = await this.pluginsSystem.setupPlugins(deps);
|
||||
this.registerPluginStaticDirs(deps);
|
||||
} else {
|
||||
this.log.info('Plugin initialization disabled.');
|
||||
}
|
||||
|
@ -223,6 +224,7 @@ export class PluginsService implements CoreService<PluginsServiceSetup, PluginsS
|
|||
if (plugin.includesUiPlugin) {
|
||||
this.uiPluginInternalInfo.set(plugin.name, {
|
||||
publicTargetDir: Path.resolve(plugin.path, 'target/public'),
|
||||
publicAssetsDir: Path.resolve(plugin.path, 'public/assets'),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -262,4 +264,13 @@ export class PluginsService implements CoreService<PluginsServiceSetup, PluginsS
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
private registerPluginStaticDirs(deps: PluginsServiceSetupDeps) {
|
||||
for (const [pluginName, pluginInfo] of this.uiPluginInternalInfo) {
|
||||
deps.http.registerStaticDir(
|
||||
`/plugins/${pluginName}/assets/{path*}`,
|
||||
pluginInfo.publicAssetsDir
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,6 +194,10 @@ export interface InternalPluginInfo {
|
|||
* served
|
||||
*/
|
||||
readonly publicTargetDir: string;
|
||||
/**
|
||||
* Path to the plugin assets directory.
|
||||
*/
|
||||
readonly publicAssetsDir: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2350,8 +2350,8 @@ export const validBodyOutput: readonly ["data", "stream"];
|
|||
// src/core/server/legacy/types.ts:165:3 - (ae-forgotten-export) The symbol "LegacyAppSpec" needs to be exported by the entry point index.d.ts
|
||||
// src/core/server/legacy/types.ts:166:16 - (ae-forgotten-export) The symbol "LegacyPluginSpec" needs to be exported by the entry point index.d.ts
|
||||
// src/core/server/plugins/plugins_service.ts:47:5 - (ae-forgotten-export) The symbol "InternalPluginInfo" needs to be exported by the entry point index.d.ts
|
||||
// src/core/server/plugins/types.ts:226:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
|
||||
// src/core/server/plugins/types.ts:226:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
|
||||
// src/core/server/plugins/types.ts:228:3 - (ae-forgotten-export) The symbol "PathConfigType" needs to be exported by the entry point index.d.ts
|
||||
// src/core/server/plugins/types.ts:230:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts
|
||||
// src/core/server/plugins/types.ts:230:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts
|
||||
// src/core/server/plugins/types.ts:232:3 - (ae-forgotten-export) The symbol "PathConfigType" needs to be exported by the entry point index.d.ts
|
||||
|
||||
```
|
||||
|
|
|
@ -41,7 +41,7 @@ export const IGNORE_FILE_GLOBS = [
|
|||
'**/.*',
|
||||
'**/{webpackShims,__mocks__}/**/*',
|
||||
'x-pack/docs/**/*',
|
||||
'src/legacy/ui/public/assets/fonts/**/*',
|
||||
'src/core/server/core_app/assets/fonts/**/*',
|
||||
'packages/kbn-utility-types/test-d/**/*',
|
||||
'**/Jenkinsfile*',
|
||||
'Dockerfile*',
|
||||
|
@ -123,18 +123,18 @@ export const TEMPORARILY_IGNORED_PATHS = [
|
|||
'src/legacy/core_plugins/timelion/server/series_functions/__tests__/fixtures/tlConfig.js',
|
||||
'src/fixtures/config_upgrade_from_4.0.0_to_4.0.1-snapshot.json',
|
||||
'src/legacy/core_plugins/vis_type_vislib/public/vislib/__tests__/lib/fixtures/mock_data/terms/_seriesMultiple.js',
|
||||
'src/legacy/ui/public/assets/favicons/android-chrome-192x192.png',
|
||||
'src/legacy/ui/public/assets/favicons/android-chrome-256x256.png',
|
||||
'src/legacy/ui/public/assets/favicons/android-chrome-512x512.png',
|
||||
'src/legacy/ui/public/assets/favicons/apple-touch-icon.png',
|
||||
'src/legacy/ui/public/assets/favicons/favicon-16x16.png',
|
||||
'src/legacy/ui/public/assets/favicons/favicon-32x32.png',
|
||||
'src/legacy/ui/public/assets/favicons/mstile-70x70.png',
|
||||
'src/legacy/ui/public/assets/favicons/mstile-144x144.png',
|
||||
'src/legacy/ui/public/assets/favicons/mstile-150x150.png',
|
||||
'src/legacy/ui/public/assets/favicons/mstile-310x150.png',
|
||||
'src/legacy/ui/public/assets/favicons/mstile-310x310.png',
|
||||
'src/legacy/ui/public/assets/favicons/safari-pinned-tab.svg',
|
||||
'src/core/server/core_app/assets/favicons/android-chrome-192x192.png',
|
||||
'src/core/server/core_app/assets/favicons/android-chrome-256x256.png',
|
||||
'src/core/server/core_app/assets/favicons/android-chrome-512x512.png',
|
||||
'src/core/server/core_app/assets/favicons/apple-touch-icon.png',
|
||||
'src/core/server/core_app/assets/favicons/favicon-16x16.png',
|
||||
'src/core/server/core_app/assets/favicons/favicon-32x32.png',
|
||||
'src/core/server/core_app/assets/favicons/mstile-70x70.png',
|
||||
'src/core/server/core_app/assets/favicons/mstile-144x144.png',
|
||||
'src/core/server/core_app/assets/favicons/mstile-150x150.png',
|
||||
'src/core/server/core_app/assets/favicons/mstile-310x150.png',
|
||||
'src/core/server/core_app/assets/favicons/mstile-310x310.png',
|
||||
'src/core/server/core_app/assets/favicons/safari-pinned-tab.svg',
|
||||
'src/legacy/ui/public/styles/bootstrap/component-animations.less',
|
||||
'src/legacy/ui/public/styles/bootstrap/input-groups.less',
|
||||
'src/legacy/ui/public/styles/bootstrap/list-group.less',
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
|
||||
import { format } from 'url';
|
||||
import { resolve } from 'path';
|
||||
import _ from 'lodash';
|
||||
import Boom from 'boom';
|
||||
|
||||
|
@ -32,22 +31,6 @@ export default async function(kbnServer, server, config) {
|
|||
|
||||
await registerHapiPlugins(server);
|
||||
|
||||
// provide a simple way to expose static directories
|
||||
server.decorate('server', 'exposeStaticDir', function(routePath, dirPath) {
|
||||
this.route({
|
||||
path: routePath,
|
||||
method: 'GET',
|
||||
handler: {
|
||||
directory: {
|
||||
path: dirPath,
|
||||
listing: false,
|
||||
lookupCompressed: true,
|
||||
},
|
||||
},
|
||||
config: { auth: false },
|
||||
});
|
||||
});
|
||||
|
||||
// helper for creating view managers for servers
|
||||
server.decorate('server', 'setupViews', function(path, engines) {
|
||||
this.views({
|
||||
|
@ -77,7 +60,4 @@ export default async function(kbnServer, server, config) {
|
|||
.permanent(true);
|
||||
},
|
||||
});
|
||||
|
||||
// Expose static assets
|
||||
server.exposeStaticDir('/ui/{path*}', resolve(__dirname, '../../ui/public/assets'));
|
||||
}
|
||||
|
|
|
@ -73,7 +73,10 @@ export class Plugin {
|
|||
});
|
||||
|
||||
if (this.publicDir) {
|
||||
server.exposeStaticDir(`/plugins/${id}/{path*}`, this.publicDir);
|
||||
server.newPlatform.__internals.http.registerStaticDir(
|
||||
`/plugins/${id}/{path*}`,
|
||||
this.publicDir
|
||||
);
|
||||
}
|
||||
|
||||
// Many of the plugins are simply adding static assets to the server and we don't need
|
||||
|
|
|
@ -34,7 +34,7 @@ const access = promisify(fs.access);
|
|||
const copyFile = promisify(fs.copyFile);
|
||||
const mkdirAsync = promisify(fs.mkdir);
|
||||
|
||||
const UI_ASSETS_DIR = resolve(__dirname, '../../ui/public/assets');
|
||||
const UI_ASSETS_DIR = resolve(__dirname, '../../../core/server/core_app/assets');
|
||||
const DARK_THEME_IMPORTER = url => {
|
||||
if (url.includes('eui_colors_light')) {
|
||||
return { file: url.replace('eui_colors_light', 'eui_colors_dark') };
|
||||
|
|
|
@ -23,8 +23,6 @@ import { resolve } from 'path';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import * as UiSharedDeps from '@kbn/ui-shared-deps';
|
||||
import { AppBootstrap } from './bootstrap';
|
||||
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
|
||||
import { fromRoot } from '../../../core/server/utils';
|
||||
import { getApmConfig } from '../apm';
|
||||
import { DllCompiler } from '../../../optimize/dynamic_dll_plugin';
|
||||
|
||||
|
@ -43,11 +41,6 @@ export function uiRenderMixin(kbnServer, server, config) {
|
|||
// render all views from ./views
|
||||
server.setupViews(resolve(__dirname, 'views'));
|
||||
|
||||
server.exposeStaticDir(
|
||||
'/node_modules/@kbn/ui-framework/dist/{path*}',
|
||||
fromRoot('node_modules/@kbn/ui-framework/dist')
|
||||
);
|
||||
|
||||
const translationsCache = { translations: null, hash: null };
|
||||
server.route({
|
||||
path: '/translations/{locale}.json',
|
||||
|
|
|
@ -16,18 +16,18 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from 'test/functional/ftr_provider_context';
|
||||
import { format as formatUrl } from 'url';
|
||||
|
||||
import supertestAsPromised from 'supertest-as-promised';
|
||||
|
||||
export function KibanaSupertestProvider({ getService }) {
|
||||
export function KibanaSupertestProvider({ getService }: FtrProviderContext) {
|
||||
const config = getService('config');
|
||||
const kibanaServerUrl = formatUrl(config.get('servers.kibana'));
|
||||
return supertestAsPromised(kibanaServerUrl);
|
||||
}
|
||||
|
||||
export function ElasticsearchSupertestProvider({ getService }) {
|
||||
export function ElasticsearchSupertestProvider({ getService }: FtrProviderContext) {
|
||||
const config = getService('config');
|
||||
const elasticSearchServerUrl = formatUrl(config.get('servers.elasticsearch'));
|
||||
return supertestAsPromised(elasticSearchServerUrl);
|
|
@ -44,7 +44,7 @@ export async function initPlugin(server: Hapi.Server, path: string) {
|
|||
],
|
||||
},
|
||||
},
|
||||
handler: newsfeedHandler,
|
||||
handler: newsfeedHandler as Hapi.Lifecycle.Method,
|
||||
});
|
||||
|
||||
server.route({
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"id": "corePluginStaticAssets",
|
||||
"version": "0.0.1",
|
||||
"kibanaVersion": "kibana",
|
||||
"server": false,
|
||||
"ui": true
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "corePluginStaticAssets",
|
||||
"version": "1.0.0",
|
||||
"main": "target/test/plugin_functional/plugins/core_plugin_static_assets",
|
||||
"kibana": {
|
||||
"version": "kibana",
|
||||
"templateVersion": "1.0.0"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"kbn": "node ../../../../scripts/kbn.js",
|
||||
"build": "rm -rf './target' && tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "3.7.2"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="36" height="24" viewBox="0 0 36 24">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<path fill="#69707D" fill-rule="nonzero" d="M8,8 C8.55228,8 9,8.44772 9,9 L9,22 C9,22.5523 8.55228,23 8,23 L4,23 C3.44772,23 3,22.5523 3,22 L3,9 C3,8.44772 3.44772,8 4,8 L8,8 Z M24,1 C24.5523,1 25,1.44772 25,2 L25,22 C25,22.5523 24.5523,23 24,23 L20,23 C19.4477,23 19,22.5523 19,22 L19,2 C19,1.44772 19.4477,1 20,1 L24,1 Z"/>
|
||||
<path fill="#54B399" fill-rule="nonzero" d="M16,12 C16.5523,12 17,12.4477 17,13 L17,22 C17,22.5523 16.5523,23 16,23 L12,23 C11.4477,23 11,22.5523 11,22 L11,13 C11,12.4477 11.4477,12 12,12 L16,12 Z M32,5 C32.5523,5 33,5.44772 33,6 L33,22 C33,22.5523 32.5523,23 32,23 L28,23 C27.4477,23 27,22.5523 27,22 L27,6 C27,5.44772 27.4477,5 28,5 L32,5 Z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 816 B |