diff --git a/package-lock.json b/package-lock.json index 8ada0fa4d..ee0ed6d5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ "reflect-metadata": "0.1.13", "sharp": "0.31.3", "ts-node-iptc": "1.0.11", - "typeconfig": "2.2.13", + "typeconfig": "2.2.15", "typeorm": "0.3.12", "xml2js": "0.6.2" }, @@ -20362,9 +20362,9 @@ } }, "node_modules/typeconfig": { - "version": "2.2.13", - "resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.13.tgz", - "integrity": "sha512-eT9FqQVJTacuJELZ2XKN9s1phUnaceQd1NhzgTHZuULDWSOpcMTw8jRvg2Uyp14IRe9W9N8DOItz38QQJcwctQ==", + "version": "2.2.15", + "resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.15.tgz", + "integrity": "sha512-aqiuT5BtV0/0MYMMG78c1IqeJrF85r1W1pJckkGolPjHpE0ajA3oOgnRtX5DRDHsn3YzsY5FKMxj1B3J+ISx1g==", "dependencies": { "minimist": "1.2.8" } @@ -35283,9 +35283,9 @@ } }, "typeconfig": { - "version": "2.2.13", - "resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.13.tgz", - "integrity": "sha512-eT9FqQVJTacuJELZ2XKN9s1phUnaceQd1NhzgTHZuULDWSOpcMTw8jRvg2Uyp14IRe9W9N8DOItz38QQJcwctQ==", + "version": "2.2.15", + "resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.15.tgz", + "integrity": "sha512-aqiuT5BtV0/0MYMMG78c1IqeJrF85r1W1pJckkGolPjHpE0ajA3oOgnRtX5DRDHsn3YzsY5FKMxj1B3J+ISx1g==", "requires": { "minimist": "1.2.8" } diff --git a/package.json b/package.json index c4b859b6e..9b5c036e4 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "reflect-metadata": "0.1.13", "sharp": "0.31.3", "ts-node-iptc": "1.0.11", - "typeconfig": "2.2.13", + "typeconfig": "2.2.15", "typeorm": "0.3.12", "xml2js": "0.6.2" }, diff --git a/src/backend/model/extension/ExtensionConfigTemplateLoader.ts b/src/backend/model/extension/ExtensionConfigTemplateLoader.ts index 435189f97..f4235df86 100644 --- a/src/backend/model/extension/ExtensionConfigTemplateLoader.ts +++ b/src/backend/model/extension/ExtensionConfigTemplateLoader.ts @@ -2,7 +2,9 @@ import {PrivateConfigClass} from '../../../common/config/private/PrivateConfigCl import * as fs from 'fs'; import * as path from 'path'; import {ServerExtensionsEntryConfig} from '../../../common/config/private/subconfigs/ServerExtensionsConfig'; +import * as child_process from 'child_process'; +const execSync = child_process.execSync; const LOG_TAG = '[ExtensionConfigTemplateLoader]'; @@ -52,20 +54,25 @@ export class ExtensionConfigTemplateLoader { for (let i = 0; i < this.extensionList.length; ++i) { const extFolder = this.extensionList[i]; const extPath = path.join(this.extensionsFolder, extFolder); + const configExtPath = path.join(extPath, 'config.js'); const serverExtPath = path.join(extPath, 'server.js'); + + // if server.js is missing, it's not a valid extension if (!fs.existsSync(serverExtPath)) { continue; } - // eslint-disable-next-line @typescript-eslint/no-var-requires - const ext = require(serverExtPath); - if (typeof ext?.initConfig === 'function') { - ext?.initConfig({ - setConfigTemplate: (template: { new(): unknown }): void => { - this.extensionTemplates.push({folder: extFolder, template: template}); - } - }); + if (fs.existsSync(configExtPath)) { + // eslint-disable-next-line @typescript-eslint/no-var-requires + const extCfg = require(configExtPath); + if (typeof extCfg?.initConfig === 'function') { + extCfg?.initConfig({ + setConfigTemplate: (template: { new(): unknown }): void => { + this.extensionTemplates.push({folder: extFolder, template: template}); + } + }); + } } else { //also create basic config extensions that do not have any this.extensionTemplates.push({folder: extFolder}); diff --git a/src/backend/model/extension/ExtensionConfigWrapper.ts b/src/backend/model/extension/ExtensionConfigWrapper.ts index c4e0e827b..d96e4bc7d 100644 --- a/src/backend/model/extension/ExtensionConfigWrapper.ts +++ b/src/backend/model/extension/ExtensionConfigWrapper.ts @@ -27,6 +27,7 @@ export class ExtensionConfigWrapper { await pc.load(); // loading the basic configs, but we do not know the extension config hierarchy yet + // TODO make sure that all extensions are present even after loading them from file } catch (e) { console.error(LOG_TAG, 'Error during loading config. Reverting to defaults.'); console.error(e); @@ -49,7 +50,7 @@ export class ExtensionConfigWrapper { pc.saveSync(); } pc.loadSync(); // loading the basic configs, but we do not know the extension config hierarchy yet - + // TODO make sure that all extensions are present even after loading them from file } catch (e) { console.error(LOG_TAG, 'Error during loading config. Reverting to defaults.'); console.error(e); diff --git a/src/backend/model/extension/IExtension.ts b/src/backend/model/extension/IExtension.ts index 6a1568318..48434fb26 100644 --- a/src/backend/model/extension/IExtension.ts +++ b/src/backend/model/extension/IExtension.ts @@ -217,21 +217,31 @@ export interface IExtensionConfigInit { } /** - * Extension interface. All extension is expected to implement and export these methods + * Extension interface. All extension is expected to implement and export these methods. + * This is the content of the server.js file */ export interface IServerExtension { /** - * This function can be called any time. It should only set the config template class + * Extension init function. Extension should at minimum expose this function. * @param extension */ - initConfig(extension: IExtensionConfigInit): void; + init(extension: IExtensionObject): Promise; + + cleanUp?: (extension: IExtensionObject) => Promise; +} + + +/** + * Extension config interface. All extension can implement and export these methods. + * This is the content of the config.js file. + */ +export interface IServerExtensionConfig { /** - * Extension init function. Extension should at minimum expose this function. + * This function can be called any time. It should only set the config template class * @param extension */ - init(extension: IExtensionObject): Promise; + initConfig(extension: IExtensionConfigInit): void; - cleanUp?: (extension: IExtensionObject) => Promise; } diff --git a/src/common/config/private/Config.ts b/src/common/config/private/Config.ts index 143bc5e91..7a14e5c03 100644 --- a/src/common/config/private/Config.ts +++ b/src/common/config/private/Config.ts @@ -4,10 +4,12 @@ import {ConfigClassBuilder} from 'typeconfig/node'; import {ExtensionConfigTemplateLoader} from '../../../backend/model/extension/ExtensionConfigTemplateLoader'; import * as path from 'path'; +// we need to know the location of the extensions to load the full config (including the extensions) const pre = ConfigClassBuilder.attachPrivateInterface(new PrivateConfigClass()); try { - pre.loadSync(); -} catch (e) { /* empty */ } + pre.loadSync({preventSaving: true}); +} catch (e) { /* empty */ +} ExtensionConfigTemplateLoader.Instance.init(path.join(__dirname, '/../../../../', pre.Extensions.folder)); export const Config = ExtensionConfigWrapper.originalSync(true);