mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-24 01:18:01 +02:00
docs: Events tag (#4152)
### What This PR adds documentation for our endpoints that are covered by our "Events" tag. It also adds a type for all valid events, and then uses this as valid values for type argument.
This commit is contained in:
parent
51ffe02cfd
commit
b04545c25f
@ -1,4 +1,9 @@
|
|||||||
import { IEvent, IBaseEvent, SEGMENT_UPDATED } from '../types/events';
|
import {
|
||||||
|
IEvent,
|
||||||
|
IBaseEvent,
|
||||||
|
SEGMENT_UPDATED,
|
||||||
|
IEventType,
|
||||||
|
} from '../types/events';
|
||||||
import { LogProvider, Logger } from '../logger';
|
import { LogProvider, Logger } from '../logger';
|
||||||
import { IEventStore } from '../types/stores/event-store';
|
import { IEventStore } from '../types/stores/event-store';
|
||||||
import { ITag } from '../types/model';
|
import { ITag } from '../types/model';
|
||||||
@ -359,7 +364,7 @@ class EventStore implements IEventStore {
|
|||||||
rowToEvent(row: IEventTable): IEvent {
|
rowToEvent(row: IEventTable): IEvent {
|
||||||
return {
|
return {
|
||||||
id: row.id,
|
id: row.id,
|
||||||
type: row.type,
|
type: row.type as IEventType,
|
||||||
createdBy: row.created_by,
|
createdBy: row.created_by,
|
||||||
createdAt: row.created_at,
|
createdAt: row.created_at,
|
||||||
data: row.data,
|
data: row.data,
|
||||||
|
@ -97,10 +97,7 @@ const metaRules: Rule[] = [
|
|||||||
'createInvitedUserSchema',
|
'createInvitedUserSchema',
|
||||||
'environmentsSchema',
|
'environmentsSchema',
|
||||||
'environmentsProjectSchema',
|
'environmentsProjectSchema',
|
||||||
'eventSchema',
|
|
||||||
'eventsSchema',
|
|
||||||
'featureEnvironmentSchema',
|
'featureEnvironmentSchema',
|
||||||
'featureEventsSchema',
|
|
||||||
'featureSchema',
|
'featureSchema',
|
||||||
'featuresSchema',
|
'featuresSchema',
|
||||||
'featureStrategySegmentSchema',
|
'featureStrategySegmentSchema',
|
||||||
@ -126,7 +123,6 @@ const metaRules: Rule[] = [
|
|||||||
'resetPasswordSchema',
|
'resetPasswordSchema',
|
||||||
'requestsPerSecondSchema',
|
'requestsPerSecondSchema',
|
||||||
'sdkContextSchema',
|
'sdkContextSchema',
|
||||||
'searchEventsSchema',
|
|
||||||
'setUiConfigSchema',
|
'setUiConfigSchema',
|
||||||
'splashSchema',
|
'splashSchema',
|
||||||
'stateSchema',
|
'stateSchema',
|
||||||
@ -169,9 +165,6 @@ const metaRules: Rule[] = [
|
|||||||
'createInvitedUserSchema',
|
'createInvitedUserSchema',
|
||||||
'dateSchema',
|
'dateSchema',
|
||||||
'environmentsSchema',
|
'environmentsSchema',
|
||||||
'eventSchema',
|
|
||||||
'eventsSchema',
|
|
||||||
'featureEventsSchema',
|
|
||||||
'featureSchema',
|
'featureSchema',
|
||||||
'featuresSchema',
|
'featuresSchema',
|
||||||
'featureStrategySegmentSchema',
|
'featureStrategySegmentSchema',
|
||||||
|
@ -1,51 +1,152 @@
|
|||||||
import { FromSchema } from 'json-schema-to-ts';
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
import { tagSchema } from './tag-schema';
|
import { tagSchema } from './tag-schema';
|
||||||
|
import { IEventTypes } from '../../types';
|
||||||
|
import { variantSchema } from './variant-schema';
|
||||||
|
|
||||||
|
const eventDataSchema = {
|
||||||
|
type: 'object',
|
||||||
|
additionalProperties: true,
|
||||||
|
properties: {
|
||||||
|
name: {
|
||||||
|
type: 'string',
|
||||||
|
description:
|
||||||
|
'Name of the feature toggle/strategy/environment that this event relates to',
|
||||||
|
example: 'my.first.toggle',
|
||||||
|
},
|
||||||
|
description: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'The description of the object this event relates to',
|
||||||
|
example: 'Toggle description',
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: 'string',
|
||||||
|
description:
|
||||||
|
'If this event relates to a feature toggle, the type of feature toggle.',
|
||||||
|
example: 'release',
|
||||||
|
},
|
||||||
|
project: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'The project this event relates to',
|
||||||
|
example: 'default',
|
||||||
|
},
|
||||||
|
stale: {
|
||||||
|
description: 'Is the feature toggle this event relates to stale',
|
||||||
|
type: 'boolean',
|
||||||
|
example: true,
|
||||||
|
},
|
||||||
|
variants: {
|
||||||
|
description: 'Variants configured for this toggle',
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
$ref: '#/components/schemas/variantSchema',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date-time',
|
||||||
|
description:
|
||||||
|
'The time the event happened as a RFC 3339-conformant timestamp.',
|
||||||
|
example: '2023-07-05T12:56:00.000Z',
|
||||||
|
},
|
||||||
|
lastSeenAt: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date-time',
|
||||||
|
description: 'The time the feature was last seen',
|
||||||
|
example: '2023-07-05T12:56:00.000Z',
|
||||||
|
nullable: true,
|
||||||
|
},
|
||||||
|
impressionData: {
|
||||||
|
description:
|
||||||
|
'Should [impression events](https://docs.getunleash.io/reference/impression-data) activate for this feature toggle',
|
||||||
|
type: 'boolean',
|
||||||
|
example: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
description:
|
||||||
|
'Extra associated data related to the event, such as feature toggle state, segment configuration, etc., if applicable.',
|
||||||
|
example: {
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
} as const;
|
||||||
export const eventSchema = {
|
export const eventSchema = {
|
||||||
$id: '#/components/schemas/eventSchema',
|
$id: '#/components/schemas/eventSchema',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
required: ['id', 'createdAt', 'type', 'createdBy'],
|
required: ['id', 'createdAt', 'type', 'createdBy'],
|
||||||
|
description: 'An event describing something happening in the system',
|
||||||
properties: {
|
properties: {
|
||||||
id: {
|
id: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
minimum: 1,
|
minimum: 1,
|
||||||
|
description: 'The ID of the event. An increasing natural number.',
|
||||||
},
|
},
|
||||||
createdAt: {
|
createdAt: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
format: 'date-time',
|
format: 'date-time',
|
||||||
|
description:
|
||||||
|
'The time the event happened as a RFC 3339-conformant timestamp.',
|
||||||
|
example: '2023-07-05T12:56:00.000Z',
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
description:
|
||||||
|
'What [type](https://docs.getunleash.io/reference/api/legacy/unleash/admin/events#event-type-description) of event this is',
|
||||||
|
enum: IEventTypes,
|
||||||
|
example: 'feature-created',
|
||||||
},
|
},
|
||||||
createdBy: {
|
createdBy: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
description: 'Which user created this event',
|
||||||
|
example: 'johndoe',
|
||||||
},
|
},
|
||||||
environment: {
|
environment: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
description:
|
||||||
|
'The feature toggle environment the event relates to, if applicable.',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
example: 'development',
|
||||||
},
|
},
|
||||||
project: {
|
project: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
description: 'The project the event relates to, if applicable.',
|
||||||
|
example: 'default',
|
||||||
},
|
},
|
||||||
featureName: {
|
featureName: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
description:
|
||||||
|
'The name of the feature toggle the event relates to, if applicable.',
|
||||||
|
example: 'my.first.feature',
|
||||||
|
},
|
||||||
|
data: eventDataSchema,
|
||||||
|
preData: {
|
||||||
|
...eventDataSchema,
|
||||||
|
description:
|
||||||
|
"Data relating to the previous state of the event's subject.",
|
||||||
|
nullable: true,
|
||||||
},
|
},
|
||||||
data: { type: 'object', nullable: true },
|
|
||||||
preData: { type: 'object', nullable: true },
|
|
||||||
tags: {
|
tags: {
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: {
|
items: {
|
||||||
$ref: tagSchema.$id,
|
$ref: tagSchema.$id,
|
||||||
},
|
},
|
||||||
nullable: true,
|
nullable: true,
|
||||||
|
description: 'Any tags related to the event, if applicable.',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
schemas: {
|
schemas: {
|
||||||
tagSchema,
|
tagSchema,
|
||||||
|
variantSchema,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -7,18 +7,26 @@ export const eventsSchema = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
required: ['version', 'events'],
|
required: ['version', 'events'],
|
||||||
|
description: 'A list of events that has happened in the system',
|
||||||
properties: {
|
properties: {
|
||||||
version: {
|
version: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
minimum: 1,
|
minimum: 1,
|
||||||
|
enum: [1],
|
||||||
|
description:
|
||||||
|
'The api version of this response. A natural increasing number. Only increases if format changes',
|
||||||
|
example: 1,
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
|
description: 'The list of events',
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: { $ref: eventSchema.$id },
|
items: { $ref: eventSchema.$id },
|
||||||
},
|
},
|
||||||
totalEvents: {
|
totalEvents: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
|
description: 'The total count of events',
|
||||||
minimum: 0,
|
minimum: 0,
|
||||||
|
example: 842,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -7,18 +7,31 @@ export const featureEventsSchema = {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
required: ['events'],
|
required: ['events'],
|
||||||
|
description: 'One or more events happening to a specific feature toggle',
|
||||||
properties: {
|
properties: {
|
||||||
version: { type: 'number' },
|
version: {
|
||||||
|
type: 'integer',
|
||||||
|
description: 'An API versioning number',
|
||||||
|
minimum: 1,
|
||||||
|
enum: [1],
|
||||||
|
example: 1,
|
||||||
|
},
|
||||||
toggleName: {
|
toggleName: {
|
||||||
|
description:
|
||||||
|
'The name of the feature toggle these events relate to',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
example: 'my.first.feature.toggle',
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
|
description: 'The list of events',
|
||||||
type: 'array',
|
type: 'array',
|
||||||
items: { $ref: eventSchema.$id },
|
items: { $ref: eventSchema.$id },
|
||||||
},
|
},
|
||||||
totalEvents: {
|
totalEvents: {
|
||||||
|
description: 'How many events are there for this feature toggle',
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
minimum: 0,
|
minimum: 0,
|
||||||
|
example: 13,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { FromSchema } from 'json-schema-to-ts';
|
import { FromSchema } from 'json-schema-to-ts';
|
||||||
|
import { IEventTypes } from '../../types';
|
||||||
|
|
||||||
export const searchEventsSchema = {
|
export const searchEventsSchema = {
|
||||||
$id: '#/components/schemas/searchEventsSchema',
|
$id: '#/components/schemas/searchEventsSchema',
|
||||||
@ -11,14 +12,18 @@ export const searchEventsSchema = {
|
|||||||
type: {
|
type: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Find events by event type (case-sensitive).',
|
description: 'Find events by event type (case-sensitive).',
|
||||||
|
enum: IEventTypes,
|
||||||
|
example: 'feature-created',
|
||||||
},
|
},
|
||||||
project: {
|
project: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Find events by project ID (case-sensitive).',
|
description: 'Find events by project ID (case-sensitive).',
|
||||||
|
example: 'default',
|
||||||
},
|
},
|
||||||
feature: {
|
feature: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'Find events by feature toggle name (case-sensitive).',
|
description: 'Find events by feature toggle name (case-sensitive).',
|
||||||
|
example: 'my.first.toggle',
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@ -28,17 +33,23 @@ export const searchEventsSchema = {
|
|||||||
the username or email that created the event (if any),
|
the username or email that created the event (if any),
|
||||||
and the event data payload (if any).
|
and the event data payload (if any).
|
||||||
`,
|
`,
|
||||||
|
example: 'admin@example.com',
|
||||||
},
|
},
|
||||||
limit: {
|
limit: {
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
|
description:
|
||||||
|
'The maximum amount of events to return in the search result',
|
||||||
minimum: 1,
|
minimum: 1,
|
||||||
maximum: 100,
|
maximum: 100,
|
||||||
default: 100,
|
default: 100,
|
||||||
|
example: 50,
|
||||||
},
|
},
|
||||||
offset: {
|
offset: {
|
||||||
|
description: 'Which event id to start listing from',
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
minimum: 0,
|
minimum: 0,
|
||||||
default: 0,
|
default: 0,
|
||||||
|
example: 100,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {},
|
components: {},
|
||||||
|
@ -23,7 +23,7 @@ import { SearchEventsSchema } from '../../openapi/spec/search-events-schema';
|
|||||||
import { IFlagResolver } from '../../types/experimental';
|
import { IFlagResolver } from '../../types/experimental';
|
||||||
|
|
||||||
const ANON_KEYS = ['email', 'username', 'createdBy'];
|
const ANON_KEYS = ['email', 'username', 'createdBy'];
|
||||||
const version = 1;
|
const version = 1 as const;
|
||||||
export default class EventController extends Controller {
|
export default class EventController extends Controller {
|
||||||
private eventService: EventService;
|
private eventService: EventService;
|
||||||
|
|
||||||
@ -104,6 +104,9 @@ export default class EventController extends Controller {
|
|||||||
openApiService.validPath({
|
openApiService.validPath({
|
||||||
operationId: 'searchEvents',
|
operationId: 'searchEvents',
|
||||||
tags: ['Events'],
|
tags: ['Events'],
|
||||||
|
summary: 'Search for events',
|
||||||
|
description:
|
||||||
|
'Allows searching for events matching the search criteria in the request body',
|
||||||
requestBody: createRequestSchema('searchEventsSchema'),
|
requestBody: createRequestSchema('searchEventsSchema'),
|
||||||
responses: { 200: createResponseSchema('eventsSchema') },
|
responses: { 200: createResponseSchema('eventsSchema') },
|
||||||
}),
|
}),
|
||||||
|
@ -3,115 +3,222 @@ import { FeatureToggle, IStrategyConfig, ITag, IVariant } from './model';
|
|||||||
import { IApiToken } from './models/api-token';
|
import { IApiToken } from './models/api-token';
|
||||||
import { IUser } from './user';
|
import { IUser } from './user';
|
||||||
|
|
||||||
export const APPLICATION_CREATED = 'application-created';
|
export const APPLICATION_CREATED = 'application-created' as const;
|
||||||
|
|
||||||
// feature event types
|
// feature event types
|
||||||
export const FEATURE_CREATED = 'feature-created';
|
export const FEATURE_CREATED = 'feature-created' as const;
|
||||||
export const FEATURE_DELETED = 'feature-deleted';
|
export const FEATURE_DELETED = 'feature-deleted' as const;
|
||||||
export const FEATURE_UPDATED = 'feature-updated';
|
export const FEATURE_UPDATED = 'feature-updated' as const;
|
||||||
export const FEATURE_METADATA_UPDATED = 'feature-metadata-updated';
|
export const FEATURE_METADATA_UPDATED = 'feature-metadata-updated' as const;
|
||||||
export const FEATURE_VARIANTS_UPDATED = 'feature-variants-updated';
|
export const FEATURE_VARIANTS_UPDATED = 'feature-variants-updated' as const;
|
||||||
export const FEATURE_ENVIRONMENT_VARIANTS_UPDATED =
|
export const FEATURE_ENVIRONMENT_VARIANTS_UPDATED =
|
||||||
'feature-environment-variants-updated';
|
'feature-environment-variants-updated' as const;
|
||||||
export const FEATURE_PROJECT_CHANGE = 'feature-project-change';
|
export const FEATURE_PROJECT_CHANGE = 'feature-project-change' as const;
|
||||||
export const FEATURE_ARCHIVED = 'feature-archived';
|
export const FEATURE_ARCHIVED = 'feature-archived' as const;
|
||||||
export const FEATURE_REVIVED = 'feature-revived';
|
export const FEATURE_REVIVED = 'feature-revived' as const;
|
||||||
export const FEATURE_IMPORT = 'feature-import';
|
export const FEATURE_IMPORT = 'feature-import' as const;
|
||||||
export const FEATURE_TAGGED = 'feature-tagged';
|
export const FEATURE_TAGGED = 'feature-tagged' as const;
|
||||||
export const FEATURE_TAG_IMPORT = 'feature-tag-import';
|
export const FEATURE_TAG_IMPORT = 'feature-tag-import' as const;
|
||||||
export const FEATURE_STRATEGY_UPDATE = 'feature-strategy-update';
|
export const FEATURE_STRATEGY_UPDATE = 'feature-strategy-update' as const;
|
||||||
export const FEATURE_STRATEGY_ADD = 'feature-strategy-add';
|
export const FEATURE_STRATEGY_ADD = 'feature-strategy-add' as const;
|
||||||
export const FEATURE_STRATEGY_REMOVE = 'feature-strategy-remove';
|
export const FEATURE_STRATEGY_REMOVE = 'feature-strategy-remove' as const;
|
||||||
export const DROP_FEATURE_TAGS = 'drop-feature-tags';
|
export const DROP_FEATURE_TAGS = 'drop-feature-tags' as const;
|
||||||
export const FEATURE_UNTAGGED = 'feature-untagged';
|
export const FEATURE_UNTAGGED = 'feature-untagged' as const;
|
||||||
export const FEATURE_STALE_ON = 'feature-stale-on';
|
export const FEATURE_STALE_ON = 'feature-stale-on' as const;
|
||||||
export const FEATURE_STALE_OFF = 'feature-stale-off';
|
export const FEATURE_STALE_OFF = 'feature-stale-off' as const;
|
||||||
export const DROP_FEATURES = 'drop-features';
|
export const DROP_FEATURES = 'drop-features' as const;
|
||||||
export const FEATURE_ENVIRONMENT_ENABLED = 'feature-environment-enabled';
|
export const FEATURE_ENVIRONMENT_ENABLED =
|
||||||
export const FEATURE_ENVIRONMENT_DISABLED = 'feature-environment-disabled';
|
'feature-environment-enabled' as const;
|
||||||
|
export const FEATURE_ENVIRONMENT_DISABLED =
|
||||||
|
'feature-environment-disabled' as const;
|
||||||
|
|
||||||
export const STRATEGY_CREATED = 'strategy-created';
|
export const STRATEGY_CREATED = 'strategy-created' as const;
|
||||||
export const STRATEGY_DELETED = 'strategy-deleted';
|
export const STRATEGY_DELETED = 'strategy-deleted' as const;
|
||||||
export const STRATEGY_DEPRECATED = 'strategy-deprecated';
|
export const STRATEGY_DEPRECATED = 'strategy-deprecated' as const;
|
||||||
export const STRATEGY_REACTIVATED = 'strategy-reactivated';
|
export const STRATEGY_REACTIVATED = 'strategy-reactivated' as const;
|
||||||
export const STRATEGY_UPDATED = 'strategy-updated';
|
export const STRATEGY_UPDATED = 'strategy-updated' as const;
|
||||||
export const STRATEGY_IMPORT = 'strategy-import';
|
export const STRATEGY_IMPORT = 'strategy-import' as const;
|
||||||
export const DROP_STRATEGIES = 'drop-strategies';
|
export const DROP_STRATEGIES = 'drop-strategies' as const;
|
||||||
export const CONTEXT_FIELD_CREATED = 'context-field-created';
|
export const CONTEXT_FIELD_CREATED = 'context-field-created' as const;
|
||||||
export const CONTEXT_FIELD_UPDATED = 'context-field-updated';
|
export const CONTEXT_FIELD_UPDATED = 'context-field-updated' as const;
|
||||||
export const CONTEXT_FIELD_DELETED = 'context-field-deleted';
|
export const CONTEXT_FIELD_DELETED = 'context-field-deleted' as const;
|
||||||
export const PROJECT_ACCESS_ADDED = 'project-access-added';
|
export const PROJECT_ACCESS_ADDED = 'project-access-added' as const;
|
||||||
export const PROJECT_CREATED = 'project-created';
|
export const PROJECT_CREATED = 'project-created' as const;
|
||||||
export const PROJECT_UPDATED = 'project-updated';
|
export const PROJECT_UPDATED = 'project-updated' as const;
|
||||||
export const PROJECT_DELETED = 'project-deleted';
|
export const PROJECT_DELETED = 'project-deleted' as const;
|
||||||
export const PROJECT_IMPORT = 'project-import';
|
export const PROJECT_IMPORT = 'project-import' as const;
|
||||||
export const PROJECT_USER_ADDED = 'project-user-added';
|
export const PROJECT_USER_ADDED = 'project-user-added' as const;
|
||||||
export const PROJECT_USER_REMOVED = 'project-user-removed';
|
export const PROJECT_USER_REMOVED = 'project-user-removed' as const;
|
||||||
export const PROJECT_USER_ROLE_CHANGED = 'project-user-role-changed';
|
export const PROJECT_USER_ROLE_CHANGED = 'project-user-role-changed' as const;
|
||||||
export const PROJECT_GROUP_ADDED = 'project-group-added';
|
export const PROJECT_GROUP_ADDED = 'project-group-added' as const;
|
||||||
export const PROJECT_GROUP_REMOVED = 'project-group-removed';
|
export const PROJECT_GROUP_REMOVED = 'project-group-removed' as const;
|
||||||
export const PROJECT_GROUP_ROLE_CHANGED = 'project-group-role-changed';
|
export const PROJECT_GROUP_ROLE_CHANGED = 'project-group-role-changed' as const;
|
||||||
export const DROP_PROJECTS = 'drop-projects';
|
export const DROP_PROJECTS = 'drop-projects' as const;
|
||||||
export const TAG_CREATED = 'tag-created';
|
export const TAG_CREATED = 'tag-created' as const;
|
||||||
export const TAG_DELETED = 'tag-deleted';
|
export const TAG_DELETED = 'tag-deleted' as const;
|
||||||
export const TAG_IMPORT = 'tag-import';
|
export const TAG_IMPORT = 'tag-import' as const;
|
||||||
export const DROP_TAGS = 'drop-tags';
|
export const DROP_TAGS = 'drop-tags' as const;
|
||||||
export const TAG_TYPE_CREATED = 'tag-type-created';
|
export const TAG_TYPE_CREATED = 'tag-type-created' as const;
|
||||||
export const TAG_TYPE_DELETED = 'tag-type-deleted';
|
export const TAG_TYPE_DELETED = 'tag-type-deleted' as const;
|
||||||
export const TAG_TYPE_UPDATED = 'tag-type-updated';
|
export const TAG_TYPE_UPDATED = 'tag-type-updated' as const;
|
||||||
export const TAG_TYPE_IMPORT = 'tag-type-import';
|
export const TAG_TYPE_IMPORT = 'tag-type-import' as const;
|
||||||
export const DROP_TAG_TYPES = 'drop-tag-types';
|
export const DROP_TAG_TYPES = 'drop-tag-types' as const;
|
||||||
export const ADDON_CONFIG_CREATED = 'addon-config-created';
|
export const ADDON_CONFIG_CREATED = 'addon-config-created' as const;
|
||||||
export const ADDON_CONFIG_UPDATED = 'addon-config-updated';
|
export const ADDON_CONFIG_UPDATED = 'addon-config-updated' as const;
|
||||||
export const ADDON_CONFIG_DELETED = 'addon-config-deleted';
|
export const ADDON_CONFIG_DELETED = 'addon-config-deleted' as const;
|
||||||
export const DB_POOL_UPDATE = 'db-pool-update';
|
export const DB_POOL_UPDATE = 'db-pool-update' as const;
|
||||||
export const USER_CREATED = 'user-created';
|
export const USER_CREATED = 'user-created' as const;
|
||||||
export const USER_UPDATED = 'user-updated';
|
export const USER_UPDATED = 'user-updated' as const;
|
||||||
export const USER_DELETED = 'user-deleted';
|
export const USER_DELETED = 'user-deleted' as const;
|
||||||
export const DROP_ENVIRONMENTS = 'drop-environments';
|
export const DROP_ENVIRONMENTS = 'drop-environments' as const;
|
||||||
export const ENVIRONMENT_IMPORT = 'environment-import';
|
export const ENVIRONMENT_IMPORT = 'environment-import' as const;
|
||||||
export const SEGMENT_CREATED = 'segment-created';
|
export const SEGMENT_CREATED = 'segment-created' as const;
|
||||||
export const SEGMENT_UPDATED = 'segment-updated';
|
export const SEGMENT_UPDATED = 'segment-updated' as const;
|
||||||
export const SEGMENT_DELETED = 'segment-deleted';
|
export const SEGMENT_DELETED = 'segment-deleted' as const;
|
||||||
export const GROUP_CREATED = 'group-created';
|
export const GROUP_CREATED = 'group-created' as const;
|
||||||
export const GROUP_UPDATED = 'group-updated';
|
export const GROUP_UPDATED = 'group-updated' as const;
|
||||||
export const SETTING_CREATED = 'setting-created';
|
export const SETTING_CREATED = 'setting-created' as const;
|
||||||
export const SETTING_UPDATED = 'setting-updated';
|
export const SETTING_UPDATED = 'setting-updated' as const;
|
||||||
export const SETTING_DELETED = 'setting-deleted';
|
export const SETTING_DELETED = 'setting-deleted' as const;
|
||||||
|
|
||||||
export const CLIENT_METRICS = 'client-metrics';
|
export const CLIENT_METRICS = 'client-metrics' as const;
|
||||||
export const CLIENT_REGISTER = 'client-register';
|
export const CLIENT_REGISTER = 'client-register' as const;
|
||||||
|
|
||||||
export const PAT_CREATED = 'pat-created';
|
export const PAT_CREATED = 'pat-created' as const;
|
||||||
export const PAT_DELETED = 'pat-deleted';
|
export const PAT_DELETED = 'pat-deleted' as const;
|
||||||
|
|
||||||
export const PUBLIC_SIGNUP_TOKEN_CREATED = 'public-signup-token-created';
|
export const PUBLIC_SIGNUP_TOKEN_CREATED =
|
||||||
export const PUBLIC_SIGNUP_TOKEN_USER_ADDED = 'public-signup-token-user-added';
|
'public-signup-token-created' as const;
|
||||||
export const PUBLIC_SIGNUP_TOKEN_TOKEN_UPDATED = 'public-signup-token-updated';
|
export const PUBLIC_SIGNUP_TOKEN_USER_ADDED =
|
||||||
|
'public-signup-token-user-added' as const;
|
||||||
|
export const PUBLIC_SIGNUP_TOKEN_TOKEN_UPDATED =
|
||||||
|
'public-signup-token-updated' as const;
|
||||||
|
|
||||||
export const CHANGE_REQUEST_CREATED = 'change-request-created';
|
export const CHANGE_REQUEST_CREATED = 'change-request-created' as const;
|
||||||
export const CHANGE_REQUEST_DISCARDED = 'change-request-discarded';
|
export const CHANGE_REQUEST_DISCARDED = 'change-request-discarded' as const;
|
||||||
export const CHANGE_ADDED = 'change-added';
|
export const CHANGE_ADDED = 'change-added' as const;
|
||||||
export const CHANGE_DISCARDED = 'change-discarded';
|
export const CHANGE_DISCARDED = 'change-discarded' as const;
|
||||||
export const CHANGE_REQUEST_APPROVED = 'change-request-approved';
|
export const CHANGE_REQUEST_APPROVED = 'change-request-approved' as const;
|
||||||
export const CHANGE_REQUEST_APPROVAL_ADDED = 'change-request-approval-added';
|
export const CHANGE_REQUEST_APPROVAL_ADDED =
|
||||||
export const CHANGE_REQUEST_CANCELLED = 'change-request-cancelled';
|
'change-request-approval-added' as const;
|
||||||
export const CHANGE_REQUEST_SENT_TO_REVIEW = 'change-request-sent-to-review';
|
export const CHANGE_REQUEST_CANCELLED = 'change-request-cancelled' as const;
|
||||||
export const CHANGE_REQUEST_APPLIED = 'change-request-applied';
|
export const CHANGE_REQUEST_SENT_TO_REVIEW =
|
||||||
|
'change-request-sent-to-review' as const;
|
||||||
|
export const CHANGE_REQUEST_APPLIED = 'change-request-applied' as const;
|
||||||
|
|
||||||
export const API_TOKEN_CREATED = 'api-token-created';
|
export const API_TOKEN_CREATED = 'api-token-created' as const;
|
||||||
export const API_TOKEN_UPDATED = 'api-token-updated';
|
export const API_TOKEN_UPDATED = 'api-token-updated' as const;
|
||||||
export const API_TOKEN_DELETED = 'api-token-deleted';
|
export const API_TOKEN_DELETED = 'api-token-deleted' as const;
|
||||||
|
|
||||||
export const FEATURE_FAVORITED = 'feature-favorited';
|
export const FEATURE_FAVORITED = 'feature-favorited' as const;
|
||||||
export const FEATURE_UNFAVORITED = 'feature-unfavorited';
|
export const FEATURE_UNFAVORITED = 'feature-unfavorited' as const;
|
||||||
export const PROJECT_FAVORITED = 'project-favorited';
|
export const PROJECT_FAVORITED = 'project-favorited' as const;
|
||||||
export const PROJECT_UNFAVORITED = 'project-unfavorited';
|
export const PROJECT_UNFAVORITED = 'project-unfavorited' as const;
|
||||||
export const FEATURES_EXPORTED = 'features-exported';
|
export const FEATURES_EXPORTED = 'features-exported' as const;
|
||||||
export const FEATURES_IMPORTED = 'features-imported';
|
export const FEATURES_IMPORTED = 'features-imported' as const;
|
||||||
|
|
||||||
|
export const IEventTypes = [
|
||||||
|
APPLICATION_CREATED,
|
||||||
|
FEATURE_CREATED,
|
||||||
|
FEATURE_DELETED,
|
||||||
|
FEATURE_UPDATED,
|
||||||
|
FEATURE_METADATA_UPDATED,
|
||||||
|
FEATURE_VARIANTS_UPDATED,
|
||||||
|
FEATURE_ENVIRONMENT_VARIANTS_UPDATED,
|
||||||
|
FEATURE_PROJECT_CHANGE,
|
||||||
|
FEATURE_ARCHIVED,
|
||||||
|
FEATURE_REVIVED,
|
||||||
|
FEATURE_IMPORT,
|
||||||
|
FEATURE_TAGGED,
|
||||||
|
FEATURE_TAG_IMPORT,
|
||||||
|
FEATURE_STRATEGY_UPDATE,
|
||||||
|
FEATURE_STRATEGY_ADD,
|
||||||
|
FEATURE_STRATEGY_REMOVE,
|
||||||
|
DROP_FEATURE_TAGS,
|
||||||
|
FEATURE_UNTAGGED,
|
||||||
|
FEATURE_STALE_ON,
|
||||||
|
FEATURE_STALE_OFF,
|
||||||
|
DROP_FEATURES,
|
||||||
|
FEATURE_ENVIRONMENT_ENABLED,
|
||||||
|
FEATURE_ENVIRONMENT_DISABLED,
|
||||||
|
STRATEGY_CREATED,
|
||||||
|
STRATEGY_DELETED,
|
||||||
|
STRATEGY_DEPRECATED,
|
||||||
|
STRATEGY_REACTIVATED,
|
||||||
|
STRATEGY_UPDATED,
|
||||||
|
STRATEGY_IMPORT,
|
||||||
|
DROP_STRATEGIES,
|
||||||
|
CONTEXT_FIELD_CREATED,
|
||||||
|
CONTEXT_FIELD_UPDATED,
|
||||||
|
CONTEXT_FIELD_DELETED,
|
||||||
|
PROJECT_ACCESS_ADDED,
|
||||||
|
PROJECT_CREATED,
|
||||||
|
PROJECT_UPDATED,
|
||||||
|
PROJECT_DELETED,
|
||||||
|
PROJECT_IMPORT,
|
||||||
|
PROJECT_USER_ADDED,
|
||||||
|
PROJECT_USER_REMOVED,
|
||||||
|
PROJECT_USER_ROLE_CHANGED,
|
||||||
|
PROJECT_GROUP_ROLE_CHANGED,
|
||||||
|
PROJECT_GROUP_ADDED,
|
||||||
|
PROJECT_GROUP_REMOVED,
|
||||||
|
DROP_PROJECTS,
|
||||||
|
TAG_CREATED,
|
||||||
|
TAG_DELETED,
|
||||||
|
TAG_IMPORT,
|
||||||
|
DROP_TAGS,
|
||||||
|
TAG_TYPE_CREATED,
|
||||||
|
TAG_TYPE_DELETED,
|
||||||
|
TAG_TYPE_UPDATED,
|
||||||
|
TAG_TYPE_IMPORT,
|
||||||
|
DROP_TAG_TYPES,
|
||||||
|
ADDON_CONFIG_CREATED,
|
||||||
|
ADDON_CONFIG_UPDATED,
|
||||||
|
ADDON_CONFIG_DELETED,
|
||||||
|
DB_POOL_UPDATE,
|
||||||
|
USER_CREATED,
|
||||||
|
USER_UPDATED,
|
||||||
|
USER_DELETED,
|
||||||
|
DROP_ENVIRONMENTS,
|
||||||
|
ENVIRONMENT_IMPORT,
|
||||||
|
SEGMENT_CREATED,
|
||||||
|
SEGMENT_UPDATED,
|
||||||
|
SEGMENT_DELETED,
|
||||||
|
GROUP_CREATED,
|
||||||
|
GROUP_UPDATED,
|
||||||
|
SETTING_CREATED,
|
||||||
|
SETTING_UPDATED,
|
||||||
|
SETTING_DELETED,
|
||||||
|
CLIENT_METRICS,
|
||||||
|
CLIENT_REGISTER,
|
||||||
|
PAT_CREATED,
|
||||||
|
PAT_DELETED,
|
||||||
|
PUBLIC_SIGNUP_TOKEN_CREATED,
|
||||||
|
PUBLIC_SIGNUP_TOKEN_USER_ADDED,
|
||||||
|
PUBLIC_SIGNUP_TOKEN_TOKEN_UPDATED,
|
||||||
|
CHANGE_REQUEST_CREATED,
|
||||||
|
CHANGE_REQUEST_DISCARDED,
|
||||||
|
CHANGE_ADDED,
|
||||||
|
CHANGE_DISCARDED,
|
||||||
|
CHANGE_REQUEST_APPROVED,
|
||||||
|
CHANGE_REQUEST_APPROVAL_ADDED,
|
||||||
|
CHANGE_REQUEST_CANCELLED,
|
||||||
|
CHANGE_REQUEST_SENT_TO_REVIEW,
|
||||||
|
CHANGE_REQUEST_APPLIED,
|
||||||
|
API_TOKEN_CREATED,
|
||||||
|
API_TOKEN_UPDATED,
|
||||||
|
API_TOKEN_DELETED,
|
||||||
|
FEATURE_FAVORITED,
|
||||||
|
FEATURE_UNFAVORITED,
|
||||||
|
PROJECT_FAVORITED,
|
||||||
|
PROJECT_UNFAVORITED,
|
||||||
|
FEATURES_EXPORTED,
|
||||||
|
FEATURES_IMPORTED,
|
||||||
|
] as const;
|
||||||
|
export type IEventType = typeof IEventTypes[number];
|
||||||
|
|
||||||
export interface IBaseEvent {
|
export interface IBaseEvent {
|
||||||
type: string;
|
type: IEventType;
|
||||||
createdBy: string;
|
createdBy: string;
|
||||||
project?: string;
|
project?: string;
|
||||||
environment?: string;
|
environment?: string;
|
||||||
@ -132,7 +239,7 @@ export interface IEventList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class BaseEvent implements IBaseEvent {
|
class BaseEvent implements IBaseEvent {
|
||||||
readonly type: string;
|
readonly type: IEventType;
|
||||||
|
|
||||||
readonly createdBy: string;
|
readonly createdBy: string;
|
||||||
|
|
||||||
@ -141,7 +248,11 @@ class BaseEvent implements IBaseEvent {
|
|||||||
/**
|
/**
|
||||||
* @param createdBy accepts a string for backward compatibility. Prefer using IUser for standardization
|
* @param createdBy accepts a string for backward compatibility. Prefer using IUser for standardization
|
||||||
*/
|
*/
|
||||||
constructor(type: string, createdBy: string | IUser, tags: ITag[] = []) {
|
constructor(
|
||||||
|
type: IEventType,
|
||||||
|
createdBy: string | IUser,
|
||||||
|
tags: ITag[] = [],
|
||||||
|
) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.createdBy =
|
this.createdBy =
|
||||||
typeof createdBy === 'string'
|
typeof createdBy === 'string'
|
||||||
|
@ -59,7 +59,6 @@ test('the generated OpenAPI spec is valid', async () => {
|
|||||||
.get('/docs/openapi.json')
|
.get('/docs/openapi.json')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(200);
|
.expect(200);
|
||||||
|
|
||||||
// this throws if the swagger parser can't parse it correctly
|
// this throws if the swagger parser can't parse it correctly
|
||||||
// also parses examples, but _does_ do some string coercion in examples
|
// also parses examples, but _does_ do some string coercion in examples
|
||||||
try {
|
try {
|
||||||
@ -86,7 +85,6 @@ test('the generated OpenAPI spec is valid', async () => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (enforcerWarning !== undefined) {
|
if (enforcerWarning !== undefined) {
|
||||||
console.warn(enforcerWarning);
|
console.warn(enforcerWarning);
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@ beforeAll(async () => {
|
|||||||
});
|
});
|
||||||
userStore = stores.userStore;
|
userStore = stores.userStore;
|
||||||
const rootRoles = await accessService.getRootRoles();
|
const rootRoles = await accessService.getRootRoles();
|
||||||
adminRole = rootRoles.find((r) => r.name === RoleName.ADMIN);
|
adminRole = rootRoles.find((r) => r.name === RoleName.ADMIN)!;
|
||||||
viewerRole = rootRoles.find((r) => r.name === RoleName.VIEWER);
|
viewerRole = rootRoles.find((r) => r.name === RoleName.VIEWER)!;
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
@ -218,7 +218,6 @@ test('updating a user without an email should not strip the email', async () =>
|
|||||||
|
|
||||||
await userService.updateUser({
|
await userService.updateUser({
|
||||||
id: user.id,
|
id: user.id,
|
||||||
email: null,
|
|
||||||
name: 'some',
|
name: 'some',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ test('Should include id and createdAt when saving', async () => {
|
|||||||
appName: 'test1',
|
appName: 'test1',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const seen = [];
|
const seen: Array<IEvent> = [];
|
||||||
eventStore.on(APPLICATION_CREATED, (e) => seen.push(e));
|
eventStore.on(APPLICATION_CREATED, (e) => seen.push(e));
|
||||||
await eventStore.store(event1);
|
await eventStore.store(event1);
|
||||||
jest.advanceTimersByTime(100);
|
jest.advanceTimersByTime(100);
|
||||||
|
Loading…
Reference in New Issue
Block a user