diff --git a/src/base-commands/base-command.js b/src/base-commands/base-command.js index 4f664f1c..7ad3a6b5 100644 --- a/src/base-commands/base-command.js +++ b/src/base-commands/base-command.js @@ -3,7 +3,7 @@ const { CLIError } = require('@oclif/errors'); const pkg = require('../../package.json'); const MessageTemplates = require('../services/messaging/templates'); -const { Config, ConfigData } = require('../services/config'); +const { Config, ConfigData, PluginConfig } = require('../services/config'); const { TwilioCliError } = require('../services/error'); const { logger, LoggingLevel } = require('../services/messaging/logging'); const { OutputFormats } = require('../services/output-formats'); @@ -170,6 +170,22 @@ class BaseCommand extends Command { async install(name) { return requireInstall(name, this); } + + get pluginConfig() { + if (!this._pluginConfig) { + const pluginName = getCommandPlugin(this); + this._pluginConfig = new PluginConfig(this.config.configDir, pluginName); + } + return this._pluginConfig; + } + + async getPluginConfig() { + return this.pluginConfig.getConfig(); + } + + async setPluginConfig(config) { + return this.pluginConfig.setConfig(config); + } } BaseCommand.flags = { diff --git a/src/services/config.js b/src/services/config.js index 3c1a1071..7c5763dc 100644 --- a/src/services/config.js +++ b/src/services/config.js @@ -192,8 +192,32 @@ class Config { } } +class PluginConfig { + constructor(configDir, pluginName) { + this.filePath = path.join(configDir, 'plugins', pluginName, 'config.json'); + } + + async getConfig() { + try { + return await fs.readJSON(this.filePath, { encoding: 'utf-8' }); + } catch (error) { + return {}; + } + } + + async setConfig(config) { + try { + await fs.writeJSON(this.filePath, config); + } catch (error) { + await fs.mkdir(path.dirname(this.filePath), { recursive: true }); + await fs.writeJSON(this.filePath, config); + } + } +} + module.exports = { CLI_NAME, Config, ConfigData, + PluginConfig, }; diff --git a/test/services/config.test.js b/test/services/config.test.js index e38bc9d5..af77b689 100644 --- a/test/services/config.test.js +++ b/test/services/config.test.js @@ -3,7 +3,7 @@ const path = require('path'); const tmp = require('tmp'); const { expect, test, constants } = require('@twilio/cli-test'); -const { Config, ConfigData } = require('../../src/services/config'); +const { Config, ConfigData, PluginConfig } = require('../../src/services/config'); const FAKE_AUTH_TOKEN = '1234567890abcdefghijklmnopqrstuvwxyz'; @@ -231,5 +231,35 @@ describe('services', () => { expect(saveMessage).to.contain(`${nestedConfig}${path.sep}config.json`); }); }); + + describe('PluginConfig', () => { + let tempConfigDir; + beforeEach(() => { + tempConfigDir = tmp.dirSync({ unsafeCleanup: true }); + }); + afterEach(() => { + tempConfigDir.removeCallback(); + }); + + test.it("loads an empty object when the plugin directory doesn't exist", async () => { + const pluginConfig = new PluginConfig(tempConfigDir.name, 'test-plugin'); + expect(await pluginConfig.getConfig()).to.deep.equal({}); + }); + + test.it("saves config to the plugin directory when it doesn't exist", async () => { + const pluginConfig = new PluginConfig(tempConfigDir.name, 'test-plugin'); + await pluginConfig.setConfig({ foo: 'bar' }); + expect(await pluginConfig.getConfig()).to.deep.equal({ foo: 'bar' }); + }); + + test.it('overwrites config when it already exists', async () => { + const pluginConfig = new PluginConfig(tempConfigDir.name, 'test-plugin'); + await pluginConfig.setConfig({ hello: 'world' }); + + const pluginConfig2 = new PluginConfig(tempConfigDir.name, 'test-plugin'); + await pluginConfig2.setConfig({ foo: 'bar' }); + expect(await pluginConfig2.getConfig()).to.deep.equal({ foo: 'bar' }); + }); + }); }); });