boolean
| Indicates whether or not this app is currently on the screen. |
-| [baseUrl](./kibana-plugin-public.chromenavlink.baseurl.md) | string
| The base route used to open the root of an application. |
-| [category](./kibana-plugin-public.chromenavlink.category.md) | AppCategory
| The category the app lives in |
-| [disabled](./kibana-plugin-public.chromenavlink.disabled.md) | boolean
| Disables a link from being clickable. |
-| [disableSubUrlTracking](./kibana-plugin-public.chromenavlink.disablesuburltracking.md) | boolean
| A flag that tells legacy chrome to ignore the link when tracking sub-urls |
-| [euiIconType](./kibana-plugin-public.chromenavlink.euiicontype.md) | string
| A EUI iconType that will be used for the app's icon. This icon takes precendence over the icon
property. |
-| [hidden](./kibana-plugin-public.chromenavlink.hidden.md) | boolean
| Hides a link from the navigation. |
-| [icon](./kibana-plugin-public.chromenavlink.icon.md) | string
| A URL to an image file used as an icon. Used as a fallback if euiIconType
is not provided. |
-| [id](./kibana-plugin-public.chromenavlink.id.md) | string
| A unique identifier for looking up links. |
-| [linkToLastSubUrl](./kibana-plugin-public.chromenavlink.linktolastsuburl.md) | boolean
| Whether or not the subUrl feature should be enabled. |
-| [order](./kibana-plugin-public.chromenavlink.order.md) | number
| An ordinal used to sort nav links relative to one another for display. |
-| [subUrlBase](./kibana-plugin-public.chromenavlink.suburlbase.md) | string
| A url base that legacy apps can set to match deep URLs to an application. |
-| [title](./kibana-plugin-public.chromenavlink.title.md) | string
| The title of the application. |
-| [tooltip](./kibana-plugin-public.chromenavlink.tooltip.md) | string
| A tooltip shown when hovering over an app link. |
-| [url](./kibana-plugin-public.chromenavlink.url.md) | string
| A url that legacy apps can set to deep link into their applications. |
-
+
+
+[Home](./index.md) > [kibana-plugin-public](./kibana-plugin-public.md) > [ChromeNavLink](./kibana-plugin-public.chromenavlink.md)
+
+## ChromeNavLink interface
+
+
+Signature:
+
+```typescript
+export interface ChromeNavLink
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [active](./kibana-plugin-public.chromenavlink.active.md) | boolean
| Indicates whether or not this app is currently on the screen. |
+| [baseUrl](./kibana-plugin-public.chromenavlink.baseurl.md) | string
| The base route used to open the root of an application. |
+| [category](./kibana-plugin-public.chromenavlink.category.md) | AppCategory
| The category the app lives in |
+| [disabled](./kibana-plugin-public.chromenavlink.disabled.md) | boolean
| Disables a link from being clickable. |
+| [disableSubUrlTracking](./kibana-plugin-public.chromenavlink.disablesuburltracking.md) | boolean
| A flag that tells legacy chrome to ignore the link when tracking sub-urls |
+| [euiIconType](./kibana-plugin-public.chromenavlink.euiicontype.md) | string
| A EUI iconType that will be used for the app's icon. This icon takes precendence over the icon
property. |
+| [hidden](./kibana-plugin-public.chromenavlink.hidden.md) | boolean
| Hides a link from the navigation. |
+| [icon](./kibana-plugin-public.chromenavlink.icon.md) | string
| A URL to an image file used as an icon. Used as a fallback if euiIconType
is not provided. |
+| [id](./kibana-plugin-public.chromenavlink.id.md) | string
| A unique identifier for looking up links. |
+| [linkToLastSubUrl](./kibana-plugin-public.chromenavlink.linktolastsuburl.md) | boolean
| Whether or not the subUrl feature should be enabled. |
+| [order](./kibana-plugin-public.chromenavlink.order.md) | number
| An ordinal used to sort nav links relative to one another for display. |
+| [subUrlBase](./kibana-plugin-public.chromenavlink.suburlbase.md) | string
| A url base that legacy apps can set to match deep URLs to an application. |
+| [title](./kibana-plugin-public.chromenavlink.title.md) | string
| The title of the application. |
+| [tooltip](./kibana-plugin-public.chromenavlink.tooltip.md) | string
| A tooltip shown when hovering over an app link. |
+| [url](./kibana-plugin-public.chromenavlink.url.md) | string
| A url that legacy apps can set to deep link into their applications. |
+
diff --git a/docs/development/core/server/kibana-plugin-server.configdeprecationfactory.md b/docs/development/core/server/kibana-plugin-server.configdeprecationfactory.md
index c61907f366301..2ebee16874c80 100644
--- a/docs/development/core/server/kibana-plugin-server.configdeprecationfactory.md
+++ b/docs/development/core/server/kibana-plugin-server.configdeprecationfactory.md
@@ -30,7 +30,7 @@ const provider: ConfigDeprecationProvider = ({ rename, unused }) => [
| Method | Description |
| --- | --- |
| [rename(oldKey, newKey)](./kibana-plugin-server.configdeprecationfactory.rename.md) | Rename a configuration property from inside a plugin's configuration path. Will log a deprecation warning if the oldKey was found and deprecation applied. |
-| [renameFromRoot(oldKey, newKey)](./kibana-plugin-server.configdeprecationfactory.renamefromroot.md) | Rename a configuration property from the root configuration. Will log a deprecation warning if the oldKey was found and deprecation applied.This should be only used when renaming properties from different configuration's path. To rename properties from inside a plugin's configuration, use 'rename' instead. |
+| [renameFromRoot(oldKey, newKey, silent)](./kibana-plugin-server.configdeprecationfactory.renamefromroot.md) | Rename a configuration property from the root configuration. Will log a deprecation warning if the oldKey was found and deprecation applied.This should be only used when renaming properties from different configuration's path. To rename properties from inside a plugin's configuration, use 'rename' instead. |
| [unused(unusedKey)](./kibana-plugin-server.configdeprecationfactory.unused.md) | Remove a configuration property from inside a plugin's configuration path. Will log a deprecation warning if the unused key was found and deprecation applied. |
| [unusedFromRoot(unusedKey)](./kibana-plugin-server.configdeprecationfactory.unusedfromroot.md) | Remove a configuration property from the root configuration. Will log a deprecation warning if the unused key was found and deprecation applied.This should be only used when removing properties from outside of a plugin's configuration. To remove properties from inside a plugin's configuration, use 'unused' instead. |
diff --git a/docs/development/core/server/kibana-plugin-server.configdeprecationfactory.renamefromroot.md b/docs/development/core/server/kibana-plugin-server.configdeprecationfactory.renamefromroot.md
index 269f242ec35da..40ea891b17c95 100644
--- a/docs/development/core/server/kibana-plugin-server.configdeprecationfactory.renamefromroot.md
+++ b/docs/development/core/server/kibana-plugin-server.configdeprecationfactory.renamefromroot.md
@@ -11,7 +11,7 @@ This should be only used when renaming properties from different configuration's
Signature:
```typescript
-renameFromRoot(oldKey: string, newKey: string): ConfigDeprecation;
+renameFromRoot(oldKey: string, newKey: string, silent?: boolean): ConfigDeprecation;
```
## Parameters
@@ -20,6 +20,7 @@ renameFromRoot(oldKey: string, newKey: string): ConfigDeprecation;
| --- | --- | --- |
| oldKey | string
| |
| newKey | string
| |
+| silent | boolean
| |
Returns:
diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.host.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.host.md
new file mode 100644
index 0000000000000..ee7e1e5b7c9c9
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.host.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) > [host](./kibana-plugin-server.httpserverinfo.host.md)
+
+## HttpServerInfo.host property
+
+The hostname of the server
+
+Signature:
+
+```typescript
+host: string;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.md
new file mode 100644
index 0000000000000..6dbdb11ddb66e
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.md
@@ -0,0 +1,22 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md)
+
+## HttpServerInfo interface
+
+
+Signature:
+
+```typescript
+export interface HttpServerInfo
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [host](./kibana-plugin-server.httpserverinfo.host.md) | string
| The hostname of the server |
+| [name](./kibana-plugin-server.httpserverinfo.name.md) | string
| The name of the Kibana server |
+| [port](./kibana-plugin-server.httpserverinfo.port.md) | number
| The port the server is listening on |
+| [protocol](./kibana-plugin-server.httpserverinfo.protocol.md) | 'http' | 'https' | 'socket'
| The protocol used by the server |
+
diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.name.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.name.md
new file mode 100644
index 0000000000000..8d3a45c90a342
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.name.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) > [name](./kibana-plugin-server.httpserverinfo.name.md)
+
+## HttpServerInfo.name property
+
+The name of the Kibana server
+
+Signature:
+
+```typescript
+name: string;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.port.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.port.md
new file mode 100644
index 0000000000000..5dd5a53830c44
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.port.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) > [port](./kibana-plugin-server.httpserverinfo.port.md)
+
+## HttpServerInfo.port property
+
+The port the server is listening on
+
+Signature:
+
+```typescript
+port: number;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.httpserverinfo.protocol.md b/docs/development/core/server/kibana-plugin-server.httpserverinfo.protocol.md
new file mode 100644
index 0000000000000..08afb5c3f7213
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.httpserverinfo.protocol.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) > [protocol](./kibana-plugin-server.httpserverinfo.protocol.md)
+
+## HttpServerInfo.protocol property
+
+The protocol used by the server
+
+Signature:
+
+```typescript
+protocol: 'http' | 'https' | 'socket';
+```
diff --git a/docs/development/core/server/kibana-plugin-server.httpservicesetup.getserverinfo.md b/docs/development/core/server/kibana-plugin-server.httpservicesetup.getserverinfo.md
new file mode 100644
index 0000000000000..4501a7e26f75f
--- /dev/null
+++ b/docs/development/core/server/kibana-plugin-server.httpservicesetup.getserverinfo.md
@@ -0,0 +1,13 @@
+
+
+[Home](./index.md) > [kibana-plugin-server](./kibana-plugin-server.md) > [HttpServiceSetup](./kibana-plugin-server.httpservicesetup.md) > [getServerInfo](./kibana-plugin-server.httpservicesetup.getserverinfo.md)
+
+## HttpServiceSetup.getServerInfo property
+
+Provides common [information](./kibana-plugin-server.httpserverinfo.md) about the running http server.
+
+Signature:
+
+```typescript
+getServerInfo: () => HttpServerInfo;
+```
diff --git a/docs/development/core/server/kibana-plugin-server.httpservicesetup.md b/docs/development/core/server/kibana-plugin-server.httpservicesetup.md
index 2a4b0e09977c1..c2d53ec1eaf52 100644
--- a/docs/development/core/server/kibana-plugin-server.httpservicesetup.md
+++ b/docs/development/core/server/kibana-plugin-server.httpservicesetup.md
@@ -86,6 +86,7 @@ async (context, request, response) => {
| [createCookieSessionStorageFactory](./kibana-plugin-server.httpservicesetup.createcookiesessionstoragefactory.md) | <T>(cookieOptions: SessionStorageCookieOptions<T>) => Promise<SessionStorageFactory<T>>
| Creates cookie based session storage factory [SessionStorageFactory](./kibana-plugin-server.sessionstoragefactory.md) |
| [createRouter](./kibana-plugin-server.httpservicesetup.createrouter.md) | () => IRouter
| Provides ability to declare a handler function for a particular path and HTTP request method. |
| [csp](./kibana-plugin-server.httpservicesetup.csp.md) | ICspConfig
| The CSP config used for Kibana. |
+| [getServerInfo](./kibana-plugin-server.httpservicesetup.getserverinfo.md) | () => HttpServerInfo
| Provides common [information](./kibana-plugin-server.httpserverinfo.md) about the running http server. |
| [isTlsEnabled](./kibana-plugin-server.httpservicesetup.istlsenabled.md) | boolean
| Flag showing whether a server was configured to use TLS connection. |
| [registerAuth](./kibana-plugin-server.httpservicesetup.registerauth.md) | (handler: AuthenticationHandler) => void
| To define custom authentication and/or authorization mechanism for incoming requests. |
| [registerOnPostAuth](./kibana-plugin-server.httpservicesetup.registeronpostauth.md) | (handler: OnPostAuthHandler) => void
| To define custom logic to perform for incoming requests. |
diff --git a/docs/development/core/server/kibana-plugin-server.md b/docs/development/core/server/kibana-plugin-server.md
index e7b1334652540..a3abeff44c25c 100644
--- a/docs/development/core/server/kibana-plugin-server.md
+++ b/docs/development/core/server/kibana-plugin-server.md
@@ -64,6 +64,7 @@ The plugin integrates with the core system via lifecycle events: `setup`
| [ErrorHttpResponseOptions](./kibana-plugin-server.errorhttpresponseoptions.md) | HTTP response parameters |
| [FakeRequest](./kibana-plugin-server.fakerequest.md) | Fake request object created manually by Kibana plugins. |
| [HttpResponseOptions](./kibana-plugin-server.httpresponseoptions.md) | HTTP response parameters |
+| [HttpServerInfo](./kibana-plugin-server.httpserverinfo.md) | |
| [HttpServiceSetup](./kibana-plugin-server.httpservicesetup.md) | Kibana HTTP Service provides own abstraction for work with HTTP stack. Plugins don't have direct access to hapi
server and its primitives anymore. Moreover, plugins shouldn't rely on the fact that HTTP Service uses one or another library under the hood. This gives the platform flexibility to upgrade or changing our internal HTTP stack without breaking plugins. If the HTTP Service lacks functionality you need, we are happy to discuss and support your needs. |
| [HttpServiceStart](./kibana-plugin-server.httpservicestart.md) | |
| [IContextContainer](./kibana-plugin-server.icontextcontainer.md) | An object that handles registration of context providers and configuring handlers with context. |
diff --git a/docs/migration/migrate_8_0.asciidoc b/docs/migration/migrate_8_0.asciidoc
index 146d4e97b6cf4..a34f956ace263 100644
--- a/docs/migration/migrate_8_0.asciidoc
+++ b/docs/migration/migrate_8_0.asciidoc
@@ -74,6 +74,12 @@ specified explicitly.
*Impact:* Define `xpack.security.authc.saml.realm` when using the SAML authentication provider instead.
+[float]
+==== `/api/security/v1/saml` endpoint is no longer supported
+*Details:* The deprecated `/api/security/v1/saml` endpoint is no longer supported.
+
+*Impact:* Rely on `/api/security/saml/callback` endpoint when using SAML instead. This change should be reflected in Kibana `server.xsrf.whitelist` config as well as in Elasticsearch and Identity Provider SAML settings.
+
[float]
=== `optimize` directory is now in the `data` folder
*Details:* Generated bundles have moved to the configured `path.data` folder.
diff --git a/package.json b/package.json
index e249546e71581..ff6d32bfc39e5 100644
--- a/package.json
+++ b/package.json
@@ -120,7 +120,7 @@
"@elastic/charts": "^16.1.0",
"@elastic/datemath": "5.0.2",
"@elastic/ems-client": "7.6.0",
- "@elastic/eui": "18.2.1",
+ "@elastic/eui": "18.3.0",
"@elastic/filesaver": "1.1.2",
"@elastic/good": "8.1.1-kibana2",
"@elastic/numeral": "2.3.3",
diff --git a/packages/kbn-plugin-generator/index.js b/packages/kbn-plugin-generator/index.js
index 90274288357b8..15adce7f01c8e 100644
--- a/packages/kbn-plugin-generator/index.js
+++ b/packages/kbn-plugin-generator/index.js
@@ -29,6 +29,7 @@ exports.run = function run(argv) {
const options = getopts(argv, {
alias: {
h: 'help',
+ i: 'internal',
},
});
@@ -40,17 +41,22 @@ exports.run = function run(argv) {
if (options.help) {
console.log(
dedent(chalk`
- {dim usage:} node scripts/generate-plugin {bold [name]}
-
- generate a fresh Kibana plugin in the plugins/ directory
+ # {dim Usage:}
+ node scripts/generate-plugin {bold [name]}
+ Generate a fresh Kibana plugin in the plugins/ directory
+
+ # {dim Core Kibana plugins:}
+ node scripts/generate-plugin {bold [name]} -i
+ To generate a core Kibana plugin inside the src/plugins/ directory, add the -i flag.
`) + '\n'
);
process.exit(1);
}
const name = options._[0];
+ const isKibanaPlugin = options.internal;
const template = resolve(__dirname, './sao_template');
- const kibanaPlugins = resolve(__dirname, '../../plugins');
+ const kibanaPlugins = resolve(__dirname, isKibanaPlugin ? '../../src/plugins' : '../../plugins');
const targetPath = resolve(kibanaPlugins, snakeCase(name));
sao({
@@ -58,6 +64,8 @@ exports.run = function run(argv) {
targetPath: targetPath,
configOptions: {
name,
+ isKibanaPlugin,
+ targetPath,
},
}).catch(error => {
console.error(chalk`{red fatal error}!`);
diff --git a/src/es_archiver/index.js b/packages/kbn-plugin-generator/index.js.d.ts
similarity index 88%
rename from src/es_archiver/index.js
rename to packages/kbn-plugin-generator/index.js.d.ts
index f7a579a98a42d..46f7c43fd5790 100644
--- a/src/es_archiver/index.js
+++ b/packages/kbn-plugin-generator/index.js.d.ts
@@ -16,5 +16,9 @@
* specific language governing permissions and limitations
* under the License.
*/
-
-export { EsArchiver } from './es_archiver';
+interface PluginGenerator {
+ /**
+ * Run plugin generator.
+ */
+ run: (...args: any[]) => any;
+}
diff --git a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js
index aa6611f3b6738..129125c4583d5 100644
--- a/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js
+++ b/packages/kbn-plugin-generator/integration_tests/generate_plugin.test.js
@@ -61,7 +61,8 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug
expect(stats.isDirectory()).toBe(true);
});
- it(`should create an internationalization config file with a blank line appended to satisfy the parser`, async () => {
+ // skipped until internationalization is re-introduced
+ it.skip(`should create an internationalization config file with a blank line appended to satisfy the parser`, async () => {
// Link to the error that happens when the blank line is not there:
// https://github.com/elastic/kibana/pull/45044#issuecomment-530092627
const intlFile = `${generatedPath}/.i18nrc.json`;
@@ -78,16 +79,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug
});
});
- it(`'yarn test:server' should exit 0`, async () => {
- await execa('yarn', ['test:server'], {
- cwd: generatedPath,
- env: {
- DISABLE_JUNIT_REPORTER: '1',
- },
- });
- });
-
- it(`'yarn build' should exit 0`, async () => {
+ it.skip(`'yarn build' should exit 0`, async () => {
await execa('yarn', ['build'], { cwd: generatedPath });
});
@@ -109,7 +101,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug
'--migrations.skip=true',
],
cwd: generatedPath,
- wait: /ispec_plugin.+Status changed from uninitialized to green - Ready/,
+ wait: new RegExp('\\[ispecPlugin\\]\\[plugins\\] Setting up plugin'),
});
await proc.stop('kibana');
});
@@ -120,7 +112,7 @@ describe(`running the plugin-generator via 'node scripts/generate_plugin.js plug
await execa('yarn', ['preinstall'], { cwd: generatedPath });
});
- it(`'yarn lint' should exit 0`, async () => {
+ it.skip(`'yarn lint' should exit 0`, async () => {
await execa('yarn', ['lint'], { cwd: generatedPath });
});
diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js
index f7401cba84358..aed4b9a02838f 100755
--- a/packages/kbn-plugin-generator/sao_template/sao.js
+++ b/packages/kbn-plugin-generator/sao_template/sao.js
@@ -17,21 +17,19 @@
* under the License.
*/
-const { resolve, relative, dirname } = require('path');
+const { relative } = require('path');
const startCase = require('lodash.startcase');
const camelCase = require('lodash.camelcase');
const snakeCase = require('lodash.snakecase');
-const execa = require('execa');
const chalk = require('chalk');
+const execa = require('execa');
const pkg = require('../package.json');
const kibanaPkgPath = require.resolve('../../../package.json');
const kibanaPkg = require(kibanaPkgPath); // eslint-disable-line import/no-dynamic-require
-const KBN_DIR = dirname(kibanaPkgPath);
-
-module.exports = function({ name }) {
+module.exports = function({ name, targetPath, isKibanaPlugin }) {
return {
prompts: {
description: {
@@ -47,41 +45,38 @@ module.exports = function({ name }) {
message: 'Should an app component be generated?',
default: true,
},
- generateTranslations: {
- type: 'confirm',
- message: 'Should translation files be generated?',
- default: true,
- },
- generateHack: {
- type: 'confirm',
- message: 'Should a hack component be generated?',
- default: true,
- },
generateApi: {
type: 'confirm',
message: 'Should a server API be generated?',
default: true,
},
+ // generateTranslations: {
+ // type: 'confirm',
+ // message: 'Should translation files be generated?',
+ // default: true,
+ // },
generateScss: {
type: 'confirm',
message: 'Should SCSS be used?',
when: answers => answers.generateApp,
default: true,
},
+ generateEslint: {
+ type: 'confirm',
+ message: 'Would you like to use a custom eslint file?',
+ default: !isKibanaPlugin,
+ },
},
filters: {
+ 'public/**/index.scss': 'generateScss',
'public/**/*': 'generateApp',
- 'translations/**/*': 'generateTranslations',
- '.i18nrc.json': 'generateTranslations',
- 'public/hack.js': 'generateHack',
'server/**/*': 'generateApi',
- 'public/app.scss': 'generateScss',
- '.kibana-plugin-helpers.json': 'generateScss',
+ // 'translations/**/*': 'generateTranslations',
+ // '.i18nrc.json': 'generateTranslations',
+ 'eslintrc.js': 'generateEslint',
},
move: {
- gitignore: '.gitignore',
'eslintrc.js': '.eslintrc.js',
- 'package_template.json': 'package.json',
},
data: answers =>
Object.assign(
@@ -91,34 +86,36 @@ module.exports = function({ name }) {
camelCase,
snakeCase,
name,
+ isKibanaPlugin,
+ kbnVersion: answers.kbnVersion,
+ upperCamelCaseName: name.charAt(0).toUpperCase() + camelCase(name).slice(1),
+ hasUi: !!answers.generateApp,
+ hasServer: !!answers.generateApi,
+ hasScss: !!answers.generateScss,
+ relRoot: isKibanaPlugin ? '../../../..' : '../../..',
},
answers
),
enforceNewFolder: true,
installDependencies: false,
- gitInit: true,
+ gitInit: !isKibanaPlugin,
async post({ log }) {
- await execa('yarn', ['kbn', 'bootstrap'], {
- cwd: KBN_DIR,
- stdio: 'inherit',
- });
-
- const dir = relative(process.cwd(), resolve(KBN_DIR, 'plugins', snakeCase(name)));
+ const dir = relative(process.cwd(), targetPath);
+ // Apply eslint to the generated plugin
try {
- await execa('yarn', ['lint', '--fix'], {
- cwd: dir,
- all: true,
- });
+ await execa('yarn', ['lint:es', `./${dir}/**/*.ts*`, '--no-ignore', '--fix']);
} catch (error) {
- throw new Error(`Failure when running prettier on the generated output: ${error.all}`);
+ console.error(error);
+ throw new Error(
+ `Failure when running prettier on the generated output: ${error.all || error}`
+ );
}
log.success(chalk`🎉
-Your plugin has been created in {bold ${dir}}. Move into that directory to run it:
+Your plugin has been created in {bold ${dir}}.
- {bold cd "${dir}"}
{bold yarn start}
`);
},
diff --git a/packages/kbn-plugin-generator/sao_template/sao.test.js b/packages/kbn-plugin-generator/sao_template/sao.test.js
index 80149c008dad8..0dbdb7d3c097b 100755
--- a/packages/kbn-plugin-generator/sao_template/sao.test.js
+++ b/packages/kbn-plugin-generator/sao_template/sao.test.js
@@ -19,8 +19,6 @@
const sao = require('sao');
-const templatePkg = require('../package.json');
-
const template = {
fromPath: __dirname,
configOptions: {
@@ -32,121 +30,57 @@ function getFileContents(file) {
return file.contents.toString();
}
-function getConfig(file) {
- const contents = getFileContents(file).replace(/\r?\n/gm, '');
- return contents.split('kibana.Plugin(')[1];
-}
-
describe('plugin generator sao integration', () => {
test('skips files when answering no', async () => {
const res = await sao.mockPrompt(template, {
generateApp: false,
- generateHack: false,
generateApi: false,
});
- expect(res.fileList).not.toContain('public/app.js');
- expect(res.fileList).not.toContain('public/__tests__/index.js');
- expect(res.fileList).not.toContain('public/hack.js');
- expect(res.fileList).not.toContain('server/routes/example.js');
- expect(res.fileList).not.toContain('server/__tests__/index.js');
-
- const uiExports = getConfig(res.files['index.js']);
- expect(uiExports).not.toContain('app:');
- expect(uiExports).not.toContain('hacks:');
- expect(uiExports).not.toContain('init(server, options)');
- expect(uiExports).not.toContain('registerFeature(');
+ expect(res.fileList).toContain('common/index.ts');
+ expect(res.fileList).not.toContain('public/index.ts');
+ expect(res.fileList).not.toContain('server/index.ts');
});
it('includes app when answering yes', async () => {
const res = await sao.mockPrompt(template, {
generateApp: true,
- generateHack: false,
- generateApi: false,
- });
-
- // check output files
- expect(res.fileList).toContain('public/app.js');
- expect(res.fileList).toContain('public/__tests__/index.js');
- expect(res.fileList).not.toContain('public/hack.js');
- expect(res.fileList).not.toContain('server/routes/example.js');
- expect(res.fileList).not.toContain('server/__tests__/index.js');
-
- const uiExports = getConfig(res.files['index.js']);
- expect(uiExports).toContain('app:');
- expect(uiExports).toContain('init(server, options)');
- expect(uiExports).toContain('registerFeature(');
- expect(uiExports).not.toContain('hacks:');
- });
-
- it('includes hack when answering yes', async () => {
- const res = await sao.mockPrompt(template, {
- generateApp: true,
- generateHack: true,
generateApi: false,
});
// check output files
- expect(res.fileList).toContain('public/app.js');
- expect(res.fileList).toContain('public/__tests__/index.js');
- expect(res.fileList).toContain('public/hack.js');
- expect(res.fileList).not.toContain('server/routes/example.js');
- expect(res.fileList).not.toContain('server/__tests__/index.js');
-
- const uiExports = getConfig(res.files['index.js']);
- expect(uiExports).toContain('app:');
- expect(uiExports).toContain('hacks:');
- expect(uiExports).toContain('init(server, options)');
- expect(uiExports).toContain('registerFeature(');
+ expect(res.fileList).toContain('common/index.ts');
+ expect(res.fileList).toContain('public/index.ts');
+ expect(res.fileList).toContain('public/plugin.ts');
+ expect(res.fileList).toContain('public/types.ts');
+ expect(res.fileList).toContain('public/components/app.tsx');
+ expect(res.fileList).not.toContain('server/index.ts');
});
it('includes server api when answering yes', async () => {
const res = await sao.mockPrompt(template, {
generateApp: true,
- generateHack: true,
generateApi: true,
});
// check output files
- expect(res.fileList).toContain('public/app.js');
- expect(res.fileList).toContain('public/__tests__/index.js');
- expect(res.fileList).toContain('public/hack.js');
- expect(res.fileList).toContain('server/routes/example.js');
- expect(res.fileList).toContain('server/__tests__/index.js');
-
- const uiExports = getConfig(res.files['index.js']);
- expect(uiExports).toContain('app:');
- expect(uiExports).toContain('hacks:');
- expect(uiExports).toContain('init(server, options)');
- expect(uiExports).toContain('registerFeature(');
- });
-
- it('plugin config has correct name and main path', async () => {
- const res = await sao.mockPrompt(template, {
- generateApp: true,
- generateHack: true,
- generateApi: true,
- });
-
- const indexContents = getFileContents(res.files['index.js']);
- const nameLine = indexContents.match('name: (.*)')[1];
- const mainLine = indexContents.match('main: (.*)')[1];
-
- expect(nameLine).toContain('some_fancy_plugin');
- expect(mainLine).toContain('plugins/some_fancy_plugin/app');
+ expect(res.fileList).toContain('public/plugin.ts');
+ expect(res.fileList).toContain('server/plugin.ts');
+ expect(res.fileList).toContain('server/index.ts');
+ expect(res.fileList).toContain('server/types.ts');
+ expect(res.fileList).toContain('server/routes/index.ts');
});
- it('plugin package has correct name', async () => {
+ it('plugin package has correct title', async () => {
const res = await sao.mockPrompt(template, {
generateApp: true,
- generateHack: true,
generateApi: true,
});
- const packageContents = getFileContents(res.files['package.json']);
- const pkg = JSON.parse(packageContents);
+ const contents = getFileContents(res.files['common/index.ts']);
+ const controllerLine = contents.match("PLUGIN_NAME = '(.*)'")[1];
- expect(pkg.name).toBe('some_fancy_plugin');
+ expect(controllerLine).toContain('Some fancy plugin');
});
it('package has version "kibana" with master', async () => {
@@ -154,10 +88,10 @@ describe('plugin generator sao integration', () => {
kbnVersion: 'master',
});
- const packageContents = getFileContents(res.files['package.json']);
+ const packageContents = getFileContents(res.files['kibana.json']);
const pkg = JSON.parse(packageContents);
- expect(pkg.kibana.version).toBe('kibana');
+ expect(pkg.version).toBe('master');
});
it('package has correct version', async () => {
@@ -165,39 +99,26 @@ describe('plugin generator sao integration', () => {
kbnVersion: 'v6.0.0',
});
- const packageContents = getFileContents(res.files['package.json']);
- const pkg = JSON.parse(packageContents);
-
- expect(pkg.kibana.version).toBe('v6.0.0');
- });
-
- it('package has correct templateVersion', async () => {
- const res = await sao.mockPrompt(template, {
- kbnVersion: 'master',
- });
-
- const packageContents = getFileContents(res.files['package.json']);
+ const packageContents = getFileContents(res.files['kibana.json']);
const pkg = JSON.parse(packageContents);
- expect(pkg.kibana.templateVersion).toBe(templatePkg.version);
+ expect(pkg.version).toBe('v6.0.0');
});
it('sample app has correct values', async () => {
const res = await sao.mockPrompt(template, {
generateApp: true,
- generateHack: true,
generateApi: true,
});
- const contents = getFileContents(res.files['public/app.js']);
- const controllerLine = contents.match('setRootController(.*)')[1];
+ const contents = getFileContents(res.files['common/index.ts']);
+ const controllerLine = contents.match("PLUGIN_ID = '(.*)'")[1];
expect(controllerLine).toContain('someFancyPlugin');
});
it('includes dotfiles', async () => {
const res = await sao.mockPrompt(template);
- expect(res.files['.gitignore']).toBeTruthy();
expect(res.files['.eslintrc.js']).toBeTruthy();
});
});
diff --git a/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json b/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json
deleted file mode 100644
index 1a8aea8853876..0000000000000
--- a/packages/kbn-plugin-generator/sao_template/template/.i18nrc.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "paths": {
- "<%= camelCase(name) %>": "./"
- },
- "translations": [
- "translations/zh-CN.json"
- ]
-}
-
diff --git a/packages/kbn-plugin-generator/sao_template/template/.kibana-plugin-helpers.json b/packages/kbn-plugin-generator/sao_template/template/.kibana-plugin-helpers.json
deleted file mode 100644
index 383368c7f8ce1..0000000000000
--- a/packages/kbn-plugin-generator/sao_template/template/.kibana-plugin-helpers.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "styleSheetToCompile": "public/app.scss"
-}
diff --git a/packages/kbn-plugin-generator/sao_template/template/README.md b/packages/kbn-plugin-generator/sao_template/template/README.md
index 59c3adf2713c8..1e0139428fcbc 100755
--- a/packages/kbn-plugin-generator/sao_template/template/README.md
+++ b/packages/kbn-plugin-generator/sao_template/template/README.md
@@ -6,34 +6,7 @@
---
-## development
+## Development
-See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment. Once you have completed that, use the following yarn scripts.
+See the [kibana contributing guide](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md) for instructions setting up your development environment.
- - `yarn kbn bootstrap`
-
- Install dependencies and crosslink Kibana and all projects/plugins.
-
- > ***IMPORTANT:*** Use this script instead of `yarn` to install dependencies when switching branches, and re-run it whenever your dependencies change.
-
- - `yarn start`
-
- Start kibana and have it include this plugin. You can pass any arguments that you would normally send to `bin/kibana`
-
- ```
- yarn start --elasticsearch.hosts http://localhost:9220
- ```
-
- - `yarn build`
-
- Build a distributable archive of your plugin.
-
- - `yarn test:browser`
-
- Run the browser tests in a real web browser.
-
- - `yarn test:mocha`
-
- Run the server tests using mocha.
-
-For more information about any of these commands run `yarn ${task} --help`. For a full list of tasks checkout the `package.json` file, or run `yarn run`.
diff --git a/packages/kbn-plugin-generator/sao_template/template/common/index.ts b/packages/kbn-plugin-generator/sao_template/template/common/index.ts
new file mode 100644
index 0000000000000..90ffcb70045aa
--- /dev/null
+++ b/packages/kbn-plugin-generator/sao_template/template/common/index.ts
@@ -0,0 +1,2 @@
+export const PLUGIN_ID = '<%= camelCase(name) %>';
+export const PLUGIN_NAME = '<%= name %>';
diff --git a/packages/kbn-plugin-generator/sao_template/template/eslintrc.js b/packages/kbn-plugin-generator/sao_template/template/eslintrc.js
old mode 100755
new mode 100644
index e1dfadc212b7e..b68d42e32e047
--- a/packages/kbn-plugin-generator/sao_template/template/eslintrc.js
+++ b/packages/kbn-plugin-generator/sao_template/template/eslintrc.js
@@ -1,24 +1,9 @@
-module.exports = {
- root: true,
+module.exports = {
+ root: true,
extends: ['@elastic/eslint-config-kibana', 'plugin:@elastic/eui/recommended'],
- settings: {
- 'import/resolver': {
- '@kbn/eslint-import-resolver-kibana': {
- rootPackageName: '<%= snakeCase(name) %>',
- },
- },
- },
- overrides: [
- {
- files: ['**/public/**/*'],
- settings: {
- 'import/resolver': {
- '@kbn/eslint-import-resolver-kibana': {
- forceNode: false,
- rootPackageName: '<%= snakeCase(name) %>',
- },
- },
- },
- },
- ]
-};
+ <%_ if (!isKibanaPlugin) { -%>
+ rules: {
+ "@kbn/eslint/require-license-header": "off"
+ }
+ <%_ } -%>
+};
\ No newline at end of file
diff --git a/packages/kbn-plugin-generator/sao_template/template/gitignore b/packages/kbn-plugin-generator/sao_template/template/gitignore
deleted file mode 100755
index db28fed19376d..0000000000000
--- a/packages/kbn-plugin-generator/sao_template/template/gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-npm-debug.log*
-node_modules
-/build/
-<%_ if (generateScss) { -%>
-/public/app.css
-<%_ } -%>
diff --git a/packages/kbn-plugin-generator/sao_template/template/index.js b/packages/kbn-plugin-generator/sao_template/template/index.js
deleted file mode 100755
index 4bc3347ae6019..0000000000000
--- a/packages/kbn-plugin-generator/sao_template/template/index.js
+++ /dev/null
@@ -1,89 +0,0 @@
-<% if (generateScss) { -%>
-import { resolve } from 'path';
-import { existsSync } from 'fs';
-
-<% } -%>
-
-<% if (generateApp) { -%>
-import { i18n } from '@kbn/i18n';
-<% } -%>
-
-<% if (generateApi) { -%>
-import exampleRoute from './server/routes/example';
-
-<% } -%>
-export default function (kibana) {
- return new kibana.Plugin({
- require: ['elasticsearch'],
- name: '<%= snakeCase(name) %>',
- uiExports: {
- <%_ if (generateApp) { -%>
- app: {
- title: '<%= startCase(name) %>',
- description: '<%= description %>',
- main: 'plugins/<%= snakeCase(name) %>/app',
- },
- <%_ } -%>
- <%_ if (generateHack) { -%>
- hacks: [
- 'plugins/<%= snakeCase(name) %>/hack'
- ],
- <%_ } -%>
- <%_ if (generateScss) { -%>
- styleSheetPaths: [resolve(__dirname, 'public/app.scss'), resolve(__dirname, 'public/app.css')].find(p => existsSync(p)),
- <%_ } -%>
- },
-
- config(Joi) {
- return Joi.object({
- enabled: Joi.boolean().default(true),
- }).default();
- },
- <%_ if (generateApi || generateApp) { -%>
-
- // eslint-disable-next-line no-unused-vars
- init(server, options) {
- <%_ if (generateApp) { -%>
- const xpackMainPlugin = server.plugins.xpack_main;
- if (xpackMainPlugin) {
- const featureId = '<%= snakeCase(name) %>';
-
- xpackMainPlugin.registerFeature({
- id: featureId,
- name: i18n.translate('<%= camelCase(name) %>.featureRegistry.featureName', {
- defaultMessage: '<%= name %>',
- }),
- navLinkId: featureId,
- icon: 'questionInCircle',
- app: [featureId, 'kibana'],
- catalogue: [],
- privileges: {
- all: {
- api: [],
- savedObject: {
- all: [],
- read: [],
- },
- ui: ['show'],
- },
- read: {
- api: [],
- savedObject: {
- all: [],
- read: [],
- },
- ui: ['show'],
- },
- },
- });
- }
- <%_ } -%>
-
- <%_ if (generateApi) { -%>
- // Add server routes and initialize the plugin here
- exampleRoute(server);
- <%_ } -%>
- }
- <%_ } -%>
- });
-}
diff --git a/packages/kbn-plugin-generator/sao_template/template/kibana.json b/packages/kbn-plugin-generator/sao_template/template/kibana.json
new file mode 100644
index 0000000000000..f8bb07040abeb
--- /dev/null
+++ b/packages/kbn-plugin-generator/sao_template/template/kibana.json
@@ -0,0 +1,8 @@
+{
+ "id": "<%= camelCase(name) %>",
+ "version": "<%= kbnVersion %>",
+ "server": <%= hasServer %>,
+ "ui": <%= hasUi %>,
+ "requiredPlugins": ["navigation"],
+ "optionalPlugins": []
+}
diff --git a/packages/kbn-plugin-generator/sao_template/template/package_template.json b/packages/kbn-plugin-generator/sao_template/template/package_template.json
deleted file mode 100644
index 4b6629fa90268..0000000000000
--- a/packages/kbn-plugin-generator/sao_template/template/package_template.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "name": "<%= snakeCase(name) %>",
- "version": "0.0.0",
- "description": "<%= description %>",
- "main": "index.js",
- "kibana": {
- "version": "<%= (kbnVersion === 'master') ? 'kibana' : kbnVersion %>",
- "templateVersion": "<%= templateVersion %>"
- },
- "scripts": {
- "preinstall": "node ../../preinstall_check",
- "kbn": "node ../../scripts/kbn",
- "es": "node ../../scripts/es",
- "lint": "eslint .",
- "start": "plugin-helpers start",
- "test:server": "plugin-helpers test:server",
- "test:browser": "plugin-helpers test:browser",
- "build": "plugin-helpers build"
- },
- <%_ if (generateTranslations) { _%>
- "dependencies": {
- "@kbn/i18n": "link:../../packages/kbn-i18n"
- },
- <%_ } _%>
- "devDependencies": {
- "@elastic/eslint-config-kibana": "link:../../packages/eslint-config-kibana",
- "@elastic/eslint-import-resolver-kibana": "link:../../packages/kbn-eslint-import-resolver-kibana",
- "@kbn/expect": "link:../../packages/kbn-expect",
- "@kbn/plugin-helpers": "link:../../packages/kbn-plugin-helpers",
- "babel-eslint": "^10.0.1",
- "eslint": "^5.16.0",
- "eslint-plugin-babel": "^5.3.0",
- "eslint-plugin-import": "^2.16.0",
- "eslint-plugin-jest": "^22.4.1",
- "eslint-plugin-jsx-a11y": "^6.2.1",
- "eslint-plugin-mocha": "^5.3.0",
- "eslint-plugin-no-unsanitized": "^3.0.2",
- "eslint-plugin-prefer-object-spread": "^1.2.1",
- "eslint-plugin-react": "^7.12.4"
- }
-}
diff --git a/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js b/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js
deleted file mode 100755
index 9320bd7b028a8..0000000000000
--- a/packages/kbn-plugin-generator/sao_template/template/public/__tests__/index.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import expect from '@kbn/expect';
-
-describe('suite', () => {
- it('is a test', () => {
- expect(true).to.equal(true);
- });
-});
diff --git a/packages/kbn-plugin-generator/sao_template/template/public/app.js b/packages/kbn-plugin-generator/sao_template/template/public/app.js
deleted file mode 100755
index 37a7c37e916a0..0000000000000
--- a/packages/kbn-plugin-generator/sao_template/template/public/app.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from 'react';
-import { uiModules } from 'ui/modules';
-import chrome from 'ui/chrome';
-import { render, unmountComponentAtNode } from 'react-dom';
-<%_ if (generateTranslations) { _%>
-import { I18nProvider } from '@kbn/i18n/react';
-<%_ } _%>
-
-import { Main } from './components/main';
-
-const app = uiModules.get('apps/<%= camelCase(name) %>');
-
-app.config($locationProvider => {
- $locationProvider.html5Mode({
- enabled: false,
- requireBase: false,
- rewriteLinks: false,
- });
-});
-app.config(stateManagementConfigProvider =>
- stateManagementConfigProvider.disable()
-);
-
-function RootController($scope, $element, $http) {
- const domNode = $element[0];
-
- // render react to DOM
- <%_ if (generateTranslations) { _%>
- render(
-
+
+
- <%_ if (generateTranslations) { _%>
-
-
-
-
-
-