bower
Version:
The browser package manager
148 lines (118 loc) • 3.4 kB
JavaScript
var fs = require('graceful-fs');
var path = require('path');
var deepExtend = require('deep-extend');
var isComponent = require('./util/isComponent');
var createError = require('./util/createError');
var possibleJsons = ['bower.json', 'component.json', '.bower.json'];
function read(file, options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
// Check if file is a directory
fs.stat(file, function (err, stat) {
if (err) {
return callback(err);
}
// It's a directory, so we find the json inside it
if (stat.isDirectory()) {
return find(file, function (err, file) {
if (err) {
return callback(err);
}
read(file, options, callback);
});
}
// Otherwise read it
fs.readFile(file, function (err, contents) {
var json;
if (err) {
return callback(err);
}
try {
json = JSON.parse(contents.toString());
} catch (err) {
err.file = path.resolve(file);
err.code = 'EMALFORMED';
return callback(err);
}
// Parse it
try {
json = parse(json, options);
} catch (err) {
err.file = path.resolve(file);
return callback(err);
}
callback(null, json, file);
});
});
}
function parse(json, options) {
options = deepExtend({
normalize: false,
validate: true,
clone: false
}, options || {});
// Clone
if (options.clone) {
json = deepExtend({}, json);
}
// Validate
if (options.validate) {
validate(json);
}
// Normalize
if (options.normalize) {
normalize(json);
}
return json;
}
function validate(json) {
if (!json.name) {
throw createError('No name property set', 'EINVALID');
}
// TODO
return json;
}
function normalize(json) {
if (typeof json.main === 'string') {
json.main = json.main.split(',');
}
// TODO
return json;
}
function find(folder, files, callback) {
var err;
var file;
if (typeof files === 'function') {
callback = files;
files = possibleJsons;
}
if (!files.length) {
err = createError('None of ' + possibleJsons.join(', ') + ' were found in ' + folder, 'ENOENT');
return callback(err);
}
file = path.resolve(path.join(folder, files[0]));
fs.exists(file, function (exists) {
if (!exists) {
return find(folder, files.slice(1), callback);
}
if (files[0] !== 'component.json') {
return callback(null, file);
}
// If the file is component.json, check it it's a component(1) file
// If it is, we ignore it and keep searching
isComponent(file, function (is) {
if (is) {
return find(folder, files.slice(1), callback);
}
callback(null, file);
});
});
}
module.exports = read;
module.exports.read = read;
module.exports.parse = parse;
module.exports.validate = validate;
module.exports.normalize = normalize;
module.exports.find = find;