Merge pull request #401 from HeyPuter/eric/service-patches

Allow patching services
This commit is contained in:
Eric Dubé 2024-05-15 15:47:14 -04:00 committed by GitHub
commit b72e5b7e02
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 51 additions and 0 deletions

View File

@ -319,6 +319,10 @@ module.exports = class APIError {
status: 401, status: 401,
message: 'This authentication token is not supported here.', message: 'This authentication token is not supported here.',
}, },
'token_expired': {
status: 401,
message: 'Authentication token has expired.',
},
'account_suspended': { 'account_suspended': {
status: 403, status: 403,
message: 'Account suspended.', message: 'Account suspended.',

View File

@ -26,12 +26,32 @@ class Container {
this.instances_ = {}; this.instances_ = {};
this.ready = new TeePromise(); this.ready = new TeePromise();
} }
/**
* registerService registers a service with the servuces container.
*
* @param {String} name - the name of the service
* @param {BaseService.constructor} cls - an implementation of BaseService
* @param {Array} args - arguments to pass to the service constructor
*/
registerService (name, cls, args) { registerService (name, cls, args) {
const my_config = config.services?.[name] || {}; const my_config = config.services?.[name] || {};
this.instances_[name] = cls.getInstance this.instances_[name] = cls.getInstance
? cls.getInstance({ services: this, config, my_config, name, args }) ? cls.getInstance({ services: this, config, my_config, name, args })
: new cls({ services: this, config, my_config, name, args }) ; : new cls({ services: this, config, my_config, name, args }) ;
} }
/**
* patchService allows overriding methods on a service that is already
* constructed and initialized.
*
* @param {String} name - the name of the service to patch
* @param {ServicePatch.constructor} patch - the patch
* @param {Array} args - arguments to pass to the patch
*/
patchService (name, patch, args) {
const original_service = this.instances_[name];
const patch_instance = new patch();
patch_instance.patch({ original_service, args });
}
set (name, instance) { this.instances_[name] = instance; } set (name, instance) { this.instances_[name] = instance; }
get (name, opts) { get (name, opts) {
if ( this.instances_[name] ) { if ( this.instances_[name] ) {

View File

@ -0,0 +1,27 @@
const { AdvancedBase } = require("@heyputer/puter-js-common");
class ServicePatch extends AdvancedBase {
patch ({ original_service }) {
const patch_methods = this._get_merged_static_object('PATCH_METHODS');
for ( const k in patch_methods ) {
if ( typeof patch_methods[k] !== 'function' ) {
throw new Error(`Patch method ${k} to ${original_service.service_name} ` +
`from ${this.constructor.name} ` +
`is not a function.`)
}
const patch_method = patch_methods[k];
const patch_arguments = {
that: original_service,
original: original_service[k].bind(original_service),
};
original_service[k] = (...a) => {
return patch_method.call(this, patch_arguments, ...a);
}
}
}
}
module.exports = ServicePatch;