From 4c49d5d1be0b959be515307131c1a420226c372b Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Thu, 12 Nov 2020 22:00:57 +0100 Subject: [PATCH] Upgrade Node.js to version 12 (#61587) --- .ci/Dockerfile | 2 +- .node-version | 2 +- .nvmrc | 2 +- docs/setup/settings.asciidoc | 6 +- package.json | 8 +- .../src/types/stream_type.test.ts | 8 +- .../kbn-dev-utils/src/proc_runner/proc.ts | 8 +- .../tooling_log_text_writer.test.ts.snap | 3 +- packages/kbn-es-archiver/src/actions/load.ts | 2 +- .../streams/concat_stream_providers.test.js | 2 +- .../lib/streams/concat_stream_providers.ts | 2 +- .../src/__snapshots__/loader.test.ts.snap | 2 +- .../basic_optimization.test.ts | 1 - .../kbn-optimizer/src/optimizer/get_mtimes.ts | 2 +- .../src/optimizer/observe_worker.ts | 6 +- packages/kbn-pm/dist/index.js | 9 +- packages/kbn-pm/src/commands/watch.ts | 2 +- packages/kbn-pm/src/utils/child_process.ts | 4 +- .../lib/docker_servers/container_logs.ts | 4 +- .../lib/lifecycle_phase.test.ts | 8 +- packages/kbn-test/src/kbn/kbn_test_config.ts | 4 +- src/cli/repl/__snapshots__/repl.test.js.snap | 30 ++- .../reload_logging_config.test.ts | 10 +- src/core/public/http/types.ts | 19 +- src/core/public/public.api.md | 3 +- src/core/public/utils/crypto/sha256.ts | 14 +- .../core_usage_data_service.test.ts | 4 + .../client/configure_client.test.ts | 1 - .../__snapshots__/http_config.test.ts.snap | 4 + src/core/server/http/http_server.test.ts | 2 +- src/core/server/http/http_tools.test.ts | 4 +- .../http/router/validator/validator.test.ts | 2 +- src/core/server/http/ssl_config.test.ts | 23 ++- src/core/server/http/ssl_config.ts | 17 +- .../appenders/file/file_appender.test.ts | 4 +- .../logging/appenders/file/file_appender.ts | 2 +- .../server/metrics/metrics_service.test.ts | 32 ++-- .../streams/concat_stream_providers.test.ts | 2 +- .../utils/streams/concat_stream_providers.ts | 2 +- src/dev/build/lib/scan_delete.ts | 2 +- src/dev/build/lib/watch_stdio_for_line.ts | 4 +- src/dev/build/tasks/bin/scripts/kibana | 2 +- .../build/tasks/patch_native_modules_task.ts | 12 +- src/dev/prs/run_update_prs_cli.ts | 5 +- .../__tests__/integration.test.js | 2 +- .../actions/clone_panel_action.test.tsx | 1 + .../__snapshots__/data_view.test.tsx.snap | 2 + .../core/create_start_service_getter.test.ts | 2 + .../state_management/url/kbn_url_storage.ts | 5 +- .../routes/lib/short_url_assert_valid.ts | 2 +- src/setup_node_env/exit_on_warning.js | 73 +++++++- .../services/remote/create_stdout_stream.ts | 2 +- .../server/builtin_action_types/slack.ts | 1 + .../api/__tests__/shareable.test.tsx | 1 - .../server/services/epm/registry/requests.ts | 1 + .../operations/operations.test.ts | 4 +- .../xy_visualization/xy_suggestions.test.ts | 32 ++-- .../common/format_timestamp_to_duration.js | 6 +- .../chromium/driver/chromium_driver.ts | 8 +- .../export_types/common/get_full_urls.ts | 6 +- .../utils/clone_http_fetch_query.test.ts | 3 +- .../public/management/common/routing.ts | 4 +- .../view/url_from_query_params.ts | 2 +- .../network/pages/details/index.test.tsx | 4 +- .../spaces/common/lib/spaces_url_parser.ts | 6 +- .../edit_space/manage_space_page.test.tsx | 41 ++-- .../nav_control/nav_control_popover.test.tsx | 10 +- .../lib/copy_to_spaces/copy_to_spaces.test.ts | 2 +- .../resolve_copy_conflicts.test.ts | 2 +- .../__tests__/synthetics_callout.test.tsx | 1 - .../__tests__/monitor_list.test.tsx | 1 - .../actions/builtin_action_types/jira.ts | 36 +++- .../actions/builtin_action_types/resilient.ts | 36 +++- .../builtin_action_types/servicenow.ts | 36 +++- .../tests/transaction_groups/distribution.ts | 2 +- .../trial/tests/service_maps/service_maps.ts | 2 +- .../reporting/hugedata/data.json.gz | Bin 33744 -> 33745 bytes .../reporting/scripted_small2/data.json.gz | Bin 4248 -> 4436 bytes .../reporting_api_integration/fixtures.ts | 177 +++++++++--------- yarn.lock | 16 +- 80 files changed, 520 insertions(+), 296 deletions(-) diff --git a/.ci/Dockerfile b/.ci/Dockerfile index d6eee046611b..9ac6c32772e4 100644 --- a/.ci/Dockerfile +++ b/.ci/Dockerfile @@ -1,7 +1,7 @@ # NOTE: This Dockerfile is ONLY used to run certain tasks in CI. It is not used to run Kibana or as a distributable. # If you're looking for the Kibana Docker image distributable, please see: src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts -ARG NODE_VERSION=10.22.1 +ARG NODE_VERSION=12.19.0 FROM node:${NODE_VERSION} AS base diff --git a/.node-version b/.node-version index c2f6421352c4..260a0e20f68f 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -10.22.1 +12.19.0 diff --git a/.nvmrc b/.nvmrc index c2f6421352c4..260a0e20f68f 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -10.22.1 +12.19.0 diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 2f2c87ca9c7d..efc7a1b93093 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -512,8 +512,8 @@ In addition to this setting, trusted certificates may be specified via <=10.17.17 <10.20.0", + "**/@types/node": "12.19.4", "**/cross-fetch/node-fetch": "^2.6.1", "**/deepmerge": "^4.2.2", "**/fast-deep-equal": "^3.1.1", @@ -97,7 +97,7 @@ "**/typescript": "4.0.2" }, "engines": { - "node": "10.22.1", + "node": "12.19.0", "yarn": "^1.21.1" }, "dependencies": { @@ -497,7 +497,7 @@ "@types/mustache": "^0.8.31", "@types/ncp": "^2.0.1", "@types/nock": "^10.0.3", - "@types/node": ">=10.17.17 <10.20.0", + "@types/node": "12.19.4", "@types/node-fetch": "^2.5.7", "@types/node-forge": "^0.9.5", "@types/nodemailer": "^6.2.1", @@ -560,7 +560,7 @@ "@types/vinyl-fs": "^2.4.11", "@types/watchpack": "^1.1.5", "@types/webpack": "^4.41.3", - "@types/webpack-env": "^1.15.2", + "@types/webpack-env": "^1.15.3", "@types/webpack-merge": "^4.1.5", "@types/write-pkg": "^3.1.0", "@types/xml-crypto": "^1.4.1", diff --git a/packages/kbn-config-schema/src/types/stream_type.test.ts b/packages/kbn-config-schema/src/types/stream_type.test.ts index 2e6f31ad09b3..91a75d01bde9 100644 --- a/packages/kbn-config-schema/src/types/stream_type.test.ts +++ b/packages/kbn-config-schema/src/types/stream_type.test.ts @@ -57,7 +57,13 @@ test('includes namespace in failure', () => { describe('#defaultValue', () => { test('returns default when undefined', () => { const value = new Stream(); - expect(schema.stream({ defaultValue: value }).validate(undefined)).toStrictEqual(value); + expect(schema.stream({ defaultValue: value }).validate(undefined)).toMatchInlineSnapshot(` + Stream { + "_events": Object {}, + "_eventsCount": 0, + "_maxListeners": undefined, + } + `); }); test('returns value when specified', () => { diff --git a/packages/kbn-dev-utils/src/proc_runner/proc.ts b/packages/kbn-dev-utils/src/proc_runner/proc.ts index bd2368defd7e..f9483255eda8 100644 --- a/packages/kbn-dev-utils/src/proc_runner/proc.ts +++ b/packages/kbn-dev-utils/src/proc_runner/proc.ts @@ -91,9 +91,9 @@ export function startProc(name: string, options: ProcOptions, log: ToolingLog) { }); if (stdin) { - childProcess.stdin.end(stdin, 'utf8'); + childProcess.stdin!.end(stdin, 'utf8'); // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdin will not be null } else { - childProcess.stdin.end(); + childProcess.stdin!.end(); // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdin will not be null } let stopCalled = false; @@ -123,8 +123,8 @@ export function startProc(name: string, options: ProcOptions, log: ToolingLog) { ).pipe(share()); const lines$ = Rx.merge( - observeLines(childProcess.stdout), - observeLines(childProcess.stderr) + observeLines(childProcess.stdout!), // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + observeLines(childProcess.stderr!) // TypeScript note: As long as the proc stdio[1] is 'pipe', then stderr will not be null ).pipe( tap((line) => log.write(` ${chalk.gray('proc')} [${chalk.gray(name)}] ${line}`)), share() diff --git a/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log_text_writer.test.ts.snap b/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log_text_writer.test.ts.snap index 76c018fdb366..f5d084da6a4e 100644 --- a/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log_text_writer.test.ts.snap +++ b/packages/kbn-dev-utils/src/tooling_log/__snapshots__/tooling_log_text_writer.test.ts.snap @@ -2,8 +2,7 @@ exports[`formats %s patterns and indents multi-line messages correctly 1`] = ` " │ succ foo bar - │ { foo: { bar: { '1': [Array] } }, - │ bar: { bar: { '1': [Array] } } } + │ { foo: { bar: { '1': [Array] } }, bar: { bar: { '1': [Array] } } } │ │ Infinity " diff --git a/packages/kbn-es-archiver/src/actions/load.ts b/packages/kbn-es-archiver/src/actions/load.ts index efb1fe9f9ea5..c2f5f18a07e9 100644 --- a/packages/kbn-es-archiver/src/actions/load.ts +++ b/packages/kbn-es-archiver/src/actions/load.ts @@ -43,7 +43,7 @@ import { // are not listened for const pipeline = (...streams: Readable[]) => streams.reduce((source, dest) => - source.once('error', (error) => dest.emit('error', error)).pipe(dest as any) + source.once('error', (error) => dest.destroy(error)).pipe(dest as any) ); export async function loadAction({ diff --git a/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.test.js b/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.test.js index b742a770b70c..878d645d9b4a 100644 --- a/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.test.js +++ b/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.test.js @@ -44,7 +44,7 @@ describe('concatStreamProviders() helper', () => { () => new Readable({ read() { - this.emit('error', new Error('foo')); + this.destroy(new Error('foo')); }, }), ]); diff --git a/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.ts b/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.ts index 4794d76cc7f8..be0768316b29 100644 --- a/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.ts +++ b/packages/kbn-es-archiver/src/lib/streams/concat_stream_providers.ts @@ -50,7 +50,7 @@ export function concatStreamProviders( source // proxy errors from the source to the destination - .once('error', (error) => destination.emit('error', error)) + .once('error', (error) => destination.destroy(error)) // pipe the source to the destination but only proxy the // end event if this is the last source .pipe(destination, { end: isLast }); diff --git a/packages/kbn-i18n/src/__snapshots__/loader.test.ts.snap b/packages/kbn-i18n/src/__snapshots__/loader.test.ts.snap index 05b3fd17a674..941d9fbf7d6a 100644 --- a/packages/kbn-i18n/src/__snapshots__/loader.test.ts.snap +++ b/packages/kbn-i18n/src/__snapshots__/loader.test.ts.snap @@ -2,4 +2,4 @@ exports[`I18n loader registerTranslationFile should throw error if path to translation file is not an absolute 1`] = `"Paths to translation files must be absolute. Got relative path: \\"./en.json\\""`; -exports[`I18n loader registerTranslationFile should throw error if path to translation file is not specified 1`] = `"The \\"path\\" argument must be of type string. Received type undefined"`; +exports[`I18n loader registerTranslationFile should throw error if path to translation file is not specified 1`] = `"The \\"path\\" argument must be of type string. Received undefined"`; diff --git a/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts b/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts index a89f84e5c543..46660f0dd958 100644 --- a/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts +++ b/packages/kbn-optimizer/src/integration_tests/basic_optimization.test.ts @@ -261,7 +261,6 @@ const expectFileMatchesSnapshotWithCompression = (filePath: string, snapshotLabe // Verify the brotli variant matches expect( - // @ts-expect-error @types/node is missing the brotli functions Zlib.brotliDecompressSync( Fs.readFileSync(Path.resolve(MOCK_REPO_DIR, `${filePath}.br`)) ).toString() diff --git a/packages/kbn-optimizer/src/optimizer/get_mtimes.ts b/packages/kbn-optimizer/src/optimizer/get_mtimes.ts index b6c367870988..71c83d653398 100644 --- a/packages/kbn-optimizer/src/optimizer/get_mtimes.ts +++ b/packages/kbn-optimizer/src/optimizer/get_mtimes.ts @@ -23,7 +23,7 @@ import * as Rx from 'rxjs'; import { mergeMap, map, catchError } from 'rxjs/operators'; import { allValuesFrom } from '../common'; -const stat$ = Rx.bindNodeCallback(Fs.stat); +const stat$ = Rx.bindNodeCallback(Fs.stat); /** * get mtimes of referenced paths concurrently, limit concurrency to 100 diff --git a/packages/kbn-optimizer/src/optimizer/observe_worker.ts b/packages/kbn-optimizer/src/optimizer/observe_worker.ts index 31b34bd5c593..6745de40fd66 100644 --- a/packages/kbn-optimizer/src/optimizer/observe_worker.ts +++ b/packages/kbn-optimizer/src/optimizer/observe_worker.ts @@ -164,7 +164,8 @@ export function observeWorker( type: 'worker started', bundles, }), - observeStdio$(proc.stdout).pipe( + // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + observeStdio$(proc.stdout!).pipe( map( (line): WorkerStdio => ({ type: 'worker stdio', @@ -173,7 +174,8 @@ export function observeWorker( }) ) ), - observeStdio$(proc.stderr).pipe( + // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null + observeStdio$(proc.stderr!).pipe( map( (line): WorkerStdio => ({ type: 'worker stdio', diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index b7d9803059aa..f0ac050b128f 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -32273,8 +32273,10 @@ function spawnStreaming(command, args, opts, { mergeMultiline: true, tag: color.bold(prefix) }); - spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); - spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); + spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + + spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null + return spawned; } @@ -51377,7 +51379,8 @@ const WatchCommand = { await Object(_utils_parallelize__WEBPACK_IMPORTED_MODULE_2__["parallelizeBatches"])(batchedProjects, async pkg => { const completionHint = await Object(_utils_watch__WEBPACK_IMPORTED_MODULE_4__["waitUntilWatchIsReady"])(pkg.runScriptStreaming(watchScriptName, { debug: false - }).stdout); + }).stdout // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + ); _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"].success(`[${pkg.name}] Initial build completed (${completionHint}).`); }); } diff --git a/packages/kbn-pm/src/commands/watch.ts b/packages/kbn-pm/src/commands/watch.ts index 6775f728c149..7bd78ba4e5a7 100644 --- a/packages/kbn-pm/src/commands/watch.ts +++ b/packages/kbn-pm/src/commands/watch.ts @@ -80,7 +80,7 @@ export const WatchCommand: ICommand = { const completionHint = await waitUntilWatchIsReady( pkg.runScriptStreaming(watchScriptName, { debug: false, - }).stdout + }).stdout! // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null ); log.success(`[${pkg.name}] Initial build completed (${completionHint}).`); diff --git a/packages/kbn-pm/src/utils/child_process.ts b/packages/kbn-pm/src/utils/child_process.ts index bafe2bf57adc..2f761676d77f 100644 --- a/packages/kbn-pm/src/utils/child_process.ts +++ b/packages/kbn-pm/src/utils/child_process.ts @@ -71,8 +71,8 @@ export function spawnStreaming( const prefixedStdout = logTransformer({ tag: color.bold(prefix) }); const prefixedStderr = logTransformer({ mergeMultiline: true, tag: color.bold(prefix) }); - spawned.stdout.pipe(prefixedStdout).pipe(streamToLog(debug)); - spawned.stderr.pipe(prefixedStderr).pipe(streamToLog(debug)); + spawned.stdout!.pipe(prefixedStdout).pipe(streamToLog(debug)); // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + spawned.stderr!.pipe(prefixedStderr).pipe(streamToLog(debug)); // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null return spawned; } diff --git a/packages/kbn-test/src/functional_test_runner/lib/docker_servers/container_logs.ts b/packages/kbn-test/src/functional_test_runner/lib/docker_servers/container_logs.ts index f8e8137ce40a..788037b49b14 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/docker_servers/container_logs.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/docker_servers/container_logs.ts @@ -35,8 +35,8 @@ export function observeContainerLogs(name: string, containerId: string, log: Too const logLine$ = new Rx.Subject(); Rx.merge( - observeLines(logsProc.stdout).pipe(tap((line) => log.info(`[docker:${name}] ${line}`))), - observeLines(logsProc.stderr).pipe(tap((line) => log.error(`[docker:${name}] ${line}`))) + observeLines(logsProc.stdout!).pipe(tap((line) => log.info(`[docker:${name}] ${line}`))), // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + observeLines(logsProc.stderr!).pipe(tap((line) => log.error(`[docker:${name}] ${line}`))) // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null ).subscribe(logLine$); return logLine$.asObservable(); diff --git a/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts b/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts index d17c5503c42f..d133d0e498b4 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/lifecycle_phase.test.ts @@ -59,11 +59,17 @@ describe('with randomness', () => { ); await phase.trigger(); + + // `phase.trigger()` uses `Math.random` to sort the internal array of + // handlers. But since the sorting algorithm used internally in + // `Array.prototype.sort` is not spec'ed, it can change between Node.js + // versions, and as a result the expected output below might not match if + // you up/downgrade Node.js. expect(order).toMatchInlineSnapshot(` Array [ - "one", "three", "two", + "one", ] `); }); diff --git a/packages/kbn-test/src/kbn/kbn_test_config.ts b/packages/kbn-test/src/kbn/kbn_test_config.ts index 909c94098cf5..1753fa3885f4 100644 --- a/packages/kbn-test/src/kbn/kbn_test_config.ts +++ b/packages/kbn-test/src/kbn/kbn_test_config.ts @@ -39,9 +39,9 @@ export const kbnTestConfig = new (class KbnTestConfig { const testKibanaUrl = url.parse(process.env.TEST_KIBANA_URL); return { protocol: testKibanaUrl.protocol?.slice(0, -1), - hostname: testKibanaUrl.hostname, + hostname: testKibanaUrl.hostname === null ? undefined : testKibanaUrl.hostname, port: testKibanaUrl.port ? parseInt(testKibanaUrl.port, 10) : undefined, - auth: testKibanaUrl.auth, + auth: testKibanaUrl.auth === null ? undefined : testKibanaUrl.auth, username: testKibanaUrl.auth?.split(':')[0], password: testKibanaUrl.auth?.split(':')[1], }; diff --git a/src/cli/repl/__snapshots__/repl.test.js.snap b/src/cli/repl/__snapshots__/repl.test.js.snap index 7171e99dbcc0..c7751b5797f4 100644 --- a/src/cli/repl/__snapshots__/repl.test.js.snap +++ b/src/cli/repl/__snapshots__/repl.test.js.snap @@ -5,8 +5,14 @@ exports[`repl it allows print depth to be specified 1`] = `"{ '0': {  exports[`repl it colorizes raw values 1`] = `"{ meaning: 42 }"`; exports[`repl it handles deep and recursive objects 1`] = ` -"{ '0': { '1': { '2': { '3': { '4': { '5': [Object] } } } } }, - whoops: [Circular] }" +"{ + '0': { + '1': { + '2': { '3': { '4': { '5': [Object] } } } + } + }, + whoops: [Circular] +}" `; exports[`repl it handles undefined 1`] = `"undefined"`; @@ -45,8 +51,14 @@ Array [ Array [ "Promise Rejected: ", - "{ '0': { '1': { '2': { '3': { '4': { '5': [Object] } } } } }, - whoops: [Circular] }", + "{ + '0': { + '1': { + '2': { '3': { '4': { '5': [Object] } } } + } + }, + whoops: [Circular] +}", ], ] `; @@ -59,8 +71,14 @@ Array [ Array [ "Promise Resolved: ", - "{ '0': { '1': { '2': { '3': { '4': { '5': [Object] } } } } }, - whoops: [Circular] }", + "{ + '0': { + '1': { + '2': { '3': { '4': { '5': [Object] } } } + } + }, + whoops: [Circular] +}", ], ] `; diff --git a/src/cli/serve/integration_tests/reload_logging_config.test.ts b/src/cli/serve/integration_tests/reload_logging_config.test.ts index 55f71ea2401d..0a2c90460430 100644 --- a/src/cli/serve/integration_tests/reload_logging_config.test.ts +++ b/src/cli/serve/integration_tests/reload_logging_config.test.ts @@ -121,14 +121,15 @@ describe('Server logging configuration', function () { '--verbose', ]); - const message$ = Rx.fromEvent(child.stdout, 'data').pipe( + // TypeScript note: As long as the child stdio[1] is 'pipe', then stdout will not be null + const message$ = Rx.fromEvent(child.stdout!, 'data').pipe( map((messages) => String(messages).split('\n').filter(Boolean)) ); await message$ .pipe( // We know the sighup handler will be registered before this message logged - filter((messages) => messages.some((m) => m.includes('setting up root'))), + filter((messages: string[]) => messages.some((m) => m.includes('setting up root'))), take(1) ) .toPromise(); @@ -189,14 +190,15 @@ describe('Server logging configuration', function () { child = Child.spawn(process.execPath, [kibanaPath, '--oss', '--config', configFilePath]); - const message$ = Rx.fromEvent(child.stdout, 'data').pipe( + // TypeScript note: As long as the child stdio[1] is 'pipe', then stdout will not be null + const message$ = Rx.fromEvent(child.stdout!, 'data').pipe( map((messages) => String(messages).split('\n').filter(Boolean)) ); await message$ .pipe( // We know the sighup handler will be registered before this message logged - filter((messages) => messages.some((m) => m.includes('setting up root'))), + filter((messages: string[]) => messages.some((m) => m.includes('setting up root'))), take(1) ) .toPromise(); diff --git a/src/core/public/http/types.ts b/src/core/public/http/types.ts index b12cd1fe09a9..2361d981b859 100644 --- a/src/core/public/http/types.ts +++ b/src/core/public/http/types.ts @@ -206,12 +206,19 @@ export interface HttpRequestInit { /** @public */ export interface HttpFetchQuery { - [key: string]: - | string - | number - | boolean - | undefined - | Array; + /** + * TypeScript note: Technically we should use this interface instead, but @types/node uses the below stricter + * definition, so to avoid TypeScript errors, we'll restrict our version. + * + * [key: string]: + * | string + * | number + * | boolean + * | Array + * | undefined + * | null; + */ + [key: string]: string | number | boolean | string[] | number[] | boolean[] | undefined | null; } /** diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index c8add5a8ddf5..28a20845426d 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -625,8 +625,7 @@ export interface HttpFetchOptionsWithPath extends HttpFetchOptions { // @public (undocumented) export interface HttpFetchQuery { - // (undocumented) - [key: string]: string | number | boolean | undefined | Array; + [key: string]: string | number | boolean | string[] | number[] | boolean[] | undefined | null; } // @public diff --git a/src/core/public/utils/crypto/sha256.ts b/src/core/public/utils/crypto/sha256.ts index 1617c8ca8d26..eaa057d60468 100644 --- a/src/core/public/utils/crypto/sha256.ts +++ b/src/core/public/utils/crypto/sha256.ts @@ -118,6 +118,18 @@ const K = [ const W = new Array(64); +type BufferEncoding = + | 'ascii' + | 'utf8' + | 'utf-8' + | 'utf16le' + | 'ucs2' + | 'ucs-2' + | 'base64' + | 'latin1' + | 'binary' + | 'hex'; + /* eslint-disable no-bitwise, no-shadow */ export class Sha256 { private _a: number; @@ -157,7 +169,7 @@ export class Sha256 { this._s = 0; } - update(data: string | Buffer, encoding?: string): Sha256 { + update(data: string | Buffer, encoding?: BufferEncoding): Sha256 { if (typeof data === 'string') { encoding = encoding || 'utf8'; data = Buffer.from(data, encoding); diff --git a/src/core/server/core_usage_data/core_usage_data_service.test.ts b/src/core/server/core_usage_data/core_usage_data_service.test.ts index 9f9e18c08b0d..e1c78edb902a 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.test.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.test.ts @@ -145,6 +145,9 @@ describe('CoreUsageDataService', () => { "certificateAuthoritiesConfigured": false, "certificateConfigured": false, "cipherSuites": Array [ + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_AES_128_GCM_SHA256", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES256-GCM-SHA384", @@ -174,6 +177,7 @@ describe('CoreUsageDataService', () => { "supportedProtocols": Array [ "TLSv1.1", "TLSv1.2", + "TLSv1.3", ], "truststoreConfigured": false, }, diff --git a/src/core/server/elasticsearch/client/configure_client.test.ts b/src/core/server/elasticsearch/client/configure_client.test.ts index 250cfc18a757..614ec112e8f0 100644 --- a/src/core/server/elasticsearch/client/configure_client.test.ts +++ b/src/core/server/elasticsearch/client/configure_client.test.ts @@ -322,7 +322,6 @@ describe('configureClient', () => { ); const response = createResponseWithBody( - // @ts-expect-error definition doesn't know about from Readable.from( JSON.stringify({ seq_no_primary_term: true, diff --git a/src/core/server/http/__snapshots__/http_config.test.ts.snap b/src/core/server/http/__snapshots__/http_config.test.ts.snap index e9b818fe859e..8e8891b8a73a 100644 --- a/src/core/server/http/__snapshots__/http_config.test.ts.snap +++ b/src/core/server/http/__snapshots__/http_config.test.ts.snap @@ -47,6 +47,9 @@ Object { "socketTimeout": 120000, "ssl": Object { "cipherSuites": Array [ + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_AES_128_GCM_SHA256", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES256-GCM-SHA384", @@ -75,6 +78,7 @@ Object { "supportedProtocols": Array [ "TLSv1.1", "TLSv1.2", + "TLSv1.3", ], "truststore": Object {}, }, diff --git a/src/core/server/http/http_server.test.ts b/src/core/server/http/http_server.test.ts index 7507a08dd150..5da4c5de5d31 100644 --- a/src/core/server/http/http_server.test.ts +++ b/src/core/server/http/http_server.test.ts @@ -79,7 +79,7 @@ beforeEach(() => { ssl: { enabled: true, certificate, - cipherSuites: ['cipherSuite'], + cipherSuites: ['TLS_AES_256_GCM_SHA384'], getSecureOptions: () => 0, key, redirectHttpFromPort: config.port + 1, diff --git a/src/core/server/http/http_tools.test.ts b/src/core/server/http/http_tools.test.ts index 336c491a131d..1423e27b914a 100644 --- a/src/core/server/http/http_tools.test.ts +++ b/src/core/server/http/http_tools.test.ts @@ -143,7 +143,7 @@ describe('getServerOptions', () => { Object { "ca": undefined, "cert": "content-some-certificate-path", - "ciphers": "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA", + "ciphers": "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA", "honorCipherOrder": true, "key": "content-some-key-path", "passphrase": undefined, @@ -175,7 +175,7 @@ describe('getServerOptions', () => { "content-ca-2", ], "cert": "content-some-certificate-path", - "ciphers": "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA", + "ciphers": "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA", "honorCipherOrder": true, "key": "content-some-key-path", "passphrase": undefined, diff --git a/src/core/server/http/router/validator/validator.test.ts b/src/core/server/http/router/validator/validator.test.ts index 30f66f5d41fb..f6a1dd82cb10 100644 --- a/src/core/server/http/router/validator/validator.test.ts +++ b/src/core/server/http/router/validator/validator.test.ts @@ -36,7 +36,7 @@ describe('Router validator', () => { expect(() => validator.getParams({})).toThrowError('[foo]: Not a string'); expect(() => validator.getParams(undefined)).toThrowError( - "Cannot destructure property `foo` of 'undefined' or 'null'." + "Cannot destructure property 'foo' of 'undefined' as it is undefined." ); expect(() => validator.getParams({}, 'myField')).toThrowError('[myField.foo]: Not a string'); diff --git a/src/core/server/http/ssl_config.test.ts b/src/core/server/http/ssl_config.test.ts index 5d0bed601f54..9140efe4a237 100644 --- a/src/core/server/http/ssl_config.test.ts +++ b/src/core/server/http/ssl_config.test.ts @@ -266,14 +266,19 @@ describe('#sslSchema', () => { certificate: '/path/to/certificate', enabled: true, key: '/path/to/key', - supportedProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2'], + supportedProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3'], }; const singleKnownProtocolConfig = sslSchema.validate(singleKnownProtocol); expect(singleKnownProtocolConfig.supportedProtocols).toEqual(['TLSv1']); const allKnownProtocolsConfig = sslSchema.validate(allKnownProtocols); - expect(allKnownProtocolsConfig.supportedProtocols).toEqual(['TLSv1', 'TLSv1.1', 'TLSv1.2']); + expect(allKnownProtocolsConfig.supportedProtocols).toEqual([ + 'TLSv1', + 'TLSv1.1', + 'TLSv1.2', + 'TLSv1.3', + ]); }); test('rejects unknown protocols`', () => { @@ -288,21 +293,23 @@ describe('#sslSchema', () => { certificate: '/path/to/certificate', enabled: true, key: '/path/to/key', - supportedProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'SOMEv100500'], + supportedProtocols: ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3', 'SOMEv100500'], }; expect(() => sslSchema.validate(singleUnknownProtocol)).toThrowErrorMatchingInlineSnapshot(` "[supportedProtocols.0]: types that failed validation: - [supportedProtocols.0.0]: expected value to equal [TLSv1] - [supportedProtocols.0.1]: expected value to equal [TLSv1.1] -- [supportedProtocols.0.2]: expected value to equal [TLSv1.2]" +- [supportedProtocols.0.2]: expected value to equal [TLSv1.2] +- [supportedProtocols.0.3]: expected value to equal [TLSv1.3]" `); expect(() => sslSchema.validate(allKnownWithOneUnknownProtocols)) .toThrowErrorMatchingInlineSnapshot(` -"[supportedProtocols.3]: types that failed validation: -- [supportedProtocols.3.0]: expected value to equal [TLSv1] -- [supportedProtocols.3.1]: expected value to equal [TLSv1.1] -- [supportedProtocols.3.2]: expected value to equal [TLSv1.2]" +"[supportedProtocols.4]: types that failed validation: +- [supportedProtocols.4.0]: expected value to equal [TLSv1] +- [supportedProtocols.4.1]: expected value to equal [TLSv1.1] +- [supportedProtocols.4.2]: expected value to equal [TLSv1.2] +- [supportedProtocols.4.3]: expected value to equal [TLSv1.3]" `); }); }); diff --git a/src/core/server/http/ssl_config.ts b/src/core/server/http/ssl_config.ts index 75dc05d1a801..0c5d0017614b 100644 --- a/src/core/server/http/ssl_config.ts +++ b/src/core/server/http/ssl_config.ts @@ -18,18 +18,16 @@ */ import { schema, TypeOf } from '@kbn/config-schema'; -import crypto from 'crypto'; +import { constants as cryptoConstants } from 'crypto'; import { readFileSync } from 'fs'; import { readPkcs12Keystore, readPkcs12Truststore } from '../utils'; -// `crypto` type definitions doesn't currently include `crypto.constants`, see -// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/fa5baf1733f49cf26228a4e509914572c1b74adf/types/node/v6/index.d.ts#L3412 -const cryptoConstants = (crypto as any).constants; - const protocolMap = new Map([ ['TLSv1', cryptoConstants.SSL_OP_NO_TLSv1], ['TLSv1.1', cryptoConstants.SSL_OP_NO_TLSv1_1], ['TLSv1.2', cryptoConstants.SSL_OP_NO_TLSv1_2], + // @ts-expect-error According to the docs SSL_OP_NO_TLSv1_3 should exist (https://nodejs.org/docs/latest-v12.x/api/crypto.html) + ['TLSv1.3', cryptoConstants.SSL_OP_NO_TLSv1_3], ]); export const sslSchema = schema.object( @@ -56,8 +54,13 @@ export const sslSchema = schema.object( }), redirectHttpFromPort: schema.maybe(schema.number()), supportedProtocols: schema.arrayOf( - schema.oneOf([schema.literal('TLSv1'), schema.literal('TLSv1.1'), schema.literal('TLSv1.2')]), - { defaultValue: ['TLSv1.1', 'TLSv1.2'], minSize: 1 } + schema.oneOf([ + schema.literal('TLSv1'), + schema.literal('TLSv1.1'), + schema.literal('TLSv1.2'), + schema.literal('TLSv1.3'), + ]), + { defaultValue: ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], minSize: 1 } ), clientAuthentication: schema.oneOf( [schema.literal('none'), schema.literal('optional'), schema.literal('required')], diff --git a/src/core/server/logging/appenders/file/file_appender.test.ts b/src/core/server/logging/appenders/file/file_appender.test.ts index 645455c5ae04..843eb1103b7a 100644 --- a/src/core/server/logging/appenders/file/file_appender.test.ts +++ b/src/core/server/logging/appenders/file/file_appender.test.ts @@ -144,7 +144,7 @@ test('`dispose()` succeeds even if stream is not created.', async () => { test('`dispose()` closes stream.', async () => { const mockStreamEndFinished = jest.fn(); - const mockStreamEnd = jest.fn(async (chunk, encoding, callback) => { + const mockStreamEnd = jest.fn(async (callback) => { // It's required to make sure `dispose` waits for `end` to complete. await tickMs(100); mockStreamEndFinished(); @@ -170,7 +170,7 @@ test('`dispose()` closes stream.', async () => { await appender.dispose(); expect(mockStreamEnd).toHaveBeenCalledTimes(1); - expect(mockStreamEnd).toHaveBeenCalledWith(undefined, undefined, expect.any(Function)); + expect(mockStreamEnd).toHaveBeenCalledWith(expect.any(Function)); expect(mockStreamEndFinished).toHaveBeenCalled(); // Consequent `dispose` calls should not fail even if stream has been disposed. diff --git a/src/core/server/logging/appenders/file/file_appender.ts b/src/core/server/logging/appenders/file/file_appender.ts index b1712bd4e941..c86ea4972324 100644 --- a/src/core/server/logging/appenders/file/file_appender.ts +++ b/src/core/server/logging/appenders/file/file_appender.ts @@ -76,7 +76,7 @@ export class FileAppender implements DisposableAppender { return resolve(); } - this.outputStream.end(undefined, undefined, () => { + this.outputStream.end(() => { this.outputStream = undefined; resolve(); }); diff --git a/src/core/server/metrics/metrics_service.test.ts b/src/core/server/metrics/metrics_service.test.ts index 384a56c8dba9..c39f5f25b02b 100644 --- a/src/core/server/metrics/metrics_service.test.ts +++ b/src/core/server/metrics/metrics_service.test.ts @@ -82,21 +82,23 @@ describe('MetricsService', () => { // `advanceTimersByTime` only ensure the interval handler is executed // however the `reset` call is executed after the async call to `collect` // meaning that we are going to miss the call if we don't wait for the - // actual observable emission that is performed after - const waitForNextEmission = () => getOpsMetrics$().pipe(take(1)).toPromise(); + // actual observable emission that is performed after. The extra + // `nextTick` is to ensure we've done a complete roundtrip of the event + // loop. + const nextEmission = async () => { + jest.advanceTimersByTime(testInterval); + await getOpsMetrics$().pipe(take(1)).toPromise(); + await new Promise((resolve) => process.nextTick(resolve)); + }; expect(mockOpsCollector.collect).toHaveBeenCalledTimes(1); expect(mockOpsCollector.reset).toHaveBeenCalledTimes(1); - let nextEmission = waitForNextEmission(); - jest.advanceTimersByTime(testInterval); - await nextEmission; + await nextEmission(); expect(mockOpsCollector.collect).toHaveBeenCalledTimes(2); expect(mockOpsCollector.reset).toHaveBeenCalledTimes(2); - nextEmission = waitForNextEmission(); - jest.advanceTimersByTime(testInterval); - await nextEmission; + await nextEmission(); expect(mockOpsCollector.collect).toHaveBeenCalledTimes(3); expect(mockOpsCollector.reset).toHaveBeenCalledTimes(3); }); @@ -117,13 +119,15 @@ describe('MetricsService', () => { await metricsService.setup({ http: httpMock }); const { getOpsMetrics$ } = await metricsService.start(); - const firstEmission = getOpsMetrics$().pipe(take(1)).toPromise(); - jest.advanceTimersByTime(testInterval); - expect(await firstEmission).toEqual({ metric: 'first' }); + const nextEmission = async () => { + jest.advanceTimersByTime(testInterval); + const emission = await getOpsMetrics$().pipe(take(1)).toPromise(); + await new Promise((resolve) => process.nextTick(resolve)); + return emission; + }; - const secondEmission = getOpsMetrics$().pipe(take(1)).toPromise(); - jest.advanceTimersByTime(testInterval); - expect(await secondEmission).toEqual({ metric: 'second' }); + expect(await nextEmission()).toEqual({ metric: 'first' }); + expect(await nextEmission()).toEqual({ metric: 'second' }); }); }); diff --git a/src/core/server/utils/streams/concat_stream_providers.test.ts b/src/core/server/utils/streams/concat_stream_providers.test.ts index b742a770b70c..878d645d9b4a 100644 --- a/src/core/server/utils/streams/concat_stream_providers.test.ts +++ b/src/core/server/utils/streams/concat_stream_providers.test.ts @@ -44,7 +44,7 @@ describe('concatStreamProviders() helper', () => { () => new Readable({ read() { - this.emit('error', new Error('foo')); + this.destroy(new Error('foo')); }, }), ]); diff --git a/src/core/server/utils/streams/concat_stream_providers.ts b/src/core/server/utils/streams/concat_stream_providers.ts index bb836e3d7378..236d68c89707 100644 --- a/src/core/server/utils/streams/concat_stream_providers.ts +++ b/src/core/server/utils/streams/concat_stream_providers.ts @@ -54,7 +54,7 @@ export function concatStreamProviders( source // proxy errors from the source to the destination - .once('error', (error) => destination.emit('error', error)) + .once('error', (error) => destination.destroy(error)) // pipe the source to the destination but only proxy the // end event if this is the last source .pipe(destination, { end: isLast }); diff --git a/src/dev/build/lib/scan_delete.ts b/src/dev/build/lib/scan_delete.ts index 6e41d207e311..aeccd711b032 100644 --- a/src/dev/build/lib/scan_delete.ts +++ b/src/dev/build/lib/scan_delete.ts @@ -27,7 +27,7 @@ import { count, map, mergeAll, mergeMap } from 'rxjs/operators'; // @ts-ignore import { assertAbsolute } from './fs'; -const getStat$ = Rx.bindNodeCallback(Fs.stat); +const getStat$ = Rx.bindNodeCallback(Fs.stat); const getReadDir$ = Rx.bindNodeCallback(Fs.readdir); interface Options { diff --git a/src/dev/build/lib/watch_stdio_for_line.ts b/src/dev/build/lib/watch_stdio_for_line.ts index 3d7929ccfc33..c97b1c3b26db 100644 --- a/src/dev/build/lib/watch_stdio_for_line.ts +++ b/src/dev/build/lib/watch_stdio_for_line.ts @@ -69,13 +69,13 @@ export async function watchStdioForLine( } }), createPromiseFromStreams([ - proc.stdout, + proc.stdout!, // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null createSplitStream('\n'), skipLastEmptyLineStream(), createMapStream(onLogLine), ]), createPromiseFromStreams([ - proc.stderr, + proc.stderr!, // TypeScript note: As long as the proc stdio[1] is 'pipe', then stderr will not be null createSplitStream('\n'), skipLastEmptyLineStream(), createMapStream(onLogLine), diff --git a/src/dev/build/tasks/bin/scripts/kibana b/src/dev/build/tasks/bin/scripts/kibana index a4fc5385500b..3c12c8bbf58d 100755 --- a/src/dev/build/tasks/bin/scripts/kibana +++ b/src/dev/build/tasks/bin/scripts/kibana @@ -26,4 +26,4 @@ if [ -f "${CONFIG_DIR}/node.options" ]; then KBN_NODE_OPTS="$(grep -v ^# < ${CONFIG_DIR}/node.options | xargs)" fi -NODE_OPTIONS="--no-warnings --max-http-header-size=65536 $KBN_NODE_OPTS $NODE_OPTIONS" NODE_ENV=production exec "${NODE}" "${DIR}/src/cli/dist" ${@} +NODE_OPTIONS="--no-warnings --max-http-header-size=65536 --tls-min-v1.0 $KBN_NODE_OPTS $NODE_OPTIONS" NODE_ENV=production exec "${NODE}" "${DIR}/src/cli/dist" ${@} diff --git a/src/dev/build/tasks/patch_native_modules_task.ts b/src/dev/build/tasks/patch_native_modules_task.ts index b56d01b61646..c3011fa80988 100644 --- a/src/dev/build/tasks/patch_native_modules_task.ts +++ b/src/dev/build/tasks/patch_native_modules_task.ts @@ -47,16 +47,16 @@ const packages: Package[] = [ extractMethod: 'gunzip', archives: { darwin: { - url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/darwin-x64-64.gz', - sha256: '595c6653d796493ddb288fc0732a0d1df8560099796f55a1dd242357d96bb8d6', + url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/darwin-x64-72.gz', + sha256: '983106049bb86e21b7f823144b2b83e3f1408217401879b3cde0312c803512c9', }, linux: { - url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/linux-x64-64.gz', - sha256: 'e743587bc96314edf10c3e659c03168bc374a5cd9a6623ee99d989251e331f28', + url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/linux-x64-72.gz', + sha256: '8b6692037f7b0df24dabc9c9b039038d1c3a3110f62121616b406c482169710a', }, win32: { - url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/win32-x64-64.gz', - sha256: 'b33de62cda24fb02dc80a19fb79977d686468ac746e97cd211059d2d4c75d529', + url: 'https://github.com/uhop/node-re2/releases/download/1.15.4/win32-x64-72.gz', + sha256: '0a6991e693577160c3e9a3f196bd2518368c52d920af331a1a183313e0175604', }, }, }, diff --git a/src/dev/prs/run_update_prs_cli.ts b/src/dev/prs/run_update_prs_cli.ts index 49668199a26d..57da9d164b39 100644 --- a/src/dev/prs/run_update_prs_cli.ts +++ b/src/dev/prs/run_update_prs_cli.ts @@ -72,7 +72,10 @@ run( await Promise.all([ proc.then(() => log.debug(` - ${cmd} exited with 0`)), - Rx.merge(getLine$(proc.stdout), getLine$(proc.stderr)) + Rx.merge( + getLine$(proc.stdout!), // TypeScript note: As long as the proc stdio[1] is 'pipe', then stdout will not be null + getLine$(proc.stderr!) // TypeScript note: As long as the proc stdio[2] is 'pipe', then stderr will not be null + ) .pipe(tap((line) => log.debug(line))) .toPromise(), ]); diff --git a/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js b/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js index 06823a981af4..0b443ef400d6 100644 --- a/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js +++ b/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js @@ -661,7 +661,7 @@ describe('Integration', () => { { name: 'Any of - mixed - both', cursor: { lineNumber: 14, column: 3 }, - autoCompleteSet: [tt('{'), tt(3)], + autoCompleteSet: [tt(3), tt('{')], }, ] ); diff --git a/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx b/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx index 25179fd7ccd3..5f001e3de55d 100644 --- a/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx +++ b/src/plugins/dashboard/public/application/actions/clone_panel_action.test.tsx @@ -111,6 +111,7 @@ test('Clone adds a new embeddable', async () => { expect(newPanel.type).toEqual('placeholder'); // let the placeholder load await dashboard.untilEmbeddableLoaded(newPanelId!); + await new Promise((r) => process.nextTick(r)); // Allow the current loop of the event loop to run to completion // now wait for the full embeddable to replace it const loadedPanel = await dashboard.untilEmbeddableLoaded(newPanelId!); expect(loadedPanel.type).toEqual(embeddable.type); diff --git a/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap b/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap index 3bd3bb6531cc..ec68b307734e 100644 --- a/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap +++ b/src/plugins/inspector/public/views/data/components/__snapshots__/data_view.test.tsx.snap @@ -12,6 +12,7 @@ exports[`Inspector Data View component should render empty state 1`] = ` "_maxListeners": undefined, "tabular": [Function], "tabularOptions": Object {}, + Symbol(kCapture): false, }, } } @@ -130,6 +131,7 @@ exports[`Inspector Data View component should render empty state 1`] = ` "_maxListeners": undefined, "tabular": [Function], "tabularOptions": Object {}, + Symbol(kCapture): false, }, } } diff --git a/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts b/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts index 1553257a04ad..a096430af362 100644 --- a/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts +++ b/src/plugins/kibana_utils/public/core/create_start_service_getter.test.ts @@ -49,6 +49,7 @@ describe('createStartServicesGetter', () => { await new Promise((r) => setTimeout(r, 1)); future.resolve([core, plugins, self]); await future.promise; + await new Promise((r) => process.nextTick(r)); // Allow the current loop of the event loop to run to completion expect(start()).toEqual({ core, @@ -68,6 +69,7 @@ describe('createStartServicesGetter', () => { await new Promise((r) => setTimeout(r, 1)); future.resolve([core, plugins, self]); await future.promise; + await new Promise((r) => process.nextTick(r)); // Allow the current loop of the event loop to run to completion expect(start()).toEqual({ core, diff --git a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts index a3b220f91150..cb3c9470c7ab 100644 --- a/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts +++ b/src/plugins/kibana_utils/public/state_management/url/kbn_url_storage.ts @@ -238,7 +238,8 @@ export const createKbnUrlControls = ( * 4. Hash history with base path */ export function getRelativeToHistoryPath(absoluteUrl: string, history: History): History.Path { - function stripBasename(path: string = '') { + function stripBasename(path: string | null) { + if (path === null) path = ''; const stripLeadingHash = (_: string) => (_.charAt(0) === '#' ? _.substr(1) : _); const stripTrailingSlash = (_: string) => _.charAt(_.length - 1) === '/' ? _.substr(0, _.length - 1) : _; @@ -250,7 +251,7 @@ export function getRelativeToHistoryPath(absoluteUrl: string, history: History): const parsedHash = isHashHistory ? null : parseUrlHash(absoluteUrl); return formatUrl({ - pathname: stripBasename(parsedUrl.pathname), + pathname: stripBasename(parsedUrl.pathname ?? null), search: stringify(urlUtils.encodeQuery(parsedUrl.query), { sort: false, encode: false }), hash: parsedHash ? formatUrl({ diff --git a/src/plugins/share/server/routes/lib/short_url_assert_valid.ts b/src/plugins/share/server/routes/lib/short_url_assert_valid.ts index 462fc31944b7..581410359322 100644 --- a/src/plugins/share/server/routes/lib/short_url_assert_valid.ts +++ b/src/plugins/share/server/routes/lib/short_url_assert_valid.ts @@ -32,7 +32,7 @@ export function shortUrlAssertValid(url: string) { throw Boom.notAcceptable(`Short url targets cannot have a hostname, found "${hostname}"`); } - const pathnameParts = trim(pathname, '/').split('/'); + const pathnameParts = trim(pathname === null ? undefined : pathname, '/').split('/'); if (pathnameParts.length !== 2) { throw Boom.notAcceptable( `Short url target path must be in the format "/app/{{appId}}", found "${pathname}"` diff --git a/src/setup_node_env/exit_on_warning.js b/src/setup_node_env/exit_on_warning.js index c0a0f0ecc0b8..d5f6ab00de2d 100644 --- a/src/setup_node_env/exit_on_warning.js +++ b/src/setup_node_env/exit_on_warning.js @@ -17,11 +17,34 @@ * under the License. */ -if (process.noProcessWarnings !== true) { - var ignore = ['MaxListenersExceededWarning']; +var EOL = require('os').EOL; + +// Be very careful of what you add to this list. Idealy this array should be +// empty, but in certain circumstances, we can allow a warning to be ignored +// temporarily. +// +// Each element in the array is a "rule-object". All rules defined in a +// "rule-object" has to match for a warning to be ignored. Possible rules are: +// `name`, `code`, `message`, `file`, `lines`, and `col`. +// +// The `file`, `line`, and `col` rules will be checked against the top stack +// frame only. Also, `file` doesn't have to match the full path, only the end of +// it. +var IGNORE_WARNINGS = [ + { + name: 'MaxListenersExceededWarning', + }, + { + name: 'DeprecationWarning', + code: 'DEP0066', + file: '/node_modules/supertest/node_modules/superagent/lib/node/index.js', + line: 418, + }, +]; +if (process.noProcessWarnings !== true) { process.on('warning', function (warn) { - if (ignore.includes(warn.name)) return; + if (shouldIgnore(warn)) return; if (process.traceProcessWarnings === true) { console.error('Node.js process-warning detected - Terminating process...'); @@ -48,3 +71,47 @@ if (process.noProcessWarnings !== true) { process.exit(1); }); } + +function shouldIgnore(warn) { + warn = parseWarn(warn); + return IGNORE_WARNINGS.some(function ({ name, code, message, file, line, col }) { + if (name && name !== warn.name) return false; + if (code && code !== warn.code) return false; + if (message && message !== warn.message) return false; + if (file && !warn.frames[0].file.endsWith(file)) return false; + if (line && line !== warn.frames[0].line) return false; + if (col && col !== warn.frames[0].col) return false; + return true; + }); +} + +function parseWarn(warn) { + var lines = warn.stack.split(EOL); + return { + name: warn.name, + code: warn.code, + message: lines[0].split(': ')[1], + frames: parseStack(lines.slice(1)), + }; +} + +function parseStack(stack) { + return stack.map(parseFrame).filter(function (frame) { + return frame; + }); +} + +function parseFrame(frame) { + // supports the following frame types: + // - " at function-name (file-path:1:2)" + // - " at function-name (file-path)" + // - " at file-path:1:2" + var match = frame.match(/^ at (?:([^(]+) )?\(?([^:)]+)(?::(\d+):(\d+))?\)?$/); + if (match === null) return; // in case the stack trace is modified by another module, e.g. jest + return { + func: match[1], + file: match[2], + line: Number(match[3]), + col: Number(match[4]), + }; +} diff --git a/test/functional/services/remote/create_stdout_stream.ts b/test/functional/services/remote/create_stdout_stream.ts index 9af5cba63f9e..9993cfb37d9b 100644 --- a/test/functional/services/remote/create_stdout_stream.ts +++ b/test/functional/services/remote/create_stdout_stream.ts @@ -76,7 +76,7 @@ export async function createStdoutSocket() { throw new Error('server must listen to a random port, not a unix socket'); } - const input = Net.createConnection(addressInfo.port, addressInfo.address); + const input = Net.createConnection(addressInfo!.port, addressInfo!.address); // TypeScript note: addressInfo will not be null after 'listening' has been emitted await Rx.fromEvent(input, 'connect').pipe(take(1)).toPromise(); return { diff --git a/x-pack/plugins/actions/server/builtin_action_types/slack.ts b/x-pack/plugins/actions/server/builtin_action_types/slack.ts index 1605cd4b69f5..628a13e19f7a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/slack.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/slack.ts @@ -126,6 +126,7 @@ async function slackExecutor( // https://slack.dev/node-slack-sdk/webhook // node-slack-sdk use Axios inside :) const webhook = new IncomingWebhook(webhookUrl, { + // @ts-expect-error The types exposed by 'HttpsProxyAgent' isn't up to date with 'Agent' agent: proxyAgent, }); result = await webhook.send(message); diff --git a/x-pack/plugins/canvas/shareable_runtime/api/__tests__/shareable.test.tsx b/x-pack/plugins/canvas/shareable_runtime/api/__tests__/shareable.test.tsx index 4b3aa8dc2fb6..0851ae8d04eb 100644 --- a/x-pack/plugins/canvas/shareable_runtime/api/__tests__/shareable.test.tsx +++ b/x-pack/plugins/canvas/shareable_runtime/api/__tests__/shareable.test.tsx @@ -15,7 +15,6 @@ jest.mock('../../supported_renderers'); describe('Canvas Shareable Workpad API', () => { // Mock the AJAX load of the workpad. beforeEach(function () { - // @ts-expect-error Applying a global in Jest is alright. global.fetch = jest.fn().mockImplementation(() => { const p = new Promise((resolve, _reject) => { resolve({ diff --git a/x-pack/plugins/fleet/server/services/epm/registry/requests.ts b/x-pack/plugins/fleet/server/services/epm/registry/requests.ts index c8d158c8afaa..7bd023219aeb 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/requests.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/requests.ts @@ -93,6 +93,7 @@ export function getFetchOptions(targetUrl: string): RequestInit | undefined { logger.debug(`Using ${proxyUrl} as proxy for ${targetUrl}`); return { + // @ts-expect-error The types exposed by 'HttpsProxyAgent' isn't up to date with 'Agent' agent: getProxyAgent({ proxyUrl, targetUrl }), }; } diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts index 99149c3e7456..d6f5b10cf64e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.test.ts @@ -249,12 +249,12 @@ describe('getOperationTypesForField', () => { }, Object { "field": "bytes", - "operationType": "max", + "operationType": "min", "type": "field", }, Object { "field": "bytes", - "operationType": "min", + "operationType": "max", "type": "field", }, Object { diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts index d6c6ee308295..e8c328214609 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/xy_suggestions.test.ts @@ -186,15 +186,15 @@ describe('xy_suggestions', () => { expect(suggestions).toHaveLength(visualizationTypes.length); expect(suggestions.map(({ state }) => xyVisualization.getVisualizationTypeId(state))).toEqual([ 'bar_stacked', - 'line', - 'area_percentage_stacked', - 'area_stacked', - 'area', - 'bar_horizontal_percentage_stacked', - 'bar_horizontal_stacked', - 'bar_percentage_stacked', - 'bar_horizontal', 'bar', + 'bar_horizontal', + 'bar_percentage_stacked', + 'bar_horizontal_stacked', + 'bar_horizontal_percentage_stacked', + 'area', + 'area_stacked', + 'area_percentage_stacked', + 'line', ]); }); @@ -226,15 +226,15 @@ describe('xy_suggestions', () => { ]); expect(suggestions.map(({ state }) => xyVisualization.getVisualizationTypeId(state))).toEqual([ 'bar_stacked', - 'line', - 'area_percentage_stacked', - 'area_stacked', - 'area', - 'bar_horizontal_percentage_stacked', - 'bar_horizontal_stacked', - 'bar_percentage_stacked', - 'bar_horizontal', 'bar', + 'bar_horizontal', + 'bar_percentage_stacked', + 'bar_horizontal_stacked', + 'bar_horizontal_percentage_stacked', + 'area', + 'area_stacked', + 'area_percentage_stacked', + 'line', ]); }); diff --git a/x-pack/plugins/monitoring/common/format_timestamp_to_duration.js b/x-pack/plugins/monitoring/common/format_timestamp_to_duration.js index 46c8f7db49b0..9e1d421989f5 100644 --- a/x-pack/plugins/monitoring/common/format_timestamp_to_duration.js +++ b/x-pack/plugins/monitoring/common/format_timestamp_to_duration.js @@ -48,7 +48,7 @@ export function formatTimestampToDuration(timestamp, calculationFlag, initialTim } return duration - .replace(/ 0 mins$/, '') - .replace(/ 0 hrs$/, '') - .replace(/ 0 days$/, ''); // See https://github.com/jsmreese/moment-duration-format/issues/64 + .replace(/ -?0 mins$/, '') + .replace(/ -?0 hrs$/, '') + .replace(/ -?0 days$/, ''); // See https://github.com/jsmreese/moment-duration-format/issues/64 } diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts index 04ab572a53db..500185cd7e14 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts @@ -333,12 +333,8 @@ export class HeadlessChromiumDriver { private _shouldUseCustomHeaders(conditions: ConditionalHeadersConditions, url: string) { const { hostname, protocol, port, pathname } = parseUrl(url); - if (pathname === undefined) { - // There's a discrepancy between the NodeJS docs and the typescript types. NodeJS docs - // just say 'string' and the typescript types say 'string | undefined'. We haven't hit a - // situation where it's undefined but here's an explicit Error if we do. - throw new Error(`pathname is undefined, don't know how to proceed`); - } + if (port === null) throw new Error(`URL missing port: ${url}`); + if (pathname === null) throw new Error(`URL missing pathname: ${url}`); return ( hostname === conditions.hostname && diff --git a/x-pack/plugins/reporting/server/export_types/common/get_full_urls.ts b/x-pack/plugins/reporting/server/export_types/common/get_full_urls.ts index 7621a95083bc..8b2507ed3d25 100644 --- a/x-pack/plugins/reporting/server/export_types/common/get_full_urls.ts +++ b/x-pack/plugins/reporting/server/export_types/common/get_full_urls.ts @@ -50,9 +50,9 @@ export function getFullUrls(config: ReportingConfig, job: TaskPayloadPDF | TaskP const urls = relativeUrls.map((relativeUrl) => { const parsedRelative: UrlWithStringQuery = urlParse(relativeUrl); const jobUrl = getAbsoluteUrl({ - path: parsedRelative.pathname, - hash: parsedRelative.hash, - search: parsedRelative.search, + path: parsedRelative.pathname === null ? undefined : parsedRelative.pathname, + hash: parsedRelative.hash === null ? undefined : parsedRelative.hash, + search: parsedRelative.search === null ? undefined : parsedRelative.search, }); // capture the route to the visualization diff --git a/x-pack/plugins/security_solution/public/common/utils/clone_http_fetch_query.test.ts b/x-pack/plugins/security_solution/public/common/utils/clone_http_fetch_query.test.ts index f70c2e8b6388..efb0a712d9b4 100644 --- a/x-pack/plugins/security_solution/public/common/utils/clone_http_fetch_query.test.ts +++ b/x-pack/plugins/security_solution/public/common/utils/clone_http_fetch_query.test.ts @@ -14,7 +14,7 @@ describe('cloneHttpFetchQuery', () => { a: 'a', '1': 1, undefined, - array: [1, 2, undefined], + array: [1, 2], }; expect(cloneHttpFetchQuery(query)).toMatchInlineSnapshot(` Object { @@ -23,7 +23,6 @@ describe('cloneHttpFetchQuery', () => { "array": Array [ 1, 2, - undefined, ], "undefined": undefined, } diff --git a/x-pack/plugins/security_solution/public/management/common/routing.ts b/x-pack/plugins/security_solution/public/management/common/routing.ts index b3162a8708a5..c2c82639bf7d 100644 --- a/x-pack/plugins/security_solution/public/management/common/routing.ts +++ b/x-pack/plugins/security_solution/public/management/common/routing.ts @@ -32,9 +32,9 @@ type Exact = T extends Shape ? ExactKeys : never; * Ensures that when creating a URL query param string, that the given input strictly * matches the expected interface (guards against possibly leaking internal state) */ -const querystringStringify: ( +const querystringStringify = ( params: Exact -) => string = querystring.stringify; +): string => querystring.stringify((params as unknown) as querystring.ParsedUrlQueryInput); /** Make `selected_endpoint` required */ type EndpointDetailsUrlProps = Omit & diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/url_from_query_params.ts b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/url_from_query_params.ts index c421f513556f..c9f0ff6235cc 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/url_from_query_params.ts +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/url_from_query_params.ts @@ -11,7 +11,7 @@ import { EndpointIndexUIQueryParams } from '../types'; import { AppLocation } from '../../../../../common/endpoint/types'; export function urlFromQueryParams(queryParams: EndpointIndexUIQueryParams): Partial { - const search = querystring.stringify(queryParams); + const search = querystring.stringify(queryParams as Record); return { search, }; diff --git a/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx b/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx index 430b5702be1b..8b2810143cb1 100644 --- a/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx +++ b/x-pack/plugins/security_solution/public/network/pages/details/index.test.tsx @@ -26,8 +26,6 @@ import { NetworkDetails } from './index'; type Action = 'PUSH' | 'POP' | 'REPLACE'; const pop: Action = 'POP'; -type GlobalWithFetch = NodeJS.Global & { fetch: jest.Mock }; - jest.mock('react-router-dom', () => { const original = jest.requireActual('react-router-dom'); @@ -85,7 +83,7 @@ describe('Network Details', () => { indicesExist: false, indexPattern: {}, }); - (global as GlobalWithFetch).fetch = jest.fn().mockImplementationOnce(() => + global.fetch = jest.fn().mockImplementationOnce(() => Promise.resolve({ ok: true, json: () => { diff --git a/x-pack/plugins/spaces/common/lib/spaces_url_parser.ts b/x-pack/plugins/spaces/common/lib/spaces_url_parser.ts index be950e6a651e..6466835899f1 100644 --- a/x-pack/plugins/spaces/common/lib/spaces_url_parser.ts +++ b/x-pack/plugins/spaces/common/lib/spaces_url_parser.ts @@ -8,9 +8,11 @@ import { DEFAULT_SPACE_ID } from '../constants'; const spaceContextRegex = /^\/s\/([a-z0-9_\-]+)/; export function getSpaceIdFromPath( - requestBasePath: string = '/', - serverBasePath: string = '/' + requestBasePath?: string | null, + serverBasePath?: string | null ): { spaceId: string; pathHasExplicitSpaceIdentifier: boolean } { + if (requestBasePath == null) requestBasePath = '/'; + if (serverBasePath == null) serverBasePath = '/'; const pathToCheck: string = stripServerBasePath(requestBasePath, serverBasePath); // Look for `/s/space-url-context` in the base path diff --git a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx index 270cf862ccbd..04d8dfb87cf9 100644 --- a/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx +++ b/x-pack/plugins/spaces/public/management/edit_space/manage_space_page.test.tsx @@ -7,6 +7,7 @@ import { EuiButton, EuiCheckboxProps } from '@elastic/eui'; import { ReactWrapper } from 'enzyme'; import React from 'react'; +import { wait } from '@testing-library/react'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { ConfirmAlterActiveSpaceModal } from './confirm_alter_active_space_modal'; @@ -69,7 +70,10 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); + await wait(() => { + wrapper.update(); + expect(wrapper.find('input[name="name"]')).toHaveLength(1); + }); const nameInput = wrapper.find('input[name="name"]'); const descriptionInput = wrapper.find('textarea[name="description"]'); @@ -128,9 +132,11 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); + await wait(() => { + wrapper.update(); + expect(spacesManager.getSpace).toHaveBeenCalledWith('existing-space'); + }); - expect(spacesManager.getSpace).toHaveBeenCalledWith('existing-space'); expect(onLoadSpace).toHaveBeenCalledWith({ ...spaceToUpdate, }); @@ -179,10 +185,11 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); - - expect(notifications.toasts.addError).toHaveBeenCalledWith(error, { - title: 'Error loading available features', + await wait(() => { + wrapper.update(); + expect(notifications.toasts.addError).toHaveBeenCalledWith(error, { + title: 'Error loading available features', + }); }); }); @@ -216,9 +223,10 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); - - expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); + await wait(() => { + wrapper.update(); + expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); + }); await Promise.resolve(); @@ -277,9 +285,10 @@ describe('ManageSpacePage', () => { /> ); - await waitForDataLoad(wrapper); - - expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); + await wait(() => { + wrapper.update(); + expect(spacesManager.getSpace).toHaveBeenCalledWith('my-space'); + }); await Promise.resolve(); @@ -327,9 +336,3 @@ async function clickSaveButton(wrapper: ReactWrapper) { wrapper.update(); } - -async function waitForDataLoad(wrapper: ReactWrapper) { - await Promise.resolve(); - await Promise.resolve(); - wrapper.update(); -} diff --git a/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx b/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx index 5de7fcf69b36..be12550648a0 100644 --- a/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx +++ b/x-pack/plugins/spaces/public/nav_control/nav_control_popover.test.tsx @@ -13,6 +13,7 @@ import { SpacesManager } from '../spaces_manager'; import { NavControlPopover } from './nav_control_popover'; import { EuiHeaderSectionItemButton } from '@elastic/eui'; import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { wait } from '@testing-library/react'; describe('NavControlPopover', () => { it('renders without crashing', () => { @@ -64,10 +65,9 @@ describe('NavControlPopover', () => { wrapper.find(EuiHeaderSectionItemButton).simulate('click'); // Wait for `getSpaces` promise to resolve - await Promise.resolve(); - await Promise.resolve(); - wrapper.update(); - - expect(wrapper.find(SpaceAvatar)).toHaveLength(3); + await wait(() => { + wrapper.update(); + expect(wrapper.find(SpaceAvatar)).toHaveLength(3); + }); }); }); diff --git a/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts b/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts index 1cec7b769fa2..d1a8e93bff92 100644 --- a/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts +++ b/x-pack/plugins/spaces/server/lib/copy_to_spaces/copy_to_spaces.test.ts @@ -283,7 +283,7 @@ describe('copySavedObjectsToSpaces', () => { new Readable({ objectMode: true, read() { - this.emit('error', new Error('Something went wrong while reading this stream')); + this.destroy(new Error('Something went wrong while reading this stream')); }, }) ); diff --git a/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts b/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts index 37181c9d8164..f1b475ee9d1b 100644 --- a/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts +++ b/x-pack/plugins/spaces/server/lib/copy_to_spaces/resolve_copy_conflicts.test.ts @@ -290,7 +290,7 @@ describe('resolveCopySavedObjectsToSpacesConflicts', () => { new Readable({ objectMode: true, read() { - this.emit('error', new Error('Something went wrong while reading this stream')); + this.destroy(new Error('Something went wrong while reading this stream')); }, }) ); diff --git a/x-pack/plugins/uptime/public/components/overview/__tests__/synthetics_callout.test.tsx b/x-pack/plugins/uptime/public/components/overview/__tests__/synthetics_callout.test.tsx index 88bae4c72b68..980021b7d607 100644 --- a/x-pack/plugins/uptime/public/components/overview/__tests__/synthetics_callout.test.tsx +++ b/x-pack/plugins/uptime/public/components/overview/__tests__/synthetics_callout.test.tsx @@ -19,7 +19,6 @@ describe('SyntheticsCallout', () => { setItem: setItemMock, }; - // @ts-expect-error replacing a call to localStorage we use for monitor list size global.localStorage = localStorageMock; }); diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx index 352369cfdb72..8e5ae13836f4 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/__tests__/monitor_list.test.tsx @@ -135,7 +135,6 @@ describe('MonitorList component', () => { setItem: jest.fn(), }; - // @ts-expect-error replacing a call to localStorage we use for monitor list size global.localStorage = localStorageMock; }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts index 4e9293b74c99..edac71b8c594 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts @@ -311,12 +311,36 @@ export default function jiraTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: `error validating action params: Cannot read property 'Symbol(Symbol.iterator)' of undefined`, - }); + expect(Object.keys(resp.body)).to.eql(['status', 'actionId', 'message', 'retry']); + expect(resp.body.actionId).to.eql(simulatedActionId); + expect(resp.body.status).to.eql('error'); + expect(resp.body.retry).to.eql(false); + // Node.js 12 oddity: + // + // The first time after the server is booted, the error message will be: + // + // undefined is not iterable (cannot read property Symbol(Symbol.iterator)) + // + // After this, the error will be: + // + // Cannot destructure property 'value' of 'undefined' as it is undefined. + // + // The error seems to come from the exact same place in the code based on the + // exact same circomstances: + // + // https://github.com/elastic/kibana/blob/b0a223ebcbac7e404e8ae6da23b2cc6a4b509ff1/packages/kbn-config-schema/src/types/literal_type.ts#L28 + // + // What triggers the error is that the `handleError` function expects its 2nd + // argument to be an object containing a `valids` property of type array. + // + // In this test the object does not contain a `valids` property, so hence the + // error. + // + // Why the error message isn't the same in all scenarios is unknown to me and + // could be a bug in V8. + expect(resp.body.message).to.match( + /^error validating action params: (undefined is not iterable \(cannot read property Symbol\(Symbol.iterator\)\)|Cannot destructure property 'value' of 'undefined' as it is undefined\.)$/ + ); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts index 34c1c757ab11..617f66ec98f5 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/resilient.ts @@ -312,12 +312,36 @@ export default function resilientTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: `error validating action params: Cannot read property 'Symbol(Symbol.iterator)' of undefined`, - }); + expect(Object.keys(resp.body)).to.eql(['status', 'actionId', 'message', 'retry']); + expect(resp.body.actionId).to.eql(simulatedActionId); + expect(resp.body.status).to.eql('error'); + expect(resp.body.retry).to.eql(false); + // Node.js 12 oddity: + // + // The first time after the server is booted, the error message will be: + // + // undefined is not iterable (cannot read property Symbol(Symbol.iterator)) + // + // After this, the error will be: + // + // Cannot destructure property 'value' of 'undefined' as it is undefined. + // + // The error seems to come from the exact same place in the code based on the + // exact same circomstances: + // + // https://github.com/elastic/kibana/blob/b0a223ebcbac7e404e8ae6da23b2cc6a4b509ff1/packages/kbn-config-schema/src/types/literal_type.ts#L28 + // + // What triggers the error is that the `handleError` function expects its 2nd + // argument to be an object containing a `valids` property of type array. + // + // In this test the object does not contain a `valids` property, so hence the + // error. + // + // Why the error message isn't the same in all scenarios is unknown to me and + // could be a bug in V8. + expect(resp.body.message).to.match( + /^error validating action params: (undefined is not iterable \(cannot read property Symbol\(Symbol.iterator\)\)|Cannot destructure property 'value' of 'undefined' as it is undefined\.)$/ + ); }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index 5b4db53a59a4..47bfd3c49612 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -306,12 +306,36 @@ export default function servicenowTest({ getService }: FtrProviderContext) { params: {}, }) .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: `error validating action params: Cannot read property 'Symbol(Symbol.iterator)' of undefined`, - }); + expect(Object.keys(resp.body)).to.eql(['status', 'actionId', 'message', 'retry']); + expect(resp.body.actionId).to.eql(simulatedActionId); + expect(resp.body.status).to.eql('error'); + expect(resp.body.retry).to.eql(false); + // Node.js 12 oddity: + // + // The first time after the server is booted, the error message will be: + // + // undefined is not iterable (cannot read property Symbol(Symbol.iterator)) + // + // After this, the error will be: + // + // Cannot destructure property 'value' of 'undefined' as it is undefined. + // + // The error seems to come from the exact same place in the code based on the + // exact same circomstances: + // + // https://github.com/elastic/kibana/blob/b0a223ebcbac7e404e8ae6da23b2cc6a4b509ff1/packages/kbn-config-schema/src/types/literal_type.ts#L28 + // + // What triggers the error is that the `handleError` function expects its 2nd + // argument to be an object containing a `valids` property of type array. + // + // In this test the object does not contain a `valids` property, so hence the + // error. + // + // Why the error message isn't the same in all scenarios is unknown to me and + // could be a bug in V8. + expect(resp.body.message).to.match( + /^error validating action params: (undefined is not iterable \(cannot read property Symbol\(Symbol.iterator\)\)|Cannot destructure property 'value' of 'undefined' as it is undefined\.)$/ + ); }); }); diff --git a/x-pack/test/apm_api_integration/basic/tests/transaction_groups/distribution.ts b/x-pack/test/apm_api_integration/basic/tests/transaction_groups/distribution.ts index c72d48094ca8..e0b03e1a91f4 100644 --- a/x-pack/test/apm_api_integration/basic/tests/transaction_groups/distribution.ts +++ b/x-pack/test/apm_api_integration/basic/tests/transaction_groups/distribution.ts @@ -20,7 +20,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { const url = `/api/apm/services/opbeans-java/transaction_groups/distribution?${qs.stringify({ start: metadata.start, end: metadata.end, - uiFilters: {}, + uiFilters: encodeURIComponent('{}'), transactionName: 'APIRestController#stats', transactionType: 'request', })}`; diff --git a/x-pack/test/apm_api_integration/trial/tests/service_maps/service_maps.ts b/x-pack/test/apm_api_integration/trial/tests/service_maps/service_maps.ts index 25c3f753341d..9c01833f78e5 100644 --- a/x-pack/test/apm_api_integration/trial/tests/service_maps/service_maps.ts +++ b/x-pack/test/apm_api_integration/trial/tests/service_maps/service_maps.ts @@ -111,7 +111,7 @@ export default function serviceMapsApiTests({ getService }: FtrProviderContext) const q = querystring.stringify({ start: metadata.start, end: metadata.end, - uiFilters: {}, + uiFilters: encodeURIComponent('{}'), }); const response = await supertest.get(`/api/apm/service-map/service/opbeans-node?${q}`); diff --git a/x-pack/test/functional/es_archives/reporting/hugedata/data.json.gz b/x-pack/test/functional/es_archives/reporting/hugedata/data.json.gz index c616730ff35b64074b036f0bf30b77d0e45b6c75..83da642be87622f3b3d7a7b0b92f62e88fed5977 100644 GIT binary patch delta 32865 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 D>-1#y delta 32864 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 8", "@types/node@>=10.17.17 <10.20.0", "@types/node@>=8.9.0", "@types/node@^12.0.2": - version "10.17.26" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.26.tgz#a8a119960bff16b823be4c617da028570779bcfd" - integrity sha512-myMwkO2Cr82kirHY8uknNRHEVtn0wV3DTQfkrjx17jmkstDRZ24gNUdl8AHXVyVclTYI/bNjgTPTAWvWLqXqkw== +"@types/node@*", "@types/node@12.19.4", "@types/node@8.10.54", "@types/node@>= 8", "@types/node@>=8.9.0", "@types/node@^12.0.2": + version "12.19.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.4.tgz#cdfbb62e26c7435ed9aab9c941393cc3598e9b46" + integrity sha512-o3oj1bETk8kBwzz1WlO6JWL/AfAA3Vm6J1B3C9CsdxHYp7XgPiH7OEXPUbZTndHlRaIElrANkQfe6ZmfJb3H2w== "@types/nodemailer@^6.2.1": version "6.2.1" @@ -5881,10 +5881,10 @@ "@types/node" "*" chokidar "^2.1.2" -"@types/webpack-env@^1.15.2": - version "1.15.2" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.2.tgz#927997342bb9f4a5185a86e6579a0a18afc33b0a" - integrity sha512-67ZgZpAlhIICIdfQrB5fnDvaKFcDxpKibxznfYRVAT4mQE41Dido/3Ty+E3xGBmTogc5+0Qb8tWhna+5B8z1iQ== +"@types/webpack-env@^1.15.2", "@types/webpack-env@^1.15.3": + version "1.15.3" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.3.tgz#fb602cd4c2f0b7c0fb857e922075fdf677d25d84" + integrity sha512-5oiXqR7kwDGZ6+gmzIO2lTC+QsriNuQXZDWNYRV3l2XRN/zmPgnC21DLSx2D05zvD8vnXW6qUg7JnXZ4I6qLVQ== "@types/webpack-merge@^4.1.5": version "4.1.5"