Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions packages/kbn-generate-console-definitions/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# @kbn/generate-console-definitions
# Generate console definitions
This package is a script to generate definitions used in Console to display autocomplete suggestions. The script is
a new implementation of `kbn-spec-to-console` package: The old script uses [JSON specs](https://github.com/elastic/elasticsearch/tree/main/rest-api-spec) from the Elasticsearch repo as the source, whereas this script uses the Elasticsearch specification [repo](https://github.com/elastic/elasticsearch-specification) as the source.

## Instructions
1. Checkout the Elasticsearch specification [repo](https://github.com/elastic/elasticsearch-specification).
2. Run the command `node scripts/generate_console_definitions.js --source <ES_SPECIFICATION_REPO> --emptyDest`
This command will use the folder `<ES_SPECIFICATION_REPO>` as the source and the constant [`AUTOCOMPLETE_DEFINITIONS_FOLDER`](https://github.com/elastic/kibana/blob/main/src/plugins/console/common/constants/autocomplete_definitions.ts) as the destination. Based on the value of the constant, the autocomplete definitions will be generated in the folder `<KIBANA_REPO>/src/plugins/server/lib/spec_definitions/json/generated`. Using the flag `--emptyDest` will remove any existing files in the destination folder.
3. It's possible to generate the definitions into a different folder. For that pass an option to the command `--dest <DEFINITIONS_FOLDER>` and also update the constant [`AUTOCOMPLETE_DEFINITIONS_FOLDER`](https://github.com/elastic/kibana/blob/main/src/plugins/console/common/constants/autocomplete_definitions.ts) so that the Console server will load the definitions from this folder.

Empty package generated by @kbn/generate
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,16 @@
import fs from 'fs';
import Path, { join } from 'path';
import { ToolingLog } from '@kbn/tooling-log';

interface EndpointRequest {
name: string;
namespace: string;
}

interface Endpoint {
name: string;
urls: Array<{
methods: string[];
path: string;
}>;
docUrl: string;
request: null | EndpointRequest;
}

interface SchemaType {
name: {
name: string;
namespace: string;
};
}

interface Schema {
endpoints: Endpoint[];
types: SchemaType[];
}

interface UrlParams {
[key: string]: number | string;
}

interface BodyParams {
[key: string]: number | string;
}

interface Definition {
documentation?: string;
methods: string[];
patterns: string[];
url_params?: UrlParams;
data_autocomplete_rules?: BodyParams;
}

const generateMethods = (endpoint: Endpoint): string[] => {
import { generateQueryParams } from './generate_query_params';
import type {
AutocompleteBodyParams,
AutocompleteDefinition,
AutocompleteUrlParams,
SpecificationTypes,
} from './types';
import { findTypeDefinition } from './utils';

const generateMethods = (endpoint: SpecificationTypes.Endpoint): string[] => {
// this array consists of arrays of strings
const methodsArray = endpoint.urls.map((url) => url.methods);
// flatten to return array of strings
Expand All @@ -62,7 +27,7 @@ const generateMethods = (endpoint: Endpoint): string[] => {
return [...new Set(flattenMethodsArray)];
};

const generatePatterns = (endpoint: Endpoint): string[] => {
const generatePatterns = (endpoint: SpecificationTypes.Endpoint): string[] => {
return endpoint.urls.map(({ path }) => {
let pattern = path;
// remove leading / if present
Expand All @@ -73,42 +38,37 @@ const generatePatterns = (endpoint: Endpoint): string[] => {
});
};

const generateDocumentation = (endpoint: Endpoint): string => {
const generateDocumentation = (endpoint: SpecificationTypes.Endpoint): string => {
return endpoint.docUrl;
};

const generateParams = (
endpoint: Endpoint,
schema: Schema
): { urlParams: UrlParams; bodyParams: BodyParams } | undefined => {
endpoint: SpecificationTypes.Endpoint,
schema: SpecificationTypes.Model
): { urlParams: AutocompleteUrlParams; bodyParams: AutocompleteBodyParams } | undefined => {
const { request } = endpoint;
if (!request) {
return;
}
const requestType = schema.types.find(
({ name: { name, namespace } }) => name === request.name && namespace === request.namespace
);
const requestType = findTypeDefinition(schema, request);
if (!requestType) {
return;
}

const urlParams = generateUrlParams(requestType);
const urlParams = generateQueryParams(requestType as SpecificationTypes.Request, schema);
const bodyParams = generateBodyParams(requestType);
return { urlParams, bodyParams };
};

const generateUrlParams = (requestType: SchemaType): UrlParams => {
return {};
};

const generateBodyParams = (requestType: SchemaType): BodyParams => {
const generateBodyParams = (
requestType: SpecificationTypes.TypeDefinition
): AutocompleteBodyParams => {
return {};
};

const addParams = (
definition: Definition,
params: { urlParams: UrlParams; bodyParams: BodyParams }
): Definition => {
definition: AutocompleteDefinition,
params: { urlParams: AutocompleteUrlParams; bodyParams: AutocompleteBodyParams }
): AutocompleteDefinition => {
const { urlParams, bodyParams } = params;
if (urlParams && Object.keys(urlParams).length > 0) {
definition.url_params = urlParams;
Expand All @@ -119,15 +79,19 @@ const addParams = (
return definition;
};

const generateDefinition = (endpoint: Endpoint, schema: Schema): Definition => {
const generateDefinition = (
endpoint: SpecificationTypes.Endpoint,
schema: SpecificationTypes.Model
): AutocompleteDefinition => {
const methods = generateMethods(endpoint);
const patterns = generatePatterns(endpoint);
const documentation = generateDocumentation(endpoint);
let definition: Definition = { methods, patterns, documentation };
let definition: AutocompleteDefinition = {};
const params = generateParams(endpoint, schema);
if (params) {
definition = addParams(definition, params);
}
definition = { ...definition, methods, patterns, documentation };

return definition;
};
Expand All @@ -143,15 +107,15 @@ export function generateConsoleDefinitions({
}) {
const pathToSchemaFile = Path.resolve(specsRepo, 'output/schema/schema.json');
log.info('loading the ES specification schema file');
const schema = JSON.parse(fs.readFileSync(pathToSchemaFile, 'utf8')) as Schema;
const schema = JSON.parse(fs.readFileSync(pathToSchemaFile, 'utf8')) as SpecificationTypes.Model;

const { endpoints } = schema;
log.info(`iterating over endpoints array: ${endpoints.length} endpoints`);
endpoints.forEach((endpoint) => {
const { name } = endpoint;
log.info(name);
const definition = generateDefinition(endpoint, schema);
const fileContent: { [name: string]: Definition } = {
const fileContent: { [name: string]: AutocompleteDefinition } = {
[name]: definition,
};
fs.writeFileSync(
Expand Down
Loading