mirror of
https://github.com/Unleash/unleash.git
synced 2025-01-25 00:07:47 +01:00
feat: add OpenAPI spec to events controller. (#1754)
* Feat: add initial event schema * Feat: add events-schema plus tests * Feat(broken): add openapi validation to getEvents endpoint * Add schema to basic events endpoint * Feat: Add openapi for feature events * Fix: fix recursive schema inclusion * Feat: add test for recursive function * Fix: make nullable fields nullable * Fix: remove `ADMIN` permission for toggle events. * fix: add new schemas to the snapshot * Fix: remove recursive schema inclusion * Feat: test feature events schema * Fix: add correct permissions for feature events endpoint. * Refactor: rename "name" to "featureName" for clearer docs * Fix: Add missing "version" field to feature events * Feat: add descriptions and extra responses to events endpoints. * Fix: update openapi snapshot * Simplify standard responses function * Refactor: move endpoint descriptions into own file. * Refactor: simplify type signature. * Feat: specify type of data and preData properties to object * Fix: update snapshot * Refactor: move standard-responses into /util/ directory.
This commit is contained in:
parent
7816d8a1f9
commit
4dec126199
15
src/lib/openapi/endpoint-descriptions.ts
Normal file
15
src/lib/openapi/endpoint-descriptions.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export const endpointDescriptions = {
|
||||
admin: {
|
||||
events: {
|
||||
description:
|
||||
'Returns **the last 100** from the Unleash instance when called without a query parameter. When called with a `project` parameter, returns **all events** for the specified project.\n\nIf the provided project does not exist, the list of events will be empty.',
|
||||
summary:
|
||||
'Get the most recent events from the Unleash instance or all events related to a project.',
|
||||
},
|
||||
eventsPerFeature: {
|
||||
description:
|
||||
'Returns all events related to the specified feature toggle. If the feature toggle does not exist, the list of events will be empty.',
|
||||
summary: 'Get all events related to a specific feature toggle.',
|
||||
},
|
||||
},
|
||||
} as const;
|
@ -82,6 +82,9 @@ import { emailSchema } from './spec/email-schema';
|
||||
import { strategySchema } from './spec/strategy-schema';
|
||||
import { strategiesSchema } from './spec/strategies-schema';
|
||||
import { upsertStrategySchema } from './spec/upsert-strategy-schema';
|
||||
import { eventSchema } from './spec/event-schema';
|
||||
import { eventsSchema } from './spec/events-schema';
|
||||
import { featureEventsSchema } from './spec/feature-events-schema';
|
||||
import { clientApplicationSchema } from './spec/client-application-schema';
|
||||
import { IServerOption } from '../types';
|
||||
import { URL } from 'url';
|
||||
@ -109,9 +112,12 @@ export const schemas = {
|
||||
emailSchema,
|
||||
environmentSchema,
|
||||
environmentsSchema,
|
||||
eventSchema,
|
||||
eventsSchema,
|
||||
exportParametersSchema,
|
||||
featureEnvironmentSchema,
|
||||
featureEnvironmentMetricsSchema,
|
||||
featureEventsSchema,
|
||||
featureSchema,
|
||||
featureMetricsSchema,
|
||||
featureUsageSchema,
|
||||
|
31
src/lib/openapi/spec/event-schema.test.ts
Normal file
31
src/lib/openapi/spec/event-schema.test.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { validateSchema } from '../validate';
|
||||
import { EventSchema } from './event-schema';
|
||||
|
||||
test('eventSchema', () => {
|
||||
const data: EventSchema = {
|
||||
id: 899,
|
||||
type: 'feature-created',
|
||||
createdBy: 'user@company.com',
|
||||
createdAt: '2022-05-31T13:32:20.560Z',
|
||||
data: {
|
||||
name: 'new-feature',
|
||||
description: 'Toggle description',
|
||||
type: 'release',
|
||||
project: 'my-project',
|
||||
stale: false,
|
||||
variants: [],
|
||||
createdAt: '2022-05-31T13:32:20.547Z',
|
||||
lastSeenAt: null,
|
||||
impressionData: true,
|
||||
},
|
||||
preData: null,
|
||||
tags: [{ type: 'simple', value: 'my-val' }],
|
||||
featureName: 'new-feature',
|
||||
project: 'my-project',
|
||||
environment: null,
|
||||
};
|
||||
|
||||
expect(
|
||||
validateSchema('#/components/schemas/eventSchema', data),
|
||||
).toBeUndefined();
|
||||
});
|
53
src/lib/openapi/spec/event-schema.ts
Normal file
53
src/lib/openapi/spec/event-schema.ts
Normal file
@ -0,0 +1,53 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
import { tagSchema } from './tag-schema';
|
||||
|
||||
export const eventSchema = {
|
||||
$id: '#/components/schemas/eventSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['id', 'createdAt', 'type', 'createdBy'],
|
||||
properties: {
|
||||
id: {
|
||||
type: 'integer',
|
||||
minimum: 1,
|
||||
},
|
||||
createdAt: {
|
||||
type: 'string',
|
||||
format: 'date-time',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
},
|
||||
createdBy: {
|
||||
type: 'string',
|
||||
},
|
||||
environment: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
},
|
||||
project: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
},
|
||||
featureName: {
|
||||
type: 'string',
|
||||
nullable: true,
|
||||
},
|
||||
data: { type: 'object', nullable: true },
|
||||
preData: { type: 'object', nullable: true },
|
||||
tags: {
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: tagSchema.$id,
|
||||
},
|
||||
nullable: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
schemas: {
|
||||
tagSchema,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type EventSchema = FromSchema<typeof eventSchema>;
|
77
src/lib/openapi/spec/events-schema.test.ts
Normal file
77
src/lib/openapi/spec/events-schema.test.ts
Normal file
@ -0,0 +1,77 @@
|
||||
import { validateSchema } from '../validate';
|
||||
import { EventsSchema } from './events-schema';
|
||||
|
||||
test('eventsSchema', () => {
|
||||
const data: EventsSchema = {
|
||||
version: 1,
|
||||
events: [
|
||||
{
|
||||
id: 899,
|
||||
type: 'feature-created',
|
||||
createdBy: 'user@company.com',
|
||||
createdAt: '2022-05-31T13:32:20.560Z',
|
||||
data: {
|
||||
name: 'new-feature',
|
||||
description: 'Toggle description',
|
||||
type: 'release',
|
||||
project: 'my-project',
|
||||
stale: false,
|
||||
variants: [],
|
||||
createdAt: '2022-05-31T13:32:20.547Z',
|
||||
lastSeenAt: null,
|
||||
impressionData: true,
|
||||
},
|
||||
preData: null,
|
||||
tags: [],
|
||||
featureName: 'new-feature',
|
||||
project: 'my-project',
|
||||
environment: null,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(
|
||||
validateSchema('#/components/schemas/eventsSchema', data),
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
test('eventsSchema types', () => {
|
||||
const data: EventsSchema = {
|
||||
version: 1,
|
||||
events: [
|
||||
{
|
||||
// @ts-expect-error
|
||||
id: '1',
|
||||
type: 'feature-created',
|
||||
createdBy: 'user@company.com',
|
||||
createdAt: '2022-05-31T13:32:20.560Z',
|
||||
data: {
|
||||
name: 'new-feature',
|
||||
description: 'Toggle description',
|
||||
type: 'release',
|
||||
project: 'my-project',
|
||||
stale: false,
|
||||
variants: [],
|
||||
createdAt: '2022-05-31T13:32:20.547Z',
|
||||
lastSeenAt: null,
|
||||
impressionData: true,
|
||||
},
|
||||
preData: null,
|
||||
tags: [
|
||||
{
|
||||
type: '',
|
||||
// @ts-expect-error
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
featureName: 'new-feature',
|
||||
project: 'my-project',
|
||||
environment: null,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(
|
||||
validateSchema('#/components/schemas/eventsSchema', data),
|
||||
).not.toBeUndefined();
|
||||
});
|
28
src/lib/openapi/spec/events-schema.ts
Normal file
28
src/lib/openapi/spec/events-schema.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
import { eventSchema } from './event-schema';
|
||||
import { tagSchema } from './tag-schema';
|
||||
|
||||
export const eventsSchema = {
|
||||
$id: '#/components/schemas/eventsSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['version', 'events'],
|
||||
properties: {
|
||||
version: {
|
||||
type: 'integer',
|
||||
minimum: 1,
|
||||
},
|
||||
events: {
|
||||
type: 'array',
|
||||
items: { $ref: eventSchema.$id },
|
||||
},
|
||||
},
|
||||
components: {
|
||||
schemas: {
|
||||
eventSchema,
|
||||
tagSchema,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type EventsSchema = FromSchema<typeof eventsSchema>;
|
76
src/lib/openapi/spec/feature-events-schema.test.ts
Normal file
76
src/lib/openapi/spec/feature-events-schema.test.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { validateSchema } from '../validate';
|
||||
import {
|
||||
FeatureEventsSchema,
|
||||
featureEventsSchema,
|
||||
} from './feature-events-schema';
|
||||
|
||||
test('featureEventsSchema', () => {
|
||||
const data: FeatureEventsSchema = {
|
||||
toggleName: 'my-feature',
|
||||
events: [
|
||||
{
|
||||
id: 899,
|
||||
type: 'feature-created',
|
||||
createdBy: 'user@company.com',
|
||||
createdAt: '2022-05-31T13:32:20.560Z',
|
||||
data: {
|
||||
name: 'new-feature',
|
||||
description: 'Toggle description',
|
||||
type: 'release',
|
||||
project: 'my-project',
|
||||
stale: false,
|
||||
variants: [],
|
||||
createdAt: '2022-05-31T13:32:20.547Z',
|
||||
lastSeenAt: null,
|
||||
impressionData: true,
|
||||
},
|
||||
preData: null,
|
||||
tags: [],
|
||||
featureName: 'new-feature',
|
||||
project: 'my-project',
|
||||
environment: null,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(validateSchema(featureEventsSchema.$id, data)).toBeUndefined();
|
||||
});
|
||||
|
||||
test('featureEventsSchema types', () => {
|
||||
const data: FeatureEventsSchema = {
|
||||
toggleName: 'my-feature',
|
||||
events: [
|
||||
{
|
||||
// @ts-expect-error
|
||||
id: '1',
|
||||
type: 'feature-created',
|
||||
createdBy: 'user@company.com',
|
||||
createdAt: '2022-05-31T13:32:20.560Z',
|
||||
data: {
|
||||
name: 'new-feature',
|
||||
description: 'Toggle description',
|
||||
type: 'release',
|
||||
project: 'my-project',
|
||||
stale: false,
|
||||
variants: [],
|
||||
createdAt: '2022-05-31T13:32:20.547Z',
|
||||
lastSeenAt: null,
|
||||
impressionData: true,
|
||||
},
|
||||
preData: null,
|
||||
tags: [
|
||||
{
|
||||
type: '',
|
||||
// @ts-expect-error
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
featureName: 'new-feature',
|
||||
project: 'my-project',
|
||||
environment: null,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(validateSchema(featureEventsSchema.$id, data)).not.toBeUndefined();
|
||||
});
|
28
src/lib/openapi/spec/feature-events-schema.ts
Normal file
28
src/lib/openapi/spec/feature-events-schema.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { FromSchema } from 'json-schema-to-ts';
|
||||
import { eventSchema } from './event-schema';
|
||||
import { tagSchema } from './tag-schema';
|
||||
|
||||
export const featureEventsSchema = {
|
||||
$id: '#/components/schemas/featureEventsSchema',
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
required: ['toggleName', 'events'],
|
||||
properties: {
|
||||
version: { type: 'number' },
|
||||
toggleName: {
|
||||
type: 'string',
|
||||
},
|
||||
events: {
|
||||
type: 'array',
|
||||
items: { $ref: eventSchema.$id },
|
||||
},
|
||||
},
|
||||
components: {
|
||||
schemas: {
|
||||
eventSchema,
|
||||
tagSchema,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type FeatureEventsSchema = FromSchema<typeof featureEventsSchema>;
|
21
src/lib/openapi/util/standard-responses.ts
Normal file
21
src/lib/openapi/util/standard-responses.ts
Normal file
@ -0,0 +1,21 @@
|
||||
export const unauthorizedResponse = {
|
||||
description:
|
||||
'Authorization information is missing or invalid. Provide a valid API token as the `authorization` header, e.g. `authorization:*.*.my-admin-token`.',
|
||||
} as const;
|
||||
|
||||
const standardResponses = {
|
||||
401: unauthorizedResponse,
|
||||
} as const;
|
||||
|
||||
type StandardResponses = typeof standardResponses;
|
||||
|
||||
export const getStandardResponses = (
|
||||
...statusCodes: (keyof StandardResponses)[]
|
||||
): Partial<StandardResponses> =>
|
||||
statusCodes.reduce(
|
||||
(acc, n) => ({
|
||||
...acc,
|
||||
[n]: standardResponses[n],
|
||||
}),
|
||||
{} as Partial<StandardResponses>,
|
||||
);
|
@ -2,10 +2,23 @@ import { Request, Response } from 'express';
|
||||
import { IUnleashConfig } from '../../types/option';
|
||||
import { IUnleashServices } from '../../types/services';
|
||||
import EventService from '../../services/event-service';
|
||||
import { ADMIN } from '../../types/permissions';
|
||||
import { ADMIN, NONE } from '../../types/permissions';
|
||||
import { IEvent } from '../../types/events';
|
||||
import Controller from '../controller';
|
||||
import { anonymise } from '../../util/anonymise';
|
||||
import { OpenApiService } from '../../services/openapi-service';
|
||||
import { createResponseSchema } from '../../../lib/openapi';
|
||||
import { endpointDescriptions } from '../../../lib/openapi/endpoint-descriptions';
|
||||
import {
|
||||
eventsSchema,
|
||||
EventsSchema,
|
||||
} from '../../../lib/openapi/spec/events-schema';
|
||||
import { serializeDates } from '../../../lib/types/serialize-dates';
|
||||
import {
|
||||
featureEventsSchema,
|
||||
FeatureEventsSchema,
|
||||
} from '../../../lib/openapi/spec/feature-events-schema';
|
||||
import { getStandardResponses } from '../../../lib/openapi/util/standard-responses';
|
||||
|
||||
const version = 1;
|
||||
export default class EventController extends Controller {
|
||||
@ -13,15 +26,66 @@ export default class EventController extends Controller {
|
||||
|
||||
private anonymise: boolean = false;
|
||||
|
||||
private openApiService: OpenApiService;
|
||||
|
||||
constructor(
|
||||
config: IUnleashConfig,
|
||||
{ eventService }: Pick<IUnleashServices, 'eventService'>,
|
||||
{
|
||||
eventService,
|
||||
openApiService,
|
||||
}: Pick<IUnleashServices, 'eventService' | 'openApiService'>,
|
||||
) {
|
||||
super(config);
|
||||
this.eventService = eventService;
|
||||
this.anonymise = config.experimental?.anonymiseEventLog;
|
||||
this.get('/', this.getEvents, ADMIN);
|
||||
this.get('/:name', this.getEventsForToggle);
|
||||
this.openApiService = openApiService;
|
||||
|
||||
this.route({
|
||||
method: 'get',
|
||||
path: '',
|
||||
handler: this.getEvents,
|
||||
permission: ADMIN,
|
||||
middleware: [
|
||||
openApiService.validPath({
|
||||
operationId: 'getEvents',
|
||||
tags: ['admin'],
|
||||
responses: {
|
||||
...getStandardResponses(401),
|
||||
200: createResponseSchema('eventsSchema'),
|
||||
},
|
||||
|
||||
parameters: [
|
||||
{
|
||||
name: 'project',
|
||||
description:
|
||||
'The name of the project whose events you want to retrieve',
|
||||
schema: { type: 'string' },
|
||||
in: 'query',
|
||||
},
|
||||
],
|
||||
|
||||
...endpointDescriptions.admin.events,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
this.route({
|
||||
method: 'get',
|
||||
path: '/:featureName',
|
||||
handler: this.getEventsForToggle,
|
||||
permission: NONE,
|
||||
middleware: [
|
||||
openApiService.validPath({
|
||||
operationId: 'getEventsForToggle',
|
||||
tags: ['admin'],
|
||||
responses: {
|
||||
...getStandardResponses(401),
|
||||
200: createResponseSchema('featureEventsSchema'),
|
||||
},
|
||||
...endpointDescriptions.admin.eventsPerFeature,
|
||||
}),
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
fixEvents(events: IEvent[]): IEvent[] {
|
||||
@ -36,7 +100,7 @@ export default class EventController extends Controller {
|
||||
|
||||
async getEvents(
|
||||
req: Request<any, any, any, { project?: string }>,
|
||||
res: Response,
|
||||
res: Response<EventsSchema>,
|
||||
): Promise<void> {
|
||||
const { project } = req.query;
|
||||
let events: IEvent[];
|
||||
@ -45,23 +109,37 @@ export default class EventController extends Controller {
|
||||
} else {
|
||||
events = await this.eventService.getEvents();
|
||||
}
|
||||
res.json({
|
||||
|
||||
const response: EventsSchema = {
|
||||
version,
|
||||
events: this.fixEvents(events),
|
||||
});
|
||||
events: serializeDates(this.fixEvents(events)),
|
||||
};
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
eventsSchema.$id,
|
||||
response,
|
||||
);
|
||||
}
|
||||
|
||||
async getEventsForToggle(
|
||||
req: Request<{ name: string }>,
|
||||
res: Response,
|
||||
req: Request<{ featureName: string }>,
|
||||
res: Response<FeatureEventsSchema>,
|
||||
): Promise<void> {
|
||||
const toggleName = req.params.name;
|
||||
const toggleName = req.params.featureName;
|
||||
const events = await this.eventService.getEventsForToggle(toggleName);
|
||||
|
||||
res.json({
|
||||
const response = {
|
||||
version,
|
||||
toggleName,
|
||||
events: this.fixEvents(events),
|
||||
});
|
||||
events: serializeDates(this.fixEvents(events)),
|
||||
};
|
||||
|
||||
this.openApiService.respondWithValidation(
|
||||
200,
|
||||
res,
|
||||
featureEventsSchema.$id,
|
||||
response,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -615,6 +615,79 @@ Object {
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"eventSchema": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
"createdAt": Object {
|
||||
"format": "date-time",
|
||||
"type": "string",
|
||||
},
|
||||
"createdBy": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"data": Object {
|
||||
"nullable": true,
|
||||
"type": "object",
|
||||
},
|
||||
"environment": Object {
|
||||
"nullable": true,
|
||||
"type": "string",
|
||||
},
|
||||
"featureName": Object {
|
||||
"nullable": true,
|
||||
"type": "string",
|
||||
},
|
||||
"id": Object {
|
||||
"minimum": 1,
|
||||
"type": "integer",
|
||||
},
|
||||
"preData": Object {
|
||||
"nullable": true,
|
||||
"type": "object",
|
||||
},
|
||||
"project": Object {
|
||||
"nullable": true,
|
||||
"type": "string",
|
||||
},
|
||||
"tags": Object {
|
||||
"items": Object {
|
||||
"$ref": "#/components/schemas/tagSchema",
|
||||
},
|
||||
"nullable": true,
|
||||
"type": "array",
|
||||
},
|
||||
"type": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
"required": Array [
|
||||
"id",
|
||||
"createdAt",
|
||||
"type",
|
||||
"createdBy",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"eventsSchema": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
"events": Object {
|
||||
"items": Object {
|
||||
"$ref": "#/components/schemas/eventSchema",
|
||||
},
|
||||
"type": "array",
|
||||
},
|
||||
"version": Object {
|
||||
"minimum": 1,
|
||||
"type": "integer",
|
||||
},
|
||||
},
|
||||
"required": Array [
|
||||
"version",
|
||||
"events",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"exportParametersSchema": Object {
|
||||
"properties": Object {
|
||||
"download": Object {
|
||||
@ -743,6 +816,28 @@ Object {
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"featureEventsSchema": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
"events": Object {
|
||||
"items": Object {
|
||||
"$ref": "#/components/schemas/eventSchema",
|
||||
},
|
||||
"type": "array",
|
||||
},
|
||||
"toggleName": Object {
|
||||
"type": "string",
|
||||
},
|
||||
"version": Object {
|
||||
"type": "number",
|
||||
},
|
||||
},
|
||||
"required": Array [
|
||||
"toggleName",
|
||||
"events",
|
||||
],
|
||||
"type": "object",
|
||||
},
|
||||
"featureMetricsSchema": Object {
|
||||
"additionalProperties": false,
|
||||
"properties": Object {
|
||||
@ -2873,6 +2968,78 @@ Object {
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/events": Object {
|
||||
"get": Object {
|
||||
"description": "Returns **the last 100** from the Unleash instance when called without a query parameter. When called with a \`project\` parameter, returns **all events** for the specified project.
|
||||
|
||||
If the provided project does not exist, the list of events will be empty.",
|
||||
"operationId": "getEvents",
|
||||
"parameters": Array [
|
||||
Object {
|
||||
"description": "The name of the project whose events you want to retrieve",
|
||||
"in": "query",
|
||||
"name": "project",
|
||||
"schema": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": Object {
|
||||
"200": Object {
|
||||
"content": Object {
|
||||
"application/json": Object {
|
||||
"schema": Object {
|
||||
"$ref": "#/components/schemas/eventsSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "eventsSchema",
|
||||
},
|
||||
"401": Object {
|
||||
"description": "Authorization information is missing or invalid. Provide a valid API token as the \`authorization\` header, e.g. \`authorization:*.*.my-admin-token\`.",
|
||||
},
|
||||
},
|
||||
"summary": "Get the most recent events from the Unleash instance or all events related to a project.",
|
||||
"tags": Array [
|
||||
"admin",
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/events/{featureName}": Object {
|
||||
"get": Object {
|
||||
"description": "Returns all events related to the specified feature toggle. If the feature toggle does not exist, the list of events will be empty.",
|
||||
"operationId": "getEventsForToggle",
|
||||
"parameters": Array [
|
||||
Object {
|
||||
"in": "path",
|
||||
"name": "featureName",
|
||||
"required": true,
|
||||
"schema": Object {
|
||||
"type": "string",
|
||||
},
|
||||
},
|
||||
],
|
||||
"responses": Object {
|
||||
"200": Object {
|
||||
"content": Object {
|
||||
"application/json": Object {
|
||||
"schema": Object {
|
||||
"$ref": "#/components/schemas/featureEventsSchema",
|
||||
},
|
||||
},
|
||||
},
|
||||
"description": "featureEventsSchema",
|
||||
},
|
||||
"401": Object {
|
||||
"description": "Authorization information is missing or invalid. Provide a valid API token as the \`authorization\` header, e.g. \`authorization:*.*.my-admin-token\`.",
|
||||
},
|
||||
},
|
||||
"summary": "Get all events related to a specific feature toggle.",
|
||||
"tags": Array [
|
||||
"admin",
|
||||
],
|
||||
},
|
||||
},
|
||||
"/api/admin/feature-types": Object {
|
||||
"get": Object {
|
||||
"operationId": "getAllFeatureTypes",
|
||||
|
Loading…
Reference in New Issue
Block a user