Skip to content

Commit

Permalink
[OAS] Include alerting rule APIs (#189962)
Browse files Browse the repository at this point in the history
## Summary

Includes alerting rule APIs in our OAS snapshots.

## How to test

Using bump CLI you can preview the output:

```sh
bump preview ./oas_docs/bundle.json
# or
bump preview ./oas_docs/bundle.serverless.json
```

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
jloleysens and kibanamachine authored Aug 13, 2024
1 parent 7fb1577 commit b85b1cb
Show file tree
Hide file tree
Showing 11 changed files with 9,535 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .buildkite/scripts/steps/capture_oas_snapshot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ set -euo pipefail
source .buildkite/scripts/common/util.sh

echo --- Capture OAS snapshot
cmd="node scripts/capture_oas_snapshot --include-path /api/status"
cmd="node scripts/capture_oas_snapshot --include-path /api/status --include-path /api/alerting/rule/ --include-path /api/alerting/rules"
if is_pr && ! is_auto_commit_disabled; then
cmd="$cmd --update"
fi
Expand Down
4,709 changes: 4,708 additions & 1 deletion oas_docs/bundle.json

Large diffs are not rendered by default.

4,709 changes: 4,708 additions & 1 deletion oas_docs/bundle.serverless.json

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const sharedOas = {
'/bar': {
get: {
deprecated: true,
operationId: '/bar#0',
operationId: '%2Fbar#0',
parameters: [
{
description: 'The version of the API to use',
Expand Down Expand Up @@ -152,7 +152,7 @@ export const sharedOas = {
'/foo/{id}/{path*}': {
get: {
description: 'route description',
operationId: '/foo/{id}/{path*}#0',
operationId: '%2Ffoo%2F%7Bid%7D%2F%7Bpath*%7D#0',
parameters: [
{
description: 'The version of the API to use',
Expand Down Expand Up @@ -276,7 +276,7 @@ export const sharedOas = {
},
post: {
description: 'route description',
operationId: '/foo/{id}/{path*}#1',
operationId: '%2Ffoo%2F%7Bid%7D%2F%7Bpath*%7D#1',
parameters: [
{
description: 'The version of the API to use',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,39 @@ describe('processEnum', () => {
],
},
},
{
name: 'correctly transforms schema.nullable inputs',
input: {
anyOf: [
{
description: 'test',
type: 'object',
properties: {
test: {
type: 'string',
},
},
required: ['test'],
},
{
enum: [],
nullable: true,
type: undefined,
},
],
} as OpenAPIV3.SchemaObject,
expected: {
description: 'test',
type: 'object',
properties: {
test: {
type: 'string',
},
},
required: ['test'],
nullable: true,
},
},
])('$name', ({ input, expected }) => {
processEnum(input);
expect(input).toEqual(expected);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,38 @@
import type { OpenAPIV3 } from 'openapi-types';
import { isReferenceObject } from '../../../common';

export const processEnum = (schema: OpenAPIV3.SchemaObject) => {
if (!schema.anyOf) return;
/** Identify special case output of schema.nullable() */
const isNullableOutput = (schema: OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject) => {
return (
!isReferenceObject(schema) &&
Object.keys(schema).length === 3 &&
schema.enum?.length === 0 &&
schema.nullable === true &&
schema.type === undefined
);
};

/**
* Handle special case output of schema.nullable()
*
* We go from:
* { anyOf: [ { type: 'string' }, { nullable: true, enum: [] } ] }
*
* To:
* { type: 'string', nullable: true }
*/
const processNullableOutput = (schema: OpenAPIV3.SchemaObject) => {
if (schema.anyOf!.length !== 2) return false;
const idx = schema.anyOf!.findIndex((item) => isNullableOutput(item));
if (idx === -1) return false;
const anyOf = schema.anyOf!;
delete schema.anyOf;
schema.nullable = true;
Object.assign(schema, anyOf[1 - idx]);
return true;
};

const prettifyEnum = (schema: OpenAPIV3.SchemaObject) => {
const result: unknown[] = [];
let type: OpenAPIV3.SchemaObject['type'];
for (const item of schema.anyOf!) {
Expand All @@ -24,3 +54,9 @@ export const processEnum = (schema: OpenAPIV3.SchemaObject) => {
schema.enum = result;
delete schema.anyOf;
};

export const processEnum = (schema: OpenAPIV3.SchemaObject) => {
if (!schema.anyOf) return;
if (processNullableOutput(schema)) return;
prettifyEnum(schema);
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,10 @@ import { joi2JsonInternal } from '../../parse';
import { processObject } from './object';

test.each([
[
schema.object({}),
{ type: 'object', properties: {}, additionalProperties: false, required: [] },
],
[schema.object({}), { type: 'object', properties: {}, additionalProperties: false }],
[
schema.object({ never: schema.never() }),
{ type: 'object', properties: {}, additionalProperties: false, required: [] },
{ type: 'object', properties: {}, additionalProperties: false },
],
[
schema.object(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const populateRequiredFields = (schema: OpenAPIV3.SchemaObject): void => {
}
}

schema.required = required;
if (required.length > 0) schema.required = required;
};

const removeNeverType = (schema: OpenAPIV3.SchemaObject): void => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 { createOperationIdCounter } from './operation_id_counter';

test('empty case', () => {
const opIdCounter = createOperationIdCounter();
expect(opIdCounter('')).toBe('#0');
});

test('other cases', () => {
const opIdCounter = createOperationIdCounter();
const tests = [
['/', '%2F#0'],
['/api/cool', '%2Fapi%2Fcool#0'],
['/api/cool', '%2Fapi%2Fcool#1'],
['/api/cool', '%2Fapi%2Fcool#2'],
['/api/cool/{variable}', '%2Fapi%2Fcool%2F%7Bvariable%7D#0'],
['/api/cool/{optionalVariable?}', '%2Fapi%2Fcool%2F%7BoptionalVariable%3F%7D#0'],
['/api/cool/{optionalVariable?}', '%2Fapi%2Fcool%2F%7BoptionalVariable%3F%7D#1'],
];

tests.forEach(([input, expected]) => {
expect(opIdCounter(input)).toBe(expected);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export type OperationIdCounter = (name: string) => string;
export const createOperationIdCounter = () => {
const operationIdCounters = new Map<string, number>();
return (name: string): string => {
name = encodeURIComponent(name);
// Aliases an operationId to ensure it is unique across
// multiple method+path combinations sharing a name.
// "search" -> "search#0", "search#1", etc.
Expand Down

0 comments on commit b85b1cb

Please sign in to comment.