diff --git a/src/backend/src/services/drivers/DriverService.js b/src/backend/src/services/drivers/DriverService.js index bee469a51..2fcb99fb7 100644 --- a/src/backend/src/services/drivers/DriverService.js +++ b/src/backend/src/services/drivers/DriverService.js @@ -41,6 +41,44 @@ class DriverService extends BaseService { types: require('./types'), } + // 'IMPLEMENTS' here makes DriverService itself a driver + static IMPLEMENTS = { + driver: { + async usage () { + const actor = Context.get('actor'); + + const usages = { + user: {}, // map[str(iface:method)]{date,count,max} + apps: {}, // []{app,map[str(iface:method)]{date,count,max}} + app_objects: {}, + usages: [], + }; + + const event = { + actor, + usages: [], + }; + const svc_event = this.services.get('event'); + await svc_event.emit('usages.query', event); + usages.usages = event.usages; + + + for ( const k in usages.apps ) { + usages.apps[k] = Object.values(usages.apps[k]); + } + + return { + // Usage endpoint reports these, but the driver doesn't need to + // user: Object.values(usages.user), + // apps: usages.apps, + // app_objects: usages.app_objects, + + // This is the main "usages" object + usages: usages.usages, + }; + } + } + } _construct () { this.drivers = {}; @@ -126,6 +164,26 @@ class DriverService extends BaseService { { col_drivers }); } + // This is a bit meta: we register the "driver" driver interface. + // This allows DriverService to be a driver called "driver". + // The driver drivers allows checking metered usage for drivers, + // and in the future may provide other driver-related functions. + async ['__on_driver.register.interfaces'] () { + const svc_registry = this.services.get('registry'); + const col_interfaces = svc_registry.get('interfaces'); + + col_interfaces.set('driver', { + description: 'provides functions for managing Puter drivers', + methods: { + usage: { + description: 'get usage information for drivers', + parameters: {}, + result: { type: 'json' }, + } + } + }); + } + register_driver (interface_name, implementation) { this.interface_to_implementation[interface_name] = implementation; }