src/extensibility/node/package-validator.js
function validatePackageJSON(path, packageJSON, options, callback) {
    var errors = [];
    if (fs.existsSync(packageJSON)) {
        fs.readFile(packageJSON, {
            encoding: "utf8"
        }, function (err, data) {
            if (err) {
                callback(err, null, null);
                return;
            }

            var metadata;

            try {
                metadata = JSON.parse(data);
            } catch (e) {
                errors.push([Errors.INVALID_PACKAGE_JSON, e.toString(), path]);
                callback(null, errors, undefined);
                return;
            }

            // confirm required fields in the metadata
            if (!metadata.name) {
                errors.push([Errors.MISSING_PACKAGE_NAME, path]);
            } else if (!validateName(metadata.name)) {
                errors.push([Errors.BAD_PACKAGE_NAME, metadata.name]);
            }
            if (!metadata.version) {
                errors.push([Errors.MISSING_PACKAGE_VERSION, path]);
            } else if (!semver.valid(metadata.version)) {
                errors.push([Errors.INVALID_VERSION_NUMBER, metadata.version, path]);
            }

            // normalize the author
            if (metadata.author) {
                metadata.author = parsePersonString(metadata.author);
            }

            // contributors should be an array of people.
            // normalize each entry.
            if (metadata.contributors) {
                if (metadata.contributors.map) {
                    metadata.contributors = metadata.contributors.map(function (person) {
                        return parsePersonString(person);
                    });
                } else {
                    metadata.contributors = [
                        parsePersonString(metadata.contributors)
                    ];
                }
            }

            if (metadata.engines && metadata.engines.brackets) {
                var range = metadata.engines.brackets;
                if (!semver.validRange(range)) {
                    errors.push([Errors.INVALID_BRACKETS_VERSION, range, path]);
                }
            }

            if (options.disallowedWords) {
                ["title", "description", "name"].forEach(function (field) {
                    var words = containsWords(options.disallowedWords, metadata[field]);
                    if (words.length > 0) {
                        errors.push([Errors.DISALLOWED_WORDS, field, words.toString(), path]);
                    }
                });
            }
            callback(null, errors, metadata);
        });
    } else {
        if (options.requirePackageJSON) {
            errors.push([Errors.MISSING_PACKAGE_JSON, path]);
        }
        callback(null, errors, null);
    }
}
function validatePackageJSON(path, packageJSON, options, callback) {
    var errors = [];
    if (fs.existsSync(packageJSON)) {
        fs.readFile(packageJSON, {
            encoding: "utf8"
        }, function (err, data) {
            if (err) {
                callback(err, null, null);
                return;
            }

            var metadata;

            try {
                metadata = JSON.parse(data);
            } catch (e) {
                errors.push([Errors.INVALID_PACKAGE_JSON, e.toString(), path]);
                callback(null, errors, undefined);
                return;
            }

            // confirm required fields in the metadata
            if (!metadata.name) {
                errors.push([Errors.MISSING_PACKAGE_NAME, path]);
            } else if (!validateName(metadata.name)) {
                errors.push([Errors.BAD_PACKAGE_NAME, metadata.name]);
            }
            if (!metadata.version) {
                errors.push([Errors.MISSING_PACKAGE_VERSION, path]);
            } else if (!semver.valid(metadata.version)) {
                errors.push([Errors.INVALID_VERSION_NUMBER, metadata.version, path]);
            }

            // normalize the author
            if (metadata.author) {
                metadata.author = parsePersonString(metadata.author);
            }

            // contributors should be an array of people.
            // normalize each entry.
            if (metadata.contributors) {
                if (metadata.contributors.map) {
                    metadata.contributors = metadata.contributors.map(function (person) {
                        return parsePersonString(person);
                    });
                } else {
                    metadata.contributors = [
                        parsePersonString(metadata.contributors)
                    ];
                }
            }

            if (metadata.engines && metadata.engines.brackets) {
                var range = metadata.engines.brackets;
                if (!semver.validRange(range)) {
                    errors.push([Errors.INVALID_BRACKETS_VERSION, range, path]);
                }
            }

            if (options.disallowedWords) {
                ["title", "description", "name"].forEach(function (field) {
                    var words = containsWords(options.disallowedWords, metadata[field]);
                    if (words.length > 0) {
                        errors.push([Errors.DISALLOWED_WORDS, field, words.toString(), path]);
                    }
                });
            }
            callback(null, errors, metadata);
        });
    } else {
        if (options.requirePackageJSON) {
            errors.push([Errors.MISSING_PACKAGE_JSON, path]);
        }
        callback(null, errors, null);
    }
}
function validatePackageJSON ( path , packageJSON , options , callback ) { var errors = [ ] ; if ( fs . existsSync ( packageJSON ) ) { fs . readFile ( packageJSON , { encoding : "utf8" } , function ( err , data ) { if ( err ) { callback ( err , null , null ) ; return ; } var metadata ; try { metadata = JSON . parse ( data ) ; } catch ( e ) { errors . push ( [ Errors . INVALID_PACKAGE_JSON , e . toString ( ) , path ] ) ; callback ( null , errors , undefined ) ; return ; } // confirm required fields in the metadata if ( ! metadata . name ) { errors . push ( [ Errors . MISSING_PACKAGE_NAME , path ] ) ; } else if ( ! validateName ( metadata . name ) ) { errors . push ( [ Errors . BAD_PACKAGE_NAME , metadata . name ] ) ; } if ( ! metadata . version ) { errors . push ( [ Errors . MISSING_PACKAGE_VERSION , path ] ) ; } else if ( ! semver . valid ( metadata . version ) ) { errors . push ( [ Errors . INVALID_VERSION_NUMBER , metadata . version , path ] ) ; } // normalize the author if ( metadata . author ) { metadata . author = parsePersonString ( metadata . author ) ; } // contributors should be an array of people. // normalize each entry. if ( metadata . contributors ) { if ( metadata . contributors . map ) { metadata . contributors = metadata . contributors . map ( function ( person ) { return parsePersonString ( person ) ; } ) ; } else { metadata . contributors = [ parsePersonString ( metadata . contributors ) ] ; } } if ( metadata . engines && metadata . engines . brackets ) { var range = metadata . engines . brackets ; if ( ! semver . validRange ( range ) ) { errors . push ( [ Errors . INVALID_BRACKETS_VERSION , range , path ] ) ; } } if ( options . disallowedWords ) { [ "title" , "description" , "name" ] . forEach ( function ( field ) { var words = containsWords ( options . disallowedWords , metadata [ field ] ) ; if ( words . length > 0 ) { errors . push ( [ Errors . DISALLOWED_WORDS , field , words . toString ( ) , path ] ) ; } } ) ; } callback ( null , errors , metadata ) ; } ) ; } else { if ( options . requirePackageJSON ) { errors . push ( [ Errors . MISSING_PACKAGE_JSON , path ] ) ; } callback ( null , errors , null ) ; } }
Validates the contents of package.json.

@param {string} path path to package file (used in error reporting)
@param {string} packageJSON path to the package.json file to check
@param {Object} options validation options passed to `validate()`
@param {function(Error, Array.<Array.<string, ...>>, Object)} callback function to call with array of errors and metadata
Validates the contents of package . json .