@mdf.js/service-registry
Version:
MMS - API - Service Registry
218 lines • 10.7 kB
JavaScript
;
/**
* Copyright 2024 Mytra Control S.L. All rights reserved.
*
* Use of this source code is governed by an MIT-style license that can be found in the LICENSE file
* or at https://opensource.org/licenses/MIT.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SettingsManagerBase = void 0;
const tslib_1 = require("tslib");
const crash_1 = require("@mdf.js/crash");
const service_setup_provider_1 = require("@mdf.js/service-setup-provider");
const sync_1 = tslib_1.__importDefault(require("escalade/sync"));
const events_1 = tslib_1.__importDefault(require("events"));
const fs_1 = tslib_1.__importDefault(require("fs"));
const lodash_1 = require("lodash");
const markdown_it_1 = tslib_1.__importDefault(require("markdown-it"));
const normalize_package_data_1 = tslib_1.__importDefault(require("normalize-package-data"));
const uuid_1 = require("uuid");
const types_1 = require("./types");
/**
* SettingsManager is responsible for managing the application's settings, including the
* configuration for the service registry and custom settings specified by the user. It extends
* EventEmitter to allow for emitting events related to settings management and implements the
* Service interface from the Layer.App namespace, indicating its role in the application's service
* architecture. It utilizes configuration managers for both service registry and custom settings,
* supporting dynamic loading and management of these configurations.
*
* Additionally, it can load application metadata from package.json and README.md content, providing
* a centralized way to access application information and documentation.
*/
class SettingsManagerBase extends events_1.default {
/**
* Constructs a SettingsManager instance, initializing configuration providers and loading
* `package.json` and README information.
* @param bootstrapSettings - Bootstrap settings, define how the Custom and the Service Registry
* settings should be loaded.
* @param serviceRegistrySettings - Service Registry settings, used as a base for the Service
* Registry configuration manager.
* @param customSettings - Custom settings provided by the user, used as a base for the Custom
* configuration manager.
*/
constructor(bootstrapSettings, serviceRegistrySettings, customSettings) {
super();
/** Instance identifier */
this.instanceId = (0, uuid_1.v4)();
this.readme = this.loadReadme(bootstrapSettings === null || bootstrapSettings === void 0 ? void 0 : bootstrapSettings.loadReadme);
this.serviceRegistrySettingsProvider = service_setup_provider_1.Setup.Factory.create(this.defineServiceRegistryConfigManagerOptions(bootstrapSettings, serviceRegistrySettings));
this.customSettingsProvider = service_setup_provider_1.Setup.Factory.create(this.defineCustomSettingsConfigManager(this.serviceRegistrySettingsProvider.client.config.configLoaderOptions, customSettings));
this.addError(this.serviceRegistrySettingsProvider.client.error);
this.addError(this.customSettingsProvider.client.error);
}
/**
* Loads package.json information, normalizing its structure and extracting relevant metadata for
* application settings.
* @param flag - Indicates whether package information should be loaded or not.
* @returns An object containing parsed package information or undefined if loading is not
* requested or fails.
*/
loadPackageInfo(flag) {
var _a;
if (!flag) {
return undefined;
}
let packageInfo;
try {
const packagePath = (0, sync_1.default)(process.cwd(), (dir, names) => {
return names.includes('package.json') && 'package.json';
});
if (packagePath) {
packageInfo = JSON.parse(fs_1.default.readFileSync(packagePath, 'utf8'));
(0, normalize_package_data_1.default)(packageInfo);
}
}
catch (rawError) {
const cause = crash_1.Crash.from(rawError);
this.addError(new crash_1.Crash(`Error loading package info: ${cause.message}`, { cause }));
}
if (!packageInfo) {
return undefined;
}
return {
metadata: {
name: packageInfo.name,
description: packageInfo.description,
version: (_a = packageInfo.version) === null || _a === void 0 ? void 0 : _a.split('.')[0],
release: packageInfo.version,
tags: packageInfo.keywords,
instanceId: (0, lodash_1.get)(packageInfo, `config.${packageInfo.name}.instanceId`, undefined),
serviceId: (0, lodash_1.get)(packageInfo, `config.${packageInfo.name}.serviceId`, undefined),
serviceGroupId: (0, lodash_1.get)(packageInfo, `config.${packageInfo.name}.serviceGroupId`, undefined),
namespace: (0, lodash_1.get)(packageInfo, `config.${packageInfo.name}.namespace`, undefined),
links: (0, lodash_1.get)(packageInfo, `config.${packageInfo.name}.links`, undefined),
},
};
}
/**
* Loads `README.md` content, converting it to HTML using markdown-it for easy display or use
* within the application.
* @param fileName - The file name of the readme or a boolean indicating if the default
* `README.md` should be loaded.
* @returns The rendered HTML content of the `README.md` file or undefined if not found or
* loading is not requested.
*/
loadReadme(fileName) {
let readme;
const _fileName = typeof fileName === 'boolean' ? 'README.md' : fileName;
if (!_fileName) {
return undefined;
}
try {
const markdownPath = (0, sync_1.default)(process.cwd(), (dir, names) => {
return names.includes(_fileName) && _fileName;
});
if (markdownPath) {
const md = (0, markdown_it_1.default)({ html: true, linkify: true, typographer: true });
readme = md.render(fs_1.default.readFileSync(markdownPath, 'utf8'));
}
}
catch (rawError) {
const cause = crash_1.Crash.from(rawError);
this.addError(new crash_1.Crash(`Error loading ${_fileName} info: ${cause.message}`, { cause }));
}
return readme;
}
/**
* Adds an error to the validation error list, creating a new Multi error if necessary. If the
* error is a Multi error, its causes are added to the list.
* @param error - The error to add to the validation error list.
*/
addError(error) {
if (!error) {
return;
}
if (!this._error) {
this._error = new crash_1.Multi(`Error in the service configuration`);
}
if (error instanceof crash_1.Multi) {
if (error.causes) {
error.causes.forEach(cause => {
var _a;
(_a = this._error) === null || _a === void 0 ? void 0 : _a.push(cause);
});
}
else {
this._error.push(error);
}
}
else if (error instanceof crash_1.Crash) {
this._error.push(error);
}
else {
this._error.push(crash_1.Crash.from(error));
}
}
/**
* Defines the configuration options to create an instance of a `ConfigManager` `Provider` to
* manage the Service Registry settings, based in the Bootstrap settings and the Service Registry
* initial settings.
* @param bootstrapSettings - Bootstrap settings
* @param serviceRegistrySettings - Initial Service Registry settings
* @returns The configuration options for initializing the `ServiceRegistry` `ConfigManager`
* `Provider`.
*/
defineServiceRegistryConfigManagerOptions(bootstrapSettings, serviceRegistrySettings) {
const _default = (0, lodash_1.merge)((0, lodash_1.cloneDeep)(types_1.DEFAULT_SERVICE_REGISTRY_OPTIONS), { metadata: { instanceId: this.instanceId } }, this.loadPackageInfo(bootstrapSettings === null || bootstrapSettings === void 0 ? void 0 : bootstrapSettings.loadPackage), serviceRegistrySettings);
const _envPrefix = (bootstrapSettings === null || bootstrapSettings === void 0 ? void 0 : bootstrapSettings.useEnvironment) === true
? types_1.DEFAULT_SERVICE_REGISTRY_SETTINGS_ENV_CONFIG
: undefined;
return {
name: `ServiceRegistry`,
config: (0, lodash_1.merge)((0, lodash_1.cloneDeep)(types_1.DEFAULT_SERVICE_REGISTRY_CONFIG_CONFIG_LOADER_OPTIONS), {
configFiles: bootstrapSettings === null || bootstrapSettings === void 0 ? void 0 : bootstrapSettings.configFiles,
presetFiles: bootstrapSettings === null || bootstrapSettings === void 0 ? void 0 : bootstrapSettings.presetFiles,
preset: bootstrapSettings === null || bootstrapSettings === void 0 ? void 0 : bootstrapSettings.preset,
envPrefix: _envPrefix,
default: _default,
}),
useEnvironment: false,
};
}
/**
* Defines the configuration options to create an instance of a `ConfigManager` `Provider` to
* manage the Custom settings, based on the Service Registry settings and the initial custom
* settings.
* @param configLoader - Configuration loader settings
* @param customSettings - Initial Custom settings
* @returns The configuration options for initializing the Custom settings `ConfigManager`
* `Provider`.
*/
defineCustomSettingsConfigManager(configLoader, customSettings) {
return {
name: `CustomSettings`,
config: {
...configLoader,
base: customSettings,
},
useEnvironment: false,
};
}
/** Start the underlying configuration providers */
async start() {
await this.serviceRegistrySettingsProvider.start();
await this.customSettingsProvider.start();
}
/** Stop the underlying configuration providers */
async stop() {
await this.serviceRegistrySettingsProvider.stop();
await this.customSettingsProvider.stop();
}
/** Close the underlying configuration providers */
async close() {
await this.serviceRegistrySettingsProvider.close();
await this.customSettingsProvider.close();
}
}
exports.SettingsManagerBase = SettingsManagerBase;
//# sourceMappingURL=SettingsManagerBase.js.map