[IDM] define v2 Kibana manifest schema (#137611)

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Spencer 2022-08-04 20:19:46 -05:00 committed by GitHub
parent 4462e16973
commit 76f1b8d5d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 1806 additions and 82 deletions

5
.github/CODEOWNERS vendored
View file

@ -248,6 +248,11 @@
/packages/kbn-ui-shared-deps-npm/ @elastic/kibana-operations
/packages/kbn-ui-shared-deps-src/ @elastic/kibana-operations
/packages/kbn-utils/ @elastic/kibana-operations
/packages/kbn-jsonc/ @elastic/kibana-operations
/packages/kbn-kibana-manifest-parser/ @elastic/kibana-operations
/packages/kbn-kibana-manifest-schema/ @elastic/kibana-operations
/packages/kbn-managed-vscode-config/ @elastic/kibana-operations
/packages/kbn-managed-vscode-config-cli/ @elastic/kibana-operations
/src/cli/keystore/ @elastic/kibana-operations
/.ci/es-snapshots/ @elastic/kibana-operations
/.github/workflows/ @elastic/kibana-operations

View file

@ -121,6 +121,20 @@ THE SOFTWARE.
This product uses Noto fonts that are licensed under the SIL Open
Font License, Version 1.1.
---
Vendored copy of `strip-json-comments` so that we can use it when npm modules are not available.
https://github.com/sindresorhus/strip-json-comments/tree/34b79cb0f1129aa85ef4b5c3292e8bc546984ef9
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
Based on the scroll-into-view-if-necessary module from npm
https://github.com/stipsan/compute-scroll-into-view/blob/master/src/index.ts#L269-L340

View file

@ -68,5 +68,10 @@ layout: landing
{ pageId: "kibDevDocsOpsDevCliRunner" },
{ pageId: "kibDevDocsOpsGetRepoFiles" },
{ pageId: "kibDevDocsOpsRepoSourceClassifier" },
{ pageId: "kibDevDocsOpsJsonc" },
{ pageId: "kibDevDocsOpsKibanaManifestParser" },
{ pageId: "kibDevDocsOpsKibanaManifestSchema" },
{ pageId: "kibDevDocsOpsManagedVscodeConfig" },
{ pageId: "kibDevDocsOpsManagedVscodeConfigCli" },
]}
/>

View file

@ -548,6 +548,21 @@
},
{
"id": "kibDevDocsOpsRepoSourceClassifier"
},
{
"id": "kibDevDocsOpsJsonc"
},
{
"id": "kibDevDocsOpsKibanaManifestParser"
},
{
"id": "kibDevDocsOpsKibanaManifestSchema"
},
{
"id": "kibDevDocsOpsManagedVscodeConfig"
},
{
"id": "kibDevDocsOpsManagedVscodeConfigCli"
}
]
}

View file

@ -268,7 +268,9 @@
"@kbn/i18n-react": "link:bazel-bin/packages/kbn-i18n-react",
"@kbn/interpreter": "link:bazel-bin/packages/kbn-interpreter",
"@kbn/io-ts-utils": "link:bazel-bin/packages/kbn-io-ts-utils",
"@kbn/kibana-json-schema": "link:bazel-bin/packages/kbn-kibana-json-schema",
"@kbn/jsonc": "link:bazel-bin/packages/kbn-jsonc",
"@kbn/kibana-manifest-parser": "link:bazel-bin/packages/kbn-kibana-manifest-parser",
"@kbn/kibana-manifest-schema": "link:bazel-bin/packages/kbn-kibana-manifest-schema",
"@kbn/logging": "link:bazel-bin/packages/kbn-logging",
"@kbn/logging-mocks": "link:bazel-bin/packages/kbn-logging-mocks",
"@kbn/mapbox-gl": "link:bazel-bin/packages/kbn-mapbox-gl",
@ -641,6 +643,8 @@
"@kbn/get-repo-files": "link:bazel-bin/packages/kbn-get-repo-files",
"@kbn/import-resolver": "link:bazel-bin/packages/kbn-import-resolver",
"@kbn/jest-serializers": "link:bazel-bin/packages/kbn-jest-serializers",
"@kbn/managed-vscode-config": "link:bazel-bin/packages/kbn-managed-vscode-config",
"@kbn/managed-vscode-config-cli": "link:bazel-bin/packages/kbn-managed-vscode-config-cli",
"@kbn/optimizer": "link:bazel-bin/packages/kbn-optimizer",
"@kbn/optimizer-webpack-helpers": "link:bazel-bin/packages/kbn-optimizer-webpack-helpers",
"@kbn/performance-testing-dataset-extractor": "link:bazel-bin/packages/kbn-performance-testing-dataset-extractor",
@ -693,6 +697,7 @@
"@types/apidoc": "^0.22.3",
"@types/archiver": "^5.3.1",
"@types/babel__core": "^7.1.19",
"@types/babel__generator": "^7.6.4",
"@types/babel__helper-plugin-utils": "^7.10.0",
"@types/base64-js": "^1.2.5",
"@types/chance": "^1.0.0",
@ -751,6 +756,7 @@
"@types/js-search": "^1.4.0",
"@types/js-yaml": "^3.11.1",
"@types/jsdom": "^16.2.14",
"@types/json-schema": "^7",
"@types/json-stable-stringify": "^1.0.32",
"@types/json5": "^0.0.30",
"@types/jsonwebtoken": "^8.5.6",
@ -916,10 +922,14 @@
"@types/kbn__interpreter": "link:bazel-bin/packages/kbn-interpreter/npm_module_types",
"@types/kbn__io-ts-utils": "link:bazel-bin/packages/kbn-io-ts-utils/npm_module_types",
"@types/kbn__jest-serializers": "link:bazel-bin/packages/kbn-jest-serializers/npm_module_types",
"@types/kbn__jsonc": "link:bazel-bin/packages/kbn-jsonc/npm_module_types",
"@types/kbn__kbn-ci-stats-performance-metrics": "link:bazel-bin/packages/kbn-kbn-ci-stats-performance-metrics/npm_module_types",
"@types/kbn__kibana-json-schema": "link:bazel-bin/packages/kbn-kibana-json-schema/npm_module_types",
"@types/kbn__kibana-manifest-parser": "link:bazel-bin/packages/kbn-kibana-manifest-parser/npm_module_types",
"@types/kbn__kibana-manifest-schema": "link:bazel-bin/packages/kbn-kibana-manifest-schema/npm_module_types",
"@types/kbn__logging": "link:bazel-bin/packages/kbn-logging/npm_module_types",
"@types/kbn__logging-mocks": "link:bazel-bin/packages/kbn-logging-mocks/npm_module_types",
"@types/kbn__managed-vscode-config": "link:bazel-bin/packages/kbn-managed-vscode-config/npm_module_types",
"@types/kbn__managed-vscode-config-cli": "link:bazel-bin/packages/kbn-managed-vscode-config-cli/npm_module_types",
"@types/kbn__mapbox-gl": "link:bazel-bin/packages/kbn-mapbox-gl/npm_module_types",
"@types/kbn__ml-agg-utils": "link:bazel-bin/x-pack/packages/ml/agg_utils/npm_module_types",
"@types/kbn__ml-is-populated-object": "link:bazel-bin/x-pack/packages/ml/is_populated_object/npm_module_types",
@ -1093,6 +1103,7 @@
"@yarnpkg/lockfile": "^1.1.0",
"abab": "^2.0.4",
"aggregate-error": "^3.1.0",
"ajv": "^8.11.0",
"antlr4ts-cli": "^0.5.0-alpha.3",
"apidoc": "^0.29.0",
"apidoc-markdown": "^6.0.0",
@ -1195,7 +1206,7 @@
"jest-styled-components": "^7.0.3",
"jimp": "^0.14.0",
"jsdom": "13.1.0",
"json-schema-typed": "^7.0.3",
"json-schema-typed": "^8.0.1",
"json5": "^1.0.1",
"jsondiffpatch": "0.4.1",
"license-checker": "^25.0.1",

View file

@ -173,9 +173,13 @@ filegroup(
"//packages/kbn-interpreter:build",
"//packages/kbn-io-ts-utils:build",
"//packages/kbn-jest-serializers:build",
"//packages/kbn-kibana-json-schema:build",
"//packages/kbn-jsonc:build",
"//packages/kbn-kibana-manifest-parser:build",
"//packages/kbn-kibana-manifest-schema:build",
"//packages/kbn-logging-mocks:build",
"//packages/kbn-logging:build",
"//packages/kbn-managed-vscode-config-cli:build",
"//packages/kbn-managed-vscode-config:build",
"//packages/kbn-mapbox-gl:build",
"//packages/kbn-monaco:build",
"//packages/kbn-optimizer-webpack-helpers:build",
@ -424,9 +428,13 @@ filegroup(
"//packages/kbn-interpreter:build_types",
"//packages/kbn-io-ts-utils:build_types",
"//packages/kbn-jest-serializers:build_types",
"//packages/kbn-kibana-json-schema:build_types",
"//packages/kbn-jsonc:build_types",
"//packages/kbn-kibana-manifest-parser:build_types",
"//packages/kbn-kibana-manifest-schema:build_types",
"//packages/kbn-logging-mocks:build_types",
"//packages/kbn-logging:build_types",
"//packages/kbn-managed-vscode-config-cli:build_types",
"//packages/kbn-managed-vscode-config:build_types",
"//packages/kbn-mapbox-gl:build_types",
"//packages/kbn-monaco:build_types",
"//packages/kbn-optimizer-webpack-helpers:build_types",

View file

@ -50,7 +50,7 @@ RUNTIME_DEPS = [
"//packages/kbn-stdio-dev-helpers",
"//packages/kbn-ci-stats-reporter",
"//packages/kbn-jest-serializers",
"//packages/kbn-kibana-json-schema",
"//packages/kbn-kibana-manifest-schema",
"@npm//@babel/core",
"@npm//axios",
"@npm//chalk",
@ -84,7 +84,7 @@ TYPES_DEPS = [
"//packages/kbn-stdio-dev-helpers:npm_module_types",
"//packages/kbn-ci-stats-reporter:npm_module_types",
"//packages/kbn-jest-serializers:npm_module_types",
"//packages/kbn-kibana-json-schema:npm_module_types",
"//packages/kbn-kibana-manifest-schema:npm_module_types",
"@npm//@babel/parser",
"@npm//@babel/types",
"@npm//@types/babel__core",

View file

@ -25,5 +25,4 @@ export * from './plugin_list';
export * from './streams';
export * from './babel';
export * from './extract';
export * from './vscode_config';
export * from './diff_strings';

View file

@ -0,0 +1,117 @@
load("@npm//@bazel/typescript:index.bzl", "ts_config")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
PKG_DIRNAME = "kbn-jsonc"
PKG_REQUIRE_NAME = "@kbn/jsonc"
SOURCE_FILES = glob(
[
"src/**/*.js",
],
exclude = [
"**/*.test.*",
"**/*.stories.*",
],
)
SRCS = SOURCE_FILES
filegroup(
name = "srcs",
srcs = SRCS,
)
NPM_MODULE_EXTRA_FILES = [
"package.json",
]
# In this array place runtime dependencies, including other packages and NPM packages
# which must be available for this code to run.
#
# To reference other packages use:
# "//repo/relative/path/to/package"
# eg. "//packages/kbn-utils"
#
# To reference a NPM package use:
# "@npm//name-of-package"
# eg. "@npm//lodash"
RUNTIME_DEPS = [
]
# In this array place dependencies necessary to build the types, which will include the
# :npm_module_types target of other packages and packages from NPM, including @types/*
# packages.
#
# To reference the types for another package use:
# "//repo/relative/path/to/package:npm_module_types"
# eg. "//packages/kbn-utils:npm_module_types"
#
# References to NPM packages work the same as RUNTIME_DEPS
TYPES_DEPS = [
"@npm//@types/node",
"@npm//@types/jest",
]
jsts_transpiler(
name = "target_node",
srcs = SRCS,
build_pkg_name = package_name(),
)
ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"//:tsconfig.base.json",
"//:tsconfig.bazel.json",
],
)
ts_project(
name = "tsc_types",
args = ['--pretty'],
srcs = SRCS,
deps = TYPES_DEPS,
declaration = True,
declaration_map = True,
allow_js = True,
emit_declaration_only = True,
out_dir = "target_types",
root_dir = "src",
tsconfig = ":tsconfig",
)
js_library(
name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
visibility = ["//visibility:public"],
)
pkg_npm(
name = "npm_module",
deps = [":" + PKG_DIRNAME],
)
filegroup(
name = "build",
srcs = [":npm_module"],
visibility = ["//visibility:public"],
)
pkg_npm_types(
name = "npm_module_types",
srcs = SRCS,
deps = [":tsc_types"],
package_name = PKG_REQUIRE_NAME,
tsconfig = ":tsconfig",
visibility = ["//visibility:public"],
)
filegroup(
name = "build_types",
srcs = [":npm_module_types"],
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,20 @@
---
id: kibDevDocsOpsJsonc
slug: /kibana-dev-docs/ops/jsonc
title: "@kbn/jsonc"
description: A package for parsing jsonc
date: 2022-05-24
tags: ['kibana', 'dev', 'contributor', 'operations', 'json', 'jsonc']
---
This package exposes a simple `parse(jsonc: string)` function for parsing JSON-C content. JSON-C is a variant of JSON which supports both block and line comments, which are incredibly useful for configuration files that are committed to the repository and would benefit from the context of comments.
Additionally supported in JSON-C... TRAILING COMMAS!
VSCode and TypeScript use jsonc for their config files, so we're already using it in a lot of places, but we're going to start using it in more places too. This package is implemented in vanilla JS with a vendored copy of [`strip-json-comments`](https://github.com/sindresorhus/strip-json-comments) so that we can use this code from kbn_pm without node modules installed.
## API
### parse(jsonc: string): any
Parses a JSON-C string into the value defined by the content.

View file

@ -6,4 +6,8 @@
* Side Public License, v 1.
*/
export { KibanaJsonSchema } from './kibana_json_schema';
module.exports = {
preset: '@kbn/test/jest_node',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-jsonc'],
};

View file

@ -1,5 +1,5 @@
{
"name": "@kbn/kibana-json-schema",
"name": "@kbn/jsonc",
"private": true,
"version": "1.0.0",
"main": "./target_node/index.js",

View file

@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
const { stripJsonComments } = require('./strip_json_comments');
/**
* @param {string} jsonWithComments
*/
function parse(jsonWithComments) {
return JSON.parse(
stripJsonComments(jsonWithComments, {
whitespace: false,
trailingCommas: true,
})
);
}
module.exports = { parse };

View file

@ -0,0 +1,153 @@
/* eslint-disable @kbn/eslint/require-license-header */
/**
* @notice
*
* Vendored copy of `strip-json-comments` so that we can use it when npm modules are not available.
* https://github.com/sindresorhus/strip-json-comments/tree/34b79cb0f1129aa85ef4b5c3292e8bc546984ef9
*
* MIT License
*
* Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
const singleComment = Symbol('singleComment');
const multiComment = Symbol('multiComment');
const stripWithoutWhitespace = () => '';
/**
* @param {string} string
* @param {number | undefined} start
* @param {number | undefined} end
*/
const stripWithWhitespace = (string, start = undefined, end = undefined) =>
string.slice(start, end).replace(/\S/g, ' ');
/**
* @param {string} jsonString
* @param {number} quotePosition
*/
const isEscaped = (jsonString, quotePosition) => {
let index = quotePosition - 1;
let backslashCount = 0;
while (jsonString[index] === '\\') {
index -= 1;
backslashCount += 1;
}
return Boolean(backslashCount % 2);
};
/**
* @param {string} jsonString
* @param {{ whitespace?: boolean; trailingCommas?: boolean }} options
*/
function stripJsonComments(jsonString, { whitespace = true, trailingCommas = false } = {}) {
if (typeof jsonString !== 'string') {
throw new TypeError(
`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof jsonString}\``
);
}
const strip = whitespace ? stripWithWhitespace : stripWithoutWhitespace;
let isInsideString = false;
/** @type {boolean | symbol} */
let isInsideComment = false;
let offset = 0;
let buffer = '';
let result = '';
let commaIndex = -1;
for (let index = 0; index < jsonString.length; index++) {
const currentCharacter = jsonString[index];
const nextCharacter = jsonString[index + 1];
if (!isInsideComment && currentCharacter === '"') {
// Enter or exit string
const escaped = isEscaped(jsonString, index);
if (!escaped) {
isInsideString = !isInsideString;
}
}
if (isInsideString) {
continue;
}
if (!isInsideComment && currentCharacter + nextCharacter === '//') {
// Enter single-line comment
buffer += jsonString.slice(offset, index);
offset = index;
isInsideComment = singleComment;
index++;
} else if (isInsideComment === singleComment && currentCharacter + nextCharacter === '\r\n') {
// Exit single-line comment via \r\n
index++;
isInsideComment = false;
buffer += strip(jsonString, offset, index);
offset = index;
continue;
} else if (isInsideComment === singleComment && currentCharacter === '\n') {
// Exit single-line comment via \n
isInsideComment = false;
buffer += strip(jsonString, offset, index);
offset = index;
} else if (!isInsideComment && currentCharacter + nextCharacter === '/*') {
// Enter multiline comment
buffer += jsonString.slice(offset, index);
offset = index;
isInsideComment = multiComment;
index++;
continue;
} else if (isInsideComment === multiComment && currentCharacter + nextCharacter === '*/') {
// Exit multiline comment
index++;
isInsideComment = false;
buffer += strip(jsonString, offset, index + 1);
offset = index + 1;
continue;
} else if (trailingCommas && !isInsideComment) {
if (commaIndex !== -1) {
if (currentCharacter === '}' || currentCharacter === ']') {
// Strip trailing comma
buffer += jsonString.slice(offset, index);
result += strip(buffer, 0, 1) + buffer.slice(1);
buffer = '';
offset = index;
commaIndex = -1;
} else if (
currentCharacter !== ' ' &&
currentCharacter !== '\t' &&
currentCharacter !== '\r' &&
currentCharacter !== '\n'
) {
// Hit non-whitespace following a comma; comma is not trailing
buffer += jsonString.slice(offset, index);
offset = index;
commaIndex = -1;
}
} else if (currentCharacter === ',') {
// Flush buffer prior to this point, and save new comma index
result += buffer + jsonString.slice(offset, index);
buffer = '';
offset = index;
commaIndex = index;
}
}
}
return (
result + buffer + (isInsideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset))
);
}
module.exports = { stripJsonComments };

View file

@ -0,0 +1,20 @@
{
"extends": "../../tsconfig.bazel.json",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"allowJs": true,
"checkJs": true,
"outDir": "target_types",
"rootDir": "src",
"stripInternal": false,
"types": [
"jest",
"node"
]
},
"include": [
"src/**/*"
]
}

View file

@ -1,3 +0,0 @@
# @kbn/kibana-json-schema
The JSON Schema used for kibana.json files

View file

@ -0,0 +1,119 @@
load("@npm//@bazel/typescript:index.bzl", "ts_config")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
PKG_DIRNAME = "kbn-kibana-manifest-parser"
PKG_REQUIRE_NAME = "@kbn/kibana-manifest-parser"
SOURCE_FILES = glob(
[
"src/**/*.js",
"src/**/*.ts",
],
exclude = [
"**/*.test.*",
"**/*.stories.*",
],
)
SRCS = SOURCE_FILES
filegroup(
name = "srcs",
srcs = SRCS,
)
NPM_MODULE_EXTRA_FILES = [
"package.json",
]
# In this array place runtime dependencies, including other packages and NPM packages
# which must be available for this code to run.
#
# To reference other packages use:
# "//repo/relative/path/to/package"
# eg. "//packages/kbn-utils"
#
# To reference a NPM package use:
# "@npm//name-of-package"
# eg. "@npm//lodash"
RUNTIME_DEPS = [
]
# In this array place dependencies necessary to build the types, which will include the
# :npm_module_types target of other packages and packages from NPM, including @types/*
# packages.
#
# To reference the types for another package use:
# "//repo/relative/path/to/package:npm_module_types"
# eg. "//packages/kbn-utils:npm_module_types"
#
# References to NPM packages work the same as RUNTIME_DEPS
TYPES_DEPS = [
"@npm//@types/node",
"@npm//@types/jest",
"//packages/kbn-jsonc:npm_module_types",
]
jsts_transpiler(
name = "target_node",
srcs = SRCS,
build_pkg_name = package_name(),
)
ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"//:tsconfig.base.json",
"//:tsconfig.bazel.json",
],
)
ts_project(
name = "tsc_types",
args = ['--pretty'],
srcs = SRCS,
deps = TYPES_DEPS,
declaration = True,
declaration_map = True,
allow_js = True,
emit_declaration_only = True,
out_dir = "target_types",
root_dir = "src",
tsconfig = ":tsconfig",
)
js_library(
name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
visibility = ["//visibility:public"],
)
pkg_npm(
name = "npm_module",
deps = [":" + PKG_DIRNAME],
)
filegroup(
name = "build",
srcs = [":npm_module"],
visibility = ["//visibility:public"],
)
pkg_npm_types(
name = "npm_module_types",
srcs = SRCS,
deps = [":tsc_types"],
package_name = PKG_REQUIRE_NAME,
tsconfig = ":tsconfig",
visibility = ["//visibility:public"],
)
filegroup(
name = "build_types",
srcs = [":npm_module_types"],
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,24 @@
---
id: kibDevDocsOpsKibanaManifestParser
slug: /kibana-dev-docs/ops/kibana-manifest-parser
title: "@kbn/kibana-manifest-parser"
description: A package for parsing Kibana package manifest files
date: 2022-05-24
tags: ['kibana', 'dev', 'contributor', 'operations', 'package', 'kibana.json', 'kibana.jsonc']
---
This package exposes functions and types for parsing Kibana manifest files (in the new `kibana.jsonc` format)
## API
### `parseKibanaManifest(jsonc: string): KibanaPackageManifest`
Parses a JSON-C string into a valid `KibanaPackageManifest` object. If the manifest is invalid an error is thrown.
### `readKibanaManifest(path: string): KibanaPackageManifest`
Read a Kibana manifest from disk and parse it, returning a KibanaPackageManifest. If the file doesn't exist or is invalid in some way an error is thrown.
### `validateKibanaManifest(value: unknown): KibanaPackageManifest`
Validate a parsed Kibana manifest. If the manifest is invalid an error is thrown.

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test/jest_node',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-kibana-manifest-parser'],
};

View file

@ -0,0 +1,7 @@
{
"name": "@kbn/kibana-manifest-parser",
"private": true,
"version": "1.0.0",
"main": "./target_node/index.js",
"license": "SSPL-1.0 OR Elastic License 2.0"
}

View file

@ -0,0 +1,14 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export {
parseKibanaManifest,
readKibanaManifest,
validateKibanaManifest,
} from './parse_kibana_manifest';
export type { KibanaPackageManifest } from './kibana_manifest';

View file

@ -0,0 +1,52 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export type KibanaPackageType =
| 'plugin-browser'
| 'plugin-server'
| 'shared-browser'
| 'shared-server'
| 'shared-common'
| 'shared-scss'
| 'functional-tests'
| 'test-helper';
interface PackageManifestBaseFields {
type: KibanaPackageType;
id: string;
owner: string;
typeDeps: string[];
runtimeDeps: string[];
}
export interface PluginPackageManifest extends PackageManifestBaseFields {
type: 'plugin-browser' | 'plugin-server';
plugin: {
id: string;
configPath?: string[];
requiredPlugins?: string[];
optionalPlugins?: string[];
description?: string;
enabledOnAnonymousPages?: boolean;
serviceFolders?: string[];
};
}
export interface SharedBrowserPackageManifest extends PackageManifestBaseFields {
type: 'shared-browser' | 'shared-common';
sharedBrowserBundle?: boolean;
}
export interface BasePackageManifest extends PackageManifestBaseFields {
type: 'shared-server' | 'functional-tests' | 'test-helper' | 'shared-scss';
}
export type KibanaPackageManifest =
| PluginPackageManifest
| SharedBrowserPackageManifest
| BasePackageManifest;

View file

@ -0,0 +1,229 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { validateKibanaManifest } from './parse_kibana_manifest';
const BASE_FIELDS = {
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: [],
runtimeDeps: [],
};
describe('validateKibanaManifest', () => {
it('requires valid type', () => {
expect(() => validateKibanaManifest({})).toThrowErrorMatchingInlineSnapshot(
`"invalid package \\"type\\", options are [functional-tests, plugin-browser, plugin-server, shared-browser, shared-common, shared-server, test-helper, shared-scss]"`
);
});
it('requires valid id', () => {
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
})
).toThrowErrorMatchingInlineSnapshot(
`"invalid package \\"id\\", must be a string that starts with @kbn/"`
);
});
it('requires valid owner', () => {
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
})
).toThrowErrorMatchingInlineSnapshot(
`"invalid package \\"owner\\", must be a valid Github team handle starting with @"`
);
});
it('requires valid typeDeps', () => {
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
})
).toThrowErrorMatchingInlineSnapshot(`"invalid \\"typeDeps\\", must be an array of strings"`);
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: false,
})
).toThrowErrorMatchingInlineSnapshot(`"invalid \\"typeDeps\\", must be an array of strings"`);
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: [1],
})
).toThrowErrorMatchingInlineSnapshot(`"invalid \\"typeDeps\\", must be an array of strings"`);
});
it('requires valid runtimeDeps', () => {
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: [],
})
).toThrowErrorMatchingInlineSnapshot(
`"invalid \\"runtimeDeps\\", must be an array of strings"`
);
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: [],
runtimeDeps: false,
})
).toThrowErrorMatchingInlineSnapshot(
`"invalid \\"runtimeDeps\\", must be an array of strings"`
);
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: [],
runtimeDeps: [1],
})
).toThrowErrorMatchingInlineSnapshot(
`"invalid \\"runtimeDeps\\", must be an array of strings"`
);
});
it('validates base types', () => {
expect(
validateKibanaManifest({
type: 'shared-server',
...BASE_FIELDS,
})
).toMatchInlineSnapshot(`
Object {
"id": "@kbn/foo",
"owner": "@elastic/kibana-operations",
"runtimeDeps": Array [],
"type": "shared-server",
"typeDeps": Array [],
}
`);
expect(
validateKibanaManifest({
type: 'functional-tests',
...BASE_FIELDS,
})
).toMatchInlineSnapshot(`
Object {
"id": "@kbn/foo",
"owner": "@elastic/kibana-operations",
"runtimeDeps": Array [],
"type": "functional-tests",
"typeDeps": Array [],
}
`);
expect(
validateKibanaManifest({
type: 'test-helper',
...BASE_FIELDS,
})
).toMatchInlineSnapshot(`
Object {
"id": "@kbn/foo",
"owner": "@elastic/kibana-operations",
"runtimeDeps": Array [],
"type": "test-helper",
"typeDeps": Array [],
}
`);
});
describe('plugin-* types', () => {
it('requires valid plugin for plugin-* types', () => {
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: [],
runtimeDeps: [],
})
).toThrowErrorMatchingInlineSnapshot(`"invalid package \\"plugin\\", must be an object"`);
});
it('requires "id" in plugins', () => {
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: [],
runtimeDeps: [],
plugin: {},
})
).toThrowErrorMatchingInlineSnapshot(
`"invalid \\"plugin.id\\", must be a string in camel or snake case"`
);
expect(() =>
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: [],
runtimeDeps: [],
plugin: {
id: 'not-camel-case',
},
})
).toThrowErrorMatchingInlineSnapshot(
`"invalid \\"plugin.id\\", must be a string in camel or snake case"`
);
expect(
validateKibanaManifest({
type: 'plugin-browser',
id: '@kbn/foo',
owner: '@elastic/kibana-operations',
typeDeps: [],
runtimeDeps: [],
plugin: {
id: 'camelCase',
},
})
).toMatchInlineSnapshot(`
Object {
"id": "@kbn/foo",
"owner": "@elastic/kibana-operations",
"plugin": Object {
"configPath": undefined,
"description": undefined,
"enabledOnAnonymousPages": undefined,
"id": "camelCase",
"optionalPlugins": undefined,
"requiredPlugins": undefined,
"serviceFolders": undefined,
},
"runtimeDeps": Array [],
"type": "plugin-browser",
"typeDeps": Array [],
}
`);
});
});
});

View file

@ -0,0 +1,189 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import Fs from 'fs';
import { parse } from '@kbn/jsonc';
import { PluginPackageManifest, KibanaPackageManifest } from './kibana_manifest';
import {
isObj,
isValidId,
isValidPkgType,
isArrOfIds,
isArrOfStrings,
PACKAGE_TYPES,
} from './util';
const err = (msg: string) => new Error(msg);
function validateKibanaManifestPlugin(plugin: unknown): PluginPackageManifest['plugin'] {
if (!isObj(plugin)) {
throw err(`invalid package "plugin", must be an object`);
}
const {
id,
configPath,
requiredPlugins,
optionalPlugins,
description,
enabledOnAnonymousPages,
serviceFolders,
...extra
} = plugin;
const extraKeys = Object.keys(extra);
if (extraKeys.length) {
throw err(`unexpected keys in "plugin" of package [${extraKeys.join(', ')}]`);
}
if (typeof id !== 'string' || !isValidId(id)) {
throw err(`invalid "plugin.id", must be a string in camel or snake case`);
}
if (configPath !== undefined && !isArrOfIds(configPath)) {
throw err(`invalid "plugin.configPath", must be an array of strings in camel or snake case`);
}
if (requiredPlugins !== undefined && !isArrOfIds(requiredPlugins)) {
throw err(
`invalid "plugin.requiredPlugins", must be an array of strings in camel or snake case`
);
}
if (optionalPlugins !== undefined && !isArrOfIds(optionalPlugins)) {
throw err(
`invalid "plugin.requiredPlugins", must be an array of strings in camel or snake case`
);
}
if (description !== undefined && typeof description !== 'string') {
throw err(`invalid "plugin.description", must be a string`);
}
if (enabledOnAnonymousPages !== undefined && typeof enabledOnAnonymousPages !== 'boolean') {
throw err(`invalid "plugin.enabledOnAnonymousPages", must be a boolean`);
}
if (serviceFolders !== undefined && !isArrOfStrings(serviceFolders)) {
throw err(`invalid "plugin.serviceFolders", must be an array of strings`);
}
return {
id,
configPath,
requiredPlugins,
optionalPlugins,
description,
enabledOnAnonymousPages,
serviceFolders,
};
}
/**
* Validate the contents of a parsed kibana.jsonc file.
*/
export function validateKibanaManifest(parsed: unknown): KibanaPackageManifest {
if (!isObj(parsed)) {
throw err('expected root value to be an object');
}
const { type, id, owner, typeDeps, runtimeDeps, plugin, sharedBrowserBundle, ...extra } = parsed;
const extraKeys = Object.keys(extra);
if (extraKeys.length) {
throw err(`unexpected keys in package manifest [${extraKeys.join(', ')}]`);
}
if (!isValidPkgType(type)) {
throw err(`invalid package "type", options are [${PACKAGE_TYPES.join(', ')}]`);
}
if (typeof id !== 'string' || !id.startsWith('@kbn/')) {
throw err(`invalid package "id", must be a string that starts with @kbn/`);
}
if (typeof owner !== 'string' || !owner.startsWith('@')) {
throw err(`invalid package "owner", must be a valid Github team handle starting with @`);
}
if (!isArrOfStrings(typeDeps)) {
throw err(`invalid "typeDeps", must be an array of strings`);
}
if (!isArrOfStrings(runtimeDeps)) {
throw err(`invalid "runtimeDeps", must be an array of strings`);
}
const base = {
id,
owner,
typeDeps,
runtimeDeps,
};
// return if this is one of the more basic types of package types
if (type === 'shared-server' || type === 'functional-tests' || type === 'test-helper') {
return {
type,
...base,
};
}
// handle the plugin field for plugin-* types
if (type === 'plugin-browser' || type === 'plugin-server') {
return {
type,
...base,
plugin: validateKibanaManifestPlugin(plugin),
};
}
// parse the sharedBrowserBundle for shared-browser and shared-common types
if (sharedBrowserBundle !== undefined && typeof sharedBrowserBundle !== 'boolean') {
throw err(`invalid "sharedBrowserBundle" field, expected undefined or a boolean`);
}
return {
type,
...base,
sharedBrowserBundle,
};
}
/**
* Parse a kibana.jsonc file from the filesystem
*/
export function readKibanaManifest(path: string) {
let content;
try {
content = Fs.readFileSync(path, 'utf8');
} catch (error) {
if (error.code === 'ENOENT') {
throw err(`Missing kibana.json file at ${path}`);
}
throw error;
}
return parseKibanaManifest(content);
}
/**
* Parse a kibana.jsonc file from a string
*/
export function parseKibanaManifest(content: string) {
let parsed;
try {
parsed = parse(content);
} catch (error) {
throw err(`Invalid JSONc: ${error.message}`);
}
return validateKibanaManifest(parsed);
}

View file

@ -0,0 +1,44 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { KibanaPackageType } from './kibana_manifest';
export const ID_PATTERN = /^[a-z][a-zA-Z_]*$/;
export function isObj(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null;
}
export const isArrOfStrings = (v: unknown): v is string[] =>
Array.isArray(v) && v.every((i) => typeof i === 'string');
export const isValidId = (id: string) => ID_PATTERN.test(id);
export const isArrOfIds = (v: unknown): v is string[] => isArrOfStrings(v) && v.every(isValidId);
/**
* This weird map allows us to ensure that every value in the
* `KibanaPackageType` union is represented because the mapped
* type requires that the `PACKAGE_TYPE_MAP` map has a property
* matching every value in the union.
*/
const PACKAGE_TYPE_MAP: { [k in KibanaPackageType]: true } = {
'functional-tests': true,
'plugin-browser': true,
'plugin-server': true,
'shared-browser': true,
'shared-common': true,
'shared-server': true,
'test-helper': true,
'shared-scss': true,
};
export const PACKAGE_TYPES = Object.keys(PACKAGE_TYPE_MAP) as KibanaPackageType[];
export const isValidPkgType = (type: unknown): type is keyof typeof PACKAGE_TYPE_MAP =>
typeof type === 'string' && Object.hasOwn(PACKAGE_TYPE_MAP, type);

View file

@ -0,0 +1,20 @@
{
"extends": "../../tsconfig.bazel.json",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"allowJs": true,
"checkJs": true,
"outDir": "target_types",
"rootDir": "src",
"stripInternal": false,
"types": [
"jest",
"node"
]
},
"include": [
"src/**/*"
]
}

View file

@ -2,8 +2,8 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
PKG_DIRNAME = "kbn-kibana-json-schema"
PKG_REQUIRE_NAME = "@kbn/kibana-json-schema"
PKG_DIRNAME = "kbn-kibana-manifest-schema"
PKG_REQUIRE_NAME = "@kbn/kibana-manifest-schema"
SOURCE_FILES = glob(
[
@ -52,7 +52,8 @@ TYPES_DEPS = [
"@npm//@types/dedent",
"@npm//@types/node",
"@npm//@types/jest",
"@npm//json-schema-typed"
"@npm//@types/json-schema",
"@npm//json-schema-typed",
]
jsts_transpiler(

View file

@ -0,0 +1,10 @@
---
id: kibDevDocsOpsKibanaManifestSchema
slug: /kibana-dev-docs/ops/kibana-manifest-schema
title: "@kbn/jsonc"
description: The JSON schema for Kibana manifest files
date: 2022-05-24
tags: ['kibana', 'dev', 'contributor', 'operations', 'json', 'schema', 'manifest']
---
This package exposes JSON-Schema definitions for the `kibana.json` and `kibana.jsonc` manifest files. The JSON-Schemas are not used for validation, but are instead installed in the `.vscode` directory to provide autocomplete for these files in VSCode.

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test/jest_node',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-kibana-manifest-schema'],
};

View file

@ -0,0 +1,7 @@
{
"name": "@kbn/kibana-manifest-schema",
"private": true,
"version": "1.0.0",
"main": "./target_node/index.js",
"license": "SSPL-1.0 OR Elastic License 2.0"
}

View file

@ -0,0 +1,26 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import dedent from 'dedent';
export const desc = (str: TemplateStringsArray, vars?: any[]) => {
const sourceLines = dedent(str, vars)
.split('\n')
.map((l) => l.trim());
const lines: string[] = [];
for (const line of sourceLines) {
if (line === '') {
lines.push('', '');
continue;
}
const existing = lines.length ? lines.pop() : '';
lines.push(existing ? `${existing} ${line}` : line);
}
return lines.join('\n');
};

View file

@ -6,4 +6,5 @@
* Side Public License, v 1.
*/
export * from './update_vscode_config_cli';
export { MANIFEST_V1 } from './kibana_json_v1_schema';
export { MANIFEST_V2 } from './kibana_json_v2_schema';

View file

@ -6,15 +6,15 @@
* Side Public License, v 1.
*/
import type { JSONSchema } from 'json-schema-typed';
import dedent from 'dedent';
import { JSONSchema } from 'json-schema-typed';
import { desc } from './desc';
export const KibanaJsonSchema: JSONSchema = {
export const MANIFEST_V1: JSONSchema = {
type: 'object',
required: ['id', 'version', 'owner'],
properties: {
id: {
description: dedent`
description: desc`
Identifier of the plugin. Must be a string in camelCase. Part of a plugin
public contract. Other plugins leverage it to access plugin API, navigate
to the plugin, etc.
@ -28,7 +28,7 @@ export const KibanaJsonSchema: JSONSchema = {
pattern: '^(kibana|v?\\d+(\\.\\d+){0,2})$',
},
kibanaVersion: {
description: dedent`
description: desc`
The version of Kibana the plugin is compatible with, defaults to the value of the version field.
`,
type: 'string',
@ -50,7 +50,7 @@ export const KibanaJsonSchema: JSONSchema = {
],
},
requiredPlugins: {
description: dedent`
description: desc`
An optional list of the other plugins that MUST BE installed and enabled for this
plugin to function properly.
`,
@ -58,7 +58,7 @@ export const KibanaJsonSchema: JSONSchema = {
items: { type: 'string' },
},
optionalPlugins: {
description: dedent`
description: desc`
An optional list of the other plugins that if installed and enabled **may be**
leveraged by this plugin for some additional functionality but otherwise are
not required for this plugin to work properly.
@ -67,7 +67,7 @@ export const KibanaJsonSchema: JSONSchema = {
items: { type: 'string' },
},
requiredBundles: {
description: dedent`
description: desc`
An optional list of the other plugins that if installed and enabled MAY BE leveraged
by this plugin for some additional functionality but otherwise are not required for
this plugin to work properly.
@ -81,20 +81,20 @@ export const KibanaJsonSchema: JSONSchema = {
items: { type: 'string' },
},
ui: {
description: dedent`
description: desc`
Specifies whether plugin includes some client/browser specific functionality
that should be included into client bundle via \`public/ui_plugin.js\` file.
`,
type: 'boolean',
},
server: {
description: dedent`
description: desc`
Specifies whether plugin includes some server-side specific functionality.
`,
type: 'boolean',
},
extraPublicDirs: {
description: dedent`
description: desc`
Specifies directory names that can be imported by other ui-plugins built
using the same instance of the @kbn/optimizer. A temporary measure we plan
to replace with better mechanisms for sharing static code between plugins
@ -104,7 +104,7 @@ export const KibanaJsonSchema: JSONSchema = {
items: { type: 'string' },
},
serviceFolders: {
description: dedent`
description: desc`
Only used for the automatically generated API documentation. Specifying service
folders will cause your plugin API reference to be broken up into sub sections.
`,
@ -120,7 +120,7 @@ export const KibanaJsonSchema: JSONSchema = {
type: 'string',
},
githubTeam: {
description: dedent`
description: desc`
All internal plugins should have a github team specified. GitHub teams can be
viewed here: https://github.com/orgs/elastic/teams
`,
@ -129,13 +129,13 @@ export const KibanaJsonSchema: JSONSchema = {
},
},
description: {
description: dedent`
description: desc`
A brief description of what this plugin does and any capabilities it provides.
`,
type: 'string',
},
enabledOnAnonymousPages: {
description: dedent`
description: desc`
Specifies whether this plugin - and its required dependencies - will be enabled for anonymous pages (login page, status page when
configured, etc.) Default is false.
`,

View file

@ -0,0 +1,147 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import type { JSONSchema } from 'json-schema-typed';
import { desc } from './desc';
export const PLUGIN_ID_PATTERN = /^[a-z][a-zA-Z_]*$/;
export const MANIFEST_V2: JSONSchema = {
type: 'object',
required: ['id', 'type', 'owner', 'typeDependencies', 'runtimeDependencies'],
properties: {
id: {
type: 'string',
pattern: '^@kbn/',
},
owner: {
type: 'string',
description: desc`
Github handle for the person or team who is responsible for this package.
This owner will be used in the codeowners files for this package.
For additional codeowners, you add additional entries at the end of the
codeowners file.
`,
pattern: '^@',
},
typeDependencies: {
type: 'array',
description: desc`
Packages which are required for the source code in the package to be
type-checked. This list is updated automatically by the package linter.
`,
items: {
type: 'string',
},
},
runtimeDependencies: {
type: 'array',
description: desc`
Packages which are required for the source code in the package to run. This list
is updated automatically by the package linter.
`,
items: {
type: 'string',
},
},
},
oneOf: [
{
type: 'object',
properties: {
type: {
enum: ['plugin-browser', 'plugin-server'],
},
plugin: {
type: 'object',
required: ['id'],
properties: {
id: {
type: 'string',
pattern: PLUGIN_ID_PATTERN.source,
},
configPath: {
description:
'Root configuration path used by the plugin, defaults to "id" in snake_case format.',
type: 'array',
items: {
type: 'string',
pattern: PLUGIN_ID_PATTERN.source,
},
},
requiredPlugins: {
type: 'array',
items: {
type: 'string',
pattern: PLUGIN_ID_PATTERN.source,
},
},
optionalPlugins: {
type: 'array',
items: {
type: 'string',
pattern: PLUGIN_ID_PATTERN.source,
},
},
description: {
description: desc`
A brief description of what this plugin does and any capabilities it provides.
`,
type: 'string',
},
enabledOnAnonymousPages: {
description: desc`
Specifies whether this plugin - and its required dependencies - will be enabled for anonymous pages (login page, status page when
configured, etc.) Default is false.
`,
type: 'boolean',
},
serviceFolders: {
description: desc`
Only used for the automatically generated API documentation. Specifying service
folders will cause your plugin API reference to be broken up into sub sections.
`,
type: 'array',
items: { type: 'string' },
},
},
},
},
},
{
type: 'object',
properties: {
type: {
const: 'shared-browser',
},
sharedBrowserBundle: {
type: 'boolean',
description: desc`
Set this flag to true for this package to produce it's own bundle that will be loaded
asynchronously when needed. Defaults to false.
`,
},
},
},
{
type: 'object',
properties: {
type: {
enum: [
'shared-server',
'shared-common',
'functional-tests',
'test-helper',
'shared-scss',
],
},
},
},
],
};

View file

@ -0,0 +1,120 @@
load("@npm//@bazel/typescript:index.bzl", "ts_config")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
PKG_DIRNAME = "kbn-managed-vscode-config-cli"
PKG_REQUIRE_NAME = "@kbn/managed-vscode-config-cli"
SOURCE_FILES = glob(
[
"src/**/*.ts",
],
exclude = [
"**/*.test.*",
"**/*.stories.*",
],
)
SRCS = SOURCE_FILES
filegroup(
name = "srcs",
srcs = SRCS,
)
NPM_MODULE_EXTRA_FILES = [
"package.json",
]
# In this array place runtime dependencies, including other packages and NPM packages
# which must be available for this code to run.
#
# To reference other packages use:
# "//repo/relative/path/to/package"
# eg. "//packages/kbn-utils"
#
# To reference a NPM package use:
# "@npm//name-of-package"
# eg. "@npm//lodash"
RUNTIME_DEPS = [
]
# In this array place dependencies necessary to build the types, which will include the
# :npm_module_types target of other packages and packages from NPM, including @types/*
# packages.
#
# To reference the types for another package use:
# "//repo/relative/path/to/package:npm_module_types"
# eg. "//packages/kbn-utils:npm_module_types"
#
# References to NPM packages work the same as RUNTIME_DEPS
TYPES_DEPS = [
"@npm//@types/node",
"@npm//@types/jest",
"@npm//dedent",
"//packages/kbn-utils:npm_module_types",
"//packages/kbn-dev-cli-runner:npm_module_types",
"//packages/kbn-managed-vscode-config:npm_module_types",
]
jsts_transpiler(
name = "target_node",
srcs = SRCS,
build_pkg_name = package_name(),
)
ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"//:tsconfig.base.json",
"//:tsconfig.bazel.json",
],
)
ts_project(
name = "tsc_types",
args = ['--pretty'],
srcs = SRCS,
deps = TYPES_DEPS,
declaration = True,
declaration_map = True,
emit_declaration_only = True,
out_dir = "target_types",
root_dir = "src",
tsconfig = ":tsconfig",
)
js_library(
name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
visibility = ["//visibility:public"],
)
pkg_npm(
name = "npm_module",
deps = [":" + PKG_DIRNAME],
)
filegroup(
name = "build",
srcs = [":npm_module"],
visibility = ["//visibility:public"],
)
pkg_npm_types(
name = "npm_module_types",
srcs = SRCS,
deps = [":tsc_types"],
package_name = PKG_REQUIRE_NAME,
tsconfig = ":tsconfig",
visibility = ["//visibility:public"],
)
filegroup(
name = "build_types",
srcs = [":npm_module_types"],
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,12 @@
---
id: kibDevDocsOpsManagedVscodeConfigCli
slug: /kibana-dev-docs/ops/managed-vscode-config-cli
title: "@kbn/managed-vscode-config-cli"
description: CLI for updating the .vscode directory
date: 2022-05-24
tags: ['kibana', 'dev', 'contributor', 'operations', 'vscode']
---
Usage: `node scripts/update_vscode_config`
Updates the `.vscode` directory to have the current value of the managed configs, and updates the managed config files from <DocLink id="kibDevDocsOpsManagedVscodeConfig" />

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test/jest_node',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-managed-vscode-config-cli'],
};

View file

@ -0,0 +1,10 @@
{
"name": "@kbn/managed-vscode-config-cli",
"private": true,
"version": "1.0.0",
"main": "./target_node/index.js",
"license": "SSPL-1.0 OR Elastic License 2.0",
"kibana": {
"devOnly": true
}
}

View file

@ -14,43 +14,44 @@ import dedent from 'dedent';
import { run } from '@kbn/dev-cli-runner';
import { MANAGED_CONFIG_KEYS, MANAGED_CONFIG_FILES } from './managed_config_keys';
import { updateVscodeConfig } from './update_vscode_config';
import {
MANAGED_CONFIG_KEYS,
MANAGED_CONFIG_FILES,
updateVscodeConfig,
} from '@kbn/managed-vscode-config';
const CONFIG_DIR = Path.resolve(REPO_ROOT, '.vscode');
export function runUpdateVscodeConfigCli() {
run(async ({ log }) => {
const path = Path.resolve(CONFIG_DIR, 'settings.json');
run(async ({ log }) => {
const path = Path.resolve(CONFIG_DIR, 'settings.json');
let json;
try {
json = await Fsp.readFile(path, 'utf-8');
} catch (error) {
if (error.code !== 'ENOENT') {
throw error;
}
let json;
try {
json = await Fsp.readFile(path, 'utf-8');
} catch (error) {
if (error.code !== 'ENOENT') {
throw error;
}
}
const updatedJson = updateVscodeConfig(
MANAGED_CONFIG_KEYS,
dedent`
const updatedJson = updateVscodeConfig(
MANAGED_CONFIG_KEYS,
dedent`
Some settings in this file are managed by @kbn/dev-utils. When a setting is managed it is preceeded
with a comment "// @managed" comment. Replace that with "// self managed" and the scripts will not
touch that value. Put a "// self managed" comment at the top of the file, or above a group of settings
to disable management of that entire section.
`,
json
);
await Fsp.mkdir(Path.dirname(path), { recursive: true });
json
);
await Fsp.mkdir(Path.dirname(path), { recursive: true });
// write managed config files
for (const { name, content } of MANAGED_CONFIG_FILES) {
await Fsp.writeFile(Path.resolve(CONFIG_DIR, name), content);
}
// write managed config files
for (const { name, content } of MANAGED_CONFIG_FILES) {
await Fsp.writeFile(Path.resolve(CONFIG_DIR, name), content);
}
await Fsp.writeFile(path, updatedJson);
await Fsp.writeFile(path, updatedJson);
log.success('updated', path);
});
}
log.success('updated', path);
});

View file

@ -0,0 +1,18 @@
{
"extends": "../../tsconfig.bazel.json",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"outDir": "target_types",
"rootDir": "src",
"stripInternal": false,
"types": [
"jest",
"node"
]
},
"include": [
"src/**/*"
]
}

View file

@ -0,0 +1,122 @@
load("@npm//@bazel/typescript:index.bzl", "ts_config")
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
PKG_DIRNAME = "kbn-managed-vscode-config"
PKG_REQUIRE_NAME = "@kbn/managed-vscode-config"
SOURCE_FILES = glob(
[
"src/**/*.ts",
],
exclude = [
"**/*.test.*",
"**/*.stories.*",
],
)
SRCS = SOURCE_FILES
filegroup(
name = "srcs",
srcs = SRCS,
)
NPM_MODULE_EXTRA_FILES = [
"package.json",
]
# In this array place runtime dependencies, including other packages and NPM packages
# which must be available for this code to run.
#
# To reference other packages use:
# "//repo/relative/path/to/package"
# eg. "//packages/kbn-utils"
#
# To reference a NPM package use:
# "@npm//name-of-package"
# eg. "@npm//lodash"
RUNTIME_DEPS = [
]
# In this array place dependencies necessary to build the types, which will include the
# :npm_module_types target of other packages and packages from NPM, including @types/*
# packages.
#
# To reference the types for another package use:
# "//repo/relative/path/to/package:npm_module_types"
# eg. "//packages/kbn-utils:npm_module_types"
#
# References to NPM packages work the same as RUNTIME_DEPS
TYPES_DEPS = [
"@npm//@types/node",
"@npm//@types/jest",
"@npm//@babel/parser",
"@npm//@babel/types",
"@npm//@types/babel__generator",
"@npm//@types/prettier",
"@npm//tslib",
"//packages/kbn-kibana-manifest-schema:npm_module_types",
]
jsts_transpiler(
name = "target_node",
srcs = SRCS,
build_pkg_name = package_name(),
)
ts_config(
name = "tsconfig",
src = "tsconfig.json",
deps = [
"//:tsconfig.base.json",
"//:tsconfig.bazel.json",
],
)
ts_project(
name = "tsc_types",
args = ['--pretty'],
srcs = SRCS,
deps = TYPES_DEPS,
declaration = True,
declaration_map = True,
emit_declaration_only = True,
out_dir = "target_types",
root_dir = "src",
tsconfig = ":tsconfig",
)
js_library(
name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
visibility = ["//visibility:public"],
)
pkg_npm(
name = "npm_module",
deps = [":" + PKG_DIRNAME],
)
filegroup(
name = "build",
srcs = [":npm_module"],
visibility = ["//visibility:public"],
)
pkg_npm_types(
name = "npm_module_types",
srcs = SRCS,
deps = [":tsc_types"],
package_name = PKG_REQUIRE_NAME,
tsconfig = ":tsconfig",
visibility = ["//visibility:public"],
)
filegroup(
name = "build_types",
srcs = [":npm_module_types"],
visibility = ["//visibility:public"],
)

View file

@ -0,0 +1,14 @@
---
id: kibDevDocsOpsManagedVscodeConfig
slug: /kibana-dev-docs/ops/managed-vscode-config
title: "@kbn/managed-vscode-config"
description: Config options for vscode that are automatically setup for contributors
date: 2022-05-24
tags: ['kibana', 'dev', 'contributor', 'operations', 'vscode']
---
This package contains VSCode settings which are automatically setup for contributors on bootstrap. This is done via the <DocsLink id="kibDevDocsOpsManagedVscodeConfigCli" /> using `node scripts/update_vscode_config`.
In order to support contributors maintaining workspace-specific configuration of their own, this tool prefixes all managed config settings with `// @managed` comments. If you want to override any config that is `// @managed` then just update that comment to `// self managed` and the update script won't touch that key/value.
`// self managed` comments are only necessary for keys which are currently or might become managed in the future. Config keys which are not managed are always preserved when updating the `.vscode` directory.

View file

@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
preset: '@kbn/test/jest_node',
rootDir: '../..',
roots: ['<rootDir>/packages/kbn-managed-vscode-config'],
};

View file

@ -0,0 +1,10 @@
{
"name": "@kbn/managed-vscode-config",
"private": true,
"version": "1.0.0",
"main": "./target_node/index.js",
"license": "SSPL-1.0 OR Elastic License 2.0",
"kibana": {
"devOnly": true
}
}

View file

@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
export { MANAGED_CONFIG_FILES, MANAGED_CONFIG_KEYS } from './managed_config_keys';
export { updateVscodeConfig } from './update_vscode_config';

View file

@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
import { KibanaJsonSchema } from '@kbn/kibana-json-schema';
import { MANIFEST_V1, MANIFEST_V2 } from '@kbn/kibana-manifest-schema';
export interface ManagedConfigKey {
key: string;
@ -67,10 +67,21 @@ export const MANAGED_CONFIG_KEYS: ManagedConfigKey[] = [
fileMatch: ['kibana.json'],
url: './.vscode/kibana-json-schema.json',
},
{
fileMatch: ['kibana.jsonc'],
url: './.vscode/kibana-manifest-schema-v2.json',
},
],
},
];
export const MANAGED_CONFIG_FILES = [
{ name: 'kibana-json-schema.json', content: JSON.stringify(KibanaJsonSchema, null, 2) },
{
name: 'kibana-json-schema.json',
content: JSON.stringify(MANIFEST_V1, null, 2),
},
{
name: 'kibana-manifest-schema-v2.json',
content: JSON.stringify(MANIFEST_V2, null, 2),
},
];

View file

@ -0,0 +1,18 @@
{
"extends": "../../tsconfig.bazel.json",
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"outDir": "target_types",
"rootDir": "src",
"stripInternal": false,
"types": [
"jest",
"node"
]
},
"include": [
"src/**/*"
]
}

View file

@ -27,19 +27,20 @@ function safeReadDir(path) {
}
/**
* Given an iterable of paths with optoinal "*" segments, expand the path to the
* list of actual absolute paths, removing all "*" segments, and then return the
* set of paths which end up pointing to actual files.
* Search for files named `name` in `dir`, up to `depth` levels deep. If a directory has a
* matching file its children are not iterated, otherwise if depth > 0 then all child
* directories are checked recursively with depth-1
*
* @param {string} dir
* @param {number} depth
* @param {string} name
* @returns {string[]}
*/
function findKibanaJsonFiles(dir, depth) {
function findFiles(dir, depth, name) {
// if depth = 0 then we just need to determine if there is a kibana.json file in this directory
// and return either that path or an empty array
if (depth === 0) {
const path = Path.resolve(dir, 'kibana.json');
const path = Path.resolve(dir, name);
return Fs.existsSync(path) ? [path] : [];
}
@ -51,7 +52,7 @@ function findKibanaJsonFiles(dir, depth) {
const childDirs = [];
for (const ent of files) {
if (ent.isFile()) {
if (ent.name === 'kibana.json') {
if (ent.name === name) {
return [Path.resolve(dir, ent.name)];
}
} else if (ent.isDirectory()) {
@ -59,7 +60,7 @@ function findKibanaJsonFiles(dir, depth) {
}
}
return childDirs.flatMap((dir) => findKibanaJsonFiles(dir, depth - 1));
return childDirs.flatMap((dir) => findFiles(dir, depth - 1, name));
}
module.exports = { findKibanaJsonFiles };
module.exports = { findFiles };

View file

@ -7,7 +7,7 @@
*/
const { parseKibanaPlatformPlugin } = require('./parse_kibana_platform_plugin');
const { findKibanaJsonFiles } = require('./find_kibana_json_files');
const { findFiles } = require('./find_files');
/**
* Helper to find the new platform plugins.
@ -19,9 +19,9 @@ function simpleKibanaPlatformPluginDiscovery(scanDirs, pluginPaths) {
return Array.from(
new Set([
// find kibana.json files up to 5 levels within each scan dir
...scanDirs.flatMap((dir) => findKibanaJsonFiles(dir, 5)),
...scanDirs.flatMap((dir) => findFiles(dir, 5, 'kibana.json')),
// find kibana.json files at the root of each plugin path
...pluginPaths.flatMap((path) => findKibanaJsonFiles(path, 0)),
...pluginPaths.flatMap((path) => findFiles(path, 0, 'kibana.json')),
])
).map(parseKibanaPlatformPlugin);
}

View file

@ -7,4 +7,4 @@
*/
require('../src/setup_node_env/no_transpilation');
require('@kbn/dev-utils').runUpdateVscodeConfigCli();
require('@kbn/managed-vscode-config-cli');

View file

@ -3579,7 +3579,15 @@
version "0.0.0"
uid ""
"@kbn/kibana-json-schema@link:bazel-bin/packages/kbn-kibana-json-schema":
"@kbn/jsonc@link:bazel-bin/packages/kbn-jsonc":
version "0.0.0"
uid ""
"@kbn/kibana-manifest-parser@link:bazel-bin/packages/kbn-kibana-manifest-parser":
version "0.0.0"
uid ""
"@kbn/kibana-manifest-schema@link:bazel-bin/packages/kbn-kibana-manifest-schema":
version "0.0.0"
uid ""
@ -3591,6 +3599,14 @@
version "0.0.0"
uid ""
"@kbn/managed-vscode-config-cli@link:bazel-bin/packages/kbn-managed-vscode-config-cli":
version "0.0.0"
uid ""
"@kbn/managed-vscode-config@link:bazel-bin/packages/kbn-managed-vscode-config":
version "0.0.0"
uid ""
"@kbn/mapbox-gl@link:bazel-bin/packages/kbn-mapbox-gl":
version "0.0.0"
uid ""
@ -6181,6 +6197,13 @@
dependencies:
"@babel/types" "^7.0.0"
"@types/babel__generator@^7.6.4":
version "7.6.4"
resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7"
integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==
dependencies:
"@babel/types" "^7.0.0"
"@types/babel__helper-plugin-utils@^7.10.0":
version "7.10.0"
resolved "https://registry.yarnpkg.com/@types/babel__helper-plugin-utils/-/babel__helper-plugin-utils-7.10.0.tgz#dcd2416f9c189d5837ab2a276368cf67134efe78"
@ -6793,6 +6816,11 @@
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
"@types/json-schema@^7":
version "7.0.11"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
"@types/json-stable-stringify@^1.0.32":
version "1.0.32"
resolved "https://registry.yarnpkg.com/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz#121f6917c4389db3923640b2e68de5fa64dda88e"
@ -7463,11 +7491,19 @@
version "0.0.0"
uid ""
"@types/kbn__jsonc@link:bazel-bin/packages/kbn-jsonc/npm_module_types":
version "0.0.0"
uid ""
"@types/kbn__kbn-ci-stats-performance-metrics@link:bazel-bin/packages/kbn-kbn-ci-stats-performance-metrics/npm_module_types":
version "0.0.0"
uid ""
"@types/kbn__kibana-json-schema@link:bazel-bin/packages/kbn-kibana-json-schema/npm_module_types":
"@types/kbn__kibana-manifest-parser@link:bazel-bin/packages/kbn-kibana-manifest-parser/npm_module_types":
version "0.0.0"
uid ""
"@types/kbn__kibana-manifest-schema@link:bazel-bin/packages/kbn-kibana-manifest-schema/npm_module_types":
version "0.0.0"
uid ""
@ -7479,6 +7515,14 @@
version "0.0.0"
uid ""
"@types/kbn__managed-vscode-config-cli@link:bazel-bin/packages/kbn-managed-vscode-config-cli/npm_module_types":
version "0.0.0"
uid ""
"@types/kbn__managed-vscode-config@link:bazel-bin/packages/kbn-managed-vscode-config/npm_module_types":
version "0.0.0"
uid ""
"@types/kbn__mapbox-gl@link:bazel-bin/packages/kbn-mapbox-gl/npm_module_types":
version "0.0.0"
uid ""
@ -9298,10 +9342,10 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.11.0, ajv@^6.12.2, ajv@^6.12.4, ajv
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ajv@^8.0.0, ajv@^8.0.1, ajv@^8.8.0:
version "8.9.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18"
integrity sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ==
ajv@^8.0.0, ajv@^8.0.1, ajv@^8.11.0, ajv@^8.8.0:
version "8.11.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f"
integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==
dependencies:
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
@ -19343,10 +19387,10 @@ json-schema-traverse@^1.0.0:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
json-schema-typed@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-7.0.3.tgz#23ff481b8b4eebcd2ca123b4fa0409e66469a2d9"
integrity sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==
json-schema-typed@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/json-schema-typed/-/json-schema-typed-8.0.1.tgz#826ee39e3b6cef536f85412ff048d3ff6f19dfa0"
integrity sha512-XQmWYj2Sm4kn4WeTYvmpKEbyPsL7nBsb647c7pMe6l02/yx2+Jfc4dT6UZkEXnIUb5LhD55r2HPsJ1milQ4rDg==
json-schema@0.2.3, json-schema@0.4.0, json-schema@^0.4.0:
version "0.4.0"