From fc7754d3c953c16a436e2deba0794a6c17f13aae Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Mon, 14 Sep 2020 14:12:03 +0200 Subject: [PATCH 1/7] move `src/core/utils` to the @kbn/std package --- package.json | 1 + packages/kbn-std/README.md | 555 ++++++++++++++++++ packages/kbn-std/package.json | 21 + .../src}/__snapshots__/get.test.ts.snap | 0 .../kbn-std/src}/assert_never.ts | 0 .../kbn-std/src}/deep_freeze.test.ts | 0 .../kbn-std/src}/deep_freeze.ts | 0 .../kbn-std/src}/get.test.ts | 0 .../utils => packages/kbn-std/src}/get.ts | 0 .../kbn-std/src}/get_flattened_object.test.ts | 0 .../kbn-std/src}/get_flattened_object.ts | 0 packages/kbn-std/src/index.ts | 29 + .../kbn-std/src}/map_to_object.ts | 0 .../kbn-std/src}/map_utils.test.ts | 0 .../kbn-std/src}/map_utils.ts | 0 .../kbn-std/src}/merge.test.ts | 0 .../utils => packages/kbn-std/src}/merge.ts | 2 +- .../utils => packages/kbn-std/src}/pick.ts | 0 .../kbn-std/src}/promise.test.ts | 0 .../utils => packages/kbn-std/src}/promise.ts | 0 .../kbn-std/src}/unset.test.ts | 0 .../utils => packages/kbn-std/src}/unset.ts | 0 .../kbn-std/src}/url.test.ts | 0 .../utils => packages/kbn-std/src}/url.ts | 0 packages/kbn-std/tsconfig.json | 16 + .../capabilities/capabilities_service.mock.ts | 2 +- .../capabilities/capabilities_service.tsx | 2 +- src/core/public/chrome/nav_links/nav_link.ts | 2 +- src/core/public/core_system.ts | 2 +- .../public/doc_links/doc_links_service.ts | 2 +- src/core/public/http/base_path.ts | 2 +- src/core/public/index.ts | 8 +- .../injected_metadata_service.ts | 2 +- src/core/public/plugins/plugins_service.ts | 2 +- .../config/deprecation/deprecation_factory.ts | 4 +- .../server/config/object_to_config_adapter.ts | 4 +- .../elasticsearch/elasticsearch_service.ts | 2 +- .../legacy/elasticsearch_client_config.ts | 2 +- src/core/server/http/base_path_service.ts | 4 +- src/core/server/http/http_service.ts | 2 +- src/core/server/http/router/headers.ts | 3 +- src/core/server/http/router/request.ts | 2 +- src/core/server/index.ts | 4 +- .../legacy/config/get_unused_config_keys.ts | 2 +- .../server/logging/appenders/appenders.ts | 2 +- src/core/server/logging/layouts/layouts.ts | 2 +- src/core/server/logging/log_level.ts | 2 +- src/core/server/plugins/plugin_context.ts | 3 +- src/core/server/plugins/plugins_service.ts | 4 +- src/core/server/plugins/plugins_system.ts | 2 +- .../saved_objects_type_registry.ts | 2 +- src/core/server/server.ts | 2 +- src/core/server/status/types.ts | 2 +- .../server/ui_settings/settings/navigation.ts | 2 +- .../server/ui_settings/ui_settings_service.ts | 4 +- src/core/utils/context.ts | 4 +- src/core/utils/index.ts | 21 +- 57 files changed, 674 insertions(+), 55 deletions(-) create mode 100644 packages/kbn-std/README.md create mode 100644 packages/kbn-std/package.json rename {src/core/utils => packages/kbn-std/src}/__snapshots__/get.test.ts.snap (100%) rename {src/core/utils => packages/kbn-std/src}/assert_never.ts (100%) rename {src/core/utils => packages/kbn-std/src}/deep_freeze.test.ts (100%) rename {src/core/utils => packages/kbn-std/src}/deep_freeze.ts (100%) rename {src/core/utils => packages/kbn-std/src}/get.test.ts (100%) rename {src/core/utils => packages/kbn-std/src}/get.ts (100%) rename {src/core/utils => packages/kbn-std/src}/get_flattened_object.test.ts (100%) rename {src/core/utils => packages/kbn-std/src}/get_flattened_object.ts (100%) create mode 100644 packages/kbn-std/src/index.ts rename {src/core/utils => packages/kbn-std/src}/map_to_object.ts (100%) rename {src/core/utils => packages/kbn-std/src}/map_utils.test.ts (100%) rename {src/core/utils => packages/kbn-std/src}/map_utils.ts (100%) rename {src/core/utils => packages/kbn-std/src}/merge.test.ts (100%) rename {src/core/utils => packages/kbn-std/src}/merge.ts (98%) rename {src/core/utils => packages/kbn-std/src}/pick.ts (100%) rename {src/core/utils => packages/kbn-std/src}/promise.test.ts (100%) rename {src/core/utils => packages/kbn-std/src}/promise.ts (100%) rename {src/core/utils => packages/kbn-std/src}/unset.test.ts (100%) rename {src/core/utils => packages/kbn-std/src}/unset.ts (100%) rename {src/core/utils => packages/kbn-std/src}/url.test.ts (100%) rename {src/core/utils => packages/kbn-std/src}/url.ts (100%) create mode 100644 packages/kbn-std/tsconfig.json diff --git a/package.json b/package.json index 7468a49d56959..d4ebfefc87270 100644 --- a/package.json +++ b/package.json @@ -141,6 +141,7 @@ "@kbn/i18n": "1.0.0", "@kbn/interpreter": "1.0.0", "@kbn/pm": "1.0.0", + "@kbn/std": "1.0.0", "@kbn/telemetry-tools": "1.0.0", "@kbn/test-subj-selector": "0.2.1", "@kbn/ui-framework": "1.0.0", diff --git a/packages/kbn-std/README.md b/packages/kbn-std/README.md new file mode 100644 index 0000000000000..a4f2c1f6458cf --- /dev/null +++ b/packages/kbn-std/README.md @@ -0,0 +1,555 @@ +# `@kbn/config-schema` — The Kibana config validation library + +`@kbn/config-schema` is a TypeScript library inspired by Joi and designed to allow run-time validation of the +Kibana configuration entries providing developers with a fully typed model of the validated data. + +## Table of Contents + +- [Why `@kbn/config-schema`?](#why-kbnconfig-schema) +- [Schema building blocks](#schema-building-blocks) + - [Basic types](#basic-types) + - [`schema.string()`](#schemastring) + - [`schema.number()`](#schemanumber) + - [`schema.boolean()`](#schemaboolean) + - [`schema.literal()`](#schemaliteral) + - [`schema.buffer()`](#schemabuffer) + - [`schema.stream()`](#schemastream) + - [Composite types](#composite-types) + - [`schema.arrayOf()`](#schemaarrayof) + - [`schema.object()`](#schemaobject) + - [`schema.recordOf()`](#schemarecordof) + - [`schema.mapOf()`](#schemamapof) + - [Advanced types](#advanced-types) + - [`schema.oneOf()`](#schemaoneof) + - [`schema.any()`](#schemaany) + - [`schema.maybe()`](#schemamaybe) + - [`schema.nullable()`](#schemanullable) + - [`schema.never()`](#schemanever) + - [`schema.uri()`](#schemauri) + - [`schema.byteSize()`](#schemabytesize) + - [`schema.duration()`](#schemaduration) + - [`schema.conditional()`](#schemaconditional) + - [References](#references) + - [`schema.contextRef()`](#schemacontextref) + - [`schema.siblingRef()`](#schemasiblingref) +- [Custom validation](#custom-validation) +- [Default values](#default-values) + +## Why `@kbn/config-schema`? + +Validation of externally supplied data is very important for Kibana. Especially if this data is used to configure how it operates. + +There are a number of reasons why we decided to roll our own solution for the configuration validation: + +* **Limited API surface** - having a future rich library is awesome, but it's a really hard task to audit such library and make sure everything is sane and secure enough. As everyone knows complexity is the enemy of security and hence we'd like to have a full control over what exactly we expose and commit to maintain. +* **Custom error messages** - detailed validation error messages are a great help to developers, but at the same time they can contain information that's way too sensitive to expose to everyone. We'd like to control these messages and make them only as detailed as really needed. For example, we don't want validation error messages to contain the passwords for internal users to show-up in the logs. These logs are commonly ingested into Elasticsearch, and accessible to a large number of users which shouldn't have access to the internal user's password. +* **Type information** - having run-time guarantees is great, but additionally having compile-time guarantees is even better. We'd like to provide developers with a fully typed model of the validated data so that it's harder to misuse it _after_ validation. +* **Upgradability** - no matter how well a validation library is implemented, it will have bugs and may need to be improved at some point anyway. Some external libraries are very well supported, some aren't or won't be in the future. It's always a risk to depend on an external party with their own release cadence when you need to quickly fix a security vulnerability in a patch version. We'd like to have a better control over lifecycle of such an important piece of our codebase. + +## Schema building blocks + +The schema is composed of one or more primitives depending on the shape of the data you'd like to validate. + +```typescript +const simpleStringSchema = schema.string(); +const moreComplexObjectSchema = schema.object({ name: schema.string() }); +``` + +Every schema instance has a `validate` method that is used to perform a validation of the data according to the schema. This method accepts three arguments: + +* `data: any` - **required**, data to be validated with the schema +* `context: Record` - **optional**, object whose properties can be referenced by the [context references](#schemacontextref) +* `namespace: string` - **optional**, arbitrary string that is used to prefix every error message thrown during validation + +```typescript +const valueSchema = schema.object({ + isEnabled: schema.boolean(), + env: schema.string({ defaultValue: schema.contextRef('envName') }), +}); + +expect(valueSchema.validate({ isEnabled: true, env: 'prod' })).toEqual({ + isEnabled: true, + env: 'prod', +}); + +// Use default value for `env` from context via reference +expect(valueSchema.validate({ isEnabled: true }, { envName: 'staging' })).toEqual({ + isEnabled: true, + env: 'staging', +}); + +// Fail because of type mismatch +expect(() => + valueSchema.validate({ isEnabled: 'non-bool' }, { envName: 'staging' }) +).toThrowError( + '[isEnabled]: expected value of type [boolean] but got [string]' +); + +// Fail because of type mismatch and prefix error with a custom namespace +expect(() => + valueSchema.validate({ isEnabled: 'non-bool' }, { envName: 'staging' }, 'configuration') +).toThrowError( + '[configuration.isEnabled]: expected value of type [boolean] but got [string]' +); +``` + +__Notes:__ +* `validate` method throws as soon as the first schema violation is encountered, no further validation is performed. +* when you retrieve configuration within a Kibana plugin `validate` function is called by the Core automatically providing appropriate namespace and context variables (environment name, package info etc.). + +### Basic types + +#### `schema.string()` + +Validates input data as a string. + +__Output type:__ `string` + +__Options:__ + * `defaultValue: string | Reference | (() => string)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: string) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + * `minLength: number` - defines a minimum length the string should have. + * `maxLength: number` - defines a maximum length the string should have. + * `hostname: boolean` - indicates whether the string should be validated as a valid hostname (per [RFC 1123](https://tools.ietf.org/html/rfc1123)). + +__Usage:__ +```typescript +const valueSchema = schema.string({ maxLength: 10 }); +``` + +__Notes:__ +* By default `schema.string()` allows empty strings, to prevent that use non-zero value for `minLength` option. +* To validate a string using a regular expression use a custom validator function, see [Custom validation](#custom-validation) section for more details. + +#### `schema.number()` + +Validates input data as a number. + +__Output type:__ `number` + +__Options:__ + * `defaultValue: number | Reference | (() => number)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: number) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + * `min: number` - defines a minimum value the number should have. + * `max: number` - defines a maximum value the number should have. + +__Usage:__ +```typescript +const valueSchema = schema.number({ max: 10 }); +``` + +__Notes:__ +* The `schema.number()` also supports a string as input if it can be safely coerced into number. + +#### `schema.boolean()` + +Validates input data as a boolean. + +__Output type:__ `boolean` + +__Options:__ + * `defaultValue: boolean | Reference | (() => boolean)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: boolean) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = schema.boolean({ defaultValue: false }); +``` + +__Notes:__ +* The `schema.boolean()` also supports a string as input if it equals `'true'` or `'false'` (case-insensitive). + +#### `schema.literal()` + +Validates input data as a [string](https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types), [numeric](https://www.typescriptlang.org/docs/handbook/advanced-types.html#numeric-literal-types) or boolean literal. + +__Output type:__ `string`, `number` or `boolean` literals + +__Options:__ + * `defaultValue: TLiteral | Reference | (() => TLiteral)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: TLiteral) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = [ + schema.literal('stringLiteral'), + schema.literal(100500), + schema.literal(false), +]; +``` + +#### `schema.buffer()` + +Validates input data as a NodeJS `Buffer`. + +__Output type:__ `Buffer` + +__Options:__ + * `defaultValue: TBuffer | Reference | (() => TBuffer)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: TBuffer) => Buffer | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = schema.buffer({ defaultValue: Buffer.from('Hi, there!') }); +``` + +#### `schema.stream()` + +Validates input data as a NodeJS `stream`. + +__Output type:__ `Stream`, `Readable` or `Writtable` + +__Options:__ + * `defaultValue: TStream | Reference | (() => TStream)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: TStream) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = schema.stream({ defaultValue: new Stream() }); +``` + +### Composite types + +#### `schema.arrayOf()` + +Validates input data as a homogeneous array with the values being validated against predefined schema. + +__Output type:__ `TValue[]` + +__Options:__ + * `defaultValue: TValue[] | Reference | (() => TValue[])` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: TValue[]) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + * `minSize: number` - defines a minimum size the array should have. + * `maxSize: number` - defines a maximum size the array should have. + +__Usage:__ +```typescript +const valueSchema = schema.arrayOf(schema.number()); +``` + +__Notes:__ +* The `schema.arrayOf()` also supports a json string as input if it can be safely parsed using `JSON.parse` and if the resulting value is an array. + +#### `schema.object()` + +Validates input data as an object with a predefined set of properties. + +__Output type:__ `{ [K in keyof TProps]: TypeOf } as TObject` + +__Options:__ + * `defaultValue: TObject | Reference | (() => TObject)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: TObject) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + * `unknowns: 'allow' | 'ignore' | 'forbid'` - indicates whether unknown object properties should be allowed, ignored, or forbidden. It's `forbid` by default. + +__Usage:__ +```typescript +const valueSchema = schema.object({ + isEnabled: schema.boolean({ defaultValue: false }), + name: schema.string({ minLength: 10 }), +}); +``` + +__Notes:__ +* Using `unknowns: 'allow'` is discouraged and should only be used in exceptional circumstances. Consider using `schema.recordOf()` instead. +* Currently `schema.object()` always has a default value of `{}`, but this may change in the near future. Try to not rely on this behaviour and specify default value explicitly or use `schema.maybe()` if the value is optional. +* `schema.object()` also supports a json string as input if it can be safely parsed using `JSON.parse` and if the resulting value is a plain object. + +#### `schema.recordOf()` + +Validates input data as an object with the keys and values being validated against predefined schema. + +__Output type:__ `Record` + +__Options:__ + * `defaultValue: Record | Reference> | (() => Record)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: Record) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = schema.recordOf(schema.string(), schema.number()); +``` + +__Notes:__ +* You can use a union of literal types as a record's key schema to restrict record to a specific set of keys, e.g. `schema.oneOf([schema.literal('isEnabled'), schema.literal('name')])`. +* `schema.recordOf()` also supports a json string as input if it can be safely parsed using `JSON.parse` and if the resulting value is a plain object. + +#### `schema.mapOf()` + +Validates input data as a map with the keys and values being validated against the predefined schema. + +__Output type:__ `Map` + +__Options:__ + * `defaultValue: Map | Reference> | (() => Map)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: Map) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = schema.mapOf(schema.string(), schema.number()); +``` + +__Notes:__ +* You can use a union of literal types as a record's key schema to restrict record to a specific set of keys, e.g. `schema.oneOf([schema.literal('isEnabled'), schema.literal('name')])`. +* `schema.mapOf()` also supports a json string as input if it can be safely parsed using `JSON.parse` and if the resulting value is a plain object. + +### Advanced types + +#### `schema.oneOf()` + +Allows a list of alternative schemas to validate input data against. + +__Output type:__ `TValue1 | TValue2 | TValue3 | ..... as TUnion` + +__Options:__ + * `defaultValue: TUnion | Reference | (() => TUnion)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: TUnion) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = schema.oneOf([schema.literal('∞'), schema.number()]); +``` + +__Notes:__ +* Since the result data type is a type union you should use various TypeScript type guards to get the exact type. + +#### `schema.any()` + +Indicates that input data shouldn't be validated and returned as is. + +__Output type:__ `any` + +__Options:__ + * `defaultValue: any | Reference | (() => any)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: any) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = schema.any(); +``` + +__Notes:__ +* `schema.any()` is essentially an escape hatch for the case when your data can __really__ have any type and should be avoided at all costs. + +#### `schema.maybe()` + +Indicates that input data is optional and may not be present. + +__Output type:__ `T | undefined` + +__Usage:__ +```typescript +const valueSchema = schema.maybe(schema.string()); +``` + +__Notes:__ +* Don't use `schema.maybe()` if a nested type defines a default value. + +#### `schema.nullable()` + +Indicates that input data is optional and defaults to `null` if it's not present. + +__Output type:__ `T | null` + +__Usage:__ +```typescript +const valueSchema = schema.nullable(schema.string()); +``` + +__Notes:__ +* `schema.nullable()` also treats explicitly specified `null` as a valid input. + +#### `schema.never()` + +Indicates that input data is forbidden. + +__Output type:__ `never` + +__Usage:__ +```typescript +const valueSchema = schema.never(); +``` + +__Notes:__ +* `schema.never()` has a very limited application and usually used within [conditional schemas](#schemaconditional) to fully or partially forbid input data. + +#### `schema.uri()` + +Validates input data as a proper URI string (per [RFC 3986](https://tools.ietf.org/html/rfc3986)). + +__Output type:__ `string` + +__Options:__ + * `defaultValue: string | Reference | (() => string)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: string) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + * `scheme: string | string[]` - limits allowed URI schemes to the one(s) defined here. + +__Usage:__ +```typescript +const valueSchema = schema.uri({ scheme: 'https' }); +``` + +__Notes:__ +* Prefer using `schema.uri()` for all URI validations even though it may be possible to replicate it with a custom validator for `schema.string()`. + +#### `schema.byteSize()` + +Validates input data as a proper digital data size. + +__Output type:__ `ByteSizeValue` + +__Options:__ + * `defaultValue: ByteSizeValue | string | number | Reference | (() => ByteSizeValue | string | number)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: ByteSizeValue | string | number) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + * `min: ByteSizeValue | string | number` - defines a minimum value the size should have. + * `max: ByteSizeValue | string | number` - defines a maximum value the size should have. + +__Usage:__ +```typescript +const valueSchema = schema.byteSize({ min: '3kb' }); +``` + +__Notes:__ +* The string value for `schema.byteSize()` and its options supports the following optional suffixes: `b`, `kb`, `mb`, `gb` and `tb`. The default suffix is `b`. +* The number value is treated as a number of bytes and hence should be a positive integer, e.g. `100` is equal to `'100b'`. +* Currently you cannot specify zero bytes with a string format and should use number `0` instead. + +#### `schema.duration()` + +Validates input data as a proper [duration](https://momentjs.com/docs/#/durations/). + +__Output type:__ `moment.Duration` + +__Options:__ + * `defaultValue: moment.Duration | string | number | Reference | (() => moment.Duration | string | number)` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: moment.Duration | string | number) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = schema.duration({ defaultValue: '70ms' }); +``` + +__Notes:__ +* The string value for `schema.duration()` supports the following optional suffixes: `ms`, `s`, `m`, `h`, `d`, `w`, `M` and `Y`. The default suffix is `ms`. +* The number value is treated as a number of milliseconds and hence should be a positive integer, e.g. `100` is equal to `'100ms'`. + +#### `schema.conditional()` + +Allows a specified condition that is evaluated _at the validation time_ and results in either one or another input validation schema. + +The first argument is always a [reference](#references) while the second one can be: +* another reference, in this cases both references are "dereferenced" and compared +* schema, in this case the schema is used to validate "dereferenced" value of the first reference +* value, in this case "dereferenced" value of the first reference is compared to that value + +The third argument is a schema that should be used if the result of the aforementioned comparison evaluates to `true`, otherwise `schema.conditional()` should fallback +to the schema provided as the fourth argument. + +__Output type:__ `TTrueResult | TFalseResult` + +__Options:__ + * `defaultValue: TTrueResult | TFalseResult | Reference | (() => TTrueResult | TFalseResult` - defines a default value, see [Default values](#default-values) section for more details. + * `validate: (value: TTrueResult | TFalseResult) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. + +__Usage:__ +```typescript +const valueSchema = schema.object({ + key: schema.oneOf([schema.literal('number'), schema.literal('string')]), + value: schema.conditional(schema.siblingRef('key'), 'number', schema.number(), schema.string()), +}); +``` + +__Notes:__ +* Conditional schemas may be hard to read and understand and hence should be used only sparingly. + +### References + +#### `schema.contextRef()` + +Defines a reference to the value specified through the validation context. Context reference is only used as part of a [conditional schema](#schemaconditional) or as a default value for any other schema. + +__Output type:__ `TReferenceValue` + +__Usage:__ +```typescript +const valueSchema = schema.object({ + env: schema.string({ defaultValue: schema.contextRef('envName') }), +}); +valueSchema.validate({}, { envName: 'dev' }); +``` + +__Notes:__ +* The `@kbn/config-schema` neither validates nor coerces the "dereferenced" value and the developer is responsible for making sure that it has the appropriate type. +* The root context that Kibana provides during config validation includes lots of useful properties like `environment name` that can be used to provide a strict schema for production and more relaxed one for development. + +#### `schema.siblingRef()` + +Defines a reference to the value of the sibling key. Sibling references are only used a part of [conditional schema](#schemaconditional) or as a default value for any other schema. + +__Output type:__ `TReferenceValue` + +__Usage:__ +```typescript +const valueSchema = schema.object({ + node: schema.object({ tag: schema.string() }), + env: schema.string({ defaultValue: schema.siblingRef('node.tag') }), +}); +``` + +__Notes:__ +* The `@kbn/config-schema` neither validates nor coerces the "dereferenced" value and the developer is responsible for making sure that it has the appropriate type. + +## Custom validation + +Using built-in schema primitives may not be enough in some scenarios or sometimes the attempt to model complex schemas with built-in primitives only may result in unreadable code. +For these cases `@kbn/config-schema` provides a way to specify a custom validation function for almost any schema building block through the `validate` option. + +For example `@kbn/config-schema` doesn't have a dedicated primitive for the `RegExp` based validation currently, but you can easily do that with a custom `validate` function: + +```typescript +const valueSchema = schema.string({ + minLength: 3, + validate(value) { + if (!/^[a-z0-9_-]+$/.test(value)) { + return `must be lower case, a-z, 0-9, '_', and '-' are allowed`; + } + }, +}); + +// ...or if you use that construct a lot... + +const regexSchema = (regex: RegExp) => schema.string({ + validate: value => regex.test(value) ? undefined : `must match "${regex.toString()}"`, +}); +const valueSchema = regexSchema(/^[a-z0-9_-]+$/); +``` + +Custom validation function is run _only after_ all built-in validations passed. It should either return a `string` as an error message +to denote the failed validation or not return anything at all (`void`) otherwise. Please also note that `validate` function is synchronous. + +Another use case for custom validation functions is when the schema depends on some run-time data: + +```typescript +const gesSchema = randomRunTimeSeed => schema.string({ + validate: value => value !== randomRunTimeSeed ? 'value is not allowed' : undefined +}); + +const schema = gesSchema('some-random-run-time-data'); +``` + +## Default values + +If you have an optional config field that you can have a default value for you may want to consider using dedicated `defaultValue` option to not +deal with "defined or undefined"-like checks all over the place in your code. You have three options to provide a default value for almost any schema primitive: + +* plain value that's known at the compile time +* [reference](#references) to a value that will be "dereferenced" at the validation time +* function that is invoked at the validation time and returns a plain value + +```typescript +const valueSchemaWithPlainValueDefault = schema.string({ defaultValue: 'n/a' }); +const valueSchemaWithReferencedValueDefault = schema.string({ defaultValue: schema.contextRef('env') }); +const valueSchemaWithFunctionEvaluatedDefault = schema.string({ defaultValue: () => Math.random().toString() }); +``` + +__Notes:__ +* `@kbn/config-schema` neither validates nor coerces default value and developer is responsible for making sure that it has the appropriate type. diff --git a/packages/kbn-std/package.json b/packages/kbn-std/package.json new file mode 100644 index 0000000000000..4c67706b45d27 --- /dev/null +++ b/packages/kbn-std/package.json @@ -0,0 +1,21 @@ +{ + "name": "@kbn/std", + "main": "./target/index.js", + "types": "./target/index.d.ts", + "version": "1.0.0", + "license": "Apache-2.0", + "private": true, + "scripts": { + "build": "tsc", + "kbn:bootstrap": "yarn build" + }, + "devDependencies": { + "typescript": "4.0.2", + "tsd": "^0.13.1" + }, + "dependencies": { + "@kbn/utility-types": "1.0.0", + "lodash": "^4.17.15", + "query-string": "5.1.1" + } +} diff --git a/src/core/utils/__snapshots__/get.test.ts.snap b/packages/kbn-std/src/__snapshots__/get.test.ts.snap similarity index 100% rename from src/core/utils/__snapshots__/get.test.ts.snap rename to packages/kbn-std/src/__snapshots__/get.test.ts.snap diff --git a/src/core/utils/assert_never.ts b/packages/kbn-std/src/assert_never.ts similarity index 100% rename from src/core/utils/assert_never.ts rename to packages/kbn-std/src/assert_never.ts diff --git a/src/core/utils/deep_freeze.test.ts b/packages/kbn-std/src/deep_freeze.test.ts similarity index 100% rename from src/core/utils/deep_freeze.test.ts rename to packages/kbn-std/src/deep_freeze.test.ts diff --git a/src/core/utils/deep_freeze.ts b/packages/kbn-std/src/deep_freeze.ts similarity index 100% rename from src/core/utils/deep_freeze.ts rename to packages/kbn-std/src/deep_freeze.ts diff --git a/src/core/utils/get.test.ts b/packages/kbn-std/src/get.test.ts similarity index 100% rename from src/core/utils/get.test.ts rename to packages/kbn-std/src/get.test.ts diff --git a/src/core/utils/get.ts b/packages/kbn-std/src/get.ts similarity index 100% rename from src/core/utils/get.ts rename to packages/kbn-std/src/get.ts diff --git a/src/core/utils/get_flattened_object.test.ts b/packages/kbn-std/src/get_flattened_object.test.ts similarity index 100% rename from src/core/utils/get_flattened_object.test.ts rename to packages/kbn-std/src/get_flattened_object.test.ts diff --git a/src/core/utils/get_flattened_object.ts b/packages/kbn-std/src/get_flattened_object.ts similarity index 100% rename from src/core/utils/get_flattened_object.ts rename to packages/kbn-std/src/get_flattened_object.ts diff --git a/packages/kbn-std/src/index.ts b/packages/kbn-std/src/index.ts new file mode 100644 index 0000000000000..7cf70a0e28e2c --- /dev/null +++ b/packages/kbn-std/src/index.ts @@ -0,0 +1,29 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +export { assertNever } from './assert_never'; +export { deepFreeze, Freezable } from './deep_freeze'; +export { get } from './get'; +export { mapToObject } from './map_to_object'; +export { merge } from './merge'; +export { pick } from './pick'; +export { withTimeout } from './promise'; +export { isRelativeUrl, modifyUrl, URLMeaningfulParts } from './url'; +export { unset } from './unset'; +export { getFlattenedObject } from './get_flattened_object'; diff --git a/src/core/utils/map_to_object.ts b/packages/kbn-std/src/map_to_object.ts similarity index 100% rename from src/core/utils/map_to_object.ts rename to packages/kbn-std/src/map_to_object.ts diff --git a/src/core/utils/map_utils.test.ts b/packages/kbn-std/src/map_utils.test.ts similarity index 100% rename from src/core/utils/map_utils.test.ts rename to packages/kbn-std/src/map_utils.test.ts diff --git a/src/core/utils/map_utils.ts b/packages/kbn-std/src/map_utils.ts similarity index 100% rename from src/core/utils/map_utils.ts rename to packages/kbn-std/src/map_utils.ts diff --git a/src/core/utils/merge.test.ts b/packages/kbn-std/src/merge.test.ts similarity index 100% rename from src/core/utils/merge.test.ts rename to packages/kbn-std/src/merge.test.ts diff --git a/src/core/utils/merge.ts b/packages/kbn-std/src/merge.ts similarity index 98% rename from src/core/utils/merge.ts rename to packages/kbn-std/src/merge.ts index 43878c27b1e19..c0de50544a34e 100644 --- a/src/core/utils/merge.ts +++ b/packages/kbn-std/src/merge.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { isPlainObject } from 'lodash'; +import isPlainObject from 'lodash/isPlainObject'; /** * Deeply merges two objects, omitting undefined values, and not deeply merging Arrays. * diff --git a/src/core/utils/pick.ts b/packages/kbn-std/src/pick.ts similarity index 100% rename from src/core/utils/pick.ts rename to packages/kbn-std/src/pick.ts diff --git a/src/core/utils/promise.test.ts b/packages/kbn-std/src/promise.test.ts similarity index 100% rename from src/core/utils/promise.test.ts rename to packages/kbn-std/src/promise.test.ts diff --git a/src/core/utils/promise.ts b/packages/kbn-std/src/promise.ts similarity index 100% rename from src/core/utils/promise.ts rename to packages/kbn-std/src/promise.ts diff --git a/src/core/utils/unset.test.ts b/packages/kbn-std/src/unset.test.ts similarity index 100% rename from src/core/utils/unset.test.ts rename to packages/kbn-std/src/unset.test.ts diff --git a/src/core/utils/unset.ts b/packages/kbn-std/src/unset.ts similarity index 100% rename from src/core/utils/unset.ts rename to packages/kbn-std/src/unset.ts diff --git a/src/core/utils/url.test.ts b/packages/kbn-std/src/url.test.ts similarity index 100% rename from src/core/utils/url.test.ts rename to packages/kbn-std/src/url.test.ts diff --git a/src/core/utils/url.ts b/packages/kbn-std/src/url.ts similarity index 100% rename from src/core/utils/url.ts rename to packages/kbn-std/src/url.ts diff --git a/packages/kbn-std/tsconfig.json b/packages/kbn-std/tsconfig.json new file mode 100644 index 0000000000000..5c86ad17a90e9 --- /dev/null +++ b/packages/kbn-std/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "declarationDir": "./target", + "outDir": "./target", + "stripInternal": true, + "declarationMap": true, + "types": ["jest", "node"] + }, + "include": [ + "./src/**/*.ts", + "../../typings/query_string.d.ts" + ], + "exclude": ["target"] +} diff --git a/src/core/public/application/capabilities/capabilities_service.mock.ts b/src/core/public/application/capabilities/capabilities_service.mock.ts index 54aaa31e08859..cf259ed46025c 100644 --- a/src/core/public/application/capabilities/capabilities_service.mock.ts +++ b/src/core/public/application/capabilities/capabilities_service.mock.ts @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ +import { deepFreeze } from '@kbn/std'; import { CapabilitiesService, CapabilitiesStart } from './capabilities_service'; -import { deepFreeze } from '../../../utils'; const createStartContractMock = (): jest.Mocked => ({ capabilities: deepFreeze({ diff --git a/src/core/public/application/capabilities/capabilities_service.tsx b/src/core/public/application/capabilities/capabilities_service.tsx index 7304a8e5a66bc..1164164aec4c5 100644 --- a/src/core/public/application/capabilities/capabilities_service.tsx +++ b/src/core/public/application/capabilities/capabilities_service.tsx @@ -17,9 +17,9 @@ * under the License. */ import { RecursiveReadonly } from '@kbn/utility-types'; +import { deepFreeze } from '@kbn/std'; import { Capabilities } from '../../../types/capabilities'; -import { deepFreeze } from '../../../utils'; import { HttpStart } from '../../http'; interface StartDeps { diff --git a/src/core/public/chrome/nav_links/nav_link.ts b/src/core/public/chrome/nav_links/nav_link.ts index 4b82e0ced4505..80f0265819c40 100644 --- a/src/core/public/chrome/nav_links/nav_link.ts +++ b/src/core/public/chrome/nav_links/nav_link.ts @@ -17,7 +17,7 @@ * under the License. */ -import { pick } from '../../../utils'; +import { pick } from '@kbn/std'; import { AppCategory } from '../../'; /** diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index 006d0036f7a12..a1d6f9c988b27 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -17,6 +17,7 @@ * under the License. */ +import { pick } from '@kbn/std'; import { CoreId } from '../server'; import { PackageInfo, EnvironmentMode } from '../server/types'; import { CoreSetup, CoreStart } from '.'; @@ -35,7 +36,6 @@ import { OverlayService } from './overlays'; import { PluginsService } from './plugins'; import { UiSettingsService } from './ui_settings'; import { ApplicationService } from './application'; -import { pick } from '../utils/'; import { DocLinksService } from './doc_links'; import { RenderingService } from './rendering'; import { SavedObjectsService } from './saved_objects'; diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index fae7a272c9635..47f58a3a9fcbf 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -17,8 +17,8 @@ * under the License. */ +import { deepFreeze } from '@kbn/std'; import { InjectedMetadataSetup } from '../injected_metadata'; -import { deepFreeze } from '../../utils'; interface StartDeps { injectedMetadata: InjectedMetadataSetup; diff --git a/src/core/public/http/base_path.ts b/src/core/public/http/base_path.ts index ac85d71c793fe..5d9eb51023b78 100644 --- a/src/core/public/http/base_path.ts +++ b/src/core/public/http/base_path.ts @@ -35,7 +35,7 @@ * under the License. */ -import { modifyUrl } from '../../utils'; +import { modifyUrl } from '@kbn/std'; export class BasePath { constructor( diff --git a/src/core/public/index.ts b/src/core/public/index.ts index a9774dafd2340..5c9884328c28c 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -68,7 +68,6 @@ import { UiSettingsState, IUiSettingsClient } from './ui_settings'; import { ApplicationSetup, Capabilities, ApplicationStart } from './application'; import { DocLinksStart } from './doc_links'; import { SavedObjectsStart } from './saved_objects'; -export { PackageInfo, EnvironmentMode } from '../server/types'; import { IContextContainer, IContextProvider, @@ -78,9 +77,8 @@ import { HandlerParameters, } from './context'; -export { CoreContext, CoreSystem } from './core_system'; +export { PackageInfo, EnvironmentMode } from '../server/types'; export { - DEFAULT_APP_CATEGORIES, getFlattenedObject, URLMeaningfulParts, modifyUrl, @@ -88,7 +86,9 @@ export { Freezable, deepFreeze, assertNever, -} from '../utils'; +} from '@kbn/std'; +export { CoreContext, CoreSystem } from './core_system'; +export { DEFAULT_APP_CATEGORIES } from '../utils'; export { AppCategory, UiSettingsParams, diff --git a/src/core/public/injected_metadata/injected_metadata_service.ts b/src/core/public/injected_metadata/injected_metadata_service.ts index 23630a5bcf228..5b51bc823d166 100644 --- a/src/core/public/injected_metadata/injected_metadata_service.ts +++ b/src/core/public/injected_metadata/injected_metadata_service.ts @@ -18,6 +18,7 @@ */ import { get } from 'lodash'; +import { deepFreeze } from '@kbn/std'; import { DiscoveredPlugin, PluginName } from '../../server'; import { EnvironmentMode, @@ -25,7 +26,6 @@ import { UiSettingsParams, UserProvidedValues, } from '../../server/types'; -import { deepFreeze } from '../../utils/'; import { AppCategory } from '../'; export interface InjectedPluginMetadata { diff --git a/src/core/public/plugins/plugins_service.ts b/src/core/public/plugins/plugins_service.ts index f9bc40ca52601..87219f4c0bdd3 100644 --- a/src/core/public/plugins/plugins_service.ts +++ b/src/core/public/plugins/plugins_service.ts @@ -17,6 +17,7 @@ * under the License. */ +import { withTimeout } from '@kbn/std'; import { PluginName, PluginOpaqueId } from '../../server'; import { CoreService } from '../../types'; import { CoreContext } from '../core_system'; @@ -28,7 +29,6 @@ import { } from './plugin_context'; import { InternalCoreSetup, InternalCoreStart } from '../core_system'; import { InjectedPluginMetadata } from '../injected_metadata'; -import { withTimeout } from '../../utils'; const Sec = 1000; /** @internal */ diff --git a/src/core/server/config/deprecation/deprecation_factory.ts b/src/core/server/config/deprecation/deprecation_factory.ts index cbc9984924c5d..0598347d2cffc 100644 --- a/src/core/server/config/deprecation/deprecation_factory.ts +++ b/src/core/server/config/deprecation/deprecation_factory.ts @@ -17,10 +17,10 @@ * under the License. */ -import { set } from '@elastic/safer-lodash-set'; import { get } from 'lodash'; +import { set } from '@elastic/safer-lodash-set'; +import { unset } from '@kbn/std'; import { ConfigDeprecation, ConfigDeprecationLogger, ConfigDeprecationFactory } from './types'; -import { unset } from '../../../utils'; const _rename = ( config: Record, diff --git a/src/core/server/config/object_to_config_adapter.ts b/src/core/server/config/object_to_config_adapter.ts index 50b31722dceeb..c4d6ac02ccf05 100644 --- a/src/core/server/config/object_to_config_adapter.ts +++ b/src/core/server/config/object_to_config_adapter.ts @@ -17,10 +17,10 @@ * under the License. */ -import { set } from '@elastic/safer-lodash-set'; import { cloneDeep, get, has } from 'lodash'; +import { set } from '@elastic/safer-lodash-set'; +import { getFlattenedObject } from '@kbn/std'; -import { getFlattenedObject } from '../../utils'; import { Config, ConfigPath } from './'; /** diff --git a/src/core/server/elasticsearch/elasticsearch_service.ts b/src/core/server/elasticsearch/elasticsearch_service.ts index 2cc065aaaaeb1..5d07840e8bda7 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.ts @@ -19,9 +19,9 @@ import { Observable, Subject } from 'rxjs'; import { first, map, shareReplay, takeUntil } from 'rxjs/operators'; +import { merge } from '@kbn/std'; import { CoreService } from '../../types'; -import { merge } from '../../utils'; import { CoreContext } from '../core_context'; import { Logger } from '../logging'; import { diff --git a/src/core/server/elasticsearch/legacy/elasticsearch_client_config.ts b/src/core/server/elasticsearch/legacy/elasticsearch_client_config.ts index 3dbc1c2c647a9..6896c0a2e301f 100644 --- a/src/core/server/elasticsearch/legacy/elasticsearch_client_config.ts +++ b/src/core/server/elasticsearch/legacy/elasticsearch_client_config.ts @@ -22,7 +22,7 @@ import { cloneDeep } from 'lodash'; import { Duration } from 'moment'; import { checkServerIdentity } from 'tls'; import url from 'url'; -import { pick } from '../../../utils'; +import { pick } from '@kbn/std'; import { Logger } from '../../logging'; import { ElasticsearchConfig } from '../elasticsearch_config'; diff --git a/src/core/server/http/base_path_service.ts b/src/core/server/http/base_path_service.ts index 093d73b2da3bf..059eb36f42dd5 100644 --- a/src/core/server/http/base_path_service.ts +++ b/src/core/server/http/base_path_service.ts @@ -16,9 +16,9 @@ * specific language governing permissions and limitations * under the License. */ -import { ensureRawRequest, KibanaRequest, LegacyRequest } from './router'; +import { modifyUrl } from '@kbn/std'; -import { modifyUrl } from '../../utils'; +import { ensureRawRequest, KibanaRequest, LegacyRequest } from './router'; /** * Access or manipulate the Kibana base path diff --git a/src/core/server/http/http_service.ts b/src/core/server/http/http_service.ts index c2fd653918171..82b141c8e50dd 100644 --- a/src/core/server/http/http_service.ts +++ b/src/core/server/http/http_service.ts @@ -20,9 +20,9 @@ import { Observable, Subscription, combineLatest } from 'rxjs'; import { first, map } from 'rxjs/operators'; import { Server } from 'hapi'; +import { pick } from '@kbn/std'; import { CoreService } from '../../types'; -import { pick } from '../../utils'; import { Logger, LoggerFactory } from '../logging'; import { ContextSetup } from '../context'; import { Env } from '../config'; diff --git a/src/core/server/http/router/headers.ts b/src/core/server/http/router/headers.ts index f27f5e937b2c0..498dd153a43dd 100644 --- a/src/core/server/http/router/headers.ts +++ b/src/core/server/http/router/headers.ts @@ -17,8 +17,7 @@ * under the License. */ import { IncomingHttpHeaders } from 'http'; - -import { pick } from '../../../utils'; +import { pick } from '@kbn/std'; /** * Creates a Union type of all known keys of a given interface. diff --git a/src/core/server/http/router/request.ts b/src/core/server/http/router/request.ts index 76f8761a7e998..e04f8585981b5 100644 --- a/src/core/server/http/router/request.ts +++ b/src/core/server/http/router/request.ts @@ -23,8 +23,8 @@ import { Request, RouteOptionsApp, ApplicationState } from 'hapi'; import { Observable, fromEvent, merge } from 'rxjs'; import { shareReplay, first, takeUntil } from 'rxjs/operators'; import { RecursiveReadonly } from '@kbn/utility-types'; +import { deepFreeze } from '@kbn/std'; -import { deepFreeze } from '../../../utils'; import { Headers } from './headers'; import { RouteMethod, RouteConfigOptions, validBodyOutput, isSafeMethod } from './route'; import { KibanaSocket, IKibanaSocket } from './socket'; diff --git a/src/core/server/index.ts b/src/core/server/index.ts index d127471348d9f..623200762d3c4 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -322,8 +322,8 @@ export { MetricsServiceSetup, } from './metrics'; +export { DEFAULT_APP_CATEGORIES } from '../utils'; export { - DEFAULT_APP_CATEGORIES, getFlattenedObject, URLMeaningfulParts, modifyUrl, @@ -331,7 +331,7 @@ export { Freezable, deepFreeze, assertNever, -} from '../utils'; +} from '@kbn/std'; export { SavedObject, diff --git a/src/core/server/legacy/config/get_unused_config_keys.ts b/src/core/server/legacy/config/get_unused_config_keys.ts index d10c574f04974..c15c3b270df05 100644 --- a/src/core/server/legacy/config/get_unused_config_keys.ts +++ b/src/core/server/legacy/config/get_unused_config_keys.ts @@ -18,8 +18,8 @@ */ import { difference } from 'lodash'; +import { getFlattenedObject } from '@kbn/std'; import { unset } from '../../../../legacy/utils'; -import { getFlattenedObject } from '../../../utils'; import { hasConfigPathIntersection } from '../../config'; import { LegacyPluginSpec, LegacyConfig, LegacyVars } from '../types'; diff --git a/src/core/server/logging/appenders/appenders.ts b/src/core/server/logging/appenders/appenders.ts index edfce4988275a..9c19ee2bd8be5 100644 --- a/src/core/server/logging/appenders/appenders.ts +++ b/src/core/server/logging/appenders/appenders.ts @@ -18,8 +18,8 @@ */ import { schema } from '@kbn/config-schema'; +import { assertNever } from '@kbn/std'; -import { assertNever } from '../../../utils'; import { LegacyAppender, LegacyAppenderConfig, diff --git a/src/core/server/logging/layouts/layouts.ts b/src/core/server/logging/layouts/layouts.ts index 124c007bae104..03e8adbee6311 100644 --- a/src/core/server/logging/layouts/layouts.ts +++ b/src/core/server/logging/layouts/layouts.ts @@ -18,8 +18,8 @@ */ import { schema } from '@kbn/config-schema'; +import { assertNever } from '@kbn/std'; -import { assertNever } from '../../../utils'; import { LogRecord } from '../log_record'; import { JsonLayout, JsonLayoutConfigType } from './json_layout'; import { PatternLayout, PatternLayoutConfigType } from './pattern_layout'; diff --git a/src/core/server/logging/log_level.ts b/src/core/server/logging/log_level.ts index 577239ddae8e5..165e56e632d6d 100644 --- a/src/core/server/logging/log_level.ts +++ b/src/core/server/logging/log_level.ts @@ -17,7 +17,7 @@ * under the License. */ -import { assertNever } from '../../utils'; +import { assertNever } from '@kbn/std'; /** * Possible log level string values. diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index af0b0e19b3227..55e63941523ee 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -19,6 +19,8 @@ import { map, shareReplay } from 'rxjs/operators'; import { combineLatest } from 'rxjs'; +import { pick, deepFreeze } from '@kbn/std'; + import { CoreContext } from '../core_context'; import { PluginWrapper } from './plugin'; import { PluginsServiceSetupDeps, PluginsServiceStartDeps } from './plugins_service'; @@ -34,7 +36,6 @@ import { ElasticsearchConfigType, config as elasticsearchConfig, } from '../elasticsearch/elasticsearch_config'; -import { pick, deepFreeze } from '../../utils'; import { CoreSetup, CoreStart } from '..'; export interface InstanceInfo { diff --git a/src/core/server/plugins/plugins_service.ts b/src/core/server/plugins/plugins_service.ts index 30cd47c9d44e1..e8fe42ee491ca 100644 --- a/src/core/server/plugins/plugins_service.ts +++ b/src/core/server/plugins/plugins_service.ts @@ -20,9 +20,10 @@ import Path from 'path'; import { Observable } from 'rxjs'; import { filter, first, map, mergeMap, tap, toArray } from 'rxjs/operators'; +import { pick } from '@kbn/std'; + import { CoreService } from '../../types'; import { CoreContext } from '../core_context'; - import { Logger } from '../logging'; import { discover, PluginDiscoveryError, PluginDiscoveryErrorType } from './discovery'; import { PluginWrapper } from './plugin'; @@ -31,7 +32,6 @@ import { PluginsConfig, PluginsConfigType } from './plugins_config'; import { PluginsSystem } from './plugins_system'; import { InternalCoreSetup, InternalCoreStart } from '../internal_types'; import { IConfigService } from '../config'; -import { pick } from '../../utils'; import { InternalEnvironmentServiceSetup } from '../environment'; /** @internal */ diff --git a/src/core/server/plugins/plugins_system.ts b/src/core/server/plugins/plugins_system.ts index b2acd9a6fd04b..72d2cfe158b37 100644 --- a/src/core/server/plugins/plugins_system.ts +++ b/src/core/server/plugins/plugins_system.ts @@ -17,13 +17,13 @@ * under the License. */ +import { withTimeout } from '@kbn/std'; import { CoreContext } from '../core_context'; import { Logger } from '../logging'; import { PluginWrapper } from './plugin'; import { DiscoveredPlugin, PluginName } from './types'; import { createPluginSetupContext, createPluginStartContext } from './plugin_context'; import { PluginsServiceSetupDeps, PluginsServiceStartDeps } from './plugins_service'; -import { withTimeout } from '../../utils'; import { PluginDependencies } from '.'; const Sec = 1000; diff --git a/src/core/server/saved_objects/saved_objects_type_registry.ts b/src/core/server/saved_objects/saved_objects_type_registry.ts index d0035294226ea..bb840e459bf22 100644 --- a/src/core/server/saved_objects/saved_objects_type_registry.ts +++ b/src/core/server/saved_objects/saved_objects_type_registry.ts @@ -17,7 +17,7 @@ * under the License. */ -import { deepFreeze } from '../../utils'; +import { deepFreeze } from '@kbn/std'; import { SavedObjectsType } from './types'; /** diff --git a/src/core/server/server.ts b/src/core/server/server.ts index a02b0f51b559f..cc1f305caf95d 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -17,6 +17,7 @@ * under the License. */ +import { mapToObject } from '@kbn/std'; import { ConfigService, Env, RawConfigurationProvider, coreDeprecationProvider } from './config'; import { CoreApp } from './core_app'; import { AuditTrailService } from './audit_trail'; @@ -44,7 +45,6 @@ import { config as kibanaConfig } from './kibana_config'; import { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects'; import { config as uiSettingsConfig } from './ui_settings'; import { config as statusConfig } from './status'; -import { mapToObject } from '../utils'; import { ContextService } from './context'; import { RequestHandlerContext } from '.'; import { InternalCoreSetup, InternalCoreStart, ServiceConfigDescriptor } from './internal_types'; diff --git a/src/core/server/status/types.ts b/src/core/server/status/types.ts index f884b80316fa8..9fa33a8c6d40c 100644 --- a/src/core/server/status/types.ts +++ b/src/core/server/status/types.ts @@ -18,7 +18,7 @@ */ import { Observable } from 'rxjs'; -import { deepFreeze } from '../../utils'; +import { deepFreeze } from '@kbn/std'; import { PluginName } from '../plugins'; /** diff --git a/src/core/server/ui_settings/settings/navigation.ts b/src/core/server/ui_settings/settings/navigation.ts index 6483e86a1395a..ec825a2779f38 100644 --- a/src/core/server/ui_settings/settings/navigation.ts +++ b/src/core/server/ui_settings/settings/navigation.ts @@ -19,8 +19,8 @@ import { schema } from '@kbn/config-schema'; import { i18n } from '@kbn/i18n'; +import { isRelativeUrl } from '@kbn/std'; import { UiSettingsParams } from '../../../types'; -import { isRelativeUrl } from '../../../utils'; export const getNavigationSettings = (): Record => { return { diff --git a/src/core/server/ui_settings/ui_settings_service.ts b/src/core/server/ui_settings/ui_settings_service.ts index 8598cf7a62287..25062490f5b6b 100644 --- a/src/core/server/ui_settings/ui_settings_service.ts +++ b/src/core/server/ui_settings/ui_settings_service.ts @@ -19,10 +19,11 @@ import { Observable } from 'rxjs'; import { first } from 'rxjs/operators'; +import { mapToObject } from '@kbn/std'; + import { CoreService } from '../../types'; import { CoreContext } from '../core_context'; import { Logger } from '../logging'; - import { SavedObjectsClientContract } from '../saved_objects/types'; import { InternalSavedObjectsServiceSetup } from '../saved_objects'; import { InternalHttpServiceSetup } from '../http'; @@ -33,7 +34,6 @@ import { InternalUiSettingsServiceStart, UiSettingsParams, } from './types'; -import { mapToObject } from '../../utils/'; import { uiSettingsType } from './saved_objects'; import { registerRoutes } from './routes'; import { getCoreSettings } from './settings'; diff --git a/src/core/utils/context.ts b/src/core/utils/context.ts index 941bbceb0cd92..f28d3330b8e36 100644 --- a/src/core/utils/context.ts +++ b/src/core/utils/context.ts @@ -19,8 +19,8 @@ import { flatten } from 'lodash'; import { ShallowPromise } from '@kbn/utility-types'; -import { pick } from '.'; -import { CoreId, PluginOpaqueId } from '../server'; +import { pick } from '@kbn/std'; +import type { CoreId, PluginOpaqueId } from '../server'; /** * Make all properties in T optional, except for the properties whose keys are in the union K diff --git a/src/core/utils/index.ts b/src/core/utils/index.ts index a6df0992f6cc6..c620e4e5ee155 100644 --- a/src/core/utils/index.ts +++ b/src/core/utils/index.ts @@ -17,15 +17,12 @@ * under the License. */ -export * from './assert_never'; -export * from './context'; -export * from './deep_freeze'; -export * from './get'; -export * from './map_to_object'; -export * from './merge'; -export * from './pick'; -export * from './promise'; -export * from './url'; -export * from './unset'; -export * from './get_flattened_object'; -export * from './default_app_categories'; +export { + ContextContainer, + HandlerContextType, + HandlerFunction, + HandlerParameters, + IContextContainer, + IContextProvider, +} from './context'; +export { DEFAULT_APP_CATEGORIES } from './default_app_categories'; From 793a25133d81ed9b471d584babd70addaad307f0 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Mon, 14 Sep 2020 14:13:42 +0200 Subject: [PATCH 2/7] update README --- packages/kbn-std/README.md | 556 +------------------------------------ 1 file changed, 2 insertions(+), 554 deletions(-) diff --git a/packages/kbn-std/README.md b/packages/kbn-std/README.md index a4f2c1f6458cf..dfd98287ada4b 100644 --- a/packages/kbn-std/README.md +++ b/packages/kbn-std/README.md @@ -1,555 +1,3 @@ -# `@kbn/config-schema` — The Kibana config validation library +# `@kbn/std` — Kibana standard library -`@kbn/config-schema` is a TypeScript library inspired by Joi and designed to allow run-time validation of the -Kibana configuration entries providing developers with a fully typed model of the validated data. - -## Table of Contents - -- [Why `@kbn/config-schema`?](#why-kbnconfig-schema) -- [Schema building blocks](#schema-building-blocks) - - [Basic types](#basic-types) - - [`schema.string()`](#schemastring) - - [`schema.number()`](#schemanumber) - - [`schema.boolean()`](#schemaboolean) - - [`schema.literal()`](#schemaliteral) - - [`schema.buffer()`](#schemabuffer) - - [`schema.stream()`](#schemastream) - - [Composite types](#composite-types) - - [`schema.arrayOf()`](#schemaarrayof) - - [`schema.object()`](#schemaobject) - - [`schema.recordOf()`](#schemarecordof) - - [`schema.mapOf()`](#schemamapof) - - [Advanced types](#advanced-types) - - [`schema.oneOf()`](#schemaoneof) - - [`schema.any()`](#schemaany) - - [`schema.maybe()`](#schemamaybe) - - [`schema.nullable()`](#schemanullable) - - [`schema.never()`](#schemanever) - - [`schema.uri()`](#schemauri) - - [`schema.byteSize()`](#schemabytesize) - - [`schema.duration()`](#schemaduration) - - [`schema.conditional()`](#schemaconditional) - - [References](#references) - - [`schema.contextRef()`](#schemacontextref) - - [`schema.siblingRef()`](#schemasiblingref) -- [Custom validation](#custom-validation) -- [Default values](#default-values) - -## Why `@kbn/config-schema`? - -Validation of externally supplied data is very important for Kibana. Especially if this data is used to configure how it operates. - -There are a number of reasons why we decided to roll our own solution for the configuration validation: - -* **Limited API surface** - having a future rich library is awesome, but it's a really hard task to audit such library and make sure everything is sane and secure enough. As everyone knows complexity is the enemy of security and hence we'd like to have a full control over what exactly we expose and commit to maintain. -* **Custom error messages** - detailed validation error messages are a great help to developers, but at the same time they can contain information that's way too sensitive to expose to everyone. We'd like to control these messages and make them only as detailed as really needed. For example, we don't want validation error messages to contain the passwords for internal users to show-up in the logs. These logs are commonly ingested into Elasticsearch, and accessible to a large number of users which shouldn't have access to the internal user's password. -* **Type information** - having run-time guarantees is great, but additionally having compile-time guarantees is even better. We'd like to provide developers with a fully typed model of the validated data so that it's harder to misuse it _after_ validation. -* **Upgradability** - no matter how well a validation library is implemented, it will have bugs and may need to be improved at some point anyway. Some external libraries are very well supported, some aren't or won't be in the future. It's always a risk to depend on an external party with their own release cadence when you need to quickly fix a security vulnerability in a patch version. We'd like to have a better control over lifecycle of such an important piece of our codebase. - -## Schema building blocks - -The schema is composed of one or more primitives depending on the shape of the data you'd like to validate. - -```typescript -const simpleStringSchema = schema.string(); -const moreComplexObjectSchema = schema.object({ name: schema.string() }); -``` - -Every schema instance has a `validate` method that is used to perform a validation of the data according to the schema. This method accepts three arguments: - -* `data: any` - **required**, data to be validated with the schema -* `context: Record` - **optional**, object whose properties can be referenced by the [context references](#schemacontextref) -* `namespace: string` - **optional**, arbitrary string that is used to prefix every error message thrown during validation - -```typescript -const valueSchema = schema.object({ - isEnabled: schema.boolean(), - env: schema.string({ defaultValue: schema.contextRef('envName') }), -}); - -expect(valueSchema.validate({ isEnabled: true, env: 'prod' })).toEqual({ - isEnabled: true, - env: 'prod', -}); - -// Use default value for `env` from context via reference -expect(valueSchema.validate({ isEnabled: true }, { envName: 'staging' })).toEqual({ - isEnabled: true, - env: 'staging', -}); - -// Fail because of type mismatch -expect(() => - valueSchema.validate({ isEnabled: 'non-bool' }, { envName: 'staging' }) -).toThrowError( - '[isEnabled]: expected value of type [boolean] but got [string]' -); - -// Fail because of type mismatch and prefix error with a custom namespace -expect(() => - valueSchema.validate({ isEnabled: 'non-bool' }, { envName: 'staging' }, 'configuration') -).toThrowError( - '[configuration.isEnabled]: expected value of type [boolean] but got [string]' -); -``` - -__Notes:__ -* `validate` method throws as soon as the first schema violation is encountered, no further validation is performed. -* when you retrieve configuration within a Kibana plugin `validate` function is called by the Core automatically providing appropriate namespace and context variables (environment name, package info etc.). - -### Basic types - -#### `schema.string()` - -Validates input data as a string. - -__Output type:__ `string` - -__Options:__ - * `defaultValue: string | Reference | (() => string)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: string) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - * `minLength: number` - defines a minimum length the string should have. - * `maxLength: number` - defines a maximum length the string should have. - * `hostname: boolean` - indicates whether the string should be validated as a valid hostname (per [RFC 1123](https://tools.ietf.org/html/rfc1123)). - -__Usage:__ -```typescript -const valueSchema = schema.string({ maxLength: 10 }); -``` - -__Notes:__ -* By default `schema.string()` allows empty strings, to prevent that use non-zero value for `minLength` option. -* To validate a string using a regular expression use a custom validator function, see [Custom validation](#custom-validation) section for more details. - -#### `schema.number()` - -Validates input data as a number. - -__Output type:__ `number` - -__Options:__ - * `defaultValue: number | Reference | (() => number)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: number) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - * `min: number` - defines a minimum value the number should have. - * `max: number` - defines a maximum value the number should have. - -__Usage:__ -```typescript -const valueSchema = schema.number({ max: 10 }); -``` - -__Notes:__ -* The `schema.number()` also supports a string as input if it can be safely coerced into number. - -#### `schema.boolean()` - -Validates input data as a boolean. - -__Output type:__ `boolean` - -__Options:__ - * `defaultValue: boolean | Reference | (() => boolean)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: boolean) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = schema.boolean({ defaultValue: false }); -``` - -__Notes:__ -* The `schema.boolean()` also supports a string as input if it equals `'true'` or `'false'` (case-insensitive). - -#### `schema.literal()` - -Validates input data as a [string](https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types), [numeric](https://www.typescriptlang.org/docs/handbook/advanced-types.html#numeric-literal-types) or boolean literal. - -__Output type:__ `string`, `number` or `boolean` literals - -__Options:__ - * `defaultValue: TLiteral | Reference | (() => TLiteral)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: TLiteral) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = [ - schema.literal('stringLiteral'), - schema.literal(100500), - schema.literal(false), -]; -``` - -#### `schema.buffer()` - -Validates input data as a NodeJS `Buffer`. - -__Output type:__ `Buffer` - -__Options:__ - * `defaultValue: TBuffer | Reference | (() => TBuffer)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: TBuffer) => Buffer | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = schema.buffer({ defaultValue: Buffer.from('Hi, there!') }); -``` - -#### `schema.stream()` - -Validates input data as a NodeJS `stream`. - -__Output type:__ `Stream`, `Readable` or `Writtable` - -__Options:__ - * `defaultValue: TStream | Reference | (() => TStream)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: TStream) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = schema.stream({ defaultValue: new Stream() }); -``` - -### Composite types - -#### `schema.arrayOf()` - -Validates input data as a homogeneous array with the values being validated against predefined schema. - -__Output type:__ `TValue[]` - -__Options:__ - * `defaultValue: TValue[] | Reference | (() => TValue[])` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: TValue[]) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - * `minSize: number` - defines a minimum size the array should have. - * `maxSize: number` - defines a maximum size the array should have. - -__Usage:__ -```typescript -const valueSchema = schema.arrayOf(schema.number()); -``` - -__Notes:__ -* The `schema.arrayOf()` also supports a json string as input if it can be safely parsed using `JSON.parse` and if the resulting value is an array. - -#### `schema.object()` - -Validates input data as an object with a predefined set of properties. - -__Output type:__ `{ [K in keyof TProps]: TypeOf } as TObject` - -__Options:__ - * `defaultValue: TObject | Reference | (() => TObject)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: TObject) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - * `unknowns: 'allow' | 'ignore' | 'forbid'` - indicates whether unknown object properties should be allowed, ignored, or forbidden. It's `forbid` by default. - -__Usage:__ -```typescript -const valueSchema = schema.object({ - isEnabled: schema.boolean({ defaultValue: false }), - name: schema.string({ minLength: 10 }), -}); -``` - -__Notes:__ -* Using `unknowns: 'allow'` is discouraged and should only be used in exceptional circumstances. Consider using `schema.recordOf()` instead. -* Currently `schema.object()` always has a default value of `{}`, but this may change in the near future. Try to not rely on this behaviour and specify default value explicitly or use `schema.maybe()` if the value is optional. -* `schema.object()` also supports a json string as input if it can be safely parsed using `JSON.parse` and if the resulting value is a plain object. - -#### `schema.recordOf()` - -Validates input data as an object with the keys and values being validated against predefined schema. - -__Output type:__ `Record` - -__Options:__ - * `defaultValue: Record | Reference> | (() => Record)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: Record) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = schema.recordOf(schema.string(), schema.number()); -``` - -__Notes:__ -* You can use a union of literal types as a record's key schema to restrict record to a specific set of keys, e.g. `schema.oneOf([schema.literal('isEnabled'), schema.literal('name')])`. -* `schema.recordOf()` also supports a json string as input if it can be safely parsed using `JSON.parse` and if the resulting value is a plain object. - -#### `schema.mapOf()` - -Validates input data as a map with the keys and values being validated against the predefined schema. - -__Output type:__ `Map` - -__Options:__ - * `defaultValue: Map | Reference> | (() => Map)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: Map) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = schema.mapOf(schema.string(), schema.number()); -``` - -__Notes:__ -* You can use a union of literal types as a record's key schema to restrict record to a specific set of keys, e.g. `schema.oneOf([schema.literal('isEnabled'), schema.literal('name')])`. -* `schema.mapOf()` also supports a json string as input if it can be safely parsed using `JSON.parse` and if the resulting value is a plain object. - -### Advanced types - -#### `schema.oneOf()` - -Allows a list of alternative schemas to validate input data against. - -__Output type:__ `TValue1 | TValue2 | TValue3 | ..... as TUnion` - -__Options:__ - * `defaultValue: TUnion | Reference | (() => TUnion)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: TUnion) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = schema.oneOf([schema.literal('∞'), schema.number()]); -``` - -__Notes:__ -* Since the result data type is a type union you should use various TypeScript type guards to get the exact type. - -#### `schema.any()` - -Indicates that input data shouldn't be validated and returned as is. - -__Output type:__ `any` - -__Options:__ - * `defaultValue: any | Reference | (() => any)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: any) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = schema.any(); -``` - -__Notes:__ -* `schema.any()` is essentially an escape hatch for the case when your data can __really__ have any type and should be avoided at all costs. - -#### `schema.maybe()` - -Indicates that input data is optional and may not be present. - -__Output type:__ `T | undefined` - -__Usage:__ -```typescript -const valueSchema = schema.maybe(schema.string()); -``` - -__Notes:__ -* Don't use `schema.maybe()` if a nested type defines a default value. - -#### `schema.nullable()` - -Indicates that input data is optional and defaults to `null` if it's not present. - -__Output type:__ `T | null` - -__Usage:__ -```typescript -const valueSchema = schema.nullable(schema.string()); -``` - -__Notes:__ -* `schema.nullable()` also treats explicitly specified `null` as a valid input. - -#### `schema.never()` - -Indicates that input data is forbidden. - -__Output type:__ `never` - -__Usage:__ -```typescript -const valueSchema = schema.never(); -``` - -__Notes:__ -* `schema.never()` has a very limited application and usually used within [conditional schemas](#schemaconditional) to fully or partially forbid input data. - -#### `schema.uri()` - -Validates input data as a proper URI string (per [RFC 3986](https://tools.ietf.org/html/rfc3986)). - -__Output type:__ `string` - -__Options:__ - * `defaultValue: string | Reference | (() => string)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: string) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - * `scheme: string | string[]` - limits allowed URI schemes to the one(s) defined here. - -__Usage:__ -```typescript -const valueSchema = schema.uri({ scheme: 'https' }); -``` - -__Notes:__ -* Prefer using `schema.uri()` for all URI validations even though it may be possible to replicate it with a custom validator for `schema.string()`. - -#### `schema.byteSize()` - -Validates input data as a proper digital data size. - -__Output type:__ `ByteSizeValue` - -__Options:__ - * `defaultValue: ByteSizeValue | string | number | Reference | (() => ByteSizeValue | string | number)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: ByteSizeValue | string | number) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - * `min: ByteSizeValue | string | number` - defines a minimum value the size should have. - * `max: ByteSizeValue | string | number` - defines a maximum value the size should have. - -__Usage:__ -```typescript -const valueSchema = schema.byteSize({ min: '3kb' }); -``` - -__Notes:__ -* The string value for `schema.byteSize()` and its options supports the following optional suffixes: `b`, `kb`, `mb`, `gb` and `tb`. The default suffix is `b`. -* The number value is treated as a number of bytes and hence should be a positive integer, e.g. `100` is equal to `'100b'`. -* Currently you cannot specify zero bytes with a string format and should use number `0` instead. - -#### `schema.duration()` - -Validates input data as a proper [duration](https://momentjs.com/docs/#/durations/). - -__Output type:__ `moment.Duration` - -__Options:__ - * `defaultValue: moment.Duration | string | number | Reference | (() => moment.Duration | string | number)` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: moment.Duration | string | number) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = schema.duration({ defaultValue: '70ms' }); -``` - -__Notes:__ -* The string value for `schema.duration()` supports the following optional suffixes: `ms`, `s`, `m`, `h`, `d`, `w`, `M` and `Y`. The default suffix is `ms`. -* The number value is treated as a number of milliseconds and hence should be a positive integer, e.g. `100` is equal to `'100ms'`. - -#### `schema.conditional()` - -Allows a specified condition that is evaluated _at the validation time_ and results in either one or another input validation schema. - -The first argument is always a [reference](#references) while the second one can be: -* another reference, in this cases both references are "dereferenced" and compared -* schema, in this case the schema is used to validate "dereferenced" value of the first reference -* value, in this case "dereferenced" value of the first reference is compared to that value - -The third argument is a schema that should be used if the result of the aforementioned comparison evaluates to `true`, otherwise `schema.conditional()` should fallback -to the schema provided as the fourth argument. - -__Output type:__ `TTrueResult | TFalseResult` - -__Options:__ - * `defaultValue: TTrueResult | TFalseResult | Reference | (() => TTrueResult | TFalseResult` - defines a default value, see [Default values](#default-values) section for more details. - * `validate: (value: TTrueResult | TFalseResult) => string | void` - defines a custom validator function, see [Custom validation](#custom-validation) section for more details. - -__Usage:__ -```typescript -const valueSchema = schema.object({ - key: schema.oneOf([schema.literal('number'), schema.literal('string')]), - value: schema.conditional(schema.siblingRef('key'), 'number', schema.number(), schema.string()), -}); -``` - -__Notes:__ -* Conditional schemas may be hard to read and understand and hence should be used only sparingly. - -### References - -#### `schema.contextRef()` - -Defines a reference to the value specified through the validation context. Context reference is only used as part of a [conditional schema](#schemaconditional) or as a default value for any other schema. - -__Output type:__ `TReferenceValue` - -__Usage:__ -```typescript -const valueSchema = schema.object({ - env: schema.string({ defaultValue: schema.contextRef('envName') }), -}); -valueSchema.validate({}, { envName: 'dev' }); -``` - -__Notes:__ -* The `@kbn/config-schema` neither validates nor coerces the "dereferenced" value and the developer is responsible for making sure that it has the appropriate type. -* The root context that Kibana provides during config validation includes lots of useful properties like `environment name` that can be used to provide a strict schema for production and more relaxed one for development. - -#### `schema.siblingRef()` - -Defines a reference to the value of the sibling key. Sibling references are only used a part of [conditional schema](#schemaconditional) or as a default value for any other schema. - -__Output type:__ `TReferenceValue` - -__Usage:__ -```typescript -const valueSchema = schema.object({ - node: schema.object({ tag: schema.string() }), - env: schema.string({ defaultValue: schema.siblingRef('node.tag') }), -}); -``` - -__Notes:__ -* The `@kbn/config-schema` neither validates nor coerces the "dereferenced" value and the developer is responsible for making sure that it has the appropriate type. - -## Custom validation - -Using built-in schema primitives may not be enough in some scenarios or sometimes the attempt to model complex schemas with built-in primitives only may result in unreadable code. -For these cases `@kbn/config-schema` provides a way to specify a custom validation function for almost any schema building block through the `validate` option. - -For example `@kbn/config-schema` doesn't have a dedicated primitive for the `RegExp` based validation currently, but you can easily do that with a custom `validate` function: - -```typescript -const valueSchema = schema.string({ - minLength: 3, - validate(value) { - if (!/^[a-z0-9_-]+$/.test(value)) { - return `must be lower case, a-z, 0-9, '_', and '-' are allowed`; - } - }, -}); - -// ...or if you use that construct a lot... - -const regexSchema = (regex: RegExp) => schema.string({ - validate: value => regex.test(value) ? undefined : `must match "${regex.toString()}"`, -}); -const valueSchema = regexSchema(/^[a-z0-9_-]+$/); -``` - -Custom validation function is run _only after_ all built-in validations passed. It should either return a `string` as an error message -to denote the failed validation or not return anything at all (`void`) otherwise. Please also note that `validate` function is synchronous. - -Another use case for custom validation functions is when the schema depends on some run-time data: - -```typescript -const gesSchema = randomRunTimeSeed => schema.string({ - validate: value => value !== randomRunTimeSeed ? 'value is not allowed' : undefined -}); - -const schema = gesSchema('some-random-run-time-data'); -``` - -## Default values - -If you have an optional config field that you can have a default value for you may want to consider using dedicated `defaultValue` option to not -deal with "defined or undefined"-like checks all over the place in your code. You have three options to provide a default value for almost any schema primitive: - -* plain value that's known at the compile time -* [reference](#references) to a value that will be "dereferenced" at the validation time -* function that is invoked at the validation time and returns a plain value - -```typescript -const valueSchemaWithPlainValueDefault = schema.string({ defaultValue: 'n/a' }); -const valueSchemaWithReferencedValueDefault = schema.string({ defaultValue: schema.contextRef('env') }); -const valueSchemaWithFunctionEvaluatedDefault = schema.string({ defaultValue: () => Math.random().toString() }); -``` - -__Notes:__ -* `@kbn/config-schema` neither validates nor coerces default value and developer is responsible for making sure that it has the appropriate type. +This package is a set of utilities that can be used both on server-side and client-side. \ No newline at end of file From 9eaec5511ba5cbf141ecdd4d80674b32943a6dc1 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Mon, 14 Sep 2020 14:46:51 +0200 Subject: [PATCH 3/7] update codeowners and add yarn lock file --- .github/CODEOWNERS | 1 + packages/kbn-std/yarn.lock | 1 + 2 files changed, 2 insertions(+) create mode 120000 packages/kbn-std/yarn.lock diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bcb4774475849..51eb10514092b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -152,6 +152,7 @@ /x-pack/plugins/cloud/ @elastic/kibana-platform /x-pack/test/saved_objects_field_count/ @elastic/kibana-platform /packages/kbn-config-schema/ @elastic/kibana-platform +/packages/kbn-std/ @elastic/kibana-platform /src/legacy/server/config/ @elastic/kibana-platform /src/legacy/server/http/ @elastic/kibana-platform /src/legacy/server/logging/ @elastic/kibana-platform diff --git a/packages/kbn-std/yarn.lock b/packages/kbn-std/yarn.lock new file mode 120000 index 0000000000000..3f82ebc9cdbae --- /dev/null +++ b/packages/kbn-std/yarn.lock @@ -0,0 +1 @@ +../../yarn.lock \ No newline at end of file From 85aea41f9a5be9df7fcac0b758ad4e40cc07af47 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Mon, 14 Sep 2020 14:56:53 +0200 Subject: [PATCH 4/7] remove export from src/core/public and src/core/server and use package import instead --- src/core/public/index.ts | 9 --------- src/core/server/index.ts | 9 --------- .../ui/shard_failure_modal/shard_failure_description.tsx | 2 +- src/plugins/share/server/routes/goto.ts | 2 +- src/plugins/vis_type_timelion/server/plugin.ts | 2 +- test/functional/services/common/browser.ts | 2 +- x-pack/plugins/actions/server/lib/license_state.ts | 2 +- x-pack/plugins/alerts/server/lib/license_state.ts | 2 +- x-pack/plugins/features/server/plugin.ts | 2 +- .../graph/public/state_management/url_templates.ts | 2 +- .../public/applications/ingest_manager/services/index.ts | 2 +- .../security/server/authentication/providers/base.ts | 2 +- x-pack/plugins/security/server/plugin.ts | 2 +- x-pack/plugins/spaces/server/saved_objects/mappings.ts | 2 +- .../drilldowns/url_drilldown/url_drilldown_scope.ts | 2 +- 15 files changed, 13 insertions(+), 31 deletions(-) diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 5c9884328c28c..24d19e2d32074 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -78,15 +78,6 @@ import { } from './context'; export { PackageInfo, EnvironmentMode } from '../server/types'; -export { - getFlattenedObject, - URLMeaningfulParts, - modifyUrl, - isRelativeUrl, - Freezable, - deepFreeze, - assertNever, -} from '@kbn/std'; export { CoreContext, CoreSystem } from './core_system'; export { DEFAULT_APP_CATEGORIES } from '../utils'; export { diff --git a/src/core/server/index.ts b/src/core/server/index.ts index 623200762d3c4..01797d073ae2e 100644 --- a/src/core/server/index.ts +++ b/src/core/server/index.ts @@ -323,15 +323,6 @@ export { } from './metrics'; export { DEFAULT_APP_CATEGORIES } from '../utils'; -export { - getFlattenedObject, - URLMeaningfulParts, - modifyUrl, - isRelativeUrl, - Freezable, - deepFreeze, - assertNever, -} from '@kbn/std'; export { SavedObject, diff --git a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_description.tsx b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_description.tsx index 3606bfbaeb1f9..1f124291669ec 100644 --- a/src/plugins/data/public/ui/shard_failure_modal/shard_failure_description.tsx +++ b/src/plugins/data/public/ui/shard_failure_modal/shard_failure_description.tsx @@ -17,9 +17,9 @@ * under the License. */ import React from 'react'; +import { getFlattenedObject } from '@kbn/std'; import { EuiCodeBlock, EuiDescriptionList, EuiSpacer } from '@elastic/eui'; import { ShardFailure } from './shard_failure_types'; -import { getFlattenedObject } from '../../../../../core/public'; import { ShardFailureDescriptionHeader } from './shard_failure_description_header'; /** diff --git a/src/plugins/share/server/routes/goto.ts b/src/plugins/share/server/routes/goto.ts index 193f2acb87c95..0cd6d26adac26 100644 --- a/src/plugins/share/server/routes/goto.ts +++ b/src/plugins/share/server/routes/goto.ts @@ -19,11 +19,11 @@ import { CoreSetup, IRouter } from 'kibana/server'; import { schema } from '@kbn/config-schema'; +import { modifyUrl } from '@kbn/std'; import { shortUrlAssertValid } from './lib/short_url_assert_valid'; import { ShortUrlLookupService } from './lib/short_url_lookup'; import { getGotoPath } from '../../common/short_url_routes'; -import { modifyUrl } from '../../../../core/server'; export const createGotoRoute = ({ router, diff --git a/src/plugins/vis_type_timelion/server/plugin.ts b/src/plugins/vis_type_timelion/server/plugin.ts index 52c50b0646299..c518b73bb3cde 100644 --- a/src/plugins/vis_type_timelion/server/plugin.ts +++ b/src/plugins/vis_type_timelion/server/plugin.ts @@ -21,10 +21,10 @@ import { i18n } from '@kbn/i18n'; import { first } from 'rxjs/operators'; import { TypeOf, schema } from '@kbn/config-schema'; import { RecursiveReadonly } from '@kbn/utility-types'; +import { deepFreeze } from '@kbn/std'; import { PluginStart } from '../../../../src/plugins/data/server'; import { CoreSetup, PluginInitializerContext } from '../../../../src/core/server'; -import { deepFreeze } from '../../../../src/core/server'; import { configSchema } from '../config'; import loadFunctions from './lib/load_functions'; import { functionsRoute } from './routes/functions'; diff --git a/test/functional/services/common/browser.ts b/test/functional/services/common/browser.ts index e81845023a8fa..2f8e87c1d58d6 100644 --- a/test/functional/services/common/browser.ts +++ b/test/functional/services/common/browser.ts @@ -22,9 +22,9 @@ import { Key, Origin } from 'selenium-webdriver'; // @ts-ignore internal modules are not typed import { LegacyActionSequence } from 'selenium-webdriver/lib/actions'; import { ProvidedType } from '@kbn/test/types/ftr'; +import { modifyUrl } from '@kbn/std'; import Jimp from 'jimp'; -import { modifyUrl } from '../../../../src/core/utils'; import { WebElementWrapper } from '../lib/web_element_wrapper'; import { FtrProviderContext } from '../../ftr_provider_context'; import { Browsers } from '../remote/browsers'; diff --git a/x-pack/plugins/actions/server/lib/license_state.ts b/x-pack/plugins/actions/server/lib/license_state.ts index 914aada08bb2c..1686d0201e96c 100644 --- a/x-pack/plugins/actions/server/lib/license_state.ts +++ b/x-pack/plugins/actions/server/lib/license_state.ts @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; import { Observable, Subscription } from 'rxjs'; -import { assertNever } from '../../../../../src/core/server'; +import { assertNever } from '@kbn/std'; import { ILicense } from '../../../licensing/common/types'; import { PLUGIN } from '../constants/plugin'; import { ActionType } from '../types'; diff --git a/x-pack/plugins/alerts/server/lib/license_state.ts b/x-pack/plugins/alerts/server/lib/license_state.ts index ea0106f717b02..b3204d886960f 100644 --- a/x-pack/plugins/alerts/server/lib/license_state.ts +++ b/x-pack/plugins/alerts/server/lib/license_state.ts @@ -6,9 +6,9 @@ import Boom from 'boom'; import { i18n } from '@kbn/i18n'; +import { assertNever } from '@kbn/std'; import { Observable, Subscription } from 'rxjs'; import { ILicense } from '../../../licensing/common/types'; -import { assertNever } from '../../../../../src/core/server'; import { PLUGIN } from '../constants/plugin'; export interface AlertingLicenseInformation { diff --git a/x-pack/plugins/features/server/plugin.ts b/x-pack/plugins/features/server/plugin.ts index 61b66d95ca44f..29778a088f880 100644 --- a/x-pack/plugins/features/server/plugin.ts +++ b/x-pack/plugins/features/server/plugin.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { RecursiveReadonly } from '@kbn/utility-types'; +import { deepFreeze } from '@kbn/std'; import { CoreSetup, CoreStart, @@ -12,7 +13,6 @@ import { PluginInitializerContext, } from '../../../../src/core/server'; import { Capabilities as UICapabilities } from '../../../../src/core/server'; -import { deepFreeze } from '../../../../src/core/server'; import { PluginSetupContract as TimelionSetupContract } from '../../../../src/plugins/vis_type_timelion/server'; import { FeatureRegistry } from './feature_registry'; import { Feature, FeatureConfig } from '../common/feature'; diff --git a/x-pack/plugins/graph/public/state_management/url_templates.ts b/x-pack/plugins/graph/public/state_management/url_templates.ts index 19de52d444209..9149a27a4f986 100644 --- a/x-pack/plugins/graph/public/state_management/url_templates.ts +++ b/x-pack/plugins/graph/public/state_management/url_templates.ts @@ -7,6 +7,7 @@ import actionCreatorFactory from 'typescript-fsa'; import { reducerWithInitialState } from 'typescript-fsa-reducers/dist'; import { i18n } from '@kbn/i18n'; +import { modifyUrl } from '@kbn/std'; import rison from 'rison-node'; import { takeEvery, select } from 'redux-saga/effects'; import { format, parse } from 'url'; @@ -17,7 +18,6 @@ import { setDatasource, IndexpatternDatasource, requestDatasource } from './data import { outlinkEncoders } from '../helpers/outlink_encoders'; import { urlTemplatePlaceholder } from '../helpers/url_template'; import { matchesOne } from './helpers'; -import { modifyUrl } from '../../../../../src/core/public'; const actionCreator = actionCreatorFactory('x-pack/graph/urlTemplates'); diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts index 56179b02c5ba2..2c9e8b84d4069 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/services/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -export { getFlattenedObject } from '../../../../../../../src/core/public'; +export { getFlattenedObject } from '@kbn/std'; export { AgentStatusKueryHelper, diff --git a/x-pack/plugins/security/server/authentication/providers/base.ts b/x-pack/plugins/security/server/authentication/providers/base.ts index 631721b032752..7b2ad510db968 100644 --- a/x-pack/plugins/security/server/authentication/providers/base.ts +++ b/x-pack/plugins/security/server/authentication/providers/base.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { deepFreeze } from '@kbn/std'; import { KibanaRequest, Logger, @@ -11,7 +12,6 @@ import { ILegacyClusterClient, Headers, } from '../../../../../../src/core/server'; -import { deepFreeze } from '../../../../../../src/core/server'; import { AuthenticatedUser } from '../../../common/model'; import { AuthenticationResult } from '../authentication_result'; import { DeauthenticationResult } from '../deauthentication_result'; diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index 1eb406dd2061b..bd57a24033968 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -7,9 +7,9 @@ import { combineLatest } from 'rxjs'; import { first, map } from 'rxjs/operators'; import { TypeOf } from '@kbn/config-schema'; +import { deepFreeze } from '@kbn/std'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { - deepFreeze, CoreSetup, CoreStart, Logger, diff --git a/x-pack/plugins/spaces/server/saved_objects/mappings.ts b/x-pack/plugins/spaces/server/saved_objects/mappings.ts index 3afa7c389927c..875a164e25217 100644 --- a/x-pack/plugins/spaces/server/saved_objects/mappings.ts +++ b/x-pack/plugins/spaces/server/saved_objects/mappings.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { deepFreeze } from '../../../../../src/core/server'; +import { deepFreeze } from '@kbn/std'; export const SpacesSavedObjectMappings = deepFreeze({ properties: { diff --git a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_drilldown_scope.ts b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_drilldown_scope.ts index d499812a9d5ae..2c9237fac593f 100644 --- a/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_drilldown_scope.ts +++ b/x-pack/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_drilldown_scope.ts @@ -5,8 +5,8 @@ */ import partition from 'lodash/partition'; +import { getFlattenedObject } from '@kbn/std'; import { UrlDrilldownGlobalScope, UrlDrilldownScope } from './types'; -import { getFlattenedObject } from '../../../../../../src/core/public'; export function buildScope< ContextScope extends object = object, From 51f9e0688ac874858a07ec5f75ace826c8acef0f Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Mon, 14 Sep 2020 15:03:49 +0200 Subject: [PATCH 5/7] update generated doc --- .../kibana-plugin-core-public.assertnever.md | 24 ----------- .../kibana-plugin-core-public.deepfreeze.md | 24 ----------- .../kibana-plugin-core-public.freezable.md | 14 ------ ...a-plugin-core-public.getflattenedobject.md | 30 ------------- ...kibana-plugin-core-public.isrelativeurl.md | 24 ----------- .../core/public/kibana-plugin-core-public.md | 12 ------ .../kibana-plugin-core-public.modifyurl.md | 31 ------------- ...gin-core-public.urlmeaningfulparts.auth.md | 11 ----- ...gin-core-public.urlmeaningfulparts.hash.md | 11 ----- ...core-public.urlmeaningfulparts.hostname.md | 11 ----- ...a-plugin-core-public.urlmeaningfulparts.md | 27 ------------ ...core-public.urlmeaningfulparts.pathname.md | 11 ----- ...gin-core-public.urlmeaningfulparts.port.md | 11 ----- ...core-public.urlmeaningfulparts.protocol.md | 11 ----- ...in-core-public.urlmeaningfulparts.query.md | 11 ----- ...-core-public.urlmeaningfulparts.slashes.md | 11 ----- .../kibana-plugin-core-server.assertnever.md | 24 ----------- .../kibana-plugin-core-server.deepfreeze.md | 24 ----------- .../kibana-plugin-core-server.freezable.md | 14 ------ ...a-plugin-core-server.getflattenedobject.md | 30 ------------- ...kibana-plugin-core-server.isrelativeurl.md | 24 ----------- .../core/server/kibana-plugin-core-server.md | 7 --- .../kibana-plugin-core-server.modifyurl.md | 31 ------------- ...gin-core-server.urlmeaningfulparts.auth.md | 11 ----- ...gin-core-server.urlmeaningfulparts.hash.md | 11 ----- ...core-server.urlmeaningfulparts.hostname.md | 11 ----- ...a-plugin-core-server.urlmeaningfulparts.md | 27 ------------ ...core-server.urlmeaningfulparts.pathname.md | 11 ----- ...gin-core-server.urlmeaningfulparts.port.md | 11 ----- ...core-server.urlmeaningfulparts.protocol.md | 11 ----- ...in-core-server.urlmeaningfulparts.query.md | 11 ----- ...-core-server.urlmeaningfulparts.slashes.md | 11 ----- src/core/public/public.api.md | 43 ------------------- src/core/server/server.api.md | 43 ------------------- 34 files changed, 629 deletions(-) delete mode 100644 docs/development/core/public/kibana-plugin-core-public.assertnever.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.deepfreeze.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.freezable.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.getflattenedobject.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.isrelativeurl.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.modifyurl.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.auth.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.hash.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.hostname.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.pathname.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.port.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.protocol.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.query.md delete mode 100644 docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.slashes.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.assertnever.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.deepfreeze.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.freezable.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.getflattenedobject.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.isrelativeurl.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.modifyurl.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.auth.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.hash.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.hostname.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.pathname.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.port.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.protocol.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.query.md delete mode 100644 docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.slashes.md diff --git a/docs/development/core/public/kibana-plugin-core-public.assertnever.md b/docs/development/core/public/kibana-plugin-core-public.assertnever.md deleted file mode 100644 index 8fefd4450d49b..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.assertnever.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [assertNever](./kibana-plugin-core-public.assertnever.md) - -## assertNever() function - -Can be used in switch statements to ensure we perform exhaustive checks, see https://www.typescriptlang.org/docs/handbook/advanced-types.html\#exhaustiveness-checking - -Signature: - -```typescript -export declare function assertNever(x: never): never; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| x | never | | - -Returns: - -`never` - diff --git a/docs/development/core/public/kibana-plugin-core-public.deepfreeze.md b/docs/development/core/public/kibana-plugin-core-public.deepfreeze.md deleted file mode 100644 index 7c879b659a852..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.deepfreeze.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [deepFreeze](./kibana-plugin-core-public.deepfreeze.md) - -## deepFreeze() function - -Apply Object.freeze to a value recursively and convert the return type to Readonly variant recursively - -Signature: - -```typescript -export declare function deepFreeze(object: T): RecursiveReadonly; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| object | T | | - -Returns: - -`RecursiveReadonly` - diff --git a/docs/development/core/public/kibana-plugin-core-public.freezable.md b/docs/development/core/public/kibana-plugin-core-public.freezable.md deleted file mode 100644 index fee87dde25c28..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.freezable.md +++ /dev/null @@ -1,14 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [Freezable](./kibana-plugin-core-public.freezable.md) - -## Freezable type - - -Signature: - -```typescript -export declare type Freezable = { - [k: string]: any; -} | any[]; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.getflattenedobject.md b/docs/development/core/public/kibana-plugin-core-public.getflattenedobject.md deleted file mode 100644 index 3ef9b6bf703eb..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.getflattenedobject.md +++ /dev/null @@ -1,30 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [getFlattenedObject](./kibana-plugin-core-public.getflattenedobject.md) - -## getFlattenedObject() function - -Flattens a deeply nested object to a map of dot-separated paths pointing to all primitive values \*\*and arrays\*\* from `rootValue`. - -example: getFlattenedObject({ a: { b: 1, c: \[2,3\] } }) // => { 'a.b': 1, 'a.c': \[2,3\] } - -Signature: - -```typescript -export declare function getFlattenedObject(rootValue: Record): { - [key: string]: any; -}; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| rootValue | Record<string, any> | | - -Returns: - -`{ - [key: string]: any; -}` - diff --git a/docs/development/core/public/kibana-plugin-core-public.isrelativeurl.md b/docs/development/core/public/kibana-plugin-core-public.isrelativeurl.md deleted file mode 100644 index 3c2ffa6340a97..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.isrelativeurl.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [isRelativeUrl](./kibana-plugin-core-public.isrelativeurl.md) - -## isRelativeUrl() function - -Determine if a url is relative. Any url including a protocol, hostname, or port is not considered relative. This means that absolute \*paths\* are considered to be relative \*urls\* - -Signature: - -```typescript -export declare function isRelativeUrl(candidatePath: string): boolean; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| candidatePath | string | | - -Returns: - -`boolean` - diff --git a/docs/development/core/public/kibana-plugin-core-public.md b/docs/development/core/public/kibana-plugin-core-public.md index 08b12190ef638..f2bf72a597656 100644 --- a/docs/development/core/public/kibana-plugin-core-public.md +++ b/docs/development/core/public/kibana-plugin-core-public.md @@ -27,16 +27,6 @@ The plugin integrates with the core system via lifecycle events: `setup` | [AppNavLinkStatus](./kibana-plugin-core-public.appnavlinkstatus.md) | Status of the application's navLink. | | [AppStatus](./kibana-plugin-core-public.appstatus.md) | Accessibility status of an application. | -## Functions - -| Function | Description | -| --- | --- | -| [assertNever(x)](./kibana-plugin-core-public.assertnever.md) | Can be used in switch statements to ensure we perform exhaustive checks, see https://www.typescriptlang.org/docs/handbook/advanced-types.html\#exhaustiveness-checking | -| [deepFreeze(object)](./kibana-plugin-core-public.deepfreeze.md) | Apply Object.freeze to a value recursively and convert the return type to Readonly variant recursively | -| [getFlattenedObject(rootValue)](./kibana-plugin-core-public.getflattenedobject.md) | Flattens a deeply nested object to a map of dot-separated paths pointing to all primitive values \*\*and arrays\*\* from rootValue.example: getFlattenedObject({ a: { b: 1, c: \[2,3\] } }) // => { 'a.b': 1, 'a.c': \[2,3\] } | -| [isRelativeUrl(candidatePath)](./kibana-plugin-core-public.isrelativeurl.md) | Determine if a url is relative. Any url including a protocol, hostname, or port is not considered relative. This means that absolute \*paths\* are considered to be relative \*urls\* | -| [modifyUrl(url, urlModifier)](./kibana-plugin-core-public.modifyurl.md) | Takes a URL and a function that takes the meaningful parts of the URL as a key-value object, modifies some or all of the parts, and returns the modified parts formatted again as a url.Url Parts sent: - protocol - slashes (does the url have the //) - auth - hostname (just the name of the host, no port or auth information) - port - pathname (the path after the hostname, no query or hash, starts with a slash if there was a path) - query (always an object, even when no query on original url) - hashWhy? - The default url library in node produces several conflicting properties on the "parsed" output. Modifying any of these might lead to the modifications being ignored (depending on which property was modified) - It's not always clear whether to use path/pathname, host/hostname, so this tries to add helpful constraints | - ## Interfaces | Interface | Description | @@ -128,7 +118,6 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ToastOptions](./kibana-plugin-core-public.toastoptions.md) | Options available for [IToasts](./kibana-plugin-core-public.itoasts.md) APIs. | | [UiSettingsParams](./kibana-plugin-core-public.uisettingsparams.md) | UiSettings parameters defined by the plugins. | | [UiSettingsState](./kibana-plugin-core-public.uisettingsstate.md) | | -| [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) | We define our own typings because the current version of @types/node declares properties to be optional "hostname?: string". Although, parse call returns "hostname: null \| string". | | [UserProvidedValues](./kibana-plugin-core-public.userprovidedvalues.md) | Describes the values explicitly set by user. | ## Variables @@ -156,7 +145,6 @@ The plugin integrates with the core system via lifecycle events: `setup` | [ChromeHelpExtensionMenuLink](./kibana-plugin-core-public.chromehelpextensionmenulink.md) | | | [ChromeNavLinkUpdateableFields](./kibana-plugin-core-public.chromenavlinkupdateablefields.md) | | | [FatalErrorsStart](./kibana-plugin-core-public.fatalerrorsstart.md) | FatalErrors stop the Kibana Public Core and displays a fatal error screen with details about the Kibana build and the error. | -| [Freezable](./kibana-plugin-core-public.freezable.md) | | | [HandlerContextType](./kibana-plugin-core-public.handlercontexttype.md) | Extracts the type of the first argument of a [HandlerFunction](./kibana-plugin-core-public.handlerfunction.md) to represent the type of the context. | | [HandlerFunction](./kibana-plugin-core-public.handlerfunction.md) | A function that accepts a context object and an optional number of additional arguments. Used for the generic types in [IContextContainer](./kibana-plugin-core-public.icontextcontainer.md) | | [HandlerParameters](./kibana-plugin-core-public.handlerparameters.md) | Extracts the types of the additional arguments of a [HandlerFunction](./kibana-plugin-core-public.handlerfunction.md), excluding the [HandlerContextType](./kibana-plugin-core-public.handlercontexttype.md). | diff --git a/docs/development/core/public/kibana-plugin-core-public.modifyurl.md b/docs/development/core/public/kibana-plugin-core-public.modifyurl.md deleted file mode 100644 index b174f733a5c64..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.modifyurl.md +++ /dev/null @@ -1,31 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [modifyUrl](./kibana-plugin-core-public.modifyurl.md) - -## modifyUrl() function - -Takes a URL and a function that takes the meaningful parts of the URL as a key-value object, modifies some or all of the parts, and returns the modified parts formatted again as a url. - -Url Parts sent: - protocol - slashes (does the url have the //) - auth - hostname (just the name of the host, no port or auth information) - port - pathname (the path after the hostname, no query or hash, starts with a slash if there was a path) - query (always an object, even when no query on original url) - hash - -Why? - The default url library in node produces several conflicting properties on the "parsed" output. Modifying any of these might lead to the modifications being ignored (depending on which property was modified) - It's not always clear whether to use path/pathname, host/hostname, so this tries to add helpful constraints - -Signature: - -```typescript -export declare function modifyUrl(url: string, urlModifier: (urlParts: URLMeaningfulParts) => Partial | void): string; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| url | string | | -| urlModifier | (urlParts: URLMeaningfulParts) => Partial<URLMeaningfulParts> | void | | - -Returns: - -`string` - -The modified and reformatted url - diff --git a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.auth.md b/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.auth.md deleted file mode 100644 index 238dd66885896..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.auth.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) > [auth](./kibana-plugin-core-public.urlmeaningfulparts.auth.md) - -## URLMeaningfulParts.auth property - -Signature: - -```typescript -auth?: string | null; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.hash.md b/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.hash.md deleted file mode 100644 index 161e7dc7ebfae..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.hash.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) > [hash](./kibana-plugin-core-public.urlmeaningfulparts.hash.md) - -## URLMeaningfulParts.hash property - -Signature: - -```typescript -hash?: string | null; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.hostname.md b/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.hostname.md deleted file mode 100644 index f1884718337b5..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.hostname.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) > [hostname](./kibana-plugin-core-public.urlmeaningfulparts.hostname.md) - -## URLMeaningfulParts.hostname property - -Signature: - -```typescript -hostname?: string | null; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.md b/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.md deleted file mode 100644 index 2816d4c7df541..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.md +++ /dev/null @@ -1,27 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) - -## URLMeaningfulParts interface - -We define our own typings because the current version of @types/node declares properties to be optional "hostname?: string". Although, parse call returns "hostname: null \| string". - -Signature: - -```typescript -export interface URLMeaningfulParts -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [auth](./kibana-plugin-core-public.urlmeaningfulparts.auth.md) | string | null | | -| [hash](./kibana-plugin-core-public.urlmeaningfulparts.hash.md) | string | null | | -| [hostname](./kibana-plugin-core-public.urlmeaningfulparts.hostname.md) | string | null | | -| [pathname](./kibana-plugin-core-public.urlmeaningfulparts.pathname.md) | string | null | | -| [port](./kibana-plugin-core-public.urlmeaningfulparts.port.md) | string | null | | -| [protocol](./kibana-plugin-core-public.urlmeaningfulparts.protocol.md) | string | null | | -| [query](./kibana-plugin-core-public.urlmeaningfulparts.query.md) | ParsedQuery | | -| [slashes](./kibana-plugin-core-public.urlmeaningfulparts.slashes.md) | boolean | null | | - diff --git a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.pathname.md b/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.pathname.md deleted file mode 100644 index 5ad21f004481c..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.pathname.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) > [pathname](./kibana-plugin-core-public.urlmeaningfulparts.pathname.md) - -## URLMeaningfulParts.pathname property - -Signature: - -```typescript -pathname?: string | null; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.port.md b/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.port.md deleted file mode 100644 index 2e70da2f17421..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.port.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) > [port](./kibana-plugin-core-public.urlmeaningfulparts.port.md) - -## URLMeaningfulParts.port property - -Signature: - -```typescript -port?: string | null; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.protocol.md b/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.protocol.md deleted file mode 100644 index cedc7f0b878e3..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.protocol.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) > [protocol](./kibana-plugin-core-public.urlmeaningfulparts.protocol.md) - -## URLMeaningfulParts.protocol property - -Signature: - -```typescript -protocol?: string | null; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.query.md b/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.query.md deleted file mode 100644 index a9541efe0882a..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.query.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) > [query](./kibana-plugin-core-public.urlmeaningfulparts.query.md) - -## URLMeaningfulParts.query property - -Signature: - -```typescript -query: ParsedQuery; -``` diff --git a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.slashes.md b/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.slashes.md deleted file mode 100644 index cb28a25f9e162..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.urlmeaningfulparts.slashes.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [URLMeaningfulParts](./kibana-plugin-core-public.urlmeaningfulparts.md) > [slashes](./kibana-plugin-core-public.urlmeaningfulparts.slashes.md) - -## URLMeaningfulParts.slashes property - -Signature: - -```typescript -slashes?: boolean | null; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.assertnever.md b/docs/development/core/server/kibana-plugin-core-server.assertnever.md deleted file mode 100644 index c13c88df9b9bf..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.assertnever.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [assertNever](./kibana-plugin-core-server.assertnever.md) - -## assertNever() function - -Can be used in switch statements to ensure we perform exhaustive checks, see https://www.typescriptlang.org/docs/handbook/advanced-types.html\#exhaustiveness-checking - -Signature: - -```typescript -export declare function assertNever(x: never): never; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| x | never | | - -Returns: - -`never` - diff --git a/docs/development/core/server/kibana-plugin-core-server.deepfreeze.md b/docs/development/core/server/kibana-plugin-core-server.deepfreeze.md deleted file mode 100644 index 946050bff0585..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.deepfreeze.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [deepFreeze](./kibana-plugin-core-server.deepfreeze.md) - -## deepFreeze() function - -Apply Object.freeze to a value recursively and convert the return type to Readonly variant recursively - -Signature: - -```typescript -export declare function deepFreeze(object: T): RecursiveReadonly; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| object | T | | - -Returns: - -`RecursiveReadonly` - diff --git a/docs/development/core/server/kibana-plugin-core-server.freezable.md b/docs/development/core/server/kibana-plugin-core-server.freezable.md deleted file mode 100644 index 32ba89e8370c1..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.freezable.md +++ /dev/null @@ -1,14 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [Freezable](./kibana-plugin-core-server.freezable.md) - -## Freezable type - - -Signature: - -```typescript -export declare type Freezable = { - [k: string]: any; -} | any[]; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.getflattenedobject.md b/docs/development/core/server/kibana-plugin-core-server.getflattenedobject.md deleted file mode 100644 index 2e7850ca579f6..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.getflattenedobject.md +++ /dev/null @@ -1,30 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [getFlattenedObject](./kibana-plugin-core-server.getflattenedobject.md) - -## getFlattenedObject() function - -Flattens a deeply nested object to a map of dot-separated paths pointing to all primitive values \*\*and arrays\*\* from `rootValue`. - -example: getFlattenedObject({ a: { b: 1, c: \[2,3\] } }) // => { 'a.b': 1, 'a.c': \[2,3\] } - -Signature: - -```typescript -export declare function getFlattenedObject(rootValue: Record): { - [key: string]: any; -}; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| rootValue | Record<string, any> | | - -Returns: - -`{ - [key: string]: any; -}` - diff --git a/docs/development/core/server/kibana-plugin-core-server.isrelativeurl.md b/docs/development/core/server/kibana-plugin-core-server.isrelativeurl.md deleted file mode 100644 index bff9eb05419be..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.isrelativeurl.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [isRelativeUrl](./kibana-plugin-core-server.isrelativeurl.md) - -## isRelativeUrl() function - -Determine if a url is relative. Any url including a protocol, hostname, or port is not considered relative. This means that absolute \*paths\* are considered to be relative \*urls\* - -Signature: - -```typescript -export declare function isRelativeUrl(candidatePath: string): boolean; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| candidatePath | string | | - -Returns: - -`boolean` - diff --git a/docs/development/core/server/kibana-plugin-core-server.md b/docs/development/core/server/kibana-plugin-core-server.md index c16600d1d0492..30b98b9f0553e 100644 --- a/docs/development/core/server/kibana-plugin-core-server.md +++ b/docs/development/core/server/kibana-plugin-core-server.md @@ -42,13 +42,8 @@ The plugin integrates with the core system via lifecycle events: `setup` | Function | Description | | --- | --- | -| [assertNever(x)](./kibana-plugin-core-server.assertnever.md) | Can be used in switch statements to ensure we perform exhaustive checks, see https://www.typescriptlang.org/docs/handbook/advanced-types.html\#exhaustiveness-checking | -| [deepFreeze(object)](./kibana-plugin-core-server.deepfreeze.md) | Apply Object.freeze to a value recursively and convert the return type to Readonly variant recursively | | [exportSavedObjectsToStream({ types, objects, search, savedObjectsClient, exportSizeLimit, includeReferencesDeep, excludeExportDetails, namespace, })](./kibana-plugin-core-server.exportsavedobjectstostream.md) | Generates sorted saved object stream to be used for export. See the [options](./kibana-plugin-core-server.savedobjectsexportoptions.md) for more detailed information. | -| [getFlattenedObject(rootValue)](./kibana-plugin-core-server.getflattenedobject.md) | Flattens a deeply nested object to a map of dot-separated paths pointing to all primitive values \*\*and arrays\*\* from rootValue.example: getFlattenedObject({ a: { b: 1, c: \[2,3\] } }) // => { 'a.b': 1, 'a.c': \[2,3\] } | | [importSavedObjectsFromStream({ readStream, objectLimit, overwrite, createNewCopies, savedObjectsClient, typeRegistry, namespace, })](./kibana-plugin-core-server.importsavedobjectsfromstream.md) | Import saved objects from given stream. See the [options](./kibana-plugin-core-server.savedobjectsimportoptions.md) for more detailed information. | -| [isRelativeUrl(candidatePath)](./kibana-plugin-core-server.isrelativeurl.md) | Determine if a url is relative. Any url including a protocol, hostname, or port is not considered relative. This means that absolute \*paths\* are considered to be relative \*urls\* | -| [modifyUrl(url, urlModifier)](./kibana-plugin-core-server.modifyurl.md) | Takes a URL and a function that takes the meaningful parts of the URL as a key-value object, modifies some or all of the parts, and returns the modified parts formatted again as a url.Url Parts sent: - protocol - slashes (does the url have the //) - auth - hostname (just the name of the host, no port or auth information) - port - pathname (the path after the hostname, no query or hash, starts with a slash if there was a path) - query (always an object, even when no query on original url) - hashWhy? - The default url library in node produces several conflicting properties on the "parsed" output. Modifying any of these might lead to the modifications being ignored (depending on which property was modified) - It's not always clear whether to use path/pathname, host/hostname, so this tries to add helpful constraints | | [resolveSavedObjectsImportErrors({ readStream, objectLimit, retries, savedObjectsClient, typeRegistry, namespace, createNewCopies, })](./kibana-plugin-core-server.resolvesavedobjectsimporterrors.md) | Resolve and return saved object import errors. See the [options](./kibana-plugin-core-server.savedobjectsresolveimporterrorsoptions.md) for more detailed informations. | ## Interfaces @@ -217,7 +212,6 @@ The plugin integrates with the core system via lifecycle events: `setup` | [UiSettingsParams](./kibana-plugin-core-server.uisettingsparams.md) | UiSettings parameters defined by the plugins. | | [UiSettingsServiceSetup](./kibana-plugin-core-server.uisettingsservicesetup.md) | | | [UiSettingsServiceStart](./kibana-plugin-core-server.uisettingsservicestart.md) | | -| [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) | We define our own typings because the current version of @types/node declares properties to be optional "hostname?: string". Although, parse call returns "hostname: null \| string". | | [UserProvidedValues](./kibana-plugin-core-server.userprovidedvalues.md) | Describes the values explicitly set by user. | ## Variables @@ -246,7 +240,6 @@ The plugin integrates with the core system via lifecycle events: `setup` | [DestructiveRouteMethod](./kibana-plugin-core-server.destructiveroutemethod.md) | Set of HTTP methods changing the state of the server. | | [ElasticsearchClient](./kibana-plugin-core-server.elasticsearchclient.md) | Client used to query the elasticsearch cluster. | | [ElasticsearchClientConfig](./kibana-plugin-core-server.elasticsearchclientconfig.md) | Configuration options to be used to create a [cluster client](./kibana-plugin-core-server.iclusterclient.md) using the [createClient API](./kibana-plugin-core-server.elasticsearchservicestart.createclient.md) | -| [Freezable](./kibana-plugin-core-server.freezable.md) | | | [GetAuthHeaders](./kibana-plugin-core-server.getauthheaders.md) | Get headers to authenticate a user against Elasticsearch. | | [GetAuthState](./kibana-plugin-core-server.getauthstate.md) | Gets authentication state for a request. Returned by auth interceptor. | | [HandlerContextType](./kibana-plugin-core-server.handlercontexttype.md) | Extracts the type of the first argument of a [HandlerFunction](./kibana-plugin-core-server.handlerfunction.md) to represent the type of the context. | diff --git a/docs/development/core/server/kibana-plugin-core-server.modifyurl.md b/docs/development/core/server/kibana-plugin-core-server.modifyurl.md deleted file mode 100644 index fc0bc354a3ca3..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.modifyurl.md +++ /dev/null @@ -1,31 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [modifyUrl](./kibana-plugin-core-server.modifyurl.md) - -## modifyUrl() function - -Takes a URL and a function that takes the meaningful parts of the URL as a key-value object, modifies some or all of the parts, and returns the modified parts formatted again as a url. - -Url Parts sent: - protocol - slashes (does the url have the //) - auth - hostname (just the name of the host, no port or auth information) - port - pathname (the path after the hostname, no query or hash, starts with a slash if there was a path) - query (always an object, even when no query on original url) - hash - -Why? - The default url library in node produces several conflicting properties on the "parsed" output. Modifying any of these might lead to the modifications being ignored (depending on which property was modified) - It's not always clear whether to use path/pathname, host/hostname, so this tries to add helpful constraints - -Signature: - -```typescript -export declare function modifyUrl(url: string, urlModifier: (urlParts: URLMeaningfulParts) => Partial | void): string; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| url | string | | -| urlModifier | (urlParts: URLMeaningfulParts) => Partial<URLMeaningfulParts> | void | | - -Returns: - -`string` - -The modified and reformatted url - diff --git a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.auth.md b/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.auth.md deleted file mode 100644 index 0422738669a70..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.auth.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) > [auth](./kibana-plugin-core-server.urlmeaningfulparts.auth.md) - -## URLMeaningfulParts.auth property - -Signature: - -```typescript -auth?: string | null; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.hash.md b/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.hash.md deleted file mode 100644 index 13a3f4a9c95c8..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.hash.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) > [hash](./kibana-plugin-core-server.urlmeaningfulparts.hash.md) - -## URLMeaningfulParts.hash property - -Signature: - -```typescript -hash?: string | null; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.hostname.md b/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.hostname.md deleted file mode 100644 index 6631f6f6744c5..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.hostname.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) > [hostname](./kibana-plugin-core-server.urlmeaningfulparts.hostname.md) - -## URLMeaningfulParts.hostname property - -Signature: - -```typescript -hostname?: string | null; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.md b/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.md deleted file mode 100644 index 257f7b4b634ab..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.md +++ /dev/null @@ -1,27 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) - -## URLMeaningfulParts interface - -We define our own typings because the current version of @types/node declares properties to be optional "hostname?: string". Although, parse call returns "hostname: null \| string". - -Signature: - -```typescript -export interface URLMeaningfulParts -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [auth](./kibana-plugin-core-server.urlmeaningfulparts.auth.md) | string | null | | -| [hash](./kibana-plugin-core-server.urlmeaningfulparts.hash.md) | string | null | | -| [hostname](./kibana-plugin-core-server.urlmeaningfulparts.hostname.md) | string | null | | -| [pathname](./kibana-plugin-core-server.urlmeaningfulparts.pathname.md) | string | null | | -| [port](./kibana-plugin-core-server.urlmeaningfulparts.port.md) | string | null | | -| [protocol](./kibana-plugin-core-server.urlmeaningfulparts.protocol.md) | string | null | | -| [query](./kibana-plugin-core-server.urlmeaningfulparts.query.md) | ParsedQuery | | -| [slashes](./kibana-plugin-core-server.urlmeaningfulparts.slashes.md) | boolean | null | | - diff --git a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.pathname.md b/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.pathname.md deleted file mode 100644 index 8fee8c8e146ca..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.pathname.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) > [pathname](./kibana-plugin-core-server.urlmeaningfulparts.pathname.md) - -## URLMeaningfulParts.pathname property - -Signature: - -```typescript -pathname?: string | null; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.port.md b/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.port.md deleted file mode 100644 index dcf3517d92ba2..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.port.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) > [port](./kibana-plugin-core-server.urlmeaningfulparts.port.md) - -## URLMeaningfulParts.port property - -Signature: - -```typescript -port?: string | null; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.protocol.md b/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.protocol.md deleted file mode 100644 index 914dcd4e8a8a5..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.protocol.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) > [protocol](./kibana-plugin-core-server.urlmeaningfulparts.protocol.md) - -## URLMeaningfulParts.protocol property - -Signature: - -```typescript -protocol?: string | null; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.query.md b/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.query.md deleted file mode 100644 index 358adcfd3d180..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.query.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) > [query](./kibana-plugin-core-server.urlmeaningfulparts.query.md) - -## URLMeaningfulParts.query property - -Signature: - -```typescript -query: ParsedQuery; -``` diff --git a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.slashes.md b/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.slashes.md deleted file mode 100644 index d5b598167f2f2..0000000000000 --- a/docs/development/core/server/kibana-plugin-core-server.urlmeaningfulparts.slashes.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [URLMeaningfulParts](./kibana-plugin-core-server.urlmeaningfulparts.md) > [slashes](./kibana-plugin-core-server.urlmeaningfulparts.slashes.md) - -## URLMeaningfulParts.slashes property - -Signature: - -```typescript -slashes?: boolean | null; -``` diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index d90b8f780b674..50d0767ca893b 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -22,7 +22,6 @@ import { Location } from 'history'; import { LocationDescriptorObject } from 'history'; import { MaybePromise } from '@kbn/utility-types'; import { Observable } from 'rxjs'; -import { ParsedQuery } from 'query-string'; import { Path } from 'history'; import { PublicUiSettingsParams as PublicUiSettingsParams_2 } from 'src/core/server/types'; import React from 'react'; @@ -187,9 +186,6 @@ export type AppUpdatableFields = Pick Partial | undefined; -// @public -export function assertNever(x: never): never; - // @public export interface Capabilities { [key: string]: Record>; @@ -444,9 +440,6 @@ export class CoreSystem { stop(): void; } -// @public -export function deepFreeze(object: T): RecursiveReadonly; - // @internal (undocumented) export const DEFAULT_APP_CATEGORIES: Readonly<{ kibana: { @@ -616,16 +609,6 @@ export interface FatalErrorsSetup { // @public export type FatalErrorsStart = FatalErrorsSetup; -// @public (undocumented) -export type Freezable = { - [k: string]: any; -} | any[]; - -// @public -export function getFlattenedObject(rootValue: Record): { - [key: string]: any; -}; - // @public export type HandlerContextType> = T extends HandlerFunction ? U : never; @@ -837,9 +820,6 @@ export interface ImageValidation { }; } -// @public -export function isRelativeUrl(candidatePath: string): boolean; - // @public export type IToasts = Pick; @@ -868,9 +848,6 @@ export interface IUiSettingsClient { set: (key: string, value: any) => Promise; } -// @public -export function modifyUrl(url: string, urlModifier: (urlParts: URLMeaningfulParts) => Partial | void): string; - // @public export type MountPoint = (element: T) => UnmountCallback; @@ -1447,26 +1424,6 @@ export type UnmountCallback = () => void; // @public export const URL_MAX_LENGTH: number; -// @public -export interface URLMeaningfulParts { - // (undocumented) - auth?: string | null; - // (undocumented) - hash?: string | null; - // (undocumented) - hostname?: string | null; - // (undocumented) - pathname?: string | null; - // (undocumented) - port?: string | null; - // (undocumented) - protocol?: string | null; - // (undocumented) - query: ParsedQuery; - // (undocumented) - slashes?: boolean | null; -} - // @public export interface UserProvidedValues { // (undocumented) diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index ec457704e89c7..96239d8ada54f 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -106,7 +106,6 @@ import { NodesInfoParams } from 'elasticsearch'; import { NodesStatsParams } from 'elasticsearch'; import { ObjectType } from '@kbn/config-schema'; import { Observable } from 'rxjs'; -import { ParsedQuery } from 'query-string'; import { PeerCertificate } from 'tls'; import { PingParams } from 'elasticsearch'; import { PutScriptParams } from 'elasticsearch'; @@ -160,9 +159,6 @@ import { Url } from 'url'; // @public (undocumented) export type AppenderConfigType = ConsoleAppenderConfig | FileAppenderConfig | LegacyAppenderConfig; -// @public -export function assertNever(x: never): never; - // @public @deprecated (undocumented) export interface AssistanceAPIResponse { // (undocumented) @@ -504,9 +500,6 @@ export interface CustomHttpResponseOptions(object: T): RecursiveReadonly; - // @internal (undocumented) export const DEFAULT_APP_CATEGORIES: Readonly<{ kibana: { @@ -716,11 +709,6 @@ export interface FakeRequest { headers: Headers; } -// @public (undocumented) -export type Freezable = { - [k: string]: any; -} | any[]; - // @public export type GetAuthHeaders = (request: KibanaRequest | LegacyRequest) => AuthHeaders | undefined; @@ -730,11 +718,6 @@ export type GetAuthState = (request: KibanaRequest | LegacyRequest) state: T; }; -// @public -export function getFlattenedObject(rootValue: Record): { - [key: string]: any; -}; - // @public (undocumented) export interface GetResponse { // (undocumented) @@ -966,9 +949,6 @@ export interface IScopedClusterClient { readonly asInternalUser: ElasticsearchClient; } -// @public -export function isRelativeUrl(candidatePath: string): boolean; - // @public export interface IUiSettingsClient { get: (key: string) => Promise; @@ -1543,9 +1523,6 @@ export type MIGRATION_ASSISTANCE_INDEX_ACTION = 'upgrade' | 'reindex'; // @public @deprecated (undocumented) export type MIGRATION_DEPRECATION_LEVEL = 'none' | 'info' | 'warning' | 'critical'; -// @public -export function modifyUrl(url: string, urlModifier: (urlParts: URLMeaningfulParts) => Partial | void): string; - // @public export type MutatingOperationRefreshSetting = boolean | 'wait_for'; @@ -2848,26 +2825,6 @@ export interface UiSettingsServiceStart { // @public export type UiSettingsType = 'undefined' | 'json' | 'markdown' | 'number' | 'select' | 'boolean' | 'string' | 'array' | 'image'; -// @public -export interface URLMeaningfulParts { - // (undocumented) - auth?: string | null; - // (undocumented) - hash?: string | null; - // (undocumented) - hostname?: string | null; - // (undocumented) - pathname?: string | null; - // (undocumented) - port?: string | null; - // (undocumented) - protocol?: string | null; - // (undocumented) - query: ParsedQuery; - // (undocumented) - slashes?: boolean | null; -} - // @public export interface UserProvidedValues { // (undocumented) From 01e73e6a8e0be204b469e7cafa297d9fc9dd4865 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Mon, 14 Sep 2020 15:31:11 +0200 Subject: [PATCH 6/7] adapt forgotten import --- .../fixtures/api_consumer_plugin/server/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts index 87bed7f416019..33ceee68a6013 100644 --- a/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts +++ b/x-pack/test/encrypted_saved_objects_api_integration/fixtures/api_consumer_plugin/server/index.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ +import { deepFreeze } from '@kbn/std'; import { - deepFreeze, CoreSetup, PluginInitializer, SavedObjectsNamespaceType, From 4285681275cbc9eb49725c660d0d8c002c39ec53 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Mon, 14 Sep 2020 15:35:52 +0200 Subject: [PATCH 7/7] update `data` plugin doc --- .../kibana-plugin-plugins-data-public.querystringinput.md | 2 +- src/plugins/data/public/public.api.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md index cf171d9ee9f37..e85747b8cc3d7 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.querystringinput.md @@ -7,5 +7,5 @@ Signature: ```typescript -QueryStringInput: React.FC> +QueryStringInput: React.FC> ``` diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index fa5d3cd85f430..1f5edb1f1cc75 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -1685,7 +1685,7 @@ export interface QueryStateChange extends QueryStateChangePartial { // Warning: (ae-missing-release-tag) "QueryStringInput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const QueryStringInput: React.FC>; +export const QueryStringInput: React.FC>; // @public (undocumented) export type QuerySuggestion = QuerySuggestionBasic | QuerySuggestionField;