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
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ export interface GeneratorConfig {
*/
outFile: string;
};
/**
* Schema name transformation strategy for generated TypeScript/zod types
* - 'pascalCase': Converts names to PascalCase
* - undefined: No transformation (preserves original names)
* @default undefined
*/
schemaNameTransform?: 'pascalCase';
}

export const generate = async (config: GeneratorConfig) => {
Expand All @@ -62,7 +69,9 @@ export const generate = async (config: GeneratorConfig) => {
return {
sourcePath,
generatedPath: getGeneratedFilePath(sourcePath),
generationContext: getGenerationContext(parsedSchema),
generationContext: getGenerationContext(parsedSchema, {
schemaNameTransform: config.schemaNameTransform,
}),
};
})
);
Expand Down Expand Up @@ -106,6 +115,9 @@ export const generate = async (config: GeneratorConfig) => {
title,
version: 'Bundle (no version)',
},
config: {
schemaNameTransform: config.schemaNameTransform,
},
});

await fs.writeFile(bundle.outFile, result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

import type { OpenAPIV3 } from 'openapi-types';
import type { GeneratorConfig } from '../openapi_generator';
import { getApiOperationsList } from './lib/get_api_operations_list';
import { getComponents } from './lib/get_components';
import type { ImportsMap } from './lib/get_imports_map';
Expand All @@ -23,15 +24,20 @@ export interface GenerationContext {
info: OpenAPIV3.InfoObject;
imports: ImportsMap;
circularRefs: Set<string>;
config: Pick<GeneratorConfig, 'schemaNameTransform'>;
}

export interface BundleGenerationContext {
operations: NormalizedOperation[];
sources: ParsedSource[];
info: OpenAPIV3.InfoObject;
config: Pick<GeneratorConfig, 'schemaNameTransform'>;
}

export function getGenerationContext(document: OpenApiDocument): GenerationContext {
export function getGenerationContext(
document: OpenApiDocument,
config: GenerationContext['config']
): GenerationContext {
const normalizedDocument = normalizeSchema(document);

const components = getComponents(normalizedDocument);
Expand All @@ -46,5 +52,6 @@ export function getGenerationContext(document: OpenApiDocument): GenerationConte
info,
imports,
circularRefs,
config,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
*/
import type Handlebars from '@kbn/handlebars';
import type { HelperOptions } from '@kbn/handlebars';
import { snakeCase, camelCase, upperCase } from 'lodash';
import { snakeCase, camelCase, upperCase, startCase } from 'lodash';

function pascalCase(str: string): string {
return startCase(camelCase(str)).replace(/ /g, '');
}

export function registerHelpers(handlebarsInstance: typeof Handlebars) {
handlebarsInstance.registerHelper('concat', (...args) => {
Expand All @@ -18,6 +22,16 @@ export function registerHelpers(handlebarsInstance: typeof Handlebars) {
handlebarsInstance.registerHelper('snakeCase', snakeCase);
handlebarsInstance.registerHelper('camelCase', camelCase);
handlebarsInstance.registerHelper('upperCase', upperCase);
handlebarsInstance.registerHelper(
'transformSchemaName',
(name: string, options: HelperOptions) => {
const config = options.data?.root?.config;
if (config?.schemaNameTransform === 'pascalCase') {
return pascalCase(name);
}
return name;
}
);
handlebarsInstance.registerHelper('toJSON', (value: unknown) => {
return JSON.stringify(value);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,29 @@
{{~/if~}}

{{~#if $ref~}}
{{referenceName}}
{{transformSchemaName referenceName}}
{{~#if (isCircularRef $ref)}}Input{{/if~}}
{{~#if nullable}} | null {{/if~}}
{{~/if~}}

{{~#if allOf~}}
{{~#each allOf~}}
{{~> ts_input_type ~}}
{{~#unless @last~}}&{{~/unless~}}
{{~#unless @last~}}&{{~/unless~}}
{{~/each~}}
{{~/if~}}

{{~#if anyOf~}}
{{~#each anyOf~}}
{{~> ts_input_type ~}}
{{~#unless @last~}}|{{~/unless~}}
{{~#unless @last~}}|{{~/unless~}}
{{~/each~}}
{{~/if~}}

{{~#if oneOf~}}
{{~#each oneOf~}}
{{~> ts_input_type ~}}
{{~#unless @last~}}|{{~/unless~}}
{{~#unless @last~}}|{{~/unless~}}
{{~/each~}}
{{~/if~}}

Expand Down Expand Up @@ -55,8 +55,8 @@ unknown
{
{{#each properties}}
{{#if description}}
/**
* {{{description}}}
/**
* {{{description}}}
*/
{{/if}}
'{{@key}}'{{~#unless (includes ../required @key)}}?{{/unless~}}: {{> ts_input_type }};
Expand All @@ -77,7 +77,7 @@ unknown
{{~#if enum~}}
{{~#each enum~}}
'{{.}}'
{{~#unless @last~}}|{{~/unless~}}
{{~#unless @last~}}|{{~/unless~}}
{{~/each~}}
{{~else~}}
string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,28 @@
{{~/if~}}

{{~#if $ref~}}
{{referenceName}}
{{transformSchemaName referenceName}}
{{~#if nullable}} | null {{/if~}}
{{~/if~}}

{{~#if allOf~}}
{{~#each allOf~}}
{{~> ts_type ~}}
{{~#unless @last~}}&{{~/unless~}}
{{~#unless @last~}}&{{~/unless~}}
{{~/each~}}
{{~/if~}}

{{~#if anyOf~}}
{{~#each anyOf~}}
{{~> ts_type ~}}
{{~#unless @last~}}|{{~/unless~}}
{{~#unless @last~}}|{{~/unless~}}
{{~/each~}}
{{~/if~}}

{{~#if oneOf~}}
{{~#each oneOf~}}
{{~> ts_type ~}}
{{~#unless @last~}}|{{~/unless~}}
{{~#unless @last~}}|{{~/unless~}}
{{~/each~}}
{{~/if~}}

Expand Down Expand Up @@ -54,8 +54,8 @@ unknown
{
{{#each properties}}
{{#if description}}
/**
* {{{description}}}
/**
* {{{description}}}
*/
{{/if}}
'{{@key}}'{{~#unless (or (includes ../required @key) (defined default))}}?{{/unless~}}: {{> ts_type }};
Expand All @@ -76,7 +76,7 @@ unknown
{{~#if enum~}}
{{~#each enum~}}
'{{.}}'
{{~#unless @last~}}|{{~/unless~}}
{{~#unless @last~}}|{{~/unless~}}
{{~/each~}}
{{~else~}}
string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,26 @@ import {
*/
{{/if}}
{{#if (isCircularSchema @key)}}
export type {{@key}} = {{> ts_type}};
export type {{@key}}Input = {{> ts_input_type }};
export const {{@key}}: z.ZodType<{{@key}}, ZodTypeDef, {{@key}}Input> = {{> zod_schema_item }};
export type {{transformSchemaName @key}} = {{> ts_type}};
export type {{transformSchemaName @key}}Input = {{> ts_input_type }};
export const {{transformSchemaName @key}}: z.ZodType<{{transformSchemaName @key}}, ZodTypeDef, {{transformSchemaName @key}}Input> = {{> zod_schema_item }};
{{else}}
{{#if (shouldCastExplicitly this)}}
{{!-- We need this temporary type to infer from it below, but in the end we want to export as a casted {{@key}} type --}}
{{!-- We need this temporary type to infer from it below, but in the end we want to export as a casted {{transformSchemaName @key}} type --}}
{{!-- error TS7056: The inferred type of this node exceeds the maximum length the compiler will serialize. An explicit type annotation is needed. --}}
export const {{@key}}Internal = {{> zod_schema_item}};
export const {{transformSchemaName @key}}Internal = {{> zod_schema_item}};

export type {{@key}} = z.infer<typeof {{@key}}Internal>;
export const {{@key}} = {{@key}}Internal as z.ZodType<{{@key}}>;
export type {{transformSchemaName @key}} = z.infer<typeof {{transformSchemaName @key}}Internal>;
export const {{transformSchemaName @key}} = {{transformSchemaName @key}}Internal as z.ZodType<{{transformSchemaName @key}}>;
{{else}}
export type {{@key}} = z.infer<typeof {{@key}}>;
export const {{@key}} = {{> zod_schema_item}};
export type {{transformSchemaName @key}} = z.infer<typeof {{transformSchemaName @key}}>;
export const {{transformSchemaName @key}} = {{> zod_schema_item}};
{{/if }}
{{/if}}
{{#if enum}}
{{#unless (isSingle enum)}}
export type {{@key}}Enum = typeof {{@key}}.enum;
export const {{@key}}Enum = {{@key}}.enum;
export type {{transformSchemaName @key}}Enum = typeof {{transformSchemaName @key}}.enum;
export const {{transformSchemaName @key}}Enum = {{transformSchemaName @key}}.enum;
{{/unless}}
{{/if}}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{~#if $ref~}}
{{referenceName}}
{{transformSchemaName referenceName}}
{{~#if nullable}}.nullable(){{/if~}}
{{~#if (eq requiredBool false)}}.optional(){{/if~}}
{{~#if (defined default)}}.default({{{toJSON default}}}){{/if~}}
Expand All @@ -9,8 +9,8 @@
z.object({
{{#each properties}}
{{#if description}}
/**
* {{{description}}}
/**
* {{{description}}}
*/
{{/if}}
{{@key}}: {{> zod_query_item requiredBool=(includes ../required @key)}},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

{{~#if $ref~}}
{{~#if (isCircularRef $ref)~}}
z.lazy(() => {{referenceName}})
z.lazy(() => {{transformSchemaName referenceName}})
{{~else~}}
{{referenceName}}
{{transformSchemaName referenceName}}
{{~/if~}}
{{~#if nullable}}.nullable(){{/if~}}
{{~#if (eq requiredBool false)}}.optional(){{/if~}}
Expand All @@ -32,7 +32,7 @@
{{#if discriminator}}
z.discriminatedUnion('{{discriminator.propertyName}}', [
{{else}}
z.union([
z.union([
{{/if}}
{{~#each anyOf~}}
{{~> zod_schema_item ~}},
Expand All @@ -46,7 +46,7 @@
{{#if discriminator}}
z.discriminatedUnion('{{discriminator.propertyName}}', [
{{else}}
z.union([
z.union([
{{/if}}
{{~#each oneOf~}}
{{~> zod_schema_item ~}},
Expand Down Expand Up @@ -86,8 +86,8 @@ z.unknown()
z.object({
{{#each properties}}
{{#if description}}
/**
* {{{description}}}
/**
* {{{description}}}
*/
{{/if}}
'{{@key}}':{{~> zod_schema_item requiredBool=(includes ../required @key)~}},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,11 +294,11 @@ export const FindAttackDiscoveryAlertsParams = z.object({

export type AttackDiscoveryGenerationConfig = z.infer<typeof AttackDiscoveryGenerationConfig>;
export const AttackDiscoveryGenerationConfig = z.object({
/**
/**
* The (space specific) index pattern that contains the alerts to use as
context for the attack discovery.
Example: .alerts-security.alerts-default

*/
alertsIndexPattern: z.string(),
/**
Expand All @@ -311,7 +311,7 @@ Example: .alerts-security.alerts-default
apiConfig: ApiConfig,
connectorName: z.string().optional(),
end: z.string().optional(),
/**
/**
* An Elasticsearch-style query DSL object used to filter alerts. For example:
```json {
"filter": {
Expand All @@ -335,7 +335,7 @@ Example: .alerts-security.alerts-default
"must_not": []
}
}
} ```
} ```
*/
filter: z.object({}).catchall(z.unknown()).optional(),
langSmithProject: z.string().optional(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ export const FindEndpointListItemsFilter = NonEmptyString;

export type FindEndpointListItemsRequestQuery = z.infer<typeof FindEndpointListItemsRequestQuery>;
export const FindEndpointListItemsRequestQuery = z.object({
/**
/**
* Filters the returned results according to the value of the specified field,
using the `<field name>:<field value>` syntax.

*/
filter: FindEndpointListItemsFilter.optional(),
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ export const FindExceptionListItemsRequestQuery = z.object({
* The `list_id`s of the items to fetch.
*/
list_id: ArrayFromString(ExceptionListHumanId),
/**
/**
* Filters the returned results according to the value of the specified field,
using the `<field name>:<field value>` syntax.

*/
filter: ArrayFromString(FindExceptionListItemsFilter).optional().default([]),
/**
/**
* Determines whether the returned containers are Kibana associated with a Kibana space
or available in all spaces (`agnostic` or `single`)

*/
namespace_type: ArrayFromString(ExceptionNamespaceType).optional().default(['single']),
search: z.string().optional(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ export const FindExceptionListsFilter = z.string();

export type FindExceptionListsRequestQuery = z.infer<typeof FindExceptionListsRequestQuery>;
export const FindExceptionListsRequestQuery = z.object({
/**
/**
* Filters the returned results according to the value of the specified field.

Uses the `so type.field name:field` value syntax, where `so type` can be:

- `exception-list`: Specify a space-aware exception list.
- `exception-list-agnostic`: Specify an exception list that is shared across spaces.

*/
filter: FindExceptionListsFilter.optional(),
/**
/**
* Determines whether the returned containers are Kibana associated with a Kibana space
or available in all spaces (`agnostic` or `single`)

*/
namespace_type: ArrayFromString(ExceptionNamespaceType).optional().default(['single']),
/**
Expand Down
Loading
Loading