Skip to content

Commit

Permalink
Lots of refactoring. Introducing a plug-in model ("resolvers" and "pa…
Browse files Browse the repository at this point in the history
…rsers") for #8
  • Loading branch information
JamesMessinger committed Mar 27, 2016
1 parent 30ecdd2 commit 2d5b52c
Show file tree
Hide file tree
Showing 34 changed files with 799 additions and 629 deletions.
1 change: 0 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,3 @@ coverage
dist
www
node_modules
tests
4 changes: 2 additions & 2 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"browser": true, // browser global variables.
"node": true, // Node.js global variables and Node.js-specific rules.
"amd": false, // defines require() and define() as global variables as per the amd spec.
"mocha": true, // adds all of the Mocha testing global variables.
"mocha": false, // adds all of the Mocha testing global variables.
"jasmine": false, // adds all of the Jasmine testing global variables for version 0.3 and 0.0.
"phantomjs": false, // phantomjs global variables.
"jquery": false, // jquery global variables.
Expand Down Expand Up @@ -207,7 +207,7 @@
"beforeColon": false, // require a space before the colon in a key/value pair
"afterColon": true // require a space after the colon in a key/value pair
}],
"lines-around-comment": [2, { // enforce empty lines around comments
"lines-around-comment": [0, { // enforce empty lines around comments
"beforeBlockComment": true, // require a blank line before block comments
"afterBlockComment": false, // require a blank line after block comments
"beforeLineComment": false, // require a blank line before line comments
Expand Down
14 changes: 7 additions & 7 deletions lib/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

var $Ref = require('./ref'),
Pointer = require('./pointer'),
util = require('./util'),
url = require('url');
debug = require('./util/debug'),
url = require('./util/url');

module.exports = bundle;

Expand All @@ -22,7 +22,7 @@ module.exports = bundle;
* @param {$RefParserOptions} options
*/
function bundle(parser, options) {
util.debug('Bundling $ref pointers in %s', parser.$refs._basePath);
debug('Bundling $ref pointers in %s', parser.$refs._basePath);

// Build an inventory of all $ref pointers in the JSON Schema
var inventory = [];
Expand Down Expand Up @@ -88,8 +88,8 @@ function inventory$Ref($refParent, $refKey, path, pathFromRoot, inventory, $refs
var $refPath = url.resolve(path, $ref.$ref);
var pointer = $refs._resolve($refPath, options);
var depth = Pointer.parse(pathFromRoot).length;
var file = util.path.stripHash(pointer.path);
var hash = util.path.getHash(pointer.path);
var file = url.stripHash(pointer.path);
var hash = url.getHash(pointer.path);
var external = file !== $refs._basePath;
var extended = $Ref.isExtended$Ref($ref);

Expand Down Expand Up @@ -160,7 +160,7 @@ function remap(inventory) {

var file, hash, pathFromRoot;
inventory.forEach(function(i) {
util.debug('Re-mapping $ref pointer "%s" at %s', i.$ref.$ref, i.pathFromRoot);
debug('Re-mapping $ref pointer "%s" at %s', i.$ref.$ref, i.pathFromRoot);

if (!i.external) {
// This $ref already resolves to the main JSON Schema file
Expand All @@ -186,6 +186,6 @@ function remap(inventory) {
i.$ref.$ref = Pointer.join(pathFromRoot, Pointer.parse(i.hash));
}

util.debug(' new value: %s', (i.$ref && i.$ref.$ref) ? i.$ref.$ref : '[object Object]');
debug(' new value: %s', (i.$ref && i.$ref.$ref) ? i.$ref.$ref : '[object Object]');
});
}
8 changes: 4 additions & 4 deletions lib/dereference.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

var $Ref = require('./ref'),
Pointer = require('./pointer'),
util = require('./util'),
ono = require('ono'),
url = require('url');
debug = require('./util/debug'),
url = require('./util/url');

module.exports = dereference;

Expand All @@ -16,7 +16,7 @@ module.exports = dereference;
* @param {$RefParserOptions} options
*/
function dereference(parser, options) {
util.debug('Dereferencing $ref pointers in %s', parser.$refs._basePath);
debug('Dereferencing $ref pointers in %s', parser.$refs._basePath);
parser.$refs.circular = false;
crawl(parser.schema, parser.$refs._basePath, '#', [], parser.$refs, options);
}
Expand Down Expand Up @@ -79,7 +79,7 @@ function crawl(obj, path, pathFromRoot, parents, $refs, options) {
* @returns {object}
*/
function dereference$Ref($ref, path, pathFromRoot, parents, $refs, options) {
util.debug('Dereferencing $ref pointer "%s" at %s', $ref.$ref, path);
debug('Dereferencing $ref pointer "%s" at %s', $ref.$ref, path);

var $refPath = url.resolve(path, $ref.$ref);
var pointer = $refs._resolve($refPath, options);
Expand Down
9 changes: 4 additions & 5 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ var Promise = require('./util/promise'),
resolve = require('./resolve'),
bundle = require('./bundle'),
dereference = require('./dereference'),
util = require('./util'),
url = require('url'),
url = require('./util/url'),
maybe = require('call-me-maybe'),
ono = require('ono');

Expand Down Expand Up @@ -82,9 +81,9 @@ $RefParser.prototype.parse = function(schema, options, callback) {
}

// Resolve the absolute path of the schema
args.schema = util.path.localPathToUrl(args.schema);
args.schema = url.resolve(util.path.cwd(), args.schema);
this.$refs._basePath = util.path.stripHash(args.schema);
args.schema = url.localPathToUrl(args.schema);
args.schema = url.resolve(url.cwd(), args.schema);
this.$refs._basePath = url.stripHash(args.schema);

// Read the schema file/url
promise = read(args.schema, this.$refs, args.options);
Expand Down
87 changes: 42 additions & 45 deletions lib/options.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
/* eslint lines-around-comment: [2, {beforeBlockComment: false}] */
'use strict';

var parseJSON = require('./parse/json'),
parseYAML = require('./parse/yaml'),
parseText = require('./parse/text'),
parseBinary = require('./parse/binary'),
readFile = require('./read/file'),
readHttp = require('./read/http'),
util = require('./util');
var jsonParser = require('./parsers/json'),
yamlParser = require('./parsers/yaml'),
textParser = require('./parsers/text'),
binaryParser = require('./parsers/binary'),
fileResolver = require('./resolvers/file'),
httpResolver = require('./resolvers/http');

module.exports = $RefParserOptions;

Expand All @@ -18,6 +17,11 @@ module.exports = $RefParserOptions;
* @constructor
*/
function $RefParserOptions(options) {
merge(this, $RefParserOptions.defaults);
merge(this, options);
}

$RefParserOptions.defaults = {
/**
* Determines how different types of files will be parsed.
*
Expand All @@ -36,31 +40,31 @@ function $RefParserOptions(options) {
* don't contain any keys.
*/
this.parse = {
json: parseJSON,
yaml: parseYAML,
text: parseText,
binary: parseBinary,
json: jsonParser,
yaml: yamlParser,
text: textParser,
binary: binaryParser,
};

/**
* Determines how external JSON References will be resolved.
* Determines how JSON References will be resolved.
*
* You can add additional readers of your own, replace an existing one with
* your own implemenation, or disable any reader by setting it to false.
* You can add additional resolvers of your own, replace an existing one with
* your own implemenation, or disable any resolver by setting it to false.
*
* Each of the built-in readers has the following options:
* Each of the built-in resolvers has the following options:
*
* order {number} - The order in which the reader will run
* order {number} - The order in which the resolver will run
*
* cache {number} - How long to cache files (in milliseconds)
* The default cache duration is different for each reader.
* Setting the cache duration to zero disables caching for that reader.
* The default cache duration is different for each resolver.
* Setting the cache duration to zero disables caching for that resolver.
*
* The HTTP reader has additional options. See read/http.js for details.
* The HTTP resolver has additional options. See read/http.js for details.
*/
this.resolve = {
file: readFile,
http: readHttp,
file: fileResolver,
http: httpResolver,

/**
* Determines whether external $ref pointers will be resolved.
Expand All @@ -85,39 +89,32 @@ function $RefParserOptions(options) {
*/
circular: true
};

merge(options, this);
}
};

/**
* Merges user-specified options with default options.
* Merges the specified options into the target object.
*
* @param {?object} user - The options that were specified by the user
* @param {$RefParserOptions} defaults - The {@link $RefParserOptions} object that we're populating
* @returns {*}
* @param {object} target - The object that we're populating
* @param {?object} source - The options that are being merged
* @returns {object}
*/
function merge(user, defaults) {
if (user) {
var keys = Object.keys(user);
function merge(target, source) {
if (source) {
var keys = Object.keys(source);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
var userSetting = user[key];
var defaultSetting = defaults[key];

if (userSetting && typeof userSetting === 'object' && !Array.isArray(userSetting)) {
if (typeof defaultSetting === 'function') {
// Create a copy of the default function, so the user can safely modify its options
defaultSetting = merge(defaultSetting, util.bind(defaultSetting));
}
var sourceSetting = source[key];
var targetSetting = target[key];

// Merge the user-sepcified options for this object/function
defaults[key] = merge(userSetting, defaultSetting || {});
if (sourceSetting && typeof sourceSetting === 'object' && !Array.isArray(sourceSetting)) {
// It's a nested object, so merge it recursively
target[key] = merge(targetSetting || {}, sourceSetting);
}
else {
// A scalar value, function, or array. So override the default value.
defaults[key] = userSetting;
else if (sourceSetting !== undefined) {
// It's a scalar value, function, or array. No merging necessary. Just overwrite the target value.
target[key] = sourceSetting;
}
}
}
return defaults;
return target;
}
11 changes: 6 additions & 5 deletions lib/parse/index.js → lib/parse.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
'use strict';

var util = require('../util'),
Promise = require('../util/promise'),
ono = require('ono');
var ono = require('ono'),
debug = require('./util/debug'),
url = require('./util/url'),
Promise = require('../util/promise');

module.exports = parse;

Expand All @@ -17,7 +18,7 @@ module.exports = parse;
*/
function parse(data, path, options) {
return new Promise(function(resolve, reject) {
util.debug('Parsing %s', path);
debug('Parsing %s', path);
var parsers = getSortedParsers(path, options);
util.runOrderedFunctions(parsers, data, path, options).then(onParsed, onError);

Expand Down Expand Up @@ -52,7 +53,7 @@ function parse(data, path, options) {
* @returns {{name: string, order: number, score: number, fn: function}[]}
*/
function getSortedParsers(path, options) {
var ext = util.path.extname(path);
var ext = url.extname(path);
var bestScore = 3;

return util.getOrderedFunctions(options.parse)
Expand Down
42 changes: 0 additions & 42 deletions lib/parse/binary.js

This file was deleted.

49 changes: 0 additions & 49 deletions lib/parse/json.js

This file was deleted.

0 comments on commit 2d5b52c

Please sign in to comment.