@@ -10,31 +10,70 @@ var callbacks = ["cb", "callback", "callback_", "done"];
1010 * inspecting the last argument in the parameter signature for a callback.
1111 *
1212 * @param {* } exports - Should be a function or an object, identity other.
13+ * @param {Function } test - Optional function to identify async methods.
14+ * @param {String } parentKeyName - Tracks the keyName in a digestable format.
1315 * @returns {* } exports - Identity.
1416 */
15- function processExports ( exports ) {
17+ function processExports ( exports , test , cached , parentKeyName ) {
18+ // Return early if this object has already been processed.
19+ if ( cached . indexOf ( exports ) > - 1 ) {
20+ return exports ;
21+ }
22+
23+ // Record this object in the cache.
24+ cached . push ( exports ) ;
25+
1626 // Pass through if not an object or function.
1727 if ( typeof exports != "object" && typeof exports != "function" ) {
1828 return exports ;
1929 }
2030
31+ var name = exports . name + "#" ;
32+
2133 // If a function, simply return it wrapped.
2234 if ( typeof exports === "function" ) {
23- return Promise . denodeify ( exports ) ;
35+ // Find properties added to functions.
36+ for ( var keyName in exports ) {
37+ exports [ keyName ] = processExports ( exports [ keyName ] , test , cached , name ) ;
38+ }
39+
40+ // Assign the new function in place.
41+ var wrapped = Promise . denodeify ( exports ) ;
42+
43+ // Find methods on the prototype, if there are any.
44+ if ( Object . keys ( exports . prototype ) . length ) {
45+ processExports ( exports . prototype , test , cached , name ) ;
46+ }
47+
48+ // Attach the augmented prototype.
49+ wrapped . prototype = exports . prototype ;
50+
51+ // Ensure attached properties to the previous function are accessible.
52+ wrapped . __proto__ = exports ;
53+
54+ return wrapped ;
2455 }
2556
2657 Object . keys ( exports ) . map ( function ( keyName ) {
2758 // Convert to values.
2859 return [ keyName , exports [ keyName ] ] ;
2960 } ) . filter ( function ( keyVal ) {
61+ var keyName = keyVal [ 0 ] ;
3062 var value = keyVal [ 1 ] ;
3163
3264 // If an object is encountered, recursively traverse.
3365 if ( typeof value === "object" ) {
34- processExports ( exports ) ;
66+ processExports ( exports , test , cached , keyName + "." ) ;
3567 }
3668 // Filter to functions with callbacks only.
3769 else if ( typeof value === "function" ) {
70+ // If a filter function exists, use this to determine if the function
71+ // is asynchronous.
72+ if ( test ) {
73+ // Pass the function itself, its keyName, and the parent keyName.
74+ return test ( value , keyName , parentKeyName ) ;
75+ }
76+
3877 // If the callback name exists as the last argument, consider it an
3978 // asynchronous function. Brittle? Fragile? Effective.
4079 if ( callbacks . indexOf ( args ( value ) . slice ( - 1 ) [ 0 ] ) > - 1 ) {
@@ -45,8 +84,8 @@ function processExports(exports) {
4584 var keyName = keyVal [ 0 ] ;
4685 var func = keyVal [ 1 ] ;
4786
48- // Assign the new function in place .
49- exports [ keyName ] = Promise . denodeify ( func ) ;
87+ // Wrap this function and reassign .
88+ exports [ keyName ] = processExports ( func , test , cached , parentKeyName ) ;
5089 } ) ;
5190
5291 return exports ;
@@ -56,9 +95,10 @@ function processExports(exports) {
5695 * Public API for Promisify. Will resolve modules names using `require`.
5796 *
5897 * @param {* } name - Can be a module name, object, or function.
98+ * @param {Function } test - Optional function to identify async methods.
5999 * @returns {* } exports - The resolved value from require or passed in value.
60100 */
61- module . exports = function ( name ) {
101+ module . exports = function ( name , test ) {
62102 var exports = name ;
63103
64104 // If the name argument is a String, will need to resovle using the built in
@@ -69,7 +109,7 @@ module.exports = function(name) {
69109
70110 // Iterate over all properties and find asynchronous functions to convert to
71111 // promises.
72- return processExports ( exports ) ;
112+ return processExports ( exports , test , [ ] ) ;
73113} ;
74114
75115// Export callbacks to the module.
0 commit comments