Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Console] Add logic for query params #160515

Merged
merged 12 commits into from
Jul 5, 2023
Merged
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