1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2024-11-03 21:04:03 +08:00

Improving extension loading. It mostly solves #847 and #784

This commit is contained in:
Patrik J. Braun 2024-04-13 01:21:05 +02:00
parent 1ae44e8d7f
commit 055862f275
6 changed files with 46 additions and 26 deletions

14
package-lock.json generated
View File

@ -27,7 +27,7 @@
"reflect-metadata": "0.1.13", "reflect-metadata": "0.1.13",
"sharp": "0.31.3", "sharp": "0.31.3",
"ts-node-iptc": "1.0.11", "ts-node-iptc": "1.0.11",
"typeconfig": "2.2.13", "typeconfig": "2.2.15",
"typeorm": "0.3.12", "typeorm": "0.3.12",
"xml2js": "0.6.2" "xml2js": "0.6.2"
}, },
@ -20362,9 +20362,9 @@
} }
}, },
"node_modules/typeconfig": { "node_modules/typeconfig": {
"version": "2.2.13", "version": "2.2.15",
"resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.13.tgz", "resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.15.tgz",
"integrity": "sha512-eT9FqQVJTacuJELZ2XKN9s1phUnaceQd1NhzgTHZuULDWSOpcMTw8jRvg2Uyp14IRe9W9N8DOItz38QQJcwctQ==", "integrity": "sha512-aqiuT5BtV0/0MYMMG78c1IqeJrF85r1W1pJckkGolPjHpE0ajA3oOgnRtX5DRDHsn3YzsY5FKMxj1B3J+ISx1g==",
"dependencies": { "dependencies": {
"minimist": "1.2.8" "minimist": "1.2.8"
} }
@ -35283,9 +35283,9 @@
} }
}, },
"typeconfig": { "typeconfig": {
"version": "2.2.13", "version": "2.2.15",
"resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.13.tgz", "resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.15.tgz",
"integrity": "sha512-eT9FqQVJTacuJELZ2XKN9s1phUnaceQd1NhzgTHZuULDWSOpcMTw8jRvg2Uyp14IRe9W9N8DOItz38QQJcwctQ==", "integrity": "sha512-aqiuT5BtV0/0MYMMG78c1IqeJrF85r1W1pJckkGolPjHpE0ajA3oOgnRtX5DRDHsn3YzsY5FKMxj1B3J+ISx1g==",
"requires": { "requires": {
"minimist": "1.2.8" "minimist": "1.2.8"
} }

View File

@ -54,7 +54,7 @@
"reflect-metadata": "0.1.13", "reflect-metadata": "0.1.13",
"sharp": "0.31.3", "sharp": "0.31.3",
"ts-node-iptc": "1.0.11", "ts-node-iptc": "1.0.11",
"typeconfig": "2.2.13", "typeconfig": "2.2.15",
"typeorm": "0.3.12", "typeorm": "0.3.12",
"xml2js": "0.6.2" "xml2js": "0.6.2"
}, },

View File

@ -2,7 +2,9 @@ import {PrivateConfigClass} from '../../../common/config/private/PrivateConfigCl
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import {ServerExtensionsEntryConfig} from '../../../common/config/private/subconfigs/ServerExtensionsConfig'; import {ServerExtensionsEntryConfig} from '../../../common/config/private/subconfigs/ServerExtensionsConfig';
import * as child_process from 'child_process';
const execSync = child_process.execSync;
const LOG_TAG = '[ExtensionConfigTemplateLoader]'; const LOG_TAG = '[ExtensionConfigTemplateLoader]';
@ -52,20 +54,25 @@ export class ExtensionConfigTemplateLoader {
for (let i = 0; i < this.extensionList.length; ++i) { for (let i = 0; i < this.extensionList.length; ++i) {
const extFolder = this.extensionList[i]; const extFolder = this.extensionList[i];
const extPath = path.join(this.extensionsFolder, extFolder); const extPath = path.join(this.extensionsFolder, extFolder);
const configExtPath = path.join(extPath, 'config.js');
const serverExtPath = path.join(extPath, 'server.js'); const serverExtPath = path.join(extPath, 'server.js');
// if server.js is missing, it's not a valid extension
if (!fs.existsSync(serverExtPath)) { if (!fs.existsSync(serverExtPath)) {
continue; continue;
} }
// eslint-disable-next-line @typescript-eslint/no-var-requires if (fs.existsSync(configExtPath)) {
const ext = require(serverExtPath); // eslint-disable-next-line @typescript-eslint/no-var-requires
if (typeof ext?.initConfig === 'function') { const extCfg = require(configExtPath);
ext?.initConfig({ if (typeof extCfg?.initConfig === 'function') {
setConfigTemplate: (template: { new(): unknown }): void => { extCfg?.initConfig({
this.extensionTemplates.push({folder: extFolder, template: template}); setConfigTemplate: (template: { new(): unknown }): void => {
} this.extensionTemplates.push({folder: extFolder, template: template});
}); }
});
}
} else { } else {
//also create basic config extensions that do not have any //also create basic config extensions that do not have any
this.extensionTemplates.push({folder: extFolder}); this.extensionTemplates.push({folder: extFolder});

View File

@ -27,6 +27,7 @@ export class ExtensionConfigWrapper {
await pc.load(); // loading the basic configs, but we do not know the extension config hierarchy yet 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) { } catch (e) {
console.error(LOG_TAG, 'Error during loading config. Reverting to defaults.'); console.error(LOG_TAG, 'Error during loading config. Reverting to defaults.');
console.error(e); console.error(e);
@ -49,7 +50,7 @@ export class ExtensionConfigWrapper {
pc.saveSync(); pc.saveSync();
} }
pc.loadSync(); // loading the basic configs, but we do not know the extension config hierarchy yet 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) { } catch (e) {
console.error(LOG_TAG, 'Error during loading config. Reverting to defaults.'); console.error(LOG_TAG, 'Error during loading config. Reverting to defaults.');
console.error(e); console.error(e);

View File

@ -217,16 +217,11 @@ export interface IExtensionConfigInit<C> {
} }
/** /**
* 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<C> { export interface IServerExtension<C> {
/**
* This function can be called any time. It should only set the config template class
* @param extension
*/
initConfig(extension: IExtensionConfigInit<C>): void;
/** /**
* Extension init function. Extension should at minimum expose this function. * Extension init function. Extension should at minimum expose this function.
* @param extension * @param extension
@ -235,3 +230,18 @@ export interface IServerExtension<C> {
cleanUp?: (extension: IExtensionObject<C>) => Promise<void>; cleanUp?: (extension: IExtensionObject<C>) => Promise<void>;
} }
/**
* Extension config interface. All extension can implement and export these methods.
* This is the content of the config.js file.
*/
export interface IServerExtensionConfig<C> {
/**
* This function can be called any time. It should only set the config template class
* @param extension
*/
initConfig(extension: IExtensionConfigInit<C>): void;
}

View File

@ -4,10 +4,12 @@ import {ConfigClassBuilder} from 'typeconfig/node';
import {ExtensionConfigTemplateLoader} from '../../../backend/model/extension/ExtensionConfigTemplateLoader'; import {ExtensionConfigTemplateLoader} from '../../../backend/model/extension/ExtensionConfigTemplateLoader';
import * as path from 'path'; 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()); const pre = ConfigClassBuilder.attachPrivateInterface(new PrivateConfigClass());
try { try {
pre.loadSync(); pre.loadSync({preventSaving: true});
} catch (e) { /* empty */ } } catch (e) { /* empty */
}
ExtensionConfigTemplateLoader.Instance.init(path.join(__dirname, '/../../../../', pre.Extensions.folder)); ExtensionConfigTemplateLoader.Instance.init(path.join(__dirname, '/../../../../', pre.Extensions.folder));
export const Config = ExtensionConfigWrapper.originalSync(true); export const Config = ExtensionConfigWrapper.originalSync(true);