import { NodeCGIOCore } from "." ; import { NodeCG } from "nodecg-types/types/server" ; import { ObjectMap , Service } from "./service" ; import { Result } from "./utils/result" ; import * as fs from "fs" ; import * as path from "path" ; import { Logger } from "./utils/logger" ; typeParam typeParam C the type of client that the service will provide to bundles using  createClient .
  export abstract class ServiceBundle < R , C > implements Service < R , C > { public core : NodeCGIOCore | undefined ; public nodecg : NodeCG ; public serviceType : string ; public schema ? : ObjectMap < unknown > ; /**
     * The default value for the config.
     */ public defaultConfig ? : R ; /**
     * 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.
     */ public presets ? : ObjectMap < R > ; param nodecg param serviceName param pathSegments constructor ( nodecg , serviceName , ... pathSegments ) { this . nodecg = nodecg ; this . serviceType = serviceName ; this . schema = this . readSchema ( pathSegments ) ; this . nodecg . log . info ( this . serviceType + " bundle started." ) ; this . core = this . nodecg . extensions [ "nodecg-io-core" ] as unknown as NodeCGIOCore | undefined ; if ( this . core === undefined ) { this . nodecg . log . error ( "nodecg-io-core isn't loaded! " + this . serviceType + " bundle won't function without it." ) ; } } return public register ( ) { this . core ?. registerService ( this ) ; } param config param logger return abstract validateConfig ( config , logger ) ; param config param logger return abstract createClient ( config , logger ) ; param client param logger abstract stopClient ( client , logger ) ; param client removeHandlers ? ( client ) ; /**
     * This flag can be enabled by services if they can't implement removeHandlers but also have some handlers that
     * should be reset if a bundleDependency has been changed.
     * It gets rid of the handlers by stopping the client and creating a new one, to which then only the
     * now wanted handlers get registered (e.g., if a bundle doesn't use this service any more, but another still does).
     * Not ideal, but if your service can't implement removeHandlers for some reason it is still better than
     * having dangling handlers that still fire events even though they shouldn't.
     */ reCreateClientToRemoveHandlers = false ; /**
     * This flag says that this service cannot be configured and doesn't need any config passed to  createClient .
     * If this is set,  validateConfig will never be called.
     *  default requiresNoConfig = false ; private readSchema ( pathSegments ) { if ( pathSegments . length === 0 ) return undefined ; const joinedPath = path . resolve ( ... pathSegments ) ; try { const fileContent = fs . readFileSync ( joinedPath , "utf8" ) ; return JSON . parse ( fileContent ) ; } catch ( err ) { this . nodecg . log . error ( "Couldn't read and parse service schema at " + joinedPath . toString ( ) ) ; return undefined ; } } }