1
0
Эх сурвалжийг харах

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

Allow patching services
Eric Dubé 1 жил өмнө
parent
commit
b72e5b7e02

+ 4 - 0
packages/backend/src/api/APIError.js

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

+ 20 - 0
packages/backend/src/services/Container.js

@@ -26,12 +26,32 @@ class Container {
         this.instances_ = {};
         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) {
         const my_config = config.services?.[name] || {};
         this.instances_[name] = cls.getInstance
             ? cls.getInstance({ 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; }
     get (name, opts) {
         if ( this.instances_[name] ) {

+ 27 - 0
packages/backend/src/services/ServicePatch.js

@@ -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;