fabricator
Advanced tools
| module.exports = module.exports = function Is() { | ||
| /* noop */ | ||
| }; |
+31
-137
@@ -7,51 +7,42 @@ 'use strict'; | ||
| /** | ||
| * Expose small fabrication helper. Provide an optional callback to run the method | ||
| * asynchronously. | ||
| * Expose small fabrication helper. | ||
| * | ||
| * @param {Mixed} stack String, array or object that contains constructible entities | ||
| * @param {String} source Optional absolute path to be used to resolve filepaths | ||
| * @param {Function} done Optional completion callback. | ||
| * @return {Array} collection of constructors, if called synchronously. | ||
| * @param {Object} options | ||
| * | ||
| * Possible options | ||
| * - source: {String} Absolute path to be used to resolve filepaths | ||
| * - recursive: {Boolean} Should file paths be recursively discovered | ||
| * | ||
| * @returns {Array} collection of constructors. | ||
| * @api public | ||
| */ | ||
| module.exports = function fabricator(stack, source, done) { | ||
| module.exports = function fabricator(stack, options) { | ||
| var type = typeof stack; | ||
| if ('object' === type && Array.isArray(stack)) type = 'array'; | ||
| // | ||
| // No source was provided, check if the call was asynchronous. | ||
| // | ||
| if ('function' === typeof source) { | ||
| done = source; | ||
| source = null; | ||
| } | ||
| // | ||
| // Call the fabricate function (a)synchronously. | ||
| // | ||
| if ('function' !== typeof done) return fabricateSync(type, stack, source); | ||
| fabricate(type, stack, source, done); | ||
| return fabricate(type, stack, options || {}); | ||
| }; | ||
| /** | ||
| * Synchronous discover constructible entities. | ||
| * Discover constructible entities. | ||
| * | ||
| * @param {String} type Typeof stack. | ||
| * @param {Mixed} stack | ||
| * @param {String} source Optional absolute path to be used to resolve filepaths | ||
| * @param {Object} options | ||
| * @return {Array} filtered collection of constructible entities. | ||
| * @api private | ||
| */ | ||
| function fabricateSync(type, stack, source) { | ||
| function fabricate(type, stack, options) { | ||
| switch (type) { | ||
| case 'string': | ||
| stack = readSync(stack, source); | ||
| stack = read(stack, options); | ||
| break; | ||
| case 'object': | ||
| stack = Object.keys(stack).reduce(iterator(readSync, stack, source), []); | ||
| stack = Object.keys(stack).reduce(iterator(read, stack, options), []); | ||
| break; | ||
| case 'array': | ||
| stack = stack.reduce(iterator(readSync, source), []); | ||
| stack = stack.reduce(iterator(read, null, options), []); | ||
| break; | ||
@@ -64,47 +55,11 @@ } | ||
| /** | ||
| * Asynchronously discover constructible entities. | ||
| * | ||
| * @param {String} type Typeof stack. | ||
| * @param {Mixed} stack | ||
| * @param {String} source Optional absolute path to be used to resolve filepaths | ||
| * @param {Function} done Completion callback. | ||
| * @api private | ||
| */ | ||
| function fabricate(type, stack, source, done) { | ||
| var result = []; | ||
| switch (type) { | ||
| case 'string': | ||
| read(stack, source, done); | ||
| break; | ||
| case 'object': | ||
| Object.keys(stack).reduce(iterator( | ||
| read, | ||
| stack, | ||
| source, | ||
| recur(Object.keys(stack).length, result, done) | ||
| ), result); | ||
| break; | ||
| case 'array': | ||
| stack.reduce(iterator( | ||
| read, | ||
| null, | ||
| source, | ||
| recur(stack.length, result, done) | ||
| ), result); | ||
| break; | ||
| } | ||
| } | ||
| /** | ||
| * Read directory and initialize javascript files. | ||
| * | ||
| * @param {String} filepath Full directory path. | ||
| * @param {Object} options | ||
| * @return {Array} collection of constructors | ||
| * @api private | ||
| */ | ||
| function readSync(filepath, source) { | ||
| if (source) filepath = path.resolve(source, filepath); | ||
| function read(filepath, options) { | ||
| if (options.source) filepath = path.resolve(options.source, filepath); | ||
@@ -119,4 +74,11 @@ // | ||
| // | ||
| // Read the directory synchronous, only process files. | ||
| // Recursion on directories not allowed, initialize the index.js file. | ||
| // | ||
| if (options.recursive === false) return [ | ||
| init(filepath, path.basename(filepath, '.js')) | ||
| ]; | ||
| // | ||
| // Read the directory, only process files. | ||
| // | ||
| return fs.readdirSync(filepath).map(function locate(file) { | ||
@@ -134,41 +96,2 @@ file = path.resolve(filepath, file); | ||
| /** | ||
| * Asynchronous read directory and initialize javascript files. | ||
| * | ||
| * @param {String} filepath Full directory path. | ||
| * @param {String} source Optional absolute path to be used to resolve filepaths | ||
| * @param {done} | ||
| * @api privat | ||
| */ | ||
| function read(filepath, source, done) { | ||
| var iterate; | ||
| if (source) filepath = path.resolve(source, filepath); | ||
| // | ||
| // Check if the provided string is a JS file. | ||
| // | ||
| if (js(filepath)) return done(null, [ | ||
| init(filepath, path.basename(filepath, '.js')) | ||
| ]); | ||
| // | ||
| // Read the directory asynchronous, only process files. | ||
| // | ||
| fs.readdir(filepath, function readfilepath(error, files) { | ||
| if (error) return done(error); | ||
| iterate = recur(files.length, [], done); | ||
| files.forEach(function map(file) { | ||
| file = path.resolve(filepath, file); | ||
| if (!js(file)) return iterate(); | ||
| fs.stat(file, function details(error, stat) { | ||
| if (error || !stat.isFile()) return iterate(); | ||
| iterate(null, init(file, path.basename(file, '.js'))); | ||
| }); | ||
| }); | ||
| }); | ||
| } | ||
| /** | ||
| * Return iterator for array or object. | ||
@@ -178,8 +101,7 @@ * | ||
| * @param {Object} obj Original object, if set values are fetched by entity. | ||
| * @param {String} source Optional absolute path to be used to resolve filepaths | ||
| * @param {Function} done Optional completion callback. | ||
| * @param {Object} options | ||
| * @return {Function} iterator | ||
| * @api private | ||
| */ | ||
| function iterator(traverse, obj, source, done) { | ||
| function iterator(traverse, obj, options) { | ||
| return function reduce(stack, entity) { | ||
@@ -190,13 +112,5 @@ var base = obj ? obj[entity] : entity | ||
| // | ||
| // Run traverse function async, callback was provided, traverse will init. | ||
| // Run the functions, traverse will handle init. | ||
| // | ||
| if ('function' === typeof done) { | ||
| if (nojs) return traverse(base, source, done); | ||
| return done(null, init(base, entity)); | ||
| } | ||
| // | ||
| // Run the sync functions, traverse will handle init. | ||
| // | ||
| if (nojs) return stack.concat(traverse(base, source)); | ||
| if (nojs) return stack.concat(traverse(base, options)); | ||
| return stack.concat(init(base, entity)); | ||
@@ -207,22 +121,2 @@ }; | ||
| /** | ||
| * Result mapper, returns when all callbacks finished. | ||
| * | ||
| * @param {Number} n Number of execution before done is called. | ||
| * @param {Array} results Stack to push results into. | ||
| * @param {Function} done Completion callback. | ||
| * @returns {Fuction} handler to process files after finished iteration. | ||
| * @api private | ||
| */ | ||
| function recur(n, results, done) { | ||
| return function iterate(error, files) { | ||
| if (!error && files) results = results.concat(files); | ||
| // | ||
| // Check if the base stack is completely processed. | ||
| // | ||
| if (!--n) return done(error, results.filter(Boolean)); | ||
| }; | ||
| } | ||
| /** | ||
| * Make sure only valid JavaScript files are used as source. Ignore other files, | ||
@@ -229,0 +123,0 @@ * like .log files. Also allow constructors. |
+1
-1
| { | ||
| "name": "fabricator", | ||
| "version": "0.3.0", | ||
| "version": "0.4.0", | ||
| "description": "Discover collections of constructible instances from strings (filepaths), arrays or objects", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
+1
-11
@@ -11,5 +11,2 @@ # Fabricator [![Build Status][status]](https://travis-ci.org/bigpipe/fabricator) [![NPM version][npmimgurl]](http://badge.fury.io/js/fabricator) [![Coverage Status][coverage]](http://coveralls.io/r/bigpipe/fabricator?branch=master) | ||
| The module exposes a factory function which can be provided with an optional | ||
| completion callback. Providing the callback will make the discovery asynchronous. | ||
| The [BigPipe] project is using the fabricator to find Pages and/or Pagelets. This | ||
@@ -37,12 +34,5 @@ gives developers using BigPipe more flexibility. For example, you don't have to | ||
| // | ||
| // Discover constructors synchronously. | ||
| // Discover constructors. | ||
| // | ||
| var stack = fabricator(obj); | ||
| // | ||
| // Similar to above but asynchronously. | ||
| // | ||
| fabricator(path, function fabricate(error, results) { | ||
| console.log(results); | ||
| }); | ||
| ``` | ||
@@ -49,0 +39,0 @@ |
+16
-56
@@ -12,18 +12,10 @@ describe('Fabricator', function () { | ||
| it('can be called (a)synchronous and returns an array', function (done) { | ||
| it('always returns an array', function () { | ||
| var result = fabricator(fixtures.array); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(2); | ||
| fabricator(fixtures.array, function (error, result) { | ||
| assume(error).to.equal(null); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(2); | ||
| done(); | ||
| }); | ||
| assume(result.length).to.equal(3); | ||
| }); | ||
| it('can init constructors from file paths', function (done) { | ||
| it('can init constructors from file paths', function () { | ||
| var result = fabricator(fixtures.string); | ||
@@ -33,44 +25,28 @@ | ||
| assume(result.length).to.equal(1); | ||
| fabricator(fixtures.string, function (error, result) { | ||
| assume(error).to.equal(null); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(1); | ||
| done(); | ||
| }); | ||
| }); | ||
| it('will discover constructors in subdirectories and ignore other JS files', function (done) { | ||
| it('will discover constructors in subdirectories and ignore other JS files', function () { | ||
| var result = fabricator(fixtures.directory); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(1); | ||
| assume(result.length).to.equal(2); | ||
| }); | ||
| fabricator(fixtures.directory, function (error, result) { | ||
| assume(error).to.equal(null); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(1); | ||
| it('can be provided with a absolute source path to resolve filepaths', function () { | ||
| var path = __dirname + '/fixtures' | ||
| , result = fabricator(fixtures.relative, { source: path }); | ||
| done(); | ||
| }); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(2); | ||
| }); | ||
| it('can be provided with a absolute source path to resolve filepaths', function (done) { | ||
| it('can be prevented from recursing a directory', function () { | ||
| var path = __dirname + '/fixtures' | ||
| , result = fabricator(fixtures.relative, path); | ||
| , result = fabricator(fixtures.directory, { recursive: false }); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(1); | ||
| fabricator(fixtures.relative, path, function (error, result) { | ||
| assume(error).to.equal(null); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(1); | ||
| done(); | ||
| }); | ||
| }); | ||
| it('will discover constructors from objects', function (done) { | ||
| it('will discover constructors from objects', function () { | ||
| var result = fabricator(fixtures.object); | ||
@@ -80,25 +56,9 @@ | ||
| assume(result.length).to.equal(3); | ||
| fabricator(fixtures.object, function (error, result) { | ||
| assume(error).to.equal(null); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(3); | ||
| done(); | ||
| }); | ||
| }); | ||
| it('will discover constructors from arrays', function (done) { | ||
| it('will discover constructors from arrays', function () { | ||
| var result = fabricator(fixtures.array); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(2); | ||
| fabricator(fixtures.array, function (error, result) { | ||
| assume(error).to.equal(null); | ||
| assume(result).to.be.an('array'); | ||
| assume(result.length).to.equal(2); | ||
| done(); | ||
| }); | ||
| assume(result.length).to.equal(3); | ||
| }); | ||
@@ -105,0 +65,0 @@ |
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
13
8.33%11283
-26.96%221
-35.38%46
-17.86%