diff --git a/core/server/services/adapter-manager/index.js b/core/server/services/adapter-manager/index.js index e07debc73e..f1f77573c6 100644 --- a/core/server/services/adapter-manager/index.js +++ b/core/server/services/adapter-manager/index.js @@ -1,5 +1,6 @@ const AdapterManager = require('@tryghost/adapter-manager'); const getAdapterServiceConfig = require('./config'); +const resolveAdapterOptions = require('./options-resolver'); const config = require('../../../shared/config'); const adapterManager = new AdapterManager({ @@ -16,13 +17,16 @@ adapterManager.registerAdapter('scheduling', require('../../adapters/scheduling/ adapterManager.registerAdapter('sso', require('../../adapters/sso/Base')); module.exports = { - getAdapter(adapterType) { + /** + * + * @param {String} name - one of 'storage', 'scheduling', 'sso' etc. Or can contain a "resource" extension like "storage:image" + * @returns {Object} instance of an adapter + */ + getAdapter(name) { const adapterServiceConfig = getAdapterServiceConfig(config); - const adapterSettings = adapterServiceConfig[adapterType]; - const activeAdapter = adapterSettings.active; - const activeAdapterConfig = adapterSettings[activeAdapter]; + const {adapterType, adapterName, adapterConfig} = resolveAdapterOptions(name, adapterServiceConfig); - return adapterManager.getAdapter(adapterType, activeAdapter, activeAdapterConfig); + return adapterManager.getAdapter(adapterType, adapterName, adapterConfig); } }; diff --git a/core/server/services/adapter-manager/options-resolver.js b/core/server/services/adapter-manager/options-resolver.js new file mode 100644 index 0000000000..c02782c15d --- /dev/null +++ b/core/server/services/adapter-manager/options-resolver.js @@ -0,0 +1,18 @@ +module.exports = function resolveAdapterOptions(name, adapterServiceConfig) { + const [adapterType, feature] = name.split(':'); + const adapterSettings = adapterServiceConfig[adapterType]; + + let adapterName; + let adapterConfig; + + // CASE: load resource-specific adapter when there is an adapter feature name specified as well as custom feature config + if (feature && adapterSettings[feature] && adapterSettings[adapterSettings[feature]]) { + adapterName = adapterSettings[feature]; + adapterConfig = adapterSettings[adapterName]; + } else { + adapterName = adapterSettings.active; + adapterConfig = adapterSettings[adapterName]; + } + + return {adapterType, adapterName, adapterConfig}; +}; diff --git a/test/unit/server/services/adapter-manager/options-resolver.test.js b/test/unit/server/services/adapter-manager/options-resolver.test.js new file mode 100644 index 0000000000..ac881547d8 --- /dev/null +++ b/test/unit/server/services/adapter-manager/options-resolver.test.js @@ -0,0 +1,74 @@ +const should = require('should'); + +const resolveAdapterOptions = require('../../../../../core/server/services/adapter-manager/options-resolver'); + +describe('Adapter Manager: options resolver', function () { + it('returns default adapter configuration', function () { + const name = 'storage'; + const adapterServiceConfig = { + storage: { + active: 'cloud-storage', + 'cloud-storage': { + custom: 'configValue' + } + } + }; + + const {adapterType, adapterName, adapterConfig} = resolveAdapterOptions(name, adapterServiceConfig); + + adapterType.should.equal('storage'); + adapterName.should.equal('cloud-storage'); + adapterConfig.should.deepEqual({ + custom: 'configValue' + }); + }); + + it('returns adapter configuration based on specified feature', function () { + const name = 'storage:videos'; + const adapterServiceConfig = { + storage: { + active: 'cloud-storage', + videos: 'local-storage', + 'cloud-storage': { + custom: 'configValue' + }, + 'local-storage': { + custom: 'localStorageConfig' + } + } + }; + + const {adapterType, adapterName, adapterConfig} = resolveAdapterOptions(name, adapterServiceConfig); + + adapterType.should.equal('storage'); + adapterName.should.equal('local-storage'); + adapterConfig.should.deepEqual({ + custom: 'localStorageConfig' + }); + }); + + it('returns active configuration if piece of feature adapter is missing', function () { + const name = 'storage:videos'; + const adapterServiceConfig = { + storage: { + active: 'cloud-storage', + videos: 'local-storage', + 'cloud-storage': { + custom: 'configValue' + } + // when you forget to configure local-storage! + // 'local-storage': { + // custom: 'localStorageConfig' + // } + } + }; + + const {adapterType, adapterName, adapterConfig} = resolveAdapterOptions(name, adapterServiceConfig); + + adapterType.should.equal('storage'); + adapterName.should.equal('cloud-storage'); + adapterConfig.should.deepEqual({ + custom: 'configValue' + }); + }); +});