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

[OAS] Include alerting rule APIs #189962

Merged
merged 11 commits into from
Aug 13, 2024
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,699 changes: 4,698 additions & 1 deletion oas_docs/bundle.json

Large diffs are not rendered by default.

4,699 changes: 4,698 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