summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSamy Pessé <samypesse@gmail.com>2015-10-13 13:56:46 +0200
committerSamy Pessé <samypesse@gmail.com>2015-10-13 13:56:46 +0200
commitdf5d27ab6103389294795a7fada76d46f36fc00f (patch)
treeb5ce91ae52573db8574a5aa7a2bb9780a7c4d0a0
parent2870155c0b3b91efc2a4d3fe2e1edd5a1be9ae8a (diff)
downloadgitbook-df5d27ab6103389294795a7fada76d46f36fc00f.zip
gitbook-df5d27ab6103389294795a7fada76d46f36fc00f.tar.gz
gitbook-df5d27ab6103389294795a7fada76d46f36fc00f.tar.bz2
Use jsonschema to valid and default plugins config
-rw-r--r--lib/configuration.js15
-rw-r--r--lib/plugin.js29
-rw-r--r--lib/pluginslist.js56
-rw-r--r--package.json4
-rw-r--r--test/plugins.js2
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'
}));
});
});