mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-04 13:48:56 +02: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 { strategySchema } from './spec/strategy-schema';
|
||||||
import { strategiesSchema } from './spec/strategies-schema';
|
import { strategiesSchema } from './spec/strategies-schema';
|
||||||
import { upsertStrategySchema } from './spec/upsert-strategy-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 { clientApplicationSchema } from './spec/client-application-schema';
|
||||||
import { IServerOption } from '../types';
|
import { IServerOption } from '../types';
|
||||||
import { URL } from 'url';
|
import { URL } from 'url';
|
||||||
@ -109,9 +112,12 @@ export const schemas = {
|
|||||||
emailSchema,
|
emailSchema,
|
||||||
environmentSchema,
|
environmentSchema,
|
||||||
environmentsSchema,
|
environmentsSchema,
|
||||||
|
eventSchema,
|
||||||
|
eventsSchema,
|
||||||
exportParametersSchema,
|
exportParametersSchema,
|
||||||
featureEnvironmentSchema,
|
featureEnvironmentSchema,
|
||||||
featureEnvironmentMetricsSchema,
|
featureEnvironmentMetricsSchema,
|
||||||
|
featureEventsSchema,
|
||||||
featureSchema,
|
featureSchema,
|
||||||
featureMetricsSchema,
|
featureMetricsSchema,
|
||||||
featureUsageSchema,
|
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 { IUnleashConfig } from '../../types/option';
|
||||||
import { IUnleashServices } from '../../types/services';
|
import { IUnleashServices } from '../../types/services';
|
||||||
import EventService from '../../services/event-service';
|
import EventService from '../../services/event-service';
|
||||||
import { ADMIN } from '../../types/permissions';
|
import { ADMIN, NONE } from '../../types/permissions';
|
||||||
import { IEvent } from '../../types/events';
|
import { IEvent } from '../../types/events';
|
||||||
import Controller from '../controller';
|
import Controller from '../controller';
|
||||||
import { anonymise } from '../../util/anonymise';
|
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;
|
const version = 1;
|
||||||
export default class EventController extends Controller {
|
export default class EventController extends Controller {
|
||||||
@ -13,15 +26,66 @@ export default class EventController extends Controller {
|
|||||||
|
|
||||||
private anonymise: boolean = false;
|
private anonymise: boolean = false;
|
||||||
|
|
||||||
|
private openApiService: OpenApiService;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: IUnleashConfig,
|
config: IUnleashConfig,
|
||||||
{ eventService }: Pick<IUnleashServices, 'eventService'>,
|
{
|
||||||
|
eventService,
|
||||||
|
openApiService,
|
||||||
|
}: Pick<IUnleashServices, 'eventService' | 'openApiService'>,
|
||||||
) {
|
) {
|
||||||
super(config);
|
super(config);
|
||||||
this.eventService = eventService;
|
this.eventService = eventService;
|
||||||
this.anonymise = config.experimental?.anonymiseEventLog;
|
this.anonymise = config.experimental?.anonymiseEventLog;
|
||||||
this.get('/', this.getEvents, ADMIN);
|
this.openApiService = openApiService;
|
||||||
this.get('/:name', this.getEventsForToggle);
|
|
||||||
|
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[] {
|
fixEvents(events: IEvent[]): IEvent[] {
|
||||||
@ -36,7 +100,7 @@ export default class EventController extends Controller {
|
|||||||
|
|
||||||
async getEvents(
|
async getEvents(
|
||||||
req: Request<any, any, any, { project?: string }>,
|
req: Request<any, any, any, { project?: string }>,
|
||||||
res: Response,
|
res: Response<EventsSchema>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { project } = req.query;
|
const { project } = req.query;
|
||||||
let events: IEvent[];
|
let events: IEvent[];
|
||||||
@ -45,23 +109,37 @@ export default class EventController extends Controller {
|
|||||||
} else {
|
} else {
|
||||||
events = await this.eventService.getEvents();
|
events = await this.eventService.getEvents();
|
||||||
}
|
}
|
||||||
res.json({
|
|
||||||
|
const response: EventsSchema = {
|
||||||
version,
|
version,
|
||||||
events: this.fixEvents(events),
|
events: serializeDates(this.fixEvents(events)),
|
||||||
});
|
};
|
||||||
|
this.openApiService.respondWithValidation(
|
||||||
|
200,
|
||||||
|
res,
|
||||||
|
eventsSchema.$id,
|
||||||
|
response,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getEventsForToggle(
|
async getEventsForToggle(
|
||||||
req: Request<{ name: string }>,
|
req: Request<{ featureName: string }>,
|
||||||
res: Response,
|
res: Response<FeatureEventsSchema>,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const toggleName = req.params.name;
|
const toggleName = req.params.featureName;
|
||||||
const events = await this.eventService.getEventsForToggle(toggleName);
|
const events = await this.eventService.getEventsForToggle(toggleName);
|
||||||
|
|
||||||
res.json({
|
const response = {
|
||||||
version,
|
version,
|
||||||
toggleName,
|
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",
|
"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 {
|
"exportParametersSchema": Object {
|
||||||
"properties": Object {
|
"properties": Object {
|
||||||
"download": Object {
|
"download": Object {
|
||||||
@ -743,6 +816,28 @@ Object {
|
|||||||
],
|
],
|
||||||
"type": "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 {
|
"featureMetricsSchema": Object {
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"properties": Object {
|
"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 {
|
"/api/admin/feature-types": Object {
|
||||||
"get": Object {
|
"get": Object {
|
||||||
"operationId": "getAllFeatureTypes",
|
"operationId": "getAllFeatureTypes",
|
||||||
|
Loading…
Reference in New Issue
Block a user