From a1b4c54b1612ae278bf75f4f9b3b8df73a98b978 Mon Sep 17 00:00:00 2001 From: Bartosz Sekula Date: Sat, 23 Dec 2023 12:39:48 +0100 Subject: [PATCH] Allow to use extension value in addition to passing JSON file name (#9192) * [AAE-18136] Allow to use extension value * Apply suggestions from code review Co-authored-by: Robert Duda --------- Co-authored-by: Robert Duda --- .../services/extension-loader.service.spec.ts | 66 +++++++++++++++++++ .../lib/services/extension-loader.service.ts | 21 ++++-- .../lib/services/extension.service.spec.ts | 4 +- .../src/lib/services/extension.service.ts | 26 +++++++- 4 files changed, 109 insertions(+), 8 deletions(-) diff --git a/lib/extensions/src/lib/services/extension-loader.service.spec.ts b/lib/extensions/src/lib/services/extension-loader.service.spec.ts index 63f9115aefb..790e173adcc 100644 --- a/lib/extensions/src/lib/services/extension-loader.service.spec.ts +++ b/lib/extensions/src/lib/services/extension-loader.service.spec.ts @@ -121,4 +121,70 @@ describe('ExtensionLoaderService', () => { done(); }); }); + + it('should load extensions from passed extension value', (done) => { + appExtensionsConfig.$references = ['test.extension.1.json']; + + extensionLoaderService.load( + 'assets/app.extensions.json', + 'assets/plugins', + undefined, + [{ + $id: 'extension-value-id', + $license: 'license', + $name: 'name', + $version:'version', + $vendor: 'vendor' + }]).then((config: ExtensionConfig) => { + const hasExtensionValue = config.$references.some((entry: ExtensionConfig) => entry.$id === 'extension-value-id'); + expect(hasExtensionValue).toBe(true); + done(); + }); + }); + + it('should load extensions if only extension value was passed', (done) => { + extensionLoaderService.load( + 'assets/app.extensions.json', + 'assets/plugins', + undefined, + [{ + $id: 'extension-value-id', + $license: 'license', + $name: 'name', + $version:'version', + $vendor: 'vendor' + }]).then((config: ExtensionConfig) => { + const hasExtensionValue = config.$references.some((entry: ExtensionConfig) => entry.$id === 'extension-value-id'); + expect(hasExtensionValue).toBe(true); + done(); + }); + }); + + it('should load extensions with multiple extension values', (done) => { + appExtensionsConfig.$references = ['test.extension.1.json']; + + extensionLoaderService.load( + 'assets/app.extensions.json', + 'assets/plugins', + undefined, + [{ + $id: 'extension-value-id-1', + $license: 'license', + $name: 'name', + $version:'version', + $vendor: 'vendor' + },{ + $id: 'extension-value-id-2', + $license: 'license', + $name: 'name', + $version:'version', + $vendor: 'vendor' + }]).then((config: ExtensionConfig) => { + const hasFirstExtensionValue = config.$references.some((entry: ExtensionConfig) => entry.$id === 'extension-value-id-1'); + expect(hasFirstExtensionValue).toBe(true); + const hasSecondExtensionValue = config.$references.some((entry: ExtensionConfig) => entry.$id === 'extension-value-id-2'); + expect(hasSecondExtensionValue).toBe(true); + done(); + }); + }); }); diff --git a/lib/extensions/src/lib/services/extension-loader.service.ts b/lib/extensions/src/lib/services/extension-loader.service.ts index 26f9906315a..1e036bce8c7 100644 --- a/lib/extensions/src/lib/services/extension-loader.service.ts +++ b/lib/extensions/src/lib/services/extension-loader.service.ts @@ -31,7 +31,12 @@ export class ExtensionLoaderService { constructor(private http: HttpClient) { } - load(configPath: string, pluginsPath: string, extensions?: string[]): Promise { + load( + configPath: string, + pluginsPath: string, + extensions?: string[], + extensionValues?: ExtensionConfig[] + ): Promise { return new Promise((resolve) => { this.loadConfig(configPath, 0).then((result) => { if (result) { @@ -48,17 +53,25 @@ export class ExtensionLoaderService { config.$references = this.filterIgnoredExtensions(config.$references, config.$ignoreReferenceList); } - if (config.$references && config.$references.length > 0) { - const plugins = config.$references.map((name, idx) => + if (config.$references?.length > 0 || extensionValues) { + const plugins = (config.$references ?? []).map((name, idx) => this.loadConfig(`${pluginsPath}/${name}`, idx) ); Promise.all(plugins).then((results) => { - const configs = results + let configs = results .filter((entry) => entry) .sort(sortByOrder) .map((entry) => entry.config); + if (extensionValues) { + configs = [ + ...configs, + ...extensionValues + ]; + } + + if (configs.length > 0) { config = mergeObjects(config, ...configs); } diff --git a/lib/extensions/src/lib/services/extension.service.spec.ts b/lib/extensions/src/lib/services/extension.service.spec.ts index 4d1962db30d..541b77ebecf 100644 --- a/lib/extensions/src/lib/services/extension.service.spec.ts +++ b/lib/extensions/src/lib/services/extension.service.spec.ts @@ -43,7 +43,7 @@ describe('ExtensionService', () => { loader = new ExtensionLoaderService(null); componentRegister = new ComponentRegisterService(); ruleService = new RuleService(loader); - service = new ExtensionService(loader, componentRegister, ruleService, []); + service = new ExtensionService(loader, componentRegister, ruleService, [], []); }); it('should load and setup a config', async () => { @@ -53,7 +53,7 @@ describe('ExtensionService', () => { await service.load(); expect(loader.load).toHaveBeenCalled(); - expect(loader.load).toHaveBeenCalledWith('assets/app.extensions.json', 'assets/plugins', []); + expect(loader.load).toHaveBeenCalledWith('assets/app.extensions.json', 'assets/plugins', [], []); expect(service.setup).toHaveBeenCalledWith(blankConfig); }); diff --git a/lib/extensions/src/lib/services/extension.service.ts b/lib/extensions/src/lib/services/extension.service.ts index 10cd7540a6c..b7f00788d8a 100644 --- a/lib/extensions/src/lib/services/extension.service.ts +++ b/lib/extensions/src/lib/services/extension.service.ts @@ -42,6 +42,11 @@ export const EXTENSION_JSONS = new InjectionToken('extension-jsons', factory: extensionJsonsFactory }); +export const EXTENSION_JSON_VALUES = new InjectionToken('extension-jsons-values', { + providedIn: 'root', + factory: extensionJsonsFactory +}); + // eslint-disable-next-line prefer-arrow/prefer-arrow-functions /** * Provides the extension json values for the angular modules @@ -57,6 +62,20 @@ export function provideExtensionConfig(jsons: string[]) { }; }; +/** + * Provides the extension json raw values for the angular modules + * + * @param extensionConfigValue config value + * @returns a provider section + */ +export function provideExtensionConfigValues(extensionConfigValue: ExtensionConfig[]) { + return { + provide: EXTENSION_JSON_VALUES, + useValue: extensionConfigValue, + multi: true + }; +}; + @Injectable({ providedIn: 'root' }) @@ -78,7 +97,8 @@ export class ExtensionService { protected loader: ExtensionLoaderService, protected componentRegister: ComponentRegisterService, protected ruleService: RuleService, - @Inject(EXTENSION_JSONS) protected extensionJsons: string[] + @Inject(EXTENSION_JSONS) protected extensionJsons: string[], + @Inject(EXTENSION_JSON_VALUES) protected extensionJsonValues: ExtensionConfig[] ) { this.setup$ = this.onSetup$.asObservable(); } @@ -92,8 +112,10 @@ export class ExtensionService { const config = await this.loader.load( this.configPath, this.pluginsPath, - this.extensionJsons.flat() + this.extensionJsons.flat(), + this.extensionJsonValues.flat() ); + this.setup(config); return config; }