mirror of
https://github.com/bpatrik/pigallery2.git
synced 2024-12-23 01:27:14 +02:00
Merge branch 'master' of https://github.com/grasdk/pigallery2 into feature/Clear-DateTime-Tag-Priority
This commit is contained in:
commit
e6e271ccaf
15
package-lock.json
generated
15
package-lock.json
generated
@ -26,7 +26,8 @@
|
|||||||
"nodemailer": "6.9.4",
|
"nodemailer": "6.9.4",
|
||||||
"reflect-metadata": "0.1.13",
|
"reflect-metadata": "0.1.13",
|
||||||
"sharp": "0.31.3",
|
"sharp": "0.31.3",
|
||||||
"typeconfig": "2.2.11",
|
"ts-node-iptc": "1.0.11",
|
||||||
|
"typeconfig": "2.2.15",
|
||||||
"typeorm": "0.3.12",
|
"typeorm": "0.3.12",
|
||||||
"xml2js": "0.6.2"
|
"xml2js": "0.6.2"
|
||||||
},
|
},
|
||||||
@ -20361,9 +20362,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typeconfig": {
|
"node_modules/typeconfig": {
|
||||||
"version": "2.2.11",
|
"version": "2.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.15.tgz",
|
||||||
"integrity": "sha512-Knj+1kbIJ4zOZlUm2TPSWZUoiOW4txrmPyf6oyuBhaDQDlGxpSL5jobF3vVV9mZElK1V3ZQVeTgvGaiDyeT8mQ==",
|
"integrity": "sha512-aqiuT5BtV0/0MYMMG78c1IqeJrF85r1W1pJckkGolPjHpE0ajA3oOgnRtX5DRDHsn3YzsY5FKMxj1B3J+ISx1g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"minimist": "1.2.8"
|
"minimist": "1.2.8"
|
||||||
}
|
}
|
||||||
@ -35282,9 +35283,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"typeconfig": {
|
"typeconfig": {
|
||||||
"version": "2.2.11",
|
"version": "2.2.15",
|
||||||
"resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.11.tgz",
|
"resolved": "https://registry.npmjs.org/typeconfig/-/typeconfig-2.2.15.tgz",
|
||||||
"integrity": "sha512-Knj+1kbIJ4zOZlUm2TPSWZUoiOW4txrmPyf6oyuBhaDQDlGxpSL5jobF3vVV9mZElK1V3ZQVeTgvGaiDyeT8mQ==",
|
"integrity": "sha512-aqiuT5BtV0/0MYMMG78c1IqeJrF85r1W1pJckkGolPjHpE0ajA3oOgnRtX5DRDHsn3YzsY5FKMxj1B3J+ISx1g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "1.2.8"
|
"minimist": "1.2.8"
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,8 @@
|
|||||||
"nodemailer": "6.9.4",
|
"nodemailer": "6.9.4",
|
||||||
"reflect-metadata": "0.1.13",
|
"reflect-metadata": "0.1.13",
|
||||||
"sharp": "0.31.3",
|
"sharp": "0.31.3",
|
||||||
"typeconfig": "2.2.11",
|
"ts-node-iptc": "1.0.11",
|
||||||
|
"typeconfig": "2.2.15",
|
||||||
"typeorm": "0.3.12",
|
"typeorm": "0.3.12",
|
||||||
"xml2js": "0.6.2"
|
"xml2js": "0.6.2"
|
||||||
},
|
},
|
||||||
|
@ -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});
|
||||||
@ -102,6 +109,8 @@ export class ExtensionConfigTemplateLoader {
|
|||||||
if (ext.template) {
|
if (ext.template) {
|
||||||
c.configs = new ext.template();
|
c.configs = new ext.template();
|
||||||
}
|
}
|
||||||
|
// TODO: this does not hold if the order of the extensions mixes up.
|
||||||
|
// TODO: experiment with a map instead of an array
|
||||||
config.Extensions.extensions.push(c);
|
config.Extensions.extensions.push(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@ import {PrivateConfigClass} from '../../../common/config/private/PrivateConfigCl
|
|||||||
import {ConfigClassBuilder} from 'typeconfig/node';
|
import {ConfigClassBuilder} from 'typeconfig/node';
|
||||||
import {ExtensionConfigTemplateLoader} from './ExtensionConfigTemplateLoader';
|
import {ExtensionConfigTemplateLoader} from './ExtensionConfigTemplateLoader';
|
||||||
import {NotificationManager} from '../NotifocationManager';
|
import {NotificationManager} from '../NotifocationManager';
|
||||||
|
import {ServerConfig} from '../../../common/config/private/PrivateConfig';
|
||||||
|
import {ConfigClassOptions} from 'typeconfig/src/decorators/class/IConfigClass';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
|
||||||
const LOG_TAG = '[ExtensionConfigWrapper]';
|
const LOG_TAG = '[ExtensionConfigWrapper]';
|
||||||
@ -16,8 +19,15 @@ export class ExtensionConfigWrapper {
|
|||||||
const pc = ConfigClassBuilder.attachPrivateInterface(new PrivateConfigClass());
|
const pc = ConfigClassBuilder.attachPrivateInterface(new PrivateConfigClass());
|
||||||
ExtensionConfigTemplateLoader.Instance.loadExtensionTemplates(pc);
|
ExtensionConfigTemplateLoader.Instance.loadExtensionTemplates(pc);
|
||||||
try {
|
try {
|
||||||
|
// make sure the config file exists by the time we load it.
|
||||||
|
// TODO: remove this once typeconfig is fixed and can properly load defaults in arrays
|
||||||
|
if (!fs.existsSync((pc.__options as ConfigClassOptions<ServerConfig>).configPath)) {
|
||||||
|
await pc.save();
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -34,8 +44,13 @@ export class ExtensionConfigWrapper {
|
|||||||
const pc = ConfigClassBuilder.attachPrivateInterface(new PrivateConfigClass());
|
const pc = ConfigClassBuilder.attachPrivateInterface(new PrivateConfigClass());
|
||||||
ExtensionConfigTemplateLoader.Instance.loadExtensionTemplates(pc);
|
ExtensionConfigTemplateLoader.Instance.loadExtensionTemplates(pc);
|
||||||
try {
|
try {
|
||||||
|
// make sure the config file exists by the time we load it.
|
||||||
|
// TODO: remove this once typeconfig is fixed and can properly load defaults in arrays
|
||||||
|
if (!fs.existsSync((pc.__options as ConfigClassOptions<ServerConfig>).configPath)) {
|
||||||
|
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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -59,7 +59,8 @@ export class ServerExtensionsConfig extends ClientExtensionsConfig {
|
|||||||
})
|
})
|
||||||
folder: string = 'extensions';
|
folder: string = 'extensions';
|
||||||
|
|
||||||
|
// TODO: this does not hold if the order of the extensions mixes up.
|
||||||
|
// TODO: experiment with a map instead of an array
|
||||||
@ConfigProperty({
|
@ConfigProperty({
|
||||||
arrayType: ServerExtensionsEntryConfig,
|
arrayType: ServerExtensionsEntryConfig,
|
||||||
tags: {
|
tags: {
|
||||||
|
@ -48,9 +48,7 @@ describe('SettingsRouter', () => {
|
|||||||
attachVolatile: true,
|
attachVolatile: true,
|
||||||
skipTags: {secret: true} as TAGS
|
skipTags: {secret: true} as TAGS
|
||||||
})));
|
})));
|
||||||
//TODO: fix broken test.
|
|
||||||
// It breaks if config. sets value through constructor
|
|
||||||
/*
|
|
||||||
const result = await chai.request(server.Server)
|
const result = await chai.request(server.Server)
|
||||||
.get(Config.Server.apiPath + '/settings');
|
.get(Config.Server.apiPath + '/settings');
|
||||||
|
|
||||||
@ -58,7 +56,7 @@ describe('SettingsRouter', () => {
|
|||||||
result.body.should.be.a('object');
|
result.body.should.be.a('object');
|
||||||
should.equal(result.body.error, null);
|
should.equal(result.body.error, null);
|
||||||
(result.body.result as ServerConfig).Environment.upTime = null;
|
(result.body.result as ServerConfig).Environment.upTime = null;
|
||||||
result.body.result.should.deep.equal(originalJSON);*/
|
result.body.result.should.deep.equal(originalJSON);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
import {expect} from 'chai';
|
||||||
|
import {ExtensionConfigWrapper} from '../../../../../src/backend/model/extension/ExtensionConfigWrapper';
|
||||||
|
import {TAGS} from '../../../../../src/common/config/public/ClientConfig';
|
||||||
|
|
||||||
|
// to help WebStorm to handle the test cases
|
||||||
|
declare let describe: any;
|
||||||
|
declare const after: any;
|
||||||
|
declare const before: any;
|
||||||
|
declare const it: any;
|
||||||
|
|
||||||
|
|
||||||
|
describe('ExtensionConfigWrapper', () => {
|
||||||
|
|
||||||
|
it('should load original config multiple times with the same result', async () => {
|
||||||
|
const get = async () => JSON.parse(JSON.stringify((await ExtensionConfigWrapper.original()).toJSON({
|
||||||
|
attachState: true,
|
||||||
|
attachVolatile: true,
|
||||||
|
skipTags: {secret: true} as TAGS
|
||||||
|
})));
|
||||||
|
const a = await get();
|
||||||
|
const b = await get();
|
||||||
|
expect(b).to.deep.equal(a);
|
||||||
|
const c = await get();
|
||||||
|
expect(c).to.deep.equal(a);
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user