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;