From 1719d8138060627832bdbd6f7e9fd856362abe9e Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Fri, 4 Feb 2022 11:15:31 +0000 Subject: [PATCH 1/2] fix eslint warnings for Extensions project --- lib/extensions/.eslintrc.json | 13 +--- .../dynamic.component.spec.ts | 2 +- .../dynamic-component/dynamic.component.ts | 14 ++-- .../src/lib/config/action.extensions.ts | 5 +- .../src/lib/config/extension-utils.spec.ts | 4 +- .../src/lib/config/extension-utils.ts | 34 +++++----- .../src/lib/config/sidebar.extensions.ts | 2 +- .../src/lib/config/viewer.extensions.ts | 2 +- .../lib/evaluators/core.evaluators.spec.ts | 2 +- .../src/lib/evaluators/core.evaluators.ts | 12 ++-- .../lib/mock/app-extension.service.mock.ts | 4 +- .../src/lib/services/app-extension.service.ts | 6 +- .../lib/services/extension-loader.service.ts | 64 +++++++++---------- .../lib/services/extension.service.spec.ts | 51 ++++++--------- .../src/lib/services/extension.service.ts | 26 ++++---- .../src/lib/services/rule.service.ts | 8 ++- .../lib/services/startup-extension-factory.ts | 4 +- 17 files changed, 111 insertions(+), 142 deletions(-) diff --git a/lib/extensions/.eslintrc.json b/lib/extensions/.eslintrc.json index 8ec87431981..694cb0a1cea 100644 --- a/lib/extensions/.eslintrc.json +++ b/lib/extensions/.eslintrc.json @@ -20,18 +20,7 @@ "eslint-plugin-rxjs" ], "rules": { - "jsdoc/newline-after-description": "warn", - "@typescript-eslint/naming-convention": "warn", - "@typescript-eslint/consistent-type-assertions": "warn", - "@typescript-eslint/prefer-for-of": "warn", - "no-underscore-dangle": "warn", - "no-shadow": "warn", - "quote-props": "warn", - "object-shorthand": "warn", - "prefer-const": "warn", - "arrow-body-style": "warn", - "@angular-eslint/no-output-native": "warn", - "space-before-function-paren": "warn", + "no-underscore-dangle": ["error", { "allowAfterThis": true }], "@angular-eslint/component-selector": [ "error", diff --git a/lib/extensions/src/lib/components/dynamic-component/dynamic.component.spec.ts b/lib/extensions/src/lib/components/dynamic-component/dynamic.component.spec.ts index 7b47d83d50c..4ce8eaec74e 100644 --- a/lib/extensions/src/lib/components/dynamic-component/dynamic.component.spec.ts +++ b/lib/extensions/src/lib/components/dynamic-component/dynamic.component.spec.ts @@ -93,7 +93,7 @@ describe('DynamicExtensionComponent', () => { component.ngOnChanges({}); fixture.detectChanges(); - expect(( componentFactoryResolver.resolveComponentFactory).calls.count()).toBe(1); + expect((componentFactoryResolver.resolveComponentFactory as any).calls.count()).toBe(1); }); it('should pass through the data', () => { diff --git a/lib/extensions/src/lib/components/dynamic-component/dynamic.component.ts b/lib/extensions/src/lib/components/dynamic-component/dynamic.component.ts index 3c3fbc0674d..e45c378ca01 100644 --- a/lib/extensions/src/lib/components/dynamic-component/dynamic.component.ts +++ b/lib/extensions/src/lib/components/dynamic-component/dynamic.component.ts @@ -63,6 +63,13 @@ export class DynamicExtensionComponent implements OnChanges, OnDestroy { this.proxy('ngOnChanges', changes); } + ngOnDestroy() { + if (this.componentCreated()) { + this.componentRef.destroy(); + this.componentRef = null; + } + } + private loadComponent() { const componentType = this.extensions.getComponentById(this.id); if (componentType) { @@ -76,13 +83,6 @@ export class DynamicExtensionComponent implements OnChanges, OnDestroy { } } - ngOnDestroy() { - if (this.componentCreated()) { - this.componentRef.destroy(); - this.componentRef = null; - } - } - private updateInstance() { if (this.componentCreated()) { this.componentRef.instance.data = this.data; diff --git a/lib/extensions/src/lib/config/action.extensions.ts b/lib/extensions/src/lib/config/action.extensions.ts index bfeb9569bd1..d27edb5e559 100644 --- a/lib/extensions/src/lib/config/action.extensions.ts +++ b/lib/extensions/src/lib/config/action.extensions.ts @@ -17,6 +17,7 @@ import { ExtensionElement } from './extension-element'; +// eslint-disable-next-line no-shadow export enum ContentActionType { default = 'default', button = 'button', @@ -36,13 +37,13 @@ export interface ContentActionRef extends ExtensionElement { data?: any; color?: string; actions?: { - click?: string; [key: string]: string; + click?: string; }; rules?: { + [key: string]: string; enabled?: string; visible?: string; - [key: string]: string; }; } diff --git a/lib/extensions/src/lib/config/extension-utils.spec.ts b/lib/extensions/src/lib/config/extension-utils.spec.ts index 54e532a2fb1..b2821b6fb79 100644 --- a/lib/extensions/src/lib/config/extension-utils.spec.ts +++ b/lib/extensions/src/lib/config/extension-utils.spec.ts @@ -45,8 +45,8 @@ describe('Extension Utils', () => { }); it('should not process special properties starting with $', () => { - const obj1 = { '$id': 'uid', aHello: 1 }; - const obj2 = { '$schema': 'schema-id', bWorld: 2 }; + const obj1 = { $id: 'uid', aHello: 1 }; + const obj2 = { $schema: 'schema-id', bWorld: 2 }; const result = mergeObjects(obj1, obj2); diff --git a/lib/extensions/src/lib/config/extension-utils.ts b/lib/extensions/src/lib/config/extension-utils.ts index 3b1c12429ae..74fc785c5fb 100644 --- a/lib/extensions/src/lib/config/extension-utils.ts +++ b/lib/extensions/src/lib/config/extension-utils.ts @@ -17,7 +17,7 @@ import { ContentActionRef, ContentActionType } from './action.extensions'; -export function getValue(target: any, key: string): any { +export const getValue = (target: any, key: string): any => { if (!target) { return undefined; } @@ -42,27 +42,25 @@ export function getValue(target: any, key: string): any { } while (keys.length); return target; -} +}; -export function filterEnabled(entry: { disabled?: boolean }): boolean { - return !entry.disabled; -} +export const filterEnabled = (entry: { disabled?: boolean }): boolean => !entry.disabled; -export function sortByOrder( +export const sortByOrder = ( a: { order?: number | undefined }, b: { order?: number | undefined } -) { +) => { const left = a.order === undefined ? Number.MAX_SAFE_INTEGER : a.order; const right = b.order === undefined ? Number.MAX_SAFE_INTEGER : b.order; return left - right; -} +}; -export function reduceSeparators( +export const reduceSeparators = ( acc: ContentActionRef[], el: ContentActionRef, i: number, arr: ContentActionRef[] -): ContentActionRef[] { +): ContentActionRef[] => { // remove leading separator if (i === 0) { if (arr[i].type === ContentActionType.separator) { @@ -88,21 +86,21 @@ export function reduceSeparators( } return acc.concat(el); -} +}; -export function reduceEmptyMenus( +export const reduceEmptyMenus = ( acc: ContentActionRef[], el: ContentActionRef -): ContentActionRef[] { +): ContentActionRef[] => { if (el.type === ContentActionType.menu) { if ((el.children || []).length === 0) { return acc; } } return acc.concat(el); -} +}; -export function mergeObjects(...objects: any[]): any { +export const mergeObjects = (...objects: any[]): any => { const result = {}; objects.forEach((source) => { @@ -129,9 +127,9 @@ export function mergeObjects(...objects: any[]): any { }); return result; -} +}; -export function mergeArrays(left: any[], right: any[]): any[] { +export const mergeArrays = (left: any[], right: any[]): any[] => { const result = []; const map = {}; @@ -155,4 +153,4 @@ export function mergeArrays(left: any[], right: any[]): any[] { }); return Object.keys(map).map((key) => map[key]).concat(result); -} +}; diff --git a/lib/extensions/src/lib/config/sidebar.extensions.ts b/lib/extensions/src/lib/config/sidebar.extensions.ts index 59ffcece8c0..916f918f393 100644 --- a/lib/extensions/src/lib/config/sidebar.extensions.ts +++ b/lib/extensions/src/lib/config/sidebar.extensions.ts @@ -23,7 +23,7 @@ export interface SidebarTabRef extends ExtensionElement { icon?: string; rules?: { - visible?: string; [key: string]: string; + visible?: string; }; } diff --git a/lib/extensions/src/lib/config/viewer.extensions.ts b/lib/extensions/src/lib/config/viewer.extensions.ts index 6a4768dcdfd..fb373397f58 100644 --- a/lib/extensions/src/lib/config/viewer.extensions.ts +++ b/lib/extensions/src/lib/config/viewer.extensions.ts @@ -22,7 +22,7 @@ export interface ViewerExtensionRef extends ExtensionElement { component: string; rules?: { - visible?: string; [key: string]: string; + visible?: string; }; } diff --git a/lib/extensions/src/lib/evaluators/core.evaluators.spec.ts b/lib/extensions/src/lib/evaluators/core.evaluators.spec.ts index af520dae646..a586ccdc12f 100644 --- a/lib/extensions/src/lib/evaluators/core.evaluators.spec.ts +++ b/lib/extensions/src/lib/evaluators/core.evaluators.spec.ts @@ -21,7 +21,7 @@ import { RuleParameter } from '../config/rule.extensions'; describe('Core Evaluators', () => { const context: any = { - getEvaluator(key: string) { + getEvaluator: (key: string) => { switch (key) { case 'positive': return () => true; diff --git a/lib/extensions/src/lib/evaluators/core.evaluators.ts b/lib/extensions/src/lib/evaluators/core.evaluators.ts index ea0bb7718a4..927504c119d 100644 --- a/lib/extensions/src/lib/evaluators/core.evaluators.ts +++ b/lib/extensions/src/lib/evaluators/core.evaluators.ts @@ -17,7 +17,7 @@ import { RuleContext, RuleParameter } from '../config/rule.extensions'; -export function not(context: RuleContext, ...args: RuleParameter[]): boolean { +export const not = (context: RuleContext, ...args: RuleParameter[]): boolean => { if (!args || args.length === 0) { return false; } @@ -31,9 +31,9 @@ export function not(context: RuleContext, ...args: RuleParameter[]): boolean { } return !evaluator(context, ...(arg.parameters || [])); }); -} +}; -export function every(context: RuleContext, ...args: RuleParameter[]): boolean { +export const every = (context: RuleContext, ...args: RuleParameter[]): boolean => { if (!args || args.length === 0) { return false; } @@ -47,9 +47,9 @@ export function every(context: RuleContext, ...args: RuleParameter[]): boolean { } return evaluator(context, ...(arg.parameters || [])); }); -} +}; -export function some(context: RuleContext, ...args: RuleParameter[]): boolean { +export const some = (context: RuleContext, ...args: RuleParameter[]): boolean => { if (!args || args.length === 0) { return false; } @@ -63,4 +63,4 @@ export function some(context: RuleContext, ...args: RuleParameter[]): boolean { } return evaluator(context, ...(arg.parameters || [])); }); -} +}; diff --git a/lib/extensions/src/lib/mock/app-extension.service.mock.ts b/lib/extensions/src/lib/mock/app-extension.service.mock.ts index 7e54ebd0084..9fbffe3f9ae 100644 --- a/lib/extensions/src/lib/mock/app-extension.service.mock.ts +++ b/lib/extensions/src/lib/mock/app-extension.service.mock.ts @@ -24,9 +24,8 @@ import { ViewerExtensionRef } from '../config/viewer.extensions'; providedIn: 'root' }) export class AppExtensionServiceMock { - private _references = new BehaviorSubject([]); - references$: Observable; + private _references = new BehaviorSubject([]); constructor() { this.references$ = this._references.asObservable(); @@ -35,5 +34,4 @@ export class AppExtensionServiceMock { getViewerExtensions(): ViewerExtensionRef[] { return []; } - } diff --git a/lib/extensions/src/lib/services/app-extension.service.ts b/lib/extensions/src/lib/services/app-extension.service.ts index 99fe9592bab..f0344b87a78 100644 --- a/lib/extensions/src/lib/services/app-extension.service.ts +++ b/lib/extensions/src/lib/services/app-extension.service.ts @@ -26,9 +26,8 @@ import { DocumentListPresetRef } from '../config/document-list.extensions'; providedIn: 'root' }) export class AppExtensionService { - private _references = new BehaviorSubject([]); - references$: Observable; + private _references = new BehaviorSubject([]); constructor(protected extensionService: ExtensionService) { this.references$ = this._references.asObservable(); @@ -46,13 +45,14 @@ export class AppExtensionService { const references = (config.$references || []) .filter((entry) => typeof entry === 'object') - .map((entry) => entry); + .map((entry) => entry as ExtensionRef); this._references.next(references); } /** * Provides a collection of document list columns for the particular preset. * The result is filtered by the **disabled** state. + * * @param key Preset key. */ getDocumentListPreset(key: string): DocumentListPresetRef[] { diff --git a/lib/extensions/src/lib/services/extension-loader.service.ts b/lib/extensions/src/lib/services/extension-loader.service.ts index 3f2635f43a0..357369f8d96 100644 --- a/lib/extensions/src/lib/services/extension-loader.service.ts +++ b/lib/extensions/src/lib/services/extension-loader.service.ts @@ -79,38 +79,6 @@ export class ExtensionLoaderService { }); } - protected getMetadata(config: ExtensionConfig): ExtensionRef { - const result: any = {}; - - Object - .keys(config) - .filter((key) => key.startsWith('$')) - .forEach((key) => { - result[key] = config[key]; - }); - - return result; - } - - protected loadConfig( - url: string, - order: number - ): Promise<{ order: number; config: ExtensionConfig }> { - return new Promise((resolve) => { - this.http.get(url).subscribe( - (config) => { - resolve({ - order, - config - }); - }, - () => { - resolve(null); - } - ); - }); - } - /** * Retrieves configuration elements. * Filters element by **enabled** and **order** attributes. @@ -161,6 +129,38 @@ export class ExtensionLoaderService { return []; } + protected getMetadata(config: ExtensionConfig): ExtensionRef { + const result: any = {}; + + Object + .keys(config) + .filter((key) => key.startsWith('$')) + .forEach((key) => { + result[key] = config[key]; + }); + + return result; + } + + protected loadConfig( + url: string, + order: number + ): Promise<{ order: number; config: ExtensionConfig }> { + return new Promise((resolve) => { + this.http.get(url).subscribe( + (config) => { + resolve({ + order, + config + }); + }, + () => { + resolve(null); + } + ); + }); + } + protected setActionDefaults(action: ContentActionRef): ContentActionRef { if (action) { action.type = action.type || ContentActionType.default; diff --git a/lib/extensions/src/lib/services/extension.service.spec.ts b/lib/extensions/src/lib/services/extension.service.spec.ts index f54ee94e856..833e1393b86 100644 --- a/lib/extensions/src/lib/services/extension.service.spec.ts +++ b/lib/extensions/src/lib/services/extension.service.spec.ts @@ -47,10 +47,7 @@ describe('ExtensionService', () => { }); it('should load and setup a config', async () => { - spyOn(loader, 'load').and.callFake(() => { - return Promise.resolve(blankConfig); - }); - + spyOn(loader, 'load').and.callFake(() => Promise.resolve(blankConfig)); spyOn(service, 'setup').and.stub(); await service.load(); @@ -82,8 +79,8 @@ describe('ExtensionService', () => { const evaluator2 = () => false; service.setEvaluators({ - 'eval1': evaluator1, - 'eval2': evaluator2 + eval1: evaluator1, + eval2: evaluator2 }); expect(service.getEvaluator('eval1')).toBe(evaluator1); @@ -100,7 +97,7 @@ describe('ExtensionService', () => { service.setEvaluators({ 'core.every': evaluator1, - 'eval2': evaluator2 + eval2: evaluator2 }); expect(service.getEvaluator('core.every')).toBe(evaluator1); @@ -111,7 +108,7 @@ describe('ExtensionService', () => { const positive = () => true; service.setEvaluators({ - 'positive': positive + positive }); let evaluator = service.getEvaluator('positive'); @@ -136,8 +133,8 @@ describe('ExtensionService', () => { const guard2: any = {}; service.setAuthGuards({ - 'auth1': guard1, - 'auth2': guard2 + auth1: guard1, + auth2: guard2 }); registered = service.getAuthGuards(['auth1', 'auth2']); @@ -151,13 +148,13 @@ describe('ExtensionService', () => { const guard2: any = {}; service.setAuthGuards({ - 'auth': guard1 + auth: guard1 }); expect(service.getAuthGuards(['auth'])).toEqual([guard1]); service.setAuthGuards({ - 'auth': guard2 + auth: guard2 }); expect(service.getAuthGuards(['auth'])).toEqual([guard2]); @@ -167,7 +164,7 @@ describe('ExtensionService', () => { const guard1: any = {}; service.setAuthGuards({ - 'auth': guard1 + auth: guard1 }); service.setAuthGuards(null); @@ -184,7 +181,7 @@ describe('ExtensionService', () => { const component: any = {}; service.setComponents({ - 'component1': component + component1: component }); expect(service.getComponentById('component1')).toBe(component); @@ -195,13 +192,13 @@ describe('ExtensionService', () => { const component2: any = {}; service.setComponents({ - 'component': component1 + component: component1 }); expect(service.getComponentById('component')).toBe(component1); service.setComponents({ - 'component': component2 + component: component2 }); expect(service.getComponentById('component')).toBe(component2); @@ -211,7 +208,7 @@ describe('ExtensionService', () => { const component: any = {}; service.setComponents({ - 'component1': component + component1: component }); expect(service.getComponentById('component1')).toBe(component); @@ -266,9 +263,7 @@ describe('ExtensionService', () => { }); const context: any = { - getEvaluator(key: string) { - return service.getEvaluator(key); - } + getEvaluator: (key: string) => service.getEvaluator(key) }; const result = service.evaluateRule('test.condition', context); @@ -277,9 +272,7 @@ describe('ExtensionService', () => { it('should evaluate missing condition as [false]', () => { const context: any = { - getEvaluator(key: string) { - return service.getEvaluator(key); - } + getEvaluator: (key: string) => service.getEvaluator(key) }; const result = service.evaluateRule('missing.condition', context); @@ -308,9 +301,7 @@ describe('ExtensionService', () => { }); const context: any = { - getEvaluator(key: string) { - return service.getEvaluator(key); - } + getEvaluator: (key: string) => service.getEvaluator(key) }; const result = service.evaluateRule('test.rule', context); @@ -327,9 +318,7 @@ describe('ExtensionService', () => { service.setup(blankConfig); const context: any = { - getEvaluator(key: string) { - return service.getEvaluator(key); - } + getEvaluator: (key: string) => service.getEvaluator(key) }; const result = service.evaluateRule('test.rule', context); @@ -352,9 +341,7 @@ describe('ExtensionService', () => { service.setup(blankConfig); const context: any = { - getEvaluator(key: string) { - return service.getEvaluator(key); - } + getEvaluator: (key: string) => service.getEvaluator(key) }; const result = service.evaluateRule('test.rule', context); diff --git a/lib/extensions/src/lib/services/extension.service.ts b/lib/extensions/src/lib/services/extension.service.ts index d8f453c8d1a..cba3cb92e72 100644 --- a/lib/extensions/src/lib/services/extension.service.ts +++ b/lib/extensions/src/lib/services/extension.service.ts @@ -25,32 +25,25 @@ import * as core from '../evaluators/core.evaluators'; import { ComponentRegisterService } from './component-register.service'; import { RuleService } from './rule.service'; import { ExtensionElement } from '../config/extension-element'; -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; -export function extensionJsonsFactory() { - return []; -} +export const extensionJsonsFactory = () => []; export const EXTENSION_JSONS = new InjectionToken('extension-jsons', { providedIn: 'root', factory: extensionJsonsFactory }); -export function provideExtensionConfig(jsons: string[]) { - return { - provide: EXTENSION_JSONS, - useValue: jsons, - multi: true - }; -} +export const provideExtensionConfig = (jsons: string[]) => ({ + provide: EXTENSION_JSONS, + useValue: jsons, + multi: true +}); @Injectable({ providedIn: 'root' }) export class ExtensionService { - - protected config: ExtensionConfig = null; - configPath = 'assets/app.extensions.json'; pluginsPath = 'assets/plugins'; @@ -59,8 +52,10 @@ export class ExtensionService { features: Array = []; authGuards: { [key: string]: Type } = {}; + setup$: Observable; + + protected config: ExtensionConfig = null; protected onSetup$ = new BehaviorSubject(this.config); - setup$ = this.onSetup$.asObservable(); constructor( protected loader: ExtensionLoaderService, @@ -68,6 +63,7 @@ export class ExtensionService { protected ruleService: RuleService, @Inject(EXTENSION_JSONS) protected extensionJsons: string[] ) { + this.setup$ = this.onSetup$.asObservable(); } /** diff --git a/lib/extensions/src/lib/services/rule.service.ts b/lib/extensions/src/lib/services/rule.service.ts index 7b348b06411..39753efdb8c 100644 --- a/lib/extensions/src/lib/services/rule.service.ts +++ b/lib/extensions/src/lib/services/rule.service.ts @@ -36,6 +36,7 @@ export class RuleService { /** * Adds one or more new rule evaluators to the existing set. + * * @param values The new evaluators to add */ setEvaluators(values: { [key: string]: RuleEvaluator }) { @@ -46,6 +47,7 @@ export class RuleService { /** * Retrieves a rule using its ID value. + * * @param id The ID value to look for * @returns The rule or null if not found */ @@ -55,21 +57,21 @@ export class RuleService { /** * Retrieves a RuleEvaluator function using its key name. + * * @param key Key name to look for * @returns RuleEvaluator or null if not found */ getEvaluator(key: string): RuleEvaluator { if (key && key.startsWith('!')) { const fn = this.evaluators[key.substring(1)]; - return (context: RuleContext, ...args: RuleParameter[]): boolean => { - return !fn(context, ...args); - }; + return (context: RuleContext, ...args: RuleParameter[]): boolean => !fn(context, ...args); } return this.evaluators[key]; } /** * Evaluates a rule. + * * @param ruleId ID of the rule to evaluate * @param context Custom rule execution context. * @returns True if the rule passed, false otherwise diff --git a/lib/extensions/src/lib/services/startup-extension-factory.ts b/lib/extensions/src/lib/services/startup-extension-factory.ts index 9b45d458a32..6c841df1419 100644 --- a/lib/extensions/src/lib/services/startup-extension-factory.ts +++ b/lib/extensions/src/lib/services/startup-extension-factory.ts @@ -17,6 +17,4 @@ import { AppExtensionService } from './app-extension.service'; -export function setupExtensions(appExtensionService: AppExtensionService) { - return () => appExtensionService.load(); -} +export const setupExtensions = (appExtensionService: AppExtensionService) => () => appExtensionService.load(); From c8cde62c6a39a09bcfdf6aee8ccd97bf521674a7 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Tue, 8 Feb 2022 10:43:27 +0000 Subject: [PATCH 2/2] fix production mode compilation --- .../src/lib/services/extension.service.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/extensions/src/lib/services/extension.service.ts b/lib/extensions/src/lib/services/extension.service.ts index cba3cb92e72..e54fc708448 100644 --- a/lib/extensions/src/lib/services/extension.service.ts +++ b/lib/extensions/src/lib/services/extension.service.ts @@ -27,18 +27,24 @@ import { RuleService } from './rule.service'; import { ExtensionElement } from '../config/extension-element'; import { BehaviorSubject, Observable } from 'rxjs'; -export const extensionJsonsFactory = () => []; +// eslint-disable-next-line prefer-arrow/prefer-arrow-functions +export function extensionJsonsFactory() { + return []; +}; export const EXTENSION_JSONS = new InjectionToken('extension-jsons', { providedIn: 'root', factory: extensionJsonsFactory }); -export const provideExtensionConfig = (jsons: string[]) => ({ - provide: EXTENSION_JSONS, - useValue: jsons, - multi: true -}); +// eslint-disable-next-line prefer-arrow/prefer-arrow-functions +export function provideExtensionConfig(jsons: string[]) { + return { + provide: EXTENSION_JSONS, + useValue: jsons, + multi: true + }; +}; @Injectable({ providedIn: 'root'