[ADF-5284] Restore original plugin functionality (#6348)

* add $ignoreReferenceList to ExtensionConfig interface

* update schema

* change type

* load registered extensions

* filter out ignored extensions

* tests

* conditionally load plugins

* update tests
This commit is contained in:
Cilibiu Bogdan
2020-11-16 19:42:35 +02:00
committed by GitHub
parent 4dfa9b6d53
commit 145e3244e7
5 changed files with 150 additions and 9 deletions

View File

@@ -41,4 +41,5 @@ export interface ExtensionRef {
export interface ExtensionConfig extends ExtensionRef { export interface ExtensionConfig extends ExtensionRef {
$references?: Array<string | ExtensionRef>; $references?: Array<string | ExtensionRef>;
$ignoreReferenceList?: Array<string>;
} }

View File

@@ -593,6 +593,15 @@
"minItems": 0, "minItems": 0,
"uniqueItems": true "uniqueItems": true
}, },
"$ignoreReferenceList": {
"description": "Plugins references to exclude",
"type": "array",
"items": {
"type": "string"
},
"minItems": 0,
"uniqueItems": true
},
"rules": { "rules": {
"description": "List of rule definitions", "description": "List of rule definitions",
"type": "array", "type": "array",

View File

@@ -0,0 +1,121 @@
/*!
* @license
* Copyright 2019 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { async, TestBed } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { ExtensionConfig } from '../config/extension.config';
import { ExtensionLoaderService } from './extension-loader.service';
import { HttpClient } from '@angular/common/http';
import { of } from 'rxjs';
describe('ExtensionLoaderService', () => {
let extensionLoaderService: ExtensionLoaderService;
let httpClient: HttpClient;
let appExtensionsConfig: ExtensionConfig;
const pluginConfig1: ExtensionConfig = {
$id: 'test1',
$name: 'test.extension.1',
$version: '1.0.0',
$vendor: 'Alfresco',
$license: 'MIT',
$runtime: '2.6.1'
};
const pluginConfig2: ExtensionConfig = {
$id: 'test2',
$name: 'test.extension.2',
$version: '1.0.0',
$vendor: 'Alfresco',
$license: 'MIT',
$runtime: '2.6.1'
};
const pluginConfig3: ExtensionConfig = {
$id: 'test3',
$name: 'test.extension.3',
$version: '1.0.0',
$vendor: 'Alfresco',
$license: 'MIT',
$runtime: '2.6.1'
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
HttpClient,
ExtensionLoaderService
]
});
extensionLoaderService = TestBed.inject(ExtensionLoaderService);
httpClient = TestBed.inject(HttpClient);
appExtensionsConfig = {
$id: 'test',
$name: 'test.config',
$version: '1.0.0',
$vendor: 'Alfresco',
$license: 'MIT',
$runtime: '2.6.1',
$references: [],
$ignoreReferenceList: []
};
spyOn(httpClient, 'get').and.callFake((url: string) => {
if (url === 'assets/app.extensions.json') {
return of(appExtensionsConfig);
}
if (url === 'assets/plugins/test.extension.1.json') {
return of(pluginConfig1);
}
if (url === 'assets/plugins/test.extension.2.json') {
return of(pluginConfig2);
}
if (url === 'assets/plugins/test.extension.3.json') {
return of(pluginConfig3);
}
return of({});
});
});
it('should load default registered app extensions when no custom $references defined', async(() => {
extensionLoaderService.load('assets/app.extensions.json', 'assets/plugins', ['test.extension.1.json']).then((config: ExtensionConfig) => {
const pluginsReference = config.$references.map((entry: ExtensionConfig) => entry.$name);
expect(pluginsReference).toEqual(['test.extension.1']);
});
}));
it('should ignore default registered app extension if defined in $ignoreReferenceList', async(() => {
appExtensionsConfig.$ignoreReferenceList = ['test.extension.1.json'];
extensionLoaderService.load('assets/app.extensions.json', 'assets/plugins', ['test.extension.1.json']).then((config: ExtensionConfig) => {
const pluginsReference = config.$references.map((entry: ExtensionConfig) => entry.$name);
expect(pluginsReference).toEqual([]);
});
}));
it('should load only extensions defined by $references', async(() => {
appExtensionsConfig.$references = ['test.extension.1.json'];
extensionLoaderService.load('assets/app.extensions.json', 'assets/plugins', ['test.extension.2.json, test.extension.3.json']).then((config: ExtensionConfig) => {
const pluginsReference = config.$references.map((entry: ExtensionConfig) => entry.$name);
expect(pluginsReference).toEqual(['test.extension.1']);
});
}));
});

View File

@@ -31,7 +31,7 @@ export class ExtensionLoaderService {
constructor(private http: HttpClient) { constructor(private http: HttpClient) {
} }
load(configPath: string, pluginsPath: string, extensions?: ExtensionConfig[]): Promise<ExtensionConfig> { load(configPath: string, pluginsPath: string, extensions?: string[]): Promise<ExtensionConfig> {
return new Promise<any>((resolve) => { return new Promise<any>((resolve) => {
this.loadConfig(configPath, 0).then((result) => { this.loadConfig(configPath, 0).then((result) => {
if (result) { if (result) {
@@ -42,6 +42,12 @@ export class ExtensionLoaderService {
config = JSON.parse(override); config = JSON.parse(override);
} }
if (!config.$references || !config.$references.length) {
config.$references = this.filterIgnoredExtensions(extensions || [], config.$ignoreReferenceList);
} else {
config.$references = this.filterIgnoredExtensions(config.$references, config.$ignoreReferenceList);
}
if (config.$references && config.$references.length > 0) { if (config.$references && config.$references.length > 0) {
const plugins = config.$references.map((name, idx) => const plugins = config.$references.map((name, idx) =>
this.loadConfig(`${pluginsPath}/${name}`, idx) this.loadConfig(`${pluginsPath}/${name}`, idx)
@@ -53,10 +59,6 @@ export class ExtensionLoaderService {
.sort(sortByOrder) .sort(sortByOrder)
.map((entry) => entry.config); .map((entry) => entry.config);
if (extensions && extensions.length > 0) {
configs.push(...extensions);
}
if (configs.length > 0) { if (configs.length > 0) {
config = mergeObjects(config, ...configs); config = mergeObjects(config, ...configs);
} }
@@ -166,4 +168,12 @@ export class ExtensionLoaderService {
} }
return action; return action;
} }
private filterIgnoredExtensions(extensions: Array<string | ExtensionRef>, ignoreReferenceList: string[]): Array<string | ExtensionRef> {
if (!ignoreReferenceList || !ignoreReferenceList.length) {
return extensions;
}
return extensions.map((file: string) => file.match('(?!.*\/).+')[0]).filter((fileName: string) => !ignoreReferenceList.includes(fileName));
}
} }

View File

@@ -17,7 +17,7 @@
import { Injectable, Type, InjectionToken, Inject } from '@angular/core'; import { Injectable, Type, InjectionToken, Inject } from '@angular/core';
import { RuleEvaluator, RuleRef, RuleContext } from '../config/rule.extensions'; import { RuleEvaluator, RuleRef, RuleContext } from '../config/rule.extensions';
import { ExtensionConfig, ExtensionRef } from '../config/extension.config'; import { ExtensionConfig } from '../config/extension.config';
import { ExtensionLoaderService } from './extension-loader.service'; import { ExtensionLoaderService } from './extension-loader.service';
import { RouteRef } from '../config/routing.extensions'; import { RouteRef } from '../config/routing.extensions';
import { ActionRef } from '../config/action.extensions'; import { ActionRef } from '../config/action.extensions';
@@ -30,12 +30,12 @@ export function extensionJsonsFactory() {
return []; return [];
} }
export const EXTENSION_JSONS = new InjectionToken<ExtensionRef[][]>('extension-jsons', { export const EXTENSION_JSONS = new InjectionToken<string[][]>('extension-jsons', {
providedIn: 'root', providedIn: 'root',
factory: extensionJsonsFactory factory: extensionJsonsFactory
}); });
export function provideExtensionConfig(jsons: ExtensionRef[]) { export function provideExtensionConfig(jsons: string[]) {
return { return {
provide: EXTENSION_JSONS, provide: EXTENSION_JSONS,
useValue: jsons, useValue: jsons,
@@ -62,7 +62,7 @@ export class ExtensionService {
protected loader: ExtensionLoaderService, protected loader: ExtensionLoaderService,
protected componentRegister: ComponentRegisterService, protected componentRegister: ComponentRegisterService,
protected ruleService: RuleService, protected ruleService: RuleService,
@Inject(EXTENSION_JSONS) protected extensionJsons: ExtensionRef[] @Inject(EXTENSION_JSONS) protected extensionJsons: string[]
) { ) {
} }