nodecg-io-core
Advanced tools
Comparing version 0.1.2 to 0.2.0
/// <reference types="node" /> | ||
import { NodeCG } from "nodecg/types/server"; | ||
import { ObjectMap, Service, ServiceDependency, ServiceInstance } from "./types"; | ||
import { NodeCG } from "nodecg-types/types/server"; | ||
import { ObjectMap, Service, ServiceDependency, ServiceInstance } from "./service"; | ||
import { Result } from "./utils/result"; | ||
@@ -16,5 +16,5 @@ import { EventEmitter } from "events"; | ||
* Gets all bundle dependencies | ||
* @return {ObjectMap<string, ServiceDependency<unknown>[]>} all bundle dependencies | ||
* @return {ObjectMap<ServiceDependency<unknown>[]>} all bundle dependencies | ||
*/ | ||
getBundleDependencies(): ObjectMap<string, ServiceDependency<unknown>[]>; | ||
getBundleDependencies(): ObjectMap<ServiceDependency<unknown>[]>; | ||
/** | ||
@@ -25,10 +25,12 @@ * Registers that a bundle has a dependency on a specific service. | ||
* @param clientUpdate the callback that should be called if a client becomes available or gets updated. | ||
* @return a {@link ServiceProvider} that allows the bundle to access the service client, if a service instance is set | ||
* and there were no errors in the client creation. | ||
*/ | ||
registerServiceDependency<C>(bundleName: string, service: Service<unknown, C>): ServiceProvider<C> | undefined; | ||
/** | ||
* Satisfies a service dependency by providing a service instance of the type and connects the bundle and service together. | ||
* Assigns a service instance to the service dependency of a bundle and gives the bundle access to the current | ||
* service client. Future client updates will be handled through {@link BundleManager.handleInstanceUpdate}. | ||
* @param bundleName the name of the bundle that has the dependency on the service. | ||
* @param instanceName the name of the service instance that should be used to satisfy the dependency of the bundle. | ||
* @param instance the service instance object that should be used to satisfy the dependency of the bundle. | ||
* @return void if successful and a string explain what went wrong otherwise | ||
*/ | ||
@@ -52,1 +54,2 @@ setServiceDependency(bundleName: string, instanceName: string, instance: ServiceInstance<unknown, unknown>): Result<void>; | ||
} | ||
//# sourceMappingURL=bundleManager.d.ts.map |
@@ -14,2 +14,3 @@ "use strict"; | ||
this.nodecg = nodecg; | ||
// Object that maps a bundle name to the array that contains all services that this bundle depends upon | ||
this.bundles = {}; | ||
@@ -19,3 +20,3 @@ } | ||
* Gets all bundle dependencies | ||
* @return {ObjectMap<string, ServiceDependency<unknown>[]>} all bundle dependencies | ||
* @return {ObjectMap<ServiceDependency<unknown>[]>} all bundle dependencies | ||
*/ | ||
@@ -30,6 +31,9 @@ getBundleDependencies() { | ||
* @param clientUpdate the callback that should be called if a client becomes available or gets updated. | ||
* @return a {@link ServiceProvider} that allows the bundle to access the service client, if a service instance is set | ||
* and there were no errors in the client creation. | ||
*/ | ||
registerServiceDependency(bundleName, service) { | ||
var _a; | ||
// Get current service dependencies or an empty array if none | ||
const serviceDependencies = this.bundles[bundleName] || []; | ||
const serviceDependencies = (_a = this.bundles[bundleName]) !== null && _a !== void 0 ? _a : []; | ||
// Check if the same type of dependency is already registered | ||
@@ -47,3 +51,3 @@ if (serviceDependencies.find((sd) => sd.serviceType === service.serviceType)) { | ||
}); | ||
// Save new dependencies. | ||
// Save update dependencies array. | ||
this.bundles[bundleName] = serviceDependencies; | ||
@@ -55,28 +59,27 @@ this.emit("change"); | ||
/** | ||
* Satisfies a service dependency by providing a service instance of the type and connects the bundle and service together. | ||
* Assigns a service instance to the service dependency of a bundle and gives the bundle access to the current | ||
* service client. Future client updates will be handled through {@link BundleManager.handleInstanceUpdate}. | ||
* @param bundleName the name of the bundle that has the dependency on the service. | ||
* @param instanceName the name of the service instance that should be used to satisfy the dependency of the bundle. | ||
* @param instance the service instance object that should be used to satisfy the dependency of the bundle. | ||
* @return void if successful and a string explain what went wrong otherwise | ||
*/ | ||
setServiceDependency(bundleName, instanceName, instance) { | ||
// Check that bundle exists and get service dependencies | ||
// Check that bundle exists and get its service dependencies | ||
const bundle = this.bundles[bundleName]; | ||
if (bundle === undefined) { | ||
return result_1.error(`Bundle "${bundleName}" couldn't be found.`); | ||
return (0, result_1.error)(`Bundle "${bundleName}" couldn't be found.`); | ||
} | ||
// Check that the bundle actually depends on this type of service | ||
// Get the service dependency that manages dependance for this service type | ||
const svcDependency = bundle.find((svcDep) => svcDep.serviceType === instance.serviceType); | ||
if (svcDependency === undefined) { | ||
return result_1.error(`Bundle "${bundleName} doesn't depend on the "${instance.serviceType}" service.`); | ||
return (0, result_1.error)(`Bundle "${bundleName} doesn't depend on the "${instance.serviceType}" service.`); | ||
} | ||
const oldInstance = svcDependency.serviceInstance; | ||
// Update service instance of service dependency, remove client update callback from old service instance (if applicable) | ||
// and add the callback to the new instance. | ||
// Assign service instance to the service dependency of this bundle | ||
svcDependency.serviceInstance = instanceName; | ||
// Let the bundle update his reference to the client | ||
// Let the bundle update its reference to the client | ||
svcDependency.provider.updateClient(instance.client); | ||
this.emit("change"); | ||
this.emit("reregisterInstance", oldInstance); | ||
return result_1.emptySuccess(); | ||
return (0, result_1.emptySuccess)(); | ||
} | ||
@@ -113,9 +116,5 @@ /** | ||
// Iterate over all bundles | ||
for (const bundle in this.bundles) { | ||
if (!Object.prototype.hasOwnProperty.call(this.bundles, bundle)) { | ||
continue; | ||
} | ||
// Get their dependencies and if they have this instance set somewhere then update the bundle. | ||
const dependencies = this.bundles[bundle]; | ||
dependencies === null || dependencies === void 0 ? void 0 : dependencies.forEach((dep) => { | ||
Object.entries(this.bundles).forEach(([_bundleName, svcDependencies]) => { | ||
// If they have this instance set somewhere in their dependencies then update the bundle. | ||
svcDependencies.forEach((dep) => { | ||
if (dep.serviceInstance === instName) { | ||
@@ -125,3 +124,3 @@ dep.provider.updateClient(serviceInstance.client); | ||
}); | ||
} | ||
}); | ||
} | ||
@@ -128,0 +127,0 @@ } |
@@ -1,3 +0,3 @@ | ||
import { NodeCG } from "nodecg/types/server"; | ||
import { Service } from "./types"; | ||
import { NodeCG } from "nodecg-types/types/server"; | ||
import { Service } from "./service"; | ||
import { ServiceProvider } from "./serviceProvider"; | ||
@@ -12,1 +12,2 @@ /** | ||
} | ||
//# sourceMappingURL=index.d.ts.map |
@@ -8,2 +8,3 @@ "use strict"; | ||
const persistenceManager_1 = require("./persistenceManager"); | ||
const logger_1 = require("./utils/logger"); | ||
module.exports = (nodecg) => { | ||
@@ -59,3 +60,3 @@ nodecg.log.info("Minzig!"); | ||
try { | ||
service.result.stopClient(client); | ||
service.result.stopClient(client, new logger_1.Logger(key, nodecg)); | ||
} | ||
@@ -62,0 +63,0 @@ catch (err) { |
/// <reference types="node" /> | ||
import { NodeCG } from "nodecg/types/server"; | ||
import { ObjectMap, ServiceInstance } from "./types"; | ||
import { NodeCG } from "nodecg-types/types/server"; | ||
import { ObjectMap, Service, ServiceInstance } from "./service"; | ||
import { Result } from "./utils/result"; | ||
@@ -26,5 +26,5 @@ import { ServiceManager } from "./serviceManager"; | ||
* Returns all existing service instances. | ||
* @return {ObjectMap<string, ServiceInstance<unknown, unknown>>} a map of the instance name to the instance. | ||
* @return {ObjectMap<ServiceInstance<unknown, unknown>>} a map of the instance name to the instance. | ||
*/ | ||
getServiceInstances(): ObjectMap<string, ServiceInstance<unknown, unknown>>; | ||
getServiceInstances(): ObjectMap<ServiceInstance<unknown, unknown>>; | ||
/** | ||
@@ -61,8 +61,9 @@ * Creates a service instance of the passed service. | ||
*/ | ||
private updateInstanceClient; | ||
updateInstanceClient<R, C>(inst: ServiceInstance<R, C>, instanceName: string, service: Service<R, C>): Promise<Result<void>>; | ||
/** | ||
* Removes all handlers from the service client of the instance and lets bundles readd their handlers. | ||
* @param instanceName the name of the instance which handlers should be re-registred | ||
* @param instanceName the name of the instance which handlers should be re-registered | ||
*/ | ||
private reregisterHandlersOfInstance; | ||
} | ||
//# sourceMappingURL=instanceManager.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.InstanceManager = void 0; | ||
const tslib_1 = require("tslib"); | ||
const result_1 = require("./utils/result"); | ||
const ajv_1 = require("ajv"); | ||
const ajv_1 = (0, tslib_1.__importDefault)(require("ajv")); | ||
const events_1 = require("events"); | ||
const logger_1 = require("./utils/logger"); | ||
/** | ||
@@ -30,3 +32,3 @@ * Manages instances of services and their configs/clients. | ||
* Returns all existing service instances. | ||
* @return {ObjectMap<string, ServiceInstance<unknown, unknown>>} a map of the instance name to the instance. | ||
* @return {ObjectMap<ServiceInstance<unknown, unknown>>} a map of the instance name to the instance. | ||
*/ | ||
@@ -44,7 +46,7 @@ getServiceInstances() { | ||
if (!instanceName) { | ||
return result_1.error("Instance name must not be empty."); | ||
return (0, result_1.error)("Instance name must not be empty."); | ||
} | ||
// Check if a instance with the same name already exists. | ||
if (this.serviceInstances[instanceName] !== undefined) { | ||
return result_1.error("A service instance with the same name already exists."); | ||
return (0, result_1.error)("A service instance with the same name already exists."); | ||
} | ||
@@ -54,3 +56,3 @@ // Get service | ||
if (svcResult.failed) { | ||
return result_1.error("A service of this service type hasn't been registered."); | ||
return (0, result_1.error)("A service of this service type hasn't been registered."); | ||
} | ||
@@ -71,3 +73,3 @@ const service = svcResult.result; | ||
} | ||
return result_1.emptySuccess(); | ||
return (0, result_1.emptySuccess)(); | ||
} | ||
@@ -80,3 +82,2 @@ /** | ||
deleteServiceInstance(instanceName) { | ||
var _a; | ||
const instance = this.serviceInstances[instanceName]; | ||
@@ -94,5 +95,5 @@ if (!instance) | ||
else { | ||
this.nodecg.log.info(`Sucessfully stopped client of service instance "${instanceName}".`); | ||
this.nodecg.log.info(`Successfully stopped client of service instance "${instanceName}".`); | ||
try { | ||
svc.result.stopClient(instance.client); | ||
svc.result.stopClient(instance.client, new logger_1.Logger(instanceName, this.nodecg)); | ||
} | ||
@@ -104,13 +105,10 @@ catch (e) { | ||
} | ||
// Remove any assignment of a bundle to this service instance | ||
const deps = this.bundles.getBundleDependencies(); | ||
Object.entries(deps).forEach(([bundleName, deps]) => deps | ||
.filter((d) => d.serviceInstance === instanceName) // Search for bundle dependencies using this instance | ||
.forEach((d) => this.bundles.unsetServiceDependency(bundleName, d.serviceType))); | ||
// Delete and save | ||
delete this.serviceInstances[instanceName]; | ||
// Save deletion | ||
this.emit("change"); | ||
// Remove any assignment of a bundle to this service instance | ||
const deps = this.bundles.getBundleDependencies(); | ||
for (const bundle in deps) { | ||
if (!Object.prototype.hasOwnProperty.call(deps, bundle)) { | ||
continue; | ||
} | ||
(_a = deps[bundle]) === null || _a === void 0 ? void 0 : _a.filter((d) => d.serviceInstance === instanceName).forEach((d) => this.bundles.unsetServiceDependency(bundle, d.serviceType)); // unset all these | ||
} | ||
return true; | ||
@@ -132,7 +130,7 @@ } | ||
if (inst === undefined) { | ||
return Promise.resolve(result_1.error("Service instance doesn't exist.")); | ||
return Promise.resolve((0, result_1.error)("Service instance doesn't exist.")); | ||
} | ||
const service = this.services.getService(inst.serviceType); | ||
if (service.failed) { | ||
return Promise.resolve(result_1.error("The service of this instance couldn't be found.")); | ||
return Promise.resolve((0, result_1.error)("The service of this instance couldn't be found.")); | ||
} | ||
@@ -150,9 +148,12 @@ // If we don't need validation, because we are loading the configuration from disk, we can set it directly | ||
return (async () => { | ||
const schemaValid = this.ajv.validate(service.result.schema, config); | ||
if (!schemaValid) { | ||
return result_1.error("Config invalid: " + this.ajv.errorsText()); | ||
// If the service has a schema, check it. | ||
if (service.result.schema) { | ||
const schemaValid = this.ajv.validate(service.result.schema, config); | ||
if (!schemaValid) { | ||
return (0, result_1.error)("Config invalid: " + this.ajv.errorsText()); | ||
} | ||
} | ||
// Validation by the service. | ||
try { | ||
const validationRes = await service.result.validateConfig(config); | ||
const validationRes = await service.result.validateConfig(config, new logger_1.Logger(instanceName, this.nodecg)); | ||
if (validationRes.failed) { | ||
@@ -164,3 +165,3 @@ throw validationRes.errorMessage; | ||
this.nodecg.log.warn(`Couldn't validate config of ${service.result.serviceType} instance "${instanceName}": ${err}`); | ||
return result_1.error("Config invalid: " + err); | ||
return (0, result_1.error)("Config invalid: " + err); | ||
} | ||
@@ -189,10 +190,10 @@ // All checks passed. Set config and save it. | ||
else { | ||
// Create a client using the new config | ||
const service = this.services.getService(inst.serviceType); | ||
if (service.failed) { | ||
inst.client = undefined; | ||
return service; | ||
} | ||
try { | ||
const client = await service.result.createClient(inst.config); | ||
// Create a client using the new config | ||
// If the service requires a config we make the undefined check above which ensures that undefined doesn't | ||
// get passed to the createClient function of the service. | ||
// If the service does not require a config we can safely ignore the undefined error because in that case | ||
// passing undefined is the intended behavior. | ||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | ||
const client = await service.createClient(inst.config, new logger_1.Logger(instanceName, this.nodecg)); | ||
// Check if a error happened while creating the client | ||
@@ -208,6 +209,6 @@ if (client.failed) { | ||
catch (err) { | ||
const msg = `The "${inst.serviceType}" service produced an error while creating a client: ${err}`; | ||
const msg = `The "${inst.serviceType}" service with the name "${instanceName}" produced an error while creating a client: ${err}`; | ||
this.nodecg.log.error(msg); | ||
inst.client = undefined; | ||
return result_1.error(msg); | ||
return (0, result_1.error)(msg); | ||
} | ||
@@ -221,3 +222,3 @@ } | ||
try { | ||
service.stopClient(oldClient); | ||
service.stopClient(oldClient, new logger_1.Logger(instanceName, this.nodecg)); | ||
} | ||
@@ -228,7 +229,7 @@ catch (e) { | ||
} | ||
return result_1.emptySuccess(); | ||
return (0, result_1.emptySuccess)(); | ||
} | ||
/** | ||
* Removes all handlers from the service client of the instance and lets bundles readd their handlers. | ||
* @param instanceName the name of the instance which handlers should be re-registred | ||
* @param instanceName the name of the instance which handlers should be re-registered | ||
*/ | ||
@@ -245,3 +246,3 @@ reregisterHandlersOfInstance(instanceName) { | ||
if (svc.failed) { | ||
this.nodecg.log.error(`Can't reregister handlers of instance "${instanceName}": can't get service: ${svc.errorMessage}`); | ||
this.nodecg.log.error(`Can't re-register handlers of instance "${instanceName}": can't get service: ${svc.errorMessage}`); | ||
return; | ||
@@ -261,3 +262,3 @@ } | ||
catch (err) { | ||
this.nodecg.log.error(`Can't re-register handlers of instance "${instanceName}": error while removing handlers: ${err.toString()}`); | ||
this.nodecg.log.error(`Can't re-register handlers of instance "${instanceName}": error while removing handlers: ${String(err)}`); | ||
} | ||
@@ -264,0 +265,0 @@ // Readd handlers by running the `onAvailable` function of all bundles |
@@ -1,2 +0,2 @@ | ||
import { NodeCG } from "nodecg/types/server"; | ||
import { NodeCG } from "nodecg-types/types/server"; | ||
import { InstanceManager } from "./instanceManager"; | ||
@@ -40,1 +40,2 @@ import { BundleManager } from "./bundleManager"; | ||
} | ||
//# sourceMappingURL=messageManager.d.ts.map |
@@ -21,3 +21,3 @@ "use strict"; | ||
if (inst === undefined) { | ||
return result_1.error("Service instance doesn't exist."); | ||
return (0, result_1.error)("Service instance doesn't exist."); | ||
} | ||
@@ -32,3 +32,3 @@ else { | ||
this.listenWithAuth("deleteServiceInstance", async (msg) => { | ||
return result_1.success(this.instances.deleteServiceInstance(msg.instanceName)); | ||
return (0, result_1.success)(this.instances.deleteServiceInstance(msg.instanceName)); | ||
}); | ||
@@ -39,6 +39,6 @@ this.listenWithAuth("setServiceDependency", async (msg) => { | ||
if (success) { | ||
return result_1.emptySuccess(); | ||
return (0, result_1.emptySuccess)(); | ||
} | ||
else { | ||
return result_1.error("Service dependency couldn't be found."); | ||
return (0, result_1.error)("Service dependency couldn't be found."); | ||
} | ||
@@ -49,3 +49,3 @@ } | ||
if (instance === undefined) { | ||
return result_1.error("Service instance couldn't be found."); | ||
return (0, result_1.error)("Service instance couldn't be found."); | ||
} | ||
@@ -58,3 +58,3 @@ else { | ||
this.listen("isLoaded", async () => { | ||
return result_1.success(this.persist.isLoaded()); | ||
return (0, result_1.success)(this.persist.isLoaded()); | ||
}); | ||
@@ -70,6 +70,6 @@ this.listen("load", async (msg) => { | ||
const result = this.services.getServices().map((svc) => Object.assign({}, svc)); | ||
return result_1.success(result); | ||
return (0, result_1.success)(result); | ||
}); | ||
this.listen("isFirstStartup", async () => { | ||
return result_1.success(this.persist.isFirstStartup()); | ||
return (0, result_1.success)(this.persist.isFirstStartup()); | ||
}); | ||
@@ -96,3 +96,3 @@ } | ||
else { | ||
return result_1.error("The password is invalid"); | ||
return (0, result_1.error)("The password is invalid"); | ||
} | ||
@@ -99,0 +99,0 @@ }); |
@@ -1,6 +0,6 @@ | ||
import { NodeCG } from "nodecg/types/server"; | ||
import { NodeCG } from "nodecg-types/types/server"; | ||
import { InstanceManager } from "./instanceManager"; | ||
import { BundleManager } from "./bundleManager"; | ||
import { Result } from "./utils/result"; | ||
import { ObjectMap, ServiceDependency, ServiceInstance } from "./types"; | ||
import { ObjectMap, ServiceDependency, ServiceInstance } from "./service"; | ||
import { ServiceManager } from "./serviceManager"; | ||
@@ -14,7 +14,7 @@ /** | ||
*/ | ||
instances: ObjectMap<string, ServiceInstance<unknown, unknown>>; | ||
instances: ObjectMap<ServiceInstance<unknown, unknown>>; | ||
/** | ||
* All bundle dependency data that is held by the {@link BundleManager}. | ||
*/ | ||
bundleDependencies: ObjectMap<string, ServiceDependency<unknown>[]>; | ||
bundleDependencies: ObjectMap<ServiceDependency<unknown>[]>; | ||
} | ||
@@ -31,3 +31,3 @@ /** | ||
/** | ||
* Decryptes the passed encrypted data using the passed password. | ||
* Decrypts the passed encrypted data using the passed password. | ||
* If the password is wrong an error will be returned. | ||
@@ -95,2 +95,11 @@ * | ||
private saveAfterServiceInstancesLoaded; | ||
/** | ||
* Checks whether automatic login is setup and enabled. If yes it will do it using {@link PersistenceManager.setupAutomaticLogin}. | ||
*/ | ||
private checkAutomaticLogin; | ||
/** | ||
* Setups everything needed to automatically login using the provided password after nodecg has loaded. | ||
*/ | ||
private setupAutomaticLogin; | ||
} | ||
//# sourceMappingURL=persistenceManager.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.PersistenceManager = exports.decryptData = void 0; | ||
const crypto = require("crypto-js"); | ||
const tslib_1 = require("tslib"); | ||
const crypto = (0, tslib_1.__importStar)(require("crypto-js")); | ||
const result_1 = require("./utils/result"); | ||
/** | ||
* Decryptes the passed encrypted data using the passed password. | ||
* Decrypts the passed encrypted data using the passed password. | ||
* If the password is wrong an error will be returned. | ||
@@ -18,6 +19,6 @@ * | ||
const data = JSON.parse(decryptedText); | ||
return result_1.success(data); | ||
return (0, result_1.success)(data); | ||
} | ||
catch (_a) { | ||
return result_1.error("Password isn't correct."); | ||
catch { | ||
return (0, result_1.error)("Password isn't correct."); | ||
} | ||
@@ -39,2 +40,3 @@ } | ||
}); | ||
this.checkAutomaticLogin(); | ||
} | ||
@@ -64,3 +66,3 @@ /** | ||
isFirstStartup() { | ||
return this.encryptedData.value.cipherText !== undefined; | ||
return this.encryptedData.value.cipherText === undefined; | ||
} | ||
@@ -74,3 +76,3 @@ /** | ||
if (this.isLoaded()) { | ||
return result_1.error("Config has already been decrypted and loaded."); | ||
return (0, result_1.error)("Config has already been decrypted and loaded."); | ||
} | ||
@@ -102,3 +104,3 @@ if (this.encryptedData.value.cipherText === undefined) { | ||
this.bundles.on("change", () => this.save()); | ||
return result_1.emptySuccess(); | ||
return (0, result_1.emptySuccess)(); | ||
} | ||
@@ -111,14 +113,10 @@ /** | ||
loadServiceInstances(instances) { | ||
return Object.keys(instances).map((instanceName) => { | ||
const inst = instances[instanceName]; | ||
if (inst === undefined) { | ||
return Promise.resolve(); | ||
} | ||
return Object.entries(instances).map(([instanceName, instance]) => { | ||
// Re-create service instance. | ||
const result = this.instances.createServiceInstance(inst.serviceType, instanceName); | ||
const result = this.instances.createServiceInstance(instance.serviceType, instanceName); | ||
if (result.failed) { | ||
this.nodecg.log.info(`Couldn't load instance "${instanceName}" from saved configuration: ${result.errorMessage}`); | ||
this.nodecg.log.warn(`Couldn't load instance "${instanceName}" from saved configuration: ${result.errorMessage}`); | ||
return Promise.resolve(); | ||
} | ||
const svc = this.services.getService(inst.serviceType); | ||
const svc = this.services.getService(instance.serviceType); | ||
if (!svc.failed && svc.result.requiresNoConfig) { | ||
@@ -132,10 +130,10 @@ return Promise.resolve(); | ||
return this.instances | ||
.updateInstanceConfig(instanceName, inst.config, false) | ||
.then((result) => { | ||
.updateInstanceConfig(instanceName, instance.config, false) | ||
.then(async (result) => { | ||
if (result.failed) { | ||
this.nodecg.log.info(`Couldn't load config of instance "${instanceName}" from saved configuration: ${result.errorMessage}.`); | ||
throw result.errorMessage; | ||
} | ||
}) | ||
.catch((reason) => { | ||
this.nodecg.log.info(`Couldn't load config of instance "${instanceName}" from saved configuration: ${reason}.`); | ||
this.nodecg.log.warn(`Couldn't load config of instance "${instanceName}" from saved configuration: ${reason}.`); | ||
}); | ||
@@ -149,8 +147,4 @@ }); | ||
loadBundleDependencies(bundles) { | ||
Object.keys(bundles).forEach((bundleName) => { | ||
if (!Object.prototype.hasOwnProperty.call(bundles, bundleName)) { | ||
return; | ||
} | ||
const deps = bundles[bundleName]; | ||
deps === null || deps === void 0 ? void 0 : deps.forEach((svcDep) => { | ||
Object.entries(bundles).forEach(([bundleName, deps]) => { | ||
deps.forEach((svcDep) => { | ||
// Re-setting bundle service dependencies. | ||
@@ -177,3 +171,3 @@ // We can ignore the case of undefined, because the default is that the bundle doesn't get any service | ||
} | ||
// Organise all data that will be encrypted into a single object. | ||
// Organize all data that will be encrypted into a single object. | ||
const data = { | ||
@@ -194,15 +188,9 @@ instances: this.getServiceInstances(), | ||
const copy = {}; | ||
for (const instName in instances) { | ||
if (!Object.prototype.hasOwnProperty.call(instances, instName)) { | ||
continue; | ||
} | ||
const instance = instances[instName]; | ||
if (instance) { | ||
copy[instName] = { | ||
serviceType: instance === null || instance === void 0 ? void 0 : instance.serviceType, | ||
config: instance === null || instance === void 0 ? void 0 : instance.config, | ||
client: undefined, | ||
}; | ||
} | ||
} | ||
Object.entries(instances).forEach(([instName, instance]) => { | ||
copy[instName] = { | ||
serviceType: instance.serviceType, | ||
config: instance.config, | ||
client: undefined, | ||
}; | ||
}); | ||
return copy; | ||
@@ -222,4 +210,54 @@ } | ||
} | ||
/** | ||
* Checks whether automatic login is setup and enabled. If yes it will do it using {@link PersistenceManager.setupAutomaticLogin}. | ||
*/ | ||
checkAutomaticLogin() { | ||
var _a; | ||
if (((_a = this.nodecg.bundleConfig.automaticLogin) === null || _a === void 0 ? void 0 : _a.enabled) === undefined) { | ||
return; // Not configured | ||
} | ||
// If enabled isn't undefined the JSON schema guarantees that enabled is a boolean and password is a string | ||
const enabled = this.nodecg.bundleConfig.automaticLogin.enabled; | ||
const password = this.nodecg.bundleConfig.automaticLogin.password; | ||
if (enabled === false) { | ||
// We inform the user that automatic login is setup but not activated because having the ability | ||
// to disable it by setting the enabled flag to false is meant for temporary cases. | ||
// If automatic login is permanently not used the user should remove the password from the config | ||
// to regain the advantages of data-at-rest encryption which are slashed when the password is also stored on disk. | ||
this.nodecg.log.warn("Automatic login is setup but disabled."); | ||
return; | ||
} | ||
this.setupAutomaticLogin(password); | ||
} | ||
/** | ||
* Setups everything needed to automatically login using the provided password after nodecg has loaded. | ||
*/ | ||
setupAutomaticLogin(password) { | ||
// We need to do the login after all bundles have been loaded because when loading these might add bundle dependencies | ||
// or even register services which we need to load nodecg-io. | ||
// There is no official way to wait for nodecg to be done loading so we use more or less a hack to find that out: | ||
// When we declare the replicant here we will trigger a change event with a empty array. | ||
// Once nodecg is done loading all bundles it'll assign a array of bundles that were loaded to this replicant | ||
// So if we want to wait for nodecg to be loaded we can watch for changes on this replicant and | ||
// if we get a non-empty array it means that nodecg has finished loading. | ||
this.nodecg.Replicant("bundles", "nodecg").on("change", async (bundles) => { | ||
if (bundles.length > 0) { | ||
try { | ||
this.nodecg.log.info("Attempting to automatically login..."); | ||
const loadResult = await this.load(password); | ||
if (!loadResult.failed) { | ||
this.nodecg.log.info("Automatic login successful."); | ||
} | ||
else { | ||
throw loadResult.errorMessage; | ||
} | ||
} | ||
catch (err) { | ||
this.nodecg.log.error(`Failed to automatically login: ${err}`); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
exports.PersistenceManager = PersistenceManager; | ||
//# sourceMappingURL=persistenceManager.js.map |
import { NodeCGIOCore } from "."; | ||
import { NodeCG } from "nodecg/types/server"; | ||
import { Service } from "./types"; | ||
import { NodeCG } from "nodecg-types/types/server"; | ||
import { ObjectMap, Service } from "./service"; | ||
import { Result } from "./utils/result"; | ||
import { Logger } from "./utils/logger"; | ||
/** | ||
@@ -17,3 +18,3 @@ * Class helping to create a nodecg-io service | ||
serviceType: string; | ||
schema: unknown; | ||
schema?: ObjectMap<unknown>; | ||
/** | ||
@@ -24,2 +25,8 @@ * The default value for the config. | ||
/** | ||
* Config presets that the user can choose to load as their config. | ||
* Useful for e.g. detected devices with everything already filled in for that specific device. | ||
* Can also be used to show the user multiple different authentication methods or similar. | ||
*/ | ||
presets?: ObjectMap<R>; | ||
/** | ||
* This constructor creates the service and gets the nodecg-io-core | ||
@@ -40,5 +47,6 @@ * @param nodecg the current NodeCG instance | ||
* @param config the config which should be validated. | ||
* @param logger the logger which logs with the instance.name as prefix | ||
* @return void if the config passes validation and an error string describing the issue if not. | ||
*/ | ||
abstract validateConfig(config: R): Promise<Result<void>>; | ||
abstract validateConfig(config: R, logger: Logger): Promise<Result<void>>; | ||
/** | ||
@@ -49,5 +57,6 @@ * Creates a client to the service using the validated config. | ||
* @param config the user provided config for the service. | ||
* @param logger the logger which logs with the instance.name as prefix | ||
* @return the client if everything went well and an error string describing the issue if a error occured. | ||
*/ | ||
abstract createClient(config: R): Promise<Result<C>>; | ||
abstract createClient(config: R, logger: Logger): Promise<Result<C>>; | ||
/** | ||
@@ -58,4 +67,5 @@ * Stops a client of this service that is not needed anymore. | ||
* @param client the client that needs to be stopped. | ||
* @param logger the logger which logs with the instance.name as prefix | ||
*/ | ||
abstract stopClient(client: C): void; | ||
abstract stopClient(client: C, logger: Logger): void; | ||
/** | ||
@@ -89,1 +99,2 @@ * Removes all handlers from a service client. | ||
} | ||
//# sourceMappingURL=serviceBundle.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ServiceBundle = void 0; | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
const tslib_1 = require("tslib"); | ||
const fs = (0, tslib_1.__importStar)(require("fs")); | ||
const path = (0, tslib_1.__importStar)(require("path")); | ||
/** | ||
@@ -55,2 +56,4 @@ * Class helping to create a nodecg-io service | ||
readSchema(pathSegments) { | ||
if (pathSegments.length === 0) | ||
return undefined; | ||
const joinedPath = path.resolve(...pathSegments); | ||
@@ -57,0 +60,0 @@ try { |
@@ -1,3 +0,3 @@ | ||
import { Service } from "./types"; | ||
import { NodeCG } from "nodecg/types/server"; | ||
import { Service } from "./service"; | ||
import { NodeCG } from "nodecg-types/types/server"; | ||
import { Result } from "./utils/result"; | ||
@@ -27,1 +27,2 @@ /** | ||
} | ||
//# sourceMappingURL=serviceManager.d.ts.map |
@@ -36,6 +36,6 @@ "use strict"; | ||
if (svc === undefined) { | ||
return result_1.error("Service hasn't been registered."); | ||
return (0, result_1.error)("Service hasn't been registered."); | ||
} | ||
else { | ||
return result_1.success(svc); | ||
return (0, result_1.success)(svc); | ||
} | ||
@@ -42,0 +42,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import { NodeCG } from "nodecg/types/server"; | ||
import { NodeCG } from "nodecg-types/types/server"; | ||
/** | ||
@@ -30,3 +30,3 @@ * A wrapper around a ServiceClient that has helper functions for setting up callbacks and | ||
/** | ||
* Updates the client and calls all registered handlers of {{@link onAvailable}} and {{@link onUnavailable}} depending | ||
* Updates the client and calls all registered handlers of {@link onAvailable} and {@link onUnavailable} depending | ||
* whether the passed client parameter was undefined or not. | ||
@@ -46,1 +46,2 @@ * This is only intended to be called by the framework and not by a bundle. | ||
export declare function requireService<C>(nodecg: NodeCG, serviceType: string): ServiceProvider<C> | undefined; | ||
//# sourceMappingURL=serviceProvider.d.ts.map |
@@ -44,3 +44,3 @@ "use strict"; | ||
/** | ||
* Updates the client and calls all registered handlers of {{@link onAvailable}} and {{@link onUnavailable}} depending | ||
* Updates the client and calls all registered handlers of {@link onAvailable} and {@link onUnavailable} depending | ||
* whether the passed client parameter was undefined or not. | ||
@@ -47,0 +47,0 @@ * This is only intended to be called by the framework and not by a bundle. |
@@ -43,1 +43,2 @@ /** | ||
export declare function emptySuccess(): Success<void>; | ||
//# sourceMappingURL=result.d.ts.map |
@@ -1,4 +0,6 @@ | ||
export type { ObjectMap, Service, ServiceDependency, ServiceInstance } from "./extension/types"; | ||
export type { ObjectMap, Service, ServiceDependency, ServiceInstance } from "./extension/service"; | ||
export * from "./extension/utils/result"; | ||
export * from "./extension/serviceBundle"; | ||
export * from "./extension/serviceProvider"; | ||
export * from "./extension/utils/logger"; | ||
//# sourceMappingURL=index.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./extension/utils/result"), exports); | ||
tslib_1.__exportStar(require("./extension/serviceBundle"), exports); | ||
tslib_1.__exportStar(require("./extension/serviceProvider"), exports); | ||
(0, tslib_1.__exportStar)(require("./extension/utils/result"), exports); | ||
(0, tslib_1.__exportStar)(require("./extension/serviceBundle"), exports); | ||
(0, tslib_1.__exportStar)(require("./extension/serviceProvider"), exports); | ||
(0, tslib_1.__exportStar)(require("./extension/utils/logger"), exports); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "nodecg-io-core", | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"description": "The core of nodecg-io. Connects everything up.", | ||
"homepage": "https://nodecg.io", | ||
"homepage": "https://nodecg.io/RELEASE", | ||
"author": { | ||
@@ -25,5 +25,5 @@ "name": "CodeOverflow team", | ||
"scripts": { | ||
"build": "tsc -b", | ||
"watch": "tsc -b -w", | ||
"clean": "tsc -b --clean" | ||
"test": "jest", | ||
"watchTest": "jest --watch", | ||
"coverage": "jest --coverage" | ||
}, | ||
@@ -48,12 +48,15 @@ "keywords": [ | ||
"devDependencies": { | ||
"@types/crypto-js": "^4.0.1", | ||
"@types/node": "^14.14.33", | ||
"nodecg": "^1.8.1", | ||
"typescript": "^4.2.3" | ||
"@types/crypto-js": "^4.0.2", | ||
"@types/jest": "^27.0.2", | ||
"@types/node": "^16.11.7", | ||
"jest": "^27.3.1", | ||
"nodecg-types": "^1.8.3", | ||
"typescript": "^4.4.4", | ||
"ts-jest": "^27.0.7" | ||
}, | ||
"dependencies": { | ||
"ajv": "^7.2.1", | ||
"crypto-js": "^4.0.0", | ||
"tslib": "^2.1.0" | ||
"ajv": "^8.6.3", | ||
"crypto-js": "^4.1.1", | ||
"tslib": "^2.3.1" | ||
} | ||
} |
{ | ||
"exclude": ["dashboard"], | ||
"exclude": ["dashboard", "extension/__tests__"], | ||
"extends": "../tsconfig.common.json" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
109751
39
1707
7
+ Addedajv@8.17.1(transitive)
+ Addedfast-uri@3.0.3(transitive)
- Removedajv@7.2.4(transitive)
- Removedpunycode@2.3.1(transitive)
- Removeduri-js@4.4.1(transitive)
Updatedajv@^8.6.3
Updatedcrypto-js@^4.1.1
Updatedtslib@^2.3.1