lib/main.js
function Container(container_directory, package_json) {
    let config_yaml = {};
    let toc_yaml = {};

    assert(container_directory, 'resource-container: missing container_directory');
    assert.equal(typeof container_directory, 'string', 'resource-container: container_directory should be a string');

    try {
        let configFile = path.join(container_directory, content_dir, 'config.yml');
        if(fileUtils.fileExists(configFile)) config_yaml = YAML.parse(fs.readFileSync(configFile, {encoding: 'utf8'}));
    } catch (err){
        console.warn(err);
    }
    try {
        let tocFile = path.join(container_directory, content_dir, 'toc.yml');
        if(fileUtils.fileExists(tocFile)) toc_yaml = YAML.parse(fs.readFileSync(tocFile, {encoding: 'utf8'}));
    } catch (err){
        console.warn(err);
    }

    assert(package_json, 'resource-container: missing package json');
    assert(package_json.language, 'resource-container: missing language');
    assert(package_json.project, 'resource-container: missing project');
    assert(package_json.resource, 'resource-container: missing resource');
    assert(package_json.resource.type, 'resource-container: missing resource type');

    return {

        get language () {
            return package_json.language;
        },

        get project () {
            return package_json.project;
        },

        get resource () {
            return package_json.resource;
        },

        /**
         * Returns an array of chapters in this resource container
         */
        chapters: function () {
            let dir = path.join(container_directory, content_dir);
            return fs.readdirSync(dir).filter(function(file) {
                try {
                    return fs.statSync(file).isDirectory();
                } catch (err) {
                    console.log(err);
                    return false;
                }
            });
        },

        /**
         * Returns an array of chunks in the chapter
         */
        chunks: function (chapterSlug) {
            let dir = path.join(container_directory, content_dir, chapterSlug);
            return fs.readdirSync(dir).filter(function(file) {
                try {
                    return fs.statSync(file).isFile();
                } catch (err) {
                    console.log(err);
                    return false;
                }
            });
        },

        /**
         * Returns the contents of a chunk.
         * If the chunk does not exist or there is an exception an empty string will be returned.
         * @param chapterSlug
         * @param chunkSlug
         * @returns string the contents of the chunk
         */
        readChunk: function(chapterSlug, chunkSlug) {
            let file = path.join(container_directory, content_dir, chapterSlug, chunkSlug + '.' + this.chunkExt);
            return fs.readFileSync(file, {encoding: 'utf8'});
        },

        /**
         * Returns the file extension to use for content files (chunks)
         * @returns {*}
         */
        get chunkExt() {
            switch(package_json['content_mime_type']) {
                case 'text/usx':
                    return 'usx';
                case 'text/usfm':
                    return 'usfm';
                case 'text/markdown':
                    return 'md';
                default:
                    return 'txt';
            }
        },

        /**
         * Returns the path to the resource container directory
         * @returns {string}
         */
        get path () {
            return container_directory;
        },

        /**
         * Returns the slug of the resource container
         * @returns {string}
         */
        get slug () {
            return containerSlug(
                package_json.language.slug,
                package_json.project.slug,
                package_json.resource.slug);
        },

        /**
         * Returns the type of the resource container.
         * Shorthand for info.resource.type
         * @returns {string}
         */
        get type() {
            return package_json.resource.type;
        },

        /**
         * Returns the resource container package information.
         * This is the package.json file
         * @returns {{}}
         */
        get info() {
            return package_json;
        },

        /**
         * Returns the resource container data configuration.
         * This is the config.yml file under the content/ directory
         *
         * @returns {{}}
         */
        get config() {
            return config_yaml;
        },

        /**
         * Returns the table of contents.
         * This is the toc.yml file under the content/ directory
         *
         * @returns {{}|[]}
         */
        get toc() {
            return toc_yaml;
        }
    };
}
function Container(container_directory, package_json) {
    let config_yaml = {};
    let toc_yaml = {};

    assert(container_directory, 'resource-container: missing container_directory');
    assert.equal(typeof container_directory, 'string', 'resource-container: container_directory should be a string');

    try {
        let configFile = path.join(container_directory, content_dir, 'config.yml');
        if(fileUtils.fileExists(configFile)) config_yaml = YAML.parse(fs.readFileSync(configFile, {encoding: 'utf8'}));
    } catch (err){
        console.warn(err);
    }
    try {
        let tocFile = path.join(container_directory, content_dir, 'toc.yml');
        if(fileUtils.fileExists(tocFile)) toc_yaml = YAML.parse(fs.readFileSync(tocFile, {encoding: 'utf8'}));
    } catch (err){
        console.warn(err);
    }

    assert(package_json, 'resource-container: missing package json');
    assert(package_json.language, 'resource-container: missing language');
    assert(package_json.project, 'resource-container: missing project');
    assert(package_json.resource, 'resource-container: missing resource');
    assert(package_json.resource.type, 'resource-container: missing resource type');

    return {

        get language () {
            return package_json.language;
        },

        get project () {
            return package_json.project;
        },

        get resource () {
            return package_json.resource;
        },

        /**
         * Returns an array of chapters in this resource container
         */
        chapters: function () {
            let dir = path.join(container_directory, content_dir);
            return fs.readdirSync(dir).filter(function(file) {
                try {
                    return fs.statSync(file).isDirectory();
                } catch (err) {
                    console.log(err);
                    return false;
                }
            });
        },

        /**
         * Returns an array of chunks in the chapter
         */
        chunks: function (chapterSlug) {
            let dir = path.join(container_directory, content_dir, chapterSlug);
            return fs.readdirSync(dir).filter(function(file) {
                try {
                    return fs.statSync(file).isFile();
                } catch (err) {
                    console.log(err);
                    return false;
                }
            });
        },

        /**
         * Returns the contents of a chunk.
         * If the chunk does not exist or there is an exception an empty string will be returned.
         * @param chapterSlug
         * @param chunkSlug
         * @returns string the contents of the chunk
         */
        readChunk: function(chapterSlug, chunkSlug) {
            let file = path.join(container_directory, content_dir, chapterSlug, chunkSlug + '.' + this.chunkExt);
            return fs.readFileSync(file, {encoding: 'utf8'});
        },

        /**
         * Returns the file extension to use for content files (chunks)
         * @returns {*}
         */
        get chunkExt() {
            switch(package_json['content_mime_type']) {
                case 'text/usx':
                    return 'usx';
                case 'text/usfm':
                    return 'usfm';
                case 'text/markdown':
                    return 'md';
                default:
                    return 'txt';
            }
        },

        /**
         * Returns the path to the resource container directory
         * @returns {string}
         */
        get path () {
            return container_directory;
        },

        /**
         * Returns the slug of the resource container
         * @returns {string}
         */
        get slug () {
            return containerSlug(
                package_json.language.slug,
                package_json.project.slug,
                package_json.resource.slug);
        },

        /**
         * Returns the type of the resource container.
         * Shorthand for info.resource.type
         * @returns {string}
         */
        get type() {
            return package_json.resource.type;
        },

        /**
         * Returns the resource container package information.
         * This is the package.json file
         * @returns {{}}
         */
        get info() {
            return package_json;
        },

        /**
         * Returns the resource container data configuration.
         * This is the config.yml file under the content/ directory
         *
         * @returns {{}}
         */
        get config() {
            return config_yaml;
        },

        /**
         * Returns the table of contents.
         * This is the toc.yml file under the content/ directory
         *
         * @returns {{}|[]}
         */
        get toc() {
            return toc_yaml;
        }
    };
}
Represents an instance of a resource container.

@param container_directory
@param package_json {{}}
@constructor