Revert "AAE-30878 Migrating from event-emitter to eventemitter3 which is … (#11116)" (#11186)

This reverts commit 49375181e4.
This commit is contained in:
Vito Albano
2025-09-10 15:57:01 +01:00
committed by GitHub
parent c8c1ae7838
commit fd29e953d6
15 changed files with 267 additions and 174 deletions
@@ -21,7 +21,6 @@ import { HttpClientTestingModule, HttpTestingController } from '@angular/common/
import { TestBed } from '@angular/core/testing';
import { AdfHttpClient } from './adf-http-client.service';
import { AlfrescoApiResponseError } from './alfresco-api/alfresco-api.response-error';
import EventEmitter from 'eventemitter3';
const securityOptions: SecurityOptions = {
authentications: {},
@@ -31,9 +30,16 @@ const securityOptions: SecurityOptions = {
withCredentials: false
};
const emitter = {
emit: () => {},
off: () => {},
on: () => {},
once: () => {}
};
const emitters: Emitters = {
eventEmitter: new EventEmitter(),
apiClientEmitter: new EventEmitter()
eventEmitter: emitter,
apiClientEmitter: emitter
};
const mockResponse = {
@@ -118,10 +124,10 @@ describe('AdfHttpClient', () => {
httpMethod: 'POST'
};
const eventSpy = spyOn(emitters.eventEmitter, 'emit').and.callThrough();
const spy = spyOn(emitter, 'emit').and.callThrough();
angularHttpClient.request('http://example.com', options, securityOptions, emitters).catch(() => {
expect(eventSpy).toHaveBeenCalledWith('unauthorized');
expect(spy).toHaveBeenCalledWith('unauthorized');
done();
});
+30 -47
View File
@@ -34,25 +34,24 @@ import { AlfrescoApiParamEncoder } from './alfresco-api/alfresco-api.param-encod
import { AlfrescoApiResponseError } from './alfresco-api/alfresco-api.response-error';
import { Constructor } from './types';
import { RequestOptions, SecurityOptions } from './interfaces';
import { EventEmitter } from 'eventemitter3';
type EventEmitterInstance = InstanceType<typeof EventEmitter>;
type EventEmitterEvents = 'progress' | 'success' | 'error' | 'forbidden' | 'abort' | 'unauthorized' | string;
import ee, { Emitter } from 'event-emitter';
export interface Emitters {
readonly eventEmitter: EventEmitterInstance;
readonly apiClientEmitter: EventEmitterInstance;
readonly eventEmitter: Emitter;
readonly apiClientEmitter: Emitter;
}
@Injectable({
providedIn: 'root'
})
export class AdfHttpClient implements JsApiHttpClient {
private eventEmitter = new EventEmitter();
export class AdfHttpClient implements ee.Emitter, JsApiHttpClient {
on: ee.EmitterMethod;
off: ee.EmitterMethod;
once: ee.EmitterMethod;
_disableCsrf: boolean;
emit: (type: string, ...args: any[]) => void;
get disableCsrf(): boolean {
return this._disableCsrf;
}
@@ -69,27 +68,7 @@ export class AdfHttpClient implements JsApiHttpClient {
};
constructor(private httpClient: HttpClient) {
// No need for ee(this) anymore - we use composition instead of inheritance
}
// EventEmitter delegation methods
on(event: EventEmitterEvents, fn: (...args: any[]) => void, context?: any): this {
this.eventEmitter.on(event, fn, context);
return this;
}
off(event: EventEmitterEvents, fn?: (...args: any[]) => void, context?: any): this {
this.eventEmitter.off(event, fn, context);
return this;
}
once(event: EventEmitterEvents, fn: (...args: any[]) => void, context?: any): this {
this.eventEmitter.once(event, fn, context);
return this;
}
emit(event: EventEmitterEvents, ...args: any[]): boolean {
return this.eventEmitter.emit(event, ...args);
ee(this);
}
setDefaultSecurityOption(options: any) {
@@ -157,19 +136,24 @@ export class AdfHttpClient implements JsApiHttpClient {
private addPromiseListeners<T = any>(promise: Promise<T>, eventEmitter: any) {
const eventPromise = Object.assign(promise, {
on<K extends string | symbol>(event: K, fn: (...args: any[]) => void, context?: any) {
eventEmitter.on(event, fn, context);
on() {
// eslint-disable-next-line prefer-spread, prefer-rest-params
eventEmitter.on.apply(eventEmitter, arguments);
return this;
},
once<K extends string | symbol>(event: K, fn: (...args: any[]) => void, context?: any) {
eventEmitter.once(event, fn, context);
once() {
// eslint-disable-next-line prefer-spread, prefer-rest-params
eventEmitter.once.apply(eventEmitter, arguments);
return this;
},
emit<K extends string | symbol>(event: K, ...args: any[]): boolean {
return eventEmitter.emit(event, ...args);
emit() {
// eslint-disable-next-line prefer-spread, prefer-rest-params
eventEmitter.emit.apply(eventEmitter, arguments);
return this;
},
off<K extends string | symbol>(event: K, fn?: (...args: any[]) => void, context?: any) {
eventEmitter.off(event, fn, context);
off() {
// eslint-disable-next-line prefer-spread, prefer-rest-params
eventEmitter.off.apply(eventEmitter, arguments);
return this;
}
});
@@ -178,17 +162,16 @@ export class AdfHttpClient implements JsApiHttpClient {
}
private getEventEmitters(): Emitters {
const apiClientEmitter: EventEmitterInstance = new EventEmitter();
// Bind this instance's methods to the apiClientEmitter for backward compatibility
apiClientEmitter.on = this.on.bind(this);
apiClientEmitter.off = this.off.bind(this);
apiClientEmitter.once = this.once.bind(this);
apiClientEmitter.emit = this.emit.bind(this);
const apiClientEmitter = {
on: this.on.bind(this),
off: this.off.bind(this),
once: this.once.bind(this),
emit: this.emit.bind(this)
};
return {
apiClientEmitter,
eventEmitter: new EventEmitter()
eventEmitter: ee({})
};
}
@@ -16,20 +16,18 @@
*/
import { HttpHeaders } from '@angular/common/http';
import { EventEmitter } from 'eventemitter3';
import ee from 'event-emitter';
import { Observable } from 'rxjs';
type EventEmitterInstance = InstanceType<typeof EventEmitter>;
export interface AuthenticationServiceInterface {
onError: any;
onLogin: any;
onLogout: any;
on: EventEmitterInstance['on'];
off: EventEmitterInstance['off'];
once: EventEmitterInstance['once'];
emit: EventEmitterInstance['emit'];
on: ee.EmitterMethod;
off: ee.EmitterMethod;
once: ee.EmitterMethod;
emit: (type: string, ...args: any[]) => void;
getToken(): string;
isLoggedIn(): boolean;
@@ -21,13 +21,13 @@ import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.serv
import { Observable, Subject, from } from 'rxjs';
import { HttpHeaders } from '@angular/common/http';
import { AuthenticationServiceInterface } from '../interfaces/authentication-service.interface';
import ee from 'event-emitter';
import { RedirectAuthService } from '../oidc/redirect-auth.service';
import { EventEmitter } from 'eventemitter3';
type EventEmitterInstance = InstanceType<typeof EventEmitter>;
@Injectable({
providedIn: 'root'
})
export class AuthenticationService implements AuthenticationServiceInterface {
export class AuthenticationService implements AuthenticationServiceInterface, ee.Emitter {
onLogin: Subject<any> = new Subject<any>();
onLogout: Subject<any> = new Subject<any>();
onTokenReceived: Subject<any> = new Subject<any>();
@@ -49,19 +49,19 @@ export class AuthenticationService implements AuthenticationServiceInterface {
}
}
get on(): EventEmitterInstance['on'] {
get on(): ee.EmitterMethod {
return this.isOauth() ? this.oidcAuthenticationService.on : this.basicAlfrescoAuthService.on;
}
get off(): EventEmitterInstance['off'] {
get off(): ee.EmitterMethod {
return this.isOauth() ? this.oidcAuthenticationService.off : this.basicAlfrescoAuthService.off;
}
get once(): EventEmitterInstance['once'] {
get once(): ee.EmitterMethod {
return this.isOauth() ? this.oidcAuthenticationService.once : this.basicAlfrescoAuthService.once;
}
get emit(): EventEmitterInstance['emit'] {
get emit(): (type: string, ...args: any[]) => void {
return this.isOauth() ? this.oidcAuthenticationService.emit : this.basicAlfrescoAuthService.emit;
}
@@ -21,15 +21,13 @@ import { Observable, Observer, ReplaySubject, throwError } from 'rxjs';
import { AppConfigService, AppConfigValues } from '../../app-config/app-config.service';
import { CookieService } from '../../common/services/cookie.service';
import { AuthenticationServiceInterface } from '../interfaces/authentication-service.interface';
import { EventEmitter } from 'eventemitter3';
import ee from 'event-emitter';
type EventEmitterInstance = InstanceType<typeof EventEmitter>;
export abstract class BaseAuthenticationService implements AuthenticationServiceInterface {
on: EventEmitterInstance['on'];
off: EventEmitterInstance['off'];
once: EventEmitterInstance['once'];
emit: EventEmitterInstance['emit'];
export abstract class BaseAuthenticationService implements AuthenticationServiceInterface, ee.Emitter {
on: ee.EmitterMethod;
off: ee.EmitterMethod;
once: ee.EmitterMethod;
emit: (type: string, ...args: any[]) => void;
protected redirectUrl: RedirectionModel = null;
@@ -40,7 +38,9 @@ export abstract class BaseAuthenticationService implements AuthenticationService
protected constructor(
protected appConfig: AppConfigService,
protected cookie: CookieService
) {}
) {
ee(this);
}
abstract getAuthHeaders(requestUrl: string, header: HttpHeaders): HttpHeaders;
abstract getToken(): string;
+1 -1
View File
@@ -15,7 +15,7 @@
"url": "https://github.com/Alfresco/alfresco-ng2-components/issues"
},
"dependencies": {
"eventemitter3": "^5.0.1",
"event-emitter": "^0.3.5",
"superagent": "^9.0.1",
"tslib": "^2.6.1"
},
+30 -21
View File
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { EventEmitter } from 'eventemitter3';
import ee, { EmitterMethod, Emitter } from 'event-emitter';
import { ContentAuth } from './authentication/contentAuth';
import { ProcessAuth } from './authentication/processAuth';
import { Oauth2Auth } from './authentication/oauth2Auth';
@@ -26,12 +26,11 @@ import { AlfrescoApiConfig } from './alfrescoApiConfig';
import { Authentication } from './authentication/authentication';
import { AlfrescoApiType } from './to-deprecate/alfresco-api-type';
import { HttpClient } from './api-clients/http-client.interface';
import { AlfrescoApiClient, AlfrescoApiClientPromise } from './alfrescoApiClient';
type EventEmitterInstance = InstanceType<typeof EventEmitter>;
export class AlfrescoApi extends AlfrescoApiClient implements AlfrescoApiType {
export class AlfrescoApi implements Emitter, AlfrescoApiType {
__type = 'legacy-client';
storage: Storage;
config: AlfrescoApiConfig;
contentClient: ContentClient;
contentPrivateClient: ContentClient;
processClient: ProcessClient;
@@ -44,11 +43,21 @@ export class AlfrescoApi extends AlfrescoApiClient implements AlfrescoApiType {
processAuth: ProcessAuth;
contentAuth: ContentAuth;
on: EmitterMethod;
off: EmitterMethod;
once: EmitterMethod;
bufferEvents: string[] = [];
emit: (type: string, ...args: any[]) => void;
username: string;
constructor(config?: AlfrescoApiConfig, httpClient?: HttpClient) {
super(undefined, httpClient);
constructor(
config?: AlfrescoApiConfig,
public httpClient?: HttpClient
) {
ee(this);
if (config) {
this.setConfig(config);
@@ -386,15 +395,14 @@ export class AlfrescoApi extends AlfrescoApiClient implements AlfrescoApiType {
return this.contentAuth.validateTicket();
}
private loginBPMECM(username: string, password: string): AlfrescoApiClientPromise<[string, string]> {
private loginBPMECM(username: string, password: string): Promise<[string, string]> {
const contentPromise = this.contentAuth.login(username, password);
const processPromise = this.processAuth.login(username, password);
const eventEmitter: EventEmitterInstance = new EventEmitter();
const promise = new Promise<[string, string]>((resolve, reject) => {
const promise: any = new Promise<[string, string]>((resolve, reject) => {
Promise.all([contentPromise, processPromise]).then(
(data) => {
eventEmitter.emit('success');
promise.emit('success');
resolve(data);
},
(error) => {
@@ -402,15 +410,16 @@ export class AlfrescoApi extends AlfrescoApiClient implements AlfrescoApiType {
this.processAuth.invalidateSession();
if (error.status === 401) {
eventEmitter.emit('unauthorized');
promise.emit('unauthorized');
}
eventEmitter.emit('error');
promise.emit('error');
reject(error);
}
);
});
return this.addPromiseListeners(promise, eventEmitter);
ee(promise); // jshint ignore:line
return promise;
}
/**
@@ -443,29 +452,29 @@ export class AlfrescoApi extends AlfrescoApiClient implements AlfrescoApiType {
return Promise.resolve();
}
private _logoutBPMECM(): AlfrescoApiClientPromise<void> {
private _logoutBPMECM(): Promise<void> {
const contentPromise = this.contentAuth.logout();
const processPromise = this.processAuth.logout();
const eventEmitter: EventEmitterInstance = new EventEmitter();
const promise = new Promise<void>((resolve, reject) => {
const promise: any = new Promise<void>((resolve, reject) => {
Promise.all([contentPromise, processPromise]).then(
() => {
this.config.ticket = undefined;
eventEmitter.emit('logout');
promise.emit('logout');
resolve();
},
(error) => {
if (error.status === 401) {
eventEmitter.emit('unauthorized');
promise.emit('unauthorized');
}
eventEmitter.emit('error');
promise.emit('error');
reject(error);
}
);
});
return this.addPromiseListeners(promise, eventEmitter);
ee(promise); // jshint ignore:line
return promise;
}
/**
+31 -41
View File
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { EventEmitter } from 'eventemitter3';
import ee from 'event-emitter';
import { AlfrescoApiConfig } from './alfrescoApiConfig';
import { Authentication } from './authentication/authentication';
import { SuperagentHttpClient } from './superagentHttpClient';
@@ -25,13 +25,11 @@ import { Storage } from './storage';
declare const Buffer: any;
type EventEmitterInstance = InstanceType<typeof EventEmitter>;
export type AlfrescoApiClientPromise<T = any> = Promise<T> & {
on: <K extends string | symbol>(event: K, fn: (...args: any[]) => void, context?: any) => AlfrescoApiClientPromise<T>;
off: <K extends string | symbol>(event: K, fn?: (...args: any[]) => void, context?: any) => AlfrescoApiClientPromise<T>;
once: <K extends string | symbol>(event: K, fn: (...args: any[]) => void, context?: any) => AlfrescoApiClientPromise<T>;
emit: <K extends string | symbol>(event: K, ...args: any[]) => boolean;
on: ee.EmitterMethod;
off: ee.EmitterMethod;
once: ee.EmitterMethod;
emit: (type: string, ...args: any[]) => void;
abort?: () => void;
};
@@ -64,8 +62,11 @@ export function buildCollectionParam(param: string[], collectionFormat: string):
}
}
export class AlfrescoApiClient implements LegacyHttpClient {
private eventEmitter = new EventEmitter();
export class AlfrescoApiClient implements ee.Emitter, LegacyHttpClient {
on: ee.EmitterMethod;
off: ee.EmitterMethod;
once: ee.EmitterMethod;
emit: (type: string, ...args: any[]) => void;
storage: Storage;
host: string;
@@ -104,29 +105,13 @@ export class AlfrescoApiClient implements LegacyHttpClient {
constructor(host?: string, httpClient?: HttpClient) {
this.host = host;
this.storage = Storage.getInstance();
// fallback for backward compatibility
this.httpClient = httpClient || new SuperagentHttpClient();
}
// EventEmitter delegation methods
on<K extends string | symbol>(event: K, fn: (...args: any[]) => void, context?: any): this {
this.eventEmitter.on(event, fn, context);
return this;
}
off<K extends string | symbol>(event: K, fn?: (...args: any[]) => void, context?: any): this {
this.eventEmitter.off(event, fn, context);
return this;
}
once<K extends string | symbol>(event: K, fn: (...args: any[]) => void, context?: any): this {
this.eventEmitter.once(event, fn, context);
return this;
}
emit<K extends string | symbol>(event: K, ...args: any[]): boolean {
return this.eventEmitter.emit(event, ...args);
ee(this);
}
request<T = any>(options: RequestOptions): Promise<T> {
@@ -340,7 +325,7 @@ export class AlfrescoApiClient implements LegacyHttpClient {
return {
apiClientEmitter,
eventEmitter: new EventEmitter()
eventEmitter: ee({})
};
}
@@ -389,22 +374,27 @@ export class AlfrescoApiClient implements LegacyHttpClient {
return Boolean(contentType?.match(/^application\/json(;.*)?$/i));
}
addPromiseListeners<T = any>(promise: Promise<T>, eventEmitter: EventEmitterInstance): AlfrescoApiClientPromise<T> {
private addPromiseListeners<T = any>(promise: Promise<T>, eventEmitter: ee.Emitter): AlfrescoApiClientPromise<T> {
return Object.assign(promise, {
on<K extends string | symbol>(event: K, fn: (...args: any[]) => void, context?: any): AlfrescoApiClientPromise<T> {
eventEmitter.on(event, fn, context);
return this as AlfrescoApiClientPromise<T>;
on() {
// eslint-disable-next-line prefer-spread,prefer-rest-params
eventEmitter.on.apply(eventEmitter, arguments);
return this;
},
once<K extends string | symbol>(event: K, fn: (...args: any[]) => void, context?: any): AlfrescoApiClientPromise<T> {
eventEmitter.once(event, fn, context);
return this as AlfrescoApiClientPromise<T>;
once() {
// eslint-disable-next-line prefer-spread,prefer-rest-params
eventEmitter.once.apply(eventEmitter, arguments);
return this;
},
emit<K extends string | symbol>(event: K, ...args: any[]): boolean {
return eventEmitter.emit(event, ...args);
emit() {
// eslint-disable-next-line prefer-spread,prefer-rest-params
eventEmitter.emit.apply(eventEmitter, arguments);
return this;
},
off<K extends string | symbol>(event: K, fn?: (...args: any[]) => void, context?: any): AlfrescoApiClientPromise<T> {
eventEmitter.off(event, fn, context);
return this as AlfrescoApiClientPromise<T>;
off() {
// eslint-disable-next-line prefer-spread,prefer-rest-params
eventEmitter.off.apply(eventEmitter, arguments);
return this;
}
});
}
@@ -16,9 +16,7 @@
*/
import { Authentication } from '../authentication/authentication';
import { EventEmitter } from 'eventemitter3';
type EventEmitterInstance = InstanceType<typeof EventEmitter>;
import { Emitter } from 'event-emitter';
export interface RequestOptions {
path: string;
@@ -95,13 +93,8 @@ export interface SecurityOptions {
}
export interface Emitters {
readonly eventEmitter: EventEmitterInstance;
readonly apiClientEmitter: {
on: EventEmitterInstance['on'];
off: EventEmitterInstance['off'];
once: EventEmitterInstance['once'];
emit: EventEmitterInstance['emit'];
};
readonly eventEmitter: Emitter;
readonly apiClientEmitter: Emitter;
}
export interface HttpClient {
+7 -4
View File
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { EventEmitter } from 'eventemitter3';
import ee from 'event-emitter';
import { AuthenticationApi, TicketBody } from '../api/auth-rest-api';
import { AlfrescoApiClient } from '../alfrescoApiClient';
import { AlfrescoApiConfig } from '../alfrescoApiConfig';
@@ -104,7 +104,8 @@ export class ContentAuth extends AlfrescoApiClient {
});
});
return this.addPromiseListeners(promise, new EventEmitter());
ee(promise); // jshint ignore:line
return promise;
}
/**
@@ -132,7 +133,8 @@ export class ContentAuth extends AlfrescoApiClient {
);
});
return this.addPromiseListeners(promise, new EventEmitter());
ee(promise); // jshint ignore:line
return promise;
}
/**
@@ -158,7 +160,8 @@ export class ContentAuth extends AlfrescoApiClient {
);
});
return this.addPromiseListeners(promise, new EventEmitter());
ee(promise); // jshint ignore:line
return promise;
}
/**
+5 -3
View File
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { EventEmitter } from 'eventemitter3';
import ee from 'event-emitter';
import { AlfrescoApiClient } from '../alfrescoApiClient';
import { AlfrescoApiConfig } from '../alfrescoApiConfig';
import { Authentication } from './authentication';
@@ -604,7 +604,7 @@ export class Oauth2Auth extends AlfrescoApiClient {
}
);
return this.addPromiseListeners(promise, new EventEmitter());
ee(promise); // jshint ignore:line
}
pollingRefreshToken() {
@@ -654,7 +654,9 @@ export class Oauth2Auth extends AlfrescoApiClient {
);
});
return this.addPromiseListeners(promise, new EventEmitter());
ee(promise); // jshint ignore:line
return promise;
}
universalBtoa(stringToConvert: string) {
+5 -3
View File
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { EventEmitter } from 'eventemitter3';
import ee from 'event-emitter';
import { AlfrescoApiClient, AlfrescoApiClientPromise } from '../alfrescoApiClient';
import { AlfrescoApiConfig } from '../alfrescoApiConfig';
import { Authentication } from './authentication';
@@ -123,7 +123,8 @@ export class ProcessAuth extends AlfrescoApiClient {
);
});
return this.addPromiseListeners(promise, new EventEmitter());
ee(promise); // jshint ignore:line
return promise;
}
/**
@@ -153,7 +154,8 @@ export class ProcessAuth extends AlfrescoApiClient {
);
});
return this.addPromiseListeners(promise, new EventEmitter());
ee(promise);
return promise;
}
/**
+3 -5
View File
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { EventEmitter } from 'eventemitter3';
import ee, { Emitter } from 'event-emitter';
import superagent, { Response, SuperAgentRequest } from 'superagent';
import { Authentication } from './authentication/authentication';
import { RequestOptions, HttpClient, SecurityOptions, Emitters } from './api-clients/http-client.interface';
@@ -26,8 +26,6 @@ import { isBrowser, paramToString } from './utils';
declare const Blob: any;
declare const Buffer: any;
type EventEmitterInstance = InstanceType<typeof EventEmitter>;
const isProgressEvent = (event: ProgressEvent | unknown): event is ProgressEvent => (event as ProgressEvent)?.lengthComputable;
export class SuperagentHttpClient implements HttpClient {
@@ -136,7 +134,7 @@ export class SuperagentHttpClient implements HttpClient {
contentType: string,
accept: string,
responseType: string,
eventEmitter: EventEmitterInstance,
eventEmitter: ee.Emitter,
returnType: string,
securityOptions: SecurityOptions
) {
@@ -270,7 +268,7 @@ export class SuperagentHttpClient implements HttpClient {
}
}
private progress(event: ProgressEvent | unknown, eventEmitter: EventEmitterInstance): void {
private progress(event: ProgressEvent | unknown, eventEmitter: Emitter): void {
if (isProgressEvent(event)) {
const percent = Math.round((event.loaded / event.total) * 100);