diff --git a/package.json b/package.json index 91013bc12f347..bc6958f7973e2 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/packages/kbn-optimizer/src/worker/webpack.config.ts b/packages/kbn-optimizer/src/worker/webpack.config.ts index 5d8ef7626f630..dabfed7f9725c 100644 --- a/packages/kbn-optimizer/src/worker/webpack.config.ts +++ b/packages/kbn-optimizer/src/worker/webpack.config.ts @@ -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', diff --git a/packages/kbn-storybook/storybook_config/middleware.js b/packages/kbn-storybook/storybook_config/middleware.js index f517477b405bd..046758948b2cf 100644 --- a/packages/kbn-storybook/storybook_config/middleware.js +++ b/packages/kbn-storybook/storybook_config/middleware.js @@ -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'))); }; diff --git a/src/core/MIGRATION.md b/src/core/MIGRATION.md index 50fd1f716ba37..26637fc01c0b7 100644 --- a/src/core/MIGRATION.md +++ b/src/core/MIGRATION.md @@ -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 diff --git a/src/core/MIGRATION_EXAMPLES.md b/src/core/MIGRATION_EXAMPLES.md index 29edef476d7c3..37d0b9297ed3c 100644 --- a/src/core/MIGRATION_EXAMPLES.md +++ b/src/core/MIGRATION_EXAMPLES.md @@ -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. \ No newline at end of file +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(), + }, + }) +} +``` \ No newline at end of file diff --git a/src/legacy/ui/public/assets/favicons/android-chrome-192x192.png b/src/core/server/core_app/assets/favicons/android-chrome-192x192.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/android-chrome-192x192.png rename to src/core/server/core_app/assets/favicons/android-chrome-192x192.png diff --git a/src/legacy/ui/public/assets/favicons/android-chrome-256x256.png b/src/core/server/core_app/assets/favicons/android-chrome-256x256.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/android-chrome-256x256.png rename to src/core/server/core_app/assets/favicons/android-chrome-256x256.png diff --git a/src/legacy/ui/public/assets/favicons/android-chrome-512x512.png b/src/core/server/core_app/assets/favicons/android-chrome-512x512.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/android-chrome-512x512.png rename to src/core/server/core_app/assets/favicons/android-chrome-512x512.png diff --git a/src/legacy/ui/public/assets/favicons/apple-touch-icon.png b/src/core/server/core_app/assets/favicons/apple-touch-icon.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/apple-touch-icon.png rename to src/core/server/core_app/assets/favicons/apple-touch-icon.png diff --git a/src/legacy/ui/public/assets/favicons/browserconfig.xml b/src/core/server/core_app/assets/favicons/browserconfig.xml similarity index 100% rename from src/legacy/ui/public/assets/favicons/browserconfig.xml rename to src/core/server/core_app/assets/favicons/browserconfig.xml diff --git a/src/legacy/ui/public/assets/favicons/favicon-16x16.png b/src/core/server/core_app/assets/favicons/favicon-16x16.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/favicon-16x16.png rename to src/core/server/core_app/assets/favicons/favicon-16x16.png diff --git a/src/legacy/ui/public/assets/favicons/favicon-32x32.png b/src/core/server/core_app/assets/favicons/favicon-32x32.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/favicon-32x32.png rename to src/core/server/core_app/assets/favicons/favicon-32x32.png diff --git a/src/legacy/ui/public/assets/favicons/favicon.ico b/src/core/server/core_app/assets/favicons/favicon.ico similarity index 100% rename from src/legacy/ui/public/assets/favicons/favicon.ico rename to src/core/server/core_app/assets/favicons/favicon.ico diff --git a/src/legacy/ui/public/assets/favicons/manifest.json b/src/core/server/core_app/assets/favicons/manifest.json similarity index 100% rename from src/legacy/ui/public/assets/favicons/manifest.json rename to src/core/server/core_app/assets/favicons/manifest.json diff --git a/src/legacy/ui/public/assets/favicons/mstile-144x144.png b/src/core/server/core_app/assets/favicons/mstile-144x144.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/mstile-144x144.png rename to src/core/server/core_app/assets/favicons/mstile-144x144.png diff --git a/src/legacy/ui/public/assets/favicons/mstile-150x150.png b/src/core/server/core_app/assets/favicons/mstile-150x150.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/mstile-150x150.png rename to src/core/server/core_app/assets/favicons/mstile-150x150.png diff --git a/src/legacy/ui/public/assets/favicons/mstile-310x150.png b/src/core/server/core_app/assets/favicons/mstile-310x150.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/mstile-310x150.png rename to src/core/server/core_app/assets/favicons/mstile-310x150.png diff --git a/src/legacy/ui/public/assets/favicons/mstile-310x310.png b/src/core/server/core_app/assets/favicons/mstile-310x310.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/mstile-310x310.png rename to src/core/server/core_app/assets/favicons/mstile-310x310.png diff --git a/src/legacy/ui/public/assets/favicons/mstile-70x70.png b/src/core/server/core_app/assets/favicons/mstile-70x70.png similarity index 100% rename from src/legacy/ui/public/assets/favicons/mstile-70x70.png rename to src/core/server/core_app/assets/favicons/mstile-70x70.png diff --git a/src/legacy/ui/public/assets/favicons/safari-pinned-tab.svg b/src/core/server/core_app/assets/favicons/safari-pinned-tab.svg similarity index 100% rename from src/legacy/ui/public/assets/favicons/safari-pinned-tab.svg rename to src/core/server/core_app/assets/favicons/safari-pinned-tab.svg diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Black.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Black.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Black.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Black.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Black.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Black.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Black.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Black.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-BlackItalic.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-BlackItalic.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-BlackItalic.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-BlackItalic.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-BlackItalic.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-BlackItalic.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-BlackItalic.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-BlackItalic.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Bold.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Bold.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Bold.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Bold.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Bold.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Bold.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Bold.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Bold.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-BoldItalic.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-BoldItalic.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-BoldItalic.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-BoldItalic.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-BoldItalic.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-BoldItalic.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-BoldItalic.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-BoldItalic.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraBold.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraBold.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraBold.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraBold.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraBold.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraBold.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraBold.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraBold.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraBoldItalic.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraBoldItalic.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraBoldItalic.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraBoldItalic.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraBoldItalic.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraBoldItalic.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraBoldItalic.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraBoldItalic.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraLight-BETA.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraLight-BETA.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraLight-BETA.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraLight-BETA.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraLight-BETA.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraLight-BETA.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraLight-BETA.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraLight-BETA.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraLightItalic-BETA.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraLightItalic-BETA.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraLightItalic-BETA.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraLightItalic-BETA.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraLightItalic-BETA.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraLightItalic-BETA.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ExtraLightItalic-BETA.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ExtraLightItalic-BETA.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Italic.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Italic.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Italic.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Italic.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Italic.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Italic.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Italic.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Italic.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Light-BETA.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Light-BETA.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Light-BETA.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Light-BETA.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Light-BETA.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Light-BETA.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Light-BETA.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Light-BETA.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-LightItalic-BETA.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-LightItalic-BETA.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-LightItalic-BETA.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-LightItalic-BETA.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-LightItalic-BETA.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-LightItalic-BETA.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-LightItalic-BETA.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-LightItalic-BETA.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Medium.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Medium.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Medium.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Medium.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Medium.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Medium.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Medium.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Medium.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-MediumItalic.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-MediumItalic.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-MediumItalic.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-MediumItalic.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-MediumItalic.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-MediumItalic.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-MediumItalic.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-MediumItalic.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Regular.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Regular.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Regular.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Regular.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Regular.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Regular.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Regular.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Regular.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-SemiBold.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-SemiBold.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-SemiBold.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-SemiBold.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-SemiBold.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-SemiBold.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-SemiBold.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-SemiBold.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-SemiBoldItalic.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-SemiBoldItalic.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-SemiBoldItalic.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-SemiBoldItalic.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-SemiBoldItalic.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-SemiBoldItalic.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-SemiBoldItalic.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-SemiBoldItalic.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Thin-BETA.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Thin-BETA.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Thin-BETA.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Thin-BETA.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Thin-BETA.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Thin-BETA.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-Thin-BETA.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-Thin-BETA.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ThinItalic-BETA.woff b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ThinItalic-BETA.woff similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ThinItalic-BETA.woff rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ThinItalic-BETA.woff diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ThinItalic-BETA.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ThinItalic-BETA.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-ThinItalic-BETA.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-ThinItalic-BETA.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-italic.var.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-italic.var.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-italic.var.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-italic.var.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-upright.var.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-upright.var.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI-upright.var.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI-upright.var.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI.var.woff2 b/src/core/server/core_app/assets/fonts/inter_ui/Inter-UI.var.woff2 similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/Inter-UI.var.woff2 rename to src/core/server/core_app/assets/fonts/inter_ui/Inter-UI.var.woff2 diff --git a/src/legacy/ui/public/assets/fonts/inter_ui/LICENSE.txt b/src/core/server/core_app/assets/fonts/inter_ui/LICENSE.txt similarity index 100% rename from src/legacy/ui/public/assets/fonts/inter_ui/LICENSE.txt rename to src/core/server/core_app/assets/fonts/inter_ui/LICENSE.txt diff --git a/src/legacy/ui/public/assets/fonts/readme.md b/src/core/server/core_app/assets/fonts/readme.md similarity index 100% rename from src/legacy/ui/public/assets/fonts/readme.md rename to src/core/server/core_app/assets/fonts/readme.md diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/LICENSE.txt b/src/core/server/core_app/assets/fonts/roboto_mono/LICENSE.txt similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/LICENSE.txt rename to src/core/server/core_app/assets/fonts/roboto_mono/LICENSE.txt diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Bold.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Bold.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Bold.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Bold.ttf diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-BoldItalic.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-BoldItalic.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-BoldItalic.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-BoldItalic.ttf diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Italic.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Italic.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Italic.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Italic.ttf diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Light.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Light.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Light.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Light.ttf diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-LightItalic.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-LightItalic.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-LightItalic.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-LightItalic.ttf diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Medium.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Medium.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Medium.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Medium.ttf diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-MediumItalic.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-MediumItalic.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-MediumItalic.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-MediumItalic.ttf diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Regular.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Regular.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Regular.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Regular.ttf diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Thin.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Thin.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-Thin.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-Thin.ttf diff --git a/src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-ThinItalic.ttf b/src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-ThinItalic.ttf similarity index 100% rename from src/legacy/ui/public/assets/fonts/roboto_mono/RobotoMono-ThinItalic.ttf rename to src/core/server/core_app/assets/fonts/roboto_mono/RobotoMono-ThinItalic.ttf diff --git a/src/legacy/ui/public/assets/images/bg_bottom_branded.svg b/src/core/server/core_app/assets/images/bg_bottom_branded.svg similarity index 100% rename from src/legacy/ui/public/assets/images/bg_bottom_branded.svg rename to src/core/server/core_app/assets/images/bg_bottom_branded.svg diff --git a/src/legacy/ui/public/assets/images/bg_bottom_branded_dark.svg b/src/core/server/core_app/assets/images/bg_bottom_branded_dark.svg similarity index 100% rename from src/legacy/ui/public/assets/images/bg_bottom_branded_dark.svg rename to src/core/server/core_app/assets/images/bg_bottom_branded_dark.svg diff --git a/src/legacy/ui/public/assets/images/bg_top_branded.svg b/src/core/server/core_app/assets/images/bg_top_branded.svg similarity index 100% rename from src/legacy/ui/public/assets/images/bg_top_branded.svg rename to src/core/server/core_app/assets/images/bg_top_branded.svg diff --git a/src/legacy/ui/public/assets/images/bg_top_branded_dark.svg b/src/core/server/core_app/assets/images/bg_top_branded_dark.svg similarity index 100% rename from src/legacy/ui/public/assets/images/bg_top_branded_dark.svg rename to src/core/server/core_app/assets/images/bg_top_branded_dark.svg diff --git a/src/legacy/ui/public/assets/images/kibana.svg b/src/core/server/core_app/assets/images/kibana.svg similarity index 100% rename from src/legacy/ui/public/assets/images/kibana.svg rename to src/core/server/core_app/assets/images/kibana.svg diff --git a/src/core/server/core_app/core_app.ts b/src/core/server/core_app/core_app.ts index 2f8c85f47a76e..5e1a3794632ee 100644 --- a/src/core/server/core_app/core_app.ts +++ b/src/core/server/core_app/core_app.ts @@ -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') + ); + } } diff --git a/src/core/server/core_app/integration_tests/static_assets.test.ts b/src/core/server/core_app/integration_tests/static_assets.test.ts new file mode 100644 index 0000000000000..aad2510ef8c0e --- /dev/null +++ b/src/core/server/core_app/integration_tests/static_assets.test.ts @@ -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); + }); +}); diff --git a/src/core/server/http/base_path_proxy_server.ts b/src/core/server/http/base_path_proxy_server.ts index e418726465efa..acefbd00ae2be 100644 --- a/src/core/server/http/base_path_proxy_server.ts +++ b/src/core/server/http/base_path_proxy_server.ts @@ -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, diff --git a/src/core/server/http/http_server.ts b/src/core/server/http/http_server.ts index f898ed0ea1a99..77d3d99fb48cb 100644 --- a/src/core/server/http/http_server.ts +++ b/src/core/server/http/http_server.ts @@ -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 { 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 }, + }); + } } diff --git a/src/core/server/http/http_service.mock.ts b/src/core/server/http/http_service.mock.ts index 442bc93190d86..0788a8f2af7a1 100644 --- a/src/core/server/http/http_service.mock.ts +++ b/src/core/server/http/http_service.mock.ts @@ -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(), diff --git a/src/core/server/http/http_tools.test.ts b/src/core/server/http/http_tools.test.ts index c1322a5aa94db..bdaab4f2999ed 100644 --- a/src/core/server/http/http_tools.test.ts +++ b/src/core/server/http/http_tools.test.ts @@ -18,6 +18,8 @@ */ jest.mock('fs', () => ({ + // Hapi Inert patches native methods + ...jest.requireActual('fs'), readFileSync: jest.fn(), })); diff --git a/src/core/server/http/types.ts b/src/core/server/http/types.ts index 6327844108055..4be7e59acb7b9 100644 --- a/src/core/server/http/types.ts +++ b/src/core/server/http/types.ts @@ -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: ( pluginOpaqueId: PluginOpaqueId, diff --git a/src/core/server/legacy/legacy_service.test.ts b/src/core/server/legacy/legacy_service.test.ts index ef31be559b30b..c6860086e7784 100644 --- a/src/core/server/legacy/legacy_service.test.ts +++ b/src/core/server/legacy/legacy_service.test.ts @@ -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(), }, }, diff --git a/src/core/server/legacy/legacy_service.ts b/src/core/server/legacy/legacy_service.ts index 361fade6a4d0c..bb5f6d5617aae 100644 --- a/src/core/server/legacy/legacy_service.ts +++ b/src/core/server/legacy/legacy_service.ts @@ -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, diff --git a/src/core/server/plugins/plugins_service.test.ts b/src/core/server/plugins/plugins_service.test.ts index 4f69a2b4156be..14147ab9f2a8d 100644 --- a/src/core/server/plugins/plugins_service.test.ts +++ b/src/core/server/plugins/plugins_service.test.ts @@ -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": /path-1/public/assets, "publicTargetDir": /path-1/target/public, }, "plugin-2" => Object { + "publicAssetsDir": /path-2/public/assets, "publicTargetDir": /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); }); diff --git a/src/core/server/plugins/plugins_service.ts b/src/core/server/plugins/plugins_service.ts index 9987d1633c502..a0ecee47c675f 100644 --- a/src/core/server/plugins/plugins_service.ts +++ b/src/core/server/plugins/plugins_service.ts @@ -110,6 +110,7 @@ export class PluginsService implements CoreService { if (url.includes('eui_colors_light')) { return { file: url.replace('eui_colors_light', 'eui_colors_dark') }; diff --git a/src/legacy/ui/ui_render/ui_render_mixin.js b/src/legacy/ui/ui_render/ui_render_mixin.js index 0a1b95c23450b..99560b0bf653f 100644 --- a/src/legacy/ui/ui_render/ui_render_mixin.js +++ b/src/legacy/ui/ui_render/ui_render_mixin.js @@ -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', diff --git a/test/api_integration/services/supertest.js b/test/api_integration/services/supertest.ts similarity index 83% rename from test/api_integration/services/supertest.js rename to test/api_integration/services/supertest.ts index b53b4ae0ef32f..d5505c080468a 100644 --- a/test/api_integration/services/supertest.js +++ b/test/api_integration/services/supertest.ts @@ -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); diff --git a/test/common/fixtures/plugins/newsfeed/newsfeed_simulation.ts b/test/common/fixtures/plugins/newsfeed/newsfeed_simulation.ts index 4bf92868b0eca..5aa44b48f9d59 100644 --- a/test/common/fixtures/plugins/newsfeed/newsfeed_simulation.ts +++ b/test/common/fixtures/plugins/newsfeed/newsfeed_simulation.ts @@ -44,7 +44,7 @@ export async function initPlugin(server: Hapi.Server, path: string) { ], }, }, - handler: newsfeedHandler, + handler: newsfeedHandler as Hapi.Lifecycle.Method, }); server.route({ diff --git a/test/plugin_functional/plugins/core_plugin_static_assets/kibana.json b/test/plugin_functional/plugins/core_plugin_static_assets/kibana.json new file mode 100644 index 0000000000000..6f9fb94e9b49c --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_static_assets/kibana.json @@ -0,0 +1,7 @@ +{ + "id": "corePluginStaticAssets", + "version": "0.0.1", + "kibanaVersion": "kibana", + "server": false, + "ui": true +} diff --git a/test/plugin_functional/plugins/core_plugin_static_assets/package.json b/test/plugin_functional/plugins/core_plugin_static_assets/package.json new file mode 100644 index 0000000000000..304e1b11fde42 --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_static_assets/package.json @@ -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" + } +} diff --git a/test/plugin_functional/plugins/core_plugin_static_assets/public/assets/chart.svg b/test/plugin_functional/plugins/core_plugin_static_assets/public/assets/chart.svg new file mode 100644 index 0000000000000..44553960a5cce --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_static_assets/public/assets/chart.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/test/plugin_functional/plugins/core_plugin_static_assets/public/index.ts b/test/plugin_functional/plugins/core_plugin_static_assets/public/index.ts new file mode 100644 index 0000000000000..2bdb40cf19cb5 --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_static_assets/public/index.ts @@ -0,0 +1,22 @@ +/* + * 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 { CorePluginStaticAssets } from './plugin'; + +export const plugin = () => new CorePluginStaticAssets(); diff --git a/test/plugin_functional/plugins/core_plugin_static_assets/public/plugin.tsx b/test/plugin_functional/plugins/core_plugin_static_assets/public/plugin.tsx new file mode 100644 index 0000000000000..d9f3d62937584 --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_static_assets/public/plugin.tsx @@ -0,0 +1,27 @@ +/* + * 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 { Plugin, CoreSetup } from 'kibana/public'; + +export class CorePluginStaticAssets implements Plugin { + public setup(core: CoreSetup, deps: {}) {} + + public start() {} + public stop() {} +} diff --git a/test/plugin_functional/plugins/core_plugin_static_assets/tsconfig.json b/test/plugin_functional/plugins/core_plugin_static_assets/tsconfig.json new file mode 100644 index 0000000000000..4a564ee1e5578 --- /dev/null +++ b/test/plugin_functional/plugins/core_plugin_static_assets/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../../../tsconfig.json", + "compilerOptions": { + "outDir": "./target", + "skipLibCheck": true + }, + "include": [ + "index.ts", + "public/**/*.ts", + "public/**/*.tsx", + "../../../../typings/**/*" + ], + "exclude": [] +} diff --git a/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts b/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts index 82267d73782af..8ddd0ff96ba8f 100644 --- a/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts +++ b/test/plugin_functional/test_suites/core_plugins/ui_plugins.ts @@ -25,6 +25,7 @@ import '../../../../test/plugin_functional/plugins/core_provider_plugin/types'; export default function({ getService, getPageObjects }: PluginFunctionalProviderContext) { const PageObjects = getPageObjects(['common']); const browser = getService('browser'); + const supertest = getService('supertest'); describe('ui plugins', function() { describe('loading', function describeIndexTests() { @@ -97,5 +98,47 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider ).to.be('/core_plugin_b/system_request says: "System request? false"'); }); }); + + describe('Plugin static assets', function() { + it('exposes static assets from "public/assets" folder', async () => { + await supertest.get('/plugins/corePluginStaticAssets/assets/chart.svg').expect(200); + }); + + it('returns 404 if not found', async function() { + await supertest.get('/plugins/corePluginStaticAssets/assets/not-a-chart.svg').expect(404); + }); + + it('does not expose folder content', async function() { + await supertest.get('/plugins/corePluginStaticAssets/assets/').expect(403); + }); + + it('does not allow file tree traversing', async function() { + await supertest.get('/plugins/corePluginStaticAssets/assets/../../kibana.json').expect(404); + }); + + it('generates "etag" & "last-modified" headers', async () => { + const response = await supertest + .get('/plugins/corePluginStaticAssets/assets/chart.svg') + .expect(200); + + expect(response.header).to.have.property('etag'); + expect(response.header).to.have.property('last-modified'); + }); + + it('generates the same "etag" & "last-modified" for the same asset', async () => { + const firstResponse = await supertest + .get('/plugins/corePluginStaticAssets/assets/chart.svg') + .expect(200); + + expect(firstResponse.header).to.have.property('etag'); + + const secondResponse = await supertest + .get('/plugins/corePluginStaticAssets/assets/chart.svg') + .expect(200); + + expect(secondResponse.header.etag).to.be(firstResponse.header.etag); + expect(secondResponse.header['last-modified']).to.be(firstResponse.header['last-modified']); + }); + }); }); } diff --git a/x-pack/legacy/plugins/canvas/.storybook/middleware.js b/x-pack/legacy/plugins/canvas/.storybook/middleware.js index 46ae7ac90f364..8bbd2b6c1a22f 100644 --- a/x-pack/legacy/plugins/canvas/.storybook/middleware.js +++ b/x-pack/legacy/plugins/canvas/.storybook/middleware.js @@ -9,5 +9,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'))); }; diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/index.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/index.ts index 7194c642e7015..05139213b76b9 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/index.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/aad/index.ts @@ -42,7 +42,7 @@ export default function(kibana: any) { .required(), }, }, - async handler(request: CheckAADRequest) { + handler: (async (request: CheckAADRequest) => { let namespace: string | undefined; const spacesPlugin = server.plugins.spaces; if (spacesPlugin && request.payload.spaceId) { @@ -52,7 +52,7 @@ export default function(kibana: any) { namespace, }); return { success: true }; - }, + }) as Hapi.Lifecycle.Method, }); }, }); diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/pagerduty_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/pagerduty_simulation.ts index 977424aab88b7..1de1476fc4ff2 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/pagerduty_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/pagerduty_simulation.ts @@ -36,7 +36,7 @@ export function initPlugin(server: Hapi.Server, path: string) { }), }, }, - handler: pagerdutyHandler, + handler: pagerdutyHandler as Hapi.Lifecycle.Method, }); } // Pagerduty simulator: create an action pointing here, and you can get diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/servicenow_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/servicenow_simulation.ts index 329262044357b..a58738e387aeb 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/servicenow_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/servicenow_simulation.ts @@ -21,7 +21,7 @@ export function initPlugin(server: Hapi.Server, path: string) { options: { auth: false, }, - handler: createHandler, + handler: createHandler as Hapi.Lifecycle.Method, }); server.route({ @@ -35,7 +35,7 @@ export function initPlugin(server: Hapi.Server, path: string) { }), }, }, - handler: updateHandler, + handler: updateHandler as Hapi.Lifecycle.Method, }); server.route({ @@ -44,7 +44,7 @@ export function initPlugin(server: Hapi.Server, path: string) { options: { auth: false, }, - handler: getHandler, + handler: getHandler as Hapi.Lifecycle.Method, }); } diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/slack_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/slack_simulation.ts index a5d6df60be3f3..039f0c1b84a15 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/slack_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/slack_simulation.ts @@ -25,7 +25,7 @@ export function initPlugin(server: Hapi.Server, path: string) { }), }, }, - handler: slackHandler, + handler: slackHandler as Hapi.Lifecycle.Method, }); } // Slack simulator: create a slack action pointing here, and you can get diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/webhook_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/webhook_simulation.ts index 1b267f6c4976f..355245fc4929a 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/webhook_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions/webhook_simulation.ts @@ -52,7 +52,7 @@ export async function initPlugin(server: Hapi.Server, path: string) { payload: Joi.string(), }, }, - handler: webhookHandler, + handler: webhookHandler as Hapi.Lifecycle.Method, }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index 74e8e0f832299..efd707b59cd34 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -33,7 +33,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { }, }); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); objectRemover.add(Spaces.space1.id, response.body.id, 'action'); expect(response.body).to.eql({ id: response.body.id, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts index c2e5aa041055d..3faa54ee0b219 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts @@ -66,7 +66,7 @@ export default function({ getService }: FtrProviderContext) { }, }); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); expect(response.body).to.be.an('object'); const searchResult = await esTestIndexTool.search('action:test.index-record', reference); expect(searchResult.hits.total.value).to.eql(1); @@ -110,7 +110,7 @@ export default function({ getService }: FtrProviderContext) { }, }); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); expect(response.body).to.eql({ actionId: createdAction.id, status: 'error', @@ -180,7 +180,7 @@ export default function({ getService }: FtrProviderContext) { }, }); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); const searchResult = await esTestIndexTool.search('action:test.authorization', reference); expect(searchResult.hits.total.value).to.eql(1); const indexedRecord = searchResult.hits.hits[0]; diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/list_action_types.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/list_action_types.ts index fa3941dad3795..dca3769d38e12 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/list_action_types.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/list_action_types.ts @@ -23,7 +23,7 @@ export default function listActionTypesTests({ getService }: FtrProviderContext) }; } - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); // Check for values explicitly in order to avoid this test failing each time plugins register // a new action type expect( diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts index 1388108806c0f..18a0ecc23c1e1 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/type_not_enabled.ts @@ -29,7 +29,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) actionTypeId: DISABLED_ACTION_TYPE, }); - expect(response.statusCode).to.eql(403); + expect(response.status).to.eql(403); expect(response.body).to.eql({ statusCode: 403, error: 'Forbidden', @@ -46,7 +46,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) params: {}, }); - expect(response.statusCode).to.eql(403); + expect(response.status).to.eql(403); expect(response.body).to.eql({ statusCode: 403, error: 'Forbidden', @@ -58,7 +58,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) it('should handle get action request with disabled actionType appropriately', async () => { const response = await supertest.get(`/api/action/${PREWRITTEN_ACTION_ID}`); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); expect(response.body).to.eql({ actionTypeId: 'test.not-enabled', config: {}, @@ -75,7 +75,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) name: 'an action created before test.not-enabled was disabled (updated)', }); - expect(responseUpdate.statusCode).to.eql(403); + expect(responseUpdate.status).to.eql(403); expect(responseUpdate.body).to.eql({ statusCode: 403, error: 'Forbidden', @@ -84,7 +84,7 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) }); const response = await supertest.get(`/api/action/${PREWRITTEN_ACTION_ID}`); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); expect(response.body).to.eql({ actionTypeId: 'test.not-enabled', config: {}, @@ -99,10 +99,10 @@ export default function typeNotEnabledTests({ getService }: FtrProviderContext) response = await supertest .delete(`/api/action/${PREWRITTEN_ACTION_ID}`) .set('kbn-xsrf', 'foo'); - expect(response.statusCode).to.eql(204); + expect(response.status).to.eql(204); response = await supertest.get(`/api/action/${PREWRITTEN_ACTION_ID}`); - expect(response.statusCode).to.eql(404); + expect(response.status).to.eql(404); }); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts index 8f161cfa37c93..c98e3abe75ab1 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/builtin_alert_types/index_threshold/alert.ts @@ -341,7 +341,7 @@ export default function alertTests({ getService }: FtrProviderContext) { }, }; - const { statusCode, body: createdAlert } = await supertest + const { status, body: createdAlert } = await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/api/alert`) .set('kbn-xsrf', 'foo') .send({ @@ -369,7 +369,7 @@ export default function alertTests({ getService }: FtrProviderContext) { // will print the error body, if an error occurred // if (statusCode !== 200) console.log(createdAlert); - expect(statusCode).to.be(200); + expect(status).to.be(200); const alertId = createdAlert.id; objectRemover.add(Spaces.space1.id, alertId, 'alert'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts index 50e01c65b6a86..319834452a212 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/create.ts @@ -53,7 +53,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { }) ); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); objectRemover.add(Spaces.space1.id, response.body.id, 'alert'); expect(response.body).to.eql({ id: response.body.id, @@ -108,7 +108,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { .set('kbn-xsrf', 'foo') .send(getTestAlertData({ enabled: false })); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); objectRemover.add(Spaces.space1.id, response.body.id, 'alert'); expect(response.body.scheduledTaskId).to.eql(undefined); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts index 1dd0426c97cca..5f50c0d64f353 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/find.ts @@ -32,7 +32,7 @@ export default function createFindTests({ getService }: FtrProviderContext) { )}/api/alert/_find?search=test.noop&search_fields=alertTypeId` ); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); expect(response.body.page).to.equal(1); expect(response.body.perPage).to.be.greaterThan(0); expect(response.body.total).to.be.greaterThan(0); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get.ts index 30b5e43aee585..66cd8a7244081 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get.ts @@ -30,7 +30,7 @@ export default function createGetTests({ getService }: FtrProviderContext) { `${getUrlPrefix(Spaces.space1.id)}/api/alert/${createdAlert.id}` ); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); expect(response.body).to.eql({ id: createdAlert.id, name: 'abc', diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get_alert_state.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get_alert_state.ts index 053df3b7199cc..6f1aec901760e 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get_alert_state.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/get_alert_state.ts @@ -31,7 +31,7 @@ export default function createGetAlertStateTests({ getService }: FtrProviderCont `${getUrlPrefix(Spaces.space1.id)}/api/alert/${createdAlert.id}/state` ); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); expect(response.body).to.key('alertInstances', 'previousStartedAt'); }); @@ -59,7 +59,7 @@ export default function createGetAlertStateTests({ getService }: FtrProviderCont `${getUrlPrefix(Spaces.space1.id)}/api/alert/${createdAlert.id}/state` ); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); expect(response.body).to.key('alertInstances', 'alertTypeState', 'previousStartedAt'); expect(response.body.alertTypeState.runCount).to.greaterThan(1); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/list_alert_types.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/list_alert_types.ts index fbcf744b96916..fabc6884b5f96 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/list_alert_types.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/list_alert_types.ts @@ -16,7 +16,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) { describe('list_alert_types', () => { it('should return 200 with list of alert types', async () => { const response = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/alert/types`); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); const fixtureAlertType = response.body.find((alertType: any) => alertType.id === 'test.noop'); expect(fixtureAlertType).to.eql({ actionGroups: [{ id: 'default', name: 'Default' }], @@ -32,7 +32,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) { it('should return actionVariables with both context and state', async () => { const response = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/alert/types`); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); const fixtureAlertType = response.body.find( (alertType: any) => alertType.id === 'test.always-firing' @@ -46,7 +46,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) { it('should return actionVariables with just context', async () => { const response = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/alert/types`); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); const fixtureAlertType = response.body.find( (alertType: any) => alertType.id === 'test.onlyContextVariables' @@ -60,7 +60,7 @@ export default function listAlertTypes({ getService }: FtrProviderContext) { it('should return actionVariables with just state', async () => { const response = await supertest.get(`${getUrlPrefix(Spaces.space1.id)}/api/alert/types`); - expect(response.statusCode).to.eql(200); + expect(response.status).to.eql(200); const fixtureAlertType = response.body.find( (alertType: any) => alertType.id === 'test.onlyStateVariables' diff --git a/x-pack/test/api_integration/apis/apm/agent_configuration.ts b/x-pack/test/api_integration/apis/apm/agent_configuration.ts index 8cabac523791c..41d78995711f2 100644 --- a/x-pack/test/api_integration/apis/apm/agent_configuration.ts +++ b/x-pack/test/api_integration/apis/apm/agent_configuration.ts @@ -83,8 +83,8 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte }); it('can find the created config', async () => { - const { statusCode, body } = await searchConfigurations(searchParams); - expect(statusCode).to.equal(200); + const { status, body } = await searchConfigurations(searchParams); + expect(status).to.equal(200); expect(body._source.service).to.eql({}); expect(body._source.settings).to.eql({ transaction_sample_rate: '0.55' }); }); @@ -92,16 +92,16 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte it('can update the created config', async () => { await updateConfiguration({ service: {}, settings: { transaction_sample_rate: '0.85' } }); - const { statusCode, body } = await searchConfigurations(searchParams); - expect(statusCode).to.equal(200); + const { status, body } = await searchConfigurations(searchParams); + expect(status).to.equal(200); expect(body._source.service).to.eql({}); expect(body._source.settings).to.eql({ transaction_sample_rate: '0.85' }); }); it('can delete the created config', async () => { await deleteConfiguration(newConfig); - const { statusCode } = await searchConfigurations(searchParams); - expect(statusCode).to.equal(404); + const { status } = await searchConfigurations(searchParams); + expect(status).to.equal(404); }); }); @@ -166,12 +166,12 @@ export default function agentConfigurationTests({ getService }: FtrProviderConte for (const agentRequest of agentsRequests) { it(`${agentRequest.service.name} / ${agentRequest.service.environment}`, async () => { - const { statusCode, body } = await searchConfigurations({ + const { status, body } = await searchConfigurations({ service: agentRequest.service, etag: 'abc', }); - expect(statusCode).to.equal(200); + expect(status).to.equal(200); expect(body._source.settings).to.eql(agentRequest.expectedSettings); }); } diff --git a/x-pack/test/api_integration/apis/apm/feature_controls.ts b/x-pack/test/api_integration/apis/apm/feature_controls.ts index afe68f21d9e39..8ce55b8fb1d5f 100644 --- a/x-pack/test/api_integration/apis/apm/feature_controls.ts +++ b/x-pack/test/api_integration/apis/apm/feature_controls.ts @@ -182,8 +182,8 @@ export default function featureControlsTests({ getService }: FtrProviderContext) async function executeAsAdmin({ method = 'get', url, body }: Endpoint['req'], spaceId?: string) { const basePath = spaceId ? `/s/${spaceId}` : ''; - - let request = supertest[method](`${basePath}${url}`); + const fullPath = `${basePath}${url}`; + let request = supertest[method](fullPath); // json body if (body) { @@ -192,10 +192,10 @@ export default function featureControlsTests({ getService }: FtrProviderContext) const response = await request.set('kbn-xsrf', 'foo'); - const { statusCode, req } = response; - if (statusCode !== 200) { - throw new Error(`Endpoint: ${req.method} ${req.path} - Status code: ${statusCode} + const { status } = response; + if (status !== 200) { + throw new Error(`Endpoint: ${method} ${fullPath} + Status code: ${status} Response: ${response.body.message}`); } diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_rules.ts index ee34e5e261987..a886a5fb07a6c 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_rules.ts @@ -48,7 +48,6 @@ export default ({ getService }: FtrProviderContext): void => { const { body } = await supertest .delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=rule-1`) .set('kbn-xsrf', 'true') - .query() .expect(200); const bodyToCompare = removeServerGeneratedProperties(body); @@ -67,7 +66,6 @@ export default ({ getService }: FtrProviderContext): void => { const { body } = await supertest .delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=${bodyWithCreatedRule.rule_id}`) .set('kbn-xsrf', 'true') - .query() .expect(200); const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body); @@ -86,7 +84,6 @@ export default ({ getService }: FtrProviderContext): void => { const { body } = await supertest .delete(`${DETECTION_ENGINE_RULES_URL}?id=${bodyWithCreatedRule.id}`) .set('kbn-xsrf', 'true') - .query() .expect(200); const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body); @@ -97,7 +94,6 @@ export default ({ getService }: FtrProviderContext): void => { const { body } = await supertest .delete(`${DETECTION_ENGINE_RULES_URL}?id=fake_id`) .set('kbn-xsrf', 'true') - .query() .expect(404); expect(body).to.eql({ @@ -110,7 +106,6 @@ export default ({ getService }: FtrProviderContext): void => { const { body } = await supertest .delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=fake_id`) .set('kbn-xsrf', 'true') - .query() .expect(404); expect(body).to.eql({ diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_rules_bulk.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_rules_bulk.ts index 6b87c94029189..9e9071b82884f 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_rules_bulk.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/delete_rules_bulk.ts @@ -49,7 +49,6 @@ export default ({ getService }: FtrProviderContext): void => { .delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .set('kbn-xsrf', 'true') .send([{ rule_id: 'rule-1' }]) - .query() .expect(200); const bodyToCompare = removeServerGeneratedProperties(body[0]); @@ -69,7 +68,6 @@ export default ({ getService }: FtrProviderContext): void => { .delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ rule_id: bodyWithCreatedRule.rule_id }]) .set('kbn-xsrf', 'true') - .query() .expect(200); const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]); @@ -89,7 +87,6 @@ export default ({ getService }: FtrProviderContext): void => { .delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ id: bodyWithCreatedRule.id }]) .set('kbn-xsrf', 'true') - .query() .expect(200); const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]); @@ -101,7 +98,6 @@ export default ({ getService }: FtrProviderContext): void => { .delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ rule_id: 'fake_id' }]) .set('kbn-xsrf', 'true') - .query() .expect(200); expect(body).to.eql([ @@ -120,7 +116,6 @@ export default ({ getService }: FtrProviderContext): void => { .delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ id: 'fake_id' }]) .set('kbn-xsrf', 'true') - .query() .expect(200); expect(body).to.eql([ @@ -146,7 +141,6 @@ export default ({ getService }: FtrProviderContext): void => { .delete(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ id: bodyWithCreatedRule.id }, { id: 'fake_id' }]) .set('kbn-xsrf', 'true') - .query() .expect(200); const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]); @@ -182,7 +176,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .set('kbn-xsrf', 'true') .send([{ rule_id: 'rule-1' }]) - .query() .expect(200); const bodyToCompare = removeServerGeneratedProperties(body[0]); @@ -202,7 +195,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ rule_id: bodyWithCreatedRule.rule_id }]) .set('kbn-xsrf', 'true') - .query() .expect(200); const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]); @@ -222,7 +214,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ id: bodyWithCreatedRule.id }]) .set('kbn-xsrf', 'true') - .query() .expect(200); const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]); @@ -234,7 +225,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ rule_id: 'fake_id' }]) .set('kbn-xsrf', 'true') - .query() .expect(200); expect(body).to.eql([ @@ -253,7 +243,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ id: 'fake_id' }]) .set('kbn-xsrf', 'true') - .query() .expect(200); expect(body).to.eql([ @@ -279,7 +268,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_bulk_delete`) .send([{ id: bodyWithCreatedRule.id }, { id: 'fake_id' }]) .set('kbn-xsrf', 'true') - .query() .expect(200); const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/export_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/export_rules.ts index 8882448dfcdc2..a8f841db94bbc 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/export_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/export_rules.ts @@ -45,7 +45,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_export`) .set('kbn-xsrf', 'true') .send() - .query() .expect(200) .expect('Content-Type', 'application/ndjson') .expect('Content-Disposition', 'attachment; filename="export.ndjson"'); @@ -62,7 +61,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_export`) .set('kbn-xsrf', 'true') .send() - .query() .expect(200) .parse(binaryToString); @@ -83,7 +81,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_export`) .set('kbn-xsrf', 'true') .send() - .query() .expect(200) .parse(binaryToString); @@ -115,7 +112,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_export`) .set('kbn-xsrf', 'true') .send() - .query() .expect(200) .parse(binaryToString); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts index a1cb60483c332..ae4589e32ec11 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/tests/import_rules.ts @@ -40,7 +40,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.ndjson') - .query() .expect('Content-Type', 'application/json; charset=utf-8') .expect(200); }); @@ -50,7 +49,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.txt') - .query() .expect(400); expect(body).to.eql({ @@ -64,7 +62,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.ndjson') - .query() .expect(200); expect(body).to.eql({ @@ -79,7 +76,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(new Array(10001).fill('rule-1')), 'rules.ndjson') - .query() .expect(500); expect(body).to.eql({ message: "Can't import more than 10000 rules", status_code: 500 }); @@ -90,7 +86,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.ndjson') - .query() .expect(200); const { body } = await supertest @@ -107,7 +102,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1', 'rule-2']), 'rules.ndjson') - .query() .expect(200); expect(body).to.eql({ @@ -122,7 +116,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1', 'rule-1']), 'rules.ndjson') - .query() .expect(200); expect(body).to.eql({ @@ -145,7 +138,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import?overwrite=true`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1', 'rule-1']), 'rules.ndjson') - .query() .expect(200); expect(body).to.eql({ @@ -160,14 +152,12 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.ndjson') - .query() .expect(200); const { body } = await supertest .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.ndjson') - .query() .expect(200); expect(body).to.eql({ @@ -190,14 +180,12 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import?overwrite=true`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.ndjson') - .query() .expect(200); const { body } = await supertest .post(`${DETECTION_ENGINE_RULES_URL}/_import?overwrite=true`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.ndjson') - .query() .expect(200); expect(body).to.eql({ @@ -212,7 +200,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.ndjson') - .query() .expect(200); const simpleRule = getSimpleRule('rule-1'); @@ -223,7 +210,6 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import?overwrite=true`) .set('kbn-xsrf', 'true') .attach('file', ndjson, 'rules.ndjson') - .query() .expect(200); const { body } = await supertest @@ -243,14 +229,12 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1']), 'rules.ndjson') - .query() .expect(200); const { body } = await supertest .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1', 'rule-2', 'rule-3']), 'rules.ndjson') - .query() .expect(200); expect(body).to.eql({ @@ -273,14 +257,12 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1', 'rule-2']), 'rules.ndjson') - .query() .expect(200); const { body } = await supertest .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1', 'rule-2', 'rule-3']), 'rules.ndjson') - .query() .expect(200); expect(body).to.eql({ @@ -310,14 +292,12 @@ export default ({ getService }: FtrProviderContext): void => { .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1', 'rule-2']), 'rules.ndjson') - .query() .expect(200); await supertest .post(`${DETECTION_ENGINE_RULES_URL}/_import`) .set('kbn-xsrf', 'true') .attach('file', getSimpleRuleAsNdjson(['rule-1', 'rule-2', 'rule-3']), 'rules.ndjson') - .query() .expect(200); const { body: bodyOfRule1 } = await supertest diff --git a/x-pack/test/licensing_plugin/legacy/updates.ts b/x-pack/test/licensing_plugin/legacy/updates.ts index efd5df5d14511..5fa1299d1f285 100644 --- a/x-pack/test/licensing_plugin/legacy/updates.ts +++ b/x-pack/test/licensing_plugin/legacy/updates.ts @@ -27,7 +27,7 @@ export default function(ftrContext: FtrProviderContext) { const { body: legacyInitialLicense, - headers: legacyInitialLicenseHeaders, + header: legacyInitialLicenseHeaders, } = await supertest.get('/api/xpack/v1/info').expect(200); expect(legacyInitialLicense.license?.type).to.be('basic'); @@ -37,7 +37,7 @@ export default function(ftrContext: FtrProviderContext) { await scenario.startTrial(); await scenario.waitForPluginToDetectLicenseUpdate(); - const { body: legacyTrialLicense, headers: legacyTrialLicenseHeaders } = await supertest + const { body: legacyTrialLicense, header: legacyTrialLicenseHeaders } = await supertest .get('/api/xpack/v1/info') .expect(200); @@ -50,7 +50,7 @@ export default function(ftrContext: FtrProviderContext) { await scenario.startBasic(); await scenario.waitForPluginToDetectLicenseUpdate(); - const { body: legacyBasicLicense, headers: legacyBasicLicenseHeaders } = await supertest + const { body: legacyBasicLicense, header: legacyBasicLicenseHeaders } = await supertest .get('/api/xpack/v1/info') .expect(200); expect(legacyBasicLicense.license?.type).to.be('basic'); diff --git a/yarn.lock b/yarn.lock index d483db8e27de1..aab51b5665fb7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3930,6 +3930,15 @@ "@types/vinyl-fs" "*" chokidar "^2.1.2" +"@types/h2o2@^8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@types/h2o2/-/h2o2-8.1.1.tgz#f990302cd2fdfd7909cff9d6643052002b69998f" + integrity sha512-lwF9WSvo4sfT0TnDZDXKef9Yza4xUXC3561QG4Q3Axhrkr+ZFBVJ7kCwI1mUNzk60jI1aMTYVIIoHKZjwCGuHw== + dependencies: + "@types/boom" "*" + "@types/hapi" "*" + "@types/node" "*" + "@types/hapi-auth-cookie@^9.1.0": version "9.1.0" resolved "https://registry.yarnpkg.com/@types/hapi-auth-cookie/-/hapi-auth-cookie-9.1.0.tgz#cbcd2236b7d429bd0632a8cc45cfd355fdd7e7a2" @@ -3997,6 +4006,13 @@ resolved "https://registry.yarnpkg.com/@types/indent-string/-/indent-string-3.0.0.tgz#9ebb391ceda548926f5819ad16405349641b999f" integrity sha1-nrs5HO2lSJJvWBmtFkBTSWQbmZ8= +"@types/inert@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/inert/-/inert-5.1.2.tgz#2bb8bef3b2462f904c960654c9edfa39285a85c6" + integrity sha512-3IoSFLQWvhLfZ85kHas/F3iD/TyZPfeJbTsDjrwYljK1MgBGCB2OywAsyeA/YiJ62VbNXfXBwpD1/VbJPIZSGA== + dependencies: + "@types/hapi" "*" + "@types/intl-relativeformat@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@types/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz#3a2b0043380388f39c666665ec517e11412f1358"