mirror of
https://github.com/Unleash/unleash.git
synced 2024-12-22 19:07:54 +01:00
chore: drop event hook (#3565)
## About the changes
Ref:
https://docs.getunleash.io/reference/deploy/configuring-unleash#further-customization
> **eventHook** (`function(event, data)`) - (_deprecated in Unleash 4.3_
in favor of the [Webhook addon](../addons/webhook.md)) If provided, this
function will be invoked whenever a feature is mutated. The possible
values for `event` are `'feature-created'`, `'feature-archived'` and
`'feature-revived'`. The `data` argument contains information about the
mutation. Its fields are `type` (string) - the event type (same as
`event`); `createdBy` (string) - the user who performed the mutation;
`data` - the contents of the change. The contents in `data` differs
based on the event type; For `'feature-archived'` and
`'feature-revived'`, the only field will be `name` - the name of the
feature. For `'feature-created'` the data follows a schema defined in
the code
[here](7b7f0b84e8/src/lib/schema/feature-schema.ts (L77)
).
See an [api here](/reference/api/legacy/unleash/admin/events).
Related to: https://github.com/Unleash/unleash/issues/1265
This commit is contained in:
parent
96633f1a34
commit
ca01a79f71
@ -61,7 +61,6 @@ exports[`should create default config 1`] = `
|
|||||||
"_maxListeners": undefined,
|
"_maxListeners": undefined,
|
||||||
Symbol(kCapture): false,
|
Symbol(kCapture): false,
|
||||||
},
|
},
|
||||||
"eventHook": undefined,
|
|
||||||
"experimental": {
|
"experimental": {
|
||||||
"externalResolver": {
|
"externalResolver": {
|
||||||
"isEnabled": [Function],
|
"isEnabled": [Function],
|
||||||
|
@ -45,13 +45,14 @@ import {
|
|||||||
import FlagResolver from './util/flag-resolver';
|
import FlagResolver from './util/flag-resolver';
|
||||||
import { validateOrigins } from './util/validateOrigin';
|
import { validateOrigins } from './util/validateOrigin';
|
||||||
|
|
||||||
const safeToUpper = (s: string) => (s ? s.toUpperCase() : s);
|
const safeToUpper = (s?: string) => (s ? s.toUpperCase() : s);
|
||||||
|
|
||||||
export function authTypeFromString(
|
export function authTypeFromString(
|
||||||
s?: string,
|
s?: string,
|
||||||
defaultType: IAuthType = IAuthType.OPEN_SOURCE,
|
defaultType: IAuthType = IAuthType.OPEN_SOURCE,
|
||||||
): IAuthType {
|
): IAuthType {
|
||||||
return IAuthType[safeToUpper(s)] || defaultType;
|
const upperS = safeToUpper(s);
|
||||||
|
return upperS && IAuthType[upperS] ? IAuthType[upperS] : defaultType;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeAll<T>(objects: Partial<T>[]): T {
|
function mergeAll<T>(objects: Partial<T>[]): T {
|
||||||
@ -93,7 +94,7 @@ function loadClientCachingOptions(
|
|||||||
|
|
||||||
return mergeAll([
|
return mergeAll([
|
||||||
defaultClientCachingOptions,
|
defaultClientCachingOptions,
|
||||||
options.clientFeatureCaching,
|
options.clientFeatureCaching || {},
|
||||||
envs,
|
envs,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@ -249,7 +250,10 @@ const formatServerOptions = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadTokensFromString = (tokenString: String, tokenType: ApiTokenType) => {
|
const loadTokensFromString = (
|
||||||
|
tokenString: String | undefined,
|
||||||
|
tokenType: ApiTokenType,
|
||||||
|
) => {
|
||||||
if (!tokenString) {
|
if (!tokenString) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@ -297,7 +301,7 @@ const loadEnvironmentEnableOverrides = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const parseCspConfig = (
|
const parseCspConfig = (
|
||||||
cspConfig: ICspDomainOptions,
|
cspConfig?: ICspDomainOptions,
|
||||||
): ICspDomainConfig | undefined => {
|
): ICspDomainConfig | undefined => {
|
||||||
if (!cspConfig) {
|
if (!cspConfig) {
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -366,12 +370,12 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
|||||||
defaultDbOptions,
|
defaultDbOptions,
|
||||||
dbPort(extraDbOptions),
|
dbPort(extraDbOptions),
|
||||||
dbPort(fileDbOptions),
|
dbPort(fileDbOptions),
|
||||||
options.db,
|
options.db || {},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const session: ISessionOption = mergeAll([
|
const session: ISessionOption = mergeAll([
|
||||||
defaultSessionOption,
|
defaultSessionOption,
|
||||||
options.session,
|
options.session || {},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const logLevel =
|
const logLevel =
|
||||||
@ -381,12 +385,12 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
|||||||
|
|
||||||
const server: IServerOption = mergeAll([
|
const server: IServerOption = mergeAll([
|
||||||
defaultServerOption,
|
defaultServerOption,
|
||||||
formatServerOptions(options.server),
|
formatServerOptions(options.server) || {},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const versionCheck: IVersionOption = mergeAll([
|
const versionCheck: IVersionOption = mergeAll([
|
||||||
defaultVersionOption,
|
defaultVersionOption,
|
||||||
options.versionCheck,
|
options.versionCheck || {},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const initApiTokens = loadInitApiTokens();
|
const initApiTokens = loadInitApiTokens();
|
||||||
@ -403,7 +407,7 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
|||||||
|
|
||||||
const importSetting: IImportOption = mergeAll([
|
const importSetting: IImportOption = mergeAll([
|
||||||
defaultImport,
|
defaultImport,
|
||||||
options.import,
|
options.import || {},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const experimental = loadExperimental(options);
|
const experimental = loadExperimental(options);
|
||||||
@ -411,7 +415,7 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
|||||||
|
|
||||||
const ui = loadUI(options);
|
const ui = loadUI(options);
|
||||||
|
|
||||||
const email: IEmailOption = mergeAll([defaultEmail, options.email]);
|
const email: IEmailOption = mergeAll([defaultEmail, options.email || {}]);
|
||||||
|
|
||||||
let listen: IListeningPipe | IListeningHost;
|
let listen: IListeningPipe | IListeningHost;
|
||||||
if (server.pipe) {
|
if (server.pipe) {
|
||||||
@ -483,7 +487,6 @@ export function createConfig(options: IUnleashOptions): IUnleashConfig {
|
|||||||
disableLegacyFeaturesApi,
|
disableLegacyFeaturesApi,
|
||||||
preHook: options.preHook,
|
preHook: options.preHook,
|
||||||
preRouterHook: options.preRouterHook,
|
preRouterHook: options.preRouterHook,
|
||||||
eventHook: options.eventHook,
|
|
||||||
enterpriseVersion: options.enterpriseVersion,
|
enterpriseVersion: options.enterpriseVersion,
|
||||||
eventBus: new EventEmitter(),
|
eventBus: new EventEmitter(),
|
||||||
environmentEnableOverrides,
|
environmentEnableOverrides,
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
import { EventEmitter } from 'events';
|
|
||||||
import { addEventHook } from './event-hook';
|
|
||||||
import {
|
|
||||||
FEATURE_CREATED,
|
|
||||||
FEATURE_UPDATED,
|
|
||||||
FEATURE_ARCHIVED,
|
|
||||||
FEATURE_REVIVED,
|
|
||||||
} from './types/events';
|
|
||||||
|
|
||||||
const eventStore = new EventEmitter();
|
|
||||||
const o = {};
|
|
||||||
|
|
||||||
function testHook(feature, data) {
|
|
||||||
o[feature] = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeAll(() => {
|
|
||||||
addEventHook(testHook, eventStore);
|
|
||||||
});
|
|
||||||
|
|
||||||
[FEATURE_CREATED, FEATURE_UPDATED, FEATURE_ARCHIVED, FEATURE_REVIVED].forEach(
|
|
||||||
(feature) => {
|
|
||||||
test(`should invoke hook on ${feature}`, () => {
|
|
||||||
const data = { dataKey: feature };
|
|
||||||
eventStore.emit(feature, data);
|
|
||||||
expect(o[feature] === data).toBe(true);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
@ -1,26 +0,0 @@
|
|||||||
import EventEmitter from 'events';
|
|
||||||
import { EventHook } from './types/option';
|
|
||||||
import {
|
|
||||||
FEATURE_CREATED,
|
|
||||||
FEATURE_UPDATED,
|
|
||||||
FEATURE_ARCHIVED,
|
|
||||||
FEATURE_REVIVED,
|
|
||||||
} from './types/events';
|
|
||||||
|
|
||||||
export const addEventHook = (
|
|
||||||
eventHook: EventHook,
|
|
||||||
eventStore: Pick<EventEmitter, 'on'>,
|
|
||||||
): void => {
|
|
||||||
eventStore.on(FEATURE_CREATED, (data) => {
|
|
||||||
eventHook(FEATURE_CREATED, data);
|
|
||||||
});
|
|
||||||
eventStore.on(FEATURE_UPDATED, (data) => {
|
|
||||||
eventHook(FEATURE_UPDATED, data);
|
|
||||||
});
|
|
||||||
eventStore.on(FEATURE_ARCHIVED, (data) => {
|
|
||||||
eventHook(FEATURE_ARCHIVED, data);
|
|
||||||
});
|
|
||||||
eventStore.on(FEATURE_REVIVED, (data) => {
|
|
||||||
eventHook(FEATURE_REVIVED, data);
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,6 +1,5 @@
|
|||||||
export * from './logger';
|
export * from './logger';
|
||||||
export * from './metrics';
|
export * from './metrics';
|
||||||
export * from './event-hook';
|
|
||||||
export * from './metric-events';
|
export * from './metric-events';
|
||||||
export * from './default-custom-auth-deny-all';
|
export * from './default-custom-auth-deny-all';
|
||||||
export * from './addons';
|
export * from './addons';
|
||||||
|
@ -93,20 +93,6 @@ test('should call preRouterHook', async () => {
|
|||||||
await stop();
|
await stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should call eventHook', async () => {
|
|
||||||
let called = 0;
|
|
||||||
const config = createTestConfig({
|
|
||||||
server: { port: 0 },
|
|
||||||
eventHook: () => {
|
|
||||||
called++;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const { stop } = await start(config);
|
|
||||||
eventStore.emit('feature-created', {});
|
|
||||||
expect(called === 1).toBe(true);
|
|
||||||
await stop();
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should auto-create server on start()', async () => {
|
test('should auto-create server on start()', async () => {
|
||||||
const { server, stop } = await start(
|
const { server, stop } = await start(
|
||||||
createTestConfig({ server: { port: 0 } }),
|
createTestConfig({ server: { port: 0 } }),
|
||||||
|
@ -7,7 +7,6 @@ import { createMetricsMonitor } from './metrics';
|
|||||||
import { createStores } from './db';
|
import { createStores } from './db';
|
||||||
import { createServices, scheduleServices } from './services';
|
import { createServices, scheduleServices } from './services';
|
||||||
import { createConfig } from './create-config';
|
import { createConfig } from './create-config';
|
||||||
import { addEventHook } from './event-hook';
|
|
||||||
import registerGracefulShutdown from './util/graceful-shutdown';
|
import registerGracefulShutdown from './util/graceful-shutdown';
|
||||||
import { createDb } from './db/db-pool';
|
import { createDb } from './db/db-pool';
|
||||||
import sessionDb from './middleware/session-db';
|
import sessionDb from './middleware/session-db';
|
||||||
@ -70,9 +69,6 @@ async function createApp(
|
|||||||
}
|
}
|
||||||
const app = await getApp(config, stores, services, unleashSession, db);
|
const app = await getApp(config, stores, services, unleashSession, db);
|
||||||
|
|
||||||
if (typeof config.eventHook === 'function') {
|
|
||||||
addEventHook(config.eventHook, stores.eventStore);
|
|
||||||
}
|
|
||||||
await metricsMonitor.startMonitoring(
|
await metricsMonitor.startMonitoring(
|
||||||
config,
|
config,
|
||||||
stores,
|
stores,
|
||||||
|
@ -4,8 +4,6 @@ import { ILegacyApiTokenCreate } from './models/api-token';
|
|||||||
import { IFlagResolver, IExperimentalOptions, IFlags } from './experimental';
|
import { IFlagResolver, IExperimentalOptions, IFlags } from './experimental';
|
||||||
import SMTPTransport from 'nodemailer/lib/smtp-transport';
|
import SMTPTransport from 'nodemailer/lib/smtp-transport';
|
||||||
|
|
||||||
export type EventHook = (eventName: string, data: object) => void;
|
|
||||||
|
|
||||||
export interface ISSLOption {
|
export interface ISSLOption {
|
||||||
rejectUnauthorized: boolean;
|
rejectUnauthorized: boolean;
|
||||||
ca?: string;
|
ca?: string;
|
||||||
@ -112,7 +110,6 @@ export interface IUnleashOptions {
|
|||||||
enableOAS?: boolean;
|
enableOAS?: boolean;
|
||||||
preHook?: Function;
|
preHook?: Function;
|
||||||
preRouterHook?: Function;
|
preRouterHook?: Function;
|
||||||
eventHook?: EventHook;
|
|
||||||
enterpriseVersion?: string;
|
enterpriseVersion?: string;
|
||||||
disableLegacyFeaturesApi?: boolean;
|
disableLegacyFeaturesApi?: boolean;
|
||||||
inlineSegmentConstraints?: boolean;
|
inlineSegmentConstraints?: boolean;
|
||||||
@ -195,7 +192,6 @@ export interface IUnleashConfig {
|
|||||||
enableOAS: boolean;
|
enableOAS: boolean;
|
||||||
preHook?: Function;
|
preHook?: Function;
|
||||||
preRouterHook?: Function;
|
preRouterHook?: Function;
|
||||||
eventHook?: EventHook;
|
|
||||||
enterpriseVersion?: string;
|
enterpriseVersion?: string;
|
||||||
eventBus: EventEmitter;
|
eventBus: EventEmitter;
|
||||||
disableLegacyFeaturesApi?: boolean;
|
disableLegacyFeaturesApi?: boolean;
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
export const formatBaseUri = (input: string): string => {
|
export const formatBaseUri = (input?: string): string => {
|
||||||
if (!input) return '';
|
if (!input) return '';
|
||||||
const firstChar = input[0];
|
const firstChar = input[0];
|
||||||
const lastChar = input[input.length - 1];
|
const lastChar = input[input.length - 1];
|
||||||
|
|
||||||
if (firstChar === '/' && lastChar === '/') {
|
if (firstChar === '/' && lastChar === '/') {
|
||||||
return input.substr(0, input.length - 1);
|
return input.substring(0, input.length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstChar !== '/' && lastChar === '/') {
|
if (firstChar !== '/' && lastChar === '/') {
|
||||||
return `/${input.substr(0, input.length - 1)}`;
|
return `/${input.substring(0, input.length - 1)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstChar !== '/') {
|
if (firstChar !== '/') {
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
export function parseEnvVarNumber(envVar: string, defaultVal: number): number {
|
export function parseEnvVarNumber(
|
||||||
|
envVar: string | undefined,
|
||||||
|
defaultVal: number,
|
||||||
|
): number {
|
||||||
|
if (!envVar) {
|
||||||
|
return defaultVal;
|
||||||
|
}
|
||||||
const parsed = Number.parseInt(envVar, 10);
|
const parsed = Number.parseInt(envVar, 10);
|
||||||
|
|
||||||
if (Number.isNaN(parsed)) {
|
if (Number.isNaN(parsed)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user