add kibana.json json-schema for VSCode users (#130625)

* add kibana.json json-schema for VSCode users

* make kibanaVersion description more clear
This commit is contained in:
Spencer 2022-04-20 10:25:41 -05:00 committed by GitHub
parent 830d231cc0
commit 473781ad06
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 419 additions and 21 deletions

View file

@ -151,6 +151,7 @@
"@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/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",
@ -635,6 +636,7 @@
"@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__kibana-json-schema": "link:bazel-bin/packages/kbn-kibana-json-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__mapbox-gl": "link:bazel-bin/packages/kbn-mapbox-gl/npm_module_types",
@ -877,6 +879,7 @@
"jest-styled-components": "^7.0.3",
"jimp": "^0.14.0",
"jsdom": "13.1.0",
"json-schema-typed": "^7.0.3",
"json5": "^1.0.1",
"jsondiffpatch": "0.4.1",
"license-checker": "^16.0.0",

View file

@ -54,6 +54,7 @@ filegroup(
"//packages/kbn-interpreter:build",
"//packages/kbn-io-ts-utils:build",
"//packages/kbn-jest-serializers:build",
"//packages/kbn-kibana-json-schema:build",
"//packages/kbn-logging-mocks:build",
"//packages/kbn-logging:build",
"//packages/kbn-mapbox-gl:build",
@ -149,6 +150,7 @@ 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-logging-mocks:build_types",
"//packages/kbn-logging:build_types",
"//packages/kbn-mapbox-gl:build_types",

View file

@ -47,6 +47,7 @@ RUNTIME_DEPS = [
"//packages/kbn-stdio-dev-helpers",
"//packages/kbn-ci-stats-reporter",
"//packages/kbn-jest-serializers",
"//packages/kbn-kibana-json-schema",
"@npm//@babel/core",
"@npm//axios",
"@npm//chalk",
@ -77,6 +78,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",
"@npm//@babel/parser",
"@npm//@babel/types",
"@npm//@types/babel__core",

View file

@ -6,6 +6,8 @@
* Side Public License, v 1.
*/
import { KibanaJsonSchema } from '@kbn/kibana-json-schema';
export interface ManagedConfigKey {
key: string;
value: string | Record<string, any> | boolean | number;
@ -58,4 +60,17 @@ export const MANAGED_CONFIG_KEYS: ManagedConfigKey[] = [
key: 'typescript.tsserver.maxTsServerMemory',
value: 4096,
},
{
key: 'json.schemas',
value: [
{
fileMatch: ['kibana.json'],
url: './.vscode/kibana-json-schema.json',
},
],
},
];
export const MANAGED_CONFIG_FILES = [
{ name: 'kibana-json-schema.json', content: JSON.stringify(KibanaJsonSchema, null, 2) },
];

View file

@ -26,6 +26,10 @@ const TEST_KEYS: ManagedConfigKey[] = [
key: 'stringKey',
value: 'foo',
},
{
key: 'arrayKey',
value: ['foo', 'bar'],
},
];
const run = (json?: string) => updateVscodeConfig(TEST_KEYS, '', json);
@ -41,7 +45,9 @@ it('updates the passed JSON with the managed settings', () => {
"world": [1, 2, 3]
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -58,7 +64,9 @@ it('initialized empty or undefined json values', () => {
"world": [1, 2, 3]
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -73,7 +81,9 @@ it('initialized empty or undefined json values', () => {
"world": [1, 2, 3]
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -90,7 +100,9 @@ it('replaces conflicting managed keys which do not have matching value types', (
"world": [1, 2, 3]
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -136,7 +148,9 @@ it('persists comments in the original file', () => {
"world": [1, 2, 3]
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -164,7 +178,9 @@ it('overrides old values for managed keys', () => {
"world": [1, 2, 3]
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -206,7 +222,9 @@ it('does not modify properties with leading `// self managed` comment', () => {
"world": [5]
},
// self managed
"stringKey": "--"
"stringKey": "--",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -232,7 +250,9 @@ it('does not modify child properties with leading `// self managed` comment', ()
"hello": true
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -260,7 +280,9 @@ it('does not modify unknown child properties', () => {
"hello": true
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -288,7 +310,9 @@ it('removes managed properties which are no longer managed', () => {
"hello": true
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -314,7 +338,9 @@ it('wipes out child keys which conflict with newly managed child keys', () => {
"world": [1, 2, 3]
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -338,7 +364,9 @@ it('correctly formats info text when specified', () => {
"world": [1, 2, 3]
},
// @managed
"stringKey": "foo"
"stringKey": "foo",
// @managed
"arrayKey": ["foo", "bar"]
}
`);
@ -368,7 +396,9 @@ it('allows "// self managed" comments conflicting with "// @managed" comments to
"world": [1, 2, 3]
},
// self managed
"stringKey": 12345
"stringKey": 12345,
// @managed
"arrayKey": ["foo", "bar"]
}
`);

View file

@ -69,9 +69,9 @@ const createObjectPropOfManagedValues = (key: string, value: Record<string, any>
const addManagedProp = (
ast: t.ObjectExpression,
key: string,
value: string | Record<string, any> | boolean | number
value: string | Record<string, any> | boolean | number | any[]
) => {
if (['number', 'string', 'boolean'].includes(typeof value)) {
if (['number', 'string', 'boolean'].includes(typeof value) || Array.isArray(value)) {
ast.properties.push(createManagedProp(key, value));
} else {
ast.properties.push(createObjectPropOfManagedValues(key, value as Record<string, any>));
@ -183,6 +183,20 @@ export function updateVscodeConfig(keys: ManagedConfigKey[], infoText: string, j
continue;
}
if (Array.isArray(value)) {
if (!existingProp) {
addManagedProp(ast, key, value);
continue;
}
if (!isSelfManaged(existingProp)) {
replaceManagedProp(ast, existingProp, value);
continue;
}
continue;
}
if (typeof value === 'object') {
if (existingProp && existingProp.value.type === 'ObjectExpression') {
// setting exists and is an object so merge properties of `value` with it

View file

@ -7,23 +7,25 @@
*/
import Path from 'path';
import Fs from 'fs/promises';
import Fsp from 'fs/promises';
import { REPO_ROOT } from '@kbn/utils';
import dedent from 'dedent';
import { run } from '../run';
import { MANAGED_CONFIG_KEYS } from './managed_config_keys';
import { MANAGED_CONFIG_KEYS, MANAGED_CONFIG_FILES } from './managed_config_keys';
import { updateVscodeConfig } from './update_vscode_config';
const CONFIG_DIR = Path.resolve(REPO_ROOT, '.vscode');
export function runUpdateVscodeConfigCli() {
run(async ({ log }) => {
const path = Path.resolve(REPO_ROOT, '.vscode/settings.json');
const path = Path.resolve(CONFIG_DIR, 'settings.json');
let json;
try {
json = await Fs.readFile(path, 'utf-8');
json = await Fsp.readFile(path, 'utf-8');
} catch (error) {
if (error.code !== 'ENOENT') {
throw error;
@ -40,8 +42,14 @@ export function runUpdateVscodeConfigCli() {
`,
json
);
await Fs.mkdir(Path.dirname(path), { recursive: true });
await Fs.writeFile(path, updatedJson);
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);
}
await Fsp.writeFile(path, updatedJson);
log.success('updated', path);
});

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-kibana-json-schema"
PKG_REQUIRE_NAME = "@kbn/kibana-json-schema"
SOURCE_FILES = glob(
[
"src/**/*.ts",
],
exclude = [
"**/*.test.*",
],
)
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 = [
"@npm//dedent",
]
# 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/dedent",
"@npm//@types/node",
"@npm//@types/jest",
"@npm//json-schema-typed"
]
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,
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,3 @@
# @kbn/kibana-json-schema
The JSON Schema used for kibana.json files

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-json-schema'],
};

View file

@ -0,0 +1,7 @@
{
"name": "@kbn/kibana-json-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,9 @@
/*
* 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 { KibanaJsonSchema } from './kibana_json_schema';

View file

@ -0,0 +1,145 @@
/*
* 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 dedent from 'dedent';
export const KibanaJsonSchema: JSONSchema = {
type: 'object',
required: ['id', 'version', 'owner'],
properties: {
id: {
description: dedent`
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.
`,
type: 'string',
pattern: '^[a-z]{1}([a-zA-Z0-9]{1,})$',
},
version: {
description: 'Version of the plugin.',
type: 'string',
pattern: '^(kibana|v?\\d+(\\.\\d+){0,2})$',
},
kibanaVersion: {
description: dedent`
The version of Kibana the plugin is compatible with, defaults to the value of the version field.
`,
type: 'string',
pattern: '^(kibana|)$',
},
type: {
description: 'Type of the plugin, defaults to `standard`.',
enum: ['standard', 'preboot'],
},
configPath: {
description:
'Root configuration path used by the plugin, defaults to "id" in snake_case format.',
oneOf: [
{ type: 'string' },
{
type: 'array',
items: { type: 'string' },
},
],
},
requiredPlugins: {
description: dedent`
An optional list of the other plugins that MUST BE installed and enabled for this
plugin to function properly.
`,
type: 'array',
items: { type: 'string' },
},
optionalPlugins: {
description: dedent`
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.
`,
type: 'array',
items: { type: 'string' },
},
requiredBundles: {
description: dedent`
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.
The plugins listed here will be loaded in the browser, even if the plugin is
disabled. Required by \`@kbn/optimizer\` to support cross-plugin imports.
"core" and plugins already listed in \`requiredPlugins\` do not need to be
duplicated here.
`,
type: 'array',
items: { type: 'string' },
},
ui: {
description: dedent`
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`
Specifies whether plugin includes some server-side specific functionality.
`,
type: 'boolean',
},
extraPublicDirs: {
description: dedent`
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
@deprecated To be deleted when https://github.com/elastic/kibana/issues/101948 is done.
`,
type: 'array',
items: { type: 'string' },
},
serviceFolders: {
description: dedent`
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' },
},
owner: {
type: 'object',
required: ['name'],
properties: {
name: {
description: 'The name of the team that currently owns this plugin.',
type: 'string',
},
githubTeam: {
description: dedent`
All internal plugins should have a github team specified. GitHub teams can be
viewed here: https://github.com/orgs/elastic/teams
`,
type: 'string',
},
},
},
description: {
description: dedent`
A brief description of what this plugin does and any capabilities it provides.
`,
type: 'string',
},
enabledOnAnonymousPages: {
description: dedent`
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',
},
},
};

View file

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

View file

@ -3080,6 +3080,10 @@
version "0.0.0"
uid ""
"@kbn/kibana-json-schema@link:bazel-bin/packages/kbn-kibana-json-schema":
version "0.0.0"
uid ""
"@kbn/logging-mocks@link:bazel-bin/packages/kbn-logging-mocks":
version "0.0.0"
uid ""
@ -6148,6 +6152,10 @@
version "0.0.0"
uid ""
"@types/kbn__kibana-json-schema@link:bazel-bin/packages/kbn-kibana-json-schema/npm_module_types":
version "0.0.0"
uid ""
"@types/kbn__logging-mocks@link:bazel-bin/packages/kbn-logging-mocks/npm_module_types":
version "0.0.0"
uid ""
@ -18585,6 +18593,11 @@ 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@0.2.3, json-schema@0.4.0, json-schema@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"