diff options
author | Samy Pessé <samypesse@gmail.com> | 2015-10-13 13:56:46 +0200 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2015-10-13 13:56:46 +0200 |
commit | df5d27ab6103389294795a7fada76d46f36fc00f (patch) | |
tree | b5ce91ae52573db8574a5aa7a2bb9780a7c4d0a0 | |
parent | 2870155c0b3b91efc2a4d3fe2e1edd5a1be9ae8a (diff) | |
download | gitbook-df5d27ab6103389294795a7fada76d46f36fc00f.zip gitbook-df5d27ab6103389294795a7fada76d46f36fc00f.tar.gz gitbook-df5d27ab6103389294795a7fada76d46f36fc00f.tar.bz2 |
Use jsonschema to valid and default plugins config
-rw-r--r-- | lib/configuration.js | 15 | ||||
-rw-r--r-- | lib/plugin.js | 29 | ||||
-rw-r--r-- | lib/pluginslist.js | 56 | ||||
-rw-r--r-- | package.json | 4 | ||||
-rw-r--r-- | test/plugins.js | 2 |
5 files changed, 80 insertions, 26 deletions
diff --git a/lib/configuration.js b/lib/configuration.js index 24d435b..64d4b17 100644 --- a/lib/configuration.js +++ b/lib/configuration.js @@ -194,6 +194,21 @@ Configuration.prototype.get = function(key, def) { return _.get(this.options, key, def); }; +// Update a configuration +Configuration.prototype.set = function(key, value) { + return _.set(this.options, key, value); +}; + +// Return a configuration for a plugin +Configuration.prototype.getForPlugin = function(pluginName) { + return this.get('pluginsConfig.'+pluginName, {}); +}; + +// Set a configuration for a plugin +Configuration.prototype.setForPlugin = function(pluginName, config) { + return this.get('pluginsConfig.'+pluginName, config); +}; + // Default configuration Configuration.DEFAULT = DEFAULT_CONFIG; diff --git a/lib/plugin.js b/lib/plugin.js index 3191c63..45d77b8 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -5,6 +5,8 @@ var path = require('path'); var url = require('url'); var fs = require('./utils/fs'); var resolve = require('resolve'); +var jsonschema = require('jsonschema'); +var jsonSchemaDefaults = require('json-schema-defaults'); var pkg = require('../package.json'); @@ -20,7 +22,7 @@ var Plugin = function(book, name) { _.each([ 'gitbook-plugin-'+name, 'gitbook-'+name, - name, + name ], function(_name) { // Load from the book if (this.load(_name, book.root)) return false; @@ -44,7 +46,7 @@ Plugin.prototype.load = function(name, baseDir) { this.baseDir = path.dirname(res); this.packageInfos = require(res); this.infos = require(resolve.sync(name, { basedir: baseDir })); - this.name = name; + this.name = this.packageInfos.name; return true; } catch (e) { @@ -139,6 +141,29 @@ Plugin.prototype.isValid = function() { return isValid; }; +// Normalize, validate configuration for this plugin using its schema +// Throw an error when shcema is not respected +Plugin.prototype.validateConfig = function(config) { + var that = this; + + return Q() + .then(function() { + var schema = that.packageInfos.gitbook || {}; + if (!schema) return config; + + // Normalize schema + schema.type = 'object'; + + // Validate and throw if invalid + var v = new jsonschema.Validator(); + v.validate(config, schema); + + // Insert default values + var defaults = jsonSchemaDefaults(schema); + return _.merge(defaults, config); + }); +}; + // Resolve file path Plugin.prototype.resolveFile = function(filename) { return path.resolve(this.baseDir, filename); diff --git a/lib/pluginslist.js b/lib/pluginslist.js index e4594d6..636eddc 100644 --- a/lib/pluginslist.js +++ b/lib/pluginslist.js @@ -78,34 +78,46 @@ PluginsList.prototype.load = function(plugin) { that.list.push(plugin); } - // Extract filters - that.book.template.addFilters(plugin.getFilters()); + return Q() - // Extract blocks - that.book.template.addBlocks(plugin.getBlocks()); + // Validate and normalize configuration + .then(function() { + var config = that.book.config.getForPlugin(plugin.name); + return plugin.validateConfig(config); + }) + .then(function(config) { + // Update configuration + that.book.config.getForPlugin(plugin.name, config); - return _.reduce(_.keys(that.namespaces), function(prev, namespaceName) { - return prev.then(function() { - return plugin.getResources(namespaceName) - .then(function(plResources) { - var namespace = that.namespaces[namespaceName]; - - // Extract js and css - _.each(Plugin.RESOURCES, function(resourceType) { - namespace.resources[resourceType] = (namespace.resources[resourceType] || []).concat(plResources[resourceType] || []); - }); + // Extract filters + that.book.template.addFilters(plugin.getFilters()); - // Map of html resources by name added by each plugin - _.each(plResources.html || {}, function(value, tag) { - // Turn into function if not one already - if (!_.isFunction(value)) value = _.constant(value); + // Extract blocks + that.book.template.addBlocks(plugin.getBlocks()); - namespace.html[tag] = namespace.html[tag] || []; - namespace.html[tag].push(value); + return _.reduce(_.keys(that.namespaces), function(prev, namespaceName) { + return prev.then(function() { + return plugin.getResources(namespaceName) + .then(function(plResources) { + var namespace = that.namespaces[namespaceName]; + + // Extract js and css + _.each(Plugin.RESOURCES, function(resourceType) { + namespace.resources[resourceType] = (namespace.resources[resourceType] || []).concat(plResources[resourceType] || []); + }); + + // Map of html resources by name added by each plugin + _.each(plResources.html || {}, function(value, tag) { + // Turn into function if not one already + if (!_.isFunction(value)) value = _.constant(value); + + namespace.html[tag] = namespace.html[tag] || []; + namespace.html[tag].push(value); + }); }); }); - }); - }, Q()); + }, Q()); + }); }; // Call a hook diff --git a/package.json b/package.json index 3eeec2e..a9467f5 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,9 @@ "dom-serializer": "0.1.0", "spawn-cmd": "0.0.2", "escape-string-regexp": "1.0.3", - "juice": "1.5.0" + "juice": "1.5.0", + "jsonschema": "1.0.2", + "json-schema-defaults": "0.1.1" }, "devDependencies": { "eslint": "1.5.0", diff --git a/test/plugins.js b/test/plugins.js index c0f2373..4f91e9a 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -93,7 +93,7 @@ describe('Plugins', function () { // There is resources from highlight plugin and this plugin resources.css.should.have.lengthOf(2); should.exist(_.find(resources.css, { - path: './resources/test' + path: 'gitbook-plugin-resources/test' })); }); }); |